void service_udp4(packetinfo *pi, signature* sig_serv_udp) { int rc; /* PCRE */ int ovector[15]; signature *tmpsig; bstring app, service_name; app = service_name = NULL; if (pi->plen < 5 ) return; /* should make a config.tcp_client_flowdept etc * a range between 500-1000 should be good! */ tmpsig = sig_serv_udp; while (tmpsig != NULL) { rc = pcre_exec(tmpsig->regex, tmpsig->study, (const char*) pi->payload, pi->plen, 0, 0, ovector, 15); if (rc != -1) { app = get_app_name(tmpsig, pi->payload, ovector, rc); //printf("[*] - MATCH SERVICE IPv4/UDP: %s\n",(char *)bdata(app)); update_asset_service(pi, tmpsig->service, app); pi->cxt->check |= CXT_SERVICE_DONT_CHECK; bdestroy(app); return; } tmpsig = tmpsig->next; } /* * If no sig is found/mached, use default port to determin. */ if (pi->sc == SC_CLIENT && !ISSET_CLIENT_UNKNOWN(pi)) { if ((service_name = (bstring) check_known_port(IP_PROTO_UDP,ntohs(pi->d_port))) !=NULL ) { update_asset_service(pi, UNKNOWN, service_name); pi->cxt->check |= CXT_CLIENT_UNKNOWN_SET; bdestroy(service_name); } else if ((service_name = (bstring) check_known_port(IP_PROTO_UDP,ntohs(pi->s_port))) !=NULL ) { reverse_pi_cxt(pi); pi->d_port = pi->udph->src_port; update_asset_service(pi, UNKNOWN, service_name); pi->d_port = pi->udph->dst_port; pi->cxt->check |= CXT_CLIENT_UNKNOWN_SET; bdestroy(service_name); } } else if (pi->sc == SC_SERVER && !ISSET_SERVICE_UNKNOWN(pi)) { if ((service_name = (bstring) check_known_port(IP_PROTO_UDP,ntohs(pi->s_port))) !=NULL ) { update_asset_service(pi, UNKNOWN, service_name); pi->cxt->check |= CXT_SERVICE_UNKNOWN_SET; bdestroy(service_name); } else if ((service_name = (bstring) check_known_port(IP_PROTO_UDP,ntohs(pi->d_port))) !=NULL ) { reverse_pi_cxt(pi); update_asset_service(pi, UNKNOWN, service_name); pi->cxt->check |= CXT_SERVICE_UNKNOWN_SET; bdestroy(service_name); } } }
/* ---------------------------------------------------------- * FUNCTION : update_asset_service * DESCRIPTION : This function will update the service and * : application fields of an asset. * INPUT : 0 - IP Address * : 1 - Port * : 2 - Proto * : 3 - Service * : 4 - Application * RETURN : 0 - Success! * : 1 - Failure! * ---------------------------------------------------------- */ short update_asset_service(packetinfo *pi, bstring service, bstring application) { serv_asset *tmp_sa = NULL; serv_asset *head_sa = NULL; uint16_t port; if (asset_lookup(pi) == SUCCESS) { if (pi->asset != NULL) { if (pi->sc == SC_CLIENT) { port = pi->d_port; } else { port = pi->s_port; } goto service_update; } else { printf("\nBAD ERROR in update_asset_service\n"); return ERROR; } } else { /* If no asset */ update_asset(pi); return update_asset_service(pi, service, application); } service_update: /* Find asset within linked list */ tmp_sa = head_sa = pi->asset->services; pi->asset->last_seen = pi->pheader->ts.tv_sec; while (tmp_sa != NULL) { if (port == tmp_sa->port && pi->proto == tmp_sa->proto) { /* * Found! * If we have an id for the service which is != unknown AND the id now is unknown * - just increment i_attempts untill MAX_PKT_CHECK before replacing with unknown * * NEW: No more unknown :) * But now we have generic service for the port, example: @https * So now we just check the first char of the string for '@'. * if (application->data[0] != '@') (If the service matched dont starts with a '@') * and the service registered in the service_asset starts with '@', discard it and * register the new asset! */ if ((application->data[0] != '@') && (tmp_sa->application->data[0] == '@')) { tmp_sa->i_attempts = 0; bdestroy(tmp_sa->service); bdestroy(tmp_sa->application); tmp_sa->service = bstrcpy(service); tmp_sa->application = bstrcpy(application); tmp_sa->last_seen = pi->pheader->ts.tv_sec; log_asset_service(pi->asset,tmp_sa, pi->cxt); return SUCCESS; } else if (!(biseq(application, tmp_sa->application) == 1)) { if (tmp_sa->i_attempts > MAX_SERVICE_CHECK) { tmp_sa->i_attempts = 0; bdestroy(tmp_sa->service); bdestroy(tmp_sa->application); tmp_sa->service = bstrcpy(service); tmp_sa->application = bstrcpy(application); tmp_sa->last_seen = pi->pheader->ts.tv_sec; log_asset_service(pi->asset,tmp_sa, pi->cxt); return SUCCESS; } else { tmp_sa->i_attempts++; tmp_sa->last_seen = pi->pheader->ts.tv_sec; return SUCCESS; } } else { tmp_sa->i_attempts = 0; tmp_sa->last_seen = pi->pheader->ts.tv_sec; return SUCCESS; } } tmp_sa = tmp_sa->next; } if (tmp_sa == NULL) { update_service_stats(pi->sc, pi->proto); serv_asset *new_sa = NULL; new_sa = (serv_asset *) calloc(1, sizeof(serv_asset)); new_sa->port = port; if (pi->ip4 != NULL) new_sa->ttl = pi->ip4->ip_ttl; else if (pi->ip6 != NULL) new_sa->ttl = pi->ip6->hop_lmt; new_sa->proto = pi->proto; new_sa->service = bstrcpy(service); new_sa->application = bstrcpy(application); new_sa->role = pi->sc; new_sa->i_attempts = 0; new_sa->first_seen = pi->pheader->ts.tv_sec; new_sa->last_seen = pi->pheader->ts.tv_sec; new_sa->next = pi->asset->services; new_sa->prev = NULL; pi->asset->services = new_sa; log_asset_service(pi->asset, new_sa, pi->cxt); return SUCCESS; } return ERROR; }