How to implement local ICMPv6 neighbor discovery? - networking

I'm implementing my own IPv6 networking stack and am having problems getting ICMPv6 neighbor discovery to work. The stack works by capturing packets of an existing interface, picking out the ones addressed to it and sending out new packets from the "virtual" address of the stack.
To test this I have an Ubuntu machine, with an LXC container used as a testing client to send traffic from. The Ubuntu host has the following bridge interface for LXC containers:
ubuntu:~$ ifconfig
...
lxcbr0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.3.1 netmask 255.255.255.0 broadcast 0.0.0.0
inet6 fe80::216:3eff:fe00:0 prefixlen 64 scopeid 0x20<link>
ether 00:16:3e:00:00:00 txqueuelen 1000 (Ethernet)
RX packets 522282 bytes 85867541 (85.8 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 554574 bytes 51636337 (51.6 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
...
The container has the following network interface:
my-continer:~$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.3.40 netmask 255.255.255.0 broadcast 10.0.3.255
inet6 fe80::216:3eff:fe72:dc1c prefixlen 64 scopeid 0x20<link>
ether 00:16:3e:72:dc:1c txqueuelen 1000 (Ethernet)
RX packets 554722 bytes 51647709 (51.6 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 522297 bytes 93181219 (93.1 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
...
If I ping the Ubuntu host from the LXC container, it of course works:
my-continer:~$ sudo tcpdump -i eth0 -nn icmp6 -vv
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
11:56:44.435633 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32) fe80::216:3eff:fe72:dc1c > ff02::1:ff00:0: [icmp6 sum ok] ICMP6, neighbor solicitation, length 32, who has fe80::216:3eff:fe00:0
source link-address option (1), length 8 (1): 00:16:3e:72:dc:1c
0x0000: 0016 3e72 dc1c
11:56:44.435649 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32) fe80::216:3eff:fe00:0 > fe80::216:3eff:fe72:dc1c: [icmp6 sum ok] ICMP6, neighbor advertisement, length 32, tgt is fe80::216:3eff:fe00:0, Flags [solicited, override]
destination link-address option (2), length 8 (1): 00:16:3e:00:00:00
0x0000: 0016 3e00 0000
11:56:44.435652 IP6 (flowlabel 0x4fb04, hlim 64, next-header ICMPv6 (58) payload length: 64) fe80::216:3eff:fe72:dc1c > fe80::216:3eff:fe00:0: [icmp6 sum ok] ICMP6, echo request, seq 1
11:56:44.435660 IP6 (flowlabel 0xbb56b, hlim 64, next-header ICMPv6 (58) payload length: 64) fe80::216:3eff:fe00:0 > fe80::216:3eff:fe72:dc1c: [icmp6 sum ok] ICMP6, echo reply, seq 1
11:56:45.465749 IP6 (flowlabel 0x4fb04, hlim 64, next-header ICMPv6 (58) payload length: 64) fe80::216:3eff:fe72:dc1c > fe80::216:3eff:fe00:0: [icmp6 sum ok] ICMP6, echo request, seq 2
11:56:45.465768 IP6 (flowlabel 0xbb56b, hlim 64, next-header ICMPv6 (58) payload length: 64) fe80::216:3eff:fe00:0 > fe80::216:3eff:fe72:dc1c: [icmp6 sum ok] ICMP6, echo reply, seq 2
11:56:46.490187 IP6 (flowlabel 0x4fb04, hlim 64, next-header ICMPv6 (58) payload length: 64) fe80::216:3eff:fe72:dc1c > fe80::216:3eff:fe00:0: [icmp6 sum ok] ICMP6, echo request, seq 3
11:56:46.490204 IP6 (flowlabel 0xbb56b, hlim 64, next-header ICMPv6 (58) payload length: 64) fe80::216:3eff:fe00:0 > fe80::216:3eff:fe72:dc1c: [icmp6 sum ok] ICMP6, echo reply, seq 3
My own stack is configured with the mac address 0c:22:38:4e:9a:bc and the IPv6 address fe80::216:3eff:fe00:1234.
The implementation is in Erlang, and the code for processing the neighbor solicitation packet looks as follows:
process(#ipv6{headers = [#icmpv6{type = neighbor_solicitation, payload = {IP6, _}}|_]} = Packet, {IP6, Mac}) ->
#ipv6{src = Src} = Packet,
send(#ipv6{
src = IP6,
dst = Src,
next = ?IP_PROTO_ICMPv6,
hlim = 16#FF,
headers = [
{icmpv6, #icmpv6{
type = neighbor_advertisement,
code = 0,
payload = {IP6, #{source_link_layer_addr => Mac}}
}}
]
});
Packet is the incoming neighbor solicitation request and {IP6, Mac} is the IPv6 address and mac address that the stack has been configured with.
When pinging it, the packets reach the interface on the host and gets picked up by libpcap. I generate a response to the address resolution but pinging never succeeds:
my-continer:~$ ping6 -I eth0 fe80::216:3eff:fe00:1244
PING fe80::216:3eff:fe00:1244(fe80::216:3eff:fe00:1244) from fe80::216:3eff:fe72:dc1c%eth0 eth0: 56 data bytes
From fe80::216:3eff:fe72:dc1c%eth0 icmp_seq=1 Destination unreachable: Address unreachable
From fe80::216:3eff:fe72:dc1c%eth0 icmp_seq=2 Destination unreachable: Address unreachable
From fe80::216:3eff:fe72:dc1c%eth0 icmp_seq=3 Destination unreachable: Address unreachable
^C
--- fe80::216:3eff:fe00:1244 ping statistics ---
4 packets transmitted, 0 received, +3 errors, 100% packet loss, time 3065ms
The trace shows that the neighbor advertisement packets reach the container:
my-continer:~$ sudo tcpdump -i eth0 -nn icmp6 -vv
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
12:04:23.751427 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32) fe80::216:3eff:fe72:dc1c > ff02::1:ff00:1234: [icmp6 sum ok] ICMP6, neighbor solicitation, length 32, who has fe80::216:3eff:fe00:1234
source link-address option (1), length 8 (1): 00:16:3e:72:dc:1c
0x0000: 0016 3e72 dc1c
12:04:23.753662 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32) fe80::216:3eff:fe00:1234 > fe80::216:3eff:fe72:dc1c: [icmp6 sum ok] ICMP6, neighbor advertisement, length 32, tgt is fe80::216:3eff:fe00:1234, Flags [solicited, override]
source link-address option (1), length 8 (1): 0c:22:38:4e:9a:bc
0x0000: 0c22 384e 9abc
12:04:24.761850 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32) fe80::216:3eff:fe72:dc1c > ff02::1:ff00:1234: [icmp6 sum ok] ICMP6, neighbor solicitation, length 32, who has fe80::216:3eff:fe00:1234
source link-address option (1), length 8 (1): 00:16:3e:72:dc:1c
0x0000: 0016 3e72 dc1c
12:04:24.765901 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32) fe80::216:3eff:fe00:1234 > fe80::216:3eff:fe72:dc1c: [icmp6 sum ok] ICMP6, neighbor advertisement, length 32, tgt is fe80::216:3eff:fe00:1234, Flags [solicited, override]
source link-address option (1), length 8 (1): 0c:22:38:4e:9a:bc
0x0000: 0c22 384e 9abc
12:04:25.786994 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32) fe80::216:3eff:fe72:dc1c > ff02::1:ff00:1234: [icmp6 sum ok] ICMP6, neighbor solicitation, length 32, who has fe80::216:3eff:fe00:1234
source link-address option (1), length 8 (1): 00:16:3e:72:dc:1c
0x0000: 0016 3e72 dc1c
12:04:25.789413 IP6 (hlim 255, next-header ICMPv6 (58) payload length: 32) fe80::216:3eff:fe00:1234 > fe80::216:3eff:fe72:dc1c: [icmp6 sum ok] ICMP6, neighbor advertisement, length 32, tgt is fe80::216:3eff:fe00:1234, Flags [solicited, override]
source link-address option (1), length 8 (1): 0c:22:38:4e:9a:bc
0x0000: 0c22 384e 9abc
They look identical to the ones sent to and from the real interface, except for the addresses themselves.
Checking the routing table shows that the address resolution for the virtual address didn't work for some reason:
my-continer:~$ sudo ip -6 neigh
fe80::216:3eff:fe00:0 dev eth0 lladdr 00:16:3e:00:00:00 STALE
fe80::216:3eff:fe00:1234 dev eth0 FAILED
What is the reason for the failed neighbor discovery here? What is missing in my implementation of the ICMPv6 protocol to make the container accept the virtual address as a valid route?

