Restore the byte-by-byte checksum method, since the Unicode-aware
[sitka/SIPServer.git] / Sip / Checksum.pm
CommitLineData
0fca9208 1#\r
2# Copyright (C) 2006-2008 Georgia Public Library Service\r
3# \r
4# Author: David J. Fiander\r
5# \r
6# This program is free software; you can redistribute it and/or\r
7# modify it under the terms of version 2 of the GNU General Public\r
8# License as published by the Free Software Foundation.\r
9# \r
10# This program is distributed in the hope that it will be useful,\r
11# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
13# GNU General Public License for more details.\r
14# \r
15# You should have received a copy of the GNU General Public\r
16# License along with this program; if not, write to the Free\r
17# Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,\r
18# MA 02111-1307 USA\r
19\r
863db634 20package Sip::Checksum;\r
21\r
22use Exporter;\r
23use strict;\r
24use warnings;\r
25\r
26our @ISA = qw(Exporter);\r
27our @EXPORT_OK = qw(checksum verify_cksum);\r
28\r
29sub checksum {\r
30 my $pkt = shift;\r
80e317cf 31\r
b93b5b61 32 return (-unpack('%16C*', $pkt) & 0xFFFF);\r
863db634 33}\r
34\r
35sub verify_cksum {\r
36 my $pkt = shift;\r
37 my $cksum;\r
38 my $shortsum;\r
39\r
40 return 0 if (substr($pkt, -6, 2) ne "AZ"); # No checksum at end\r
41\r
42 # Convert the checksum back to hex and calculate the sum of the\r
43 # pack without the checksum.\r
44 $cksum = hex(substr($pkt, -4));\r
288e4367 45 $shortsum = unpack("%16U*", substr($pkt, 0, -4));\r
863db634 46\r
47 # The checksum is valid if the hex sum, plus the checksum of the \r
48 # base packet short when truncated to 16 bits.\r
49 return (($cksum + $shortsum) & 0xFFFF) == 0;\r
50}\r
51\r
52{\r
53 no warnings qw(once);\r
54 eval join('',<main::DATA>) || die $@ unless caller();\r
55}\r
56__END__\r
57\r
58#\r
59# Some simple test data\r
60#\r
61sub test {\r
62 my $testpkt = shift;\r
63 my $cksum = checksum($testpkt);\r
64 my $fullpkt = sprintf("%s%4X", $testpkt, $cksum);\r
65\r
66 print $fullpkt, "\n";\r
67}\r
68\r
69while (<>) {\r
70 chomp;\r
71 test($_);\r
72}\r
80e317cf 73\r
741;\r