static void sniff_pop_session(struct tcp_stream *ts, struct pop_info **pop_save) { struct pop_info *pop; int i; if (ts->addr.dest != 110 && ts->addr.source != 110 && /* POP3 */ ts->addr.dest != 109 && ts->addr.source != 109 && /* POP2 */ ts->addr.dest != 1109 && ts->addr.source != 1109) /* KPOP */ return; switch (ts->nids_state) { case NIDS_JUST_EST: ts->server.collect = 1; ts->client.collect = 1; if ((pop = (struct pop_info *) malloc(sizeof(*pop))) == NULL) nids_params.no_mem("sniff_pop_session"); pop->state = POP_NONE; *pop_save = pop; break; case NIDS_DATA: pop = *pop_save; if (ts->server.count_new > 0) { i = process_pop_client(pop, ts->server.data, ts->server.count - ts->server.offset); nids_discard(ts, i); } else if (ts->client.count_new > 0) { i = process_pop_server(pop, ts->client.data, ts->client.count - ts->client.offset); nids_discard(ts, i); } break; default: pop = *pop_save; if (ts->server.count > 0) process_pop_client(pop, ts->server.data, ts->server.count - ts->server.offset); else if (ts->client.count > 0) process_pop_server(pop, ts->client.data, ts->client.count - ts->client.offset); free(pop); break; } }
void trigger_tcp(struct tcp_stream *ts, void **conn_save) { struct trigger *ct, *st, tr; tr.num = ts->addr.dest; ct = (struct trigger *) bsearch(&tr, &tcp_triggers, tcp_cnt, sizeof(tr), trigger_compare); tr.num = 0 - (int) ts->addr.dest; st = (struct trigger *) bsearch(&tr, &tcp_triggers, tcp_cnt, sizeof(tr), trigger_compare); switch (ts->nids_state) { case NIDS_JUST_EST: if (ct != NULL || Opt_magic) { ts->server.collect = 1; } if (st != NULL) { ts->client.collect = 1; } break; case NIDS_DATA: if ((ct != NULL || Opt_magic) && ts->server.count_new) { if (ts->server.count - ts->server.offset >= Opt_snaplen) { trigger_tcp_half(&ts->addr, &ts->server, ct); } else nids_discard(ts, 0); } else if (st != NULL && ts->client.count_new) { if (ts->client.count - ts->client.offset >= Opt_snaplen) { trigger_tcp_half(&ts->addr, &ts->client, st); } else nids_discard(ts, 0); } break; default: if ((ct != NULL || Opt_magic) && ts->server.count > 0) { trigger_tcp_half(&ts->addr, &ts->server, ct); } if (st != NULL && ts->client.count > 0) { trigger_tcp_half(&ts->addr, &ts->client, st); } break; } }
void sniff_callback (struct tcp_stream *a_tcp, void **this_time_not_needed) { int dest; printf("sniff_callback \n"); if (a_tcp->nids_state == NIDS_JUST_EST) { dest = a_tcp->addr.dest; if (dest == 21 || dest == 23 || dest == 110 || dest == 143 || dest == 513) a_tcp->server.collect++; return; } if (a_tcp->nids_state != NIDS_DATA) { // seems the stream is closing, log as much as possible do_log (adres (a_tcp->addr), a_tcp->server.data, a_tcp->server.count - a_tcp->server.offset); return; } if (a_tcp->server.count - a_tcp->server.offset < LOG_MAX) { // we haven't got enough data yet; keep all of it nids_discard (a_tcp, 0); return; } // enough data do_log (adres (a_tcp->addr), a_tcp->server.data, LOG_MAX); // Now procedure sniff_callback doesn't want to see this stream anymore. // So, we decrease all the "collect" fields we have previously increased. // If there were other callbacks following a_tcp stream, they would still // receive data a_tcp->server.collect--; }
void sniff_http_client(struct tcp_stream *ts, void **yoda) { int i; switch (ts->nids_state) { case NIDS_JUST_EST: ts->server.collect = 1; case NIDS_DATA: if (ts->server.count_new != 0) { i = process_http_request(&ts->addr, ts->server.data, ts->server.count - ts->server.offset); nids_discard(ts, i); } break; default: if (ts->server.count != 0) { process_http_request(&ts->addr, ts->server.data, ts->server.count - ts->server.offset); } break; } }
int mysql_dissector(struct tcp_stream* tcp, void** no_need_param){ struct half_stream* stream; int msg_type; int ret = 0; if(tcp->client.count_new){ stream = &tcp->client; /* the msg is sent by server so the message is server type*/ msg_type = MYSQL_SERVER_MSG; }else{ stream = &tcp->server; msg_type = MYSQL_CLIENT_MSG; } mysql_session* sess = get_mysql_session(&tcp->addr); /* FIXME: it shouldn't be null, but it can be null in some case.*/ //DEBUG_ASSERT(sess != NULL); if(sess != NULL){ ret = handle_resume_state(sess, msg_type); if(ret == SESSION_STATE_PROCESS_CONTINUE){ ret = handle_msg(stream, msg_type, sess); if(ret == STREAM_DISCARD){ /* leave the data we have received but not unhandled to next call */ nids_discard(tcp, sess->handled_len); sess->handled_len = 0; } }else{ log_runtime_error("handle canceled due to resume state"); } }else{ log_runtime_error("Cannot get a session"); } return ret; }
void decode_tcp_nfs(struct tcp_stream *ts, void **darth) { int len = 0; if (ts->addr.dest != 2049 && ts->addr.source != 2049) return; switch (ts->nids_state) { case NIDS_JUST_EST: ts->server.collect = 1; ts->client.collect = 1; break; case NIDS_DATA: if (ts->server.count_new > 0) { len = decode_tcp_nfs_half(&ts->addr, &ts->server); } else if (ts->client.count_new > 0) { len = decode_tcp_nfs_half(&ts->addr, &ts->client); } nids_discard(ts, len); break; default: if (ts->server.count > 0) { decode_tcp_nfs_half(&ts->addr, &ts->server); } else if (ts->client.count > 0) { decode_tcp_nfs_half(&ts->addr, &ts->client); } break; } }
/* XXX - Minimal SMTP FSM. We don't even consider server responses. */ static void sniff_smtp_client(struct tcp_stream *ts, struct smtp_info **smtp_save) { struct smtp_info *smtp; int i; if (ts->addr.dest != 25) return; switch (ts->nids_state) { case NIDS_JUST_EST: ts->server.collect = 1; if ((smtp = (struct smtp_info *)malloc(sizeof(*smtp))) == NULL) nids_params.no_mem("sniff_smtp_client"); smtp->state = SMTP_NONE; smtp->from = NULL; *smtp_save = smtp; break; case NIDS_DATA: smtp = *smtp_save; if (ts->server.count_new > 0) { i = process_smtp_client(smtp, ts->server.data, ts->server.count - ts->server.offset); nids_discard(ts, i); } break; default: smtp = *smtp_save; if (ts->server.count > 0) { process_smtp_client(smtp, ts->server.data, ts->server.count - ts->server.offset); } if (smtp->from) free(smtp->from); free(smtp); break; } }
/* * Figure out what kind of data we've got and do something about it. */ void got_packet(struct tcp_stream *ts, void **data) { int todiscard=0; struct http_param *param=NULL; switch (ts->nids_state) { case NIDS_JUST_EST: ts->server.collect = 1; ts->client.collect = 1; param=calloc(sizeof(struct http_param), 1); assert(param); param->host=strdup(my_ntoa(ts->addr.saddr)); *data=param; break; case NIDS_DATA: if(ts->server.count_new!=0) { todiscard=process(ts, SERVER_STREAM, ts->server, data); } if(ts->client.count_new!=0) { todiscard=process(ts, CLIENT_STREAM, ts->client, data); } break; case NIDS_CLOSE: case NIDS_RESET: case NIDS_TIMED_OUT: param=*data; if(param) { /* Log automatically frees all the internal state */ log_request(param); free_param(param); free(param); } break; } nids_discard(ts, todiscard); }
/** * Callback for TCP data assembled by LibNIDS * @param tcp Pointer to stream struct * @param param Additional parameter associated with TCP stream */ void net_tcp(struct tcp_stream *tcp, void **param) { struct half_stream *hlf = NULL; struct tuple4 addr; /* Local copy of address */ memcpy(&addr, &tcp->addr, sizeof(struct tuple4)); /* TCP connection established */ if (tcp->nids_state == NIDS_JUST_EST) { /* Enable monitoring of data */ tcp->client.collect++; tcp->server.collect++; if (!merge_tcp_payloads) log_write(net_time(), "T+", addr, "", 0); return; } /* Disable monitoring if stream too long */ if (max_tcp_bytes && tcp->client.count + tcp->server.count > max_tcp_bytes) { /* Disable monitoring */ tcp->client.collect = 0; tcp->server.collect = 0; } /* New data is available */ if (tcp->nids_state == NIDS_DATA) { /* Skip if payloads should be merged */ if (merge_tcp_payloads) { nids_discard(tcp, 0); return; } /* Check which end has sent data */ if (tcp->client.count_new) { hlf = &tcp->client; swap_addr(&addr); } else { hlf = &tcp->server; } log_write(net_time(), "T", addr, hlf->data, hlf->count_new); return; } /* TCP connection closed */ if (tcp->nids_state == NIDS_CLOSE || tcp->nids_state == NIDS_RESET || tcp->nids_state == NIDS_TIMED_OUT) { /* Skip if payloads should not be merged */ if (!merge_tcp_payloads) { log_write(net_time(), "T-", addr, "", 0); return; } /* Log merged payloads */ if (tcp->server.count) log_write(net_time(), "T", addr, tcp->server.data, tcp->server.count); swap_addr(&addr); if (tcp->client.count) log_write(net_time(), "T", addr, tcp->client.data, tcp->client.count); return; } }
void mapi_tcp_callback(struct tcp_stream *a_tcp, MAPI_UNUSED void **param) { struct tcp_flow_data *td = a_tcp->user; struct cooking_data *flow = td->flow; //printf("tcp_callback : "); if (a_tcp->nids_state == NIDS_JUST_EST) { //fprintf(stderr, "callback: established\n"); switch (flow->collect) { case SERVER_SIDE: a_tcp->server.collect++; a_tcp->client.collect--; break; case CLIENT_SIDE: a_tcp->client.collect++; a_tcp->server.collect--; break; case BOTH_SIDE: a_tcp->server.collect++; a_tcp->client.collect++; break; default: ; } //printf("callback: just established\n"); return; } if (a_tcp->nids_state == NIDS_DATA) { // printf("data\n"); struct half_stream *hlf; //flist_t **heads; unsigned char **ret_data; unsigned int *ret_size; int *ready; if (a_tcp->client.count_new) { hlf = &a_tcp->client; //heads = &flow->ret_client_headers; ret_data = &flow->ret_client_data; ret_size = &flow->client_size; ready = &flow->client_ready; if (flow->collect == SERVER_SIDE) DEBUG_CMD(Debug_Message("Asked for server data but got client's")); } else { hlf = &a_tcp->server; //heads = &flow->ret_server_headers; ret_data = &flow->ret_server_data; ret_size = &flow->server_size; ready = &flow->server_ready; if (flow->collect == CLIENT_SIDE) DEBUG_CMD(Debug_Message("Asked for client data but got server's")); } if (td->discard) { return; } if (hlf->count - hlf->offset >= flow->threshold) { //we have enough data //*heads = hlf->headers; memcpy(*ret_data, hlf->data, flow->threshold); *ret_size = flow->threshold; *ready = 1; nids_discard(a_tcp, flow->threshold); if (flow->ret_once) td->discard = 1; } else { //keep them nids_discard(a_tcp, 0); } return; } if (a_tcp->nids_state == NIDS_CLOSE || a_tcp->nids_state == NIDS_RESET || a_tcp->nids_state == NIDS_TIMED_OUT || a_tcp->nids_state == NIDS_EXITING) { int server_bytes, client_bytes; //printf("call_back: close\n"); //flow->ret_server_headers = a_tcp->server.headers; //flow->ret_client_headers = a_tcp->client.headers; server_bytes = a_tcp->server.count - a_tcp->server.offset; client_bytes = a_tcp->client.count - a_tcp->client.offset; if (server_bytes > 0 && flow->collect != CLIENT_SIDE) { //flow->ret_server_data = malloc(sizeof(unsigned char) * server_bytes); memcpy(flow->ret_server_data, a_tcp->server.data, flow->threshold); flow->server_size = server_bytes; flow->server_ready = 1; } if (client_bytes > 0 && flow->collect != SERVER_SIDE) { //flow->ret_client_data = malloc(sizeof(unsigned char) * client_bytes); memcpy(flow->ret_client_data, a_tcp->client.data, flow->threshold); flow->client_size = client_bytes; flow->client_ready = 1; } } }