summaryrefslogtreecommitdiffstats
path: root/contrib/ipfilter/test/vfycksum.pl
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ipfilter/test/vfycksum.pl')
-rwxr-xr-xcontrib/ipfilter/test/vfycksum.pl282
1 files changed, 206 insertions, 76 deletions
diff --git a/contrib/ipfilter/test/vfycksum.pl b/contrib/ipfilter/test/vfycksum.pl
index b3a20be..0272e4b 100755
--- a/contrib/ipfilter/test/vfycksum.pl
+++ b/contrib/ipfilter/test/vfycksum.pl
@@ -19,82 +19,71 @@ sub dosum {
local($lsum) = $seed;
for ($idx = $start, $lsum = $seed; $idx < $max; $idx++) {
+#printf "%#x += %#x\n", $lsum, $bytes[$idx];
$lsum += $bytes[$idx];
}
- $lsum = ($lsum & 0xffff) + ($lsum >> 16);
+ while ($lsum > 0xffff) {
+ $lsum = ($lsum & 0xffff) + ($lsum >> 16);
+ }
$lsum = ~$lsum & 0xffff;
return $lsum;
}
-sub ipv4check {
- local($base) = $_[0];
- $hl = $bytes[$base] / 256;
- return if (($hl >> 4) != 4); # IPv4 ?
- $hl &= 0xf;
- $hl <<= 1; # get the header length in 16bit words
- $hs = &dosum(0, $base, $base + $hl);
- $osum = $bytes[$base + 5];
+sub ipv4addrsum {
+ local($b) = $_[0];
+ local($as) = 0;
- if ($hs != 0) {
- $bytes[$base + 5] = 0;
- $hs2 = &dosum(0, $base, $base + $hl);
- $bytes[$base + 5] = $osum;
- printf " IP: ($hl,%x) %x != %x", $hs, $osum, $hs2;
- } else {
- print " IP($base): ok ";
- }
-
- #
- # Recognise TCP & UDP and calculate checksums for each of these.
- #
- if (($bytes[$base + 4] & 0xff) == 6) {
- &tcpcheck($base);
- }
-
- if (($bytes[$base + 4] & 0xff) == 17) {
- &udpcheck($base);
- }
+ $as += $bytes[$b + 6]; # source address
+ $as += $bytes[$b + 7];
+ $as += $bytes[$b + 8]; # destination address
+ $as += $bytes[$b + 9];
+ return ($as);
+}
- if (($bytes[$base + 4] & 0xff) == 1) {
- &icmpcheck($base);
- }
- if ($base == 0) {
- print "\n";
- }
+sub ipv6addrsum {
+ local($b) = $_[0];
+ local($as) = 0;
+
+ $as += $bytes[$b + 4]; # source address
+ $as += $bytes[$b + 5];
+ $as += $bytes[$b + 6];
+ $as += $bytes[$b + 7];
+ $as += $bytes[$b + 8];
+ $as += $bytes[$b + 9];
+ $as += $bytes[$b + 10];
+ $as += $bytes[$b + 11];
+ $as += $bytes[$b + 12]; # destination address
+ $as += $bytes[$b + 13];
+ $as += $bytes[$b + 14];
+ $as += $bytes[$b + 15];
+ $as += $bytes[$b + 16];
+ $as += $bytes[$b + 17];
+ $as += $bytes[$b + 18];
+ $as += $bytes[$b + 19];
+ return ($as);
}
-sub tcpcheck {
+sub tcpcommon {
local($base) = $_[0];
- local($hl) = $bytes[$base] / 256;
- return if (($hl >> 4) != 4);
- return if ($bytes[$base + 3] & 0x1fff);
- $hl &= 0xf;
- $hl <<= 1;
+ local($hl) = $_[1];
+ local($hs) = $_[2];
+ local($lenoffset) = $_[3];
- local($hs2);
- local($hs) = 6; # TCP
- local($len) = $bytes[$base + 1] - ($hl << 1);
- $hs += $len;
- $hs += $bytes[$base + 6]; # source address
- $hs += $bytes[$base + 7];
- $hs += $bytes[$base + 8]; # destination address
- $hs += $bytes[$base + 9];
- local($tcpsum) = $hs;
-
- local($thl) = $bytes[$base + $hl + 6] >> 8;
+ local($thl) = $bytes[$base + $hl + 6];
$thl &= 0xf0;
$thl >>= 2;
- $x = $bytes[$base + 1];
- $y = ($cnt - $base) * 2;
- $z = 0;
- if ($bytes[$base + 1] > ($cnt - $base) * 2) {
+ local($x) = $bytes[$base + $lenoffset];
+ local($y) = ($cnt - $base) * 2;
+ local($z) = 0;
+
+ if ($bytes[$base + $lenoffset] > ($cnt - $base) * 2) {
print "[cnt=$cnt base=$base]";
- $x = $bytes[$base + 1];
+ $x = $bytes[$base + $lenoffset];
$y = ($cnt - $base) * 2;
$z = 1;
- } elsif (($cnt - $base) * 2 < $hl + 20) {
+ } elsif (($cnt - $base) * 2 < $hl + $hl) {
$x = ($cnt - $base) * 2;
$y = $hl + 20;
$z = 2;
@@ -106,6 +95,10 @@ sub tcpcheck {
$x = ($cnt - $base) * 2;
$y = $len;
$z = 4;
+ } elsif (($cnt - $base) * 2 < 20) {
+ $x = ($cnt - $base) * 2;
+ $y = $len;
+ $z = 5;
}
if ($z) {
@@ -115,11 +108,11 @@ sub tcpcheck {
}
local($tcpat) = $base + $hl;
- $hs = &dosum($tcpsum, $tcpat, $cnt);
+ $hs = &dosum($_[2], $tcpat, $cnt);
if ($hs != 0) {
local($osum) = $bytes[$tcpat + 8];
$bytes[$base + $hl + 8] = 0;
- $hs2 = &dosum($tcpsum, $tcpat, $cnt);
+ local($hs2) = &dosum($_[2], $tcpat, $cnt);
$bytes[$tcpat + 8] = $osum;
printf " TCP: (%x) %x != %x", $hs, $osum, $hs2;
} else {
@@ -127,23 +120,10 @@ sub tcpcheck {
}
}
-sub udpcheck {
+sub udpcommon {
local($base) = $_[0];
- local($hl) = $bytes[0] / 256;
- return if (($hl >> 4) != 4);
- return if ($bytes[3] & 0x1fff);
- $hl &= 0xf;
- $hl <<= 1;
-
- local($hs2);
- local($hs) = 17; # UDP
- local($len) = $bytes[$base + 1] - ($hl << 1);
- $hs += $len;
- $hs += $bytes[$base + 6]; # source address
- $hs += $bytes[$base + 7];
- $hs += $bytes[$base + 8]; # destination address
- $hs += $bytes[$base + 9];
- local($udpsum) = $hs;
+ local($hl) = $_[1];
+ local($hs) = $_[2];
if ($bytes[$base + 1] > ($cnt - $base) * 2) {
print " UDP: missing data(1)";
@@ -168,7 +148,7 @@ sub udpcheck {
printf " UDP: => %x", $hs;
} elsif ($hs != 0) {
$bytes[$udpat + 3] = 0;
- $hs2 = &dosum($udpsum, $udpat, $cnt);
+ local($hs2) = &dosum($udpsum, $udpat, $cnt);
$bytes[$udpat + 3] = $osum;
printf " UDP: (%x) %x != %x", $hs, $osum, $hs2;
} else {
@@ -176,6 +156,156 @@ sub udpcheck {
}
}
+sub ipv6check {
+ local($base) = $_[0];
+ $hl = $bytes[$base] / 256;
+ return if (($hl >> 4) != 6); # IPv4 ?
+ $hl = 40;
+
+ print " IPv6($base): ok ";
+
+ if (($bytes[$base + 3] >> 8) == 6) {
+ &tcpcheck6($base);
+ } elsif (($bytes[$base + 3] >> 8) == 58) {
+ &icmpcheck6($base);
+ }
+ print "\n";
+}
+
+sub tcpcheck6 {
+ local($base) = $_[0];
+ local($hl) = $bytes[$base] / 256;
+ return if (($hl >> 4) != 6);
+ $hl = 20;
+
+ local($hs) = 6; # TCP
+ local($len) = $bytes[$base + 2];
+ $hs += $len;
+ $hs += &ipv6addrsum($base);
+
+ &tcpcommon($base, $hl, $hs, 2);
+}
+
+sub icmpcheck6 {
+ local($base) = $_[0];
+ local($hl) = 20;
+
+ local($hs) = 58; # ICMP6
+ local($len) = $bytes[$base + 2];
+ $hs += $len;
+ $hs += &ipv6addrsum($base);
+
+ local($len) = $bytes[$base + 1] - ($hl << 1);
+
+ if ($bytes[$base + 2] > ($cnt - $base) * 2) {
+ print " ICMPv6: missing data(1)";
+ return;
+ } elsif ($bytes[$base + 2] < 8) {
+ print " ICMPv6: missing data(2)";
+ return;
+ }
+
+ local($osum) = $bytes[$base + $hl + 1];
+ $bytes[$base + $hl + 1] = 0;
+ local($hs2) = &dosum($hs, $base + $hl, $cnt);
+ $bytes[$base + $hl + 1] = $osum;
+
+ if ($osum != $hs2) {
+ printf " ICMPv6: (%x) %x != %x", $hs, $osum, $hs2;
+ } else {
+ print " ICMPv6: ok";
+ }
+# if ($base == 0) {
+# $type = $bytes[$hl] >> 8;
+# if ($type == 3 || $type == 4 || $type == 5 ||
+# $type == 11 || $type == 12) {
+# &ipv4check($hl + 4);
+# }
+# }
+}
+
+sub ipv4check {
+ local($base) = $_[0];
+ $hl = $bytes[$base] / 256;
+ if (($hl >> 4) == 6) {
+ &ipv6check($_[0]);
+ }
+ return if (($hl >> 4) != 4); # IPv4 ?
+ $hl &= 0xf;
+ $hl <<= 1; # get the header length in 16bit words
+
+ $hs = &dosum(0, $base, $base + $hl);
+ $osum = $bytes[$base + 5];
+
+ if ($hs != 0) {
+ $bytes[$base + 5] = 0;
+ $hs2 = &dosum(0, $base, $base + $hl);
+ $bytes[$base + 5] = $osum;
+ printf " IPv4: ($hl,%x) %x != %x", $hs, $osum, $hs2;
+ } else {
+ print " IPv4($base): ok ";
+ }
+
+ #
+ # Recognise TCP & UDP and calculate checksums for each of these.
+ #
+ if (($bytes[$base + 4] & 0xff) == 4) {
+ &ipv4check($hl);
+ }
+ if (($bytes[$base + 4] & 0xff) == 6) {
+ &tcpcheck($base);
+ }
+
+ if (($bytes[$base + 4] & 0xff) == 17) {
+ &udpcheck($base);
+ }
+
+ if (($bytes[$base + 4] & 0xff) == 1) {
+ &icmpcheck($base);
+ }
+ if ($base == 0) {
+ print "\n";
+ }
+}
+
+sub tcpcheck {
+ local($base) = $_[0];
+ local($hl) = $bytes[$base] / 256;
+ return if (($hl >> 4) != 4);
+ if ($bytes[$base + 3] & 0x3fff) {
+ print " TCP: fragment";
+ return;
+ }
+ $hl &= 0xf;
+ $hl <<= 1;
+
+ local($hs) = 6; # TCP
+ local($len) = $bytes[$base + 1] - ($hl << 1);
+ $hs += $len;
+ $hs += &ipv4addrsum($base);
+
+ &tcpcommon($base, $hl, $hs, 1);
+}
+
+sub udpcheck {
+ local($base) = $_[0];
+ local($hl) = $bytes[0] / 256;
+ return if (($hl >> 4) != 4);
+ if ($bytes[$base + 3] & 0x3fff) {
+ print " UDP: fragment";
+ return;
+ }
+ $hl &= 0xf;
+ $hl <<= 1;
+
+ local($hs) = 17; # UDP
+ local($len) = $bytes[$base + 1] - ($hl << 1);
+ $hs += $len;
+ $hs += &ipv4addrsum($base);
+ local($udpsum) = $hs;
+ &udpcommon($base, $hl, $hs);
+}
+
sub icmpcheck {
local($base) = $_[0];
local($hl) = $bytes[$base + 0] / 256;
OpenPOWER on IntegriCloud