print-ip.c revision 98527
117680Spst/* 239300Sfenner * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 317680Spst * The Regents of the University of California. All rights reserved. 417680Spst * 517680Spst * Redistribution and use in source and binary forms, with or without 617680Spst * modification, are permitted provided that: (1) source code distributions 717680Spst * retain the above copyright notice and this paragraph in its entirety, (2) 817680Spst * distributions including binary code include the above copyright notice and 917680Spst * this paragraph in its entirety in the documentation or other materials 1017680Spst * provided with the distribution, and (3) all advertising materials mentioning 1117680Spst * features or use of this software display the following acknowledgement: 1217680Spst * ``This product includes software developed by the University of California, 1317680Spst * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1417680Spst * the University nor the names of its contributors may be used to endorse 1517680Spst * or promote products derived from this software without specific prior 1617680Spst * written permission. 1717680Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1817680Spst * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1917680Spst * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2056896Sfenner * 2156896Sfenner * $FreeBSD: head/contrib/tcpdump/print-ip.c 98527 2002-06-21 00:49:02Z fenner $ 2217680Spst */ 2317680Spst 2417680Spst#ifndef lint 2526183Sfennerstatic const char rcsid[] = 2698527Sfenner "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.100 2001/09/17 21:58:03 fenner Exp $ (LBL)"; 2717680Spst#endif 2817680Spst 2956896Sfenner#ifdef HAVE_CONFIG_H 3056896Sfenner#include "config.h" 3156896Sfenner#endif 3256896Sfenner 3317680Spst#include <sys/param.h> 3417680Spst#include <sys/time.h> 3517680Spst#include <sys/socket.h> 3617680Spst 3717680Spst#include <netinet/in.h> 3817680Spst 3917680Spst#include <stdio.h> 4017680Spst#include <stdlib.h> 4117680Spst#include <string.h> 4217680Spst#include <unistd.h> 4317680Spst 4417680Spst#include "addrtoname.h" 4517680Spst#include "interface.h" 4617680Spst#include "extract.h" /* must come after interface.h */ 4717680Spst 4875118Sfenner#include "ip.h" 4975118Sfenner 5017680Spst/* Compatibility */ 5117680Spst#ifndef IPPROTO_ND 5217680Spst#define IPPROTO_ND 77 5317680Spst#endif 5417680Spst 5517680Spst/* 5617680Spst * print the recorded route in an IP RR, LSRR or SSRR option. 5717680Spst */ 5817680Spststatic void 5917680Spstip_printroute(const char *type, register const u_char *cp, u_int length) 6017680Spst{ 6117680Spst register u_int ptr = cp[2] - 1; 6217680Spst register u_int len; 6317680Spst 6417680Spst printf(" %s{", type); 6517680Spst if ((length + 1) & 3) 6617680Spst printf(" [bad length %d]", length); 6717680Spst if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1) 6817680Spst printf(" [bad ptr %d]", cp[2]); 6917680Spst 7017680Spst type = ""; 7117680Spst for (len = 3; len < length; len += 4) { 7217680Spst if (ptr == len) 7317680Spst type = "#"; 7417680Spst printf("%s%s", type, ipaddr_string(&cp[len])); 7517680Spst type = " "; 7617680Spst } 7717680Spst printf("%s}", ptr == len? "#" : ""); 7817680Spst} 7917680Spst 8056896Sfennerstatic void 8156896Sfennerip_printts(register const u_char *cp, u_int length) 8256896Sfenner{ 8356896Sfenner register u_int ptr = cp[2] - 1; 8456896Sfenner register u_int len = 0; 8556896Sfenner int hoplen; 8656896Sfenner char *type; 8756896Sfenner 8856896Sfenner printf(" TS{"); 8956896Sfenner hoplen = ((cp[3]&0xF) != IPOPT_TS_TSONLY) ? 8 : 4; 9056896Sfenner if ((length - 4) & (hoplen-1)) 9156896Sfenner printf("[bad length %d]", length); 9256896Sfenner if (ptr < 4 || ((ptr - 4) & (hoplen-1)) || ptr > length + 1) 9356896Sfenner printf("[bad ptr %d]", cp[2]); 9456896Sfenner switch (cp[3]&0xF) { 9556896Sfenner case IPOPT_TS_TSONLY: 9656896Sfenner printf("TSONLY"); 9756896Sfenner break; 9856896Sfenner case IPOPT_TS_TSANDADDR: 9956896Sfenner printf("TS+ADDR"); 10056896Sfenner break; 10156896Sfenner /* 10256896Sfenner * prespecified should really be 3, but some ones might send 2 10356896Sfenner * instead, and the IPOPT_TS_PRESPEC constant can apparently 10456896Sfenner * have both values, so we have to hard-code it here. 10556896Sfenner */ 10656896Sfenner 10756896Sfenner case 2: 10856896Sfenner printf("PRESPEC2.0"); 10956896Sfenner break; 11056896Sfenner case 3: /* IPOPT_TS_PRESPEC */ 11156896Sfenner printf("PRESPEC"); 11256896Sfenner break; 11356896Sfenner default: 11456896Sfenner printf("[bad ts type %d]", cp[3]&0xF); 11556896Sfenner goto done; 11656896Sfenner } 11756896Sfenner 11856896Sfenner type = " "; 11956896Sfenner for (len = 4; len < length; len += hoplen) { 12056896Sfenner if (ptr == len) 12156896Sfenner type = " ^ "; 12256896Sfenner printf("%s%d@%s", type, EXTRACT_32BITS(&cp[len+hoplen-4]), 12356896Sfenner hoplen!=8 ? "" : ipaddr_string(&cp[len])); 12456896Sfenner type = " "; 12556896Sfenner } 12656896Sfenner 12756896Sfennerdone: 12856896Sfenner printf("%s", ptr == len ? " ^ " : ""); 12956896Sfenner 13056896Sfenner if (cp[3]>>4) 13156896Sfenner printf(" [%d hops not recorded]} ", cp[3]>>4); 13256896Sfenner else 13356896Sfenner printf("}"); 13456896Sfenner} 13556896Sfenner 13617680Spst/* 13717680Spst * print IP options. 13817680Spst */ 13917680Spststatic void 14017680Spstip_optprint(register const u_char *cp, u_int length) 14117680Spst{ 14217680Spst register u_int len; 14317680Spst 14417680Spst for (; length > 0; cp += len, length -= len) { 14517680Spst int tt = *cp; 14617680Spst 14775118Sfenner if (tt == IPOPT_NOP || tt == IPOPT_EOL) 14875118Sfenner len = 1; 14975118Sfenner else { 15075118Sfenner if (&cp[1] >= snapend) { 15175118Sfenner printf("[|ip]"); 15275118Sfenner return; 15375118Sfenner } 15475118Sfenner len = cp[1]; 15575118Sfenner } 15617680Spst if (len <= 0) { 15717680Spst printf("[|ip op len %d]", len); 15817680Spst return; 15917680Spst } 16017680Spst if (&cp[1] >= snapend || cp + len > snapend) { 16117680Spst printf("[|ip]"); 16217680Spst return; 16317680Spst } 16417680Spst switch (tt) { 16517680Spst 16617680Spst case IPOPT_EOL: 16717680Spst printf(" EOL"); 16817680Spst if (length > 1) 16917680Spst printf("-%d", length - 1); 17017680Spst return; 17117680Spst 17217680Spst case IPOPT_NOP: 17317680Spst printf(" NOP"); 17417680Spst break; 17517680Spst 17617680Spst case IPOPT_TS: 17756896Sfenner ip_printts(cp, len); 17817680Spst break; 17917680Spst 18056896Sfenner#ifndef IPOPT_SECURITY 18156896Sfenner#define IPOPT_SECURITY 130 18256896Sfenner#endif /* IPOPT_SECURITY */ 18317680Spst case IPOPT_SECURITY: 18417680Spst printf(" SECURITY{%d}", len); 18517680Spst break; 18617680Spst 18717680Spst case IPOPT_RR: 18817680Spst ip_printroute("RR", cp, len); 18917680Spst break; 19017680Spst 19117680Spst case IPOPT_SSRR: 19217680Spst ip_printroute("SSRR", cp, len); 19317680Spst break; 19417680Spst 19517680Spst case IPOPT_LSRR: 19617680Spst ip_printroute("LSRR", cp, len); 19717680Spst break; 19817680Spst 19956896Sfenner#ifndef IPOPT_RA 20056896Sfenner#define IPOPT_RA 148 /* router alert */ 20156896Sfenner#endif 20217691Spst case IPOPT_RA: 20356896Sfenner printf(" RA"); 20456896Sfenner if (len != 4) 20556896Sfenner printf("{%d}", len); 20656896Sfenner else if (cp[2] || cp[3]) 20756896Sfenner printf("%d.%d", cp[2], cp[3]); 20898527Sfenner break; 20917691Spst 21017680Spst default: 21117680Spst printf(" IPOPT-%d{%d}", cp[0], len); 21217680Spst break; 21317680Spst } 21417680Spst } 21517680Spst} 21617680Spst 21717680Spst/* 21817680Spst * compute an IP header checksum. 21917680Spst * don't modifiy the packet. 22017680Spst */ 22156896Sfenneru_short 22298527Sfennerin_cksum(const u_short *addr, register u_int len, int csum) 22317680Spst{ 22456896Sfenner int nleft = len; 22556896Sfenner const u_short *w = addr; 22656896Sfenner u_short answer; 22756896Sfenner int sum = csum; 22817680Spst 22956896Sfenner /* 23056896Sfenner * Our algorithm is simple, using a 32 bit accumulator (sum), 23156896Sfenner * we add sequential 16 bit words to it, and at the end, fold 23256896Sfenner * back all the carry bits from the top 16 bits into the lower 23356896Sfenner * 16 bits. 23456896Sfenner */ 23556896Sfenner while (nleft > 1) { 23656896Sfenner sum += *w++; 23756896Sfenner nleft -= 2; 23856896Sfenner } 23956896Sfenner if (nleft == 1) 24056896Sfenner sum += htons(*(u_char *)w<<8); 24156896Sfenner 24217680Spst /* 24356896Sfenner * add back carry outs from top 16 bits to low 16 bits 24417680Spst */ 24556896Sfenner sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */ 24656896Sfenner sum += (sum >> 16); /* add carry */ 24756896Sfenner answer = ~sum; /* truncate to 16 bits */ 24856896Sfenner return (answer); 24917680Spst} 25017680Spst 25117680Spst/* 25217680Spst * print an IP datagram. 25317680Spst */ 25417680Spstvoid 25517680Spstip_print(register const u_char *bp, register u_int length) 25617680Spst{ 25717680Spst register const struct ip *ip; 25856896Sfenner register u_int hlen, len, len0, off; 25917680Spst register const u_char *cp; 26056896Sfenner u_char nh; 26156896Sfenner int advance; 26217680Spst 26317680Spst ip = (const struct ip *)bp; 26417680Spst#ifdef LBL_ALIGN 26517680Spst /* 26617680Spst * If the IP header is not aligned, copy into abuf. 26717680Spst * This will never happen with BPF. It does happen raw packet 26817680Spst * dumps from -r. 26917680Spst */ 27017680Spst if ((long)ip & 3) { 27117680Spst static u_char *abuf = NULL; 27217680Spst static int didwarn = 0; 27317680Spst 27417680Spst if (abuf == NULL) { 27517680Spst abuf = (u_char *)malloc(snaplen); 27617680Spst if (abuf == NULL) 27717680Spst error("ip_print: malloc"); 27817680Spst } 27917680Spst memcpy((char *)abuf, (char *)ip, min(length, snaplen)); 28017680Spst snapend += abuf - (u_char *)ip; 28117680Spst packetp = abuf; 28217680Spst ip = (struct ip *)abuf; 28317680Spst /* We really want libpcap to give us aligned packets */ 28417680Spst if (!didwarn) { 28517680Spst warning("compensating for unaligned libpcap packets"); 28617680Spst ++didwarn; 28717680Spst } 28817680Spst } 28917680Spst#endif 29017680Spst if ((u_char *)(ip + 1) > snapend) { 29117680Spst printf("[|ip]"); 29217680Spst return; 29317680Spst } 29417680Spst if (length < sizeof (struct ip)) { 29517680Spst (void)printf("truncated-ip %d", length); 29617680Spst return; 29717680Spst } 29875118Sfenner hlen = IP_HL(ip) * 4; 29975118Sfenner if (hlen < sizeof (struct ip)) { 30075118Sfenner (void)printf("bad-hlen %d", hlen); 30175118Sfenner return; 30275118Sfenner } 30317680Spst 30417680Spst len = ntohs(ip->ip_len); 30517680Spst if (length < len) 30698527Sfenner (void)printf("truncated-ip - %d bytes missing! ", 30717680Spst len - length); 30817680Spst len -= hlen; 30956896Sfenner len0 = len; 31017680Spst 31117680Spst /* 31217680Spst * If this is fragment zero, hand it to the next higher 31317680Spst * level protocol. 31417680Spst */ 31517680Spst off = ntohs(ip->ip_off); 31617680Spst if ((off & 0x1fff) == 0) { 31717680Spst cp = (const u_char *)ip + hlen; 31856896Sfenner nh = ip->ip_p; 31917680Spst 32098527Sfenner#ifndef IPPROTO_SCTP 32198527Sfenner#define IPPROTO_SCTP 132 32298527Sfenner#endif 32398527Sfenner if (nh != IPPROTO_TCP && nh != IPPROTO_UDP && 32498527Sfenner nh != IPPROTO_SCTP) { 32556896Sfenner (void)printf("%s > %s: ", ipaddr_string(&ip->ip_src), 32656896Sfenner ipaddr_string(&ip->ip_dst)); 32756896Sfenner } 32856896Sfenneragain: 32956896Sfenner switch (nh) { 33056896Sfenner 33156896Sfenner#ifndef IPPROTO_AH 33256896Sfenner#define IPPROTO_AH 51 33356896Sfenner#endif 33456896Sfenner case IPPROTO_AH: 33556896Sfenner nh = *cp; 33656896Sfenner advance = ah_print(cp, (const u_char *)ip); 33756896Sfenner cp += advance; 33856896Sfenner len -= advance; 33956896Sfenner goto again; 34056896Sfenner 34156896Sfenner#ifndef IPPROTO_ESP 34256896Sfenner#define IPPROTO_ESP 50 34356896Sfenner#endif 34456896Sfenner case IPPROTO_ESP: 34556896Sfenner { 34698527Sfenner int enh, padlen; 34798527Sfenner advance = esp_print(cp, (const u_char *)ip, &enh, &padlen); 34856896Sfenner cp += advance; 34998527Sfenner len -= advance + padlen; 35056896Sfenner if (enh < 0) 35156896Sfenner break; 35256896Sfenner nh = enh & 0xff; 35356896Sfenner goto again; 35456896Sfenner } 35556896Sfenner 35656896Sfenner#ifndef IPPROTO_IPCOMP 35756896Sfenner#define IPPROTO_IPCOMP 108 35856896Sfenner#endif 35956896Sfenner case IPPROTO_IPCOMP: 36056896Sfenner { 36156896Sfenner int enh; 36256896Sfenner advance = ipcomp_print(cp, (const u_char *)ip, &enh); 36356896Sfenner cp += advance; 36456896Sfenner len -= advance; 36556896Sfenner if (enh < 0) 36656896Sfenner break; 36756896Sfenner nh = enh & 0xff; 36856896Sfenner goto again; 36956896Sfenner } 37056896Sfenner 37198527Sfenner case IPPROTO_SCTP: 37298527Sfenner sctp_print(cp, (const u_char *)ip, len); 37398527Sfenner break; 37498527Sfenner 37517680Spst case IPPROTO_TCP: 37675118Sfenner tcp_print(cp, len, (const u_char *)ip, (off &~ 0x6000)); 37717680Spst break; 37817680Spst 37917680Spst case IPPROTO_UDP: 38075118Sfenner udp_print(cp, len, (const u_char *)ip, (off &~ 0x6000)); 38117680Spst break; 38217680Spst 38317680Spst case IPPROTO_ICMP: 38456896Sfenner icmp_print(cp, len, (const u_char *)ip); 38517680Spst break; 38617680Spst 38717680Spst#ifndef IPPROTO_IGRP 38817680Spst#define IPPROTO_IGRP 9 38917680Spst#endif 39017680Spst case IPPROTO_IGRP: 39117680Spst igrp_print(cp, len, (const u_char *)ip); 39217680Spst break; 39317680Spst 39417680Spst case IPPROTO_ND: 39517680Spst (void)printf(" nd %d", len); 39617680Spst break; 39717680Spst 39817680Spst case IPPROTO_EGP: 39917680Spst egp_print(cp, len, (const u_char *)ip); 40017680Spst break; 40117680Spst 40217680Spst#ifndef IPPROTO_OSPF 40317680Spst#define IPPROTO_OSPF 89 40417680Spst#endif 40517680Spst case IPPROTO_OSPF: 40617680Spst ospf_print(cp, len, (const u_char *)ip); 40717680Spst break; 40817680Spst 40917680Spst#ifndef IPPROTO_IGMP 41017680Spst#define IPPROTO_IGMP 2 41117680Spst#endif 41217680Spst case IPPROTO_IGMP: 41398527Sfenner igmp_print(cp, len); 41417680Spst break; 41517680Spst 41639300Sfenner case 4: 41739300Sfenner /* DVMRP multicast tunnel (ip-in-ip encapsulation) */ 41817680Spst ip_print(cp, len); 41917680Spst if (! vflag) { 42098527Sfenner printf(" (ipip-proto-4)"); 42117680Spst return; 42217680Spst } 42317680Spst break; 42417680Spst 42556896Sfenner#ifdef INET6 42656896Sfenner#ifndef IP6PROTO_ENCAP 42756896Sfenner#define IP6PROTO_ENCAP 41 42856896Sfenner#endif 42956896Sfenner case IP6PROTO_ENCAP: 43056896Sfenner /* ip6-in-ip encapsulation */ 43156896Sfenner ip6_print(cp, len); 43256896Sfenner break; 43356896Sfenner#endif /*INET6*/ 43456896Sfenner 43556896Sfenner 43626183Sfenner#ifndef IPPROTO_GRE 43726183Sfenner#define IPPROTO_GRE 47 43826183Sfenner#endif 43926183Sfenner case IPPROTO_GRE: 44026183Sfenner /* do it */ 44126183Sfenner gre_print(cp, len); 44298527Sfenner break; 44326183Sfenner 44456896Sfenner#ifndef IPPROTO_MOBILE 44556896Sfenner#define IPPROTO_MOBILE 55 44656896Sfenner#endif 44756896Sfenner case IPPROTO_MOBILE: 44856896Sfenner mobile_print(cp, len); 44956896Sfenner break; 45056896Sfenner 45156896Sfenner#ifndef IPPROTO_PIM 45256896Sfenner#define IPPROTO_PIM 103 45356896Sfenner#endif 45456896Sfenner case IPPROTO_PIM: 45556896Sfenner pim_print(cp, len); 45656896Sfenner break; 45756896Sfenner 45875118Sfenner#ifndef IPPROTO_VRRP 45975118Sfenner#define IPPROTO_VRRP 112 46075118Sfenner#endif 46175118Sfenner case IPPROTO_VRRP: 46275118Sfenner vrrp_print(cp, len, ip->ip_ttl); 46375118Sfenner break; 46475118Sfenner 46517680Spst default: 46656896Sfenner (void)printf(" ip-proto-%d %d", nh, len); 46717680Spst break; 46817680Spst } 46917680Spst } 47056896Sfenner 47156896Sfenner /* Ultra quiet now means that all this stuff should be suppressed */ 47256896Sfenner /* res 3-Nov-98 */ 47356896Sfenner if (qflag > 1) return; 47456896Sfenner 47556896Sfenner 47617680Spst /* 47717680Spst * for fragmented datagrams, print id:size@offset. On all 47817680Spst * but the last stick a "+". For unfragmented datagrams, note 47917680Spst * the don't fragment flag. 48017680Spst */ 48156896Sfenner len = len0; /* get the original length */ 48217680Spst if (off & 0x3fff) { 48317680Spst /* 48417680Spst * if this isn't the first frag, we're missing the 48517680Spst * next level protocol header. print the ip addr. 48617680Spst */ 48717680Spst if (off & 0x1fff) 48817680Spst (void)printf("%s > %s:", ipaddr_string(&ip->ip_src), 48917680Spst ipaddr_string(&ip->ip_dst)); 49056896Sfenner#ifndef IP_MF 49156896Sfenner#define IP_MF 0x2000 49256896Sfenner#endif /* IP_MF */ 49356896Sfenner#ifndef IP_DF 49456896Sfenner#define IP_DF 0x4000 49556896Sfenner#endif /* IP_DF */ 49656896Sfenner (void)printf(" (frag %d:%u@%d%s)", ntohs(ip->ip_id), len, 49717680Spst (off & 0x1fff) * 8, 49817680Spst (off & IP_MF)? "+" : ""); 49956896Sfenner 50017680Spst } else if (off & IP_DF) 50117680Spst (void)printf(" (DF)"); 50217680Spst 50356896Sfenner if (ip->ip_tos) { 50456896Sfenner (void)printf(" [tos 0x%x", (int)ip->ip_tos); 50556896Sfenner /* ECN bits */ 50698527Sfenner if (ip->ip_tos & 0x03) { 50798527Sfenner switch (ip->ip_tos & 0x03) { 50898527Sfenner case 1: 50998527Sfenner (void)printf(",ECT(1)"); 51098527Sfenner break; 51198527Sfenner case 2: 51298527Sfenner (void)printf(",ECT(0)"); 51398527Sfenner break; 51498527Sfenner case 3: 51556896Sfenner (void)printf(",CE"); 51698527Sfenner } 51756896Sfenner } 51856896Sfenner (void)printf("] "); 51956896Sfenner } 52056896Sfenner 52117680Spst if (ip->ip_ttl <= 1) 52217680Spst (void)printf(" [ttl %d]", (int)ip->ip_ttl); 52317680Spst 52417680Spst if (vflag) { 52517680Spst int sum; 52617680Spst char *sep = ""; 52717680Spst 52817680Spst printf(" ("); 52917680Spst if (ip->ip_ttl > 1) { 53017680Spst (void)printf("%sttl %d", sep, (int)ip->ip_ttl); 53117680Spst sep = ", "; 53217680Spst } 53317680Spst if ((off & 0x3fff) == 0) { 53417680Spst (void)printf("%sid %d", sep, (int)ntohs(ip->ip_id)); 53517680Spst sep = ", "; 53617680Spst } 53775118Sfenner (void)printf("%slen %d", sep, (int)ntohs(ip->ip_len)); 53875118Sfenner sep = ", "; 53917680Spst if ((u_char *)ip + hlen <= snapend) { 54056896Sfenner sum = in_cksum((const u_short *)ip, hlen, 0); 54117680Spst if (sum != 0) { 54217680Spst (void)printf("%sbad cksum %x!", sep, 54317680Spst ntohs(ip->ip_sum)); 54417680Spst sep = ", "; 54517680Spst } 54617680Spst } 54717680Spst if ((hlen -= sizeof(struct ip)) > 0) { 54817680Spst (void)printf("%soptlen=%d", sep, hlen); 54917680Spst ip_optprint((u_char *)(ip + 1), hlen); 55017680Spst } 55117680Spst printf(")"); 55217680Spst } 55317680Spst} 55475118Sfenner 55575118Sfennervoid 55675118SfenneripN_print(register const u_char *bp, register u_int length) 55775118Sfenner{ 55875118Sfenner struct ip *ip, hdr; 55975118Sfenner 56075118Sfenner ip = (struct ip *)bp; 56175118Sfenner if (length < 4) { 56275118Sfenner (void)printf("truncated-ip %d", length); 56375118Sfenner return; 56475118Sfenner } 56575118Sfenner memcpy (&hdr, (char *)ip, 4); 56675118Sfenner switch (IP_V(&hdr)) { 56775118Sfenner case 4: 56898527Sfenner ip_print (bp, length); 56998527Sfenner return; 57075118Sfenner#ifdef INET6 57175118Sfenner case 6: 57298527Sfenner ip6_print (bp, length); 57398527Sfenner return; 57475118Sfenner#endif 57575118Sfenner default: 57698527Sfenner (void)printf("unknown ip %d", IP_V(&hdr)); 57798527Sfenner return; 57875118Sfenner } 57975118Sfenner} 580