aboutsummaryrefslogtreecommitdiffstats
path: root/text2pcap.c
diff options
context:
space:
mode:
authorVasil Velichkov <vvvelichkov@gmail.com>2018-10-29 21:52:06 +0200
committerMichael Mann <mmann78@netscape.net>2018-10-31 02:45:50 +0000
commite67eebb70f1abe36abb91054d5545e40eeeb59e1 (patch)
treef678127b9087e5146c156eb0d3b681bc24e7260c /text2pcap.c
parent5359a97d4383ca75606b6011006f44b040d5b92b (diff)
text2pcap: Fix IPv6 checksum
Add the length field in the IPv6 pseudo header struct and refactor the pseudo headers initialization Change-Id: Ie0490dfba051a1112e465aaa6d03909417b2977e Reviewed-on: https://code.wireshark.org/review/30407 Reviewed-by: Peter Wu <peter@lekensteyn.nl> Petri-Dish: Peter Wu <peter@lekensteyn.nl> Tested-by: Petri Dish Buildbot Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'text2pcap.c')
-rw-r--r--text2pcap.c46
1 files changed, 24 insertions, 22 deletions
diff --git a/text2pcap.c b/text2pcap.c
index 3793ac5295..a56d2ba87d 100644
--- a/text2pcap.c
+++ b/text2pcap.c
@@ -334,11 +334,13 @@ typedef struct {
static hdr_ipv6_t HDR_IPv6;
+/* https://tools.ietf.org/html/rfc2460#section-8.1 */
static struct { /* pseudo header ipv6 for checksum calculation */
struct e_in6_addr src_addr6;
struct e_in6_addr dst_addr6;
- guint32 protocol;
- guint32 zero;
+ guint32 length;
+ guint8 zero[3];
+ guint8 next_header;
} pseudoh6;
@@ -662,6 +664,17 @@ write_current_packet (gboolean cont)
HDR_IP.hdr_checksum = 0;
HDR_IP.hdr_checksum = in_checksum(&HDR_IP, sizeof(HDR_IP));
write_bytes((const char *)&HDR_IP, sizeof(HDR_IP));
+
+ /* initialize pseudo header for checksum calculation */
+ pseudoh.src_addr = HDR_IP.src_addr;
+ pseudoh.dest_addr = HDR_IP.dest_addr;
+ pseudoh.zero = 0;
+ pseudoh.protocol = (guint8) hdr_ip_proto;
+ if (hdr_tcp) {
+ pseudoh.length = g_htons(length - header_length + sizeof(HDR_TCP));
+ } else if (hdr_udp) {
+ pseudoh.length = g_htons(length - header_length + sizeof(HDR_UDP));
+ }
} else if (hdr_ipv6) {
if (memcmp(isInbound ? &hdr_ipv6_dest_addr : &hdr_ipv6_src_addr, &NO_IPv6_ADDRESS, sizeof(ws_in6_addr)))
memcpy(&HDR_IPv6.ip6_src, isInbound ? &hdr_ipv6_dest_addr : &hdr_ipv6_src_addr, sizeof(ws_in6_addr));
@@ -678,18 +691,13 @@ write_current_packet (gboolean cont)
/* initialize pseudo ipv6 header for checksum calculation */
pseudoh6.src_addr6 = HDR_IPv6.ip6_src;
pseudoh6.dst_addr6 = HDR_IPv6.ip6_dst;
- pseudoh6.zero = 0;
- pseudoh6.protocol = (guint8) hdr_ip_proto;
- pseudoh.length = g_htons(length - header_length + sizeof(HDR_UDP));
- }
-
- if (!hdr_ipv6) {
- /* initialize pseudo header for checksum calculation */
- pseudoh.src_addr = HDR_IP.src_addr;
- pseudoh.dest_addr = HDR_IP.dest_addr;
- pseudoh.zero = 0;
- pseudoh.protocol = (guint8) hdr_ip_proto;
- pseudoh.length = g_htons(length - header_length + sizeof(HDR_UDP));
+ memset(pseudoh6.zero, 0, sizeof(pseudoh6.zero));
+ pseudoh6.next_header = (guint8) hdr_ip_proto;
+ if (hdr_tcp) {
+ pseudoh6.length = g_htons(length - header_length + sizeof(HDR_TCP));
+ } else if (hdr_udp) {
+ pseudoh6.length = g_htons(length - header_length + sizeof(HDR_UDP));
+ }
}
/* Write UDP header */
@@ -700,7 +708,7 @@ write_current_packet (gboolean cont)
/* initialize the UDP header */
HDR_UDP.source_port = isInbound ? g_htons(hdr_dest_port): g_htons(hdr_src_port);
HDR_UDP.dest_port = isInbound ? g_htons(hdr_src_port) : g_htons(hdr_dest_port);
- HDR_UDP.length = pseudoh.length;
+ HDR_UDP.length = hdr_ipv6 ? pseudoh6.length : pseudoh.length;
HDR_UDP.checksum = 0;
/* Note: g_ntohs()/g_htons() macro arg may be eval'd twice so calc value before invoking macro */
x16 = hdr_ipv6 ? in_checksum(&pseudoh6, sizeof(pseudoh6)) : in_checksum(&pseudoh, sizeof(pseudoh));
@@ -721,12 +729,6 @@ write_current_packet (gboolean cont)
guint16 x16;
guint32 u;
- /* initialize pseudo header for checksum calculation */
- pseudoh.src_addr = HDR_IP.src_addr;
- pseudoh.dest_addr = HDR_IP.dest_addr;
- pseudoh.zero = 0;
- pseudoh.protocol = (guint8) hdr_ip_proto;
- pseudoh.length = g_htons(length - header_length + sizeof(HDR_TCP));
/* initialize the TCP header */
HDR_TCP.source_port = isInbound ? g_htons(hdr_dest_port): g_htons(hdr_src_port);
HDR_TCP.dest_port = isInbound ? g_htons(hdr_src_port) : g_htons(hdr_dest_port);
@@ -744,7 +746,7 @@ write_current_packet (gboolean cont)
HDR_TCP.window = g_htons(0x2000);
HDR_TCP.checksum = 0;
/* Note: g_ntohs()/g_htons() macro arg may be eval'd twice so calc value before invoking macro */
- x16 = in_checksum(&pseudoh, sizeof(pseudoh));
+ x16 = hdr_ipv6 ? in_checksum(&pseudoh6, sizeof(pseudoh6)) : in_checksum(&pseudoh, sizeof(pseudoh));
u = g_ntohs(x16);
x16 = in_checksum(&HDR_TCP, sizeof(HDR_TCP));
u += g_ntohs(x16);