uint16_t DecodeVLANGetId(const Packet *p, uint8_t layer) { if (unlikely(layer > 1)) return 0; if (p->vlanh[layer] == NULL && (p->vlan_idx >= (layer + 1))) { return p->vlan_id[layer]; } else { return GET_VLAN_ID(p->vlanh[layer]); } return 0; }
/** * \internal * \brief this function is used to decode IEEE802.1q packets * * \param tv pointer to the thread vars * \param dtv pointer code thread vars * \param p pointer to the packet struct * \param pkt pointer to the raw packet * \param len packet len * \param pq pointer to the packet queue * */ void DecodeVLAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) { SCPerfCounterIncr(dtv->counter_vlan, tv->sc_perf_pca); if(len < VLAN_HEADER_LEN) { DECODER_SET_EVENT(p,VLAN_HEADER_TOO_SMALL); return; } p->vlanh = (VLANHdr *)pkt; if(p->vlanh == NULL) return; SCLogDebug("p %p pkt %p VLAN protocol %04x VLAN PRI %d VLAN CFI %d VLAN ID %d Len: %" PRId32 "", p, pkt, GET_VLAN_PROTO(p->vlanh), GET_VLAN_PRIORITY(p->vlanh), GET_VLAN_CFI(p->vlanh), GET_VLAN_ID(p->vlanh), len); switch (GET_VLAN_PROTO(p->vlanh)) { case ETHERNET_TYPE_IP: DecodeIPV4(tv, dtv, p, pkt + VLAN_HEADER_LEN, len - VLAN_HEADER_LEN, pq); break; case ETHERNET_TYPE_IPV6: DecodeIPV6(tv, dtv, p, pkt + VLAN_HEADER_LEN, len - VLAN_HEADER_LEN, pq); break; case ETHERNET_TYPE_PPPOE_SESS: DecodePPPOESession(tv, dtv, p, pkt + VLAN_HEADER_LEN, len - VLAN_HEADER_LEN, pq); break; case ETHERNET_TYPE_PPPOE_DISC: DecodePPPOEDiscovery(tv, dtv, p, pkt + VLAN_HEADER_LEN, len - VLAN_HEADER_LEN, pq); break; case ETHERNET_TYPE_VLAN: DecodeVLAN(tv, dtv, p, pkt + VLAN_HEADER_LEN, len - VLAN_HEADER_LEN, pq); break; default: SCLogDebug("unknown VLAN type: %" PRIx32 "",GET_VLAN_PROTO(p->vlanh)); DECODER_SET_EVENT(p,VLAN_UNKNOWN_TYPE); return; } return; }
json_t *CreateJSONHeader(Packet *p, int direction_sensitive, char *event_type) { char timebuf[64]; char srcip[46], dstip[46]; Port sp, dp; json_t *js = json_object(); if (unlikely(js == NULL)) return NULL; CreateTimeString(&p->ts, timebuf, sizeof(timebuf)); srcip[0] = '\0'; dstip[0] = '\0'; if (direction_sensitive) { if ((PKT_IS_TOCLIENT(p))) { if (PKT_IS_IPV4(p)) { PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); } else if (PKT_IS_IPV6(p)) { PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); } sp = p->sp; dp = p->dp; } else { if (PKT_IS_IPV4(p)) { PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), dstip, sizeof(dstip)); } else if (PKT_IS_IPV6(p)) { PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), dstip, sizeof(dstip)); } sp = p->dp; dp = p->sp; } } else { if (PKT_IS_IPV4(p)) { PrintInet(AF_INET, (const void *)GET_IPV4_SRC_ADDR_PTR(p), srcip, sizeof(srcip)); PrintInet(AF_INET, (const void *)GET_IPV4_DST_ADDR_PTR(p), dstip, sizeof(dstip)); } else if (PKT_IS_IPV6(p)) { PrintInet(AF_INET6, (const void *)GET_IPV6_SRC_ADDR(p), srcip, sizeof(srcip)); PrintInet(AF_INET6, (const void *)GET_IPV6_DST_ADDR(p), dstip, sizeof(dstip)); } sp = p->sp; dp = p->dp; } char proto[16]; if (SCProtoNameValid(IP_GET_IPPROTO(p)) == TRUE) { strlcpy(proto, known_proto[IP_GET_IPPROTO(p)], sizeof(proto)); } else { snprintf(proto, sizeof(proto), "%03" PRIu32, IP_GET_IPPROTO(p)); } /* time & tx */ json_object_set_new(js, "time", json_string(timebuf)); /* sensor id */ if (sensor_id >= 0) json_object_set_new(js, "sensor_id", json_integer(sensor_id)); /* pcap_cnt */ if (p->pcap_cnt != 0) { json_object_set_new(js, "pcap_cnt", json_integer(p->pcap_cnt)); } if (event_type) { json_object_set_new(js, "event_type", json_string(event_type)); } /* vlan */ if (p->vlan_idx > 0) { json_t *js_vlan; switch (p->vlan_idx) { case 1: json_object_set_new(js, "vlan", json_integer(ntohs(GET_VLAN_ID(p->vlanh[0])))); break; case 2: js_vlan = json_array(); if (unlikely(js != NULL)) { json_array_append_new(js_vlan, json_integer(ntohs(GET_VLAN_ID(p->vlanh[0])))); json_array_append_new(js_vlan, json_integer(ntohs(GET_VLAN_ID(p->vlanh[1])))); json_object_set_new(js, "vlan", js_vlan); } break; default: /* shouldn't get here */ break; } } /* tuple */ json_object_set_new(js, "src_ip", json_string(srcip)); switch(p->proto) { case IPPROTO_ICMP: break; case IPPROTO_UDP: case IPPROTO_TCP: case IPPROTO_SCTP: json_object_set_new(js, "src_port", json_integer(sp)); break; } json_object_set_new(js, "dest_ip", json_string(dstip)); switch(p->proto) { case IPPROTO_ICMP: break; case IPPROTO_UDP: case IPPROTO_TCP: case IPPROTO_SCTP: json_object_set_new(js, "dest_port", json_integer(dp)); break; } json_object_set_new(js, "proto", json_string(proto)); switch (p->proto) { case IPPROTO_ICMP: if (p->icmpv4h) { json_object_set_new(js, "icmp_type", json_integer(p->icmpv4h->type)); json_object_set_new(js, "icmp_code", json_integer(p->icmpv4h->code)); } break; case IPPROTO_ICMPV6: if (p->icmpv6h) { json_object_set_new(js, "icmp_type", json_integer(p->icmpv6h->type)); json_object_set_new(js, "icmp_code", json_integer(p->icmpv6h->code)); } break; } return js; }
/** * \internal * \brief this function is used to decode IEEE802.1q packets * * \param tv pointer to the thread vars * \param dtv pointer code thread vars * \param p pointer to the packet struct * \param pkt pointer to the raw packet * \param len packet len * \param pq pointer to the packet queue * */ int DecodeVLAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq) { uint32_t proto; SCPerfCounterIncr(dtv->counter_vlan, tv->sc_perf_pca); if(len < VLAN_HEADER_LEN) { ENGINE_SET_INVALID_EVENT(p, VLAN_HEADER_TOO_SMALL); return TM_ECODE_FAILED; } if (p->vlan_idx >= 2) { ENGINE_SET_EVENT(p,VLAN_HEADER_TOO_MANY_LAYERS); return TM_ECODE_FAILED; } p->vlanh[p->vlan_idx] = (VLANHdr *)pkt; if(p->vlanh[p->vlan_idx] == NULL) return TM_ECODE_FAILED; proto = GET_VLAN_PROTO(p->vlanh[p->vlan_idx]); SCLogDebug("p %p pkt %p VLAN protocol %04x VLAN PRI %d VLAN CFI %d VLAN ID %d Len: %" PRId32 "", p, pkt, proto, GET_VLAN_PRIORITY(p->vlanh[p->vlan_idx]), GET_VLAN_CFI(p->vlanh[p->vlan_idx]), GET_VLAN_ID(p->vlanh[p->vlan_idx]), len); /* only store the id for flow hashing if it's not disabled. */ if (dtv->vlan_disabled == 0) p->vlan_id[p->vlan_idx] = (uint16_t)GET_VLAN_ID(p->vlanh[p->vlan_idx]); p->vlan_idx++; switch (proto) { case ETHERNET_TYPE_IP: DecodeIPV4(tv, dtv, p, pkt + VLAN_HEADER_LEN, len - VLAN_HEADER_LEN, pq); break; case ETHERNET_TYPE_IPV6: DecodeIPV6(tv, dtv, p, pkt + VLAN_HEADER_LEN, len - VLAN_HEADER_LEN, pq); break; case ETHERNET_TYPE_PPPOE_SESS: DecodePPPOESession(tv, dtv, p, pkt + VLAN_HEADER_LEN, len - VLAN_HEADER_LEN, pq); break; case ETHERNET_TYPE_PPPOE_DISC: DecodePPPOEDiscovery(tv, dtv, p, pkt + VLAN_HEADER_LEN, len - VLAN_HEADER_LEN, pq); break; case ETHERNET_TYPE_VLAN: if (p->vlan_idx >= 2) { ENGINE_SET_EVENT(p,VLAN_HEADER_TOO_MANY_LAYERS); return TM_ECODE_OK; } else { DecodeVLAN(tv, dtv, p, pkt + VLAN_HEADER_LEN, len - VLAN_HEADER_LEN, pq); } break; default: SCLogDebug("unknown VLAN type: %" PRIx32 "", proto); ENGINE_SET_INVALID_EVENT(p, VLAN_UNKNOWN_TYPE); return TM_ECODE_OK; } return TM_ECODE_OK; }