Related

Why are both #seq & #ack setting 1 in the last ACK packet in 3-way-handshake?

I'm wondering why the third packet has been set seq=1 and ack=1 in 3-way-handshake.
IP (tos 0x10, ttl 62, id 0, offset 0, flags [DF], proto TCP (6), length 64)
172.17.150.X.63996 > 172.17.150.Y.1234: Flags [S], cksum 0x9b6f (correct), seq 2029035340, win 65535, options [mss 1194,nop,wscale 6,nop,nop,TS val 3650496220 ecr 0,sackOK,eol], length 0
IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
172.17.150.Y.1234 > 172.17.150.X.63996: Flags [S.], cksum 0x8546 (incorrect -> 0xec39), seq 1295300764, ack 2029035341, win 65160, options [mss 1460,sackOK,TS val 2906721667 ecr 3650496220,nop,wscale 7], length 0
IP (tos 0x10, ttl 62, id 0, offset 0, flags [DF], proto TCP (6), length 52)
172.17.150.X.63996 > 172.17.150.Y.1234: Flags [.], cksum 0x1184 (correct), seq 1, ack 1, win 2050, options [nop,nop,TS val 3650496229 ecr 2906721667], length 0
I found that tcpdump calculates sequence numbers and acknowledge numbers in TCP packets as relative. I can see the numbers in flow as absolute by using the -S option with tcpdump.

