static int packet_to_data(Packet *p, void *event, idmef_alert_t *alert) { int i; if ( ! p ) return 0; add_int_data(alert, "snort_rule_sid", ntohl(((Unified2EventCommon *)event)->signature_id)); add_int_data(alert, "snort_rule_rev", ntohl(((Unified2EventCommon *)event)->signature_revision)); if ( IPH_IS_VALID(p) ) { add_int_data(alert, "ip_ver", GET_IPH_VER(p)); add_int_data(alert, "ip_hlen", GET_IPH_HLEN(p)); add_int_data(alert, "ip_tos", GET_IPH_TOS(p)); add_int_data(alert, "ip_len", ntohs(GET_IPH_LEN(p))); #ifdef SUP_IP6 // XXX-IPv6 need fragmentation ID #else add_int_data(alert, "ip_id", ntohs(p->iph->ip_id)); #endif #ifdef SUP_IP6 // XXX-IPv6 need fragmentation offset #else add_int_data(alert, "ip_off", ntohs(p->iph->ip_off)); #endif add_int_data(alert, "ip_ttl", GET_IPH_TTL(p)); add_int_data(alert, "ip_proto", GET_IPH_PROTO(p)); #ifdef SUP_IP6 // XXX-IPv6 need checksum #else add_int_data(alert, "ip_sum", ntohs(p->iph->ip_csum)); #endif 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: #ifndef SUP_IP6 add_string_data(alert, "icmp_gwaddr", inet_ntoa(p->icmph->s_icmp_gwaddr)); #else { sfip_t gwaddr; sfip_set_raw(&gwaddr, (void *)&p->icmph->s_icmp_gwaddr.s_addr, AF_INET); add_string_data(alert, "icmp_gwaddr", inet_ntoa(&gwaddr)); } #endif 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; }
/* * Check header option specified against packet * * Return 1 if check is true (e.g. data matches) * Return 0 if check is not true. */ ENGINE_LINKAGE int checkHdrOpt(void *p, HdrOptCheck *optData) { SFSnortPacket *pkt = (SFSnortPacket *)p; /* Header field will be extracted from its native * 1 or 2 bytes, converted to host byte order, * and placed in a 4 byte value for easy comparison */ uint32_t value = 0; if ((optData->hdrField & IP_HDR_OPTCHECK_MASK) && (!pkt->ip4_header)) return RULE_NOMATCH; if ((optData->hdrField & TCP_HDR_OPTCHECK_MASK) && (!pkt->ip4_header || !pkt->tcp_header)) return RULE_NOMATCH; if ((optData->hdrField & ICMP_HDR_OPTCHECK_MASK) && (!IPH_IS_VALID(pkt) || !pkt->icmp_header)) return RULE_NOMATCH; switch (optData->hdrField) { /* IP Header Checks */ case IP_HDR_ID: value = IS_IP6(pkt) ? ntohl(GET_IPH_ID(pkt)) : ntohs((uint16_t)GET_IPH_ID(pkt)); break; case IP_HDR_PROTO: //value = pkt->ip4_header->proto; value = GET_IPH_PROTO(pkt); break; case IP_HDR_FRAGBITS: return checkBits(optData->value, optData->op, ((ntohs(GET_IPH_OFF(pkt)) & 0xe000) & ~optData->mask_value)); break; case IP_HDR_FRAGOFFSET: value = ntohs(GET_IPH_OFF((pkt))) & 0x1FFF; break; case IP_HDR_TOS: //value = pkt->ip4_header->type_service; value = GET_IPH_TOS(pkt); break; case IP_HDR_TTL: //value = pkt->ip4_header->time_to_live; value = GET_IPH_TTL(pkt); break; case IP_HDR_OPTIONS: return checkOptions(optData->value, optData->op, pkt->ip_options, pkt->num_ip_options); break; /* TCP Header checks */ case TCP_HDR_ACK: value = ntohl(pkt->tcp_header->acknowledgement); break; case TCP_HDR_SEQ: value = ntohl(pkt->tcp_header->sequence); break; case TCP_HDR_FLAGS: return checkBits(optData->value, optData->op, (pkt->tcp_header->flags & ~optData->mask_value)); break; case TCP_HDR_WIN: value = ntohs(pkt->tcp_header->window); break; case TCP_HDR_OPTIONS: return checkOptions(optData->value, optData->op, pkt->tcp_options, pkt->num_tcp_options); break; /* ICMP Header checks */ case ICMP_HDR_CODE: value = pkt->icmp_header->code; break; case ICMP_HDR_TYPE: value = pkt->icmp_header->type; break; case ICMP_HDR_ID: if ((pkt->icmp_header->code == ICMP_ECHO_REQUEST) || (pkt->icmp_header->code == ICMP_ECHO_REPLY)) { value = ntohs(pkt->icmp_header->icmp_header_union.echo.id); } else { return RULE_NOMATCH; } break; case ICMP_HDR_SEQ: if ((pkt->icmp_header->code == ICMP_ECHO_REQUEST) || (pkt->icmp_header->code == ICMP_ECHO_REPLY)) { value = ntohs(pkt->icmp_header->icmp_header_union.echo.seq); } else { return RULE_NOMATCH; } break; default: return RULE_NOMATCH; break; } return checkField(optData->op, value, optData->value); }
/*-------------------------------------------------------------------- * Function: LogIPHeader(TextLog* ) * * Purpose: Dump the IP header info to the given TextLog * * Arguments: log => TextLog to print to * * Returns: void function *-------------------------------------------------------------------- */ void LogIPHeader(TextLog* log, Packet * p) { if(!IPH_IS_VALID(p)) { TextLog_Print(log, "IP header truncated\n"); return; } if(p->frag_flag) { /* just print the straight IP header */ TextLog_Puts(log, inet_ntoa(GET_SRC_ADDR(p))); TextLog_Puts(log, " -> "); TextLog_Puts(log, inet_ntoa(GET_DST_ADDR(p))); } else { if(GET_IPH_PROTO(p) != IPPROTO_TCP && GET_IPH_PROTO(p) != IPPROTO_UDP) { /* just print the straight IP header */ TextLog_Puts(log, inet_ntoa(GET_SRC_ADDR(p))); TextLog_Puts(log, " -> "); TextLog_Puts(log, inet_ntoa(GET_DST_ADDR(p))); } else { if (!BcObfuscate()) { /* print the header complete with port information */ TextLog_Puts(log, inet_ntoa(GET_SRC_ADDR(p))); TextLog_Print(log, ":%d -> ", p->sp); TextLog_Puts(log, inet_ntoa(GET_DST_ADDR(p))); TextLog_Print(log, ":%d", p->dp); } else { /* print the header complete with port information */ if(IS_IP4(p)) TextLog_Print(log, "xxx.xxx.xxx.xxx:%d -> xxx.xxx.xxx.xxx:%d", p->sp, p->dp); else if(IS_IP6(p)) TextLog_Print(log, "x:x:x:x:x:x:x:x:%d -> x:x:x:x:x:x:x:x:%d", p->sp, p->dp); } } } if(!BcOutputDataLink()) { TextLog_NewLine(log); } else { TextLog_Putc(log, ' '); } TextLog_Print(log, "%s TTL:%u TOS:0x%X ID:%u IpLen:%u DgmLen:%u", protocol_names[GET_IPH_PROTO(p)], GET_IPH_TTL(p), GET_IPH_TOS(p), IS_IP6(p) ? ntohl(GET_IPH_ID(p)) : ntohs((uint16_t)GET_IPH_ID(p)), GET_IPH_HLEN(p) << 2, GET_IP_DGMLEN(p)); /* print the reserved bit if it's set */ if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x8000) >> 15) == 1) TextLog_Puts(log, " RB"); /* printf more frags/don't frag bits */ if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x4000) >> 14) == 1) TextLog_Puts(log, " DF"); if((uint8_t)((ntohs(GET_IPH_OFF(p)) & 0x2000) >> 13) == 1) TextLog_Puts(log, " MF"); TextLog_NewLine(log); /* print IP options */ if(p->ip_option_count != 0) { LogIpOptions(log, p); } /* print fragment info if necessary */ if(p->frag_flag) { TextLog_Print(log, "Frag Offset: 0x%04X Frag Size: 0x%04X\n", (p->frag_offset & 0x1FFF), GET_IP_PAYLEN(p)); } }