void process_tcp(u_char * data, int skblen) { struct ip *this_iphdr = (struct ip *)data; struct tcphdr *this_tcphdr = (struct tcphdr *)(data + 4 * this_iphdr->ip_hl); int datalen, iplen; int from_client = 1; unsigned int tmp_ts; struct tcp_stream *a_tcp; struct half_stream *snd, *rcv; ugly_iphdr = this_iphdr; iplen = ntohs(this_iphdr->ip_len); if ((unsigned)iplen < 4 * this_iphdr->ip_hl + sizeof(struct tcphdr)) { nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_HDR, this_iphdr, this_tcphdr); return; } // ktos sie bawi datalen = iplen - 4 * this_iphdr->ip_hl - 4 * this_tcphdr->th_off; if (datalen < 0) { nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_HDR, this_iphdr, this_tcphdr); return; } // ktos sie bawi if ((this_iphdr->ip_src.s_addr | this_iphdr->ip_dst.s_addr) == 0) { nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_HDR, this_iphdr, this_tcphdr); return; } if (!(this_tcphdr->th_flags & TH_ACK)) detect_scan(this_iphdr); if (!nids_params.n_tcp_streams) return; /*FIXME: remove the tcp header check function tempor..*/ #ifdef OSPLIT #ifdef CHECK_TCPHDR_DISABLED #if 0 if (my_tcp_check(this_tcphdr, iplen - 4 * this_iphdr->ip_hl, this_iphdr->ip_src.s_addr, this_iphdr->ip_dst.s_addr)) { nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_HDR, this_iphdr, this_tcphdr); return; } #endif #else if (my_tcp_check(this_tcphdr, iplen - 4 * this_iphdr->ip_hl, this_iphdr->ip_src.s_addr, this_iphdr->ip_dst.s_addr)) { nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_HDR, this_iphdr, this_tcphdr); return; } #endif #endif #if 0 check_flags(this_iphdr, this_tcphdr); //ECN #endif if (!(a_tcp = find_stream(this_tcphdr, this_iphdr, &from_client))) { if ((this_tcphdr->th_flags & TH_SYN) && !(this_tcphdr->th_flags & TH_ACK) && !(this_tcphdr->th_flags & TH_RST)) add_new_tcp(this_tcphdr, this_iphdr); return; } #ifdef OSPLIT struct ipfrag *frag_tag=this_fragments; struct ipfrag *ip_frag_next; if(this_fragments) ip_frag_next=this_fragments->next; /*write all fragment(s) to fp trace file*/ if(is_frag==0) { write_pcap_hdr(a_tcp->fp,(char*)nids_last_pcap_header,sizeof(struct pcap_sf_pkthdr)); write_ip(a_tcp->fp,(char*)this_iphdr,ntohs(this_iphdr->ip_len),(char*)nids_last_pcap_header); } else { /*fragments*/ while(frag_tag!=NULL) { write_pcap_hdr(a_tcp->fp,(char*)(&(frag_tag->pcap_header)),sizeof(struct pcap_sf_pkthdr)); write_ip(a_tcp->fp,(char*)frag_tag->skb->data,frag_tag->wtrace_len,(char*)(&(frag_tag->pcap_header))); free(frag_tag); frag_tag=ip_frag_next; if(ip_frag_next!=NULL) ip_frag_next=ip_frag_next->next; } is_frag=0; } /*set statistic info*/ store_flag=1; #endif if (from_client) { snd = &a_tcp->client; rcv = &a_tcp->server; } else { rcv = &a_tcp->client; snd = &a_tcp->server; } if ((this_tcphdr->th_flags & TH_SYN)) { if (from_client || a_tcp->client.state != TCP_SYN_SENT || a_tcp->server.state != TCP_CLOSE || !(this_tcphdr->th_flags & TH_ACK)) return; if (a_tcp->client.seq != ntohl(this_tcphdr->th_ack)) return; a_tcp->server.state = TCP_SYN_RECV; a_tcp->server.seq = ntohl(this_tcphdr->th_seq) + 1; a_tcp->server.first_data_seq = a_tcp->server.seq; a_tcp->server.ack_seq = ntohl(this_tcphdr->th_ack); a_tcp->server.window = ntohs(this_tcphdr->th_win); if (a_tcp->client.ts_on) { a_tcp->server.ts_on = get_ts(this_tcphdr, &a_tcp->server.curr_ts); if (!a_tcp->server.ts_on) a_tcp->client.ts_on = 0; } else a_tcp->server.ts_on = 0; if (a_tcp->client.wscale_on) { a_tcp->server.wscale_on = get_wscale(this_tcphdr, &a_tcp->server.wscale); if (!a_tcp->server.wscale_on) { a_tcp->client.wscale_on = 0; a_tcp->client.wscale = 1; a_tcp->server.wscale = 1; } } else { a_tcp->server.wscale_on = 0; a_tcp->server.wscale = 1; } return; } if ( ! ( !datalen && ntohl(this_tcphdr->th_seq) == rcv->ack_seq ) && ( !before(ntohl(this_tcphdr->th_seq), rcv->ack_seq + rcv->window*rcv->wscale) || before(ntohl(this_tcphdr->th_seq) + datalen, rcv->ack_seq) ) ) return; if ((this_tcphdr->th_flags & TH_RST)) { if (a_tcp->nids_state == NIDS_DATA) { struct lurker_node *i; a_tcp->nids_state = NIDS_RESET; for (i = a_tcp->listeners; i; i = i->next) (i->item) (a_tcp, &i->data); } nids_free_tcp_stream(a_tcp); return; } /* PAWS check */ if (rcv->ts_on && get_ts(this_tcphdr, &tmp_ts) && before(tmp_ts, snd->curr_ts)) return; if ((this_tcphdr->th_flags & TH_ACK)) { if (from_client && a_tcp->client.state == TCP_SYN_SENT && a_tcp->server.state == TCP_SYN_RECV) { if (ntohl(this_tcphdr->th_ack) == a_tcp->server.seq) { a_tcp->client.state = TCP_ESTABLISHED; a_tcp->client.ack_seq = ntohl(this_tcphdr->th_ack); { struct proc_node *i; struct lurker_node *j; void *data; a_tcp->server.state = TCP_ESTABLISHED; a_tcp->nids_state = NIDS_JUST_EST; for (i = tcp_procs; i; i = i->next) { char whatto = 0; char cc = a_tcp->client.collect; char sc = a_tcp->server.collect; char ccu = a_tcp->client.collect_urg; char scu = a_tcp->server.collect_urg; (i->item) (a_tcp, &data); if (cc < a_tcp->client.collect) whatto |= COLLECT_cc; if (ccu < a_tcp->client.collect_urg) whatto |= COLLECT_ccu; if (sc < a_tcp->server.collect) whatto |= COLLECT_sc; if (scu < a_tcp->server.collect_urg) whatto |= COLLECT_scu; if (nids_params.one_loop_less) { if (a_tcp->client.collect >=2) { a_tcp->client.collect=cc; whatto&=~COLLECT_cc; } if (a_tcp->server.collect >=2 ) { a_tcp->server.collect=sc; whatto&=~COLLECT_sc; } } if (whatto) { j = mknew(struct lurker_node); j->item = i->item; j->data = data; j->whatto = whatto; j->next = a_tcp->listeners; a_tcp->listeners = j; } } #ifdef OSPLIT #if 0 if (!a_tcp->listeners) { nids_free_tcp_stream(a_tcp); return; } #endif #endif a_tcp->nids_state = NIDS_DATA; } } // return; } }
// ------------------------------------------------ // Function: dhcp_send() // ------------------------------------------------ // Input: Message type // TRUE to broadcast answer // Output: TRUE if succesful // ------------------------------------------------ // Description: Send a DHCP message // ------------------------------------------------ BOOL dhcp_send(BYTE type, BOOL broadcast) { PPBUF buf; buf = udp_new(SOCKET_DHCP); if(buf == NULL) return FALSE; DHCP(buf->data)->op = 1; // BOOTREQUEST DHCP(buf->data)->htype = 1; // ETH 10MBPS DHCP(buf->data)->hlen = 6; // 6 bytes ETH MAC DHCP(buf->data)->hops = 0; DHCP(buf->data)->xid = xid.d; DHCP(buf->data)->secs = 0; if(broadcast) { DHCP(buf->data)->flags = HTONS(0x8000); // server must broadcast answer DHCP(buf->data)->ci.d = 0; } else { DHCP(buf->data)->flags = 0; // server must send unicast answer DHCP(buf->data)->ci.d = ip_local[INTERFACE_ETH].d; } DHCP(buf->data)->yi.d = 0; DHCP(buf->data)->gi.d = 0; DHCP(buf->data)->si.d = ip_dhcp.d; os_set((BYTE *)(&DHCP(buf->data)->chaddr), 0, 16+64+128); os_copy((BYTE *)&mac_local, (BYTE *)(&DHCP(buf->data)->chaddr), sizeof(MACADDR)); // -------------- // insert options // -------------- skip(buf, BOOTP_HDR_SIZE); buf->size = BOOTP_HDR_SIZE; write_uint32(buf, 0x63825363); // magic cookie write_byte(buf, DHCP_OPT_TYPE); // DHCP message type write_byte(buf, 1); write_byte(buf, type); write_byte(buf, DHCP_OPT_ID); // DHCP source ID write_byte(buf, 7); write_byte(buf, 1); write_buf(buf, (BYTE *)&mac_local, sizeof(MACADDR)); write_byte(buf, DHCP_OPT_IP); // Request IP address write_byte(buf, 4); write_ip(buf, ip_tmp); #ifdef _DNS write_byte(buf, DHCP_OPT_REQ); // Request options write_byte(buf, 3); write_byte(buf, DHCP_OPT_MASK); write_byte(buf, DHCP_OPT_ROUTER); write_byte(buf, DHCP_OPT_DNS); #else write_byte(buf, DHCP_OPT_REQ); // Request options write_byte(buf, 2); write_byte(buf, DHCP_OPT_MASK); write_byte(buf, DHCP_OPT_ROUTER); #endif write_byte(buf, DHCP_OPT_END); // done with options udp_send(buf); release_buffer(buf); return TRUE; }
static void add_new_tcp(struct tcphdr * this_tcphdr, struct ip * this_iphdr) { struct tcp_stream *tolink; struct tcp_stream *a_tcp; int hash_index; struct tuple4 addr; addr.source = ntohs(this_tcphdr->th_sport); addr.dest = ntohs(this_tcphdr->th_dport); addr.saddr = this_iphdr->ip_src.s_addr; addr.daddr = this_iphdr->ip_dst.s_addr; hash_index = mk_hash_index(addr); if (tcp_num > max_stream) { struct lurker_node *i; int orig_client_state=tcp_oldest->client.state; tcp_oldest->nids_state = NIDS_TIMED_OUT; for (i = tcp_oldest->listeners; i; i = i->next) (i->item) (tcp_oldest, &i->data); nids_free_tcp_stream(tcp_oldest); if (orig_client_state!=TCP_SYN_SENT) nids_params.syslog(NIDS_WARN_TCP, NIDS_WARN_TCP_TOOMUCH, ugly_iphdr, this_tcphdr); } a_tcp = free_streams; if (!a_tcp) { fprintf(stderr, "gdb me ...\n"); pause(); } free_streams = a_tcp->next_free; tcp_num++; tolink = tcp_stream_table[hash_index]; memset(a_tcp, 0, sizeof(struct tcp_stream)); #ifdef OSPLIT struct ipfrag *frag_tag=this_fragments; struct ipfrag *ip_frag_next; if(this_fragments) ip_frag_next=this_fragments->next; a_tcp->fp=split_file[(TCP_file_idx++)%SPLIT_FILE_NUM]; /*write all fragment(s) to fp trace file*/ if(is_frag==0) { write_pcap_hdr(a_tcp->fp,(char*)nids_last_pcap_header,sizeof(struct pcap_sf_pkthdr)); write_ip(a_tcp->fp,(char*)this_iphdr,ntohs(this_iphdr->ip_len),(char*)nids_last_pcap_header); } else { /*fragments*/ while(frag_tag!=NULL) { write_pcap_hdr(a_tcp->fp,(char*)(&(frag_tag->pcap_header)),sizeof(struct pcap_sf_pkthdr)); write_ip(a_tcp->fp,(char*)frag_tag->skb->data,frag_tag->wtrace_len,(char*)(&(frag_tag->pcap_header))); free(frag_tag); frag_tag=ip_frag_next; if(ip_frag_next!=NULL) ip_frag_next=ip_frag_next->next; } is_frag=0; } /*set statistic info*/ store_flag=1; #endif a_tcp->hash_index = hash_index; a_tcp->addr = addr; a_tcp->client.state = TCP_SYN_SENT; a_tcp->client.seq = ntohl(this_tcphdr->th_seq) + 1; a_tcp->client.first_data_seq = a_tcp->client.seq; a_tcp->client.window = ntohs(this_tcphdr->th_win); a_tcp->client.ts_on = get_ts(this_tcphdr, &a_tcp->client.curr_ts); a_tcp->client.wscale_on = get_wscale(this_tcphdr, &a_tcp->client.wscale); a_tcp->server.state = TCP_CLOSE; a_tcp->next_node = tolink; a_tcp->prev_node = 0; if (tolink) tolink->prev_node = a_tcp; tcp_stream_table[hash_index] = a_tcp; a_tcp->next_time = tcp_latest; a_tcp->prev_time = 0; if (!tcp_oldest) tcp_oldest = a_tcp; if (tcp_latest) tcp_latest->prev_time = a_tcp; tcp_latest = a_tcp; }
int main(int argc, char *argv[]){ char bf_ip[SIZE] = "", bf_rfcomm[SIZE] = "", bf_seial[SIZE] = ""; char buffer[20] = ""; int port_no = atoi(argv[1]); uint32_t svc_uuid_int[] = {0x1101, 0x1000, 0x80000080 ,0x5f9b34fb}; FD_ZERO(&readfds); printf("Program start up!\n"); // setup_serial(BAUD, DEVICE_ARDUINO); // setup_rfcomm(svc_uuid_int); setup_ip(port_no); fflush(stdin); FD_SET(STDIN, &readfds); fd_set readfds_temp; while(1){ readfds_temp = readfds; select(FD_SETSIZE, &readfds_temp, NULL, NULL, NULL); // just for jumping out of loop through command if (FD_ISSET(STDIN, &readfds_temp)){ scanf("%s", buffer); if(strcmp(buffer, "end")==0){ break; } } // if (FD_ISSET(fd_rfcomm_server, &readfds_temp)){ // accept_rfcomm(); // } if (FD_ISSET(fd_ip_server, &readfds_temp)){ accept_ip(); } //if all three connections are established, start reading //ip or rfcomm writing should be before serial. // if(fd_rfcomm > 0 && fd_serial > 0 && fd_ip > 0){ // if (FD_ISSET(fd_rfcomm, &readfds_temp)){ // read_rfcomm(bf_rfcomm); // if(strcmp(bf_rfcomm, EXPLORE)==0) // write_serial(bf_rfcomm); // else if(strcmp(bf_rfcomm, RUN)==0) // write_ip(bf_rfcomm); // bzero(bf_rfcomm,sizeof(bf_rfcomm)); // } // if (FD_ISSET(fd_serial, &readfds_temp)){ // read_serial(bf_seial); // write_ip(bf_seial); // bzero(bf_seial,sizeof(bf_seial)); // } if (FD_ISSET(fd_ip, &readfds_temp)){ read_ip(bf_ip); write_ip(bf_ip); // write_serial(bf_ip); bzero(bf_ip,sizeof(bf_ip)); } } // } close_ip(); // close_rfcomm(); // close_serial(); printf("Programm terminating...\n"); }