+ if (print_ipproto(le, nexthdr, payload_len, h->protocol) < 0) {
+ LEPRINTF("PROTO=%u ", h->protocol);
+ }
+
+ return 0;
+}
+
+static int
+print_routing(struct log_entry *le, struct ip6_rthdr *rthdr, int payload_len)
+{
+ char tmp[INET6_ADDRSTRLEN];
+ LEPRINTF("TYPE=%u SEGMENTS=%u", rthdr->ip6r_type, rthdr->ip6r_segleft);
+
+ if (payload_len < sizeof(*rthdr) || payload_len < rthdr->ip6r_len*8) {
+ LEPRINTF("LEN=%d ", payload_len);
+ LEPRINTF("INVALID=LEN ");
+ return -1;
+ }
+
+ if (rthdr->ip6r_type == 0) {
+ /* Route via waypoints (deprecated), this contains a list of waypoints
+ * to visit. (RFC2460 (4.4))
+ */
+ struct ip6_rthdr0 *h = (struct ip6_rthdr0*)rthdr;
+ if (rthdr->ip6r_len*8 < sizeof(*h) + rthdr->ip6r_segleft * sizeof(struct in6_addr)) {
+ LEPRINTF("INVALID=SEGMENTS ");
+ return 0;
+ }
+ return 0;
+ } else if (rthdr->ip6r_type == 1) {
+ /* nimrod routing (RFC1992) */
+ return 0;
+ } else if (rthdr->ip6r_type == 2) {
+ /* RFC3375 (6.4), the layout is like type-0 but with exactly 1 address */
+ struct ip6_rthdr0 *h = (struct ip6_rthdr0*)rthdr;
+ if (rthdr->ip6r_len*8 < sizeof(*h) + sizeof(struct in6_addr)) {
+ LEPRINTF("LEN=%d ", payload_len);
+ LEPRINTF("INVALID=LEN ");
+ return -1;
+ }
+ inet_ntop(AF_INET6, &h->ip6r0_addr[0], tmp, sizeof(tmp));
+ LEPRINTF("HOME=%s ", tmp);
+ return 0;
+ }
+
+ return 0;
+}
+
+static int
+print_fragment(struct log_entry *le, struct ip6_frag *frag, int payload_len)
+{
+ u_int16_t offlg;
+
+ if (payload_len < sizeof(*frag)) {
+ LEPRINTF("LEN=%d ", payload_len);
+ LEPRINTF("INVALID=LEN ");
+ return -1;
+ }
+
+ offlg = ntohs(frag->ip6f_offlg);
+ LEPRINTF("FRAG=%d ID=%d ", (offlg&0x2FFF), ntohl(frag->ip6f_ident));
+ if (offlg>>15) {
+ LEPRINTF("MF ");
+ }
+ return 0;
+}
+
+static int
+print_icmp6(struct log_entry *le, struct icmp6_hdr *h, int payload_len)
+{
+ struct nd_router_advert *ra;
+ struct nd_neighbor_advert *na;
+ struct nd_redirect *re;
+ char tmp[INET6_ADDRSTRLEN];
+
+ if (payload_len < sizeof(struct icmp6_hdr)) {
+ LEPRINTF("LEN=%d ", payload_len);
+ LEPRINTF("INVALID=LEN ");
+ return -1;
+ }
+
+ LEPRINTF("TYPE=%u CODE=%u ", h->icmp6_type, h->icmp6_code);
+
+ switch (h->icmp6_type) {
+ case ICMP6_ECHO_REQUEST:
+ case ICMP6_ECHO_REPLY:
+ LEPRINTF("ID=%u SEQ=%u ", ntohs(h->icmp6_id), ntohs(h->icmp6_seq));