Esempio n. 1
0
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;
	}
}
Esempio n. 2
0
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;
	}
}
Esempio n. 3
0
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--;
}
Esempio n. 4
0
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;
	}
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
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;
	}
}
Esempio n. 7
0
/* 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;
	}
}
Esempio n. 8
0
/*
 * 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);
}
Esempio n. 9
0
/**
 * 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;
    }
}
Esempio n. 10
0
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;
	    }
	}
}