Loading src/main.c +51 −32 Original line number Diff line number Diff line Loading @@ -400,6 +400,10 @@ receive_thread(struct Masscan *masscan, usecs); } LOG(1, "%u.%u.%u.%u - ackno=0x%08x flags=%02x\n", (ip_them>>24)&0xff, (ip_them>>16)&0xff, (ip_them>>8)&0xff, (ip_them>>0)&0xff, seqno_me, TCP_FLAGS(px, parsed.transport_offset)); /* If recording banners, create a new "TCP Control Block (TCB)" */ if (tcpcon) { Loading @@ -412,7 +416,9 @@ receive_thread(struct Masscan *masscan, if (TCP_IS_SYNACK(px, parsed.transport_offset)) { if (syn_hash(ip_them, parsed.port_src) != seqno_me - 1) { LOG(1, "bad packet: ackno=0x%08x expected=0x%08x\n", seqno_me-1, syn_hash(ip_them, parsed.port_src)); LOG(1, "%u.%u.%u.%u - bad cookie: ackno=0x%08x expected=0x%08x\n", (ip_them>>24)&0xff, (ip_them>>16)&0xff, (ip_them>>8)&0xff, (ip_them>>0)&0xff, seqno_me-1, syn_hash(ip_them, parsed.port_src)); continue; } Loading Loading @@ -443,7 +449,7 @@ receive_thread(struct Masscan *masscan, /* If this is a FIN, handle that. Note that ACK + payload + FIN * can come together */ if (TCP_IS_FIN(px, parsed.transport_offset)) { tcpcon_handle(tcpcon, tcb, TCP_WHAT_FIN, 0, 0, tcpcon_handle(tcpcon, tcb, TCP_WHAT_FIN, 0, seqno_them, secs, usecs); } Loading @@ -453,11 +459,21 @@ receive_thread(struct Masscan *masscan, secs, usecs); } } else if (TCP_IS_FIN(px, parsed.transport_offset)) { /* TODO: we ought to send FIN-ACK in response */ /* * NO TCB! * This happens when we've sent a FIN, deleted our connection, * but the other side didn't get the packet. */ tcpcon_send_FIN( tcpcon, ip_me, ip_them, parsed.port_dst, parsed.port_src, seqno_them, seqno_me); } } if (TCP_IS_SYNACK(px, parsed.transport_offset)) { /* figure out the status */ status = Port_Unknown; if ((px[parsed.transport_offset+13] & 0x2) == 0x2) Loading @@ -467,7 +483,9 @@ receive_thread(struct Masscan *masscan, /* verify: syn-cookies */ if (syn_hash(ip_them, parsed.port_src) != seqno_me - 1) { LOG(1, "bad packet: ackno=0x%08x expected=0x%08x\n", seqno_me-1, syn_hash(ip_them, parsed.port_src)); LOG(1, "%u.%u.%u.%u - bad cookie: ackno=0x%08x expected=0x%08x\n", (ip_them>>24)&0xff, (ip_them>>16)&0xff, (ip_them>>8)&0xff, (ip_them>>0)&0xff, seqno_me-1, syn_hash(ip_them, parsed.port_src)); continue; } Loading @@ -490,6 +508,7 @@ receive_thread(struct Masscan *masscan, px[parsed.ip_offset + 8] /* ttl */ ); } } LOG(1, "end receive thread\n"); Loading src/proto-tcp.c +49 −6 Original line number Diff line number Diff line Loading @@ -99,7 +99,7 @@ tcpcon_timeouts(struct TCP_ConnectionTable *tcpcon, unsigned secs, unsigned usec * the timeout, leaving behind stale ones that should be ignored * in deference to the newer ones */ if (tcb->counter != e.counter) { LOG(1, "%u.%u.%u.%u: stale counter: event=%u tcb=%u\n", LOG(15, "%u.%u.%u.%u: stale counter: event=%u tcb=%u\n", (unsigned char)(tcb->ip_them>>24), (unsigned char)(tcb->ip_them>>16), (unsigned char)(tcb->ip_them>> 8), Loading Loading @@ -315,6 +315,7 @@ tcpcon_lookup_tcb( return tcb; } /*************************************************************************** ***************************************************************************/ void Loading Loading @@ -372,6 +373,29 @@ tcpcon_send_packet( } } void tcpcon_send_FIN( struct TCP_ConnectionTable *tcpcon, unsigned ip_me, unsigned ip_them, unsigned port_me, unsigned port_them, uint32_t seqno_them, uint32_t ackno_them) { struct TCP_Control_Block tcb; memset(&tcb, 0, sizeof(tcb)); tcb.ip_me = ip_me; tcb.ip_them = ip_them; tcb.port_me = (unsigned short)port_me; tcb.port_them = (unsigned short)port_them; tcb.seqno_me = ackno_them; tcb.ackno_me = seqno_them + 1; tcb.seqno_them = seqno_them + 1; tcb.ackno_them = ackno_them; tcpcon_send_packet(tcpcon, &tcb, 0x11, 0, 0); } /*************************************************************************** * Parse the information we get from the server we are scanning. Typical * examples are SSH banners, FTP banners, or the response from HTTP Loading Loading @@ -447,6 +471,12 @@ handle_ack( uint32_t ackno) { LOG(4, "%u.%u.%u.%u - %u-sending, %u-reciving\n", (tcb->ip_them>>24)&0xFF, (tcb->ip_them>>16)&0xFF, (tcb->ip_them>>8)&0xFF, (tcb->ip_them>>0)&0xFF, tcb->seqno_me - ackno, ackno - tcb->ackno_them ); /* Normal: just discard repeats */ if (ackno == tcb->ackno_them) { return; Loading @@ -455,8 +485,10 @@ handle_ack( /* Make sure this isn't a duplicate ACK from past * WRAPPING of 32-bit arithmetic happens here */ if (ackno - tcb->ackno_them > 10000) { LOG(4, "tcb: ackno from pact: " LOG(4, "%u.%u.%u.%u - " "tcb: ackno from past: " "old ackno = 0x%08x, this ackno = 0x%08x\n", (tcb->ip_them>>24)&0xFF, (tcb->ip_them>>16)&0xFF, (tcb->ip_them>>8)&0xFF, (tcb->ip_them>>0)&0xFF, tcb->ackno_me, ackno); return; } Loading @@ -464,8 +496,10 @@ handle_ack( /* Make sure this isn't invalid ACK from the future * WRAPPING of 32-bit arithmatic happens here */ if (tcb->seqno_me - ackno > 10000) { LOG(4, "tcb: ackno from future: " LOG(4, "%u.%u.%u.%u - " "tcb: ackno from future: " "my seqno = 0x%08x, their ackno = 0x%08x\n", (tcb->ip_them>>24)&0xFF, (tcb->ip_them>>16)&0xFF, (tcb->ip_them>>8)&0xFF, (tcb->ip_them>>0)&0xFF, tcb->seqno_me, ackno); return; } Loading @@ -484,7 +518,7 @@ tcpcon_handle(struct TCP_ConnectionTable *tcpcon, struct TCP_Control_Block *tcb, if (tcb == NULL) return; LOG(10, "%u.%u.%u.%u - %s : %s \n", LOG(10, "%u.%u.%u.%u =%s : %s \n", (unsigned char)(tcb->ip_them>>24), (unsigned char)(tcb->ip_them>>16), (unsigned char)(tcb->ip_them>> 8), Loading Loading @@ -555,11 +589,15 @@ tcpcon_handle(struct TCP_ConnectionTable *tcpcon, struct TCP_Control_Block *tcb, } /* send request */ x_len = strlen((const char*)x); tcpcon_send_packet(tcpcon, tcb, 0x18, x, x_len); LOG(4, "%u.%u.%u.%u - sending payload %u bytes\n", (tcb->ip_them>>24)&0xFF, (tcb->ip_them>>16)&0xFF, (tcb->ip_them>>8)&0xFF, (tcb->ip_them>>0)&0xFF, x_len); /* Increment our sequence number */ tcb->seqno_me += (uint32_t)x_len; Loading Loading @@ -612,6 +650,7 @@ tcpcon_handle(struct TCP_ConnectionTable *tcpcon, struct TCP_Control_Block *tcb, break; case STATE_READY_TO_SEND<<8 | TCP_WHAT_FIN: tcb->seqno_them = (uint32_t)payload_length + 1; tcpcon_send_packet(tcpcon, tcb, 0x14, /*reset */ 0, 0); Loading Loading @@ -659,11 +698,15 @@ tcpcon_handle(struct TCP_ConnectionTable *tcpcon, struct TCP_Control_Block *tcb, len = tcb->seqno_me - tcb->ackno_them; /* Resend the payload */ tcb->seqno_me -= (tcb->payload_length - len); tcb->seqno_me -= len; tcpcon_send_packet(tcpcon, tcb, 0x18, tcb->payload + tcb->payload_length - len, len); LOG(4, "%u.%u.%u.%u - re-sending payload %u bytes\n", (tcb->ip_them>>24)&0xFF, (tcb->ip_them>>16)&0xFF, (tcb->ip_them>>8)&0xFF, (tcb->ip_them>>0)&0xFF, len); tcb->seqno_me += len; /* */ Loading @@ -685,7 +728,7 @@ tcpcon_handle(struct TCP_ConnectionTable *tcpcon, struct TCP_Control_Block *tcb, case STATE_WAITING_FOR_RESPONSE<<8 | TCP_WHAT_FIN: tcb->seqno_them++; tcb->seqno_them = (uint32_t)payload_length + 1; tcpcon_send_packet(tcpcon, tcb, 0x11, 0, 0); Loading src/proto-tcp.h +11 −0 Original line number Diff line number Diff line Loading @@ -74,4 +74,15 @@ tcpcon_create_tcb( unsigned port_src, unsigned port_dst, unsigned my_seqno, unsigned their_seqno); /** * Acknowledge a FIN even if we've forgotten about the connection */ void tcpcon_send_FIN( struct TCP_ConnectionTable *tcpcon, unsigned ip_me, unsigned ip_them, unsigned port_me, unsigned port_them, uint32_t seqno_them, uint32_t ackno_them); #endif src/rawsock-arp.c +1 −0 Original line number Diff line number Diff line Loading @@ -223,6 +223,7 @@ int arp_response( for (err=1; err; ) { err = rte_ring_sc_dequeue(packet_buffers, (void**)&response); if (err != 0) { LOG(0, "packet buffers empty (should be impossible)\n"); pixie_usleep(100); } } Loading Loading
src/main.c +51 −32 Original line number Diff line number Diff line Loading @@ -400,6 +400,10 @@ receive_thread(struct Masscan *masscan, usecs); } LOG(1, "%u.%u.%u.%u - ackno=0x%08x flags=%02x\n", (ip_them>>24)&0xff, (ip_them>>16)&0xff, (ip_them>>8)&0xff, (ip_them>>0)&0xff, seqno_me, TCP_FLAGS(px, parsed.transport_offset)); /* If recording banners, create a new "TCP Control Block (TCB)" */ if (tcpcon) { Loading @@ -412,7 +416,9 @@ receive_thread(struct Masscan *masscan, if (TCP_IS_SYNACK(px, parsed.transport_offset)) { if (syn_hash(ip_them, parsed.port_src) != seqno_me - 1) { LOG(1, "bad packet: ackno=0x%08x expected=0x%08x\n", seqno_me-1, syn_hash(ip_them, parsed.port_src)); LOG(1, "%u.%u.%u.%u - bad cookie: ackno=0x%08x expected=0x%08x\n", (ip_them>>24)&0xff, (ip_them>>16)&0xff, (ip_them>>8)&0xff, (ip_them>>0)&0xff, seqno_me-1, syn_hash(ip_them, parsed.port_src)); continue; } Loading Loading @@ -443,7 +449,7 @@ receive_thread(struct Masscan *masscan, /* If this is a FIN, handle that. Note that ACK + payload + FIN * can come together */ if (TCP_IS_FIN(px, parsed.transport_offset)) { tcpcon_handle(tcpcon, tcb, TCP_WHAT_FIN, 0, 0, tcpcon_handle(tcpcon, tcb, TCP_WHAT_FIN, 0, seqno_them, secs, usecs); } Loading @@ -453,11 +459,21 @@ receive_thread(struct Masscan *masscan, secs, usecs); } } else if (TCP_IS_FIN(px, parsed.transport_offset)) { /* TODO: we ought to send FIN-ACK in response */ /* * NO TCB! * This happens when we've sent a FIN, deleted our connection, * but the other side didn't get the packet. */ tcpcon_send_FIN( tcpcon, ip_me, ip_them, parsed.port_dst, parsed.port_src, seqno_them, seqno_me); } } if (TCP_IS_SYNACK(px, parsed.transport_offset)) { /* figure out the status */ status = Port_Unknown; if ((px[parsed.transport_offset+13] & 0x2) == 0x2) Loading @@ -467,7 +483,9 @@ receive_thread(struct Masscan *masscan, /* verify: syn-cookies */ if (syn_hash(ip_them, parsed.port_src) != seqno_me - 1) { LOG(1, "bad packet: ackno=0x%08x expected=0x%08x\n", seqno_me-1, syn_hash(ip_them, parsed.port_src)); LOG(1, "%u.%u.%u.%u - bad cookie: ackno=0x%08x expected=0x%08x\n", (ip_them>>24)&0xff, (ip_them>>16)&0xff, (ip_them>>8)&0xff, (ip_them>>0)&0xff, seqno_me-1, syn_hash(ip_them, parsed.port_src)); continue; } Loading @@ -490,6 +508,7 @@ receive_thread(struct Masscan *masscan, px[parsed.ip_offset + 8] /* ttl */ ); } } LOG(1, "end receive thread\n"); Loading
src/proto-tcp.c +49 −6 Original line number Diff line number Diff line Loading @@ -99,7 +99,7 @@ tcpcon_timeouts(struct TCP_ConnectionTable *tcpcon, unsigned secs, unsigned usec * the timeout, leaving behind stale ones that should be ignored * in deference to the newer ones */ if (tcb->counter != e.counter) { LOG(1, "%u.%u.%u.%u: stale counter: event=%u tcb=%u\n", LOG(15, "%u.%u.%u.%u: stale counter: event=%u tcb=%u\n", (unsigned char)(tcb->ip_them>>24), (unsigned char)(tcb->ip_them>>16), (unsigned char)(tcb->ip_them>> 8), Loading Loading @@ -315,6 +315,7 @@ tcpcon_lookup_tcb( return tcb; } /*************************************************************************** ***************************************************************************/ void Loading Loading @@ -372,6 +373,29 @@ tcpcon_send_packet( } } void tcpcon_send_FIN( struct TCP_ConnectionTable *tcpcon, unsigned ip_me, unsigned ip_them, unsigned port_me, unsigned port_them, uint32_t seqno_them, uint32_t ackno_them) { struct TCP_Control_Block tcb; memset(&tcb, 0, sizeof(tcb)); tcb.ip_me = ip_me; tcb.ip_them = ip_them; tcb.port_me = (unsigned short)port_me; tcb.port_them = (unsigned short)port_them; tcb.seqno_me = ackno_them; tcb.ackno_me = seqno_them + 1; tcb.seqno_them = seqno_them + 1; tcb.ackno_them = ackno_them; tcpcon_send_packet(tcpcon, &tcb, 0x11, 0, 0); } /*************************************************************************** * Parse the information we get from the server we are scanning. Typical * examples are SSH banners, FTP banners, or the response from HTTP Loading Loading @@ -447,6 +471,12 @@ handle_ack( uint32_t ackno) { LOG(4, "%u.%u.%u.%u - %u-sending, %u-reciving\n", (tcb->ip_them>>24)&0xFF, (tcb->ip_them>>16)&0xFF, (tcb->ip_them>>8)&0xFF, (tcb->ip_them>>0)&0xFF, tcb->seqno_me - ackno, ackno - tcb->ackno_them ); /* Normal: just discard repeats */ if (ackno == tcb->ackno_them) { return; Loading @@ -455,8 +485,10 @@ handle_ack( /* Make sure this isn't a duplicate ACK from past * WRAPPING of 32-bit arithmetic happens here */ if (ackno - tcb->ackno_them > 10000) { LOG(4, "tcb: ackno from pact: " LOG(4, "%u.%u.%u.%u - " "tcb: ackno from past: " "old ackno = 0x%08x, this ackno = 0x%08x\n", (tcb->ip_them>>24)&0xFF, (tcb->ip_them>>16)&0xFF, (tcb->ip_them>>8)&0xFF, (tcb->ip_them>>0)&0xFF, tcb->ackno_me, ackno); return; } Loading @@ -464,8 +496,10 @@ handle_ack( /* Make sure this isn't invalid ACK from the future * WRAPPING of 32-bit arithmatic happens here */ if (tcb->seqno_me - ackno > 10000) { LOG(4, "tcb: ackno from future: " LOG(4, "%u.%u.%u.%u - " "tcb: ackno from future: " "my seqno = 0x%08x, their ackno = 0x%08x\n", (tcb->ip_them>>24)&0xFF, (tcb->ip_them>>16)&0xFF, (tcb->ip_them>>8)&0xFF, (tcb->ip_them>>0)&0xFF, tcb->seqno_me, ackno); return; } Loading @@ -484,7 +518,7 @@ tcpcon_handle(struct TCP_ConnectionTable *tcpcon, struct TCP_Control_Block *tcb, if (tcb == NULL) return; LOG(10, "%u.%u.%u.%u - %s : %s \n", LOG(10, "%u.%u.%u.%u =%s : %s \n", (unsigned char)(tcb->ip_them>>24), (unsigned char)(tcb->ip_them>>16), (unsigned char)(tcb->ip_them>> 8), Loading Loading @@ -555,11 +589,15 @@ tcpcon_handle(struct TCP_ConnectionTable *tcpcon, struct TCP_Control_Block *tcb, } /* send request */ x_len = strlen((const char*)x); tcpcon_send_packet(tcpcon, tcb, 0x18, x, x_len); LOG(4, "%u.%u.%u.%u - sending payload %u bytes\n", (tcb->ip_them>>24)&0xFF, (tcb->ip_them>>16)&0xFF, (tcb->ip_them>>8)&0xFF, (tcb->ip_them>>0)&0xFF, x_len); /* Increment our sequence number */ tcb->seqno_me += (uint32_t)x_len; Loading Loading @@ -612,6 +650,7 @@ tcpcon_handle(struct TCP_ConnectionTable *tcpcon, struct TCP_Control_Block *tcb, break; case STATE_READY_TO_SEND<<8 | TCP_WHAT_FIN: tcb->seqno_them = (uint32_t)payload_length + 1; tcpcon_send_packet(tcpcon, tcb, 0x14, /*reset */ 0, 0); Loading Loading @@ -659,11 +698,15 @@ tcpcon_handle(struct TCP_ConnectionTable *tcpcon, struct TCP_Control_Block *tcb, len = tcb->seqno_me - tcb->ackno_them; /* Resend the payload */ tcb->seqno_me -= (tcb->payload_length - len); tcb->seqno_me -= len; tcpcon_send_packet(tcpcon, tcb, 0x18, tcb->payload + tcb->payload_length - len, len); LOG(4, "%u.%u.%u.%u - re-sending payload %u bytes\n", (tcb->ip_them>>24)&0xFF, (tcb->ip_them>>16)&0xFF, (tcb->ip_them>>8)&0xFF, (tcb->ip_them>>0)&0xFF, len); tcb->seqno_me += len; /* */ Loading @@ -685,7 +728,7 @@ tcpcon_handle(struct TCP_ConnectionTable *tcpcon, struct TCP_Control_Block *tcb, case STATE_WAITING_FOR_RESPONSE<<8 | TCP_WHAT_FIN: tcb->seqno_them++; tcb->seqno_them = (uint32_t)payload_length + 1; tcpcon_send_packet(tcpcon, tcb, 0x11, 0, 0); Loading
src/proto-tcp.h +11 −0 Original line number Diff line number Diff line Loading @@ -74,4 +74,15 @@ tcpcon_create_tcb( unsigned port_src, unsigned port_dst, unsigned my_seqno, unsigned their_seqno); /** * Acknowledge a FIN even if we've forgotten about the connection */ void tcpcon_send_FIN( struct TCP_ConnectionTable *tcpcon, unsigned ip_me, unsigned ip_them, unsigned port_me, unsigned port_them, uint32_t seqno_them, uint32_t ackno_them); #endif
src/rawsock-arp.c +1 −0 Original line number Diff line number Diff line Loading @@ -223,6 +223,7 @@ int arp_response( for (err=1; err; ) { err = rte_ring_sc_dequeue(packet_buffers, (void**)&response); if (err != 0) { LOG(0, "packet buffers empty (should be impossible)\n"); pixie_usleep(100); } } Loading