/*------------------------------------------------------------------------ * tcpok - determine if a received segment is acceptable *------------------------------------------------------------------------ */ Bool tcpok(struct tcb *ptcb, struct ep *pep) { struct ip *pip = (struct ip *)pep->ep_data; struct tcp *ptcp = (struct tcp *) pip->ip_data; int seglen, rwindow; tcpseq wlast, slast, sup; Bool rv; if (ptcb->tcb_state < TCPS_SYNRCVD) return TRUE; seglen = pip->ip_len - IP_HLEN(pip) - TCP_HLEN(ptcp); /* add SYN and FIN */ if (ptcp->tcp_code & TCPF_SYN) ++seglen; if (ptcp->tcp_code & TCPF_FIN) ++seglen; rwindow = ptcb->tcb_rbsize - ptcb->tcb_rbcount; if (rwindow == 0 && seglen == 0) return ptcp->tcp_seq == ptcb->tcb_rnext; wlast = ptcb->tcb_rnext + rwindow - 1; rv = (ptcp->tcp_seq - ptcb->tcb_rnext) >= 0 && (ptcp->tcp_seq - wlast) <= 0; if (seglen == 0) return rv; slast = ptcp->tcp_seq + seglen - 1; rv |= (slast - ptcb->tcb_rnext) >= 0 && (slast - wlast) <= 0; /* If no window, strip data but keep ACK, RST and URG */ if (rwindow == 0) pip->ip_len = IP_HLEN(pip) + TCP_HLEN(ptcp); return rv; }
static int Syslog_FormatIPHeaderLog(OpSyslog_Data *data, Packet *p) { unsigned int s, d, proto, ver, hlen, tos, len, id, off, ttl, csum; s=d=proto=ver=hlen=tos=len=id=off=ttl=csum=0; if(p->iph) { if(p->iph->ip_src.s_addr) s = ntohl( p->iph->ip_src.s_addr); if(p->iph->ip_dst.s_addr) d = ntohl( p->iph->ip_dst.s_addr); if(p->iph->ip_proto) proto = p->iph->ip_proto; if(IP_VER(p->iph)) ver = IP_VER(p->iph); if(IP_HLEN(p->iph)) ver = IP_HLEN(p->iph); if(p->iph->ip_tos) tos = p->iph->ip_tos; if(p->iph->ip_len) len = ntohs(p->iph->ip_len); if(p->iph->ip_id) id = ntohs(p->iph->ip_id); if(p->iph->ip_off) off = (p->iph->ip_off); if(p->iph->ip_ttl) ttl = (p->iph->ip_ttl); if(p->iph->ip_csum) ttl = htons(p->iph->ip_csum); } if( (data->format_current_pos += snprintf(data->formatBuffer,SYSLOG_MAX_QUERY_SIZE, "%u%c%u%c%u%c%u%c%u%c%u%c%u%c%u%c%u%c%u%c%u%c%u", proto,data->field_separators, s, data->field_separators, d, data->field_separators, ver, data->field_separators, hlen, data->field_separators, tos, data->field_separators, len, data->field_separators, id, data->field_separators, #if defined(WORDS_BIGENDIAN) ((off & 0xE000) >> 13),data->field_separators, htons(off & 0x1FFF),data->field_separators, #else ((off & 0x00E0) >> 5),data->field_separators, htons(off & 0xFF1F), data->field_separators, #endif ttl,data->field_separators, csum)) >= SYSLOG_MAX_QUERY_SIZE) { /* XXX */ return 1; } return OpSyslog_Concat(data); }
/*------------------------------------------------------------------------ * icmp - send an ICMP message *------------------------------------------------------------------------ */ int icmp(u_short type, u_short code, IPaddr dst, void *pa1, void *pa2) { struct ep *pep; struct ip *pip; struct icmp *pic; Bool isresp, iserr; int datalen; IcmpOutMsgs++; pep = icsetbuf(type, pa1, &isresp, &iserr); if (pep == 0) { IcmpOutErrors++; return SYSERR; } pip = (struct ip *)pep->ep_data; pic = (struct icmp *) pip->ip_data; datalen = IC_HLEN; /* we fill in the source here, so routing won't break it */ if (isresp) { if (iserr) { if (!icerrok(pep)) { freebuf(pep); return OK; } memcpy(pic->ic_data, pip, IP_HLEN(pip)+8); datalen += IP_HLEN(pip)+8; } icsetsrc(pip); } else pip->ip_src = ip_anyaddr; pip->ip_dst = dst; pic->ic_type = (char) type; pic->ic_code = (char) code; if (!isresp) { if (type == ICT_ECHORQ) pic->ic_seq = (int) pa1; else pic->ic_seq = 0; pic->ic_id = getpid(); } datalen += icsetdata(type, pip, pa2); pic->ic_cksum = 0; pic->ic_cksum = cksum((WORD *)pic, datalen); ipsend(dst, pep, datalen, IPT_ICMP, IPP_INCTL, IP_TTL); return OK; }
/*------------------------------------------------------------------------ * ipfcons - construct a single packet from an IP fragment queue *------------------------------------------------------------------------ */ struct ep * ipfcons(struct ipfq *iq) { struct ep *pep, *peptmp; struct ip *pip; int off, seq; pep = (struct ep *)getbuf(Net.lrgpool); if (pep == (struct ep *)SYSERR) { while (peptmp = (struct ep *)deq(iq->ipf_q)) { IpReasmFails++; freebuf(peptmp); } freeq(iq->ipf_q); iq->ipf_state = IPFF_FREE; return 0; } /* copy the Ether and IP headers */ peptmp = (struct ep *)deq(iq->ipf_q); pip = (struct ip *)peptmp->ep_data; off = IP_HLEN(pip); seq = 0; memcpy(pep, peptmp, EP_HLEN+off); /* copy the data */ while (peptmp != 0) { int dlen, doff; pip = (struct ip *)peptmp->ep_data; doff = IP_HLEN(pip) + seq - ((pip->ip_fragoff&IP_FRAGOFF)<<3); dlen = pip->ip_len - doff; memcpy(pep->ep_data+off, peptmp->ep_data+doff, dlen); off += dlen; seq += dlen; freebuf(peptmp); peptmp = (struct ep *)deq(iq->ipf_q); } /* fix the large packet header */ pip = (struct ip *)pep->ep_data; pip->ip_len = off; pip->ip_fragoff = 0; /* release resources */ freeq(iq->ipf_q); iq->ipf_state = IPFF_FREE; IpReasmOKs++; return pep; }
int InsertIPData(OpAcidDb_Data *op_data, Packet *p) { if(op_data->detail) { if(snprintf(sql_buffer, MAX_QUERY_SIZE, "INSERT INTO iphdr(sid, cid, ip_src, ip_dst, ip_proto, " "ip_ver, ip_hlen, ip_tos, ip_len, ip_id, ip_flags, ip_off, " "ip_ttl, ip_csum) VALUES('%u', '%u', '%u', '%u', '%u', " "'%u', '%u', '%u', '%u', '%u', '%u', '%u', " "'%u', '%u')", op_data->sensor_id, op_data->event_id, ntohl(p->iph->ip_src.s_addr), ntohl(p->iph->ip_dst.s_addr), p->iph->ip_proto, IP_VER(p->iph), IP_HLEN(p->iph), p->iph->ip_tos, ntohs(p->iph->ip_len), ntohs(p->iph->ip_id), #if defined(WORDS_BIGENDIAN) ((p->iph->ip_off & 0xE000) >> 13), htons(p->iph->ip_off & 0x1FFF), #else ((p->iph->ip_off & 0x00E0) >> 5), htons(p->iph->ip_off & 0xFF1F), #endif p->iph->ip_ttl, htons(p->iph->ip_csum)) < MAX_QUERY_SIZE) { Insert(op_data, sql_buffer, NULL); /* XXX: Error Checking */ } /* XXX: IP Options not handled */ } else { if(snprintf(sql_buffer, MAX_QUERY_SIZE,
/*------------------------------------------------------------------------ * ipsend - send an IP datagram to the specified address *------------------------------------------------------------------------ */ int ipsend(IPaddr faddr, struct ep *pep, unsigned datalen, u_char proto, u_char ptos, u_char ttl) { struct ip *pip = (struct ip *) pep->ep_data; pep->ep_type = EPT_IP; pep->ep_order |= EPO_IP|EPO_NET; pip->ip_verlen = (IP_VERSION<<4) | IP_MINHLEN; pip->ip_tos = ptos; pip->ip_len = datalen+IP_HLEN(pip); pip->ip_id = ipackid++; pip->ip_fragoff = 0; pip->ip_ttl = ttl; pip->ip_proto = proto; pip->ip_dst = faddr; /* * special case for ICMP, so source matches destination * on multi-homed hosts. */ if (pip->ip_proto != IPT_ICMP) pip->ip_src = ip_anyaddr; if (enq(nif[NI_LOCAL].ni_ipinq, pep, 0) < 0) { freebuf(pep); IpOutDiscards++; } send(ippid, NI_LOCAL); IpOutRequests++; return OK; }
/*------------------------------------------------------------------------ * lsu_in - handle a received link state update packet *------------------------------------------------------------------------ */ void lsu_in(struct ep *pep) { struct ip *pip = (struct ip *)pep->ep_data; struct ospf *po; struct ospf_if *pif = &ospf_if[pep->ep_ifn]; struct ospf_lsu *plsu; struct ospf_db *pdb, *db_lookup(); struct ospf_nb *pnb; int i; if (pif->if_state <= IFS_WAITING) return; pnb = &pif->if_nbtab[1]; po = (struct ospf *)((char *)pip+IP_HLEN(pip)); for (i=0; i<MAXNBR; ++i, ++pnb) if (pnb->nb_rid == po->ospf_rid) break; if (i == MAXNBR || pnb->nb_state < NBS_EXCHNG) return; /* db update here */ if (headq(pnb->nb_lsrl) && lsr_check(pnb)) freebuf(deq(pnb->nb_lsrl)); /* flooding procedure */ }
static ENC_STATUS IP4_Encode (EncState* enc, Buffer* in, Buffer* out) { int len; uint32_t start = out->end; IPHdr* hi = (IPHdr*)enc->p->layers[enc->layer-1].start; IPHdr* ho = (IPHdr*)(out->base + out->end); PROTO_ID next = NextEncoder(enc); UPDATE_BOUND(out, sizeof(*ho)); /* IPv4 encoded header is hardcoded 20 bytes */ ho->ip_verhl = 0x45; ho->ip_off = 0; ho->ip_id = IpId_Next(); ho->ip_tos = hi->ip_tos; ho->ip_proto = hi->ip_proto; if ( FORWARD(enc) ) { ho->ip_src.s_addr = hi->ip_src.s_addr; ho->ip_dst.s_addr = hi->ip_dst.s_addr; ho->ip_ttl = FwdTTL(enc, hi->ip_ttl); } else { ho->ip_src.s_addr = hi->ip_dst.s_addr; ho->ip_dst.s_addr = hi->ip_src.s_addr; ho->ip_ttl = RevTTL(enc, hi->ip_ttl); } enc->ip_hdr = (uint8_t*)hi; enc->ip_len = IP_HLEN(hi) << 2; if ( next < PROTO_MAX ) { ENC_STATUS err = encoders[next].fencode(enc, in, out); if ( ENC_OK != err ) return err; } if ( enc->proto ) { ho->ip_proto = enc->proto; enc->proto = 0; } len = out->end - start; ho->ip_len = htons((uint16_t)len); ho->ip_csum = 0; /* IPv4 encoded header is hardcoded 20 bytes, we save some * cycles and use the literal header size for checksum */ ho->ip_csum = in_chksum_ip((const uint16_t *)ho, sizeof *ho); return ENC_OK; }
/*------------------------------------------------------------------------ * lsr_in - handle a received link state request packet *------------------------------------------------------------------------ */ void lsr_in(struct ep *pep) { struct ip *pipout, *pip = (struct ip *)pep->ep_data; struct ospf *poout, *po; struct ospf_if *pif = &ospf_if[pep->ep_ifn]; struct ospf_nb *pnb; struct ospf_lsr *plsr; struct ospf_lsu *plsu; struct ospf_db *pdb; struct ep *pepout, *ospflstmpl(struct ospf_if *); unsigned i, nlsr, maxlsapp; if (pif->if_state <= IFS_WAITING) return; pnb = &pif->if_nbtab[1]; po = (struct ospf *)((char *)pip+IP_HLEN(pip)); for (i=0; i<MAXNBR; ++i, ++pnb) if (pnb->nb_rid == po->ospf_rid) break; if (i == MAXNBR || pnb->nb_state < NBS_EXCHNG) return; maxlsapp = (nif[pep->ep_ifn].ni_mtu - IPMHLEN - MINLSULEN); maxlsapp /= (LSSHDRLEN + MAXLSDLEN); pepout = ospflstmpl(pif); if (pepout == 0) return; pipout = (struct ip *)pepout->ep_data; poout = (struct ospf *)pipout->ip_data; plsu = (struct ospf_lsu *)poout->ospf_data; nlsr = (po->ospf_len - MINHDRLEN) / sizeof (struct ospf_lsr); plsr = (struct ospf_lsr *)po->ospf_data; for (i=0; i<nlsr; ++i, ++plsr) { pdb = db_lookup(pif->if_area, plsr->lsr_type, plsr->lsr_lsid); if (pdb == 0) { freebuf(pepout); nb_mismatch(pif, pnb); return; } if (plsu->lsu_nads >= maxlsapp) { lsa_send(pif, pip->ip_src, pepout); if (!(pepout = ospflstmpl(pif))) return; pipout = (struct ip *)pepout->ep_data; poout = (struct ospf *)pipout->ip_data; plsu = (struct ospf_lsu *)poout->ospf_data; } lsa_add(pif, pepout, pdb); } lsa_send(pif, pip->ip_src, pepout); }
/*------------------------------------------------------------------------ * ipdstopts - do host handling of IP options *------------------------------------------------------------------------ */ int ipdstopts(struct netif *pni, struct ep *pep) { struct ip *pip = (struct ip *)pep->ep_data; u_char *popt, *popend; int len; if (IP_HLEN(pip) == IPMHLEN) return OK; popt = pip->ip_data; popend = (u_char *)&pep->ep_data[IP_HLEN(pip)]; /* NOTE: options not implemented yet */ /* delete the options */ len = pip->ip_len-IP_HLEN(pip); /* data length */ if (len) memcpy(pip->ip_data, &pep->ep_data[IP_HLEN(pip)], len); pip->ip_len = IPMHLEN + len; pip->ip_verlen = (pip->ip_verlen&0xf0) | IP_MINHLEN; return OK; }
/*------------------------------------------------------------------------ * tcpreset - generate a reset in response to a bad packet *------------------------------------------------------------------------ */ int tcpreset(struct ep *pepin) { struct ep *pepout; struct ip *pipin = (struct ip *)pepin->ep_data, *pipout; struct tcp *ptcpin = (struct tcp *)pipin->ip_data, *ptcpout; int datalen; if (ptcpin->tcp_code & TCPF_RST) return OK; /* no RESETs on RESETs */ pepout = (struct ep *)getbuf(Net.netpool); if ((int)pepout == SYSERR) return SYSERR; pipout = (struct ip *)pepout->ep_data; pipout->ip_src = pipin->ip_dst; pipout->ip_dst = pipin->ip_src; ptcpout = (struct tcp *)pipout->ip_data; ptcpout->tcp_sport = ptcpin->tcp_dport; ptcpout->tcp_dport = ptcpin->tcp_sport; if (ptcpin->tcp_code & TCPF_ACK) { ptcpout->tcp_seq = ptcpin->tcp_ack; ptcpout->tcp_code = TCPF_RST; } else { ptcpout->tcp_seq = 0; ptcpout->tcp_code = TCPF_RST|TCPF_ACK; } datalen = pipin->ip_len - IP_HLEN(pipin) - TCP_HLEN(ptcpin); if (ptcpin->tcp_code & TCPF_SYN) datalen++; if (ptcpin->tcp_code & TCPF_FIN) datalen++; ptcpout->tcp_ack = ptcpin->tcp_seq + datalen; ptcpout->tcp_offset = TCPHOFFSET; ptcpout->tcp_window = ptcpout->tcp_urgptr = 0; tcph2net(ptcpout); ptcpout->tcp_cksum = 0; ptcpout->tcp_cksum = tcpcksum(pepout, TCPMHLEN); TcpOutSegs++; TcpOutRsts++; return ipsend(pipin->ip_src, pepout, TCPMHLEN, IPT_TCP, IPP_NORMAL, IP_TTL); }
/*------------------------------------------------------------------------ * tcpinp - handle TCP segment coming in from IP *------------------------------------------------------------------------ */ PROCESS tcpinp(void) { struct ep *pep; struct ip *pip; struct tcp *ptcp; struct tcb *ptcb; tcps_iport = pcreate(TCPQLEN); signal(Net.sema); while (TRUE) { pep = (struct ep *)preceive(tcps_iport); if ((int)pep == SYSERR) break; pip = (struct ip *)pep->ep_data; if (tcpcksum(pep, pip->ip_len - IP_HLEN(pip))) { ++TcpInErrs; freebuf(pep); continue; } ptcp = (struct tcp *)pip->ip_data; tcpnet2h(ptcp); /* convert all fields to host order */ pep->ep_order |= EPO_TCP; ptcb = tcpdemux(pep); if (ptcb == 0) { ++TcpInErrs; tcpreset(pep); freebuf(pep); continue; } if (!tcpok(ptcb, pep)) tcpackit(ptcb, pep); else { tcpopts(ptcb, pep); tcpswitch[ptcb->tcb_state](ptcb, pep); } if (ptcb->tcb_state != TCPS_FREE) signal(ptcb->tcb_mutex); freebuf(pep); } }
/*------------------------------------------------------------------------ * ospfcheck - check if a packet is a valid OSPF packet *------------------------------------------------------------------------ */ int ospfcheck(struct ep *pep) { struct ip *pip = (struct ip *)pep->ep_data; struct ospf *po = (struct ospf *)((char *)pip + IP_HLEN(pip)); struct ospf_if *pif = &ospf_if[pep->ep_ifn]; if (pif->if_state == IFS_DOWN) return FALSE; if (po->ospf_version != OSPF_VERSION) return FALSE; if (net2hs(po->ospf_authtype) != pif->if_area->ar_authtype) return FALSE; if (pif->if_area->ar_authtype && memcmp(po->ospf_auth, pif->if_area->ar_auth, AUTHLEN)) return FALSE; memset(po->ospf_auth, 0, AUTHLEN); if (cksum((WORD *)po, net2hs(po->ospf_len))) return FALSE; return TRUE; }
/*------------------------------------------------------------------------ * lsack_in - handle a received link state acknowledgement packet *------------------------------------------------------------------------ */ void lsack_in(struct ep *pep) { struct ip *pip = (struct ip *)pep->ep_data; struct ospf *po; struct ospf_if *pif = &ospf_if[pep->ep_ifn]; struct ospf_lsu *plsu; struct ospf_db *pdb, *db_lookup(); struct ospf_nb *pnb; int i; if (pif->if_state <= IFS_WAITING) return; pnb = &pif->if_nbtab[1]; po = (struct ospf *)((char *)pip+IP_HLEN(pip)); for (i=0; i<MAXNBR; ++i, ++pnb) if (pnb->nb_rid == po->ospf_rid) break; if (i == MAXNBR || pnb->nb_state < NBS_EXCHNG) return; /* check LSA list and remove if appropriate */ }
/*------------------------------------------------------------------------ * tcpackit - generate an ACK for a received TCP packet *------------------------------------------------------------------------ */ int tcpackit(struct tcb *ptcb, struct ep *pepin) { struct ep *pepout; struct ip *pipin = (struct ip *)pepin->ep_data, *pipout; struct tcp *ptcpin = (struct tcp *)pipin->ip_data, *ptcpout; if (ptcpin->tcp_code & TCPF_RST) return OK; if (pipin->ip_len <= IP_HLEN(pipin) + TCP_HLEN(ptcpin) && !(ptcpin->tcp_code & (TCPF_SYN|TCPF_FIN))) return OK; /* duplicate ACK */ pepout = (struct ep *)getbuf(Net.netpool); if ((int)pepout == SYSERR) return SYSERR; pepout->ep_order = ~0; pipout = (struct ip *)pepout->ep_data; pipout->ip_src = pipin->ip_dst; pipout->ip_dst = pipin->ip_src; ptcpout = (struct tcp *)pipout->ip_data; ptcpout->tcp_sport = ptcpin->tcp_dport; ptcpout->tcp_dport = ptcpin->tcp_sport; ptcpout->tcp_seq = ptcb->tcb_snext; ptcpout->tcp_ack = ptcb->tcb_rnext; ptcpout->tcp_code = TCPF_ACK; ptcpout->tcp_offset = TCPHOFFSET; ptcpout->tcp_window = tcprwindow(ptcb); ptcpout->tcp_urgptr = 0; ptcpout->tcp_cksum = 0; tcph2net(ptcpout); pepout->ep_order &= ~EPO_TCP; ptcpout->tcp_cksum = tcpcksum(pepout, TCPMHLEN); TcpOutSegs++; return ipsend(pipin->ip_src, pepout, TCPMHLEN, IPT_TCP, IPP_NORMAL, IP_TTL); }
static void RejectLayer2(ipq_packet_msg_t *m) { IPHdr *iph; TCPHdr *tcph; ICMPHdr *icmph; EtherHdr *eh; int proto; int size = 0; int payload_len = 0; /* pointer to the device to use: according to the libnet manpage * this should be u_char, but I get a compiler warning then. * Making it a char fixes that. VJ. */ char *device = NULL; /* to get the mac address of the interface when in layer2 mode */ struct ether_addr *link_addr; u_char enet_dst[6]; /* mac addr for creating the ethernet packet. */ u_char enet_src[6]; /* mac addr for creating the ethernet packet. */ struct libnet_link_int *network = NULL; /* pointer to link interface struct */ int i = 0; iph = (IPHdr *)(l_tcp + ETH_H); proto = tmpP->iph->ip_proto; iph->ip_src.s_addr = tmpP->iph->ip_dst.s_addr; iph->ip_dst.s_addr = tmpP->iph->ip_src.s_addr; /* set the interface. For Nat/Ip-mode the device we use to send a reset to the offender * is the device on which the packet entered. For bridge-mode indev and outdev are always * equal, so we use indev as well. There is one rare exception to this... if on the Snort_ * inline box a client is run that causes a reset, indev is not set but outdev. */ if(m->indev_name[0] != '\0') device = m->indev_name; else device = m->outdev_name; /* Let's initialize Libnet */ if((network = libnet_open_link_interface(device, errbuf)) == NULL) { libnet_error(LIBNET_ERR_FATAL, "libnet_open_link_interface for device %s failed: %s\n", device, errbuf); return; } /* lets get the mac addr of the interface */ if(!(link_addr = libnet_get_hwaddr(network, device, errbuf))) { libnet_error(LIBNET_ERR_FATAL, "libnet_get_hwaddr failed: %s\n", errbuf); return; } /* copy the mac: the src is set the the interface mac * but only if the mac wasn't supplied in the configfile */ if(pv.enet_src[0] == 0 && pv.enet_src[1] == 0 && pv.enet_src[2] == 0 && pv.enet_src[3] == 0 && pv.enet_src[4] == 0 && pv.enet_src[5] == 0) { /* either user set mac as 00:00:00:00:00:00 or it is blank */ for(i = 0; i < 6; i++) enet_src[i] = link_addr->ether_addr_octet[i]; } else { for(i = 0; i < 6; i++) enet_src[i] = pv.enet_src[i]; } /* copy the mac: the old src now becomes dst */ for(i = 0; i < 6; i++) enet_dst[i] = m->hw_addr[i]; //printf("reset src mac: %02X:%02X:%02X:%02X:%02X:%02X\n", enet_src[0],enet_src[1],enet_src[2],enet_src[3],enet_src[4],enet_src[5]); //printf("reset dst mac: %02X:%02X:%02X:%02X:%02X:%02X\n", enet_dst[0],enet_dst[1],enet_dst[2],enet_dst[3],enet_dst[4],enet_dst[5]); switch(proto) { case IPPROTO_TCP: if (!tmpP->frag_flag) { size = ETH_H + IP_H + TCP_H; eh = (EtherHdr *)l_tcp; iph = (IPHdr *)(l_tcp + ETH_H); tcph = (TCPHdr *)(l_tcp + ETH_H + IP_H); iph->ip_src.s_addr = tmpP->iph->ip_dst.s_addr; iph->ip_dst.s_addr = tmpP->iph->ip_src.s_addr; tcph->th_sport = tmpP->tcph->th_dport; tcph->th_dport = tmpP->tcph->th_sport; tcph->th_seq = tmpP->tcph->th_ack; tcph->th_ack = htonl(ntohl(tmpP->tcph->th_seq) + 1); //printf("Send TCP Rst in Bridge-mode.\n"); /* calculate the checksums */ if (libnet_do_checksum(l_tcp + ETH_H, IPPROTO_TCP, TCP_H) == -1) { libnet_error(LIBNET_ERR_CRITICAL, "SendEthTCPRST: libnet_do_checksum failed for TCP_H"); return; } if (libnet_do_checksum(l_tcp + ETH_H, IPPROTO_IP, IP_H) == -1) { libnet_error(LIBNET_ERR_CRITICAL, "SendEthTCPRST: libnet_do_checksum failed for IP_H"); return; } /* build the ethernet packet */ if (libnet_build_ethernet(enet_dst, enet_src, ETHERTYPE_IP, NULL, 0, l_tcp) == -1) { libnet_error(LIBNET_ERR_CRITICAL, "SendEthTCPRST: libnet_build_ethernet"); return; } /* finally write it to the link */ if(libnet_write_link_layer(network, device, l_tcp, size) < size) { libnet_error(LIBNET_ERR_CRITICAL, "SendEthTCPRST: libnet_write_link_layer"); return; } } /* end if !tmpP->frag_flag */ break; case IPPROTO_UDP: if (!tmpP->frag_flag) { eh = (EtherHdr *)l_icmp; iph = (IPHdr *)(l_icmp + ETH_H); icmph = (ICMPHdr *) (l_icmp + ETH_H + IP_H); iph->ip_src.s_addr = tmpP->iph->ip_dst.s_addr; iph->ip_dst.s_addr = tmpP->iph->ip_src.s_addr; if ((payload_len = ntohs(tmpP->iph->ip_len) - (IP_HLEN(tmpP->iph) << 2)) > 8) { payload_len = 8; } memcpy((char *)icmph + ICMP_UNREACH_H, tmpP->iph, (IP_HLEN(tmpP->iph) << 2) + payload_len); size = ETH_H + IP_H + ICMP_UNREACH_H + (IP_HLEN(tmpP->iph) << 2) + payload_len; iph->ip_len = htons(size); /* calculate the checksums */ if (libnet_do_checksum(l_icmp + ETH_H, IPPROTO_ICMP, size - IP_H) == -1) { libnet_error(LIBNET_ERR_CRITICAL, "SendEthICMPRST: libnet_do_checksum failed for IPPROTO_ICMP"); return; } if (libnet_do_checksum(l_icmp + ETH_H, IPPROTO_IP, IP_H) == -1) { libnet_error(LIBNET_ERR_CRITICAL, "SendEthICMPRST: libnet_do_checksum failed for IPPROTO_IP"); return; } /* build the ethernet packet */ if (libnet_build_ethernet(enet_dst, enet_src, ETHERTYPE_IP, NULL, 0, l_icmp) == -1) { libnet_error(LIBNET_ERR_CRITICAL, "SendEthICMPRST: libnet_build_ethernet"); return; } /* finally write it to the link */ //printf("Send ICMP Rst in Bridge-mode.\n"); if(libnet_write_link_layer(network, device, l_icmp, size) < size) { libnet_error(LIBNET_ERR_CRITICAL, "SendEthICMPRST: libnet_write_link_layer"); return; } } break; } /* end switch(proto) */ /* clean up file-descriptors for the next time we call RejectLayer2 */ if((libnet_close_link_interface(network)) == -1) { libnet_error(LIBNET_ERR_CRITICAL, "libnet_close_link_interface error\n"); } }
/* * Function: static void RejectSocket * * Purpose: send a reject packet (tcp-reset or icmp-unreachable * * Args: none * * Returns: nothing void function */ static void RejectSocket(void) { IPHdr *iph; TCPHdr *tcph; ICMPHdr *icmph; int proto; int size = 0; int payload_len = 0; iph = (IPHdr *)l_tcp; proto = tmpP->iph->ip_proto; iph->ip_src.s_addr = tmpP->iph->ip_dst.s_addr; iph->ip_dst.s_addr = tmpP->iph->ip_src.s_addr; switch(proto) { case IPPROTO_TCP: if (!tmpP->frag_flag) { size = IP_H + TCP_H; iph = (IPHdr *)l_tcp; tcph = (TCPHdr *)(l_tcp + IP_H); iph->ip_src.s_addr = tmpP->iph->ip_dst.s_addr; iph->ip_dst.s_addr = tmpP->iph->ip_src.s_addr; tcph->th_sport = tmpP->tcph->th_dport; tcph->th_dport = tmpP->tcph->th_sport; tcph->th_seq = tmpP->tcph->th_ack; tcph->th_ack = htonl(ntohl(tmpP->tcph->th_seq) + 1); //printf("Send TCP Rst in IP-mode.\n"); /* calculate the checksum */ if (libnet_do_checksum(l_tcp, IPPROTO_TCP, TCP_H) == -1) { libnet_error(LIBNET_ERR_CRITICAL, "SendTCPRST: libnet_do_checksum"); return; } /* write it to the socket */ if(libnet_write_ip(libnet_nd, l_tcp, size) < size) { libnet_error(LIBNET_ERR_CRITICAL, "SendTCPRST: libnet_write_ip"); return; } } /* end if !tmpP->frag_flag */ break; case IPPROTO_UDP: if (!tmpP->frag_flag) { iph = (IPHdr *)l_icmp; icmph = (ICMPHdr *)(l_icmp + IP_H); iph->ip_src.s_addr = tmpP->iph->ip_dst.s_addr; iph->ip_dst.s_addr = tmpP->iph->ip_src.s_addr; if ((payload_len = ntohs(tmpP->iph->ip_len) - (IP_HLEN(tmpP->iph) << 2)) > 8) { payload_len = 8; } memcpy((char *)icmph + ICMP_UNREACH_H, tmpP->iph, (IP_HLEN(tmpP->iph) << 2) + payload_len); size = IP_H + ICMP_UNREACH_H + (IP_HLEN(tmpP->iph) << 2) + payload_len; iph->ip_len = htons(size); /* calculate checksums */ if (libnet_do_checksum(l_icmp, IPPROTO_ICMP, size - IP_H) == -1) { libnet_error(LIBNET_ERR_CRITICAL, "SendICMPRST: libnet_do_checksum failed for IPPROTO_ICMP"); return; } /* finally write to socket */ if(libnet_write_ip(libnet_nd, l_icmp, size) < size) { libnet_error(LIBNET_ERR_CRITICAL, "SendICMPRST: libnet_write_ip"); return; } } /* end if !tmpP->frag_flag */ break; } /* end switch(proto) */ }
static ENC_STATUS IP4_Encode (EncState* enc, Buffer* in, Buffer* out) { int len; uint32_t start = out->end; IPHdr* hi = (IPHdr*)enc->p->layers[enc->layer-1].start; IPHdr* ho = (IPHdr*)(out->base + out->end); PROTO_ID next = NextEncoder(enc); UPDATE_BOUND(out, sizeof(*ho)); len = GET_IP_HDR_LEN(hi) - sizeof(*hi); ho->ip_verhl = 0x45; ho->ip_off = 0; ho->ip_id = IpId_Next(); ho->ip_tos = hi->ip_tos; ho->ip_proto = hi->ip_proto; if ( FORWARD(enc) ) { uint8_t ttl = AdjTTL(hi->ip_ttl); ho->ip_src.s_addr = hi->ip_src.s_addr; ho->ip_dst.s_addr = hi->ip_dst.s_addr; if ( enc->p->ssnptr ) ttl = GetTTL(enc); #ifdef NORMALIZER if ( ttl < ScMinTTL() && ScNewTTL() ) ttl = ScNewTTL(); #endif ho->ip_ttl = ttl; } else { uint8_t ttl = MAX_TTL; ho->ip_src.s_addr = hi->ip_dst.s_addr; ho->ip_dst.s_addr = hi->ip_src.s_addr; if ( enc->p->ssnptr ) ttl = GetTTL(enc); #ifdef NORMALIZER if ( ttl < ScMinTTL() && ScNewTTL() ) ttl = ScNewTTL(); #endif ho->ip_ttl = ttl; } enc->ip_hdr = (uint8_t*)hi; enc->ip_len = IP_HLEN(hi) << 2; if ( next < PROTO_MAX ) { int err = encoders[next].fencode(enc, in, out); if ( err ) return err; } if ( enc->proto ) { ho->ip_proto = enc->proto; enc->proto = 0; } len = out->end - start; ho->ip_len = htons((u_int16_t)len); ip_checksum(ho, len); return ENC_OK; }
uint8_t orig_ip4_ret_hlen(const Packet *p) { return IP_HLEN(p->orig_iph); }
/*------------------------------------------------------------------------ * icmp_in - handle ICMP packet coming in from the network *------------------------------------------------------------------------ */ int icmp_in(struct netif *pni, struct ep *pep) { struct ip *pip; struct icmp *pic; int i, len; pip = (struct ip *)pep->ep_data; pic = (struct icmp *) pip->ip_data; len = pip->ip_len - IP_HLEN(pip); if (cksum((WORD *)pic, len)) { IcmpInErrors++; freebuf(pep); return SYSERR; } IcmpInMsgs++; switch(pic->ic_type) { case ICT_ECHORQ: IcmpInEchos++; return icmp(ICT_ECHORP, 0, pip->ip_src, pep, 0); case ICT_MASKRQ: IcmpInAddrMasks++; if (!gateway) { freebuf(pep); return OK; } pic->ic_type = (char) ICT_MASKRP; *(IPaddr *)pic->ic_data = netmask(pip->ip_dst); break; case ICT_MASKRP: IcmpInAddrMaskReps++; for (i=0; i<Net.nif; ++i) if (nif[i].ni_ip == pip->ip_dst) break; if (i != Net.nif) { setmask(i, *(IPaddr *)pic->ic_data); send(pic->ic_id, ICT_MASKRP); } freebuf(pep); return OK; case ICT_ECHORP: IcmpInEchoReps++; if (send(pic->ic_id, (int)pep) != OK) freebuf(pep); return OK; case ICT_REDIRECT: IcmpInRedirects++; icredirect(pep); return OK; case ICT_DESTUR: IcmpInDestUnreachs++; freebuf(pep); return OK; case ICT_SRCQ: IcmpInSrcQuenchs++; freebuf(pep); return OK; case ICT_TIMEX: IcmpInTimeExcds++; freebuf(pep); return OK; case ICT_PARAMP: IcmpInParmProbs++; freebuf(pep); return OK; case ICT_TIMERQ: IcmpInTimestamps++; freebuf(pep); return OK; case ICT_TIMERP: IcmpInTimestampReps++; freebuf(pep); return OK; default: IcmpInErrors++; freebuf(pep); return OK; } icsetsrc(pip); len = pip->ip_len - IP_HLEN(pip); pic->ic_cksum = 0; pic->ic_cksum = cksum((WORD *)pic, len); IcmpOutMsgs++; ipsend(pip->ip_dst, pep, len, IPT_ICMP, IPP_INCTL, IP_TTL); return OK; }
/* sguil only uses log */ int OpSguil_Log(void *context, void *data) { char timestamp[TIMEBUF_SIZE]; char syslogMessage[SYSLOG_BUF]; char eventInfo[SYSLOG_BUF]; //int MAX_INSERT_LEN = 1024; char insertColumns[MAX_QUERY_SIZE]; char insertValues[MAX_QUERY_SIZE]; char valuesTemp[MAX_QUERY_SIZE]; char ipInfo[38]; char portInfo[16]; char *esc_message; Sid *sid = NULL; ClassType *class_type; UnifiedLogRecord *record = (UnifiedLogRecord *)data; OpSguil_Data *op_data = (OpSguil_Data *)context; Packet p; bzero(syslogMessage, SYSLOG_BUF); bzero(insertColumns, MAX_QUERY_SIZE); bzero(insertValues, MAX_QUERY_SIZE); #if 0 /* this is broken */ /* skip tagged packets, since the db does not have a mechanism to * deal with them properly */ if(record->log.event.event_reference) { LogMessage("Skipping tagged packet %i\n", record->log.event.event_reference); return 0; } #endif RenderTimestamp(record->log.pkth.ts.tv_sec, timestamp, TIMEBUF_SIZE); //fprintf(stdout, "Timestamp: %lu\n", GetMilliseconds()); //fflush(stdout); sid = GetSid(record->log.event.sig_generator, record->log.event.sig_id); if(sid == NULL) sid = FakeSid(record->log.event.sig_generator, record->log.event.sig_id); class_type = GetClassType(record->log.event.classification); //sgBeginTransaction(op_data); /* XXX: Error checking */ /* Build the event insert. */ snprintf(insertColumns, MAX_QUERY_SIZE, "INSERT INTO event (status, sid, cid, signature_id, signature_rev, signature, timestamp, priority, class"); esc_message = malloc(strlen(sid->msg)*2+1); mysql_real_escape_string(op_data->mysql, esc_message, sid->msg, strlen(sid->msg)); if(class_type == NULL) { snprintf(valuesTemp, MAX_QUERY_SIZE, "VALUES ('0', '%u', '%u', '%d', '%d', '%s', '%s', '%u', 'unknown'", op_data->sensor_id, op_data->event_id, sid->sid, sid->rev, esc_message, timestamp, record->log.event.priority); snprintf(eventInfo, SYSLOG_BUF, "RTEvent |0|%u|unknown|%s|%s|%u|%u|%s", record->log.event.priority, pv.hostname, timestamp, op_data->sensor_id, op_data->event_id, sid->msg); } else { snprintf(valuesTemp, MAX_QUERY_SIZE, "VALUES ('0', '%u', '%u', '%d', '%d', '%s', '%s', '%u', '%s'", op_data->sensor_id, op_data->event_id, sid->sid, sid->rev, esc_message, timestamp, record->log.event.priority, class_type->type); snprintf(eventInfo, SYSLOG_BUF, "RTEvent |0|%u|%s|%s|%s|%u|%u|%s", record->log.event.priority, class_type->type, pv.hostname, timestamp, op_data->sensor_id, op_data->event_id, sid->msg); } free(esc_message); insertValues[0] = '\0'; strcat(insertValues, valuesTemp); syslogMessage[0] = '\0'; strcat(syslogMessage, eventInfo); /* decode the packet */ if(DecodePacket(&p, &record->log.pkth, record->pkt + 2) == 0) { if(p.iph) { /* Insert ip header information */ //InsertIPData(op_data, &p); strcat(insertColumns, ",src_ip, dst_ip, ip_proto, ip_ver, ip_hlen, ip_tos, ip_len, ip_id, ip_flags, ip_off, ip_ttl, ip_csum"); snprintf(valuesTemp, MAX_QUERY_SIZE, ",'%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u', '%u'", ntohl(p.iph->ip_src.s_addr), ntohl(p.iph->ip_dst.s_addr), p.iph->ip_proto, IP_VER(p.iph), IP_HLEN(p.iph), p.iph->ip_tos, ntohs(p.iph->ip_len), ntohs(p.iph->ip_id), #if defined(WORDS_BIGENDIAN) ((p.iph->ip_off & 0xE000) >> 13), htons(p.iph->ip_off & 0x1FFF), #else ((p.iph->ip_off & 0x00E0) >> 5), htons(p.iph->ip_off & 0xFF1F), #endif p.iph->ip_ttl, htons(p.iph->ip_csum) < MAX_QUERY_SIZE); strcat(insertValues, valuesTemp); /* SYSLOG - Changed to SguilSendEvent*/ snprintf(ipInfo, 38, "|%u.%u.%u.%u|%u.%u.%u.%u|%u", #if defined(WORDS_BIGENDIAN) (p.iph->ip_src.s_addr & 0xff000000) >> 24, (p.iph->ip_src.s_addr & 0x00ff0000) >> 16, (p.iph->ip_src.s_addr & 0x0000ff00) >> 8, (p.iph->ip_src.s_addr & 0x000000ff), (p.iph->ip_dst.s_addr & 0xff000000) >> 24, (p.iph->ip_dst.s_addr & 0x00ff0000) >> 16, (p.iph->ip_dst.s_addr & 0x0000ff00) >> 8, (p.iph->ip_dst.s_addr & 0x000000ff), #else (p.iph->ip_src.s_addr & 0x000000ff), (p.iph->ip_src.s_addr & 0x0000ff00) >> 8, (p.iph->ip_src.s_addr & 0x00ff0000) >> 16, (p.iph->ip_src.s_addr & 0xff000000) >> 24, (p.iph->ip_dst.s_addr & 0x000000ff), (p.iph->ip_dst.s_addr & 0x0000ff00) >> 8, (p.iph->ip_dst.s_addr & 0x00ff0000) >> 16, (p.iph->ip_dst.s_addr & 0xff000000) >> 24, #endif p.iph->ip_proto); strcat(syslogMessage, ipInfo); /* store layer 4 data for non fragmented packets */ if(!(p.pkt_flags & PKT_FRAG_FLAG)) { switch(p.iph->ip_proto) { case IPPROTO_ICMP: snprintf(portInfo, 16, "|||"); if(!p.icmph) break; strcat(insertColumns, ", icmp_type, icmp_code)"); snprintf(valuesTemp, MAX_QUERY_SIZE, ", '%u', '%u')", p.icmph->icmp_type, p.icmph->icmp_code); strcat(insertValues, valuesTemp); strcat(insertColumns, insertValues); sgInsert(op_data, insertColumns, NULL); sgInsertICMPData(op_data, &p); break; case IPPROTO_TCP: strcat(insertColumns, ", src_port, dst_port)"); snprintf(valuesTemp, MAX_QUERY_SIZE, ", '%u', '%u')", p.sp, p.dp); strcat(insertValues, valuesTemp); strcat(insertColumns, insertValues); sgInsert(op_data, insertColumns, NULL); sgInsertTCPData(op_data, &p); snprintf(portInfo, 16, "|%u|%u|", p.sp, p.dp); break; case IPPROTO_UDP: strcat(insertColumns, ", src_port, dst_port)"); snprintf(valuesTemp, MAX_QUERY_SIZE, ", '%u', '%u')", p.sp, p.dp); strcat(insertValues, valuesTemp); strcat(insertColumns, insertValues); sgInsert(op_data, insertColumns, NULL); sgInsertUDPData(op_data, &p); snprintf(portInfo, 16, "|%u|%u|", p.sp, p.dp); break; } strcat(syslogMessage, portInfo); } else { strcat(syslogMessage, "|||"); } /* Insert payload data */ sgInsertPayloadData(op_data, &p); } else {
/* processGDB(): * This is the function that allows a remote gdb host to connect to * the monitor with gdb at the udp level. The connection command in * gdb to do this is: * * target remote udp:TARGET_IP:TARGET_PORT */ int processGDB(struct ether_header *ehdr,ushort size) { char *gdbp; struct ip *ihdr, *ti, *ri; struct Udphdr *uhdr, *tu, *ru; struct ether_header *te; /* If SHOW_GDB is set (via ether -vg), then we dump the trace to * the console; otherwise, we use mtrace. */ #if INCLUDE_ETHERVERBOSE if (EtherVerbose & SHOW_GDB) gdbTrace = printf; else #endif gdbTrace = Mtrace; ihdr = (struct ip *)(ehdr + 1); uhdr = (struct Udphdr *)((char *)ihdr + IP_HLEN(ihdr)); gdbp = (char *)(uhdr + 1); size = ecs(uhdr->uh_ulen) - sizeof(struct Udphdr); /* Check for ACK/NAK here: */ if (size == 1) { if ((*gdbp == '+') || (*gdbp == '-')) { gdbTrace("GDB_%s\n",*gdbp == '+' ? "ACK" : "NAK"); return(0); } } /* Copy the incoming udp payload (the gdb command) to gdbIbuf[] * and NULL terminate it... */ memcpy((char *)gdbIbuf,(char *)gdbp,size); gdbIbuf[size] = 0; /* Now that we've stored away the GDB command request, we * initially respond with the GDB acknowledgement ('+')... */ te = EtherCopy(ehdr); ti = (struct ip *) (te + 1); ri = (struct ip *) (ehdr + 1); ti->ip_vhl = ri->ip_vhl; ti->ip_tos = ri->ip_tos; ti->ip_len = ecs((1 + (sizeof(struct ip) + sizeof(struct Udphdr)))); ti->ip_id = ipId(); ti->ip_off = ri->ip_off; ti->ip_ttl = UDP_TTL; ti->ip_p = IP_UDP; memcpy((char *)&(ti->ip_src.s_addr),(char *)BinIpAddr, sizeof(struct in_addr)); memcpy((char *)&(ti->ip_dst.s_addr),(char *)&(ri->ip_src.s_addr), sizeof(struct in_addr)); tu = (struct Udphdr *) (ti + 1); ru = (struct Udphdr *) (ri + 1); tu->uh_sport = ru->uh_dport; tu->uh_dport = ru->uh_sport; tu->uh_ulen = ecs((ushort)(sizeof(struct Udphdr) + 1)); gdbp = (char *)(tu+1); *gdbp = '+'; ipChksum(ti); /* Compute checksum of ip hdr */ udpChksum(ti); /* Compute UDP checksum */ sendBuffer(sizeof(struct ether_header) + sizeof(struct ip) + sizeof(struct Udphdr) + 1); /* Wrap the processing of the incoming packet with a set/clear * of the gdbUdp flag so that the other gdb code can act * accordingly. */ gdbUdp = 1; if (gdb_cmd(gdbIbuf) == 0) { gdbUdp = 0; return(0); } gdbUdp = 0; /* Add 1 to the gdbRlen to include the NULL termination. */ gdbRlen++; /* The second respons is only done if gdb_cmd returns non-zero. * It is the response to the gdb command issued by the debugger * on the host. */ te = EtherCopy(ehdr); ti = (struct ip *) (te + 1); ri = (struct ip *) (ehdr + 1); ti->ip_vhl = ri->ip_vhl; ti->ip_tos = ri->ip_tos; ti->ip_len = ecs((gdbRlen + (sizeof(struct ip) + sizeof(struct Udphdr)))); ti->ip_id = ipId(); ti->ip_off = ri->ip_off; ti->ip_ttl = UDP_TTL; ti->ip_p = IP_UDP; memcpy((char *)&(ti->ip_src.s_addr),(char *)BinIpAddr, sizeof(struct in_addr)); memcpy((char *)&(ti->ip_dst.s_addr),(char *)&(ri->ip_src.s_addr), sizeof(struct in_addr)); tu = (struct Udphdr *) (ti + 1); ru = (struct Udphdr *) (ri + 1); tu->uh_sport = ru->uh_dport; tu->uh_dport = ru->uh_sport; tu->uh_ulen = ecs((ushort)(sizeof(struct Udphdr) + gdbRlen)); memcpy((char *)(tu+1),(char *)gdbRbuf,gdbRlen); ipChksum(ti); /* Compute checksum of ip hdr */ udpChksum(ti); /* Compute UDP checksum */ sendBuffer(sizeof(struct ether_header) + sizeof(struct ip) + sizeof(struct Udphdr) + gdbRlen); return(1); }
static int packet_to_data(Packet *p, Event *event, idmef_alert_t *alert) { int i; if ( ! p ) return 0; add_int_data(alert, "snort_rule_sid", event->sig_id); add_int_data(alert, "snort_rule_rev", event->sig_rev); if ( p->iph ) { add_int_data(alert, "ip_ver", IP_VER(p->iph)); add_int_data(alert, "ip_hlen", IP_HLEN(p->iph)); add_int_data(alert, "ip_tos", p->iph->ip_tos); add_int_data(alert, "ip_len", ntohs(p->iph->ip_len)); add_int_data(alert, "ip_id", ntohs(p->iph->ip_id)); add_int_data(alert, "ip_off", ntohs(p->iph->ip_off)); add_int_data(alert, "ip_ttl", p->iph->ip_ttl); add_int_data(alert, "ip_proto", p->iph->ip_proto); add_int_data(alert, "ip_sum", ntohs(p->iph->ip_csum)); for ( i = 0; i < p->ip_option_count; i++ ) { add_int_data(alert, "ip_option_code", p->ip_options[i].code); add_byte_data(alert, "ip_option_data", p->ip_options[i].data, p->ip_options[i].len); } } if ( p->tcph ) { add_int_data(alert, "tcp_seq", ntohl(p->tcph->th_seq)); add_int_data(alert, "tcp_ack", ntohl(p->tcph->th_ack)); add_int_data(alert, "tcp_off", TCP_OFFSET(p->tcph)); add_int_data(alert, "tcp_res", TCP_X2(p->tcph)); add_int_data(alert, "tcp_flags", p->tcph->th_flags); add_int_data(alert, "tcp_win", ntohs(p->tcph->th_win)); add_int_data(alert, "tcp_sum", ntohs(p->tcph->th_sum)); add_int_data(alert, "tcp_urp", ntohs(p->tcph->th_urp)); for ( i = 0; i < p->tcp_option_count; i++ ) { add_int_data(alert, "tcp_option_code", p->tcp_options[i].code); add_byte_data(alert, "tcp_option_data", p->tcp_options[i].data, p->tcp_options[i].len); } } else if ( p->udph ) { add_int_data(alert, "udp_len", ntohs(p->udph->uh_len)); add_int_data(alert, "udp_sum", ntohs(p->udph->uh_chk)); } else if ( p->icmph ) { add_int_data(alert, "icmp_type", p->icmph->type); add_int_data(alert, "icmp_code", p->icmph->code); add_int_data(alert, "icmp_sum", ntohs(p->icmph->csum)); switch ( p->icmph->type ) { case ICMP_ECHO: case ICMP_ECHOREPLY: case ICMP_INFO_REQUEST: case ICMP_INFO_REPLY: case ICMP_ADDRESS: case ICMP_TIMESTAMP: add_int_data(alert, "icmp_id", ntohs(p->icmph->s_icmp_id)); add_int_data(alert, "icmp_seq", ntohs(p->icmph->s_icmp_seq)); break; case ICMP_ADDRESSREPLY: add_int_data(alert, "icmp_id", ntohs(p->icmph->s_icmp_id)); add_int_data(alert, "icmp_seq", ntohs(p->icmph->s_icmp_seq)); add_int_data(alert, "icmp_mask", (uint32_t) ntohl(p->icmph->s_icmp_mask)); break; case ICMP_REDIRECT: add_string_data(alert, "icmp_gwaddr", inet_ntoa(p->icmph->s_icmp_gwaddr)); break; case ICMP_ROUTER_ADVERTISE: add_int_data(alert, "icmp_num_addrs", p->icmph->s_icmp_num_addrs); add_int_data(alert, "icmp_wpa", p->icmph->s_icmp_wpa); add_int_data(alert, "icmp_lifetime", ntohs(p->icmph->s_icmp_lifetime)); break; case ICMP_TIMESTAMPREPLY: add_int_data(alert, "icmp_id", ntohs(p->icmph->s_icmp_id)); add_int_data(alert, "icmp_seq", ntohs(p->icmph->s_icmp_seq)); add_int_data(alert, "icmp_otime", p->icmph->s_icmp_otime); add_int_data(alert, "icmp_rtime", p->icmph->s_icmp_rtime); add_int_data(alert, "icmp_ttime", p->icmph->s_icmp_ttime); break; } } add_byte_data(alert, "payload", p->data, p->dsize); return 0; }
uint8_t ip4_ret_hlen(const Packet *p) { return IP_HLEN(p->iph); }
/*-------------------------------------------------------------------- * Function: LogICMPEmbeddedIP(TextLog* , Packet *) * * Purpose: Prints the original/encapsulated IP header + 64 bits of the * original IP payload in an ICMP packet * * Arguments: log => pointer to TextLog * p => packet struct * * Returns: void function *-------------------------------------------------------------------- */ static void LogICMPEmbeddedIP(TextLog* log, Packet *p) { Packet op; Packet *orig_p; uint32_t orig_ip_hlen; if (log == NULL || p == NULL) return; memset((char*)&op, 0, sizeof(op)); orig_p = &op; orig_p->iph = p->orig_iph; orig_p->tcph = p->orig_tcph; orig_p->udph = p->orig_udph; orig_p->sp = p->orig_sp; orig_p->dp = p->orig_dp; orig_p->icmph = p->orig_icmph; #ifdef SUP_IP6 orig_p->iph_api = p->orig_iph_api; orig_p->ip4h = p->orig_ip4h; orig_p->ip6h = p->orig_ip6h; orig_p->family = p->orig_family; #endif if(orig_p->iph != NULL) { TextLog_Print(log, "\n** ORIGINAL DATAGRAM DUMP:\n"); LogIPHeader(log, orig_p); orig_ip_hlen = IP_HLEN(p->orig_iph) << 2; switch(GET_IPH_PROTO(orig_p)) { case IPPROTO_TCP: if(orig_p->tcph != NULL) TextLog_Print(log, "Seq: 0x%lX\n", (u_long)ntohl(orig_p->tcph->th_seq)); break; case IPPROTO_UDP: if(orig_p->udph != NULL) TextLog_Print(log, "Len: %d Csum: %d\n", ntohs(orig_p->udph->uh_len) - UDP_HEADER_LEN, ntohs(orig_p->udph->uh_chk)); break; case IPPROTO_ICMP: if(orig_p->icmph != NULL) LogEmbeddedICMPHeader(log, orig_p->icmph); break; default: TextLog_Print(log, "Protocol: 0x%X (unknown or " "header truncated)", GET_IPH_PROTO(orig_p)); break; } /* switch */ /* if more than 8 bytes of original IP payload sent */ if (p->dsize - orig_ip_hlen > 8) { TextLog_Print(log, "(%d more bytes of original packet)\n", p->dsize - orig_ip_hlen - 8); } TextLog_Puts(log, "** END OF DUMP"); } else { TextLog_Puts(log, "\nORIGINAL DATAGRAM TRUNCATED"); } }
/* processDHCP(): * Actually this is processBOOTP, but we call it processDHCP here so that * the same code in enetcore.c can be used to call either function (depending * on what has been configured into the uMon build). */ int processDHCP(struct ether_header *ehdr,ushort size) { char getbootfile = 0; struct ip *ihdr; struct Udphdr *uhdr; struct bootphdr *bhdr; ulong ip, temp_ip, cookie; uchar buf[16], bootsrvrip[16], *op; ihdr = (struct ip *)(ehdr + 1); uhdr = (struct Udphdr *)((char *)ihdr + IP_HLEN(ihdr)); bhdr = (struct bootphdr *)(uhdr+1); /* Verify incoming transaction id matches the previous outgoing value: */ if (xidCheck((char *)&bhdr->transaction_id,1) < 0) return(-1); /* If bootfile is nonzero, store it into BOOTFILE shell var: */ if (bhdr->bootfile[0]) getbootfile++; /* Assign IP "server_ip" to the BOOTSRVR shell var (if non-zero): */ memcpy((char *)&temp_ip,(char *)&bhdr->server_ip,4); if (temp_ip) getbootfile++; IpToString(temp_ip,(char *)bootsrvrip); /* Assign IP address loaded in "your_ip" to the IPADD shell var: */ memcpy((char *)BinIpAddr,(char *)&bhdr->your_ip,4); memcpy((char *)&temp_ip,(char *)&bhdr->your_ip,4); printf("IP: %s\n",IpToString(temp_ip,(char *)buf)); /* If STANDARD_MAGIC_COOKIE exists, then process options... */ memcpy((char *)&cookie,(char *)bhdr->vsa,4); if (cookie == ecl(STANDARD_MAGIC_COOKIE)) { /* Assign subnet mask option to NETMASK shell var (if found): */ op = DhcpGetOption(DHCPOPT_SUBNETMASK,&bhdr->vsa[4]); if (op) { memcpy((char *)BinNetMask,(char *)op+2,4); memcpy((char *)&ip,(char *)op+2,4); printf("NETMASK: %s\n",IpToString(ip,(char *)buf)); } /* Assign first router option to GIPADD shell var (if found): */ /* (the router option can have multiple entries, and they are */ /* supposed to be in order of preference, so use the first one) */ op = DhcpGetOption(DHCPOPT_ROUTER,&bhdr->vsa[4]); if (op) { memcpy((char *)BinGipAddr,(char *)op+2,4); memcpy((char *)&ip,(char *)op+2,4); printf("GIPADD: %s\n",IpToString(ip,(char *)buf)); } } /* Call loadBootFile() which will then kick off a tftp client * transfer if both BOOTFILE and BOOTSRVR shell variables are * loaded; otherwise, we are done. */ /* If the bootp server gave us the bootfile and boot server IP, * then call loadBootFile()... */ if (getbootfile == 2) loadBootFile((char *)bhdr->bootfile,(char *)bootsrvrip); else DHCPState = BOOTPSTATE_COMPLETE; return(0); }