📄 tcp.c
字号:
#include "tcpip.h"/* Generator */struct generator tcp_gen=init_generator("sig.tcp", NULL);static int tcp_serialize(struct packet *, unsigned int, char *, int);static void *tcp_deserialize(struct packet*, unsigned int, char *, int);struct proto tcp_p={ .name="tcp", .decode=tcp_decode, .print=tcp_dprint, .sig_add=tcp_commit, .sig_match=tcp_match, .serialize=tcp_serialize, .deserialize=tcp_deserialize, .free=free,};struct proto_req tcp_r[]={ proto_request("ip", 6), null_request()};/* for serialize/deserialize *//* XXX: are htonl() and ntohl() interchangable on all CPUs? */static void tcp_swapbytes(struct tcp_stream *s, struct tcp_stream *f){ f->state=s->state; f->flags=s->flags; f->scale=s->scale; f->reserved=s->reserved; f->ts_recent=htonl(s->ts_recent); f->ts_recent_stamp=htonl(s->ts_recent_stamp); f->snd_una=htonl(s->snd_una); f->snd_nxt=htonl(s->snd_una); f->rcv_nxt=htonl(s->snd_una); f->rcv_wnd=htonl(s->snd_una); f->rcv_wup=htonl(s->snd_una); f->isn=htonl(s->isn);}static int tcp_serialize(struct packet *p, unsigned int i, char *buf, int len){ struct tcp_session *s=(struct tcp_session *)p->layer[i].session; struct tcp_serial *f=(struct tcp_serial *)buf; if ( len < sizeof(struct tcp_serial) ) return -1; /* Already network byte order */ f->c_addr=s->c_addr; f->s_addr=s->s_addr; f->c_port=s->c_port; f->s_port=s->s_port; tcp_swapbytes(&s->client, &f->client); tcp_swapbytes(&s->server, &f->server); return sizeof(*f);}/* Remember: this data is un-trusted so validate it! */static void *tcp_deserialize(struct packet *p, unsigned int i, char *buf, int len){ struct tcp_session *s; struct tcp_serial *f=(struct tcp_serial *)buf; if ( len < sizeof(*f) ) return NULL; /* validate input */ if ( f->server.state >= TCP_MAX_STATES ) return NULL; if ( f->client.state >= TCP_MAX_STATES ) return NULL; if ( !(s=calloc(1, sizeof(*s))) ) return NULL; /* already network byte order */ s->c_addr=f->c_addr; s->s_addr=f->s_addr; s->c_port=f->c_port; s->s_port=f->s_port; tcp_swapbytes(&f->client, &s->client); tcp_swapbytes(&f->server, &s->server); return s;}int tcp_dprint(struct layer *l, char *buf, int buflen){ char tcpflags[]="FSRPAU12"; char disp[9]; int n, x; for(n=0,x=1; n<8; n++, x*=2) { if ( l->h.tcp->flags.flags & x ){ disp[n]=tcpflags[n]; }else{ disp[n]='*'; } }disp[8]='\0'; return snprintf(buf, buflen, "%u > %u [%s] seq=0x%x ack=0x%x win=%u", ntohs(l->h.tcp->sport), ntohs(l->h.tcp->dport), disp, ntohl(l->h.tcp->seq), ntohl(l->h.tcp->ack), ntohs(l->h.tcp->win));}static inline u_int32_t tcp_csum(struct packet *pkt, unsigned int l){ struct pkt_iphdr *iph=pkt->layer[l].h.ip; struct pkt_tcphdr *tcph=pkt->layer[l+1].h.tcp; struct tcp_phdr ph; u_int16_t *tmp; u_int32_t sum=0; u_int16_t len, csum; int i; if ( pkt->layer[l].flags&FLAG_IP_DTRUNC ) return 0; len=ntohs(iph->tot_len) - (iph->ihl<<2); /* Make pseudo-header */ ph.sip=iph->saddr; ph.dip=iph->daddr; ph.zero=0; ph.proto=iph->protocol; ph.tcp_len=htons(len); /* Checksum the pseudo-header */ tmp=(u_int16_t *)&ph; for(i=0; i<6; i++) { sum+=tmp[i]; if(sum & 0x80000000) { sum = (sum & 0xffff) + (sum >> 16); } } /* Checksum the header+data */ tmp=(u_int16_t *)tcph; for(i=0; i<len>>1; i++) { sum+=tmp[i]; if(sum & 0x80000000) { sum = (sum & 0xffff) + (sum >> 16); } } /* Deal with last byte (if odd number of bytes) */ if ( len&1 ) { union { u_int8_t b[2]; u_int16_t s; }f; f.b[0]=((u_int8_t *)tcph)[len-1]; f.b[1]=0; sum+=f.s; } while(sum >> 16) sum = (sum & 0xffff) + (sum >> 16); csum=(~sum) & 0xffff; return csum ? 0 : FLAG_TCP_CSUM;}void tcp_decode(struct packet *p){ struct layer *l=&p->layer[p->llen]; /* Check it is at least minimum size */ if ( l->h.raw+sizeof(struct pkt_tcphdr) > p->end ) { return; } /* Use the doff field to decode the packet */ if ( (p->layer[p->llen+1].h.raw= l->h.raw+(l->h.tcp->doff<<2)) > p->end ) { return; } p->llen++; if ( p->llen >= PKT_LAYERS ) return; /* State tracking */ if ( tcp_stateful ) { l->flags|=tcp_csum(p, p->llen-2); tcpstream_process(p, p->llen-2); return; } if ( p->layer[p->llen].h.raw<p->end ) p->layer[p->llen++].proto=NULL; dispatch(p);}/* =================================================== * PACKET MATCHING STUFF BEYOND THIS POINT * =================================================== */struct sig_node tcp_root;void tcp_match(struct packet *p, unsigned int l){ l--; detect_set(&cur_alert, &alert_depth); detect(tcp_root.child, p, l); if ( cur_alert ) alert(&tcp_gen, p, cur_alert);}int tcp_commit(struct rule *r){ struct criteria *c; struct sig_node *x; struct matcher *m; struct alert *a; unsigned int i; int forceflow=(tcp_stateful) ? 1 : 0; /* Can't handle this case */ if ( r->num_criteria==0 ) return 0; if ( !(x=calloc(r->num_criteria+1, sizeof(*x))) ) return 0; /* Copy the alert data */ if ( !(a=calloc(1, sizeof(*a))) ) { free(x); return 0; } memcpy(a, &r->alert, sizeof(*a)); /* Build an array of all the nodes we want to add */ for(c=r->criteria,i=0; c; c=c->next,i++) { char *key; if ( !strcmp(c->crit, "src") ) { key="ip_src"; }else if ( !strcmp(c->crit, "dst") ) { key="ip_dst"; }else if ( !strcmp(c->crit, "sport") ) { key="tcp_sport"; }else if ( !strcmp(c->crit, "dport") ) { key="tcp_dport"; }else if ( !strcmp(c->crit, "flow") || !strcmp(c->crit, "stateless") ) { if ( !tcp_stateful ) { /* dont allow flow or stateless if tcpstream * is disabled */ forceflow=-1; i--; continue; } forceflow=0; key=c->crit; }else key=c->crit; if ( !(m=matcher_find(key)) ) { mesg(M_ERR,"tcp_commit: cannot find '%s' matcher", key); detect_free_sig(x, i); return 0; } x[i].match=m; x[i].n=c->negate; x[i].cost=m->cost; if ( !(x[i].m=m->validate(c->args, &x[i].p, c->modifier, &x[i].cost)) ) { detect_free_sig(x, i); return 0; } } /* Enforce a default policy on flow */ if ( forceflow==1 ) { if ( !(m=matcher_find("flow")) ) { mesg(M_ERR,"tcp_commit: cannot find '%s' matcher", "flow"); detect_free_sig(x, i); return 0; } x[i].match=m; x[i].n=0; x[i].cost=m->cost; if ( !(x[i].m=m->validate(NULL,&x[i].p, NULL, &x[i].cost)) ) { detect_free_sig(x, i); return 0; } } return detect_add_sig(x, r->num_criteria+forceflow, &tcp_root, a);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -