void fifo_service (output_plugin *p, asset *main, serv_asset *service, connection *cxt) { FILE *fd; static char sip[INET6_ADDRSTRLEN]; static char dip[INET6_ADDRSTRLEN]; char *role = B64_PRADS_CLIENT; if(!cxt) cxt = &NULL_CXT; /* Print to FIFO */ if (p->data == NULL) { elog("[!] ERROR: File handle not open!\n"); return; } fd = (FILE *)p->data; /* prads_agent.tcl process each line until it receivs a dot by itself */ u_ntop(main->ip_addr, main->af, sip); u_ntop(cxt->d_ip, cxt->af, dip); if ( service->role == SC_SERVER ) { /* SERVER ASSET */ role = B64_PRADS_SERVER; } fprintf(fd, "01\n%s\n%u\n%s\n%u\n%d\n%d\n%d\n%s\n%s\n%lu\n%s\n.\n", sip, htonl(IP4ADDR(&cxt->s_ip)), dip, htonl(IP4ADDR(&cxt->d_ip)), ntohs(cxt->s_port), ntohs(cxt->d_port), service->proto, bdata(service->service), bdata(service->application), main->first_seen, role); fflush(fd); }
/* ---------------------------------------------------------- * FUNCTION : add_asset * DESCRIPTION : This function will add an asset to the * : specified asset data structure. * INPUT : 0 - packetinfo (af, ip_src, vlan) * RETURN : None! * ---------------------------------------------------------- */ void add_asset(packetinfo *pi) { uint64_t hash; asset *masset = NULL; config.pr_s.assets++; masset = (asset *) calloc(1, sizeof(asset)); masset->af = pi->af; masset->vlan = pi->vlan; masset->i_attempts = 0; masset->first_seen = masset->last_seen = pi->pheader->ts.tv_sec; if (pi->af == AF_INET) { if(pi->arph) // mongo arp check //memcpy(&masset->ip_addr.__u6_addr.__u6_addr32[0], pi->arph->arp_spa, sizeof(uint32_t)); IP4ADDR(&masset->ip_addr) = *(uint32_t*) pi->arph->arp_spa; else IP4ADDR(&masset->ip_addr) = PI_IP4SRC(pi); hash = ASSET_HASH4(IP4ADDR(&masset->ip_addr)); } else if (pi->af == AF_INET6) { masset->ip_addr = PI_IP6SRC(pi); hash = ASSET_HASH6(PI_IP6SRC(pi)); } masset->next = passet[hash]; if (passet[hash] != NULL) passet[hash]->prev = masset; masset->prev = NULL; masset->os = NULL; masset->services = NULL; masset->macentry = NULL; passet[hash] = masset; #ifdef DEBUGG /* verbose info for sanity checking */ static char ip_addr_s[INET6_ADDRSTRLEN]; // pi->ip_src does not exist! u_ntop(pi->ip_src, pi->af, ip_addr_s); dlog("[*] asset added: %s\n",ip_addr_s); #endif //return masset; }
/* ---------------------------------------------------------- * FUNCTION : print_stat_sguil * DESC : This function prints stats info to the FIFO file * INPUT : 0 - IP Address * : 1 - Port * : 2 - Protocol * Example : ID \n IP \n NumIP \n PORT \n PROTO \n timestamp \n . \n * 03\n10.10.10.83\n168430163\n22\n6\n1100847309\n.\n * ---------------------------------------------------------- */ void fifo_stat (output_plugin *p, asset *rec, os_asset *os, /*UNUSED*/ connection *cxt) { (void)(cxt); /* UNUSED */ static char ip_addr_s[INET6_ADDRSTRLEN]; if (p->data == NULL) { elog("[!] ERROR: File handle not open!\n"); return; } /* pads_agent.tcl process each line until it receivs a dot by itself */ u_ntop(rec->ip_addr, rec->af, ip_addr_s); fprintf((FILE*)p->data, "03\n%s\n%u\n%d\n%d\n%ld\n.\n", ip_addr_s, htonl(IP4ADDR(&rec->ip_addr)), ntohs(os->port), 6 /*just for now*/, rec->last_seen); fflush((FILE*) p->data); }
/* ---------------------------------------------------------- * FUNCTION : fifo_arp * DESC : This function prints an ARP asset to the FIFO file. * INPUT : 0 - IP Address * : 1 - MAC Address * ---------------------------------------------------------- */ void fifo_arp (output_plugin *p, asset *main) { static char ip_addr_s[INET6_ADDRSTRLEN]; FILE *fd; /* Print to FIFO */ if (p->data == NULL) { elog("[!] ERROR: File handle not open!\n"); return; } fd = (FILE *)p->data; u_ntop(main->ip_addr, main->af, ip_addr_s); if (main->macentry != NULL) { /* prads_agent.tcl process each line until it receivs a dot by itself */ fprintf(fd, "02\n%s\n%u\n%s\n%s\n%lu\n.\n", ip_addr_s, htonl(IP4ADDR(&main->ip_addr)), main->macentry->vendor, hex2mac(main->mac_addr), main->last_seen); } else { /* prads_agent.tcl process each line until it receivs a dot by itself */ fprintf(fd, "02\n%s\n%u\nunknown\n%s\n%lu\n.\n", ip_addr_s, htonl(IP4ADDR(&main->ip_addr)), hex2mac(main->mac_addr), main->last_seen); } fflush(fd); }
const char *u_ntop(const struct in6_addr ip_addr, int af, char *dest) { if (af == AF_INET) { if (!inet_ntop(AF_INET, &IP4ADDR(&ip_addr), dest, INET_ADDRSTRLEN + 1)) { dlog("[E] Something died in inet_ntop\n"); return NULL; } } else if (af == AF_INET6) { if (!inet_ntop(AF_INET6, &ip_addr, dest, INET6_ADDRSTRLEN + 1)) { dlog("[E] Something died in inet_ntop\n"); return NULL; } } return dest; }
void cxtbuffer_write () { connection *cxt; cxt = NULL; cxt = cxt_dequeue(&cxt_log_q); if (cxt == NULL) { /* no more connections in the queue */ return; } connection *next; next = NULL; char stime[80], ltime[80]; time_t tot_time; static char src_s[INET6_ADDRSTRLEN]; static char dst_s[INET6_ADDRSTRLEN]; uint32_t s_ip_t, d_ip_t; FILE *cxtFile; char *cxtfname; cxtfname = ""; asprintf(&cxtfname, "%s/stats.%s.%ld", dpath, dev, tstamp); cxtFile = fopen(cxtfname, "w"); if (cxtFile == NULL) { printf("[*] ERROR: Cant open file %s\n",cxtfname); } else { while ( cxt != NULL ) { tot_time = cxt->last_pkt_time - cxt->start_time; strftime(stime, 80, "%F %H:%M:%S", gmtime(&cxt->start_time)); strftime(ltime, 80, "%F %H:%M:%S", gmtime(&cxt->last_pkt_time)); if ( verbose == 1 ) { if (cxt->ipversion == AF_INET) { if (!inet_ntop(AF_INET, & IP4ADDR(cxt->s_ip), src_s, INET_ADDRSTRLEN + 1 )) perror("Something died in inet_ntop"); if (!inet_ntop(AF_INET, & IP4ADDR(cxt->d_ip), dst_s, INET_ADDRSTRLEN + 1 )) perror("Something died in inet_ntop"); } else if (cxt->ipversion == AF_INET6) { if (!inet_ntop(AF_INET6, &cxt->s_ip, src_s, INET6_ADDRSTRLEN + 1 )) perror("Something died in inet_ntop"); if (!inet_ntop(AF_INET6, &cxt->d_ip, dst_s, INET6_ADDRSTRLEN + 1 )) perror("Something died in inet_ntop"); } printf("%ld%09ju|%s|%s|%ld|%u|%s|%u|",cxt->start_time,cxt->cxid,stime,ltime,tot_time, cxt->proto,src_s,ntohs(cxt->s_port)); printf("%s|%u|%ju|%ju|",dst_s,ntohs(cxt->d_port),cxt->s_total_pkts,cxt->s_total_bytes); printf("%ju|%ju|%u|%u\n",cxt->d_total_pkts,cxt->d_total_bytes,cxt->s_tcpFlags, cxt->d_tcpFlags); } if ( cxt->ipversion == AF_INET6 ) { if ( verbose != 1 ) { if (!inet_ntop(AF_INET6, &cxt->s_ip, src_s, INET6_ADDRSTRLEN + 1 )) perror("Something died in inet_ntop"); if (!inet_ntop(AF_INET6, &cxt->d_ip, dst_s, INET6_ADDRSTRLEN + 1 )) perror("Something died in inet_ntop"); } fprintf(cxtFile,"%ld%09ju|%s|%s|%ld|%u|%s|%u|",cxt->start_time,cxt->cxid,stime,ltime,tot_time, cxt->proto,src_s,ntohs(cxt->s_port)); fprintf(cxtFile,"%s|%u|%ju|%ju|",dst_s,ntohs(cxt->d_port),cxt->s_total_pkts, cxt->s_total_bytes); fprintf(cxtFile,"%ju|%ju|%u|%u\n",cxt->d_total_pkts,cxt->d_total_bytes,cxt->s_tcpFlags, cxt->d_tcpFlags); } connection *tmp = cxt; cxt = cxt_dequeue(&cxt_log_q); /* cxt_requeue(tmp, &cxt_est_q, &cxt_log_q); */ cxt_requeue(tmp, &cxt_log_q, &cxt_spare_q); } free(cxt); cxt=NULL; free(tmp); tmp=NULL; fclose(cxtFile); } cxt = NULL; free(cxtfname); }
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 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 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; }