]> git.evergreen-ils.org Git - working/SIPServer.git/blob - Sip/Checksum.pm
Restore the byte-by-byte checksum method, since the Unicode-aware
[working/SIPServer.git] / Sip / Checksum.pm
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
20 package Sip::Checksum;\r
21 \r
22 use Exporter;\r
23 use strict;\r
24 use warnings;\r
25 \r
26 our @ISA = qw(Exporter);\r
27 our @EXPORT_OK = qw(checksum verify_cksum);\r
28 \r
29 sub checksum {\r
30     my $pkt = shift;\r
31 \r
32     return (-unpack('%16C*', $pkt) & 0xFFFF);\r
33 }\r
34 \r
35 sub 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
45     $shortsum = unpack("%16U*", substr($pkt, 0, -4));\r
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
61 sub 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
69 while (<>) {\r
70     chomp;\r
71     test($_);\r
72 }\r
73 \r
74 1;\r