QNetworkInterface returns duplicate addresses

Qt5.9.2 for RPi3.
Here the current target scenario:
# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.167 netmask 255.255.0.0 broadcast 192.168.255.255
inet6 fd00::b465:a62:a349:a7a5 prefixlen 64 scopeid 0x0<global>
inet6 fe80::dbfe:16c3:a5cd:9509 prefixlen 64 scopeid 0x20<link>
ether b8:27:eb:22:00:43 txqueuelen 1000 (Ethernet)
RX packets 338 bytes 44737 (43.6 KiB)
RX errors 0 dropped 1 overruns 0 frame 0
TX packets 238 bytes 27565 (26.9 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 40 bytes 8560 (8.3 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 40 bytes 8560 (8.3 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
wlan0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.179 netmask 255.255.0.0 broadcast 192.168.255.255
inet6 fd00::2eed:5f16:9646:fe07 prefixlen 64 scopeid 0x0<global>
inet6 fe80::c460:6252:ee34:8695 prefixlen 64 scopeid 0x20<link>
ether 00:c6:b1:8f:a1:38 txqueuelen 1000 (Ethernet)
RX packets 149 bytes 45709 (44.6 KiB)
RX errors 0 dropped 97 overruns 0 frame 0
TX packets 106 bytes 17632 (17.2 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Here my code that should retrieve the IPv4 addresses:
const QHostAddress &localhost = QHostAddress(QHostAddress::LocalHost);
for (const QNetworkInterface &interface: QNetworkInterface::allInterfaces())
{
QString name = interface.name();
for (const QHostAddress &address: interface.allAddresses())
{
if (address.protocol() == QAbstractSocket::IPv4Protocol && address != localhost && (interface.flags() & QNetworkInterface::IsRunning))
qDebug() << name << address << interface.flags();
}
}
Here the output:
"lo" QHostAddress("192.168.1.167") QFlags(0x1|0x2|0x8)
"lo" QHostAddress("192.168.1.179") QFlags(0x1|0x2|0x8)
"eth0" QHostAddress("192.168.1.167") QFlags(0x1|0x2|0x4|0x20)
"eth0" QHostAddress("192.168.1.179") QFlags(0x1|0x2|0x4|0x20)
"wlan0" QHostAddress("192.168.1.167") QFlags(0x1|0x2|0x4|0x20)
"wlan0" QHostAddress("192.168.1.179") QFlags(0x1|0x2|0x4|0x20)
Instead, according to ifconfig, I'm expecting only:
"eth0" QHostAddress("192.168.1.167") QFlags(0x1|0x2|0x4|0x20)
"wlan0" QHostAddress("192.168.1.179") QFlags(0x1|0x2|0x4|0x20)
Is my code wrong?
Cause
As the documentation of QNetworkInterface::allInterfaces says:
This convenience function returns all IP addresses found on the host machine.
Note: The emphasis is mine.
This means, that with two interfaces, your code will essentially loop through the addresses twice.
Solution
Use QNetworkInterface::addressEntries instead. Then use QNetworkAddressEntry::ip to obtain the information you need.
Example
Here is an example implementation of the proposed solution:
for (auto interface : QNetworkInterface::allInterfaces()) {
for (auto address : interface.addressEntries()) {
const QHostAddress &ip(address.ip());
if (!ip.isLoopback() && (ip.protocol() == QAbstractSocket::IPv4Protocol) && (interface.flags() & QNetworkInterface::IsRunning))
qDebug() << interface.humanReadableName() << ip.toString();
}
}

What the tcpdump result mean?

I can curl the site on my local, and on my production server.
But I can not curl the site on my staging server.
And On my staging server, I can curl other sites.
the tcpdump result is
2018-03-31 01:16:34.453036 IP (tos 0x0, ttl 64, id 8852, offset 0, flags [DF], proto TCP (6), length 60)
10.11.112.108.59187 > 192.175.110.124.443: Flags [S], cksum 0xa9d1 (incorrect -> 0x11ef), seq 1631407811, win 29200, options [mss 1460,sackOK,TS val 353791063 ecr 0,nop,wscale 8], length 0
2018-03-31 01:16:35.452914 IP (tos 0x0, ttl 64, id 8853, offset 0, flags [DF], proto TCP (6), length 60)
10.11.112.108.59187 > 192.175.110.124.443: Flags [S], cksum 0xa9d1 (incorrect -> 0x10f5), seq 1631407811, win 29200, options [mss 1460,sackOK,TS val 353791313 ecr 0,nop,wscale 8], length 0
2018-03-31 01:16:37.456926 IP (tos 0x0, ttl 64, id 8854, offset 0, flags [DF], proto TCP (6), length 60)
10.11.112.108.59187 > 192.175.110.124.443: Flags [S], cksum 0xa9d1 (incorrect -> 0x0f00), seq 1631407811, win 29200, options [mss 1460,sackOK,TS val 353791814 ecr 0,nop,wscale 8], length 0
2018-03-31 01:16:41.464918 IP (tos 0x0, ttl 64, id 8855, offset 0, flags [DF], proto TCP (6), length 60)
10.11.112.108.59187 > 192.175.110.124.443: Flags [S], cksum 0xa9d1 (incorrect -> 0x0b16), seq 1631407811, win 29200, options [mss 1460,sackOK,TS val 353792816 ecr 0,nop,wscale 8], length 0
2018-03-31 01:16:49.480947 IP (tos 0x0, ttl 64, id 8856, offset 0, flags [DF], proto TCP (6), length 60)
10.11.112.108.59187 > 192.175.110.124.443: Flags [S], cksum 0xa9d1 (incorrect -> 0x0342), seq 1631407811, win 29200, options [mss 1460,sackOK,TS val 353794820 ecr 0,nop,wscale 8], length 0
2018-03-31 01:17:05.528931 IP (tos 0x0, ttl 64, id 8857, offset 0, flags [DF], proto TCP (6), length 60)
10.11.112.108.59187 > 192.175.110.124.443: Flags [S], cksum 0xa9d1 (incorrect -> 0xf395), seq 1631407811, win 29200, options [mss 1460,sackOK,TS val 353798832 ecr 0,nop,wscale 8], length 0
SO I want to know what happened ? what should I do?
You can see Flags [S] in each packet. This is the TCP SYN packet, which tries to establish a connection. There is no response to it. This implies that there is a firewall rule somewhere between the client and the server which is blocking the connection. The firewall could be a network device, or could be software running on the server.

TCP sequence and ack values for TCP SYN and TCP RST

I'm sending a few TCP SYN packets to get TCP RST's back. In order to identify each probe, I include a counter in the TCP sequence field. I noticed the following:
when the sequence numbers in SYN probes are 0, 1, 2, 3..., RST messages have ack=1, 2, 3, 4..., that is ack=syn_seq+1:
12:17:27.181993 IP X.X.X.X.10104 > Y.Y.Y.10114: Flags [S], seq 0, win
8192, length 0 12:17:27.182008 IP Y.Y.Y.Y.10114 > X.X.X.X.10104: Flags
[R.], seq 0, ack 1, win 0, length 0 12:17:27.683148 IP X.X.X.X.10104 >
Y.Y.Y.Y.10114: Flags [S], seq 1, win 8192, length 0 12:17:27.683156 IP
Y.Y.Y.Y.10114 > X.X.X.X.10104: Flags [R.], seq 0, ack 2, win 0, length
0 12:17:28.184140 IP X.X.X.X.10104 > Y.Y.Y.Y.10114: Flags [S], seq 2,
win 8192, length 0 12:17:28.184147 IP Y.Y.Y.Y.10114 > X.X.X.X.10104:
Flags [R.], seq 0, ack 3, win 0, length 0 12:17:28.684993 IP
X.X.X.X.10104 > Y.Y.Y.Y.10114: Flags [S], seq 3, win 8192, length 0
12:17:28.685000 IP Y.Y.Y.Y.10114 > X.X.X.X.10104: Flags [R.], seq 0,
ack 4, win 0, length 0
on the other hand, when my probes start with a seq > 1, the first rst will have ack=syn_seq+1 as usual,
but then the following rst's will have ack=2,3,4... regardless of the sequence value of the probes:
12:11:25.274636 IP X.X.X.X.59150 > Y.Y.Y.Y.59160: Flags [S], seq
299, win 8192, length 0 12:11:25.274649 IP Y.Y.Y.Y.59160 >
X.X.X.X.59150: Flags [R.], seq 0, ack 300, win 0, length 0
12:11:25.775218 IP X.X.X.X.59150 > Y.Y.Y.Y.59160: Flags [S], seq
300, win 8192, length 0 12:11:25.775226 IP Y.Y.Y.Y.59160 >
X.X.X.X.59150: Flags [R.], seq 0, ack 2, win 0, length 0
12:11:26.276324 IP X.X.X.X.59150 > Y.Y.Y.Y.59160: Flags [S], seq
301, win 8192, length 0 12:11:26.276332 IP Y.Y.Y.Y.59160 >
X.X.X.X.59150: Flags [R.], seq 0, ack 3, win 0, length 0
12:11:26.776940 IP X.X.X.X.59150 > Y.Y.Y.Y.59160: Flags [S], seq
302, win 8192, length 0 12:11:26.776948 IP Y.Y.Y.Y.59160 >
X.X.X.X.59150: Flags [R.], seq 0, ack 4, win 0, length 0
Is this the expected behaviour?
Each side of a TCP session starts out with a (relative) sequence number of zero.
Likewise, the acknowledgement number is also zero, as there is not yet a complementary side of the conversation to acknowledge.
The server responds to the client with a sequence number of zero, as this is its first packet in this TCP session, and a relative acknowledgement number of 1.
The acknowledgement number is set to 1 to indicate the receipt of the client's SYN flag in packet.
Now to your case:
Sequence Numbers got a dual role:
If the SYN flag is set (1), then this is the initial sequence number.
The sequence number of the actual first data byte and the acknowledged
number in the corresponding ACK are then this sequence number plus 1.
If the SYN flag is clear (0), then this is the accumulated sequence
number of the first data byte of this segment for the current session.
Blockquoted part copied from Wikipedia.
So, your SYN flag is probably 0.
If so, that is the default behaviour.
Ok, there was actually no real problem. When I inspected the packets with Wireshark and looked at the real bits in the packet, the ack value of each RST packet was set to seq_of_syn + 1, as usual.
tcpdump was simply using a relative ack number in the output. That's all.

Tcpdump: Sequence and acknowledgement number mismatch with libpcap

I am writing an app where I am printing TCP sequence and ack numbers.
I ran tcpdump on the same box and the numbers do not match. Here is my
code, all headers and structures are from sniffex.c
void
got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet)
{
static int count = 1; /* packet counter */
/* declare pointers to packet headers */
const struct sniff_ethernet *ethernet; /* The ethernet header [1] */
const struct sniff_ip *ip; /* The IP header */
const struct sniff_tcp *tcp; /* The TCP header */
int size_ip;
int size_tcp;
int size_payload;
count++;
/* define ethernet header */
ethernet = (struct sniff_ethernet*)(packet);
/* define/compute ip header offset */
ip = (struct sniff_ip*)(packet + SIZE_ETHERNET);
size_ip = IP_HL(ip)*4;
if (size_ip < 20) {
printf(" * Invalid IP header length: %u bytes\n", size_ip);
return;
}
/* determine protocol */
switch(ip->ip_p) {
case IPPROTO_TCP:
printf(" Protocol: TCP\n");
break;
case IPPROTO_UDP:
printf(" Protocol: UDP\n");
return;
case IPPROTO_ICMP:
printf(" Protocol: ICMP\n");
return;
case IPPROTO_IP:
printf(" Protocol: IP\n");
return;
default:
printf(" Protocol: unknown\n");
return;
}
/* define/compute tcp header offset */
tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip);
size_tcp = TH_OFF(tcp)*4;
if (size_tcp < 20) {
printf(" * Invalid TCP header length: %u bytes\n", size_tcp);
return;
}
std::cout << "Packet# " << count << " S " << tcp->th_seq << " A "
<< tcp->th_ack << "\n";
}
And this prints:
Packet# 2 S 1063936835 A 1371648504
Packet# 3 S 1080714051 A 1975693816
Packet# 4 S 1080714051 A 1975693816
Packet# 5 S 141321027 A 2730734072
Packet# 6 S 2960220995 A 2730734072
Packet# 7 S 1484219203 A 2730734072
Packet# 8 S 8217411 A 2730734072
Packet# 9 S 2827117379 A 2730734072
Packet# 10 S 1351115587 A 2730734072
I ran tcpdump to record a pcap file as:
# sudo tcpdump -n -i eth0 -S -n -w cache.cap 'tcp and src port 80'
And then inspected it with
# sudo tcpdump -S -ttttnnr cache.cap
reading from file cache.cap, link-type EN10MB (Ethernet)
2012-09-30 18:52:58.110398 IP 192.168.122.11.80 > 192.168.122.22.7001:
Flags [S.], seq 1130588735, ack 4172398929, win 14480, options [mss
1460,sackOK,TS val 71597136 ecr 71595534,nop,wscale 3], length 0
2012-09-30 18:52:58.110925 IP 192.168.122.11.80 > 192.168.122.22.7001:
Flags [.], ack 4172399221, win 1944, options [nop,nop,TS val 71597136
ecr 71595534], length 0
2012-09-30 18:52:58.116146 IP 192.168.122.11.80 > 192.168.122.22.7001:
Flags [P.], seq 1130588736:1130589192, ack 4172399221, win 1944,
options [nop,nop,TS val 71597137 ecr 71595534], length 456
2012-09-30 18:52:58.173321 IP 192.168.122.11.80 > 192.168.122.22.7001:
Flags [.], seq 1130589192:1130590640, ack 4172399522, win 2078,
options [nop,nop,TS val 71597152 ecr 71595549], length 1448
2012-09-30 18:52:58.173388 IP 192.168.122.11.80 > 192.168.122.22.7001:
Flags [.], seq 1130590640:1130592088, ack 4172399522, win 2078,
options [nop,nop,TS val 71597152 ecr 71595549], length 1448
2012-09-30 18:52:58.173517 IP 192.168.122.11.80 > 192.168.122.22.7001:
Flags [.], seq 1130592088:1130593536, ack 4172399522, win 2078,
options [nop,nop,TS val 71597152 ecr 71595549], length 1448
2012-09-30 18:52:58.173583 IP 192.168.122.11.80 > 192.168.122.22.7001:
Flags [.], seq 1130593536:1130594984, ack 4172399522, win 2078,
options [nop,nop,TS val 71597152 ecr 71595549], length 1448
2012-09-30 18:52:58.173620 IP 192.168.122.11.80 > 192.168.122.22.7001:
Flags [.], seq 1130594984:1130596432, ack 4172399522, win 2078,
options [nop,nop,TS val 71597152 ecr 71595549], length 1448
2012-09-30 18:52:58.173656 IP 192.168.122.11.80 > 192.168.122.22.7001:
Flags [.], seq 1130596432:1130597880, ack 4172399522, win 2078,
options [nop,nop,TS val 71597152 ecr 71595549], length 1448
The sequence and ack numbers do not match. What am I missing here?
In my application, the filter is same 'tcp and src port 80'
EDIT
I changed
std::cout << "Packet# " << count << " S " << tcp->th_seq << " A "
<< tcp->th_ack << "\n";
to
std::cout << "Packet# " << count << " S " << ntohl(tcp->th_seq) << " A "
<< ntohl(tcp->th_ack) << "\n";
Now the output is
Packet# 2 S 1384921720 A 3111642711
Packet# 3 S 1384921721 A 3111643003
Packet# 4 S 1384921721 A 3111643003
Packet# 5 S 1384922177 A 3111643304
Packet# 6 S 1384923625 A 3111643304
Packet# 7 S 1384925073 A 3111643304
Packet# 8 S 1384926521 A 3111643304
Packet# 9 S 1384927969 A 3111643304
Packet# 10 S 1384929417 A 3111643304
Still does not match
You're only recording half the traffic, i.e. in one direction. The ACKs are for the part you aren't recording. Try a filter that includes destination port 80.

Resources