1 /*
2     TCP connection table
3 */
4 #include "proto-tcp.h"
5 #include <assert.h>
6 #include <ctype.h>
7 #include <stdio.h>
8 #include <stdint.h>
9 #include <stdlib.h>
10 #include <string.h>
11 #include <time.h>
12 #include <stddef.h>
13 #include "syn-cookie.h"
14 #include "event-timeout.h"      /* for tracking future events */
15 #include "rawsock.h"
16 #include "logger.h"
17 #include "templ-pkt.h"
18 #include "pixie-timer.h"
19 #include "stack-queue.h"
20 #include "proto-banner1.h"
21 #include "proto-ssl.h"
22 #include "proto-http.h"
23 #include "proto-smb.h"
24 #include "output.h"
25 #include "string_s.h"
26 #include "main-globals.h"
27 #include "crypto-base64.h"
28 #include "proto-interactive.h"
29 #include "util-malloc.h"
30 #include "scripting.h"
31 #include "versioning.h"
32 
33 
34 
35 /***************************************************************************
36  * A "TCP control block" is what most operating-systems/network-stack
37  * calls the structure that corresponds to a TCP connection. It contains
38  * things like the IP addresses, port numbers, sequence numbers, timers,
39  * and other things.
40  ***************************************************************************/
41 struct TCP_Control_Block
42 {
43     ipaddress ip_me;
44     ipaddress ip_them;
45 
46     unsigned short port_me;
47     unsigned short port_them;
48 
49     uint32_t seqno_me;      /* next seqno I will use for transmit */
50     uint32_t seqno_them;    /* the next seqno I expect to receive */
51     uint32_t ackno_me;
52     uint32_t ackno_them;
53     uint32_t seqno_them_first; /* ipv6-todo */
54 
55     struct TCP_Control_Block *next;
56     struct TimeoutEntry timeout[1];
57 
58     unsigned char ttl;
59     unsigned tcpstate:4;
60     unsigned is_ipv6:1;
61 
62     /** Set to true when the TCB is in-use/allocated, set to zero
63      * when it's about to be deleted soon */
64     unsigned is_active:1;
65 
66     /* If the payload we've sent was dynamically allocated with
67      * malloc() from the heap, in which case we'll have to free()
68      * it. (Most payloads are static memory) */
69     unsigned is_payload_dynamic:1;
70 
71     unsigned established;
72 
73     unsigned short payload_length;
74     time_t when_created;
75     const unsigned char *payload;
76 
77     /*
78      * If Running a script, the thread object
79      */
80     struct ScriptingThread *scripting_thread;
81 
82     struct BannerOutput banout;
83 
84     struct ProtocolState banner1_state;
85 
86     unsigned packet_number;
87 };
88 
89 struct TCP_ConnectionTable {
90     struct TCP_Control_Block **entries;
91     struct TCP_Control_Block *freed_list;
92     unsigned count;
93     unsigned mask;
94     unsigned timeout_connection;
95     unsigned timeout_hello;
96 
97     uint64_t active_count;
98     uint64_t entropy;
99 
100     struct Timeouts *timeouts;
101     struct TemplatePacket *pkt_template;
102     struct stack_t *stack;
103 
104     struct Banner1 *banner1;
105     OUTPUT_REPORT_BANNER report_banner;
106     struct Output *out;
107 
108     struct ScriptingVM *scripting_vm;
109 };
110 
111 enum {
112     STATE_SYN_SENT,
113     //STATE_SYN_RECEIVED,
114     STATE_ESTABLISHED_SEND, /* our own special state, can only send */
115     STATE_ESTABLISHED_RECV, /* our own special state, can only receive */
116     //STATE_CLOSE_WATI,
117     STATE_LAST_ACK,
118     STATE_FIN_WAIT1,
119     STATE_FIN_WAIT2,
120     STATE_CLOSING,
121     STATE_TIME_WAIT,
122 };
123 
124 
125 
126 /***************************************************************************
127  * Process all events, up to the current time, that need timing out.
128  ***************************************************************************/
129 void
tcpcon_timeouts(struct TCP_ConnectionTable * tcpcon,unsigned secs,unsigned usecs)130 tcpcon_timeouts(struct TCP_ConnectionTable *tcpcon, unsigned secs, unsigned usecs)
131 {
132     uint64_t timestamp = TICKS_FROM_TV(secs, usecs);
133 
134     for (;;) {
135         struct TCP_Control_Block *tcb;
136 
137         /*
138          * Get the next event that is older than the current time
139          */
140         tcb = (struct TCP_Control_Block *)timeouts_remove(tcpcon->timeouts,
141                                                           timestamp);
142 
143         /*
144          * If everything up to the current time has already been processed,
145          * then exit this loop
146          */
147         if (tcb == NULL)
148             break;
149 
150         /*
151          * Process this timeout
152          */
153         stack_incoming_tcp(
154             tcpcon,
155             tcb,
156             TCP_WHAT_TIMEOUT,
157             0, 0,
158             secs, usecs,
159             tcb->seqno_them);
160 
161         /* If the TCB hasn't been destroyed, then we need to make sure
162          * there is a timeout associated with it. KLUDGE: here is the problem:
163          * there must ALWAYS be a 'timeout' associated with a TCB, otherwise,
164          * we'll lose track of it and leak memory. In theory, this should be
165          * automatically handled elsewhere, but I have bugs, and it's not,
166          * so I put some code here as a catch-all: if the TCB hasn't been
167          * deleted, but hasn't been inserted back into the timeout system,
168          * then insert it here. */
169         if (tcb->timeout->prev == 0 && tcb->is_active) {
170             timeouts_add(   tcpcon->timeouts,
171                             tcb->timeout,
172                             offsetof(struct TCP_Control_Block, timeout),
173                             TICKS_FROM_TV(secs+2, usecs));
174         }
175     }
176 }
177 
178 /***************************************************************************
179  ***************************************************************************/
180 static int
name_equals(const char * lhs,const char * rhs)181 name_equals(const char *lhs, const char *rhs)
182 {
183     for (;;) {
184         while (*lhs == '-' || *lhs == '.' || *lhs == '_')
185             lhs++;
186         while (*rhs == '-' || *rhs == '.' || *rhs == '_')
187             rhs++;
188         if (*lhs == '\0' && *rhs == '[')
189             return 1; /*arrays*/
190         if (*rhs == '\0' && *lhs == '[')
191             return 1; /*arrays*/
192         if (tolower(*lhs & 0xFF) != tolower(*rhs & 0xFF))
193             return 0;
194         if (*lhs == '\0')
195             return 1;
196         lhs++;
197         rhs++;
198     }
199 }
200 
201 /***************************************************************************
202  * When setting parameters, this will parse integers from the config
203  * parameter strings.
204  ***************************************************************************/
205 static uint64_t
parseInt(const void * vstr,size_t length)206 parseInt(const void *vstr, size_t length)
207 {
208     const char *str = (const char *)vstr;
209     uint64_t result = 0;
210     size_t i;
211 
212     for (i=0; i<length; i++) {
213         result = result * 10 + (str[i] - '0');
214     }
215     return result;
216 }
217 
218 /***************************************************************************
219  * Called at startup, when processing command-line options, to set
220  * parameters specific to TCP processing.
221  ***************************************************************************/
222 void
tcpcon_set_parameter(struct TCP_ConnectionTable * tcpcon,const char * name,size_t value_length,const void * value)223 tcpcon_set_parameter(struct TCP_ConnectionTable *tcpcon,
224                         const char *name,
225                         size_t value_length,
226                         const void *value)
227 {
228     struct Banner1 *banner1 = tcpcon->banner1;
229 
230     /*
231      * You can reset your user-agent here. Whenever I do a scan, I always
232      * reset my user-agent. That's now you know it's not me scanning
233      * you on the open Internet -- I would never use the default user-agent
234      * string built into masscan
235      */
236     if (name_equals(name, "http-user-agent")) {
237         banner_http.hello_length = http_change_field(
238                                 (unsigned char**)&banner_http.hello,
239                                 (unsigned)banner_http.hello_length,
240                                 "User-Agent:",
241                                 (const unsigned char *)value,
242                                 (unsigned)value_length);
243         return;
244     }
245 
246     if (name_equals(name, "timeout") || name_equals(name, "connection-timeout")) {
247         uint64_t n = parseInt(value, value_length);
248         tcpcon->timeout_connection = (unsigned)n;
249         LOG(1, "TCP connection-timeout = %u\n", tcpcon->timeout_connection);
250         return;
251     }
252     if (name_equals(name, "hello-timeout")) {
253         uint64_t n = parseInt(value, value_length);
254         tcpcon->timeout_hello = (unsigned)n;
255         LOG(1, "TCP hello-timeout = \"%.*s\"\n", (int)value_length, (const char *)value);
256         LOG(1, "TCP hello-timeout = %u\n", (unsigned)tcpcon->timeout_hello);
257         return;
258     }
259 
260     /*
261      * Force SSL processing on all ports
262      */
263     if (name_equals(name, "hello") && name_equals(value, "ssl")) {
264         unsigned i;
265 
266         LOG(2, "HELLO: setting SSL hello message\n");
267         for (i=0; i<65535; i++) {
268             banner1->payloads.tcp[i] = &banner_ssl;
269         }
270 
271         return;
272     }
273 
274     /*
275      * Force HTTP processing on all ports
276      */
277     if (name_equals(name, "hello") && name_equals(value, "http")) {
278         unsigned i;
279 
280         LOG(2, "HELLO: setting HTTP hello message\n");
281         for (i=0; i<65535; i++) {
282             banner1->payloads.tcp[i] = &banner_http;
283         }
284 
285         return;
286     }
287 
288     /*
289      * Downgrade SMB hello from v1/v2 to use only v1
290      */
291     if (name_equals(name, "hello") && name_equals(value, "smbv1")) {
292         smb_set_hello_v1(&banner_smb1);
293         return;
294     }
295 
296     /*
297      * 2014-04-08: scan for Neel Mehta's "heartbleed" bug
298      */
299     if (name_equals(name, "heartbleed")) {
300         unsigned i;
301 
302         /* Change the hello message to including negotiating the use of
303          * the "heartbeat" extension */
304         banner_ssl.hello = ssl_hello(ssl_hello_heartbeat_template);
305         banner_ssl.hello_length = ssl_hello_size(banner_ssl.hello);
306         tcpcon->banner1->is_heartbleed = 1;
307 
308         for (i=0; i<65535; i++) {
309             banner1->payloads.tcp[i] = &banner_ssl;
310         }
311 
312         return;
313     }
314 
315     if (name_equals(name, "ticketbleed")) {
316         unsigned i;
317 
318         /* Change the hello message to including negotiating the use of
319          * the "heartbeat" extension */
320         banner_ssl.hello = ssl_hello(ssl_hello_ticketbleed_template);
321         banner_ssl.hello_length = ssl_hello_size(banner_ssl.hello);
322         tcpcon->banner1->is_ticketbleed = 1;
323 
324         for (i=0; i<65535; i++) {
325             banner1->payloads.tcp[i] = &banner_ssl;
326         }
327 
328         return;
329     }
330 
331     /*
332      * 2014-10-16: scan for SSLv3 servers (POODLE)
333      */
334     if (name_equals(name, "poodle") || name_equals(name, "sslv3")) {
335         unsigned i;
336         void *px;
337 
338         /* Change the hello message to including negotiating the use of
339          * the "heartbeat" extension */
340         px = ssl_hello(ssl_hello_sslv3_template);
341         banner_ssl.hello = ssl_add_cipherspec(px, 0x5600, 1);
342         banner_ssl.hello_length = ssl_hello_size(banner_ssl.hello);
343         tcpcon->banner1->is_poodle_sslv3 = 1;
344 
345         for (i=0; i<65535; i++) {
346             banner1->payloads.tcp[i] = &banner_ssl;
347         }
348 
349         return;
350     }
351 
352 
353     /*
354      * You can reconfigure the "hello" message to be anything
355      * you want.
356      */
357     if (name_equals(name, "hello-string")) {
358         struct ProtocolParserStream *x;
359         const char *p = strchr(name, '[');
360         unsigned port;
361 
362 
363         if (p == NULL) {
364             LOG(0, "tcpcon: parmeter: expected array []: %s\n", name);
365             exit(1);
366         }
367         port = (unsigned)strtoul(p+1, 0, 0);
368 
369         x = banner1->payloads.tcp[port];
370         if (x == NULL) {
371             x = CALLOC(1, sizeof(*x));
372             x->name = "(allocated)";
373         }
374 
375         x->hello = MALLOC(value_length);
376         x->hello_length = base64_decode((char*)x->hello, value_length, value, value_length);
377 
378         banner1->payloads.tcp[port] = x;
379     }
380 
381 }
382 
383 
384 /***************************************************************************
385  ***************************************************************************/
386 void
tcpcon_set_banner_flags(struct TCP_ConnectionTable * tcpcon,unsigned is_capture_cert,unsigned is_capture_servername,unsigned is_capture_html,unsigned is_capture_heartbleed,unsigned is_capture_ticketbleed)387 tcpcon_set_banner_flags(struct TCP_ConnectionTable *tcpcon,
388     unsigned is_capture_cert,
389     unsigned is_capture_servername,
390     unsigned is_capture_html,
391     unsigned is_capture_heartbleed,
392 	unsigned is_capture_ticketbleed)
393 {
394     tcpcon->banner1->is_capture_cert = is_capture_cert;
395     tcpcon->banner1->is_capture_servername = is_capture_servername;
396     tcpcon->banner1->is_capture_html = is_capture_html;
397     tcpcon->banner1->is_capture_heartbleed = is_capture_heartbleed;
398     tcpcon->banner1->is_capture_ticketbleed = is_capture_ticketbleed;
399 }
400 
401 /***************************************************************************
402  ***************************************************************************/
scripting_init_tcp(struct TCP_ConnectionTable * tcpcon,struct lua_State * L)403 void scripting_init_tcp(struct TCP_ConnectionTable *tcpcon, struct lua_State *L)
404 {
405     tcpcon->banner1->L = L;
406 
407     banner_scripting.init(tcpcon->banner1);
408 }
409 
410 /***************************************************************************
411  * Called at startup, by a receive thread, to create a TCP connection
412  * table.
413  ***************************************************************************/
414 struct TCP_ConnectionTable *
tcpcon_create_table(size_t entry_count,struct stack_t * stack,struct TemplatePacket * pkt_template,OUTPUT_REPORT_BANNER report_banner,struct Output * out,unsigned connection_timeout,uint64_t entropy)415 tcpcon_create_table(    size_t entry_count,
416                         struct stack_t *stack,
417                         struct TemplatePacket *pkt_template,
418                         OUTPUT_REPORT_BANNER report_banner,
419                         struct Output *out,
420                         unsigned connection_timeout,
421                         uint64_t entropy
422                         )
423 {
424     struct TCP_ConnectionTable *tcpcon;
425 
426 
427     tcpcon = CALLOC(1, sizeof(*tcpcon));
428     tcpcon->timeout_connection = connection_timeout;
429     if (tcpcon->timeout_connection == 0)
430         tcpcon->timeout_connection = 30; /* half a minute before destroying tcb */
431     tcpcon->timeout_hello = 2;
432     tcpcon->entropy = entropy;
433 
434     /* Find nearest power of 2 to the tcb count, but don't go
435      * over the number 16-million */
436     {
437         size_t new_entry_count;
438         new_entry_count = 1;
439         while (new_entry_count < entry_count) {
440             new_entry_count *= 2;
441             if (new_entry_count == 0) {
442                 new_entry_count = (1<<24);
443                 break;
444             }
445         }
446         if (new_entry_count > (1<<24))
447             new_entry_count = (1<<24);
448         if (new_entry_count < (1<<10))
449             new_entry_count = (1<<10);
450         entry_count = new_entry_count;
451     }
452 
453     /* Create the table. If we can't allocate enough memory, then shrink
454      * the desired size of the table */
455     while (tcpcon->entries == 0) {
456         tcpcon->entries = malloc(entry_count * sizeof(*tcpcon->entries));
457         if (tcpcon->entries == NULL) {
458             entry_count >>= 1;
459         }
460     }
461     memset(tcpcon->entries, 0, entry_count * sizeof(*tcpcon->entries));
462 
463 
464     /* fill in the table structure */
465     tcpcon->count = (unsigned)entry_count;
466     tcpcon->mask = (unsigned)(entry_count-1);
467 
468     /* create an event/timeouts structure */
469     tcpcon->timeouts = timeouts_create(TICKS_FROM_SECS(time(0)));
470 
471 
472     tcpcon->pkt_template = pkt_template;
473 
474     tcpcon->stack = stack;
475 
476 
477     tcpcon->banner1 = banner1_create();
478 
479     tcpcon->report_banner = report_banner;
480     tcpcon->out = out;
481     return tcpcon;
482 }
483 
EQUALS(const struct TCP_Control_Block * lhs,const struct TCP_Control_Block * rhs)484 static int EQUALS(const struct TCP_Control_Block *lhs, const struct TCP_Control_Block *rhs)
485 {
486     if (lhs->port_me != rhs->port_me || lhs->port_them != rhs->port_them)
487         return 0;
488     if (lhs->ip_me.version != rhs->ip_me.version)
489         return 0;
490     if (lhs->ip_me.version == 6) {
491         if (memcmp(&lhs->ip_me.ipv6, &rhs->ip_me.ipv6, sizeof(rhs->ip_me.ipv6)) != 0)
492             return 0;
493         if (memcmp(&lhs->ip_them.ipv6, &rhs->ip_them.ipv6, sizeof(rhs->ip_them.ipv6)) != 0)
494             return 0;
495     } else {
496         if (lhs->ip_me.ipv4 != rhs->ip_me.ipv4)
497             return 0;
498         if (lhs->ip_them.ipv4 != rhs->ip_them.ipv4)
499             return 0;
500     }
501 
502     return 1;
503 }
504 
505 /***************************************************************************
506  ***************************************************************************/
507 static unsigned
tcb_hash(ipaddress ip_me,unsigned port_me,ipaddress ip_them,unsigned port_them,uint64_t entropy)508 tcb_hash(   ipaddress ip_me, unsigned port_me,
509             ipaddress ip_them, unsigned port_them,
510             uint64_t entropy)
511 {
512     unsigned index;
513 
514     /* TCB hash table uses symmetric hash, so incoming/outgoing packets
515      * get the same hash. */
516     if (ip_me.version == 6) {
517         ipv6address ipv6 = ip_me.ipv6;
518         ipv6.hi ^= ip_them.ipv6.hi;
519         ipv6.lo ^= ip_them.ipv6.lo;
520         index = (unsigned)syn_cookie_ipv6(
521                                     ipv6,
522                                     port_me ^ port_them,
523                                     ipv6,
524                                     port_me ^ port_them,
525                                     entropy);
526 
527     } else {
528         index = (unsigned)syn_cookie_ipv4(   ip_me.ipv4   ^ ip_them.ipv4,
529                                         port_me ^ port_them,
530                                         ip_me.ipv4   ^ ip_them.ipv4,
531                                         port_me ^ port_them,
532                                         entropy
533                                         );
534     }
535     return index;
536 }
537 
538 enum DestroyReason {
539     Reason_Timeout = 1,
540     Reason_FIN = 2,
541     Reason_RST = 3,
542     Reason_Foo = 4,
543     Reason_Shutdown = 5,
544     Reason_StateDone = 6,
545 
546 };
547 
548 /***************************************************************************
549  * Flush all the banners asssociated with this TCP connection. This always
550  * called when TCB is destroyed. This may also be called earlier, such
551  * as when a FIN is received.
552  ***************************************************************************/
553 static void
tcpcon_flush_banners(struct TCP_ConnectionTable * tcpcon,struct TCP_Control_Block * tcb)554 tcpcon_flush_banners(struct TCP_ConnectionTable *tcpcon, struct TCP_Control_Block *tcb)
555 {
556     struct BannerOutput *banout;
557 
558     /* Go through and print all the banners. Some protocols have
559      * multiple banners. For example, web servers have both
560      * HTTP and HTML banners, and SSL also has several
561      * X.509 certificate banners */
562     for (banout = &tcb->banout; banout != NULL; banout = banout->next) {
563         if (banout->length && banout->protocol) {
564             tcpcon->report_banner(
565                                   tcpcon->out,
566                                   global_now,
567                                   tcb->ip_them,
568                                   6, /*TCP protocol*/
569                                   tcb->port_them,
570                                   banout->protocol & 0x0FFFFFFF,
571                                   tcb->ttl,
572                                   banout->banner,
573                                   banout->length);
574         }
575     }
576 
577     /*
578      * Free up all the banners.
579      */
580     banout_release(&tcb->banout);
581 
582 }
583 
584 /***************************************************************************
585  * Destroy a TCP connection entry. We have to unlink both from the
586  * TCB-table as well as the timeout-table.
587  * Called from
588  ***************************************************************************/
589 static void
tcpcon_destroy_tcb(struct TCP_ConnectionTable * tcpcon,struct TCP_Control_Block * tcb,enum DestroyReason reason)590 tcpcon_destroy_tcb(
591     struct TCP_ConnectionTable *tcpcon,
592     struct TCP_Control_Block *tcb,
593     enum DestroyReason reason)
594 {
595     unsigned index;
596     struct TCP_Control_Block **r_entry;
597     ipaddress_formatted_t fmt;
598 
599     UNUSEDPARM(reason);
600 
601     fmt = ipaddress_fmt(tcb->ip_them);
602     LOG(1, "%s %u - closing\n", fmt.string, tcb->port_them);
603 
604     /*
605      * The TCB doesn't point to it's location in the table. Therefore, we
606      * have to do a lookup to find the head pointer in the table.
607      */
608     index = tcb_hash(   tcb->ip_me, tcb->port_me,
609                         tcb->ip_them, tcb->port_them,
610                         tcpcon->entropy);
611 
612     /*
613      * At this point, we have the head of a linked list of TCBs. Now,
614      * traverse that linked list until we find our TCB
615      */
616     r_entry = &tcpcon->entries[index & tcpcon->mask];
617     while (*r_entry && *r_entry != tcb)
618         r_entry = &(*r_entry)->next;
619 
620     if (*r_entry == NULL) {
621         LOG(1, "tcb: double free\n");
622         return;
623     }
624 
625     /*
626      * Print out any banners associated with this TCP session. Most of the
627      * time, there'll only be one. After printing them out, delete the
628      * banners.
629      */
630     tcpcon_flush_banners(tcpcon, tcb);
631     if (tcb->is_payload_dynamic && tcb->payload_length && tcb->payload)
632         free((void*)tcb->payload);
633 
634     if (tcb->scripting_thread)
635         ; //scripting_thread_close(tcb->scripting_thread);
636     tcb->scripting_thread = 0;
637 
638     /* KLUDGE: this needs to be made more elegant */
639     switch (tcb->banner1_state.app_proto) {
640         case PROTO_SMB:
641             banner_smb1.cleanup(&tcb->banner1_state);
642             break;
643     }
644 
645     /*
646      * Unlink this from the timeout system.
647      */
648     timeout_unlink(tcb->timeout);
649 
650     tcb->ip_them.ipv4 = (unsigned)~0;
651     tcb->port_them = (unsigned short)~0;
652     tcb->ip_me.ipv4 = (unsigned)~0;
653     tcb->port_me = (unsigned short)~0;
654 
655     tcb->is_active = 0;
656 
657 
658 
659 
660     (*r_entry) = tcb->next;
661     tcb->next = tcpcon->freed_list;
662     tcpcon->freed_list = tcb;
663     tcpcon->active_count--;
664 }
665 
666 
667 /***************************************************************************
668  * Called at shutdown to free up all the memory used by the TCP
669  * connection table.
670  ***************************************************************************/
671 void
tcpcon_destroy_table(struct TCP_ConnectionTable * tcpcon)672 tcpcon_destroy_table(struct TCP_ConnectionTable *tcpcon)
673 {
674     unsigned i;
675 
676     if (tcpcon == NULL)
677         return;
678 
679     /*
680      * Do a graceful destruction of all the entires. If they have banners,
681      * they will be sent to the output
682      */
683     for (i=0; i<=tcpcon->mask; i++) {
684         while (tcpcon->entries[i])
685             tcpcon_destroy_tcb(tcpcon, tcpcon->entries[i], Reason_Shutdown);
686     }
687 
688     /*
689      * Now free the memory
690      */
691     while (tcpcon->freed_list) {
692         struct TCP_Control_Block *tcb = tcpcon->freed_list;
693         tcpcon->freed_list = tcb->next;
694         free(tcb);
695     }
696 
697     banner1_destroy(tcpcon->banner1);
698     free(tcpcon->entries);
699     free(tcpcon);
700 }
701 
702 
703 /***************************************************************************
704  *
705  * Called when we receive a "SYN-ACK" packet with the correct SYN-cookie.
706  *
707  ***************************************************************************/
708 struct TCP_Control_Block *
tcpcon_create_tcb(struct TCP_ConnectionTable * tcpcon,ipaddress ip_me,ipaddress ip_them,unsigned port_me,unsigned port_them,unsigned seqno_me,unsigned seqno_them,unsigned ttl)709 tcpcon_create_tcb(
710     struct TCP_ConnectionTable *tcpcon,
711     ipaddress ip_me, ipaddress ip_them,
712     unsigned port_me, unsigned port_them,
713     unsigned seqno_me, unsigned seqno_them,
714     unsigned ttl)
715 {
716     unsigned index;
717     struct TCP_Control_Block tmp;
718     struct TCP_Control_Block *tcb;
719 
720     assert(ip_me.version != 0 && ip_them.version != 0);
721 
722     tmp.ip_me = ip_me;
723     tmp.ip_them = ip_them;
724     tmp.port_me = (unsigned short)port_me;
725     tmp.port_them = (unsigned short)port_them;
726 
727     index = tcb_hash(ip_me, port_me, ip_them, port_them, tcpcon->entropy);
728 
729 
730     tcb = tcpcon->entries[index & tcpcon->mask];
731     while (tcb && !EQUALS(tcb, &tmp)) {
732         tcb = tcb->next;
733     }
734     if (tcb == NULL) {
735         if (tcpcon->freed_list) {
736             tcb = tcpcon->freed_list;
737             tcpcon->freed_list = tcb->next;
738         } else {
739             tcb = MALLOC(sizeof(*tcb));
740         }
741         memset(tcb, 0, sizeof(*tcb));
742         tcb->next = tcpcon->entries[index & tcpcon->mask];
743         tcpcon->entries[index & tcpcon->mask] = tcb;
744 
745         tcb->ip_me = ip_me;
746         tcb->ip_them = ip_them;
747         tcb->port_me = (unsigned short)port_me;
748         tcb->port_them = (unsigned short)port_them;
749 
750         tcb->seqno_them_first = seqno_them; /* ipv6-todo */
751         tcb->seqno_me = seqno_me;
752         tcb->seqno_them = seqno_them;
753         tcb->ackno_me = seqno_them;
754         tcb->ackno_them = seqno_me;
755         tcb->when_created = global_now;
756         tcb->banner1_state.port = tmp.port_them;
757         tcb->ttl = (unsigned char)ttl;
758 
759         timeout_init(tcb->timeout);
760         banout_init(&tcb->banout);
761 
762         /* The TCB is now allocated/in-use */
763         assert(tcb->ip_me.version != 0 && tcb->ip_them.version != 0);
764         tcb->is_active = 1;
765 
766 
767         tcpcon->active_count++;
768     }
769 
770     tcb_lookup(tcpcon, ip_me, ip_them, port_me, port_them);
771 
772     return tcb;
773 }
774 
775 
776 
777 /***************************************************************************
778  ***************************************************************************/
779 struct TCP_Control_Block *
tcb_lookup(struct TCP_ConnectionTable * tcpcon,ipaddress ip_me,ipaddress ip_them,unsigned port_me,unsigned port_them)780 tcb_lookup(
781     struct TCP_ConnectionTable *tcpcon,
782     ipaddress ip_me, ipaddress ip_them,
783     unsigned port_me, unsigned port_them)
784 {
785     unsigned index;
786     struct TCP_Control_Block tmp;
787     struct TCP_Control_Block *tcb;
788     ipaddress_formatted_t fmt1;
789     ipaddress_formatted_t fmt2;
790 
791     tmp.ip_me = ip_me;
792     tmp.ip_them = ip_them;
793     tmp.port_me = (unsigned short)port_me;
794     tmp.port_them = (unsigned short)port_them;
795 
796     index = tcb_hash(ip_me, port_me, ip_them, port_them, tcpcon->entropy);
797 
798     fmt1 = ipaddress_fmt(ip_me);
799     fmt2 = ipaddress_fmt(ip_them);
800     LOG(1, "tcb_hash(0x%08x) = %s %u %s %u\n",
801         (unsigned)index,
802         fmt1.string, port_me,
803         fmt2.string, port_them);
804 
805     /* Hash to an entry in the table, then follow a linked list from
806      * that point forward. */
807     tcb = tcpcon->entries[index & tcpcon->mask];
808     while (tcb && !EQUALS(tcb, &tmp)) {
809         tcb = tcb->next;
810     }
811 
812 
813     return tcb;
814 }
815 
816 
817 /***************************************************************************
818  ***************************************************************************/
819 static void
tcpcon_send_packet(struct TCP_ConnectionTable * tcpcon,struct TCP_Control_Block * tcb,unsigned tcp_flags,const unsigned char * payload,size_t payload_length,unsigned ctrl)820 tcpcon_send_packet(
821     struct TCP_ConnectionTable *tcpcon,
822     struct TCP_Control_Block *tcb,
823     unsigned tcp_flags,
824     const unsigned char *payload, size_t payload_length,
825     unsigned ctrl)
826 {
827     struct PacketBuffer *response = 0;
828 
829     assert(tcb->ip_me.version != 0 && tcb->ip_them.version != 0);
830 
831 
832     /* Get a buffer for sending the response packet. This thread doesn't
833      * send the packet itself. Instead, it formats a packet, then hands
834      * that packet off to a transmit thread for later transmission. */
835     response = stack_get_packetbuffer(tcpcon->stack);
836     if (response == NULL) {
837         static int is_warning_printed = 0;
838         if (!is_warning_printed) {
839             LOG(0, "packet buffers empty (should be impossible)\n");
840             is_warning_printed = 1;
841         }
842         fflush(stdout);
843 
844         /* FIXME: I'm no sure the best way to handle this.
845          * This would result from a bug in the code,
846          * but I'm not sure what should be done in response */
847         pixie_usleep(100); /* no packet available */
848     }
849     if (response == NULL)
850         return;
851 
852     /* Format the packet as requested. Note that there are really only
853      * four types of packets:
854      * 1. a SYN-ACK packet with no payload
855      * 2. an ACK packet with no payload
856      * 3. a RST packet with no pacyload
857      * 4. a PSH-ACK packet WITH PAYLOAD
858      */
859     response->length = tcp_create_packet(
860         tcpcon->pkt_template,
861         tcb->ip_them, tcb->port_them,
862         tcb->ip_me, tcb->port_me,
863         tcb->seqno_me, tcb->seqno_them,
864         tcp_flags,
865         payload, payload_length,
866         response->px, sizeof(response->px)
867         );
868 
869     /*
870      * KLUDGE:
871      */
872     if (ctrl & CTRL_SMALL_WINDOW) {
873         tcp_set_window(response->px, response->length, 600);
874     }
875     //tcp_set_window(response->px, response->length, 600);
876 
877     /* If we have payload, then:
878      * 1. remember the payload so we can resend it
879      */
880     tcb->payload = payload;
881     tcb->payload_length = (unsigned short)payload_length;
882 
883     /* Put this buffer on the transmit queue. Remember: transmits happen
884      * from a transmit-thread only, and this function is being called
885      * from a receive-thread. Therefore, instead of transmiting ourselves,
886      * we hae to queue it up for later transmission. */
887     stack_transmit_packetbuffer(tcpcon->stack, response);
888 }
889 
890 /***************************************************************************
891  ***************************************************************************/
892 void
tcp_send_RST(struct TemplatePacket * templ,struct stack_t * stack,ipaddress ip_them,ipaddress ip_me,unsigned port_them,unsigned port_me,unsigned seqno_them,unsigned seqno_me)893 tcp_send_RST(
894     struct TemplatePacket *templ,
895     struct stack_t *stack,
896     ipaddress ip_them, ipaddress ip_me,
897     unsigned port_them, unsigned port_me,
898     unsigned seqno_them, unsigned seqno_me
899 )
900 {
901     struct PacketBuffer *response = 0;
902 
903 
904     /* Get a buffer for sending the response packet. This thread doesn't
905      * send the packet itself. Instead, it formats a packet, then hands
906      * that packet off to a transmit thread for later transmission. */
907     response = stack_get_packetbuffer(stack);
908     if (response == NULL) {
909         static int is_warning_printed = 0;
910         if (!is_warning_printed) {
911             LOG(0, "packet buffers empty (should be impossible)\n");
912             is_warning_printed = 1;
913         }
914         fflush(stdout);
915         pixie_usleep(100); /* no packet available */
916     }
917     if (response == NULL)
918         return;
919 
920     response->length = tcp_create_packet(
921         templ,
922         ip_them, port_them,
923         ip_me, port_me,
924         seqno_me, seqno_them,
925         0x04, /*RST*/
926         0, 0,
927         response->px, sizeof(response->px)
928         );
929 
930 
931     /* Put this buffer on the transmit queue. Remember: transmits happen
932      * from a transmit-thread only, and this function is being called
933      * from a receive-thread. Therefore, instead of transmiting ourselves,
934      * we hae to queue it up for later transmission. */
935     stack_transmit_packetbuffer(stack, response);
936 }
937 
938 /***************************************************************************
939  * DEBUG: when printing debug messages (-d option), this prints a string
940  * for the given state.
941  ***************************************************************************/
942 static const char *
state_to_string(int state)943 state_to_string(int state)
944 {
945     static char buf[64];
946     switch (state) {
947             //STATE_SYN_RECEIVED,
948             //STATE_CLOSE_WATI,
949         case STATE_LAST_ACK:        return "LAST-ACK";
950         case STATE_FIN_WAIT1:       return "FIN-WAIT-1";
951         case STATE_FIN_WAIT2:       return "FIN-WAIT-2";
952         case STATE_CLOSING:         return "CLOSING";
953         case STATE_TIME_WAIT:       return "TIME-WAIT";
954         case STATE_SYN_SENT:        return "SYN_SENT";
955         case STATE_ESTABLISHED_SEND:return "ESTABLISHED_SEND";
956         case STATE_ESTABLISHED_RECV:return "ESTABLISHED_RECV";
957 
958         default:
959             sprintf_s(buf, sizeof(buf), "%d", state);
960             return buf;
961     }
962 }
963 
964 /***************************************************************************
965  * DEBUG: when printing debug messages (-d option), this prints a string
966  * for the given state.
967  ***************************************************************************/
968 static const char *
what_to_string(enum TCP_What state)969 what_to_string(enum TCP_What state)
970 {
971     static char buf[64];
972     switch (state) {
973         case TCP_WHAT_TIMEOUT: return "TIMEOUT";
974         case TCP_WHAT_SYNACK: return "SYNACK";
975         case TCP_WHAT_RST: return "RST";
976         case TCP_WHAT_FIN: return "FIN";
977         case TCP_WHAT_ACK: return "ACK";
978         case TCP_WHAT_DATA: return "DATA";
979         default:
980             sprintf_s(buf, sizeof(buf), "%d", state);
981             return buf;
982     }
983 }
984 
985 
986 /***************************************************************************
987  ***************************************************************************/
988 
989 static void
LOGSEND(struct TCP_Control_Block * tcb,const char * what)990 LOGSEND(struct TCP_Control_Block *tcb, const char *what)
991 {
992     if (tcb == NULL)
993         return;
994     LOGip(5, tcb->ip_them, tcb->port_them, "=%s : --->> %s                  \n",
995           state_to_string(tcb->tcpstate),
996           what);
997 }
998 
999 
1000 /***************************************************************************
1001  * Sends a fake FIN when we've already closed our connection, on the
1002  * assumption this will help the other side close their side more
1003  * gracefully. Maybe we shoulid do a RST instead.
1004  ***************************************************************************/
1005 void
tcpcon_send_FIN(struct TCP_ConnectionTable * tcpcon,ipaddress ip_me,ipaddress ip_them,unsigned port_me,unsigned port_them,uint32_t seqno_them,uint32_t ackno_them)1006 tcpcon_send_FIN(
1007                 struct TCP_ConnectionTable *tcpcon,
1008                 ipaddress ip_me, ipaddress ip_them,
1009                 unsigned port_me, unsigned port_them,
1010                 uint32_t seqno_them, uint32_t ackno_them)
1011 {
1012     struct TCP_Control_Block tcb;
1013 
1014     memset(&tcb, 0, sizeof(tcb));
1015 
1016     tcb.ip_me = ip_me;
1017     tcb.ip_them = ip_them;
1018     tcb.port_me = (unsigned short)port_me;
1019     tcb.port_them = (unsigned short)port_them;
1020     tcb.seqno_me = ackno_them;
1021     tcb.ackno_me = seqno_them + 1;
1022     tcb.seqno_them = seqno_them + 1;
1023     tcb.ackno_them = ackno_them;
1024 
1025     LOGSEND(&tcb, "peer(FIN) fake");
1026     tcpcon_send_packet(tcpcon, &tcb, 0x11, 0, 0, 0);
1027 }
1028 
1029 void
tcpcon_send_RST(struct TCP_ConnectionTable * tcpcon,ipaddress ip_me,ipaddress ip_them,unsigned port_me,unsigned port_them,uint32_t seqno_them,uint32_t ackno_them)1030 tcpcon_send_RST(
1031                 struct TCP_ConnectionTable *tcpcon,
1032                 ipaddress ip_me, ipaddress ip_them,
1033                 unsigned port_me, unsigned port_them,
1034                 uint32_t seqno_them, uint32_t ackno_them)
1035 {
1036     struct TCP_Control_Block tcb;
1037 
1038     memset(&tcb, 0, sizeof(tcb));
1039 
1040     tcb.ip_me = ip_me;
1041     tcb.ip_them = ip_them;
1042     tcb.port_me = (unsigned short)port_me;
1043     tcb.port_them = (unsigned short)port_them;
1044     tcb.seqno_me = ackno_them;
1045     tcb.ackno_me = seqno_them + 1;
1046     tcb.seqno_them = seqno_them + 1;
1047     tcb.ackno_them = ackno_them;
1048 
1049     LOGSEND(&tcb, "send RST");
1050     tcpcon_send_packet(tcpcon, &tcb, 0x04, 0, 0, 0);
1051 }
1052 
1053 
1054 /***************************************************************************
1055  * Parse the information we get from the server we are scanning. Typical
1056  * examples are SSH banners, FTP banners, or the response from HTTP
1057  * requests
1058  ***************************************************************************/
1059 static size_t
parse_banner(struct TCP_ConnectionTable * tcpcon,struct TCP_Control_Block * tcb,const unsigned char * payload,size_t payload_length,struct InteractiveData * more)1060 parse_banner(
1061     struct TCP_ConnectionTable *tcpcon,
1062     struct TCP_Control_Block *tcb,
1063     const unsigned char *payload,
1064     size_t payload_length,
1065     struct InteractiveData *more)
1066 {
1067     assert(tcb->banout.max_length);
1068 
1069     banner1_parse(
1070                                     tcpcon->banner1,
1071                                     &tcb->banner1_state,
1072                                     payload,
1073                                     payload_length,
1074                                     &tcb->banout,
1075                                     more);
1076     return payload_length;
1077 }
1078 
1079 
1080 /***************************************************************************
1081  ***************************************************************************/
1082 static int
handle_ack(struct TCP_Control_Block * tcb,uint32_t ackno)1083 handle_ack(
1084     struct TCP_Control_Block *tcb,
1085     uint32_t ackno)
1086 {
1087 
1088     /*LOG(4,  "%s - %u-sending, %u-reciving\n",
1089             fmt.string,
1090             tcb->seqno_me - ackno,
1091             ackno - tcb->ackno_them
1092             );*/
1093 
1094     /* Normal: just discard repeats */
1095     if (ackno == tcb->ackno_them) {
1096         return 0;
1097     }
1098 
1099     /* Make sure this isn't a duplicate ACK from past
1100      * WRAPPING of 32-bit arithmetic happens here */
1101     if (ackno - tcb->ackno_them > 10000) {
1102         ipaddress_formatted_t fmt = ipaddress_fmt(tcb->ip_them);
1103         LOG(4,  "%s - "
1104                 "tcb: ackno from past: "
1105                 "old ackno = 0x%08x, this ackno = 0x%08x\n",
1106                 fmt.string,
1107                 tcb->ackno_me, ackno);
1108         return 0;
1109     }
1110 
1111     /* Make sure this isn't invalid ACK from the future
1112      * WRAPPING of 32-bit arithmatic happens here */
1113     if (tcb->seqno_me - ackno > 10000) {
1114         ipaddress_formatted_t fmt = ipaddress_fmt(tcb->ip_them);
1115         LOG(4, "%s - "
1116                 "tcb: ackno from future: "
1117                 "my seqno = 0x%08x, their ackno = 0x%08x\n",
1118                 fmt.string,
1119                 tcb->seqno_me, ackno);
1120         return 0;
1121     }
1122 
1123     /* now that we've verified this is a good ACK, record this number */
1124     tcb->ackno_them = ackno;
1125 
1126     /* Mark that this was a good ack */
1127     return 1;
1128 }
1129 
1130 enum AppAction {
1131     APP_CONNECTED,
1132     APP_RECV_TIMEOUT,
1133     APP_RECV_PAYLOAD,
1134     APP_SEND_SENT,
1135 };
1136 
1137 
1138 /***************************************************************************
1139  ***************************************************************************/
1140 static void
application(struct TCP_ConnectionTable * tcpcon,struct TCP_Control_Block * tcb,enum AppAction action,const void * payload,size_t payload_length,unsigned secs,unsigned usecs)1141 application(struct TCP_ConnectionTable *tcpcon,
1142                  struct TCP_Control_Block *tcb,
1143                  enum AppAction action, const void *payload, size_t payload_length,
1144                  unsigned secs, unsigned usecs)
1145 {
1146     struct Banner1 *banner1 = tcpcon->banner1;
1147 
1148     enum {
1149         App_Connect,
1150         App_ReceiveHello,
1151         App_ReceiveNext,
1152         App_SendNext,
1153     };
1154 
1155     switch (tcb->established) {
1156         case App_Connect:
1157             if (banner1->payloads.tcp[tcb->port_them] == &banner_scripting) {
1158                 //int x;
1159                 ; //tcb->scripting_thread = scripting_thread_new(tcpcon->scripting_vm);
1160                 ; //x = scripting_thread_run(tcb->scripting_thread);
1161             } else {
1162                 /*
1163                  * Wait 1 second for "server hello" (like SSH), and if that's
1164                  * not found, then transmit a "client hello"
1165                  */
1166                 assert(action == APP_CONNECTED);
1167                 LOGSEND(tcb, "+timeout");
1168                 timeouts_add( tcpcon->timeouts,
1169                              tcb->timeout,
1170                              offsetof(struct TCP_Control_Block, timeout),
1171                              TICKS_FROM_TV(secs+tcpcon->timeout_hello,usecs)
1172                              );
1173                 /* Start of connection */
1174                 tcb->tcpstate = STATE_ESTABLISHED_RECV;
1175                 tcb->established = App_ReceiveHello;
1176             }
1177             break;
1178         case App_ReceiveHello:
1179             if (action == APP_RECV_TIMEOUT) {
1180                 struct ProtocolParserStream *stream = banner1->payloads.tcp[tcb->port_them];
1181 
1182                 if (stream) {
1183                     struct InteractiveData more = {0};
1184                     unsigned ctrl = 0;
1185 
1186                     if (stream->transmit_hello)
1187                         stream->transmit_hello(banner1, &more);
1188                     else {
1189                         more.m_length = (unsigned)banner1->payloads.tcp[tcb->port_them]->hello_length;
1190                         more.m_payload = banner1->payloads.tcp[tcb->port_them]->hello;
1191                         more.is_payload_dynamic = 0;
1192                     }
1193 
1194                     /*
1195                      * Kludge
1196                      */
1197                     if (banner1->payloads.tcp[tcb->port_them] == &banner_ssl) {
1198                         tcb->banner1_state.is_sent_sslhello = 1;
1199                     }
1200 
1201                     /*
1202                      * KLUDGE
1203                      */
1204                     if (tcpcon->banner1->is_heartbleed) {
1205                         ctrl = CTRL_SMALL_WINDOW;
1206                     }
1207 
1208                     /*
1209                      * Queue up the packet to be sent
1210                      */
1211                     LOGip(4, tcb->ip_them, tcb->port_them, "sending payload %u bytes\n", more.m_length);
1212                     LOGSEND(tcb, "peer(payload)");
1213                     tcpcon_send_packet(tcpcon, tcb, 0x18, more.m_payload, more.m_length, ctrl);
1214                     tcb->seqno_me += (uint32_t)more.m_length;
1215                     tcb->is_payload_dynamic = more.is_payload_dynamic;
1216                     tcb->tcpstate = STATE_ESTABLISHED_SEND;
1217 
1218                     //tcb->established = App_SendNext;
1219                 }
1220 
1221                 /* Add a timeout so that we can resend the data in case it
1222                  * goes missing. Note that we put this back in the timeout
1223                  * system regardless if we've sent data. */
1224                 LOGSEND(tcb, "+timeout");
1225                 timeouts_add(   tcpcon->timeouts,
1226                              tcb->timeout,
1227                              offsetof(struct TCP_Control_Block, timeout),
1228                              TICKS_FROM_TV(secs+1,usecs)
1229                              );
1230                 break;
1231             } else if (action == APP_RECV_PAYLOAD) {
1232                 tcb->established = App_ReceiveNext;
1233                 /* fall through */
1234             }
1235             /* fall through */
1236         case App_ReceiveNext:
1237             if (action == APP_RECV_PAYLOAD) {
1238                 struct InteractiveData more = {0};
1239 
1240                 /* [--banners]
1241                  * This is an important part of the system, where the TCP
1242                  * stack passes incoming packet payloads off to the application
1243                  * layer protocol parsers. This is where, in Sockets API, you
1244                  * might call the 'recv()' function.
1245                  */
1246                 parse_banner(
1247                                    tcpcon,
1248                                    tcb,
1249                                    payload,
1250                                    payload_length,
1251                                    &more);
1252 
1253                 /* move their sequence number forward */
1254                 tcb->seqno_them += (unsigned)payload_length;
1255 
1256                 /* acknowledge the bytes received */
1257                 if (more.m_length) {
1258                     LOGSEND(tcb, "peer(ACK)");
1259                     LOGSEND(tcb, "peer(payload)");
1260                     tcpcon_send_packet(tcpcon, tcb, 0x18, more.m_payload, more.m_length, 0);
1261                     tcb->seqno_me += (uint32_t)more.m_length;
1262                     tcb->is_payload_dynamic = more.is_payload_dynamic;
1263                     tcb->tcpstate = STATE_ESTABLISHED_SEND;
1264                     tcb->established = App_SendNext;
1265                     LOGip(4, tcb->ip_them, tcb->port_them, "sending payload %u bytes\n", more.m_length);
1266 
1267                 } else {
1268                     LOGSEND(tcb, "peer(ACK)");
1269                     tcpcon_send_packet(tcpcon, tcb,
1270                                        0x10,
1271                                        0, 0, 0);
1272                 }
1273 
1274                 if (more.is_closing) {
1275                     /* Send FIN packet */
1276                     LOGSEND(tcb, "peer(FIN)");
1277                     tcpcon_send_packet(tcpcon, tcb,
1278                                        0x11,
1279                                        0, 0, 0);
1280                     tcb->seqno_me++;
1281 
1282                     tcb->tcpstate = STATE_FIN_WAIT1;
1283                     LOGSEND(tcb, "+timeout");
1284 
1285                     timeouts_add(   tcpcon->timeouts,
1286                                  tcb->timeout,
1287                                  offsetof(struct TCP_Control_Block, timeout),
1288                                  TICKS_FROM_TV(secs+1,usecs)
1289                                  );
1290                     //tcpcon_destroy_tcb(tcpcon, tcb, Reason_StateDone);
1291                 }
1292             }
1293             break;
1294         case App_SendNext:
1295             if (action == APP_SEND_SENT) {
1296                 tcb->tcpstate = STATE_ESTABLISHED_RECV;
1297                 tcb->established = App_ReceiveNext;
1298             }
1299             break;
1300         default:
1301             LOG(0, "TCP state error\n");
1302             exit(1);
1303             break;
1304     }
1305 }
1306 
1307 
1308 /*****************************************************************************
1309  * Handles incoming events, like timeouts and packets, that cause a change
1310  * in the TCP control block "state".
1311  *
1312  * This is the part of the code that implements the famous TCP state-machine
1313  * you see drawn everywhere, where they have states like "TIME_WAIT". Only
1314  * we don't really have those states.
1315  *****************************************************************************/
1316 int
stack_incoming_tcp(struct TCP_ConnectionTable * tcpcon,struct TCP_Control_Block * tcb,int in_what,const void * vpayload,size_t payload_length,unsigned secs,unsigned usecs,unsigned seqno_them)1317 stack_incoming_tcp(struct TCP_ConnectionTable *tcpcon,
1318               struct TCP_Control_Block *tcb,
1319               int in_what, const void *vpayload, size_t payload_length,
1320               unsigned secs, unsigned usecs,
1321               unsigned seqno_them)
1322 {
1323     enum TCP_What what = in_what;
1324     const unsigned char *payload = (const unsigned char *)vpayload;
1325 
1326     if (tcb == NULL)
1327         return 0;
1328 
1329     LOGip(5, tcb->ip_them, tcb->port_them, "=%s : %s                  \n",
1330           state_to_string(tcb->tcpstate),
1331           what_to_string(what));
1332 
1333     /* Make sure no connection lasts more than ~30 seconds */
1334     if (what == TCP_WHAT_TIMEOUT) {
1335         if (tcb->when_created + tcpcon->timeout_connection < secs) {
1336             LOGip(8, tcb->ip_them, tcb->port_them,
1337                 "%s                \n",
1338                 "CONNECTION TIMEOUT---");
1339             LOGSEND(tcb, "peer(RST)");
1340             tcpcon_send_packet(tcpcon, tcb,
1341                 0x04,
1342                 0, 0, 0);
1343             tcpcon_destroy_tcb(tcpcon, tcb, Reason_Timeout);
1344             return 1;
1345         }
1346     }
1347 
1348     if (what == TCP_WHAT_RST) {
1349         LOGSEND(tcb, "tcb(destroy)");
1350         tcpcon_destroy_tcb(tcpcon, tcb, Reason_RST);
1351         return 1;
1352     }
1353 
1354 
1355     /*
1356      *
1357      *
1358      *
1359      *
1360      *
1361      *
1362      */
1363     switch (tcb->tcpstate) {
1364             /* TODO: validate any SYNACK is real before sending it here
1365              * to the state-machine, by validating that it's acking
1366              * something */
1367         case STATE_SYN_SENT:
1368             switch (what) {
1369                 case TCP_WHAT_RST:
1370                 case TCP_WHAT_TIMEOUT:
1371                 //case TCP_WHAT_SYNACK:
1372                 case TCP_WHAT_FIN:
1373                 case TCP_WHAT_ACK:
1374                 case TCP_WHAT_DATA:
1375                     break;
1376                 case TCP_WHAT_SYNACK:
1377                     /* Send "ACK" to acknowlege their "SYN-ACK" */
1378                     LOGSEND(tcb, "peer(ACK) [acknowledge SYN-ACK 1]");
1379                     tcpcon_send_packet(tcpcon, tcb,
1380                                        0x10,
1381                                        0, 0, 0);
1382                     LOGSEND(tcb, "app(connected)");
1383                     application(tcpcon, tcb, APP_CONNECTED, 0, 0, secs, usecs);
1384                     break;
1385                 }
1386             break;
1387         case STATE_ESTABLISHED_SEND:
1388         case STATE_ESTABLISHED_RECV:
1389             switch (what) {
1390                 case TCP_WHAT_RST:
1391                     break;
1392                 case TCP_WHAT_SYNACK:
1393                     /* Send "ACK" to acknowlege their "SYN-ACK" */
1394                     LOGSEND(tcb, "peer(ACK) [acknowledge SYN-ACK 2]");
1395                     tcpcon_send_packet(tcpcon, tcb,
1396                                        0x10, /* ACK */
1397                                        0, 0, 0);
1398                     break;
1399                 case TCP_WHAT_FIN:
1400                     if (tcb->tcpstate == STATE_ESTABLISHED_RECV) {
1401                         tcb->seqno_them = seqno_them + 1;
1402 
1403                         LOGSEND(tcb, "peer(FIN)");
1404                         tcpcon_send_packet(tcpcon, tcb,
1405                                            0x11, /* FIN-ACK */
1406                                            0, 0, 0);
1407                         tcb->seqno_me++;
1408                         tcb->tcpstate = STATE_LAST_ACK;
1409                     } else if (tcb->tcpstate == STATE_ESTABLISHED_RECV) {
1410                         /* Do nothing, the same thing as if we received data
1411                          * during the SENd state. The other side will send it
1412                          * again after it has acknolwedged our data */
1413                         ;
1414                     }
1415                     break;
1416                 case TCP_WHAT_ACK:
1417                     /* There's actually nothing that goes on in this state. We are
1418                      * just waiting for the timer to expire. In the meanwhile,
1419                      * though, the other side is might acknowledge that we sent
1420                      * a SYN-ACK */
1421 
1422                     /* NOTE: the arg 'payload_length' was overloaded here to be the
1423                      * 'ackno' instead */
1424                     handle_ack( tcb, (uint32_t)payload_length);
1425                     if (tcb->tcpstate == STATE_ESTABLISHED_SEND) {
1426                         if (tcb->ackno_them - tcb->seqno_me == 0) {
1427                             /* All the payload has been sent */
1428                             if (tcb->is_payload_dynamic)
1429                                 free((void*)tcb->payload);
1430                             tcb->payload = 0;
1431                             tcb->payload_length = 0;
1432                             tcb->is_payload_dynamic = 0;
1433 
1434                             LOGSEND(tcb, "app(sent)");
1435                             application(tcpcon, tcb, APP_SEND_SENT, 0, 0, secs, usecs);
1436                             tcb->tcpstate = STATE_ESTABLISHED_RECV;
1437                             LOGSEND(tcb, "+timeout");
1438                             timeouts_add(   tcpcon->timeouts,
1439                                          tcb->timeout,
1440                                          offsetof(struct TCP_Control_Block, timeout),
1441                                          TICKS_FROM_TV(secs+10,usecs)
1442                                          );
1443                         } else {
1444                             /* Reset the timeout, waiting for more data to arrive */
1445                             LOGSEND(tcb, "+timeout");
1446                             timeouts_add(   tcpcon->timeouts,
1447                                          tcb->timeout,
1448                                          offsetof(struct TCP_Control_Block, timeout),
1449                                          TICKS_FROM_TV(secs+1,usecs)
1450                                          );
1451 
1452                         }
1453                     }
1454                     break;
1455                 case TCP_WHAT_TIMEOUT:
1456                     if (tcb->tcpstate == STATE_ESTABLISHED_RECV) {
1457                         /* Didn't receive data in the expected timeframe. This is
1458                          * often a normal condition, such as during the start
1459                          * of a scanned connection, when we don't understand the
1460                          * protocol and are simply waiting for anything the
1461                          * server might send us.
1462                          */
1463                         LOGSEND(tcb, "app(timeout)");
1464                         application(tcpcon, tcb, APP_RECV_TIMEOUT, 0, 0, secs, usecs);
1465                     } else if (tcb->tcpstate == STATE_ESTABLISHED_SEND) {
1466                         /*
1467                          * We did not get a complete ACK of our sent data, so retransmit
1468                          * it to the server
1469                          */
1470                         uint32_t len;
1471 
1472 
1473                         len = tcb->seqno_me - tcb->ackno_them;
1474 
1475                         /* Resend the payload */
1476                         tcb->seqno_me -= len;
1477                         LOGSEND(tcb, "peer(payload) retransmit");
1478 
1479                         /* kludge: should never be NULL< but somehow is */
1480                         if (tcb->payload)
1481                         tcpcon_send_packet(tcpcon, tcb,
1482                                            0x18,
1483                                            tcb->payload + tcb->payload_length - len,
1484                                            len, 0);
1485                         tcb->seqno_me += len;
1486 
1487 
1488                         /* Now that we've resent the packet, register another
1489                          * timeout in order to resend it yet again if not
1490                          * acknolwedgeld. */
1491                         LOGSEND(tcb, "+timeout");
1492                         timeouts_add(tcpcon->timeouts,
1493                                      tcb->timeout,
1494                                      offsetof(struct TCP_Control_Block, timeout),
1495                                      TICKS_FROM_TV(secs+2,usecs)
1496                                      );
1497                     }
1498 
1499                     break;
1500                 case TCP_WHAT_DATA:
1501 
1502                     if ((unsigned)(tcb->seqno_them - seqno_them) > payload_length)  {
1503                         LOGSEND(tcb, "peer(ACK) [acknowledge payload 1]");
1504                         tcpcon_send_packet(tcpcon, tcb,
1505                                            0x10,
1506                                            0, 0, 0);
1507                         return 1;
1508                     }
1509 
1510                     while (seqno_them != tcb->seqno_them && payload_length) {
1511                         seqno_them++;
1512                         payload_length--;
1513                         payload++;
1514                     }
1515 
1516                     if (payload_length == 0) {
1517                         LOGSEND(tcb, "peer(ACK) [acknowledge empty data]");
1518                         tcpcon_send_packet(tcpcon, tcb,
1519                                            0x10,
1520                                            0, 0, 0);
1521                         return 1;
1522                     }
1523 
1524                     LOGSEND(tcb, "app(payload)");
1525                     application(tcpcon, tcb, APP_RECV_PAYLOAD, payload, payload_length, secs, usecs);
1526 
1527                     /* Send ack for the data */
1528                     LOGSEND(tcb, "peer(ACK) [acknowledge payload 2]");
1529                     tcpcon_send_packet(tcpcon, tcb,
1530                                        0x10,
1531                                        0, 0, 0);
1532                     break;
1533 
1534             }
1535             break;
1536         case STATE_FIN_WAIT1:
1537             switch (what) {
1538                 case TCP_WHAT_TIMEOUT:
1539                     /* resend FIN packet */
1540                     LOGSEND(tcb, "peer(FIN)");
1541                     tcpcon_send_packet(tcpcon, tcb,
1542                                        0x11,
1543                                        0, 0, 0);
1544 
1545                     /* reset timeout */
1546                     LOGSEND(tcb, "+timeout");
1547                     timeouts_add(   tcpcon->timeouts,
1548                                  tcb->timeout,
1549                                  offsetof(struct TCP_Control_Block, timeout),
1550                                  TICKS_FROM_TV(secs+1,usecs)
1551                                  );
1552                     break;
1553                 case TCP_WHAT_ACK:
1554                     if (handle_ack( tcb, (uint32_t)payload_length)) {
1555                         tcb->tcpstate = STATE_FIN_WAIT2;
1556                         LOGSEND(tcb, "+timeout");
1557                         timeouts_add(   tcpcon->timeouts,
1558                                      tcb->timeout,
1559                                      offsetof(struct TCP_Control_Block, timeout),
1560                                      TICKS_FROM_TV(secs+5,usecs)
1561                                      );
1562                     }
1563                     break;
1564                 case TCP_WHAT_FIN:
1565                     break;
1566                 case TCP_WHAT_SYNACK:
1567                 case TCP_WHAT_RST:
1568                 case TCP_WHAT_DATA:
1569                     break;
1570             }
1571             break;
1572 
1573         case STATE_FIN_WAIT2:
1574         case STATE_TIME_WAIT:
1575             switch (what) {
1576                 case TCP_WHAT_TIMEOUT:
1577                     if (tcb->tcpstate == STATE_TIME_WAIT) {
1578                         tcpcon_destroy_tcb(tcpcon, tcb, Reason_Timeout);
1579                         return 1;
1580                     }
1581                     break;
1582                 case TCP_WHAT_ACK:
1583                     break;
1584                 case TCP_WHAT_FIN:
1585                     tcb->seqno_them = seqno_them + 1;
1586                     LOGSEND(tcb, "peer(ACK) [acknowledge FIN]");
1587                     tcpcon_send_packet(tcpcon, tcb,
1588                                        0x10,
1589                                        0, 0, 0);
1590                     tcb->tcpstate = STATE_TIME_WAIT;
1591                     LOGSEND(tcb, "+timeout");
1592                     timeouts_add(   tcpcon->timeouts,
1593                                  tcb->timeout,
1594                                  offsetof(struct TCP_Control_Block, timeout),
1595                                  TICKS_FROM_TV(secs+5,usecs)
1596                                  );
1597                     break;
1598                 case TCP_WHAT_SYNACK:
1599                 case TCP_WHAT_RST:
1600                 case TCP_WHAT_DATA:
1601                     break;
1602             }
1603             break;
1604 
1605         case STATE_LAST_ACK:
1606             LOGip(1, tcb->ip_them, tcb->port_them, "=%s : %s                  \n", state_to_string(tcb->tcpstate), what_to_string(what));
1607             //LOG(1, "TCP-state: unknown state\n");
1608             break;
1609         default:
1610             LOG(1, "TCP-state: unknown state\n");
1611     }
1612     return 1;
1613 }
1614 
1615