diff options
-rw-r--r-- | filter/raw2packet/ulogd_raw2packet_BASE.c | 703 | ||||
-rw-r--r-- | include/ulogd/ipfix_protocol.h | 2 | ||||
-rw-r--r-- | include/ulogd/printpkt.h | 58 | ||||
-rw-r--r-- | input/packet/ulogd_inppkt_NFLOG.c | 26 | ||||
-rw-r--r-- | util/printpkt.c | 398 |
5 files changed, 872 insertions, 315 deletions
diff --git a/filter/raw2packet/ulogd_raw2packet_BASE.c b/filter/raw2packet/ulogd_raw2packet_BASE.c index ca67677..4420507 100644 --- a/filter/raw2packet/ulogd_raw2packet_BASE.c +++ b/filter/raw2packet/ulogd_raw2packet_BASE.c @@ -34,20 +34,73 @@ #include <stdlib.h> #include <sys/socket.h> #include <netinet/ip.h> +#include <netinet/ip6.h> #include <netinet/in.h> #include <netinet/tcp.h> #include <netinet/ip_icmp.h> +#include <netinet/icmp6.h> #include <netinet/udp.h> #include <ulogd/ulogd.h> #include <ulogd/ipfix_protocol.h> - -/*********************************************************************** - * IP HEADER - ***********************************************************************/ +enum output_keys { + KEY_IP_SADDR, + KEY_IP_DADDR, + KEY_IP_PROTOCOL, + KEY_IP_TOS, + KEY_IP_TTL, + KEY_IP_TOTLEN, + KEY_IP_IHL, + KEY_IP_CSUM, + KEY_IP_ID, + KEY_IP_FRAGOFF, + KEY_IP6_SADDR, + KEY_IP6_DADDR, + KEY_IP6_PAYLOAD_LEN, + KEY_IP6_PRIORITY, + KEY_IP6_FLOWLABEL, + KEY_IP6_HOPLIMIT, + KEY_IP6_NEXTHDR, + KEY_IP6_FRAG_OFF, + KEY_IP6_FRAG_ID, + KEY_TCP_SPORT, + KEY_TCP_DPORT, + KEY_TCP_SEQ, + KEY_TCP_ACKSEQ, + KEY_TCP_WINDOW, + KEY_TCP_OFFSET, + KEY_TCP_RESERVED, + KEY_TCP_URG, + KEY_TCP_URGP, + KEY_TCP_ACK, + KEY_TCP_PSH, + KEY_TCP_RST, + KEY_TCP_SYN, + KEY_TCP_FIN, + KEY_TCP_RES1, + KEY_TCP_RES2, + KEY_TCP_CSUM, + KEY_UDP_SPORT, + KEY_UDP_DPORT, + KEY_UDP_LEN, + KEY_UDP_CSUM, + KEY_ICMP_TYPE, + KEY_ICMP_CODE, + KEY_ICMP_ECHOID, + KEY_ICMP_ECHOSEQ, + KEY_ICMP_GATEWAY, + KEY_ICMP_FRAGMTU, + KEY_ICMP_CSUM, + KEY_ICMPV6_TYPE, + KEY_ICMPV6_CODE, + KEY_ICMPV6_ECHOID, + KEY_ICMPV6_ECHOSEQ, + KEY_ICMPV6_CSUM, + KEY_AHESP_SPI, +}; static struct ulogd_key iphdr_rets[] = { - { + [KEY_IP_SADDR] = { .type = ULOGD_RET_IPADDR, .flags = ULOGD_RETF_NONE, .name = "ip.saddr", @@ -56,7 +109,7 @@ static struct ulogd_key iphdr_rets[] = { .field_id = IPFIX_sourceIPv4Address, }, }, - { + [KEY_IP_DADDR] = { .type = ULOGD_RET_IPADDR, .flags = ULOGD_RETF_NONE, .name = "ip.daddr", @@ -65,7 +118,7 @@ static struct ulogd_key iphdr_rets[] = { .field_id = IPFIX_destinationIPv4Address, }, }, - { + [KEY_IP_PROTOCOL] = { .type = ULOGD_RET_UINT8, .flags = ULOGD_RETF_NONE, .name = "ip.protocol", @@ -74,7 +127,7 @@ static struct ulogd_key iphdr_rets[] = { .field_id = IPFIX_protocolIdentifier, }, }, - { + [KEY_IP_TOS] = { .type = ULOGD_RET_UINT8, .flags = ULOGD_RETF_NONE, .name = "ip.tos", @@ -83,7 +136,7 @@ static struct ulogd_key iphdr_rets[] = { .field_id = IPFIX_classOfServiceIPv4, }, }, - { + [KEY_IP_TTL] = { .type = ULOGD_RET_UINT8, .flags = ULOGD_RETF_NONE, .name = "ip.ttl", @@ -92,7 +145,7 @@ static struct ulogd_key iphdr_rets[] = { .field_id = IPFIX_ipTimeToLive, }, }, - { + [KEY_IP_TOTLEN] = { .type = ULOGD_RET_UINT16, .flags = ULOGD_RETF_NONE, .name = "ip.totlen", @@ -101,7 +154,7 @@ static struct ulogd_key iphdr_rets[] = { .field_id = IPFIX_totalLengthIPv4, }, }, - { + [KEY_IP_IHL] = { .type = ULOGD_RET_UINT8, .flags = ULOGD_RETF_NONE, .name = "ip.ihl", @@ -110,12 +163,12 @@ static struct ulogd_key iphdr_rets[] = { .field_id = IPFIX_internetHeaderLengthIPv4, }, }, - { + [KEY_IP_CSUM] = { .type = ULOGD_RET_UINT16, .flags = ULOGD_RETF_NONE, .name = "ip.csum", }, - { + [KEY_IP_ID] = { .type = ULOGD_RET_UINT16, .flags = ULOGD_RETF_NONE, .name = "ip.id", @@ -124,7 +177,7 @@ static struct ulogd_key iphdr_rets[] = { .field_id = IPFIX_identificationIPv4, }, }, - { + [KEY_IP_FRAGOFF] = { .type = ULOGD_RET_UINT16, .flags = ULOGD_RETF_NONE, .name = "ip.fragoff", @@ -133,10 +186,72 @@ static struct ulogd_key iphdr_rets[] = { .field_id = IPFIX_fragmentOffsetIPv4, }, }, - - /* 10 */ - - { + [KEY_IP6_SADDR] = { + .type = ULOGD_RET_RAW, + .flags = ULOGD_RETF_NONE, + .name = "ip6.saddr", + .ipfix = { + .vendor = IPFIX_VENDOR_IETF, + .field_id = IPFIX_sourceIPv6Address, + }, + }, + [KEY_IP6_DADDR] = { + .type = ULOGD_RET_RAW, + .flags = ULOGD_RETF_NONE, + .name = "ip6.daddr", + .ipfix = { + .vendor = IPFIX_VENDOR_IETF, + .field_id = IPFIX_destinationIPv6Address, + }, + }, + [KEY_IP6_PAYLOAD_LEN] = { + .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .name = "ip6.payload_len", + .ipfix = { + .vendor = IPFIX_VENDOR_IETF, + .field_id = IPFIX_payloadLengthIPv6, + }, + }, + [KEY_IP6_PRIORITY] = { + .type = ULOGD_RET_UINT8, + .flags = ULOGD_RETF_NONE, + .name = "ip6.priority", + }, + [KEY_IP6_FLOWLABEL] = { + .type = ULOGD_RET_UINT32, + .flags = ULOGD_RETF_NONE, + .name = "ip6.flowlabel", + .ipfix = { + .vendor = IPFIX_VENDOR_IETF, + .field_id = IPFIX_flowLabelIPv6, + }, + }, + [KEY_IP6_HOPLIMIT] = { + .type = ULOGD_RET_UINT8, + .flags = ULOGD_RETF_NONE, + .name = "ip6.hoplimit", + }, + [KEY_IP6_NEXTHDR] = { + .type = ULOGD_RET_UINT8, + .flags = ULOGD_RETF_NONE, + .name = "ip6.nexthdr", + .ipfix = { + .vendor = IPFIX_VENDOR_IETF, + .field_id = IPFIX_nextHeaderIPv6, + }, + }, + [KEY_IP6_FRAG_OFF] = { + .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .name = "ip6.fragoff", + }, + [KEY_IP6_FRAG_ID] = { + .type = ULOGD_RET_UINT32, + .flags = ULOGD_RETF_NONE, + .name = "ip6.fragid", + }, + [KEY_TCP_SPORT] = { .type = ULOGD_RET_UINT16, .flags = ULOGD_RETF_NONE, .name = "tcp.sport", @@ -145,7 +260,7 @@ static struct ulogd_key iphdr_rets[] = { .field_id = IPFIX_tcpSourcePort, }, }, - { + [KEY_TCP_DPORT] = { .type = ULOGD_RET_UINT16, .flags = ULOGD_RETF_NONE, .name = "tcp.dport", @@ -154,7 +269,7 @@ static struct ulogd_key iphdr_rets[] = { .field_id = IPFIX_tcpDestinationPort, }, }, - { + [KEY_TCP_SEQ] = { .type = ULOGD_RET_UINT32, .flags = ULOGD_RETF_NONE, .name = "tcp.seq", @@ -163,7 +278,7 @@ static struct ulogd_key iphdr_rets[] = { .field_id = IPFIX_tcpSequenceNumber, }, }, - { + [KEY_TCP_ACKSEQ] = { .type = ULOGD_RET_UINT32, .flags = ULOGD_RETF_NONE, .name = "tcp.ackseq", @@ -172,17 +287,17 @@ static struct ulogd_key iphdr_rets[] = { .field_id = IPFIX_tcpAcknowledgementNumber, }, }, - { + [KEY_TCP_OFFSET] = { .type = ULOGD_RET_UINT8, .flags = ULOGD_RETF_NONE, .name = "tcp.offset", }, - { + [KEY_TCP_RESERVED] = { .type = ULOGD_RET_UINT8, .flags = ULOGD_RETF_NONE, .name = "tcp.reserved", }, - { + [KEY_TCP_WINDOW] = { .type = ULOGD_RET_UINT16, .flags = ULOGD_RETF_NONE, .name = "tcp.window", @@ -191,12 +306,12 @@ static struct ulogd_key iphdr_rets[] = { .field_id = IPFIX_tcpWindowSize, }, }, - { + [KEY_TCP_URG] = { .type = ULOGD_RET_BOOL, .flags = ULOGD_RETF_NONE, .name = "tcp.urg", }, - { + [KEY_TCP_URGP] = { .type = ULOGD_RET_UINT16, .flags = ULOGD_RETF_NONE, .name = "tcp.urgp", @@ -205,50 +320,47 @@ static struct ulogd_key iphdr_rets[] = { .field_id = IPFIX_tcpUrgentPointer, }, }, - { + [KEY_TCP_ACK] = { .type = ULOGD_RET_BOOL, .flags = ULOGD_RETF_NONE, .name = "tcp.ack", }, - { + [KEY_TCP_PSH] = { .type = ULOGD_RET_BOOL, .flags = ULOGD_RETF_NONE, .name = "tcp.psh", }, - { + [KEY_TCP_RST] = { .type = ULOGD_RET_BOOL, .flags = ULOGD_RETF_NONE, .name = "tcp.rst", }, - { + [KEY_TCP_SYN] = { .type = ULOGD_RET_BOOL, .flags = ULOGD_RETF_NONE, .name = "tcp.syn", }, - { + [KEY_TCP_FIN] = { .type = ULOGD_RET_BOOL, .flags = ULOGD_RETF_NONE, .name = "tcp.fin", }, - { + [KEY_TCP_RES1] = { .type = ULOGD_RET_BOOL, .flags = ULOGD_RETF_NONE, .name = "tcp.res1", }, - { + [KEY_TCP_RES2] = { .type = ULOGD_RET_BOOL, .flags = ULOGD_RETF_NONE, .name = "tcp.res2", }, - { + [KEY_TCP_CSUM] = { .type = ULOGD_RET_UINT16, .flags = ULOGD_RETF_NONE, .name = "tcp.csum", }, - - /* 27 */ - - { + [KEY_UDP_SPORT] = { .type = ULOGD_RET_UINT16, .flags = ULOGD_RETF_NONE, .name = "udp.sport", @@ -257,7 +369,7 @@ static struct ulogd_key iphdr_rets[] = { .field_id = IPFIX_udpSourcePort, }, }, - { + [KEY_UDP_DPORT] = { .type = ULOGD_RET_UINT16, .flags = ULOGD_RETF_NONE, .name = "udp.dport", @@ -266,21 +378,17 @@ static struct ulogd_key iphdr_rets[] = { .field_id = IPFIX_udpDestinationPort, }, }, - { + [KEY_UDP_LEN] = { .type = ULOGD_RET_UINT16, .flags = ULOGD_RETF_NONE, .name = "udp.len", }, - { + [KEY_UDP_CSUM] = { .type = ULOGD_RET_UINT16, .flags = ULOGD_RETF_NONE, .name = "udp.csum", }, - - /* 31 */ - - - { + [KEY_ICMP_TYPE] = { .type = ULOGD_RET_UINT8, .flags = ULOGD_RETF_NONE, .name = "icmp.type", @@ -289,7 +397,7 @@ static struct ulogd_key iphdr_rets[] = { .field_id = IPFIX_icmpTypeIPv4, }, }, - { + [KEY_ICMP_CODE] = { .type = ULOGD_RET_UINT8, .flags = ULOGD_RETF_NONE, .name = "icmp.code", @@ -298,93 +406,121 @@ static struct ulogd_key iphdr_rets[] = { .field_id = IPFIX_icmpCodeIPv4, }, }, - { + [KEY_ICMP_ECHOID] = { .type = ULOGD_RET_UINT16, .flags = ULOGD_RETF_NONE, .name = "icmp.echoid", }, - { + [KEY_ICMP_ECHOSEQ] = { .type = ULOGD_RET_UINT16, .flags = ULOGD_RETF_NONE, .name = "icmp.echoseq", }, - { + [KEY_ICMP_GATEWAY] = { .type = ULOGD_RET_IPADDR, .flags = ULOGD_RETF_NONE, .name = "icmp.gateway", }, - { + [KEY_ICMP_FRAGMTU] = { .type = ULOGD_RET_UINT16, .flags = ULOGD_RETF_NONE, .name = "icmp.fragmtu", }, - { + [KEY_ICMP_CSUM] = { .type = ULOGD_RET_UINT16, .flags = ULOGD_RETF_NONE, .name = "icmp.csum", }, - { + [KEY_ICMPV6_TYPE] = { + .type = ULOGD_RET_UINT8, + .flags = ULOGD_RETF_NONE, + .name = "icmpv6.type", + .ipfix = { + .vendor = IPFIX_VENDOR_IETF, + .field_id = IPFIX_icmpTypeIPv6, + }, + }, + [KEY_ICMPV6_CODE] = { + .type = ULOGD_RET_UINT8, + .flags = ULOGD_RETF_NONE, + .name = "icmpv6.code", + .ipfix = { + .vendor = IPFIX_VENDOR_IETF, + .field_id = IPFIX_icmpCodeIPv6, + }, + }, + [KEY_ICMPV6_ECHOID] = { + .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .name = "icmpv6.echoid", + }, + [KEY_ICMPV6_ECHOSEQ] = { + .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .name = "icmpv6.echoseq", + }, + [KEY_ICMPV6_CSUM] = { + .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .name = "icmpv6.csum", + }, + [KEY_AHESP_SPI] = { .type = ULOGD_RET_UINT32, .flags = ULOGD_RETF_NONE, .name = "ahesp.spi", }, - /* 39 */ - }; /*********************************************************************** * TCP HEADER ***********************************************************************/ -static int _interp_tcp(struct ulogd_pluginstance *pi) +static int _interp_tcp(struct ulogd_pluginstance *pi, struct tcphdr *tcph, + u_int32_t len) { - struct ulogd_key *ret = &pi->output.keys[10]; - struct iphdr *iph = (struct iphdr *) - pi->input.keys[0].u.source->u.value.ptr; - void *protoh = (u_int32_t *)iph + iph->ihl; - struct tcphdr *tcph = (struct tcphdr *) protoh; + struct ulogd_key *ret = pi->output.keys; - if (iph->protocol != IPPROTO_TCP) + if (len < sizeof(struct tcphdr)) return 0; - ret[0].u.value.ui16 = ntohs(tcph->source); - ret[0].flags |= ULOGD_RETF_VALID; - ret[1].u.value.ui16 = ntohs(tcph->dest); - ret[1].flags |= ULOGD_RETF_VALID; - ret[2].u.value.ui32 = ntohl(tcph->seq); - ret[2].flags |= ULOGD_RETF_VALID; - ret[3].u.value.ui32 = ntohl(tcph->ack_seq); - ret[3].flags |= ULOGD_RETF_VALID; - ret[4].u.value.ui8 = ntohs(tcph->doff); - ret[4].flags |= ULOGD_RETF_VALID; - ret[5].u.value.ui8 = ntohs(tcph->res1); - ret[5].flags |= ULOGD_RETF_VALID; - ret[6].u.value.ui16 = ntohs(tcph->window); - ret[6].flags |= ULOGD_RETF_VALID; - - ret[7].u.value.b = tcph->urg; - ret[7].flags |= ULOGD_RETF_VALID; + ret[KEY_TCP_SPORT].u.value.ui16 = ntohs(tcph->source); + ret[KEY_TCP_SPORT].flags |= ULOGD_RETF_VALID; + ret[KEY_TCP_DPORT].u.value.ui16 = ntohs(tcph->dest); + ret[KEY_TCP_DPORT].flags |= ULOGD_RETF_VALID; + ret[KEY_TCP_SEQ].u.value.ui32 = ntohl(tcph->seq); + ret[KEY_TCP_SEQ].flags |= ULOGD_RETF_VALID; + ret[KEY_TCP_ACKSEQ].u.value.ui32 = ntohl(tcph->ack_seq); + ret[KEY_TCP_ACKSEQ].flags |= ULOGD_RETF_VALID; + ret[KEY_TCP_OFFSET].u.value.ui8 = ntohs(tcph->doff); + ret[KEY_TCP_OFFSET].flags |= ULOGD_RETF_VALID; + ret[KEY_TCP_RESERVED].u.value.ui8 = ntohs(tcph->res1); + ret[KEY_TCP_RESERVED].flags |= ULOGD_RETF_VALID; + ret[KEY_TCP_WINDOW].u.value.ui16 = ntohs(tcph->window); + ret[KEY_TCP_WINDOW].flags |= ULOGD_RETF_VALID; + + ret[KEY_TCP_URG].u.value.b = tcph->urg; + ret[KEY_TCP_URG].flags |= ULOGD_RETF_VALID; if (tcph->urg) { - ret[8].u.value.ui16 = ntohs(tcph->urg_ptr); - ret[8].flags |= ULOGD_RETF_VALID; + ret[KEY_TCP_URGP].u.value.ui16 = ntohs(tcph->urg_ptr); + ret[KEY_TCP_URGP].flags |= ULOGD_RETF_VALID; } - ret[9].u.value.b = tcph->ack; - ret[9].flags |= ULOGD_RETF_VALID; - ret[10].u.value.b = tcph->psh; - ret[10].flags |= ULOGD_RETF_VALID; - ret[11].u.value.b = tcph->rst; - ret[11].flags |= ULOGD_RETF_VALID; - ret[12].u.value.b = tcph->syn; - ret[12].flags |= ULOGD_RETF_VALID; - ret[13].u.value.b = tcph->fin; - ret[13].flags |= ULOGD_RETF_VALID; - ret[14].u.value.b = tcph->res1; - ret[14].flags |= ULOGD_RETF_VALID; - ret[15].u.value.b = tcph->res2; - ret[15].flags |= ULOGD_RETF_VALID; - ret[16].u.value.ui16 = ntohs(tcph->check); - ret[16].u.value.ui16 = ULOGD_RETF_VALID; + ret[KEY_TCP_ACK].u.value.b = tcph->ack; + ret[KEY_TCP_ACK].flags |= ULOGD_RETF_VALID; + ret[KEY_TCP_PSH].u.value.b = tcph->psh; + ret[KEY_TCP_PSH].flags |= ULOGD_RETF_VALID; + ret[KEY_TCP_RST].u.value.b = tcph->rst; + ret[KEY_TCP_RST].flags |= ULOGD_RETF_VALID; + ret[KEY_TCP_SYN].u.value.b = tcph->syn; + ret[KEY_TCP_SYN].flags |= ULOGD_RETF_VALID; + ret[KEY_TCP_FIN].u.value.b = tcph->fin; + ret[KEY_TCP_FIN].flags |= ULOGD_RETF_VALID; + ret[KEY_TCP_RES1].u.value.b = tcph->res1; + ret[KEY_TCP_RES1].flags |= ULOGD_RETF_VALID; + ret[KEY_TCP_RES2].u.value.b = tcph->res2; + ret[KEY_TCP_RES2].flags |= ULOGD_RETF_VALID; + ret[KEY_TCP_CSUM].u.value.ui16 = ntohs(tcph->check); + ret[KEY_TCP_CSUM].u.value.ui16 = ULOGD_RETF_VALID; return 0; } @@ -393,26 +529,23 @@ static int _interp_tcp(struct ulogd_pluginstance *pi) * UDP HEADER ***********************************************************************/ -static int _interp_udp(struct ulogd_pluginstance *pi) +static int _interp_udp(struct ulogd_pluginstance *pi, struct udphdr *udph, + u_int32_t len) { - struct ulogd_key *ret = &pi->output.keys[27]; - struct iphdr *iph = (struct iphdr *) - pi->input.keys[0].u.source->u.value.ptr; - void *protoh = (u_int32_t *)iph + iph->ihl; - struct udphdr *udph = protoh; + struct ulogd_key *ret = pi->output.keys; - if (iph->protocol != IPPROTO_UDP) + if (len < sizeof(struct udphdr)) return 0; - ret[0].u.value.ui16 = ntohs(udph->source); - ret[0].flags |= ULOGD_RETF_VALID; - ret[1].u.value.ui16 = ntohs(udph->dest); - ret[1].flags |= ULOGD_RETF_VALID; - ret[2].u.value.ui16 = ntohs(udph->len); - ret[2].flags |= ULOGD_RETF_VALID; - ret[3].u.value.ui16 = ntohs(udph->check); - ret[3].flags |= ULOGD_RETF_VALID; + ret[KEY_UDP_SPORT].u.value.ui16 = ntohs(udph->source); + ret[KEY_UDP_SPORT].flags |= ULOGD_RETF_VALID; + ret[KEY_UDP_DPORT].u.value.ui16 = ntohs(udph->dest); + ret[KEY_UDP_DPORT].flags |= ULOGD_RETF_VALID; + ret[KEY_UDP_LEN].u.value.ui16 = ntohs(udph->len); + ret[KEY_UDP_LEN].flags |= ULOGD_RETF_VALID; + ret[KEY_UDP_CSUM].u.value.ui16 = ntohs(udph->check); + ret[KEY_UDP_CSUM].flags |= ULOGD_RETF_VALID; return 0; } @@ -421,116 +554,296 @@ static int _interp_udp(struct ulogd_pluginstance *pi) * ICMP HEADER ***********************************************************************/ -static int _interp_icmp(struct ulogd_pluginstance *pi) +static int _interp_icmp(struct ulogd_pluginstance *pi, struct icmphdr *icmph, + u_int32_t len) { - struct ulogd_key *ret = &pi->output.keys[31]; - struct iphdr *iph = (struct iphdr *) - pi->input.keys[0].u.source->u.value.ptr; - void *protoh = (u_int32_t *)iph + iph->ihl; - struct icmphdr *icmph = protoh; + struct ulogd_key *ret = pi->output.keys; - if (iph->protocol != IPPROTO_ICMP) + if (len < sizeof(struct icmphdr)) return 0; - - ret[0].u.value.ui8 = icmph->type; - ret[0].flags |= ULOGD_RETF_VALID; - ret[1].u.value.ui8 = icmph->code; - ret[1].flags |= ULOGD_RETF_VALID; + + ret[KEY_ICMP_TYPE].u.value.ui8 = icmph->type; + ret[KEY_ICMP_TYPE].flags |= ULOGD_RETF_VALID; + ret[KEY_ICMP_CODE].u.value.ui8 = icmph->code; + ret[KEY_ICMP_CODE].flags |= ULOGD_RETF_VALID; switch (icmph->type) { - case ICMP_ECHO: - case ICMP_ECHOREPLY: - ret[2].u.value.ui16 = ntohs(icmph->un.echo.id); - ret[2].flags |= ULOGD_RETF_VALID; - ret[3].u.value.ui16 = ntohs(icmph->un.echo.sequence); - ret[3].flags |= ULOGD_RETF_VALID; - break; - case ICMP_REDIRECT: - case ICMP_PARAMETERPROB: - ret[4].u.value.ui32 = ntohl(icmph->un.gateway); - ret[4].flags |= ULOGD_RETF_VALID; - break; - case ICMP_DEST_UNREACH: - if (icmph->code == ICMP_FRAG_NEEDED) { - ret[5].u.value.ui16 = ntohs(icmph->un.frag.mtu); - ret[5].flags |= ULOGD_RETF_VALID; - } - break; + case ICMP_ECHO: + case ICMP_ECHOREPLY: + ret[KEY_ICMP_ECHOID].u.value.ui16 = ntohs(icmph->un.echo.id); + ret[KEY_ICMP_ECHOID].flags |= ULOGD_RETF_VALID; + ret[KEY_ICMP_ECHOSEQ].u.value.ui16 = ntohs(icmph->un.echo.sequence); + ret[KEY_ICMP_ECHOSEQ].flags |= ULOGD_RETF_VALID; + break; + case ICMP_REDIRECT: + case ICMP_PARAMETERPROB: + ret[KEY_ICMP_GATEWAY].u.value.ui32 = ntohl(icmph->un.gateway); + ret[KEY_ICMP_GATEWAY].flags |= ULOGD_RETF_VALID; + break; + case ICMP_DEST_UNREACH: + if (icmph->code == ICMP_FRAG_NEEDED) { + ret[KEY_ICMP_FRAGMTU].u.value.ui16 = ntohs(icmph->un.frag.mtu); + ret[KEY_ICMP_FRAGMTU].flags |= ULOGD_RETF_VALID; + } + break; } - ret[6].u.value.ui16 = icmph->checksum; - ret[6].flags |= ULOGD_RETF_VALID; + ret[KEY_ICMP_CSUM].u.value.ui16 = icmph->checksum; + ret[KEY_ICMP_CSUM].flags |= ULOGD_RETF_VALID; return 0; } /*********************************************************************** - * IPSEC HEADER + * ICMPv6 HEADER ***********************************************************************/ -static int _interp_ahesp(struct ulogd_pluginstance *pi) +static int _interp_icmpv6(struct ulogd_pluginstance *pi, struct icmp6_hdr *icmph, + u_int32_t len) { - struct ulogd_key *ret = &pi->output.keys[38]; - struct iphdr *iph = (struct iphdr *) - pi->input.keys[0].u.source->u.value.ptr; - void *protoh = (u_int32_t *)iph + iph->ihl; + struct ulogd_key *ret = pi->output.keys; + + if (len < sizeof(struct icmp6_hdr)) + return 0; + ret[KEY_ICMPV6_TYPE].u.value.ui8 = icmph->icmp6_type; + ret[KEY_ICMPV6_TYPE].flags |= ULOGD_RETF_VALID; + ret[KEY_ICMPV6_CODE].u.value.ui8 = icmph->icmp6_code; + ret[KEY_ICMPV6_CODE].flags |= ULOGD_RETF_VALID; + + switch (icmph->icmp6_type) { + case ICMP6_ECHO_REQUEST: + case ICMP6_ECHO_REPLY: + ret[KEY_ICMPV6_ECHOID].u.value.ui16 = ntohs(icmph->icmp6_id); + ret[KEY_ICMPV6_ECHOID].flags |= ULOGD_RETF_VALID; + ret[KEY_ICMPV6_ECHOSEQ].u.value.ui16 = ntohs(icmph->icmp6_seq); + ret[KEY_ICMPV6_ECHOSEQ].flags |= ULOGD_RETF_VALID; + break; + } + ret[KEY_ICMPV6_CSUM].u.value.ui16 = icmph->icmp6_cksum; + ret[KEY_ICMPV6_CSUM].flags |= ULOGD_RETF_VALID; + + return 0; +} + + +/*********************************************************************** + * IPSEC HEADER + ***********************************************************************/ +static int _interp_ahesp(struct ulogd_pluginstance *pi, void *protoh, + u_int32_t len) +{ #if 0 + struct ulogd_key *ret = pi->output.keys; struct esphdr *esph = protoh; - if (iph->protocol != IPPROTO_ESP) - return NULL; + if (len < sizeof(struct esphdr)) + return 0; - ret[0].u.value.ui32 = ntohl(esph->spi); - ret[0].flags |= ULOGD_RETF_VALID; + ret[KEY_AHESP_SPI].u.value.ui32 = ntohl(esph->spi); + ret[KEY_AHESP_SPI].flags |= ULOGD_RETF_VALID; #endif return 0; } -static int _interp_iphdr(struct ulogd_pluginstance *pi) +/*********************************************************************** + * IP HEADER + ***********************************************************************/ + +static int _interp_iphdr(struct ulogd_pluginstance *pi, u_int32_t len) { struct ulogd_key *ret = pi->output.keys; - struct iphdr *iph = (struct iphdr *) - pi->input.keys[0].u.source->u.value.ptr; - - ret[0].u.value.ui32 = ntohl(iph->saddr); - ret[0].flags |= ULOGD_RETF_VALID; - ret[1].u.value.ui32 = ntohl(iph->daddr); - ret[1].flags |= ULOGD_RETF_VALID; - ret[2].u.value.ui8 = iph->protocol; - ret[2].flags |= ULOGD_RETF_VALID; - ret[3].u.value.ui8 = iph->tos; - ret[3].flags |= ULOGD_RETF_VALID; - ret[4].u.value.ui8 = iph->ttl; - ret[4].flags |= ULOGD_RETF_VALID; - ret[5].u.value.ui16 = ntohs(iph->tot_len); - ret[5].flags |= ULOGD_RETF_VALID; - ret[6].u.value.ui8 = iph->ihl; - ret[6].flags |= ULOGD_RETF_VALID; - ret[7].u.value.ui16 = ntohs(iph->check); - ret[7].flags |= ULOGD_RETF_VALID; - ret[8].u.value.ui16 = ntohs(iph->id); - ret[8].flags |= ULOGD_RETF_VALID; - ret[9].u.value.ui16 = ntohs(iph->frag_off); - ret[9].flags |= ULOGD_RETF_VALID; + struct iphdr *iph = pi->input.keys[0].u.source->u.value.ptr; + void *nexthdr = (u_int32_t *)iph + iph->ihl; + + if (len < sizeof(struct iphdr) || len <= iph->ihl * 4) + return 0; + len -= iph->ihl * 4; + + ret[KEY_IP_SADDR].u.value.ui32 = iph->saddr; + ret[KEY_IP_SADDR].flags |= ULOGD_RETF_VALID; + ret[KEY_IP_DADDR].u.value.ui32 = iph->daddr; + ret[KEY_IP_DADDR].flags |= ULOGD_RETF_VALID; + ret[KEY_IP_PROTOCOL].u.value.ui8 = iph->protocol; + ret[KEY_IP_PROTOCOL].flags |= ULOGD_RETF_VALID; + ret[KEY_IP_TOS].u.value.ui8 = iph->tos; + ret[KEY_IP_TOS].flags |= ULOGD_RETF_VALID; + ret[KEY_IP_TTL].u.value.ui8 = iph->ttl; + ret[KEY_IP_TTL].flags |= ULOGD_RETF_VALID; + ret[KEY_IP_TOTLEN].u.value.ui16 = ntohs(iph->tot_len); + ret[KEY_IP_TOTLEN].flags |= ULOGD_RETF_VALID; + ret[KEY_IP_IHL].u.value.ui8 = iph->ihl; + ret[KEY_IP_IHL].flags |= ULOGD_RETF_VALID; + ret[KEY_IP_CSUM].u.value.ui16 = ntohs(iph->check); + ret[KEY_IP_CSUM].flags |= ULOGD_RETF_VALID; + ret[KEY_IP_ID].u.value.ui16 = ntohs(iph->id); + ret[KEY_IP_ID].flags |= ULOGD_RETF_VALID; + ret[KEY_IP_FRAGOFF].u.value.ui16 = ntohs(iph->frag_off); + ret[KEY_IP_FRAGOFF].flags |= ULOGD_RETF_VALID; switch (iph->protocol) { - case IPPROTO_TCP: - _interp_tcp(pi); - break; - case IPPROTO_UDP: - _interp_udp(pi); + case IPPROTO_TCP: + _interp_tcp(pi, nexthdr, len); + break; + case IPPROTO_UDP: + _interp_udp(pi, nexthdr, len); + break; + case IPPROTO_ICMP: + _interp_icmp(pi, nexthdr, len); + break; + case IPPROTO_AH: + case IPPROTO_ESP: + _interp_ahesp(pi, nexthdr, len); + break; + } + + return 0; +} + +/*********************************************************************** + * IPv6 HEADER + ***********************************************************************/ + +static int ip6_ext_hdr(u_int8_t nexthdr) +{ + switch (nexthdr) { + case IPPROTO_HOPOPTS: + case IPPROTO_ROUTING: + case IPPROTO_FRAGMENT: + case IPPROTO_ESP: + case IPPROTO_AH: + case IPPROTO_DSTOPTS: + return 1; + default: + return 0; + } +} + +static int _interp_ipv6hdr(struct ulogd_pluginstance *pi, u_int32_t len) +{ + struct ulogd_key *ret = pi->output.keys; + struct ip6_hdr *ipv6h = pi->input.keys[0].u.source->u.value.ptr; + unsigned int ptr, hdrlen = 0; + u_int8_t curhdr; + int fragment = 0; + + if (len < sizeof(struct ip6_hdr)) + return 0; + + ret[KEY_IP6_SADDR].u.value.ptr = &ipv6h->ip6_src; + ret[KEY_IP6_SADDR].flags |= ULOGD_RETF_VALID; + ret[KEY_IP6_DADDR].u.value.ptr = &ipv6h->ip6_dst; + ret[KEY_IP6_DADDR].flags |= ULOGD_RETF_VALID; + ret[KEY_IP6_PAYLOAD_LEN].u.value.ui16 = ntohs(ipv6h->ip6_plen); + ret[KEY_IP6_PAYLOAD_LEN].flags |= ULOGD_RETF_VALID; + ret[KEY_IP6_PRIORITY].u.value.ui8 = ntohl(ipv6h->ip6_flow & 0x0ff00000) >> 20; + ret[KEY_IP6_PRIORITY].flags |= ULOGD_RETF_VALID; + ret[KEY_IP6_FLOWLABEL].u.value.ui32 = ntohl(ipv6h->ip6_flow & 0x000fffff); + ret[KEY_IP6_FLOWLABEL].flags |= ULOGD_RETF_VALID; + ret[KEY_IP6_HOPLIMIT].u.value.ui8 = ipv6h->ip6_hlim; + ret[KEY_IP6_HOPLIMIT].flags |= ULOGD_RETF_VALID; + + curhdr = ipv6h->ip6_nxt; + ptr = sizeof(struct ip6_hdr); + len -= sizeof(struct ip6_hdr); + + while (curhdr != IPPROTO_NONE && ip6_ext_hdr(curhdr)) { + struct ip6_ext *ext = (void *)ipv6h + ptr; + + if (len < sizeof(struct ip6_ext)) + return 0; + + switch (curhdr) { + case IPPROTO_FRAGMENT: { + struct ip6_frag *fh = (struct ip6_frag *)ext; + + hdrlen = sizeof(struct ip6_frag); + if (len < hdrlen) + return 0; + len -= hdrlen; + + ret[KEY_IP6_FRAG_OFF].u.value.ui16 = ntohs(fh->ip6f_offlg & IP6F_OFF_MASK); + ret[KEY_IP6_FRAG_OFF].flags |= ULOGD_RETF_VALID; + ret[KEY_IP6_FRAG_ID].u.value.ui32 = ntohl(fh->ip6f_ident); + ret[KEY_IP6_FRAG_ID].flags |= ULOGD_RETF_VALID; + + if (ntohs(fh->ip6f_offlg & IP6F_OFF_MASK)) + fragment = 1; break; - case IPPROTO_ICMP: - _interp_icmp(pi); + } + case IPPROTO_DSTOPTS: + case IPPROTO_ROUTING: + case IPPROTO_HOPOPTS: + if (fragment) + goto out; + + hdrlen = (ext->ip6e_len + 1) << 3; + if (len < hdrlen) + return 0; + len -= hdrlen; break; case IPPROTO_AH: - case IPPROTO_ESP: - _interp_ahesp(pi); + if (fragment) + goto out; + + hdrlen = (ext->ip6e_len + 2) << 2; + if (len < hdrlen) + return 0; + len -= hdrlen; + + _interp_ahesp(pi, (void *)ext, len); break; + case IPPROTO_ESP: + if (fragment) + goto out; + + hdrlen = (ext->ip6e_len + 2) << 2; + if (len < hdrlen) + return 0; + len -= hdrlen; + + _interp_ahesp(pi, (void *)ext, len); + goto out; + default: + return 0; + } + + curhdr = ext->ip6e_nxt; + ptr += hdrlen; + } + + if (fragment) + goto out; + + switch (curhdr) { + case IPPROTO_TCP: + _interp_tcp(pi, (void *)ipv6h + ptr, len); + break; + case IPPROTO_UDP: + _interp_udp(pi, (void *)ipv6h + ptr, len); + break; + case IPPROTO_ICMPV6: + _interp_icmpv6(pi, (void *)ipv6h + ptr, len); + break; } +out: + ret[KEY_IP6_NEXTHDR].u.value.ui8 = curhdr; + ret[KEY_IP6_NEXTHDR].flags |= ULOGD_RETF_VALID; + return 0; +} +static int _interp_pkt(struct ulogd_pluginstance *pi) +{ + u_int32_t len = pi->input.keys[1].u.source->u.value.ui32; + u_int8_t family = pi->input.keys[2].u.source->u.value.ui8; + + switch (family) { + case AF_INET: + return _interp_iphdr(pi, len); + case AF_INET6: + return _interp_ipv6hdr(pi, len); + } return 0; } @@ -540,9 +853,21 @@ static struct ulogd_key base_inp[] = { .name = "raw.pkt", .ipfix = { .vendor = IPFIX_VENDOR_NETFILTER, - .field_id = 1 + .field_id = IPFIX_NF_rawpacket, }, }, + { + .type = ULOGD_RET_UINT32, + .name = "raw.pktlen", + .ipfix = { + .vendor = IPFIX_VENDOR_NETFILTER, + .field_id = IPFIX_NF_rawpacket_length, + }, + }, + { + .type = ULOGD_RET_UINT8, + .name = "oob.family", + } }; static struct ulogd_plugin base_plugin = { @@ -557,7 +882,7 @@ static struct ulogd_plugin base_plugin = { .num_keys = ARRAY_SIZE(iphdr_rets), .type = ULOGD_DTYPE_PACKET, }, - .interp = &_interp_iphdr, + .interp = &_interp_pkt, .version = ULOGD_VERSION, }; diff --git a/include/ulogd/ipfix_protocol.h b/include/ulogd/ipfix_protocol.h index 2bf1c3e..5d7e46a 100644 --- a/include/ulogd/ipfix_protocol.h +++ b/include/ulogd/ipfix_protocol.h @@ -64,7 +64,7 @@ enum { IPFIX_postPacketDeltaCount = 24, IPFIX_minimumPacketLength = 25, IPFIX_maximumPacketLength = 26, - IPFIX_sooureIPv6Address = 27, + IPFIX_sourceIPv6Address = 27, IPFIX_destinationIPv6Address = 28, IPFIX_sourceIPv6Mask = 29, IPFIX_destinationIPv6Mask = 30, diff --git a/include/ulogd/printpkt.h b/include/ulogd/printpkt.h index bdaeaa4..3db2862 100644 --- a/include/ulogd/printpkt.h +++ b/include/ulogd/printpkt.h @@ -1,8 +1,62 @@ #ifndef _PRINTPKT_H #define _PRINTPKT_H -#define INTR_IDS 35 -extern struct ulogd_key printpkt_keys[INTR_IDS]; +enum pkt_keys { + KEY_OOB_FAMILY, + KEY_OOB_TIME_SEC, + KEY_OOB_PREFIX, + KEY_OOB_IN, + KEY_OOB_OUT, + KEY_RAW_MAC, + KEY_RAW_MACLEN, + KEY_IP_SADDR, + KEY_IP_DADDR, + KEY_IP_TOTLEN, + KEY_IP_TOS, + KEY_IP_TTL, + KEY_IP_ID, + KEY_IP_FRAGOFF, + KEY_IP_PROTOCOL, + KEY_IP6_SADDR, + KEY_IP6_DADDR, + KEY_IP6_PAYLOAD_LEN, + KEY_IP6_PRIORITY, + KEY_IP6_HOPLIMIT, + KEY_IP6_FLOWLABEL, + KEY_IP6_NEXTHDR, + KEY_IP6_FRAG_OFF, + KEY_IP6_FRAG_ID, + KEY_TCP_SPORT, + KEY_TCP_DPORT, + KEY_TCP_SEQ, + KEY_TCP_ACKSEQ, + KEY_TCP_WINDOW, + KEY_TCP_SYN, + KEY_TCP_ACK, + KEY_TCP_PSH, + KEY_TCP_RST, + KEY_TCP_FIN, + KEY_TCP_URG, + KEY_TCP_URGP, + KEY_UDP_SPORT, + KEY_UDP_DPORT, + KEY_UDP_LEN, + KEY_ICMP_TYPE, + KEY_ICMP_CODE, + KEY_ICMP_ECHOID, + KEY_ICMP_ECHOSEQ, + KEY_ICMP_GATEWAY, + KEY_ICMP_FRAGMTU, + KEY_ICMPV6_TYPE, + KEY_ICMPV6_CODE, + KEY_ICMPV6_ECHOID, + KEY_ICMPV6_ECHOSEQ, + KEY_AHESP_SPI, + __PRINTPKT_KEYS +}; +#define PRINTPKT_KEYS (__PRINTPKT_KEYS) + +extern struct ulogd_key printpkt_keys[PRINTPKT_KEYS]; int printpkt_print(struct ulogd_key *res, char *buf); diff --git a/input/packet/ulogd_inppkt_NFLOG.c b/input/packet/ulogd_inppkt_NFLOG.c index f309259..81f9730 100644 --- a/input/packet/ulogd_inppkt_NFLOG.c +++ b/input/packet/ulogd_inppkt_NFLOG.c @@ -212,6 +212,16 @@ static struct ulogd_key output_keys[] = { .field_id = IPFIX_NF_seq_global, }, }, + { + .type = ULOGD_RET_UINT8, + .flags = ULOGD_RETF_NONE, + .name = "oob.family", + }, + { + .type = ULOGD_RET_UINT16, + .flags = ULOGD_RETF_NONE, + .name = "oob.protocol", + }, }; static inline int @@ -229,16 +239,19 @@ interp_packet(struct ulogd_pluginstance *upi, struct nflog_data *ldata) u_int32_t indev = nflog_get_indev(ldata); u_int32_t outdev = nflog_get_outdev(ldata); u_int32_t seq; - + + ret[14].u.value.ui8 = af_ce(upi->config_kset).u.value; if (ph) { /* FIXME */ ret[10].u.value.ui8 = ph->hook; ret[10].flags |= ULOGD_RETF_VALID; + ret[15].u.value.ui16 = ntohs(ph->hw_protocol); + ret[15].flags |= ULOGD_RETF_VALID; } if (hw) { - ret[0].u.value.ptr = &hw->hw_addr; + ret[0].u.value.ptr = hw->hw_addr; ret[0].flags |= ULOGD_RETF_VALID; ret[11].u.value.ui16 = ntohs(hw->hw_addrlen); ret[11].flags |= ULOGD_RETF_VALID; @@ -286,14 +299,13 @@ interp_packet(struct ulogd_pluginstance *upi, struct nflog_data *ldata) } if (nflog_get_seq(ldata, &seq)) { - ret[10].u.value.ui32 = seq; - ret[10].flags |= ULOGD_RETF_VALID; + ret[12].u.value.ui32 = seq; + ret[12].flags |= ULOGD_RETF_VALID; } if (nflog_get_seq_global(ldata, &seq)) { - ret[11].u.value.ui32 = seq; - ret[11].flags |= ULOGD_RETF_VALID; + ret[13].u.value.ui32 = seq; + ret[13].flags |= ULOGD_RETF_VALID; } - ulogd_propagate_results(upi); return 0; } diff --git a/util/printpkt.c b/util/printpkt.c index ec6cd02..7719cae 100644 --- a/util/printpkt.c +++ b/util/printpkt.c @@ -31,188 +31,354 @@ #include <arpa/inet.h> #include <netinet/ip.h> #include <netinet/ip_icmp.h> +#include <netinet/ip6.h> +#include <netinet/icmp6.h> #include <ulogd/ulogd.h> #include <ulogd/conffile.h> #include <ulogd/printpkt.h> -#define NIPQUAD(addr) \ - ((unsigned char *)&addr)[0], \ - ((unsigned char *)&addr)[1], \ - ((unsigned char *)&addr)[2], \ - ((unsigned char *)&addr)[3] - -struct ulogd_key printpkt_keys[INTR_IDS] = { - { .name = "oob.time.sec", }, - { .name = "oob.prefix", }, - { .name = "oob.in", }, - { .name = "oob.out", }, - { .name = "raw.mac", }, - { .name = "ip.saddr", }, - { .name = "ip.daddr", }, - { .name = "ip.totlen", }, - { .name = "ip.tos", }, - { .name = "ip.ttl", }, - { .name = "ip.id", }, - { .name = "ip.fragoff", }, - { .name = "ip.protocol", }, - { .name = "tcp.sport", }, - { .name = "tcp.dport", }, - { .name = "tcp.seq", }, - { .name = "tcp.ackseq", }, - { .name = "tcp.window", }, - { .name = "tcp.urg", }, - { .name = "tcp.ack", }, - { .name = "tcp.psh", }, - { .name = "tcp.rst", }, - { .name = "tcp.syn", }, - { .name = "tcp.fin", }, - { .name = "tcp.urgp", }, - { .name = "udp.sport", }, - { .name = "udp.dport", }, - { .name = "udp.len", }, - { .name = "icmp.type", }, - { .name = "icmp.code", }, - { .name = "icmp.echoid", }, - { .name = "icmp.echoseq", }, - { .name = "icmp.gateway", }, - { .name = "icmp.fragmtu", }, - { .name = "ahesp.spi", }, +struct ulogd_key printpkt_keys[] = { + [KEY_OOB_FAMILY] = { .name = "oob.family", }, + [KEY_OOB_TIME_SEC] = { .name = "oob.time.sec", }, + [KEY_OOB_PREFIX] = { .name = "oob.prefix", }, + [KEY_OOB_IN] = { .name = "oob.in", }, + [KEY_OOB_OUT] = { .name = "oob.out", }, + [KEY_RAW_MAC] = { .name = "raw.mac", }, + [KEY_RAW_MACLEN] = { .name = "raw.mac_len", }, + [KEY_IP_SADDR] = { .name = "ip.saddr", }, + [KEY_IP_DADDR] = { .name = "ip.daddr", }, + [KEY_IP_TOTLEN] = { .name = "ip.totlen", }, + [KEY_IP_TOS] = { .name = "ip.tos", }, + [KEY_IP_TTL] = { .name = "ip.ttl", }, + [KEY_IP_ID] = { .name = "ip.id", }, + [KEY_IP_FRAGOFF] = { .name = "ip.fragoff", }, + [KEY_IP_PROTOCOL] = { .name = "ip.protocol", }, + [KEY_IP6_SADDR] = { .name = "ip6.saddr", }, + [KEY_IP6_DADDR] = { .name = "ip6.daddr", }, + [KEY_IP6_PAYLOAD_LEN] = { .name = "ip6.payload_len" }, + [KEY_IP6_PRIORITY] = { .name = "ip6.priority" }, + [KEY_IP6_HOPLIMIT] = { .name = "ip6.hoplimit" }, + [KEY_IP6_FLOWLABEL] = { .name = "ip6.flowlabel" }, + [KEY_IP6_NEXTHDR] = { .name = "ip6.nexthdr" }, + [KEY_IP6_FRAG_OFF] = { .name = "ip6.fragoff" }, + [KEY_IP6_FRAG_ID] = { .name = "ip6.fragid" }, + [KEY_TCP_SPORT] = { .name = "tcp.sport", }, + [KEY_TCP_DPORT] = { .name = "tcp.dport", }, + [KEY_TCP_SEQ] = { .name = "tcp.seq", }, + [KEY_TCP_ACKSEQ] = { .name = "tcp.ackseq", }, + [KEY_TCP_WINDOW] = { .name = "tcp.window", }, + [KEY_TCP_SYN] = { .name = "tcp.syn", }, + [KEY_TCP_ACK] = { .name = "tcp.ack", }, + [KEY_TCP_URG] = { .name = "tcp.urg", }, + [KEY_TCP_PSH] = { .name = "tcp.psh", }, + [KEY_TCP_RST] = { .name = "tcp.rst", }, + [KEY_TCP_FIN] = { .name = "tcp.fin", }, + [KEY_TCP_URG] = { .name = "tcp.urg", }, + [KEY_TCP_URGP] = { .name = "tcp.urgp", }, + [KEY_UDP_SPORT] = { .name = "udp.sport", }, + [KEY_UDP_DPORT] = { .name = "udp.dport", }, + [KEY_UDP_LEN] = { .name = "udp.len", }, + [KEY_ICMP_TYPE] = { .name = "icmp.type", }, + [KEY_ICMP_CODE] = { .name = "icmp.code", }, + [KEY_ICMP_ECHOID] = { .name = "icmp.echoid", }, + [KEY_ICMP_ECHOSEQ] = { .name = "icmp.echoseq", }, + [KEY_ICMP_GATEWAY] = { .name = "icmp.gateway", }, + [KEY_ICMP_FRAGMTU] = { .name = "icmp.fragmtu", }, + [KEY_ICMPV6_TYPE] = { .name = "icmpv6.type", }, + [KEY_ICMPV6_CODE] = { .name = "icmpv6.code", }, + [KEY_ICMPV6_ECHOID] = { .name = "icmpv6.echoid", }, + [KEY_ICMPV6_ECHOSEQ] = { .name = "icmpv6.echoseq", }, + [KEY_AHESP_SPI] = { .name = "ahesp.spi", }, }; #define GET_VALUE(res, x) (res[x].u.source->u.value) #define GET_FLAGS(res, x) (res[x].u.source->flags) #define pp_is_valid(res, x) (GET_FLAGS(res, x) & ULOGD_RETF_VALID) -int printpkt_print(struct ulogd_key *res, char *buf) +static int printpkt_proto(struct ulogd_key *res, char *buf, int protocol) { char *buf_cur = buf; - if (pp_is_valid(res, 1)) - buf_cur += sprintf(buf_cur, "%s ", (char *) GET_VALUE(res, 1).ptr); - - if (pp_is_valid(res, 2) && pp_is_valid(res, 3)) { - buf_cur += sprintf(buf_cur, "IN=%s OUT=%s ", - (char *) GET_VALUE(res, 2).ptr, - (char *) GET_VALUE(res, 3).ptr); - } - - /* FIXME: configurable */ - if (pp_is_valid(res, 4)) - buf_cur += sprintf(buf_cur, "MAC=%s ", - (char *) GET_VALUE(res, 4).ptr); - else - buf_cur += sprintf(buf_cur, "MAC= "); - - if (pp_is_valid(res, 5)) - buf_cur += sprintf(buf_cur, "SRC=%s ", inet_ntoa( - (struct in_addr) {htonl(GET_VALUE(res, 5).ui32)})); - - if (pp_is_valid(res, 6)) - buf_cur += sprintf(buf_cur, "DST=%s ", inet_ntoa( - (struct in_addr) {htonl(GET_VALUE(res, 6).ui32)})); - - /* FIXME: add pp_is_valid calls to remainder of file */ - buf_cur += sprintf(buf_cur,"LEN=%u TOS=%02X PREC=0x%02X TTL=%u ID=%u ", - GET_VALUE(res, 7).ui16, GET_VALUE(res, 8).ui8 & IPTOS_TOS_MASK, - GET_VALUE(res, 8).ui8 & IPTOS_PREC_MASK, GET_VALUE(res, 9).ui8, - GET_VALUE(res, 10).ui16); - - if (GET_VALUE(res, 10).ui16 & IP_RF) - buf_cur += sprintf(buf_cur, "CE "); - - if (GET_VALUE(res, 11).ui16 & IP_DF) - buf_cur += sprintf(buf_cur, "DF "); - - if (GET_VALUE(res, 11).ui16 & IP_MF) - buf_cur += sprintf(buf_cur, "MF "); - - if (GET_VALUE(res, 11).ui16 & IP_OFFMASK) - buf_cur += sprintf(buf_cur, "FRAG:%u ", - GET_VALUE(res, 11).ui16 & IP_OFFMASK); + switch (protocol) { + case IPPROTO_TCP: + buf_cur += sprintf(buf_cur, "PROTO=KEY_TCP "); - switch (GET_VALUE(res, 12).ui8) { + if (!pp_is_valid(res, KEY_TCP_SPORT)) { + buf_cur += sprintf(buf_cur, "INCOMPLETE"); + break; + } - case IPPROTO_TCP: - buf_cur += sprintf(buf_cur, "PROTO=TCP "); buf_cur += sprintf(buf_cur, "SPT=%u DPT=%u ", - GET_VALUE(res, 13).ui16, GET_VALUE(res, 14).ui16); + GET_VALUE(res, KEY_TCP_SPORT).ui16, + GET_VALUE(res, KEY_TCP_DPORT).ui16); /* FIXME: config */ buf_cur += sprintf(buf_cur, "SEQ=%u ACK=%u ", - GET_VALUE(res, 15).ui32, GET_VALUE(res, 16).ui32); + GET_VALUE(res, KEY_TCP_SEQ).ui32, + GET_VALUE(res, KEY_TCP_ACKSEQ).ui32); - buf_cur += sprintf(buf_cur, "WINDOW=%u ", GET_VALUE(res, 17).ui16); + buf_cur += sprintf(buf_cur, "WINDOW=%u ", + GET_VALUE(res, KEY_TCP_WINDOW).ui16); // buf_cur += sprintf(buf_cur, "RES=0x%02x ", - if (GET_VALUE(res, 18).b) + if (GET_VALUE(res, KEY_TCP_URG).b) buf_cur += sprintf(buf_cur, "URG "); - if (GET_VALUE(res, 19).b) + if (GET_VALUE(res, KEY_TCP_ACK).b) buf_cur += sprintf(buf_cur, "ACK "); - if (GET_VALUE(res, 20).b) + if (GET_VALUE(res, KEY_TCP_PSH).b) buf_cur += sprintf(buf_cur, "PSH "); - if (GET_VALUE(res, 21).b) + if (GET_VALUE(res, KEY_TCP_RST).b) buf_cur += sprintf(buf_cur, "RST "); - if (GET_VALUE(res, 22).b) + if (GET_VALUE(res, KEY_TCP_SYN).b) buf_cur += sprintf(buf_cur, "SYN "); - if (GET_VALUE(res, 23).b) + if (GET_VALUE(res, KEY_TCP_FIN).b) buf_cur += sprintf(buf_cur, "FIN "); - buf_cur += sprintf(buf_cur, "URGP=%u ", GET_VALUE(res, 24).ui16); + buf_cur += sprintf(buf_cur, "URGP=%u ", + GET_VALUE(res, KEY_TCP_URGP).ui16); break; + case IPPROTO_UDP: + buf_cur += sprintf(buf_cur, "PROTO=KEY_UDP "); - buf_cur += sprintf(buf_cur, "PROTO=UDP "); + if (!pp_is_valid(res, KEY_UDP_SPORT)) { + buf_cur += sprintf(buf_cur, "INCOMPLETE"); + break; + } buf_cur += sprintf(buf_cur, "SPT=%u DPT=%u LEN=%u ", - GET_VALUE(res, 25).ui16, GET_VALUE(res, 26).ui16, - GET_VALUE(res, 27).ui16); + GET_VALUE(res, KEY_UDP_SPORT).ui16, + GET_VALUE(res, KEY_UDP_DPORT).ui16, + GET_VALUE(res, KEY_UDP_LEN).ui16); + break; + case IPPROTO_ESP: + case IPPROTO_AH: + buf_cur += sprintf(buf_cur, "PROTO=%s ", + GET_VALUE(res, KEY_IP_PROTOCOL).ui8 == IPPROTO_ESP ? "ESP" : "AH"); + + if (!pp_is_valid(res, KEY_AHESP_SPI)) { + buf_cur += sprintf(buf_cur, "INCOMPLETE"); break; - case IPPROTO_ICMP: + } + + buf_cur += sprintf(buf_cur, "SPI=0x%x ", + GET_VALUE(res, KEY_AHESP_SPI).ui32); + break; + } + + return buf_cur - buf; +} + +static int printpkt_ipv4(struct ulogd_key *res, char *buf) +{ + char *buf_cur = buf; + char tmp[INET_ADDRSTRLEN]; + + if (pp_is_valid(res, KEY_IP_SADDR)) + buf_cur += sprintf(buf_cur, "SRC=%s ", + inet_ntop(AF_INET, + &GET_VALUE(res, KEY_IP_SADDR).ui32, + tmp, sizeof(tmp))); + if (pp_is_valid(res, KEY_IP_DADDR)) + buf_cur += sprintf(buf_cur, "DST=%s ", + inet_ntop(AF_INET, + &GET_VALUE(res, KEY_IP_DADDR).ui32, + tmp, sizeof(tmp))); + + /* FIXME: add pp_is_valid calls to remainder of file */ + buf_cur += sprintf(buf_cur,"LEN=%u TOS=%02X PREC=0x%02X TTL=%u ID=%u ", + GET_VALUE(res, KEY_IP_TOTLEN).ui16, + GET_VALUE(res, KEY_IP_TOS).ui8 & IPTOS_TOS_MASK, + GET_VALUE(res, KEY_IP_TOS).ui8 & IPTOS_PREC_MASK, + GET_VALUE(res, KEY_IP_TTL).ui8, + GET_VALUE(res, KEY_IP_ID).ui16); + + if (GET_VALUE(res, KEY_IP_FRAGOFF).ui16 & IP_RF) + buf_cur += sprintf(buf_cur, "CE "); + + if (GET_VALUE(res, KEY_IP_FRAGOFF).ui16 & IP_DF) + buf_cur += sprintf(buf_cur, "DF "); + + if (GET_VALUE(res, KEY_IP_FRAGOFF).ui16 & IP_MF) + buf_cur += sprintf(buf_cur, "MF "); + + if (GET_VALUE(res, KEY_IP_FRAGOFF).ui16 & IP_OFFMASK) + buf_cur += sprintf(buf_cur, "FRAG:%u ", + GET_VALUE(res, KEY_IP_FRAGOFF).ui16 & IP_OFFMASK); + + switch (GET_VALUE(res, KEY_IP_PROTOCOL).ui8) { + case IPPROTO_TCP: + case IPPROTO_UDP: + case IPPROTO_ESP: + case IPPROTO_AH: + buf_cur += printpkt_proto(res, buf_cur, + GET_VALUE(res, KEY_IP_PROTOCOL).ui8); + break; + + case IPPROTO_ICMP: buf_cur += sprintf(buf_cur, "PROTO=ICMP "); + if (!pp_is_valid(res, KEY_ICMP_TYPE)) { + buf_cur += sprintf(buf_cur, "INCOMPLETE"); + break; + } + buf_cur += sprintf(buf_cur, "TYPE=%u CODE=%u ", - GET_VALUE(res, 28).ui8, GET_VALUE(res, 29).ui8); + GET_VALUE(res, KEY_ICMP_TYPE).ui8, + GET_VALUE(res, KEY_ICMP_CODE).ui8); - switch (GET_VALUE(res, 28).ui8) { + switch (GET_VALUE(res, KEY_ICMP_TYPE).ui8) { case ICMP_ECHO: case ICMP_ECHOREPLY: buf_cur += sprintf(buf_cur, "ID=%u SEQ=%u ", - GET_VALUE(res, 30).ui16, - GET_VALUE(res, 31).ui16); + GET_VALUE(res, KEY_ICMP_ECHOID).ui16, + GET_VALUE(res, KEY_ICMP_ECHOSEQ).ui16); break; case ICMP_PARAMETERPROB: buf_cur += sprintf(buf_cur, "PARAMETER=%u ", - GET_VALUE(res, 32).ui32 >> 24); + GET_VALUE(res, KEY_ICMP_GATEWAY).ui32 >> 24); break; case ICMP_REDIRECT: - buf_cur += sprintf(buf_cur, "GATEWAY=%s ", inet_ntoa((struct in_addr) {htonl(GET_VALUE(res, 32).ui32)})); + buf_cur += sprintf(buf_cur, "GATEWAY=%s ", + inet_ntop(AF_INET, + &GET_VALUE(res, KEY_ICMP_GATEWAY).ui32, + tmp, sizeof(tmp))); break; case ICMP_DEST_UNREACH: - if (GET_VALUE(res, 29).ui8 == ICMP_FRAG_NEEDED) + if (GET_VALUE(res, KEY_ICMP_CODE).ui8 == ICMP_FRAG_NEEDED) buf_cur += sprintf(buf_cur, "MTU=%u ", - GET_VALUE(res, 33).ui16); + GET_VALUE(res, KEY_ICMP_FRAGMTU).ui16); break; } break; + default: + buf_cur += sprintf(buf_cur, "PROTO=%u ", + GET_VALUE(res, KEY_IP_PROTOCOL).ui8); + } + + return buf_cur - buf; +} + +static int printpkt_ipv6(struct ulogd_key *res, char *buf) +{ + char *buf_cur = buf; + char tmp[INET6_ADDRSTRLEN]; + + if (pp_is_valid(res, KEY_IP6_SADDR)) + buf_cur += sprintf(buf_cur, "SRC=%s ", + inet_ntop(AF_INET6, + GET_VALUE(res, KEY_IP6_SADDR).ptr, + tmp, sizeof(tmp))); + + if (pp_is_valid(res, KEY_IP6_DADDR)) + buf_cur += sprintf(buf_cur, "DST=%s ", + inet_ntop(AF_INET6, + GET_VALUE(res, KEY_IP6_DADDR).ptr, + tmp, sizeof(tmp))); + + if (pp_is_valid(res, KEY_IP6_PAYLOAD_LEN)) + buf_cur += sprintf(buf_cur, "LEN=%Zu ", + GET_VALUE(res, KEY_IP6_PAYLOAD_LEN).ui16 + + sizeof(struct ip6_hdr)); + + if (pp_is_valid(res, KEY_IP6_PRIORITY)) + buf_cur += sprintf(buf_cur, "TC=%u ", + GET_VALUE(res, KEY_IP6_PRIORITY).ui8); + + if (pp_is_valid(res, KEY_IP6_HOPLIMIT)) + buf_cur += sprintf(buf_cur, "HOPLIMIT=%u ", + GET_VALUE(res, KEY_IP6_HOPLIMIT).ui8); + + if (pp_is_valid(res, KEY_IP6_FLOWLABEL)) + buf_cur += sprintf(buf_cur, "FLOWLBL=%u ", + GET_VALUE(res, KEY_IP6_FLOWLABEL).ui32); + + if (pp_is_valid(res, KEY_IP6_FRAG_OFF) && pp_is_valid(res, KEY_IP6_FRAG_ID)) + buf_cur += sprintf(buf_cur, "FRAG: %u ID: %08x ", + GET_VALUE(res, KEY_IP6_FRAG_OFF).ui16, + GET_VALUE(res, KEY_IP6_FRAG_ID).ui32); + + switch (GET_VALUE(res, KEY_IP6_NEXTHDR).ui8) { + case IPPROTO_TCP: + case IPPROTO_UDP: case IPPROTO_ESP: case IPPROTO_AH: - buf_cur += sprintf(buf_cur, "PROTO=%s ", GET_VALUE(res, 12).ui8 == IPPROTO_ESP ? "ESP" : "AH"); - /* FIXME: "INCOMPLETE [%u bytes]" in case of short pkt */ - if (pp_is_valid(res, 34)) { - buf_cur += sprintf(buf_cur, "SPI=0x%x ", GET_VALUE(res, 34).ui32); + buf_cur += printpkt_proto(res, buf_cur, + GET_VALUE(res, KEY_IP6_NEXTHDR).ui8); + break; + case IPPROTO_ICMPV6: + buf_cur += sprintf(buf_cur, "PROTO=ICMPv6 "); + + if (!pp_is_valid(res, KEY_ICMPV6_TYPE)) { + buf_cur += sprintf(buf_cur, "INCOMPLETE"); + break; + } + + if (!(pp_is_valid(res, KEY_ICMPV6_TYPE) && + pp_is_valid(res, KEY_ICMPV6_CODE))) { + buf_cur += sprintf(buf_cur, "TRUNCATED"); + break; + } + + buf_cur += sprintf(buf_cur, "TYPE=%u CODE=%u ", + GET_VALUE(res, KEY_ICMPV6_TYPE).ui8, + GET_VALUE(res, KEY_ICMPV6_CODE).ui8); + + switch (GET_VALUE(res, KEY_ICMPV6_TYPE).ui8) { + case ICMP6_ECHO_REQUEST: + case ICMP6_ECHO_REPLY: + buf_cur += sprintf(buf_cur, "ID=%u SEQ=%u ", + GET_VALUE(res, KEY_ICMPV6_ECHOID).ui16, + GET_VALUE(res, KEY_ICMPV6_ECHOSEQ).ui16); + break; } break; - default: + } + + return buf_cur - buf; +} - buf_cur += sprintf(buf_cur, "PROTO=%u ", GET_VALUE(res, 12).ui8); +int printpkt_print(struct ulogd_key *res, char *buf) +{ + char *buf_cur = buf; + + if (pp_is_valid(res, KEY_OOB_PREFIX)) + buf_cur += sprintf(buf_cur, "%s ", + (char *) GET_VALUE(res, KEY_OOB_PREFIX).ptr); + + if (pp_is_valid(res, KEY_OOB_IN) && pp_is_valid(res, KEY_OOB_OUT)) + buf_cur += sprintf(buf_cur, "IN=%s OUT=%s ", + (char *) GET_VALUE(res, KEY_OOB_IN).ptr, + (char *) GET_VALUE(res, KEY_OOB_OUT).ptr); + + /* FIXME: configurable */ + if (pp_is_valid(res, KEY_RAW_MAC)) { + unsigned char *mac = (unsigned char *) GET_VALUE(res, KEY_RAW_MAC).ptr; + int i, len = GET_VALUE(res, KEY_RAW_MACLEN).ui16 * 2; + + buf_cur += sprintf(buf_cur, "MAC="); + for (i = 0; i < len; i++) + buf_cur += sprintf(buf_cur, "%02x%c", mac[i], + i == len - 1 ? ' ' : ':'); + } else + buf_cur += sprintf(buf_cur, "MAC= "); + + switch (GET_VALUE(res, KEY_OOB_FAMILY).ui8) { + case AF_INET: + buf_cur += printpkt_ipv4(res, buf_cur); + break; + case AF_INET6: + buf_cur += printpkt_ipv6(res, buf_cur); + break; } + strcat(buf_cur, "\n"); return 0; |