/* darkstat 3
- * copyright (c) 2001-2009 Emil Mikulic.
+ * copyright (c) 2001-2011 Emil Mikulic.
*
* decode.c: packet decoding.
*
* GNU General Public License version 2. (see COPYING.GPL)
*/
-#include "darkstat.h"
-#include "acct.h"
-#include "cap.h"
+#include "cdefs.h"
+#include "decode.h"
+#include "err.h"
+#include "opt.h"
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <assert.h>
-#include "err.h"
#include <pcap.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h> /* inet_ntoa() */
+#include <net/if.h> /* struct ifreq */
/* need struct ether_header */
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-# include <sys/queue.h>
-# include <net/if.h>
-# include <net/if_arp.h>
+#ifdef __NetBSD__ /* works for NetBSD 5.1.2 */
# include <netinet/if_ether.h>
#else
-# ifdef __sun
-# include <sys/ethernet.h>
-# define ETHER_HDR_LEN 14
+# ifdef __OpenBSD__
+# include <sys/queue.h>
+# include <net/if_arp.h>
+# include <netinet/if_ether.h>
# else
-# ifdef _AIX
-# include <netinet/if_ether.h>
+# ifdef __sun
+# include <sys/ethernet.h>
# define ETHER_HDR_LEN 14
# else
-# include <net/ethernet.h>
+# ifdef _AIX
+# include <netinet/if_ether.h>
+# define ETHER_HDR_LEN 14
+# else
+# include <net/ethernet.h>
+# endif
# endif
# endif
#endif
+
#ifndef ETHERTYPE_PPPOE
-#define ETHERTYPE_PPPOE 0x8864
+# define ETHERTYPE_PPPOE 0x8864
#endif
-
#ifndef ETHERTYPE_IPV6
-# ifdef HAVE_NET_IF_ETHER_H
-# include <net/if_ether.h> /* ETH_P_IPV6 for GNU/kfreebsd */
-# endif
-# ifdef ETH_P_IPV6
-# define ETHERTYPE_IPV6 ETH_P_IPV6
-# endif
+# define ETHERTYPE_IPV6 0x86DD
#endif
-#include <net/if.h> /* struct ifreq */
#include <netinet/in_systm.h> /* n_long */
#include <netinet/ip.h> /* struct ip */
#include <netinet/ip6.h> /* struct ip6_hdr */
#include <netinet/tcp.h> /* struct tcphdr */
#include <netinet/udp.h> /* struct udphdr */
-extern int want_pppoe;
-
-static void decode_ether(u_char *, const struct pcap_pkthdr *,
- const u_char *);
-static void decode_loop(u_char *, const struct pcap_pkthdr *,
- const u_char *);
-static void decode_ppp(u_char *, const struct pcap_pkthdr *,
- const u_char *);
-static void decode_pppoe(u_char *, const struct pcap_pkthdr *,
- const u_char *);
-static void decode_pppoe_real(const u_char *pdata, const uint32_t len,
- pktsummary *sm);
-static void decode_linux_sll(u_char *, const struct pcap_pkthdr *,
- const u_char *);
-static void decode_raw(u_char *, const struct pcap_pkthdr *,
- const u_char *);
-static void decode_ip(const u_char *pdata, const uint32_t len,
- pktsummary *sm);
-static void decode_ipv6(const u_char *pdata, const uint32_t len,
- pktsummary *sm);
+#define PPP_HDR_LEN 4
+#define FDDI_HDR_LEN 21
+#define IP_HDR_LEN sizeof(struct ip)
+#define IPV6_HDR_LEN sizeof(struct ip6_hdr)
+#define TCP_HDR_LEN sizeof(struct tcphdr)
+#define UDP_HDR_LEN sizeof(struct udphdr)
+#define NULL_HDR_LEN 4
+#define SLL_HDR_LEN 16
+#define RAW_HDR_LEN 0
+
+#ifndef IPV6_VERSION
+# define IPV6_VERSION 0x60
+#endif
+
+#ifndef IPV6_VERSION_MASK
+# define IPV6_VERSION_MASK 0xF0
+#endif
+
+static int decode_ether(DECODER_ARGS);
+static int decode_loop(DECODER_ARGS);
+static int decode_null(DECODER_ARGS);
+static int decode_ppp(DECODER_ARGS);
+static int decode_pppoe(DECODER_ARGS);
+#ifdef DLT_LINUX_SLL
+static int decode_linux_sll(DECODER_ARGS);
+#endif
+static int decode_raw(DECODER_ARGS);
+
+#define HELPER_ARGS const u_char *pdata, \
+ const uint32_t len, \
+ struct pktsummary *sm
+
+static int helper_pppoe(HELPER_ARGS);
+static int helper_ip(HELPER_ARGS);
+static int helper_ipv6(HELPER_ARGS);
+static void helper_ip_deeper(HELPER_ARGS); /* protocols like TCP/UDP */
/* Link-type header information */
-static const linkhdr_t linkhdrs[] = {
+static const struct linkhdr linkhdrs[] = {
/* linktype hdrlen handler */
- { DLT_EN10MB, ETHER_HDR_LEN, decode_ether },
- { DLT_LOOP, NULL_HDR_LEN, decode_loop },
- { DLT_NULL, NULL_HDR_LEN, decode_loop },
+ { DLT_EN10MB, ETHER_HDR_LEN, decode_ether },
+ { DLT_LOOP, NULL_HDR_LEN, decode_loop },
+ { DLT_NULL, NULL_HDR_LEN, decode_null },
{ DLT_PPP, PPP_HDR_LEN, decode_ppp },
#if defined(__NetBSD__)
{ DLT_PPP_SERIAL, PPP_HDR_LEN, decode_ppp },
{ DLT_LINUX_SLL, SLL_HDR_LEN, decode_linux_sll },
#endif
{ DLT_RAW, RAW_HDR_LEN, decode_raw },
- { -1, -1, NULL }
+ { -1, 0, NULL }
};
-/*
- * Returns a pointer to the linkhdr_t record matching the given linktype, or
+/* Returns a pointer to the linkhdr record matching the given linktype, or
* NULL if no matching entry found.
*/
-const linkhdr_t *
-getlinkhdr(int linktype)
-{
- int i;
+const struct linkhdr *getlinkhdr(const int linktype) {
+ size_t i;
for (i=0; linkhdrs[i].linktype != -1; i++)
if (linkhdrs[i].linktype == linktype)
return (&(linkhdrs[i]));
- return (NULL);
+ return NULL;
}
-/*
- * Returns the minimum snaplen needed to decode everything up to the TCP/UDP
- * packet headers. The IPv6 header is normative. The argument lh is not
- * allowed to be NULL.
+/* Returns the minimum snaplen needed to decode everything up to and including
+ * the TCP/UDP packet headers.
*/
-int
-getsnaplen(const linkhdr_t *lh)
-{
- assert(lh != NULL);
- return (lh->hdrlen + IPV6_HDR_LEN + max(TCP_HDR_LEN, UDP_HDR_LEN));
+int getsnaplen(const struct linkhdr *lh) {
+ return (int)(lh->hdrlen + IPV6_HDR_LEN + MAX(TCP_HDR_LEN, UDP_HDR_LEN));
}
-/*
- * Convert IP address to a numbers-and-dots notation in a static buffer
- * provided by inet_ntoa().
- */
-char *
-ip_to_str(const in_addr_t ip)
-{
- struct in_addr in;
-
- in.s_addr = ip;
- return (inet_ntoa(in));
-}
-
-char ip6str[INET6_ADDRSTRLEN];
-
-char *
-ip6_to_str(const struct in6_addr *ip6)
-{
- ip6str[0] = '\0';
- inet_ntop(AF_INET6, ip6, ip6str, sizeof(ip6str));
-
- return (ip6str);
-}
-
-/* Decoding functions. */
-static void
-decode_ether(u_char *user _unused_,
- const struct pcap_pkthdr *pheader,
- const u_char *pdata)
-{
+static int decode_ether(DECODER_ARGS) {
u_short type;
const struct ether_header *hdr = (const struct ether_header *)pdata;
- pktsummary sm;
- memset(&sm, 0, sizeof(sm));
- sm.time = pheader->ts.tv_sec;
if (pheader->caplen < ETHER_HDR_LEN) {
verbosef("ether: packet too short (%u bytes)", pheader->caplen);
- return;
+ return 0;
}
-
#ifdef __sun
- memcpy(sm.src_mac, hdr->ether_shost.ether_addr_octet, sizeof(sm.src_mac));
- memcpy(sm.dst_mac, hdr->ether_dhost.ether_addr_octet, sizeof(sm.dst_mac));
+ memcpy(sm->src_mac, hdr->ether_shost.ether_addr_octet, sizeof(sm->src_mac));
+ memcpy(sm->dst_mac, hdr->ether_dhost.ether_addr_octet, sizeof(sm->dst_mac));
#else
- memcpy(sm.src_mac, hdr->ether_shost, sizeof(sm.src_mac));
- memcpy(sm.dst_mac, hdr->ether_dhost, sizeof(sm.dst_mac));
+ memcpy(sm->src_mac, hdr->ether_shost, sizeof(sm->src_mac));
+ memcpy(sm->dst_mac, hdr->ether_dhost, sizeof(sm->dst_mac));
#endif
-
- type = ntohs( hdr->ether_type );
+ type = ntohs(hdr->ether_type);
switch (type) {
- case ETHERTYPE_IP:
- case ETHERTYPE_IPV6:
- if (!want_pppoe) {
- decode_ip(pdata + ETHER_HDR_LEN,
- pheader->caplen - ETHER_HDR_LEN, &sm);
- acct_for(&sm);
- } else
+ case ETHERTYPE_IP:
+ case ETHERTYPE_IPV6:
+ if (!opt_want_pppoe)
+ return helper_ip(pdata + ETHER_HDR_LEN,
+ pheader->caplen - ETHER_HDR_LEN,
+ sm);
verbosef("ether: discarded IP packet, expecting PPPoE instead");
- break;
- case ETHERTYPE_ARP:
- /* known protocol, don't complain about it. */
- break;
- case ETHERTYPE_PPPOE:
- if (want_pppoe)
- decode_pppoe_real(pdata + ETHER_HDR_LEN,
- pheader->caplen - ETHER_HDR_LEN, &sm);
- else
+ return 0;
+ case ETHERTYPE_PPPOE:
+ if (opt_want_pppoe)
+ return helper_pppoe(pdata + ETHER_HDR_LEN,
+ pheader->caplen - ETHER_HDR_LEN,
+ sm);
verbosef("ether: got PPPoE frame: maybe you want --pppoe");
- break;
- default:
- verbosef("ether: unknown protocol (0x%04x)", type);
+ return 0;
+ case ETHERTYPE_ARP:
+ /* known protocol, don't complain about it. */
+ return 0;
+ default:
+ verbosef("ether: unknown protocol (0x%04x)", type);
+ return 0;
}
}
-static void
-decode_loop(u_char *user _unused_,
- const struct pcap_pkthdr *pheader,
- const u_char *pdata)
-{
+/* Very similar to decode_null, except on OpenBSD we need to think
+ * about family endianness.
+ */
+static int decode_loop(DECODER_ARGS) {
uint32_t family;
- pktsummary sm;
- memset(&sm, 0, sizeof(sm));
if (pheader->caplen < NULL_HDR_LEN) {
verbosef("loop: packet too short (%u bytes)", pheader->caplen);
- return;
+ return 0;
}
family = *(const uint32_t *)pdata;
#ifdef __OpenBSD__
family = ntohl(family);
#endif
- if (family == AF_INET) {
- /* OpenBSD tun or FreeBSD tun or FreeBSD lo */
- decode_ip(pdata + NULL_HDR_LEN, pheader->caplen - NULL_HDR_LEN, &sm);
- sm.time = pheader->ts.tv_sec;
- acct_for(&sm);
- }
- else if (family == AF_INET6) {
- /* XXX: Check this! */
- decode_ip(pdata + NULL_HDR_LEN, pheader->caplen - NULL_HDR_LEN, &sm);
- sm.time = pheader->ts.tv_sec;
- acct_for(&sm);
- }
- else
- verbosef("loop: unknown family (%x)", family);
+ if (family == AF_INET)
+ return helper_ip(pdata + NULL_HDR_LEN,
+ pheader->caplen - NULL_HDR_LEN, sm);
+ if (family == AF_INET6)
+ return helper_ipv6(pdata + NULL_HDR_LEN,
+ pheader->caplen - NULL_HDR_LEN, sm);
+ verbosef("loop: unknown family (0x%04x)", family);
+ return 0;
}
-static void
-decode_ppp(u_char *user _unused_,
- const struct pcap_pkthdr *pheader,
- const u_char *pdata)
-{
- pktsummary sm;
- memset(&sm, 0, sizeof(sm));
+static int decode_null(DECODER_ARGS) {
+ uint32_t family;
- if (pheader->caplen < PPPOE_HDR_LEN) {
- verbosef("ppp: packet too short (%u bytes)", pheader->caplen);
- return;
+ if (pheader->caplen < NULL_HDR_LEN) {
+ verbosef("null: packet too short (%u bytes)", pheader->caplen);
+ return 0;
}
-
- if (pdata[2] == 0x00 && pdata[3] == 0x21) {
- decode_ip(pdata + PPP_HDR_LEN, pheader->caplen - PPP_HDR_LEN, &sm);
- sm.time = pheader->ts.tv_sec;
- acct_for(&sm);
- } else
- verbosef("non-IP PPP packet; ignoring.");
-}
-
-static void
-decode_pppoe(u_char *user _unused_,
- const struct pcap_pkthdr *pheader,
- const u_char *pdata)
-{
- pktsummary sm;
- memset(&sm, 0, sizeof(sm));
- sm.time = pheader->ts.tv_sec;
- decode_pppoe_real(pdata, pheader->caplen, &sm);
+ family = *(const uint32_t *)pdata;
+ if (family == AF_INET)
+ return helper_ip(pdata + NULL_HDR_LEN,
+ pheader->caplen - NULL_HDR_LEN,
+ sm);
+ if (family == AF_INET6)
+ return helper_ipv6(pdata + NULL_HDR_LEN,
+ pheader->caplen - NULL_HDR_LEN,
+ sm);
+ verbosef("null: unknown family (0x%04x)", family);
+ return 0;
}
-static void
-decode_pppoe_real(const u_char *pdata, const uint32_t len,
- pktsummary *sm)
-{
- if (len < PPPOE_HDR_LEN) {
- verbosef("pppoe: packet too short (%u bytes)", len);
- return;
- }
-
- if (pdata[1] != 0x00) {
- verbosef("pppoe: code = 0x%02x, expecting 0; ignoring.", pdata[1]);
- return;
+static int decode_ppp(DECODER_ARGS) {
+ if (pheader->caplen < PPPOE_HDR_LEN) {
+ verbosef("ppp: packet too short (%u bytes)", pheader->caplen);
+ return 0;
}
+ if (pdata[2] == 0x00 && pdata[3] == 0x21)
+ return helper_ip(pdata + PPP_HDR_LEN,
+ pheader->caplen - PPP_HDR_LEN,
+ sm);
+ verbosef("ppp: non-IP PPP packet; ignoring.");
+ return 0;
+}
- if ((pdata[6] == 0xc0) && (pdata[7] == 0x21)) return; /* LCP */
- if ((pdata[6] == 0xc0) && (pdata[7] == 0x25)) return; /* LQR */
-
- if ((pdata[6] == 0x00) && (pdata[7] == 0x21)) {
- decode_ip(pdata + PPPOE_HDR_LEN, len - PPPOE_HDR_LEN, sm);
- acct_for(sm);
- } else
- verbosef("pppoe: non-IP PPPoE packet (0x%02x%02x); ignoring.",
- pdata[6], pdata[7]);
+static int decode_pppoe(DECODER_ARGS) {
+ return helper_pppoe(pdata, pheader->caplen, sm);
}
+#ifdef DLT_LINUX_SLL
/* very similar to decode_ether ... */
-static void
-decode_linux_sll(u_char *user _unused_,
- const struct pcap_pkthdr *pheader,
- const u_char *pdata)
-{
+static int decode_linux_sll(DECODER_ARGS) {
const struct sll_header {
uint16_t packet_type;
uint16_t device_type;
uint16_t ether_type;
} *hdr = (const struct sll_header *)pdata;
u_short type;
- pktsummary sm;
- memset(&sm, 0, sizeof(sm));
if (pheader->caplen < SLL_HDR_LEN) {
verbosef("linux_sll: packet too short (%u bytes)", pheader->caplen);
- return;
+ return 0;
}
-
- type = ntohs( hdr->ether_type );
+ type = ntohs(hdr->ether_type);
switch (type) {
case ETHERTYPE_IP:
case ETHERTYPE_IPV6:
- decode_ip(pdata + SLL_HDR_LEN, pheader->caplen - SLL_HDR_LEN, &sm);
- sm.time = pheader->ts.tv_sec;
- acct_for(&sm);
- break;
+ return helper_ip(pdata + SLL_HDR_LEN,
+ pheader->caplen - SLL_HDR_LEN,
+ sm);
case ETHERTYPE_ARP:
/* known protocol, don't complain about it. */
- break;
+ return 0;
default:
- verbosef("linux_sll: unknown protocol (%04x)", type);
+ verbosef("linux_sll: unknown protocol (0x%04x)", type);
+ return 0;
}
}
+#endif /* DLT_LINUX_SLL */
-static void
-decode_raw(u_char *user _unused_,
- const struct pcap_pkthdr *pheader,
- const u_char *pdata)
-{
- pktsummary sm;
- memset(&sm, 0, sizeof(sm));
-
- decode_ip(pdata, pheader->caplen, &sm);
- sm.time = pheader->ts.tv_sec;
- acct_for(&sm);
+static int decode_raw(DECODER_ARGS) {
+ return helper_ip(pdata, pheader->caplen, sm);
}
-static void
-decode_ip(const u_char *pdata, const uint32_t len, pktsummary *sm)
-{
- const struct ip *hdr = (const struct ip *)pdata;
+static int helper_pppoe(HELPER_ARGS) {
+ if (len < PPPOE_HDR_LEN) {
+ verbosef("pppoe: packet too short (%u bytes)", len);
+ return 0;
+ }
- if (hdr->ip_v == 6) {
- /* Redirect parsing of IPv6 packets. */
- decode_ipv6(pdata, len, sm);
- return;
+ if (pdata[1] != 0x00) {
+ verbosef("pppoe: code = 0x%02x, expecting 0; ignoring.", pdata[1]);
+ return 0;
}
+
+ if ((pdata[6] == 0xc0) && (pdata[7] == 0x21)) return 0; /* LCP */
+ if ((pdata[6] == 0xc0) && (pdata[7] == 0x25)) return 0; /* LQR */
+
+ if ((pdata[6] == 0x00) && (pdata[7] == 0x21))
+ return helper_ip(pdata + PPPOE_HDR_LEN, len - PPPOE_HDR_LEN, sm);
+
+ verbosef("pppoe: ignoring non-IP PPPoE packet (0x%02x%02x)",
+ pdata[6], pdata[7]);
+ return 0;
+}
+
+static int helper_ip(HELPER_ARGS) {
+ const struct ip *hdr = (const struct ip *)pdata;
+
if (len < IP_HDR_LEN) {
verbosef("ip: packet too short (%u bytes)", len);
- return;
+ return 0;
+ }
+ if (hdr->ip_v == 6) {
+ return helper_ipv6(pdata, len, sm);
}
if (hdr->ip_v != 4) {
verbosef("ip: version %d (expecting 4 or 6)", hdr->ip_v);
- return;
+ return 0;
}
sm->len = ntohs(hdr->ip_len);
- sm->af = AF_INET;
sm->proto = hdr->ip_p;
- sm->src_ip = hdr->ip_src.s_addr;
- sm->dest_ip = hdr->ip_dst.s_addr;
- switch (sm->proto) {
- case IPPROTO_TCP: {
- const struct tcphdr *thdr =
- (const struct tcphdr *)(pdata + IP_HDR_LEN);
- if (len < IP_HDR_LEN + TCP_HDR_LEN) {
- verbosef("tcp: packet too short (%u bytes)", len);
- return;
- }
- sm->src_port = ntohs(thdr->th_sport);
- sm->dest_port = ntohs(thdr->th_dport);
- sm->tcp_flags = thdr->th_flags &
- (TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG);
- break;
- }
+ sm->src.family = IPv4;
+ sm->src.ip.v4 = hdr->ip_src.s_addr;
- case IPPROTO_UDP: {
- const struct udphdr *uhdr =
- (const struct udphdr *)(pdata + IP_HDR_LEN);
- if (len < IP_HDR_LEN + UDP_HDR_LEN) {
- verbosef("udp: packet too short (%u bytes)", len);
- return;
- }
- sm->src_port = ntohs(uhdr->uh_sport);
- sm->dest_port = ntohs(uhdr->uh_dport);
- break;
- }
-
- case IPPROTO_ICMP:
- /* known protocol, don't complain about it */
- break;
+ sm->dst.family = IPv4;
+ sm->dst.ip.v4 = hdr->ip_dst.s_addr;
- default:
- verbosef("ip: unknown protocol %d", sm->proto);
- }
+ helper_ip_deeper(pdata + IP_HDR_LEN, len - IP_HDR_LEN, sm);
+ return 1;
}
-static void
-decode_ipv6(const u_char *pdata, const uint32_t len, pktsummary *sm)
-{
+static int helper_ipv6(HELPER_ARGS) {
const struct ip6_hdr *hdr = (const struct ip6_hdr *)pdata;
if (len < IPV6_HDR_LEN) {
verbosef("ipv6: packet too short (%u bytes)", len);
- return;
+ return 0;
+ }
+ if ((hdr->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) {
+ verbosef("ipv6: bad version (%02x, expecting %02x)",
+ hdr->ip6_vfc & IPV6_VERSION_MASK, IPV6_VERSION);
+ return 0;
}
+ /* IPv4 has "total length," but IPv6 has "payload length" which doesn't
+ * count the header bytes.
+ */
sm->len = ntohs(hdr->ip6_plen) + IPV6_HDR_LEN;
- sm->af = AF_INET6;
sm->proto = hdr->ip6_nxt;
- memcpy(&sm->src_ip6, &hdr->ip6_src, sizeof(sm->src_ip6));
- memcpy(&sm->dest_ip6, &hdr->ip6_dst, sizeof(sm->dest_ip6));
+ sm->src.family = IPv6;
+ memcpy(&sm->src.ip.v6, &hdr->ip6_src, sizeof(sm->src.ip.v6));
+ sm->dst.family = IPv6;
+ memcpy(&sm->dst.ip.v6, &hdr->ip6_dst, sizeof(sm->dst.ip.v6));
+ /* Don't do proto accounting if this packet uses extension headers. */
+ switch (sm->proto) {
+ case 0: /* Hop-by-Hop Options */
+ case IPPROTO_NONE:
+ case IPPROTO_DSTOPTS:
+ case IPPROTO_ROUTING:
+ case IPPROTO_FRAGMENT:
+ case IPPROTO_AH:
+ case IPPROTO_ESP:
+ case 135: /* Mobility */
+ sm->proto = IPPROTO_INVALID;
+ return 1; /* but we have addresses, so host accounting is ok */
+
+ default:
+ helper_ip_deeper(pdata + IPV6_HDR_LEN, len - IPV6_HDR_LEN, sm);
+ return 1;
+ }
+}
+
+static void helper_ip_deeper(HELPER_ARGS) {
+ /* At this stage we have IP addresses so we can do host accounting.
+ * If proto decode fails, we set IPPROTO_INVALID to skip proto accounting.
+ * We don't need to "return 0" like other helpers.
+ */
switch (sm->proto) {
case IPPROTO_TCP: {
- const struct tcphdr *thdr =
- (const struct tcphdr *)(pdata + IPV6_HDR_LEN);
- if (len < IPV6_HDR_LEN + TCP_HDR_LEN) {
- verbosef("tcp6: packet too short (%u bytes)", len);
+ const struct tcphdr *thdr = (const struct tcphdr *)pdata;
+ if (len < TCP_HDR_LEN) {
+ verbosef("tcp: packet too short (%u bytes)", len);
+ sm->proto = IPPROTO_INVALID; /* don't do accounting! */
return;
}
sm->src_port = ntohs(thdr->th_sport);
- sm->dest_port = ntohs(thdr->th_dport);
+ sm->dst_port = ntohs(thdr->th_dport);
sm->tcp_flags = thdr->th_flags &
(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG);
- break;
+ return;
}
case IPPROTO_UDP: {
- const struct udphdr *uhdr =
- (const struct udphdr *)(pdata + IPV6_HDR_LEN);
- if (len < IPV6_HDR_LEN + UDP_HDR_LEN) {
- verbosef("udp6: packet too short (%u bytes)", len);
+ const struct udphdr *uhdr = (const struct udphdr *)pdata;
+ if (len < UDP_HDR_LEN) {
+ verbosef("udp: packet too short (%u bytes)", len);
+ sm->proto = IPPROTO_INVALID; /* don't do accounting! */
return;
}
sm->src_port = ntohs(uhdr->uh_sport);
- sm->dest_port = ntohs(uhdr->uh_dport);
- break;
+ sm->dst_port = ntohs(uhdr->uh_dport);
+ return;
}
+ case IPPROTO_ICMP:
+ case IPPROTO_IGMP:
case IPPROTO_ICMPV6:
+ case IPPROTO_OSPF:
/* known protocol, don't complain about it */
+ sm->proto = IPPROTO_INVALID; /* also don't do accounting */
break;
default:
- verbosef("ipv6: unknown protocol %d", sm->proto);
+ verbosef("ip_deeper: unknown protocol 0x%02x", sm->proto);
}
}