*** empty log message ***
authorMatthew Mondor <mmondor@pulsar-zone.net>
Wed, 9 Jan 2008 03:53:54 +0000 (03:53 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Wed, 9 Jan 2008 03:53:54 +0000 (03:53 +0000)
mmsoftware/tap-bridge/modules/tap-logger.c
mmsoftware/tap-bridge/tap-bridge.c
mmsoftware/tap-bridge/tap-headers.h

index 0399bcb..9ab8109 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tap-logger.c,v 1.10 2007/12/26 17:32:09 mmondor Exp $ */
+/* $Id: tap-logger.c,v 1.11 2008/01/09 03:53:54 mmondor Exp $ */
 
 /*
  * Copyright (C) 2007, Matthew Mondor
@@ -50,7 +50,14 @@ static void          mod_exit(void);
 
 static void            logprintf(const char *, ...);
 static void            logdata(const void *, size_t, int);
-static void            frame_log(frame_t *, int);
+static void            log_frame(frame_t *, int);
+static ssize_t         log_arp(frame_t *, size_t);
+static ssize_t         log_ip(frame_t *, size_t, int *);
+static ssize_t         log_icmp(frame_t *, size_t);
+static ssize_t         log_tcp(frame_t *, size_t);
+static ssize_t         log_udp(frame_t *, size_t);
+static ssize_t         log_ip6(frame_t *, size_t, int *);
+static ssize_t         log_icmp6(frame_t *, size_t);
 
 
 module_t module = {
@@ -82,7 +89,7 @@ mod_init(tap_t *tap_i, tap_t *tap_e)
                        warning(errno, "fopen(/tmp/tap-filter.log)");
                        return false;
                }
-               (void) setvbuf(logfh, NULL, _IOLBF, 0);
+               (void) setvbuf(logfh, NULL, _IOFBF, 0);
 
                *udata = logfh;
        } else
@@ -95,7 +102,7 @@ static bool
 mod_recv_int(tap_t *tap, fnode_t *n)
 {
 
-       frame_log(n->frame, '<');
+       log_frame(n->frame, '<');
        fnode_destroy(n);
        return true;
 }
@@ -104,7 +111,7 @@ static bool
 mod_recv_ext(tap_t *tap, fnode_t *n)
 {
 
-       frame_log(n->frame, '>');
+       log_frame(n->frame, '>');
        fnode_destroy(n);
        return true;
 }
@@ -162,15 +169,16 @@ logdata(const void *data, size_t len, int margin)
 }
 
 static void
-frame_log(frame_t *f, int d)
+log_frame(frame_t *f, int d)
 {
        char            origin[32], destination[32];
-       struct hdr_tap  *hdrtap = (struct hdr_tap *)f->data;
-       void            *ahdrtap = &hdrtap[1];
+       size_t          offset = 0;
+       int             protocol = 0;
 
        if (f->size < sizeof(struct hdr_tap)) {
                logprintf("%c Short ethernet frame: size=%u\n", d, f->size);
-               return;
+               offset = -1;
+               goto log;
        }
 
        (void) macaddr_string(origin, 31, &f->origin);
@@ -178,229 +186,353 @@ frame_log(frame_t *f, int d)
        logprintf("%c src=%s dst=%s etype=0x%04x size=%u\n",
            d, origin, destination, f->type, f->size);
 
-       /*
-        * Orignally used switch/case but if proves to be cleaner because of
-        * required variables, while requireing less indentation levels.
-        */
-       if (f->type == HDR_TAP_ETYPE_ARP) {
-               struct hdr_arp *hdrarp;
-               uint16_t        htype, ptype;
-
-               if (f->size < sizeof(struct hdr_tap) +
-                   sizeof(struct hdr_arp)) {
-                       logprintf("  Short ARP header\n");
-                       return;
+       switch (f->type) {
+       case HDR_TAP_ETYPE_ARP:
+               offset = log_arp(f, sizeof(struct hdr_tap));
+               break;
+       case HDR_TAP_ETYPE_IP:
+               if ((offset = log_ip(f, sizeof(struct hdr_tap), &protocol))
+                   == -1)
+                       break;
+               switch (protocol) {
+               case HDR_IP_PROTO_ICMP:
+                       offset = log_icmp(f, offset);
+                       break;
+               case HDR_IP_PROTO_TCP:
+                       offset = log_tcp(f, offset);
+                       break;
+               case HDR_IP_PROTO_UDP:
+                       offset = log_udp(f, offset);
+                       break;
+               default:
+                       logprintf("  Unsupported IP protocol (%u)\n",
+                           protocol);
+                       break;
                }
-               hdrarp = ahdrtap;
-
-               htype = BYTEORDER_HOST16(hdrarp->htype);
-               ptype = BYTEORDER_HOST16(hdrarp->ptype);
-
-               logprintf("  ARP: htype=0x%04x ptype=0x%04x hlen=%u plen=%u "
-                   "oper=%d\n",
-                   htype, ptype, hdrarp->hlen, hdrarp->plen,
-                   BYTEORDER_HOST16(hdrarp->oper));
-               if (htype == HDR_ARP_HTYPE_ETHERNET &&
-                   ptype == HDR_ARP_PTYPE_IPV4 &&
-                   hdrarp->hlen == 6 && hdrarp->plen == 4) {
-                       struct hdr_arp_p4h      *hdr;
-
-                       if (f->size < sizeof(struct hdr_tap) +
-                           sizeof(struct hdr_arp_p4h)) {
-                               logprintf("       Short header\n");
-                               return;
-                       }
-
-                       hdr = ahdrtap;
-                       logprintf("       sha=%02x:%02x:%02x:%02x:%02x:%02x "
-                           "spa=0x%08x\n       "
-                           "tha=%02x:%02x:%02x:%02x:%02x:%02x tpa=0x%08x\n",
-                           hdr->sha[0], hdr->sha[1], hdr->sha[2],
-                           hdr->sha[3], hdr->sha[4], hdr->sha[5],
-                           BYTEORDER_HOST32(hdr->spa),
-                           hdr->tha[0], hdr->tha[1], hdr->tha[2],
-                           hdr->tha[3], hdr->tha[4], hdr->tha[5],
-                           BYTEORDER_HOST32(hdr->tpa));
-               } else
-                       logprintf("       Unsupported ARP packet type\n");
-
-               /* Extra payload, if any */
-               if (f->size > sizeof(struct hdr_tap) +
-                   sizeof(struct hdr_arp_p4h)) {
-                       logprintf("       EXTRA PAYLOAD:\n");
-                       logdata(f->data + sizeof(struct hdr_tap) +
-                           sizeof(struct hdr_arp_p4h), f->size -
-                           sizeof(struct hdr_tap) -
-                           sizeof(struct hdr_arp_p4h), 8);
+               break;
+       case HDR_TAP_ETYPE_IPV6:
+               if ((offset = log_ip6(f, sizeof(struct hdr_tap), &protocol))
+                   == -1)
+                       break;
+               switch (protocol) {
+               case HDR_IP6_NEXTHDR_ICMP:
+                       offset = log_icmp6(f, offset);
+                       break;
+               case HDR_IP_PROTO_TCP:
+                       offset = log_tcp(f, offset);
+                       break;
+               case HDR_IP_PROTO_UDP:
+                       offset = log_udp(f, offset);
+                       break;
+               default:
+                       logprintf("  Unsupported IP6 protocol (%u)\n",
+                           protocol);
+                       break;
                }
-               return;
+               break;
+       default:
+               logprintf("  Unsupported ethertype (0x%04x)\n", f->type);
+               offset = sizeof(struct hdr_tap);
+               break;
        }
 
-       if (f->type == HDR_TAP_ETYPE_IP) {
-               struct hdr_ip   *hdrip;
-               uint16_t        t16;
-               int             ver, hlen, flags, off;
-               void            *ahdrip;
+log:
+       /* Dump remaining of frame if needed */
+       if (offset == -1) {
+               logprintf("        Full frame dump:\n");
+               logdata(f->data, f->size, 9);
+       } else if (offset != 0) {
+               logprintf("        Partial frame dump (offset %d)\n", offset);
+               logdata(&f->data[offset], f->size - offset, 9);
+       }
 
-               if (f->size < sizeof(struct hdr_tap) + sizeof(struct hdr_ip)) {
-                       logprintf("  Short IP header\n");
-                       return;
-               }
-               hdrip = ahdrtap;
+       (void) fflush(logfh);
+}
 
-               ver = HDR_IP_VER_GET(hdrip->ver_hlen);
-               hlen = HDR_IP_HLEN_GET(hdrip->ver_hlen);
-               if (hlen < 5) {
-                       logprintf("  Short IP header length (%d)\n", hlen);
-                       return;
-               }
-               ahdrip = &((uint32_t *)hdrip)[hlen];
-
-               t16 = BYTEORDER_HOST16(hdrip->flags_off);
-               flags = HDR_IP_FLAGS_GET(t16);
-               off = HDR_IP_OFF_GET(t16);
-
-               logprintf("  IP: ver=%d hlen=%d tos=%u len=%u id=0x%04x "
-                   "flags=0x%01x off=%d ttl=%u proto=%u\n      "
-                   "hsum=0x%04x srcaddr=0x%08x dstaddr=0x%08x\n",
-                   ver, hlen, hdrip->tos, BYTEORDER_HOST16(hdrip->len),
-                   BYTEORDER_HOST16(hdrip->id), flags, off, hdrip->ttl,
-                   hdrip->protocol, BYTEORDER_HOST16(hdrip->hsum),
-                   BYTEORDER_HOST32(hdrip->srcaddr),
-                   BYTEORDER_HOST32(hdrip->dstaddr));
-               if (hlen > 5) {
-                       uint32_t        *optword;
-
-                       /* XXX IP options */
-                       logprintf("      IP Options:\n");
-                       for (optword = &((uint32_t *)hdrip)[5];
-                           optword < (uint32_t *)ahdrip; optword++)
-                               logprintf("       0x%08x\n",
-                                   BYTEORDER_HOST32(*optword));
-               }
+/*
+ * These functions are provided a byte offset in the frame, specifying the
+ * position where the structure should be found.  They return back an offset
+ * in the frame from which point generic data logging should be done for
+ * debugging.  However, a return offset of 0 means that nothing more needs
+ * to be logged.  The special value of -1 indicates that the whole frame
+ * should be dumped.  This allows functions to return an offset which may
+ * be useful rather than only for dumping in some circumstances (i.e. IP
+ * header logging function will return the offset of the other protocol
+ * header but -1 on error).
+ */
 
-               if (hdrip->protocol == HDR_IP_PROTO_ICMP) {
-                       struct hdr_icmp *hdricmp;
+static ssize_t
+log_arp(frame_t *f, size_t offset)
+{
+       struct hdr_arp  *hdrarp;
+       uint16_t        htype, ptype;
 
-                       if (f->size < (ahdrip - (void *)f->data) +
-                           sizeof(struct hdr_icmp)) {
-                               logprintf("  Short ICMP header\n");
-                               return;
-                       }
+       if (f->size - offset < sizeof(struct hdr_arp)) {
+               logprintf("  Short ARP header\n");
+               return offset;
+       }
+       hdrarp = (struct hdr_arp *)&f->data[offset];
 
-                       hdricmp = ahdrip;
-                       logprintf("  ICMP: type=%u code=%u hsum=0x%04x "
-                           "id=0x%04x seq=0x%04x\n",
-                           hdricmp->type, hdricmp->code,
-                           BYTEORDER_HOST16(hdricmp->hsum),
-                           BYTEORDER_HOST16(hdricmp->id),
-                           BYTEORDER_HOST16(hdricmp->seq));
-
-                       /* ICMP padding payload, if any */
-                       if (f->size > (uint8_t *)(ahdrip +
-                           sizeof(struct hdr_icmp)) - f->data) {
-                               logprintf("        ICMP Padding:\n");
-                               logdata(ahdrip + sizeof(struct hdr_icmp),
-                                   f->size - ((uint8_t *)(ahdrip +
-                                   sizeof(struct hdr_icmp)) - f->data), 9); 
-                       }
-                       return;
-               }
+       htype = BYTEORDER_HOST16(hdrarp->htype);
+       ptype = BYTEORDER_HOST16(hdrarp->ptype);
 
-               if (hdrip->protocol == HDR_IP_PROTO_TCP) {
-                       struct hdr_tcp          *hdrtcp;
-                       int                     doff, res, i;
-                       static const char       flagbits[] = "CEUAPRSF";
-                       char                    flags[9], *cptr;
-                       void                    *ahdrtcp;
-
-                       if (f->size < (ahdrip - (void *)f->data) +
-                           sizeof(struct hdr_tcp)) {
-                               logprintf("  Short TCP header\n");
-                               return;
-                       }
-                       hdrtcp = ahdrip;
-
-                       doff = HDR_TCP_DOFF_GET(hdrtcp->doff_res);
-                       res = HDR_TCP_RES_GET(hdrtcp->doff_res);
-                       if (doff < 5) {
-                               logprintf("  Short TCP header length (%d)\n",
-                                   doff);
-                               return;
-                       }
-                       ahdrtcp = &((uint32_t *)hdrtcp)[doff];
-
-                       for (i = 0, cptr = flags; i < 8; i++)
-                               *cptr++ = ((hdrtcp->flags & (1 << i)) != 0) ?
-                                   flagbits[i] : '-';
-                       *cptr = '\0';
-
-                       logprintf("  TCP: srcport=%u dstport=%u seq=0x%08x "
-                           "ack=0x%08x doff=%d res=0x%01x\n"
-                           "       flags=%s window=%u hsum=0x%04x "
-                           "urgptr=0x%04x\n",
-                           BYTEORDER_HOST16(hdrtcp->srcport),
-                           BYTEORDER_HOST16(hdrtcp->dstport),
-                           BYTEORDER_HOST32(hdrtcp->seq),
-                           BYTEORDER_HOST32(hdrtcp->ack),
-                           doff, res, flags,
-                           BYTEORDER_HOST16(hdrtcp->window),
-                           BYTEORDER_HOST16(hdrtcp->hsum),
-                           BYTEORDER_HOST16(hdrtcp->urgptr));
-
-                       if (doff > 5) {
-                               uint32_t        *optword;
-
-                               /* XXX TCP options */
-                               logprintf("       TCP Options:\n");
-                               for (optword = &((uint32_t *)hdrtcp)[5];
-                                   optword < (uint32_t *)ahdrtcp; optword++)
-                                       logprintf("        0x%08x\n",
-                                           BYTEORDER_HOST32(*optword));
-                       }
+       logprintf("  ARP: htype=0x%04x ptype=0x%04x hlen=%u plen=%u oper=%d\n",
+           htype, ptype, hdrarp->hlen, hdrarp->plen,
+           BYTEORDER_HOST16(hdrarp->oper));
 
-                       /* TCP payload */
-                       if (f->size > ((uint8_t *)ahdrtcp - f->data)) {
-                               logprintf("       TCP Payload:\n");
-                               logdata(ahdrtcp, f->size -
-                                   ((uint8_t *)ahdrtcp - f->data), 8);
-                       }
-                       return;
+       if (htype == HDR_ARP_HTYPE_ETHERNET && ptype == HDR_ARP_PTYPE_IPV4 &&
+           hdrarp->hlen == 6 && hdrarp->plen == 4) {
+               struct hdr_arp_p4h      *hdr;
+
+               if (f->size - offset < sizeof(struct hdr_arp_p4h)) {
+                       logprintf("       Short ARPp4h header\n");
+                       return offset;
                }
 
-               if (hdrip->protocol == HDR_IP_PROTO_UDP) {
-                       struct hdr_udp  *hdrudp;
-                       void            *ahdrudp;
+               hdr = (struct hdr_arp_p4h *)hdrarp;
+               logprintf("       sha=%02x:%02x:%02x:%02x:%02x:%02x "
+                   "spa=0x%08x\n       "
+                   "tha=%02x:%02x:%02x:%02x:%02x:%02x tpa=0x%08x\n",
+                   hdr->sha[0], hdr->sha[1], hdr->sha[2],
+                   hdr->sha[3], hdr->sha[4], hdr->sha[5],
+                   BYTEORDER_HOST32(hdr->spa),
+                   hdr->tha[0], hdr->tha[1], hdr->tha[2],
+                   hdr->tha[3], hdr->tha[4], hdr->tha[5],
+                   BYTEORDER_HOST32(hdr->tpa));
+       } else {
+               logprintf("       Unsupported ARP packet type\n");
+               return offset;
+       }
 
-                       if (f->size < (ahdrip - (void *)f->data) +
-                           sizeof(struct hdr_udp)) {
-                               logprintf("  Short UDP header\n");
-                               return;
-                       }
+       if (f->size > offset + sizeof(struct hdr_arp_p4h)) {
+               logprintf("       EXTRA PAYLOAD:\n");
+               return (offset + sizeof(struct hdr_arp_p4h));
+       }
 
-                       hdrudp = ahdrip;
-                       logprintf("  UDP: srcport=%u dstport=%u len=%u "
-                           "hsum=0x%04x\n",
-                           BYTEORDER_HOST16(hdrudp->srcport),
-                           BYTEORDER_HOST16(hdrudp->dstport),
-                           BYTEORDER_HOST16(hdrudp->len),
-                           BYTEORDER_HOST16(hdrudp->hsum));
-
-                       ahdrudp = hdrudp + sizeof(struct hdr_udp);
-
-                       /* UDP payload */
-                       if (f->size > ((uint8_t *)ahdrudp - f->data)) {
-                               logprintf("       UDP Payload:\n");
-                               logdata(ahdrudp, f->size -
-                                   ((uint8_t *)ahdrudp - f->data), 8);
-                       }
-                       return;
-               }
+       return 0;
+}
+
+static ssize_t
+log_ip(frame_t *f, size_t offset, int *protocol)
+{
+       struct hdr_ip   *hdrip;
+       uint16_t        t;
+       int             ver, hlen, flags, off;
+       void            *ahdrip;
+
+       if (f->size - offset < sizeof(struct hdr_ip)) {
+               logprintf("  Short IP header\n");
+               return -1;
+       }
+       hdrip = (struct hdr_ip *)&f->data[offset];
+
+       ver = HDR_IP_VER_GET(hdrip->ver_hlen);
+       hlen = HDR_IP_HLEN_GET(hdrip->ver_hlen);
+       if (hlen < 5) {
+               logprintf("  Short IP header length (%d)\n", hlen);
+               return -1;
+       }
+       ahdrip = &((uint32_t *)hdrip)[hlen];
+
+       t = BYTEORDER_HOST16(hdrip->flags_off);
+       flags = HDR_IP_FLAGS_GET(t);
+       off = HDR_IP_OFF_GET(t);
+
+       logprintf("  IP: ver=%d hlen=%d tos=%u len=%u id=0x%04x "
+           "flags=0x%01x off=%d ttl=%u proto=%u\n      "
+           "hsum=0x%04x srcaddr=0x%08x dstaddr=0x%08x\n",
+           ver, hlen, hdrip->tos, BYTEORDER_HOST16(hdrip->len),
+           BYTEORDER_HOST16(hdrip->id), flags, off, hdrip->ttl,
+           hdrip->protocol, BYTEORDER_HOST16(hdrip->hsum),
+           BYTEORDER_HOST32(hdrip->srcaddr),
+           BYTEORDER_HOST32(hdrip->dstaddr));
+       if (hlen > 5) {
+               uint32_t        *optword;
+
+               /* XXX IP options */
+               logprintf("      IP Options:\n");
+               for (optword = &((uint32_t *)hdrip)[5];
+                    optword < (uint32_t *)ahdrip; optword++)
+                       logprintf("       0x%08x\n",
+                           BYTEORDER_HOST32(*optword));
+       }
+
+       *protocol = hdrip->protocol;
+       return ((uint8_t *)ahdrip - f->data);
+}
+
+static ssize_t
+log_icmp(frame_t *f, size_t offset)
+{
+       struct hdr_icmp *hdricmp;
+
+       if (f->size - offset < sizeof(struct hdr_icmp)) {
+               logprintf("  Short ICMP header\n");
+               return offset;
+       }
+       hdricmp = (struct hdr_icmp *)&f->data[offset];
+
+       logprintf("  ICMP: type=%u code=%u hsum=0x%04x id=0x%04x seq=0x%04x\n",
+           hdricmp->type, hdricmp->code, BYTEORDER_HOST16(hdricmp->hsum),
+           BYTEORDER_HOST16(hdricmp->id), BYTEORDER_HOST16(hdricmp->seq));
+
+       if (f->size > offset + sizeof(struct hdr_icmp)) {
+               logprintf("        ICMP Padding:\n");
+               return (offset + sizeof(struct hdr_icmp));
+       }
+
+       return 0;
+}
+
+static ssize_t
+log_tcp(frame_t *f, size_t offset)
+{
+       struct hdr_tcp          *hdrtcp;
+       int                     doff, res, i;
+       static const char       flagbits[] = "CEUAPRSF";
+       char                    flags[9], *cptr;
+       void                    *ahdrtcp;
+
+       if (f->size - offset < sizeof(struct hdr_tcp)) {
+               logprintf("  Short TCP header\n");
+               return offset;
+       }
+       hdrtcp = (struct hdr_tcp *)&f->data[offset];
+
+       doff = HDR_TCP_DOFF_GET(hdrtcp->doff_res);
+       res = HDR_TCP_RES_GET(hdrtcp->doff_res);
+       if (doff < 5) {
+               logprintf("  Short TCP header length (%d)\n", doff);
+               return offset;
+       }
+       ahdrtcp = &((uint32_t *)hdrtcp)[doff];
+
+       for (i = 0, cptr = flags; i < 8; i++)
+               *cptr++ = ((hdrtcp->flags & (1 << i)) != 0) ? flagbits[i] :
+                   '-';
+       *cptr = '\0';
+
+       logprintf("  TCP: srcport=%u dstport=%u seq=0x%08x "
+           "ack=0x%08x doff=%d res=0x%01x\n"
+           "       flags=%s window=%u hsum=0x%04x "
+           "urgptr=0x%04x\n",
+           BYTEORDER_HOST16(hdrtcp->srcport),
+           BYTEORDER_HOST16(hdrtcp->dstport),
+           BYTEORDER_HOST32(hdrtcp->seq),
+           BYTEORDER_HOST32(hdrtcp->ack),
+           doff, res, flags,
+           BYTEORDER_HOST16(hdrtcp->window),
+           BYTEORDER_HOST16(hdrtcp->hsum),
+           BYTEORDER_HOST16(hdrtcp->urgptr));
+
+       if (doff > 5) {
+               uint32_t        *optword;
+
+               /* XXX TCP options */
+               logprintf("       TCP Options:\n");
+               for (optword = &((uint32_t *)hdrtcp)[5];
+                    optword < (uint32_t *)ahdrtcp; optword++)
+                       logprintf("        0x%08x\n",
+                           BYTEORDER_HOST32(*optword));
+       }
+
+       if (f->size > ((uint8_t *)ahdrtcp - f->data)) {
+               logprintf("       TCP Payload:\n");
+               return ((uint8_t *)ahdrtcp - f->data);
+       }
+
+       return 0;
+}
+
+static ssize_t
+log_udp(frame_t *f, size_t offset)
+{
+       struct hdr_udp  *hdrudp;
+
+       if (f->size - offset < sizeof(struct hdr_udp)) {
+               logprintf("  Short UDP header\n");
+               return offset;
+       }
+       hdrudp = (struct hdr_udp *)&f->data[offset];
+
+       logprintf("  UDP: srcport=%u dstport=%u len=%u hsum=0x%04x\n",
+           BYTEORDER_HOST16(hdrudp->srcport),
+           BYTEORDER_HOST16(hdrudp->dstport),
+           BYTEORDER_HOST16(hdrudp->len),
+           BYTEORDER_HOST16(hdrudp->hsum));
+
+       if (f->size > offset + sizeof(struct hdr_udp)) {
+               logprintf("       UDP Payload:\n");
+               return (offset + sizeof(struct hdr_udp));
+       }
+
+       return 0;
+}
+
+static ssize_t
+log_ip6(frame_t *f, size_t offset, int *protocol)
+{
+       struct hdr_ip6  *hdrip6;
+       int             ver, class;
+       uint32_t        flow, t;
+
+       if (f->size - offset < sizeof(struct hdr_ip6)) {
+               logprintf("  Short IPv6 header\n");
+               return -1;
+       }
+       hdrip6 = (struct hdr_ip6 *)&f->data[offset];
+
+       t = BYTEORDER_HOST32(hdrip6->ver_class_flow);
+       ver = HDR_IP6_VER_GET(t);
+       class = HDR_IP6_CLASS_GET(t);
+       flow = HDR_IP6_FLOW_GET(t);
+
+       logprintf("  IP6: ver=%d class=%d flow=0x%05x len=%u nexthdr=%u "
+           "hoplim=%u\n       "
+           "srcaddr=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n       "
+           "dstaddr=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
+           ver, class, flow, BYTEORDER_HOST16(hdrip6->len),
+           hdrip6->nexthdr, hdrip6->hoplim,
+           BYTEORDER_HOST16(hdrip6->srcaddr[0]),
+           BYTEORDER_HOST16(hdrip6->srcaddr[1]),
+           BYTEORDER_HOST16(hdrip6->srcaddr[2]),
+           BYTEORDER_HOST16(hdrip6->srcaddr[3]),
+           BYTEORDER_HOST16(hdrip6->srcaddr[4]),
+           BYTEORDER_HOST16(hdrip6->srcaddr[5]),
+           BYTEORDER_HOST16(hdrip6->srcaddr[6]),
+           BYTEORDER_HOST16(hdrip6->srcaddr[7]),
+           BYTEORDER_HOST16(hdrip6->dstaddr[0]),
+           BYTEORDER_HOST16(hdrip6->dstaddr[1]),
+           BYTEORDER_HOST16(hdrip6->dstaddr[2]),
+           BYTEORDER_HOST16(hdrip6->dstaddr[3]),
+           BYTEORDER_HOST16(hdrip6->dstaddr[4]),
+           BYTEORDER_HOST16(hdrip6->dstaddr[5]),
+           BYTEORDER_HOST16(hdrip6->dstaddr[6]),
+           BYTEORDER_HOST16(hdrip6->dstaddr[7]));
+
+       /* XXX May be an options header */
+       *protocol = hdrip6->nexthdr;
+       return 0;
+}
+
+static ssize_t
+log_icmp6(frame_t *f, size_t offset)
+{
+       struct hdr_icmp6        *hdricmp6;
+
+       if (f->size - offset < sizeof(struct hdr_icmp6)) {
+               logprintf("  Short ICMP6 header\n");
+               return -1;
+       }
+       hdricmp6 = (struct hdr_icmp6 *)&f->data[offset];
+
+       logprintf("  ICMP6: type=%d code=0x%02x hsum=0x%04x\n",
+           hdricmp6->type, hdricmp6->code, BYTEORDER_HOST16(hdricmp6->hsum));
 
-               logprintf("  Unsupported IP protocol (0x%02x)\n",
-                   hdrip->protocol);
-               return;
+       if (f->size > offset + sizeof(struct hdr_icmp6)) {
+               logprintf("   Body:\n");
+               return (offset + sizeof(struct hdr_icmp6));
        }
 
-       logprintf("  Unsupported ethertype (0x%04x)\n", f->type);
+       return 0;
 }
index 4a74301..e4cd532 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tap-bridge.c,v 1.4 2007/12/25 06:02:05 mmondor Exp $ */
+/* $Id: tap-bridge.c,v 1.5 2008/01/09 03:53:53 mmondor Exp $ */
 
 /*
  * Copyright (C) 2007, Matthew Mondor
@@ -493,8 +493,8 @@ parent_sighandler(int sig)
                /* FALLTHROUGH */
        case SIGHUP:
                if (child_pid != -1) {
-                       warning(0, "Parent forwarding signal %d to child",
-                           sig);
+                       warning(0, "Parent forwarding signal %s to child",
+                           sys_signame[sig]);
                        (void) kill(child_pid, sig);
                }
                break;
@@ -512,6 +512,10 @@ parent_sighandler(int sig)
                        break;
                }
                break;
+       default:
+               warning(0, "Parent received unexpected signal %s",
+                   sys_signame[sig]);
+               break;
        }
 }
 
@@ -765,7 +769,7 @@ child_sighandler(int sig)
        case SIGTERM:
                /* FALLTHROUGH */
        case SIGINT:
-               warning(0, "Child received SIGTERM; exiting");
+               warning(0, "Child received %s; exiting", sys_signame[sig]);
                child_exit = true;
                break;
        case SIGALRM:
@@ -786,11 +790,16 @@ child_sighandler(int sig)
                        schedule_now = true;
                break;
        case SIGHUP:
-               warning(0, "Child received SIGHUP; reloading modules");
+               warning(0, "Child received %s; reloading modules",
+                   sys_signame[sig]);
                /* Reload modules specified in configuration file */
                if (!modules_reload(module_dir, true))
                        warning(errno, "modules_reload");
                break;
+       default:
+               warning(0, "Child received unexpected signal %s",
+                   sys_signame[sig]);
+               break;
        }
 }
 
