int connection_tracking(packetinfo *pi) { struct in6_addr *ip_src; struct in6_addr *ip_dst; struct in6_addr ips; struct in6_addr ipd; uint16_t src_port = pi->s_port; uint16_t dst_port = pi->d_port; int af = pi->af; connection *cxt = NULL; connection *head = NULL; uint32_t hash; if(af== AF_INET6){ ip_src = &PI_IP6SRC(pi); ip_dst = &PI_IP6DST(pi); }else { ips.s6_addr32[0] = pi->ip4->ip_src; ipd.s6_addr32[0] = pi->ip4->ip_dst; ip_src = &ips; ip_dst = &ipd; } // find the right connection bucket if (af == AF_INET) { hash = CXT_HASH4(IP4ADDR(ip_src),IP4ADDR(ip_dst),src_port,dst_port,pi->proto); } else if (af == AF_INET6) { hash = CXT_HASH6(ip_src,ip_dst,src_port,dst_port,pi->proto); } cxt = bucket[hash]; head = cxt; // search through the bucket while (cxt != NULL) { // Two-way compare of given connection against connection table if (af == AF_INET) { if (CMP_CXT4(cxt,IP4ADDR(ip_src),src_port,IP4ADDR(ip_dst),dst_port)){ // Client sends first packet (TCP/SYN - UDP?) hence this is a client return cxt_update_client(cxt, pi); } else if (CMP_CXT4(cxt,IP4ADDR(ip_dst),dst_port,IP4ADDR(ip_src),src_port)) { // This is a server (Maybe not when we start up but in the long run) return cxt_update_server(cxt, pi); } } else if (af == AF_INET6) { if (CMP_CXT6(cxt,ip_src,src_port,ip_dst,dst_port)){ return cxt_update_client(cxt, pi); } else if (CMP_CXT6(cxt,ip_dst,dst_port,ip_src,src_port)){ return cxt_update_server(cxt, pi); } } cxt = cxt->next; } // bucket turned upside down didn't yeild anything. new connection cxt = cxt_new(pi); /* New connections are pushed on to the head of bucket[s_hash] */ cxt->next = head; if (head != NULL) { // are we doubly linked? head->prev = cxt; } bucket[hash] = cxt; pi->cxt = cxt; return cxt_update_client(cxt, pi); }
int connection_tracking(packetinfo *pi) { struct in6_addr *ip_src; struct in6_addr *ip_dst; struct in6_addr ips; struct in6_addr ipd; uint16_t src_port = pi->s_port; uint16_t dst_port = pi->d_port; int af = pi->af; connection *cxt = NULL; connection *head = NULL; uint32_t hash; if(af == AF_INET6){ ip_src = &PI_IP6SRC(pi); ip_dst = &PI_IP6DST(pi); } else { ips.s6_addr32[0] = pi->ip4->ip_src; ipd.s6_addr32[0] = pi->ip4->ip_dst; ip_src = &ips; ip_dst = &ipd; } /* Find the right connection bucket */ if (af == AF_INET) { hash = CXT_HASH4(IP4ADDR(ip_src), IP4ADDR(ip_dst), src_port, dst_port, pi->proto); } else if (af == AF_INET6) { hash = CXT_HASH6(ip_src, ip_dst, src_port, dst_port, pi->proto); } else { dlog("[D] Only CTX with AF_INET and AF_INET6 are supported: %d\n", af); return 0; } cxt = bucket[hash]; head = cxt; /* Search through the bucket */ while (cxt != NULL) { /* Two-way compare of given connection against connection table */ if (af == AF_INET) { if (CMP_CXT4(cxt, IP4ADDR(ip_src), src_port, IP4ADDR(ip_dst), dst_port)) { /* Client sends first packet (TCP/SYN - UDP?) hence this is a client */ dlog("[D] Found existing v4 client connection.\n"); return cxt_update_client(cxt, pi); } else if (CMP_CXT4(cxt, IP4ADDR(ip_dst), dst_port, IP4ADDR(ip_src), src_port)) { if (pi->sc == SC_SERVER) { /* This is a server */ dlog("[D] Found existing v4 server connection.\n"); return cxt_update_server(cxt, pi); } else { /* This is a client, where we saw a mid-stream DNS response first */ dlog("[D] Found existing unknown v4 server connection.\n"); return cxt_update_client(cxt, pi); } } } else if (af == AF_INET6) { if (CMP_CXT6(cxt, ip_src, src_port, ip_dst, dst_port)) { dlog("[D] Found existing v6 client connection.\n"); return cxt_update_client(cxt, pi); } else if (CMP_CXT6(cxt, ip_dst, dst_port, ip_src, src_port)) { dlog("[D] Found existing v6 client connection.\n"); return cxt_update_server(cxt, pi); } } cxt = cxt->next; } /* Bucket turned upside down didn't yield anything. New connection */ dlog("[D] New connection.\n"); cxt = cxt_new(pi); /* New connections are pushed on to the head of bucket[s_hash] */ cxt->next = head; if (head != NULL) { /* Are we double linked? */ head->prev = cxt; } bucket[hash] = cxt; pi->cxt = cxt; return cxt_update_unknown(cxt, pi); }
int cx_track(packetinfo *pi) { struct in6_addr *ip_src; struct in6_addr *ip_dst; struct in6_addr ips; struct in6_addr ipd; uint16_t src_port = pi->s_port; uint16_t dst_port = pi->d_port; int af = pi->af; connection *cxt = NULL; connection *head = NULL; uint32_t hash; if(af== AF_INET6){ ip_src = &PI_IP6SRC(pi); ip_dst = &PI_IP6DST(pi); }else { // ugly hack :( // the way we do ip4/6 is DIRTY // FIX IT?!!? ips.s6_addr32[0] = pi->ip4->ip_src; ipd.s6_addr32[0] = pi->ip4->ip_dst; ip_src = &ips; ip_dst = &ipd; } // find the right connection bucket if (af == AF_INET) { hash = CXT_HASH4(IP4ADDR(ip_src),IP4ADDR(ip_dst)); } else if (af == AF_INET6) { hash = CXT_HASH6(ip_src,ip_dst); } cxt = bucket[hash]; head = cxt; // search through the bucket while (cxt != NULL) { // Two-way compare of given connection against connection table if (af == AF_INET) { if (CMP_CXT4(cxt,IP4ADDR(ip_src),src_port,IP4ADDR(ip_dst),dst_port)){ // Client sends first packet (TCP/SYN - UDP?) hence this is a client return cxt_update_client(cxt, pi); } else if (CMP_CXT4(cxt,IP4ADDR(ip_dst),dst_port,IP4ADDR(ip_src),src_port)) { // This is a server (Maybe not when we start up but in the long run) return cxt_update_server(cxt, pi); } } else if (af == AF_INET6) { if (CMP_CXT6(cxt,ip_src,src_port,ip_dst,dst_port)){ return cxt_update_client(cxt, pi); } else if (CMP_CXT6(cxt,ip_dst,dst_port,ip_src,src_port)){ return cxt_update_server(cxt, pi); } } cxt = cxt->next; } // bucket turned upside down didn't yeild anything. new connection cxt = cxt_new(pi); if(config.cflags & CONFIG_CXWRITE) log_connection(cxt, stdout, CX_NEW); /* * New connections are pushed on to the head of bucket[s_hash] */ cxt->next = head; if (head != NULL) { // are we doubly linked? head->prev = cxt; } bucket[hash] = cxt; pi->cxt = cxt; /* * Return value should be 1, telling to do client service fingerprinting */ return 1; }