summaryrefslogtreecommitdiffstats
path: root/util/printpkt.c
diff options
context:
space:
mode:
Diffstat (limited to 'util/printpkt.c')
-rw-r--r--util/printpkt.c398
1 files changed, 282 insertions, 116 deletions
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;