index 89aed3a..af41dd2 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: tap-headers.h,v 1.3 2007/12/24 17:31:32 mmondor Exp $ */
+/* $Id: tap-headers.h,v 1.4 2008/01/09 03:53:54 mmondor Exp $ */
 
 /*
  * Copyright (C) 2007, Matthew Mondor
@@ -65,6 +65,7 @@ struct hdr_tap {
 
 #define HDR_TAP_ETYPE_IP       0x0800
 #define HDR_TAP_ETYPE_ARP      0x0806
+#define HDR_TAP_ETYPE_IPV6     0x86dd
 
 
 /*
@@ -131,9 +132,9 @@ struct hdr_ip {
        /* Followed with options if any then by protocol-specific header */
 } __attribute__((__packed__));
 
-#define HDR_IP_PROTO_ICMP      0x01
-#define HDR_IP_PROTO_TCP       0x06
-#define HDR_IP_PROTO_UDP       0x11
+#define HDR_IP_PROTO_ICMP      1
+#define HDR_IP_PROTO_TCP       6
+#define HDR_IP_PROTO_UDP       17
 
 /* Options are 32-bit padded but have an 16-bit header */
 struct hdr_ip_opt {
@@ -190,4 +191,34 @@ struct hdr_icmp {
 } __attribute__((__packed__));
 
 
+/*
+ * IP6
+ */
+
+struct hdr_ip6 {
+ /*    uint32_t                ver:4, class:8, flow:20; */
+       uint32_t                ver_class_flow;
+#define HDR_IP6_VER_CLASS_FLOW_SET(ver, class, flow) \
+    (((ver) & 0xf) << 28 | ((class) & 0xff) << 20 | ((flow) & 0xfffff) & \
+    0xffffffff);
+#define HDR_IP6_VER_GET(v)     (((v) & 0xf0000000) >> 28)
+#define HDR_IP6_CLASS_GET(v)   (((v) & 0x0ff00000) >> 20)
+#define HDR_IP6_FLOW_GET(v)    ((v) & 0x000fffff)
+       uint16_t                len;
+       uint8_t                 nexthdr;
+       uint8_t                 hoplim;
+       uint16_t                srcaddr[8];
+       uint16_t                dstaddr[8];
+} __attribute__((__packed__));
+
+#define HDR_IP6_NEXTHDR_ICMP   58
+
+struct hdr_icmp6 {
+       uint8_t                 type;
+       uint8_t                 code;
+       uint16_t                hsum;
+       /* Message body follows */
+} __attribute__((__packed__));
+
+
 #endif