summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Makefile497
-rwxr-xr-xbuilder.py7
-rwxr-xr-xfreebsd-to-rtems.py38
-rw-r--r--freebsd/contrib/libpcap/arcnet.h52
-rw-r--r--freebsd/contrib/libpcap/atmuni31.h87
-rw-r--r--freebsd/contrib/libpcap/bpf_image.c307
-rw-r--r--freebsd/contrib/libpcap/etherent.c176
-rw-r--r--freebsd/contrib/libpcap/ethertype.h122
-rw-r--r--freebsd/contrib/libpcap/fad-getad.c288
-rw-r--r--freebsd/contrib/libpcap/gencode.c8493
-rw-r--r--freebsd/contrib/libpcap/gencode.h343
-rw-r--r--freebsd/contrib/libpcap/grammar.c2280
-rw-r--r--freebsd/contrib/libpcap/grammar.y698
-rw-r--r--freebsd/contrib/libpcap/ieee80211.h146
-rw-r--r--freebsd/contrib/libpcap/inet.c935
-rw-r--r--freebsd/contrib/libpcap/llc.h69
-rw-r--r--freebsd/contrib/libpcap/nametoaddr.c525
-rw-r--r--freebsd/contrib/libpcap/nlpid.h58
-rw-r--r--freebsd/contrib/libpcap/optimize.c2249
-rw-r--r--freebsd/contrib/libpcap/pcap-bpf.c2719
-rw-r--r--freebsd/contrib/libpcap/pcap-common.c1174
-rw-r--r--freebsd/contrib/libpcap/pcap-common.h25
-rw-r--r--freebsd/contrib/libpcap/pcap-int.h513
-rw-r--r--freebsd/contrib/libpcap/pcap-namedb.h42
-rw-r--r--freebsd/contrib/libpcap/pcap.c1812
-rw-r--r--freebsd/contrib/libpcap/pcap.h45
-rw-r--r--freebsd/contrib/libpcap/pcap/ipnet.h43
-rw-r--r--freebsd/contrib/libpcap/pcap/namedb.h89
-rw-r--r--freebsd/contrib/libpcap/pcap/pcap.h461
-rw-r--r--freebsd/contrib/libpcap/pcap/sll.h129
-rw-r--r--freebsd/contrib/libpcap/pcap/usb.h143
-rw-r--r--freebsd/contrib/libpcap/ppp.h58
-rw-r--r--freebsd/contrib/libpcap/savefile.c396
-rw-r--r--freebsd/contrib/libpcap/scanner.c4890
-rw-r--r--freebsd/contrib/libpcap/scanner.l455
-rw-r--r--freebsd/contrib/libpcap/sf-pcap-ng.c1111
-rw-r--r--freebsd/contrib/libpcap/sf-pcap-ng.h31
-rw-r--r--freebsd/contrib/libpcap/sf-pcap.c620
-rw-r--r--freebsd/contrib/libpcap/sf-pcap.h36
-rw-r--r--freebsd/contrib/libpcap/sunatmpos.h45
-rw-r--r--freebsd/contrib/tcpdump/addrtoname.c1218
-rw-r--r--freebsd/contrib/tcpdump/addrtoname.h56
-rw-r--r--freebsd/contrib/tcpdump/af.c65
-rw-r--r--freebsd/contrib/tcpdump/af.h57
-rw-r--r--freebsd/contrib/tcpdump/ah.h57
-rw-r--r--freebsd/contrib/tcpdump/aodv.h190
-rw-r--r--freebsd/contrib/tcpdump/appletalk.h168
-rw-r--r--freebsd/contrib/tcpdump/arcnet.h101
-rw-r--r--freebsd/contrib/tcpdump/atm.h33
-rw-r--r--freebsd/contrib/tcpdump/bgp.h17
-rw-r--r--freebsd/contrib/tcpdump/bootp.h231
-rw-r--r--freebsd/contrib/tcpdump/bpf_dump.c68
-rw-r--r--freebsd/contrib/tcpdump/chdlc.h27
-rw-r--r--freebsd/contrib/tcpdump/checksum.c196
-rw-r--r--freebsd/contrib/tcpdump/cpack.c146
-rw-r--r--freebsd/contrib/tcpdump/cpack.h54
-rw-r--r--freebsd/contrib/tcpdump/dccp.h139
-rw-r--r--freebsd/contrib/tcpdump/decnet.h461
-rw-r--r--freebsd/contrib/tcpdump/decode_prefix.h41
-rw-r--r--freebsd/contrib/tcpdump/enc.h47
-rw-r--r--freebsd/contrib/tcpdump/esp.h68
-rw-r--r--freebsd/contrib/tcpdump/ether.h59
-rw-r--r--freebsd/contrib/tcpdump/ethertype.h188
-rw-r--r--freebsd/contrib/tcpdump/extract.h155
-rw-r--r--freebsd/contrib/tcpdump/fddi.h76
-rw-r--r--freebsd/contrib/tcpdump/forces.h679
-rw-r--r--freebsd/contrib/tcpdump/gmpls.c199
-rw-r--r--freebsd/contrib/tcpdump/gmpls.h34
-rw-r--r--freebsd/contrib/tcpdump/gmt2local.c73
-rw-r--r--freebsd/contrib/tcpdump/gmt2local.h27
-rw-r--r--freebsd/contrib/tcpdump/icmp6.h473
-rw-r--r--freebsd/contrib/tcpdump/ieee802_11.h347
-rw-r--r--freebsd/contrib/tcpdump/ieee802_11_radio.h291
-rw-r--r--freebsd/contrib/tcpdump/igrp.h33
-rw-r--r--freebsd/contrib/tcpdump/in_cksum.c202
-rw-r--r--freebsd/contrib/tcpdump/interface.h400
-rw-r--r--freebsd/contrib/tcpdump/ip.h164
-rw-r--r--freebsd/contrib/tcpdump/ip6.h192
-rw-r--r--freebsd/contrib/tcpdump/ipfc.h29
-rw-r--r--freebsd/contrib/tcpdump/ipnet.h13
-rw-r--r--freebsd/contrib/tcpdump/ipproto.c64
-rw-r--r--freebsd/contrib/tcpdump/ipproto.h148
-rw-r--r--freebsd/contrib/tcpdump/ipsec_doi.h151
-rw-r--r--freebsd/contrib/tcpdump/ipx.h31
-rw-r--r--freebsd/contrib/tcpdump/isakmp.h501
-rw-r--r--freebsd/contrib/tcpdump/l2tp.h62
-rw-r--r--freebsd/contrib/tcpdump/l2vpn.c60
-rw-r--r--freebsd/contrib/tcpdump/l2vpn.h17
-rw-r--r--freebsd/contrib/tcpdump/lane.h41
-rw-r--r--freebsd/contrib/tcpdump/llc.h123
-rw-r--r--freebsd/contrib/tcpdump/machdep.c69
-rw-r--r--freebsd/contrib/tcpdump/machdep.h27
-rw-r--r--freebsd/contrib/tcpdump/mib.h1460
-rw-r--r--freebsd/contrib/tcpdump/mpls.h41
-rw-r--r--freebsd/contrib/tcpdump/nameser.h315
-rw-r--r--freebsd/contrib/tcpdump/netbios.h16
-rw-r--r--freebsd/contrib/tcpdump/netdissect.h515
-rw-r--r--freebsd/contrib/tcpdump/nfs.h440
-rw-r--r--freebsd/contrib/tcpdump/nfsfh.h70
-rw-r--r--freebsd/contrib/tcpdump/nlpid.c48
-rw-r--r--freebsd/contrib/tcpdump/nlpid.h33
-rw-r--r--freebsd/contrib/tcpdump/ntp.h127
-rw-r--r--freebsd/contrib/tcpdump/oakley.h126
-rw-r--r--freebsd/contrib/tcpdump/ospf.h328
-rw-r--r--freebsd/contrib/tcpdump/ospf6.h265
-rw-r--r--freebsd/contrib/tcpdump/oui.c101
-rw-r--r--freebsd/contrib/tcpdump/oui.h82
-rw-r--r--freebsd/contrib/tcpdump/parsenfsfh.c488
-rw-r--r--freebsd/contrib/tcpdump/pcap-missing.h60
-rw-r--r--freebsd/contrib/tcpdump/pmap_prot.h90
-rw-r--r--freebsd/contrib/tcpdump/ppi.h9
-rw-r--r--freebsd/contrib/tcpdump/ppp.h73
-rw-r--r--freebsd/contrib/tcpdump/print-802_11.c2389
-rw-r--r--freebsd/contrib/tcpdump/print-802_15_4.c185
-rw-r--r--freebsd/contrib/tcpdump/print-ah.c73
-rw-r--r--freebsd/contrib/tcpdump/print-aodv.c457
-rw-r--r--freebsd/contrib/tcpdump/print-ap1394.c121
-rw-r--r--freebsd/contrib/tcpdump/print-arcnet.c300
-rw-r--r--freebsd/contrib/tcpdump/print-arp.c421
-rw-r--r--freebsd/contrib/tcpdump/print-ascii.c185
-rw-r--r--freebsd/contrib/tcpdump/print-atalk.c627
-rw-r--r--freebsd/contrib/tcpdump/print-atm.c455
-rw-r--r--freebsd/contrib/tcpdump/print-babel.c449
-rw-r--r--freebsd/contrib/tcpdump/print-beep.c73
-rw-r--r--freebsd/contrib/tcpdump/print-bfd.c285
-rw-r--r--freebsd/contrib/tcpdump/print-bgp.c2763
-rw-r--r--freebsd/contrib/tcpdump/print-bootp.c829
-rw-r--r--freebsd/contrib/tcpdump/print-bt.c81
-rw-r--r--freebsd/contrib/tcpdump/print-carp.c90
-rw-r--r--freebsd/contrib/tcpdump/print-cdp.c381
-rw-r--r--freebsd/contrib/tcpdump/print-cfm.c647
-rw-r--r--freebsd/contrib/tcpdump/print-chdlc.c217
-rw-r--r--freebsd/contrib/tcpdump/print-cip.c118
-rw-r--r--freebsd/contrib/tcpdump/print-cnfp.c192
-rw-r--r--freebsd/contrib/tcpdump/print-dccp.c466
-rw-r--r--freebsd/contrib/tcpdump/print-decnet.c897
-rw-r--r--freebsd/contrib/tcpdump/print-dhcp6.c871
-rw-r--r--freebsd/contrib/tcpdump/print-domain.c755
-rw-r--r--freebsd/contrib/tcpdump/print-dtp.c125
-rw-r--r--freebsd/contrib/tcpdump/print-dvmrp.c371
-rw-r--r--freebsd/contrib/tcpdump/print-eap.c309
-rw-r--r--freebsd/contrib/tcpdump/print-egp.c364
-rw-r--r--freebsd/contrib/tcpdump/print-eigrp.c482
-rw-r--r--freebsd/contrib/tcpdump/print-enc.c100
-rw-r--r--freebsd/contrib/tcpdump/print-esp.c696
-rw-r--r--freebsd/contrib/tcpdump/print-ether.c441
-rw-r--r--freebsd/contrib/tcpdump/print-fddi.c313
-rw-r--r--freebsd/contrib/tcpdump/print-forces.c1057
-rw-r--r--freebsd/contrib/tcpdump/print-fr.c887
-rw-r--r--freebsd/contrib/tcpdump/print-frag6.c84
-rw-r--r--freebsd/contrib/tcpdump/print-gre.c405
-rw-r--r--freebsd/contrib/tcpdump/print-hsrp.c142
-rw-r--r--freebsd/contrib/tcpdump/print-icmp.c699
-rw-r--r--freebsd/contrib/tcpdump/print-icmp6.c1388
-rw-r--r--freebsd/contrib/tcpdump/print-igmp.c346
-rw-r--r--freebsd/contrib/tcpdump/print-igrp.c132
-rw-r--r--freebsd/contrib/tcpdump/print-ip.c713
-rw-r--r--freebsd/contrib/tcpdump/print-ip6.c275
-rw-r--r--freebsd/contrib/tcpdump/print-ip6opts.c334
-rw-r--r--freebsd/contrib/tcpdump/print-ipcomp.c93
-rw-r--r--freebsd/contrib/tcpdump/print-ipfc.c137
-rw-r--r--freebsd/contrib/tcpdump/print-ipnet.c111
-rw-r--r--freebsd/contrib/tcpdump/print-ipx.c225
-rw-r--r--freebsd/contrib/tcpdump/print-isakmp.c2572
-rw-r--r--freebsd/contrib/tcpdump/print-isoclns.c3117
-rw-r--r--freebsd/contrib/tcpdump/print-juniper.c1458
-rw-r--r--freebsd/contrib/tcpdump/print-krb.c263
-rw-r--r--freebsd/contrib/tcpdump/print-l2tp.c721
-rw-r--r--freebsd/contrib/tcpdump/print-lane.c120
-rw-r--r--freebsd/contrib/tcpdump/print-ldp.c678
-rw-r--r--freebsd/contrib/tcpdump/print-llc.c549
-rw-r--r--freebsd/contrib/tcpdump/print-lldp.c1415
-rw-r--r--freebsd/contrib/tcpdump/print-lmp.c885
-rw-r--r--freebsd/contrib/tcpdump/print-lspping.c898
-rw-r--r--freebsd/contrib/tcpdump/print-lwapp.c361
-rw-r--r--freebsd/contrib/tcpdump/print-lwres.c603
-rw-r--r--freebsd/contrib/tcpdump/print-mobile.c114
-rw-r--r--freebsd/contrib/tcpdump/print-mobility.c314
-rw-r--r--freebsd/contrib/tcpdump/print-mpcp.c276
-rw-r--r--freebsd/contrib/tcpdump/print-mpls.c229
-rw-r--r--freebsd/contrib/tcpdump/print-msdp.c110
-rw-r--r--freebsd/contrib/tcpdump/print-msnlb.c68
-rw-r--r--freebsd/contrib/tcpdump/print-netbios.c93
-rw-r--r--freebsd/contrib/tcpdump/print-nfs.c1855
-rw-r--r--freebsd/contrib/tcpdump/print-ntp.c312
-rw-r--r--freebsd/contrib/tcpdump/print-null.c164
-rw-r--r--freebsd/contrib/tcpdump/print-olsr.c628
-rw-r--r--freebsd/contrib/tcpdump/print-ospf.c1159
-rw-r--r--freebsd/contrib/tcpdump/print-ospf6.c646
-rw-r--r--freebsd/contrib/tcpdump/print-otv.c81
-rw-r--r--freebsd/contrib/tcpdump/print-pflog.c190
-rw-r--r--freebsd/contrib/tcpdump/print-pfsync.c453
-rw-r--r--freebsd/contrib/tcpdump/print-pgm.c849
-rw-r--r--freebsd/contrib/tcpdump/print-pim.c1097
-rw-r--r--freebsd/contrib/tcpdump/print-ppi.c106
-rw-r--r--freebsd/contrib/tcpdump/print-ppp.c1761
-rw-r--r--freebsd/contrib/tcpdump/print-pppoe.c213
-rw-r--r--freebsd/contrib/tcpdump/print-pptp.c1062
-rw-r--r--freebsd/contrib/tcpdump/print-radius.c939
-rw-r--r--freebsd/contrib/tcpdump/print-raw.c55
-rw-r--r--freebsd/contrib/tcpdump/print-rip.c274
-rw-r--r--freebsd/contrib/tcpdump/print-ripng.c130
-rw-r--r--freebsd/contrib/tcpdump/print-rpki-rtr.c370
-rw-r--r--freebsd/contrib/tcpdump/print-rrcp.c145
-rw-r--r--freebsd/contrib/tcpdump/print-rsvp.c1946
-rw-r--r--freebsd/contrib/tcpdump/print-rt6.c107
-rw-r--r--freebsd/contrib/tcpdump/print-rx.c2800
-rw-r--r--freebsd/contrib/tcpdump/print-sctp.c409
-rw-r--r--freebsd/contrib/tcpdump/print-sflow.c936
-rw-r--r--freebsd/contrib/tcpdump/print-sip.c66
-rw-r--r--freebsd/contrib/tcpdump/print-sl.c243
-rw-r--r--freebsd/contrib/tcpdump/print-sll.c233
-rw-r--r--freebsd/contrib/tcpdump/print-slow.c663
-rw-r--r--freebsd/contrib/tcpdump/print-smb.c1512
-rw-r--r--freebsd/contrib/tcpdump/print-snmp.c1906
-rw-r--r--freebsd/contrib/tcpdump/print-stp.c460
-rw-r--r--freebsd/contrib/tcpdump/print-sunatm.c119
-rw-r--r--freebsd/contrib/tcpdump/print-sunrpc.c176
-rw-r--r--freebsd/contrib/tcpdump/print-symantec.c122
-rw-r--r--freebsd/contrib/tcpdump/print-syslog.c165
-rw-r--r--freebsd/contrib/tcpdump/print-tcp.c827
-rw-r--r--freebsd/contrib/tcpdump/print-telnet.c269
-rw-r--r--freebsd/contrib/tcpdump/print-tftp.c155
-rw-r--r--freebsd/contrib/tcpdump/print-timed.c113
-rw-r--r--freebsd/contrib/tcpdump/print-tipc.c394
-rw-r--r--freebsd/contrib/tcpdump/print-token.c207
-rw-r--r--freebsd/contrib/tcpdump/print-udld.c175
-rw-r--r--freebsd/contrib/tcpdump/print-udp.c693
-rw-r--r--freebsd/contrib/tcpdump/print-usb.c176
-rw-r--r--freebsd/contrib/tcpdump/print-vjc.c121
-rw-r--r--freebsd/contrib/tcpdump/print-vqp.c211
-rw-r--r--freebsd/contrib/tcpdump/print-vrrp.c149
-rw-r--r--freebsd/contrib/tcpdump/print-vtp.c380
-rw-r--r--freebsd/contrib/tcpdump/print-vxlan.c76
-rw-r--r--freebsd/contrib/tcpdump/print-wb.c446
-rw-r--r--freebsd/contrib/tcpdump/print-zephyr.c324
-rw-r--r--freebsd/contrib/tcpdump/print-zeromq.c150
-rw-r--r--freebsd/contrib/tcpdump/route6d.h77
-rw-r--r--freebsd/contrib/tcpdump/rpc_auth.h80
-rw-r--r--freebsd/contrib/tcpdump/rpc_msg.h129
-rw-r--r--freebsd/contrib/tcpdump/rx.h113
-rw-r--r--freebsd/contrib/tcpdump/sctpConstants.h571
-rw-r--r--freebsd/contrib/tcpdump/sctpHeader.h323
-rw-r--r--freebsd/contrib/tcpdump/setsignal.c95
-rw-r--r--freebsd/contrib/tcpdump/setsignal.h27
-rw-r--r--freebsd/contrib/tcpdump/signature.c161
-rw-r--r--freebsd/contrib/tcpdump/signature.h26
-rw-r--r--freebsd/contrib/tcpdump/slcompress.h87
-rw-r--r--freebsd/contrib/tcpdump/slip.h34
-rw-r--r--freebsd/contrib/tcpdump/sll.h127
-rw-r--r--freebsd/contrib/tcpdump/smb.h122
-rw-r--r--freebsd/contrib/tcpdump/smbutil.c1891
-rw-r--r--freebsd/contrib/tcpdump/tcp.h112
-rw-r--r--freebsd/contrib/tcpdump/tcpdump-stdinc.h226
-rw-r--r--freebsd/contrib/tcpdump/tcpdump.c2201
-rw-r--r--freebsd/contrib/tcpdump/telnet.h348
-rw-r--r--freebsd/contrib/tcpdump/tftp.h82
-rw-r--r--freebsd/contrib/tcpdump/timed.h97
-rw-r--r--freebsd/contrib/tcpdump/token.h53
-rw-r--r--freebsd/contrib/tcpdump/udp.h96
-rw-r--r--freebsd/contrib/tcpdump/util.c610
-rw-r--r--freebsd/usr.sbin/tcpdump/tcpdump/config.h328
-rwxr-xr-xlibbsd.py324
-rwxr-xr-xmakefile.py54
-rw-r--r--rtemsbsd/include/machine/rtems-bsd-commands.h2
-rwxr-xr-xwaf_generator.py140
-rw-r--r--wscript242
267 files changed, 122568 insertions, 90 deletions
diff --git a/Makefile b/Makefile
index 1b0cd4f1..9a3e5cad 100644
--- a/Makefile
+++ b/Makefile
@@ -107,6 +107,58 @@ LIB_C_FILES += freebsd/sys/vm/uma_core.c
LIB_C_FILES += freebsd/sys/vm/uma_dbg.c
LIB_C_FILES += freebsd/sys/cam/cam.c
LIB_C_FILES += freebsd/sys/cam/scsi/scsi_all.c
+LIB_C_FILES += freebsd/contrib/libpcap/scanner.c
+freebsd/contrib/libpcap/scanner.c: freebsd/contrib/libpcap/scanner.l freebsd/contrib/libpcap/scanner.c
+ ${LEX} -P pcap -t $< | sed -e '/YY_BUF_SIZE/s/16384/1024/' > $@
+freebsd/contrib/libpcap/scanner.o: freebsd/contrib/libpcap/scanner.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -DINET6 -D_U_=__attribute__((unused)) -DHAVE_INTTYPES=1 -DHAVE_STDINT=1 -DHAVE_STRERROR=1 -DHAVE_STRLCPY=1 -DHAVE_SNPRINTF=1 -DHAVE_VSNPRINTF=1 -DNEED_YYPARSE_WRAPPER=1 -Dyylval=pcap_lval -c $< -o $@
+LIB_C_FILES += freebsd/contrib/libpcap/grammar.c
+freebsd/contrib/libpcap/grammar.c: freebsd/contrib/libpcap/grammar.y
+ yacc -b -b pcap -d -p -b pcap $<
+ sed -e /YY_BUF_SIZE/s/16384/1024/ < -b pcap.tab.c > $@
+ rm -f -b pcap.tab.c
+ mv -b pcap.tab.h freebsd/contrib/libpcap/tokdefs.h
+freebsd/contrib/libpcap/grammar.o: freebsd/contrib/libpcap/grammar.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -DINET6 -D_U_=__attribute__((unused)) -DHAVE_INTTYPES=1 -DHAVE_STDINT=1 -DHAVE_STRERROR=1 -DHAVE_STRLCPY=1 -DHAVE_SNPRINTF=1 -DHAVE_VSNPRINTF=1 -DNEED_YYPARSE_WRAPPER=1 -Dyylval=pcap_lval -c $< -o $@
+LIB_C_FILES += freebsd/contrib/libpcap/bpf_image.c
+freebsd/contrib/libpcap/bpf_image.o: freebsd/contrib/libpcap/bpf_image.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -DINET6 -D_U_=__attribute__((unused)) -DHAVE_INTTYPES=1 -DHAVE_STDINT=1 -DHAVE_STRERROR=1 -DHAVE_STRLCPY=1 -DHAVE_SNPRINTF=1 -DHAVE_VSNPRINTF=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/libpcap/etherent.c
+freebsd/contrib/libpcap/etherent.o: freebsd/contrib/libpcap/etherent.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -DINET6 -D_U_=__attribute__((unused)) -DHAVE_INTTYPES=1 -DHAVE_STDINT=1 -DHAVE_STRERROR=1 -DHAVE_STRLCPY=1 -DHAVE_SNPRINTF=1 -DHAVE_VSNPRINTF=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/libpcap/fad-getad.c
+freebsd/contrib/libpcap/fad-getad.o: freebsd/contrib/libpcap/fad-getad.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -DINET6 -D_U_=__attribute__((unused)) -DHAVE_INTTYPES=1 -DHAVE_STDINT=1 -DHAVE_STRERROR=1 -DHAVE_STRLCPY=1 -DHAVE_SNPRINTF=1 -DHAVE_VSNPRINTF=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/libpcap/gencode.c
+freebsd/contrib/libpcap/gencode.o: freebsd/contrib/libpcap/gencode.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -DINET6 -D_U_=__attribute__((unused)) -DHAVE_INTTYPES=1 -DHAVE_STDINT=1 -DHAVE_STRERROR=1 -DHAVE_STRLCPY=1 -DHAVE_SNPRINTF=1 -DHAVE_VSNPRINTF=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/libpcap/inet.c
+freebsd/contrib/libpcap/inet.o: freebsd/contrib/libpcap/inet.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -DINET6 -D_U_=__attribute__((unused)) -DHAVE_INTTYPES=1 -DHAVE_STDINT=1 -DHAVE_STRERROR=1 -DHAVE_STRLCPY=1 -DHAVE_SNPRINTF=1 -DHAVE_VSNPRINTF=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/libpcap/pcap.c
+freebsd/contrib/libpcap/pcap.o: freebsd/contrib/libpcap/pcap.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -DINET6 -D_U_=__attribute__((unused)) -DHAVE_INTTYPES=1 -DHAVE_STDINT=1 -DHAVE_STRERROR=1 -DHAVE_STRLCPY=1 -DHAVE_SNPRINTF=1 -DHAVE_VSNPRINTF=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/libpcap/pcap-bpf.c
+freebsd/contrib/libpcap/pcap-bpf.o: freebsd/contrib/libpcap/pcap-bpf.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -DINET6 -D_U_=__attribute__((unused)) -DHAVE_INTTYPES=1 -DHAVE_STDINT=1 -DHAVE_STRERROR=1 -DHAVE_STRLCPY=1 -DHAVE_SNPRINTF=1 -DHAVE_VSNPRINTF=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/libpcap/pcap-common.c
+freebsd/contrib/libpcap/pcap-common.o: freebsd/contrib/libpcap/pcap-common.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -DINET6 -D_U_=__attribute__((unused)) -DHAVE_INTTYPES=1 -DHAVE_STDINT=1 -DHAVE_STRERROR=1 -DHAVE_STRLCPY=1 -DHAVE_SNPRINTF=1 -DHAVE_VSNPRINTF=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/libpcap/optimize.c
+freebsd/contrib/libpcap/optimize.o: freebsd/contrib/libpcap/optimize.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -DINET6 -D_U_=__attribute__((unused)) -DHAVE_INTTYPES=1 -DHAVE_STDINT=1 -DHAVE_STRERROR=1 -DHAVE_STRLCPY=1 -DHAVE_SNPRINTF=1 -DHAVE_VSNPRINTF=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/libpcap/nametoaddr.c
+freebsd/contrib/libpcap/nametoaddr.o: freebsd/contrib/libpcap/nametoaddr.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -DINET6 -D_U_=__attribute__((unused)) -DHAVE_INTTYPES=1 -DHAVE_STDINT=1 -DHAVE_STRERROR=1 -DHAVE_STRLCPY=1 -DHAVE_SNPRINTF=1 -DHAVE_VSNPRINTF=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/libpcap/savefile.c
+freebsd/contrib/libpcap/savefile.o: freebsd/contrib/libpcap/savefile.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -DINET6 -D_U_=__attribute__((unused)) -DHAVE_INTTYPES=1 -DHAVE_STDINT=1 -DHAVE_STRERROR=1 -DHAVE_STRLCPY=1 -DHAVE_SNPRINTF=1 -DHAVE_VSNPRINTF=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/libpcap/sf-pcap.c
+freebsd/contrib/libpcap/sf-pcap.o: freebsd/contrib/libpcap/sf-pcap.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -DINET6 -D_U_=__attribute__((unused)) -DHAVE_INTTYPES=1 -DHAVE_STDINT=1 -DHAVE_STRERROR=1 -DHAVE_STRLCPY=1 -DHAVE_SNPRINTF=1 -DHAVE_VSNPRINTF=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/libpcap/sf-pcap-ng.c
+freebsd/contrib/libpcap/sf-pcap-ng.o: freebsd/contrib/libpcap/sf-pcap-ng.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) -DINET6 -D_U_=__attribute__((unused)) -DHAVE_INTTYPES=1 -DHAVE_STDINT=1 -DHAVE_STRERROR=1 -DHAVE_STRLCPY=1 -DHAVE_SNPRINTF=1 -DHAVE_VSNPRINTF=1 -c $< -o $@
LIB_C_FILES += freebsd/sys/crypto/sha1.c
LIB_C_FILES += freebsd/sys/crypto/sha2/sha2.c
LIB_C_FILES += freebsd/sys/crypto/rijndael/rijndael-alg-fst.c
@@ -684,19 +736,19 @@ freebsd/lib/libc/net/nslexer.c: freebsd/lib/libc/net/nslexer.l freebsd/lib/libc/
${LEX} -P _nsyy -t $< | sed -e '/YY_BUF_SIZE/s/16384/1024/' > $@
LIB_C_FILES += freebsd/lib/libc/net/nsparser.c
freebsd/lib/libc/net/nsparser.c: freebsd/lib/libc/net/nsparser.y
- yacc -b _nsyy -d -p _nsyy $<
- sed -e /YY_BUF_SIZE/s/16384/1024/ < _nsyy.tab.c > $@
- rm -f _nsyy.tab.c
- mv _nsyy.tab.h freebsd/lib/libc/net/nsparser.h
+ yacc -b -b _nsyy -d -p -b _nsyy $<
+ sed -e /YY_BUF_SIZE/s/16384/1024/ < -b _nsyy.tab.c > $@
+ rm -f -b _nsyy.tab.c
+ mv -b _nsyy.tab.h freebsd/lib/libc/net/nsparser.h
LIB_C_FILES += freebsd/lib/libipsec/policy_token.c
freebsd/lib/libipsec/policy_token.c: freebsd/lib/libipsec/policy_token.l freebsd/lib/libipsec/policy_parse.c
${LEX} -P __libipsecyy -t $< | sed -e '/YY_BUF_SIZE/s/16384/1024/' > $@
LIB_C_FILES += freebsd/lib/libipsec/policy_parse.c
freebsd/lib/libipsec/policy_parse.c: freebsd/lib/libipsec/policy_parse.y
- yacc -b __libipsecyy -d -p __libipsecyy $<
- sed -e /YY_BUF_SIZE/s/16384/1024/ < __libipsecyy.tab.c > $@
- rm -f __libipsecyy.tab.c
- mv __libipsecyy.tab.h freebsd/lib/libipsec/y.tab.h
+ yacc -b -b __libipsecyy -d -p -b __libipsecyy $<
+ sed -e /YY_BUF_SIZE/s/16384/1024/ < -b __libipsecyy.tab.c > $@
+ rm -f -b __libipsecyy.tab.c
+ mv -b __libipsecyy.tab.h freebsd/lib/libipsec/y.tab.h
TEST_FOOBARCLIENT = testsuite/foobarclient/foobarclient.exe
TEST_FOOBARCLIENT_O_FILES =
@@ -1536,6 +1588,435 @@ freebsd/usr.bin/netstat/sctp.o: freebsd/usr.bin/netstat/sctp.c
LIB_C_FILES += freebsd/usr.bin/netstat/unix.c
freebsd/usr.bin/netstat/unix.o: freebsd/usr.bin/netstat/unix.c
$(CC) $(CPPFLAGS) $(CFLAGS) -DINET6 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/addrtoname.c
+freebsd/contrib/tcpdump/addrtoname.o: freebsd/contrib/tcpdump/addrtoname.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/af.c
+freebsd/contrib/tcpdump/af.o: freebsd/contrib/tcpdump/af.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/bpf_dump.c
+freebsd/contrib/tcpdump/bpf_dump.o: freebsd/contrib/tcpdump/bpf_dump.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/checksum.c
+freebsd/contrib/tcpdump/checksum.o: freebsd/contrib/tcpdump/checksum.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/cpack.c
+freebsd/contrib/tcpdump/cpack.o: freebsd/contrib/tcpdump/cpack.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/gmpls.c
+freebsd/contrib/tcpdump/gmpls.o: freebsd/contrib/tcpdump/gmpls.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/gmt2local.c
+freebsd/contrib/tcpdump/gmt2local.o: freebsd/contrib/tcpdump/gmt2local.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/in_cksum.c
+freebsd/contrib/tcpdump/in_cksum.o: freebsd/contrib/tcpdump/in_cksum.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/ipproto.c
+freebsd/contrib/tcpdump/ipproto.o: freebsd/contrib/tcpdump/ipproto.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/machdep.c
+freebsd/contrib/tcpdump/machdep.o: freebsd/contrib/tcpdump/machdep.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/nlpid.c
+freebsd/contrib/tcpdump/nlpid.o: freebsd/contrib/tcpdump/nlpid.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/l2vpn.c
+freebsd/contrib/tcpdump/l2vpn.o: freebsd/contrib/tcpdump/l2vpn.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/oui.c
+freebsd/contrib/tcpdump/oui.o: freebsd/contrib/tcpdump/oui.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/parsenfsfh.c
+freebsd/contrib/tcpdump/parsenfsfh.o: freebsd/contrib/tcpdump/parsenfsfh.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-802_11.c
+freebsd/contrib/tcpdump/print-802_11.o: freebsd/contrib/tcpdump/print-802_11.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-802_15_4.c
+freebsd/contrib/tcpdump/print-802_15_4.o: freebsd/contrib/tcpdump/print-802_15_4.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-ah.c
+freebsd/contrib/tcpdump/print-ah.o: freebsd/contrib/tcpdump/print-ah.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-aodv.c
+freebsd/contrib/tcpdump/print-aodv.o: freebsd/contrib/tcpdump/print-aodv.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-ap1394.c
+freebsd/contrib/tcpdump/print-ap1394.o: freebsd/contrib/tcpdump/print-ap1394.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-arcnet.c
+freebsd/contrib/tcpdump/print-arcnet.o: freebsd/contrib/tcpdump/print-arcnet.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-arp.c
+freebsd/contrib/tcpdump/print-arp.o: freebsd/contrib/tcpdump/print-arp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-ascii.c
+freebsd/contrib/tcpdump/print-ascii.o: freebsd/contrib/tcpdump/print-ascii.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-atalk.c
+freebsd/contrib/tcpdump/print-atalk.o: freebsd/contrib/tcpdump/print-atalk.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-atm.c
+freebsd/contrib/tcpdump/print-atm.o: freebsd/contrib/tcpdump/print-atm.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-babel.c
+freebsd/contrib/tcpdump/print-babel.o: freebsd/contrib/tcpdump/print-babel.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-beep.c
+freebsd/contrib/tcpdump/print-beep.o: freebsd/contrib/tcpdump/print-beep.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-bfd.c
+freebsd/contrib/tcpdump/print-bfd.o: freebsd/contrib/tcpdump/print-bfd.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-bgp.c
+freebsd/contrib/tcpdump/print-bgp.o: freebsd/contrib/tcpdump/print-bgp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-bootp.c
+freebsd/contrib/tcpdump/print-bootp.o: freebsd/contrib/tcpdump/print-bootp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-bt.c
+freebsd/contrib/tcpdump/print-bt.o: freebsd/contrib/tcpdump/print-bt.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-carp.c
+freebsd/contrib/tcpdump/print-carp.o: freebsd/contrib/tcpdump/print-carp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-cdp.c
+freebsd/contrib/tcpdump/print-cdp.o: freebsd/contrib/tcpdump/print-cdp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-cfm.c
+freebsd/contrib/tcpdump/print-cfm.o: freebsd/contrib/tcpdump/print-cfm.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-chdlc.c
+freebsd/contrib/tcpdump/print-chdlc.o: freebsd/contrib/tcpdump/print-chdlc.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-cip.c
+freebsd/contrib/tcpdump/print-cip.o: freebsd/contrib/tcpdump/print-cip.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-cnfp.c
+freebsd/contrib/tcpdump/print-cnfp.o: freebsd/contrib/tcpdump/print-cnfp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-dccp.c
+freebsd/contrib/tcpdump/print-dccp.o: freebsd/contrib/tcpdump/print-dccp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-decnet.c
+freebsd/contrib/tcpdump/print-decnet.o: freebsd/contrib/tcpdump/print-decnet.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-dhcp6.c
+freebsd/contrib/tcpdump/print-dhcp6.o: freebsd/contrib/tcpdump/print-dhcp6.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-domain.c
+freebsd/contrib/tcpdump/print-domain.o: freebsd/contrib/tcpdump/print-domain.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-dtp.c
+freebsd/contrib/tcpdump/print-dtp.o: freebsd/contrib/tcpdump/print-dtp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-dvmrp.c
+freebsd/contrib/tcpdump/print-dvmrp.o: freebsd/contrib/tcpdump/print-dvmrp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-eap.c
+freebsd/contrib/tcpdump/print-eap.o: freebsd/contrib/tcpdump/print-eap.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-egp.c
+freebsd/contrib/tcpdump/print-egp.o: freebsd/contrib/tcpdump/print-egp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-eigrp.c
+freebsd/contrib/tcpdump/print-eigrp.o: freebsd/contrib/tcpdump/print-eigrp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-enc.c
+freebsd/contrib/tcpdump/print-enc.o: freebsd/contrib/tcpdump/print-enc.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-esp.c
+freebsd/contrib/tcpdump/print-esp.o: freebsd/contrib/tcpdump/print-esp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-ether.c
+freebsd/contrib/tcpdump/print-ether.o: freebsd/contrib/tcpdump/print-ether.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-fddi.c
+freebsd/contrib/tcpdump/print-fddi.o: freebsd/contrib/tcpdump/print-fddi.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-forces.c
+freebsd/contrib/tcpdump/print-forces.o: freebsd/contrib/tcpdump/print-forces.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-fr.c
+freebsd/contrib/tcpdump/print-fr.o: freebsd/contrib/tcpdump/print-fr.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-frag6.c
+freebsd/contrib/tcpdump/print-frag6.o: freebsd/contrib/tcpdump/print-frag6.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-gre.c
+freebsd/contrib/tcpdump/print-gre.o: freebsd/contrib/tcpdump/print-gre.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-hsrp.c
+freebsd/contrib/tcpdump/print-hsrp.o: freebsd/contrib/tcpdump/print-hsrp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-icmp.c
+freebsd/contrib/tcpdump/print-icmp.o: freebsd/contrib/tcpdump/print-icmp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-icmp6.c
+freebsd/contrib/tcpdump/print-icmp6.o: freebsd/contrib/tcpdump/print-icmp6.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-igmp.c
+freebsd/contrib/tcpdump/print-igmp.o: freebsd/contrib/tcpdump/print-igmp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-igrp.c
+freebsd/contrib/tcpdump/print-igrp.o: freebsd/contrib/tcpdump/print-igrp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-ip.c
+freebsd/contrib/tcpdump/print-ip.o: freebsd/contrib/tcpdump/print-ip.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-ip6.c
+freebsd/contrib/tcpdump/print-ip6.o: freebsd/contrib/tcpdump/print-ip6.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-ip6opts.c
+freebsd/contrib/tcpdump/print-ip6opts.o: freebsd/contrib/tcpdump/print-ip6opts.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-ipcomp.c
+freebsd/contrib/tcpdump/print-ipcomp.o: freebsd/contrib/tcpdump/print-ipcomp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-ipfc.c
+freebsd/contrib/tcpdump/print-ipfc.o: freebsd/contrib/tcpdump/print-ipfc.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-ipnet.c
+freebsd/contrib/tcpdump/print-ipnet.o: freebsd/contrib/tcpdump/print-ipnet.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-ipx.c
+freebsd/contrib/tcpdump/print-ipx.o: freebsd/contrib/tcpdump/print-ipx.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-isakmp.c
+freebsd/contrib/tcpdump/print-isakmp.o: freebsd/contrib/tcpdump/print-isakmp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-isoclns.c
+freebsd/contrib/tcpdump/print-isoclns.o: freebsd/contrib/tcpdump/print-isoclns.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-juniper.c
+freebsd/contrib/tcpdump/print-juniper.o: freebsd/contrib/tcpdump/print-juniper.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-krb.c
+freebsd/contrib/tcpdump/print-krb.o: freebsd/contrib/tcpdump/print-krb.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-l2tp.c
+freebsd/contrib/tcpdump/print-l2tp.o: freebsd/contrib/tcpdump/print-l2tp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-lane.c
+freebsd/contrib/tcpdump/print-lane.o: freebsd/contrib/tcpdump/print-lane.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-ldp.c
+freebsd/contrib/tcpdump/print-ldp.o: freebsd/contrib/tcpdump/print-ldp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-llc.c
+freebsd/contrib/tcpdump/print-llc.o: freebsd/contrib/tcpdump/print-llc.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-lldp.c
+freebsd/contrib/tcpdump/print-lldp.o: freebsd/contrib/tcpdump/print-lldp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-lmp.c
+freebsd/contrib/tcpdump/print-lmp.o: freebsd/contrib/tcpdump/print-lmp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-lspping.c
+freebsd/contrib/tcpdump/print-lspping.o: freebsd/contrib/tcpdump/print-lspping.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-lwapp.c
+freebsd/contrib/tcpdump/print-lwapp.o: freebsd/contrib/tcpdump/print-lwapp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-lwres.c
+freebsd/contrib/tcpdump/print-lwres.o: freebsd/contrib/tcpdump/print-lwres.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-mobile.c
+freebsd/contrib/tcpdump/print-mobile.o: freebsd/contrib/tcpdump/print-mobile.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-mobility.c
+freebsd/contrib/tcpdump/print-mobility.o: freebsd/contrib/tcpdump/print-mobility.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-mpcp.c
+freebsd/contrib/tcpdump/print-mpcp.o: freebsd/contrib/tcpdump/print-mpcp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-mpls.c
+freebsd/contrib/tcpdump/print-mpls.o: freebsd/contrib/tcpdump/print-mpls.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-msdp.c
+freebsd/contrib/tcpdump/print-msdp.o: freebsd/contrib/tcpdump/print-msdp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-msnlb.c
+freebsd/contrib/tcpdump/print-msnlb.o: freebsd/contrib/tcpdump/print-msnlb.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-netbios.c
+freebsd/contrib/tcpdump/print-netbios.o: freebsd/contrib/tcpdump/print-netbios.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-nfs.c
+freebsd/contrib/tcpdump/print-nfs.o: freebsd/contrib/tcpdump/print-nfs.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-ntp.c
+freebsd/contrib/tcpdump/print-ntp.o: freebsd/contrib/tcpdump/print-ntp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-null.c
+freebsd/contrib/tcpdump/print-null.o: freebsd/contrib/tcpdump/print-null.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-olsr.c
+freebsd/contrib/tcpdump/print-olsr.o: freebsd/contrib/tcpdump/print-olsr.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-ospf.c
+freebsd/contrib/tcpdump/print-ospf.o: freebsd/contrib/tcpdump/print-ospf.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-ospf6.c
+freebsd/contrib/tcpdump/print-ospf6.o: freebsd/contrib/tcpdump/print-ospf6.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-otv.c
+freebsd/contrib/tcpdump/print-otv.o: freebsd/contrib/tcpdump/print-otv.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-pflog.c
+freebsd/contrib/tcpdump/print-pflog.o: freebsd/contrib/tcpdump/print-pflog.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-pfsync.c
+freebsd/contrib/tcpdump/print-pfsync.o: freebsd/contrib/tcpdump/print-pfsync.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-pgm.c
+freebsd/contrib/tcpdump/print-pgm.o: freebsd/contrib/tcpdump/print-pgm.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-pim.c
+freebsd/contrib/tcpdump/print-pim.o: freebsd/contrib/tcpdump/print-pim.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-ppi.c
+freebsd/contrib/tcpdump/print-ppi.o: freebsd/contrib/tcpdump/print-ppi.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-ppp.c
+freebsd/contrib/tcpdump/print-ppp.o: freebsd/contrib/tcpdump/print-ppp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-pppoe.c
+freebsd/contrib/tcpdump/print-pppoe.o: freebsd/contrib/tcpdump/print-pppoe.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-pptp.c
+freebsd/contrib/tcpdump/print-pptp.o: freebsd/contrib/tcpdump/print-pptp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-radius.c
+freebsd/contrib/tcpdump/print-radius.o: freebsd/contrib/tcpdump/print-radius.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-raw.c
+freebsd/contrib/tcpdump/print-raw.o: freebsd/contrib/tcpdump/print-raw.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-rip.c
+freebsd/contrib/tcpdump/print-rip.o: freebsd/contrib/tcpdump/print-rip.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-ripng.c
+freebsd/contrib/tcpdump/print-ripng.o: freebsd/contrib/tcpdump/print-ripng.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-rpki-rtr.c
+freebsd/contrib/tcpdump/print-rpki-rtr.o: freebsd/contrib/tcpdump/print-rpki-rtr.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-rrcp.c
+freebsd/contrib/tcpdump/print-rrcp.o: freebsd/contrib/tcpdump/print-rrcp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-rsvp.c
+freebsd/contrib/tcpdump/print-rsvp.o: freebsd/contrib/tcpdump/print-rsvp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-rt6.c
+freebsd/contrib/tcpdump/print-rt6.o: freebsd/contrib/tcpdump/print-rt6.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-rx.c
+freebsd/contrib/tcpdump/print-rx.o: freebsd/contrib/tcpdump/print-rx.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-sctp.c
+freebsd/contrib/tcpdump/print-sctp.o: freebsd/contrib/tcpdump/print-sctp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-sflow.c
+freebsd/contrib/tcpdump/print-sflow.o: freebsd/contrib/tcpdump/print-sflow.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-sip.c
+freebsd/contrib/tcpdump/print-sip.o: freebsd/contrib/tcpdump/print-sip.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-sl.c
+freebsd/contrib/tcpdump/print-sl.o: freebsd/contrib/tcpdump/print-sl.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-sll.c
+freebsd/contrib/tcpdump/print-sll.o: freebsd/contrib/tcpdump/print-sll.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-slow.c
+freebsd/contrib/tcpdump/print-slow.o: freebsd/contrib/tcpdump/print-slow.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-smb.c
+freebsd/contrib/tcpdump/print-smb.o: freebsd/contrib/tcpdump/print-smb.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-snmp.c
+freebsd/contrib/tcpdump/print-snmp.o: freebsd/contrib/tcpdump/print-snmp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-stp.c
+freebsd/contrib/tcpdump/print-stp.o: freebsd/contrib/tcpdump/print-stp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-sunatm.c
+freebsd/contrib/tcpdump/print-sunatm.o: freebsd/contrib/tcpdump/print-sunatm.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-symantec.c
+freebsd/contrib/tcpdump/print-symantec.o: freebsd/contrib/tcpdump/print-symantec.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-syslog.c
+freebsd/contrib/tcpdump/print-syslog.o: freebsd/contrib/tcpdump/print-syslog.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-tcp.c
+freebsd/contrib/tcpdump/print-tcp.o: freebsd/contrib/tcpdump/print-tcp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-telnet.c
+freebsd/contrib/tcpdump/print-telnet.o: freebsd/contrib/tcpdump/print-telnet.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-tftp.c
+freebsd/contrib/tcpdump/print-tftp.o: freebsd/contrib/tcpdump/print-tftp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-timed.c
+freebsd/contrib/tcpdump/print-timed.o: freebsd/contrib/tcpdump/print-timed.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-tipc.c
+freebsd/contrib/tcpdump/print-tipc.o: freebsd/contrib/tcpdump/print-tipc.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-token.c
+freebsd/contrib/tcpdump/print-token.o: freebsd/contrib/tcpdump/print-token.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-udld.c
+freebsd/contrib/tcpdump/print-udld.o: freebsd/contrib/tcpdump/print-udld.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-udp.c
+freebsd/contrib/tcpdump/print-udp.o: freebsd/contrib/tcpdump/print-udp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-usb.c
+freebsd/contrib/tcpdump/print-usb.o: freebsd/contrib/tcpdump/print-usb.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-vjc.c
+freebsd/contrib/tcpdump/print-vjc.o: freebsd/contrib/tcpdump/print-vjc.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-vqp.c
+freebsd/contrib/tcpdump/print-vqp.o: freebsd/contrib/tcpdump/print-vqp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-vrrp.c
+freebsd/contrib/tcpdump/print-vrrp.o: freebsd/contrib/tcpdump/print-vrrp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-vtp.c
+freebsd/contrib/tcpdump/print-vtp.o: freebsd/contrib/tcpdump/print-vtp.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-vxlan.c
+freebsd/contrib/tcpdump/print-vxlan.o: freebsd/contrib/tcpdump/print-vxlan.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-wb.c
+freebsd/contrib/tcpdump/print-wb.o: freebsd/contrib/tcpdump/print-wb.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-zephyr.c
+freebsd/contrib/tcpdump/print-zephyr.o: freebsd/contrib/tcpdump/print-zephyr.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/print-zeromq.c
+freebsd/contrib/tcpdump/print-zeromq.o: freebsd/contrib/tcpdump/print-zeromq.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/setsignal.c
+freebsd/contrib/tcpdump/setsignal.o: freebsd/contrib/tcpdump/setsignal.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/signature.c
+freebsd/contrib/tcpdump/signature.o: freebsd/contrib/tcpdump/signature.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/smbutil.c
+freebsd/contrib/tcpdump/smbutil.o: freebsd/contrib/tcpdump/smbutil.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/tcpdump.c
+freebsd/contrib/tcpdump/tcpdump.o: freebsd/contrib/tcpdump/tcpdump.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
+LIB_C_FILES += freebsd/contrib/tcpdump/util.c
+freebsd/contrib/tcpdump/util.o: freebsd/contrib/tcpdump/util.c
+ $(CC) $(CPPFLAGS) $(CFLAGS) freebsd/contrib/tcpdump freebsd/usr.sbin/tcpdump/tcpdump-DINET6 -D_U_=__attribute__((unused)) -DHAVE_CONFIG_H=1 -DHAVE_NET_PFVAR_H=1 -c $< -o $@
ifeq ($(NEED_DUMMY_PIC_IRQ),yes)
CFLAGS += -I rtems-dummy-pic-irq/include
diff --git a/builder.py b/builder.py
index 3a0da7a1..8059475c 100755
--- a/builder.py
+++ b/builder.py
@@ -88,6 +88,7 @@ def includes():
'-Ifreebsd/lib/libkvm',
'-Ifreebsd/lib/libmemstat',
'-Ifreebsd/lib/libipsec',
+ '-Ifreebsd/contrib/libpcap',
'-Irtemsbsd/sys',
'-ImDNSResponder/mDNSCore',
'-ImDNSResponder/mDNSShared',
@@ -302,6 +303,12 @@ class TargetSourceCPUDependentPathComposer(CPUDependentPathComposer):
return path
class BuildSystemFragmentComposer(object):
+ def __init__(self, includes = None):
+ if type(includes) is not list:
+ self.includes = [includes]
+ else:
+ self.includes = includes
+
def compose(self, path):
return ''
diff --git a/freebsd-to-rtems.py b/freebsd-to-rtems.py
index c645ac4b..3091bfc3 100755
--- a/freebsd-to-rtems.py
+++ b/freebsd-to-rtems.py
@@ -142,21 +142,23 @@ if isEarlyExit == True:
print "Early exit at user request"
sys.exit(0)
-makefile_gen = makefile.ModuleManager()
-waf_gen = waf_generator.ModuleManager()
-
-libbsd.sources(makefile_gen)
-libbsd.sources(waf_gen)
-
-# Perform the actual file manipulation
-if isForward:
- if not isOnlyMakefile:
- makefile_gen.copyFromFreeBSDToRTEMS()
- makefile_gen.generate()
- waf_gen.generate()
-else:
- makefile_gen.copyFromRTEMSToFreeBSD()
-
-# Print a summary if changing files
-if builder.isDiffMode == False:
- print '%d file(s) were changed.' % (builder.filesProcessed)
+try:
+ makefile_gen = makefile.ModuleManager()
+ waf_gen = waf_generator.ModuleManager()
+
+ libbsd.sources(makefile_gen)
+ libbsd.sources(waf_gen)
+
+ # Perform the actual file manipulation
+ if isForward:
+ if not isOnlyMakefile:
+ makefile_gen.copyFromFreeBSDToRTEMS()
+ makefile_gen.generate()
+ waf_gen.generate()
+ else:
+ makefile_gen.copyFromRTEMSToFreeBSD()
+ # Print a summary if changing files
+ if builder.isDiffMode == False:
+ print '%d file(s) were changed.' % (builder.filesProcessed)
+except IOError, ioe:
+ print 'error: %s' % (ioe)
diff --git a/freebsd/contrib/libpcap/arcnet.h b/freebsd/contrib/libpcap/arcnet.h
new file mode 100644
index 00000000..4f86043e
--- /dev/null
+++ b/freebsd/contrib/libpcap/arcnet.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) $Id: arcnet.h,v 1.2 2001-04-24 02:17:52 guy Exp $ (LBL)
+ *
+ * from: NetBSD: if_arc.h,v 1.13 1999/11/19 20:41:19 thorpej Exp
+ */
+
+/* RFC 1051 */
+#define ARCTYPE_IP_OLD 240 /* IP protocol */
+#define ARCTYPE_ARP_OLD 241 /* address resolution protocol */
+
+/* RFC 1201 */
+#define ARCTYPE_IP 212 /* IP protocol */
+#define ARCTYPE_ARP 213 /* address resolution protocol */
+#define ARCTYPE_REVARP 214 /* reverse addr resolution protocol */
+
+#define ARCTYPE_ATALK 221 /* Appletalk */
+#define ARCTYPE_BANIAN 247 /* Banyan Vines */
+#define ARCTYPE_IPX 250 /* Novell IPX */
+
+#define ARCTYPE_INET6 0xc4 /* IPng */
+#define ARCTYPE_DIAGNOSE 0x80 /* as per ANSI/ATA 878.1 */
diff --git a/freebsd/contrib/libpcap/atmuni31.h b/freebsd/contrib/libpcap/atmuni31.h
new file mode 100644
index 00000000..880cc1a8
--- /dev/null
+++ b/freebsd/contrib/libpcap/atmuni31.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1997 Yen Yen Lim and North Dakota State University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Yen Yen Lim and
+ North Dakota State University
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/atmuni31.h,v 1.3 2007-10-22 19:28:58 guy Exp $ (LBL)
+ */
+
+/* Based on UNI3.1 standard by ATM Forum */
+
+/* ATM traffic types based on VPI=0 and (the following VCI */
+#define VCI_PPC 0x05 /* Point-to-point signal msg */
+#define VCI_BCC 0x02 /* Broadcast signal msg */
+#define VCI_OAMF4SC 0x03 /* Segment OAM F4 flow cell */
+#define VCI_OAMF4EC 0x04 /* End-to-end OAM F4 flow cell */
+#define VCI_METAC 0x01 /* Meta signal msg */
+#define VCI_ILMIC 0x10 /* ILMI msg */
+
+/* Q.2931 signalling messages */
+#define CALL_PROCEED 0x02 /* call proceeding */
+#define CONNECT 0x07 /* connect */
+#define CONNECT_ACK 0x0f /* connect_ack */
+#define SETUP 0x05 /* setup */
+#define RELEASE 0x4d /* release */
+#define RELEASE_DONE 0x5a /* release_done */
+#define RESTART 0x46 /* restart */
+#define RESTART_ACK 0x4e /* restart ack */
+#define STATUS 0x7d /* status */
+#define STATUS_ENQ 0x75 /* status ack */
+#define ADD_PARTY 0x80 /* add party */
+#define ADD_PARTY_ACK 0x81 /* add party ack */
+#define ADD_PARTY_REJ 0x82 /* add party rej */
+#define DROP_PARTY 0x83 /* drop party */
+#define DROP_PARTY_ACK 0x84 /* drop party ack */
+
+/* Information Element Parameters in the signalling messages */
+#define CAUSE 0x08 /* cause */
+#define ENDPT_REF 0x54 /* endpoint reference */
+#define AAL_PARA 0x58 /* ATM adaptation layer parameters */
+#define TRAFF_DESCRIP 0x59 /* atm traffic descriptors */
+#define CONNECT_ID 0x5a /* connection identifier */
+#define QOS_PARA 0x5c /* quality of service parameters */
+#define B_HIGHER 0x5d /* broadband higher layer information */
+#define B_BEARER 0x5e /* broadband bearer capability */
+#define B_LOWER 0x5f /* broadband lower information */
+#define CALLING_PARTY 0x6c /* calling party number */
+#define CALLED_PARTY 0x70 /* called party nmber */
+
+#define Q2931 0x09
+
+/* Q.2931 signalling general messages format */
+#define PROTO_POS 0 /* offset of protocol discriminator */
+#define CALL_REF_POS 2 /* offset of call reference value */
+#define MSG_TYPE_POS 5 /* offset of message type */
+#define MSG_LEN_POS 7 /* offset of mesage length */
+#define IE_BEGIN_POS 9 /* offset of first information element */
+
+/* format of signalling messages */
+#define TYPE_POS 0
+#define LEN_POS 2
+#define FIELD_BEGIN_POS 4
diff --git a/freebsd/contrib/libpcap/bpf_image.c b/freebsd/contrib/libpcap/bpf_image.c
new file mode 100644
index 00000000..07018b33
--- /dev/null
+++ b/freebsd/contrib/libpcap/bpf_image.c
@@ -0,0 +1,307 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1990, 1991, 1992, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/bpf_image.c,v 1.28 2008-01-02 04:16:46 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <rtems/bsd/sys/types.h>
+#endif /* WIN32 */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "pcap-int.h"
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+char *
+bpf_image(p, n)
+ struct bpf_insn *p;
+ int n;
+{
+ int v;
+ const char *fmt, *op;
+ static char image[256];
+ char operand[64];
+
+ v = p->k;
+ switch (p->code) {
+
+ default:
+ op = "unimp";
+ fmt = "0x%x";
+ v = p->code;
+ break;
+
+ case BPF_RET|BPF_K:
+ op = "ret";
+ fmt = "#%d";
+ break;
+
+ case BPF_RET|BPF_A:
+ op = "ret";
+ fmt = "";
+ break;
+
+ case BPF_LD|BPF_W|BPF_ABS:
+ op = "ld";
+ fmt = "[%d]";
+ break;
+
+ case BPF_LD|BPF_H|BPF_ABS:
+ op = "ldh";
+ fmt = "[%d]";
+ break;
+
+ case BPF_LD|BPF_B|BPF_ABS:
+ op = "ldb";
+ fmt = "[%d]";
+ break;
+
+ case BPF_LD|BPF_W|BPF_LEN:
+ op = "ld";
+ fmt = "#pktlen";
+ break;
+
+ case BPF_LD|BPF_W|BPF_IND:
+ op = "ld";
+ fmt = "[x + %d]";
+ break;
+
+ case BPF_LD|BPF_H|BPF_IND:
+ op = "ldh";
+ fmt = "[x + %d]";
+ break;
+
+ case BPF_LD|BPF_B|BPF_IND:
+ op = "ldb";
+ fmt = "[x + %d]";
+ break;
+
+ case BPF_LD|BPF_IMM:
+ op = "ld";
+ fmt = "#0x%x";
+ break;
+
+ case BPF_LDX|BPF_IMM:
+ op = "ldx";
+ fmt = "#0x%x";
+ break;
+
+ case BPF_LDX|BPF_MSH|BPF_B:
+ op = "ldxb";
+ fmt = "4*([%d]&0xf)";
+ break;
+
+ case BPF_LD|BPF_MEM:
+ op = "ld";
+ fmt = "M[%d]";
+ break;
+
+ case BPF_LDX|BPF_MEM:
+ op = "ldx";
+ fmt = "M[%d]";
+ break;
+
+ case BPF_ST:
+ op = "st";
+ fmt = "M[%d]";
+ break;
+
+ case BPF_STX:
+ op = "stx";
+ fmt = "M[%d]";
+ break;
+
+ case BPF_JMP|BPF_JA:
+ op = "ja";
+ fmt = "%d";
+ v = n + 1 + p->k;
+ break;
+
+ case BPF_JMP|BPF_JGT|BPF_K:
+ op = "jgt";
+ fmt = "#0x%x";
+ break;
+
+ case BPF_JMP|BPF_JGE|BPF_K:
+ op = "jge";
+ fmt = "#0x%x";
+ break;
+
+ case BPF_JMP|BPF_JEQ|BPF_K:
+ op = "jeq";
+ fmt = "#0x%x";
+ break;
+
+ case BPF_JMP|BPF_JSET|BPF_K:
+ op = "jset";
+ fmt = "#0x%x";
+ break;
+
+ case BPF_JMP|BPF_JGT|BPF_X:
+ op = "jgt";
+ fmt = "x";
+ break;
+
+ case BPF_JMP|BPF_JGE|BPF_X:
+ op = "jge";
+ fmt = "x";
+ break;
+
+ case BPF_JMP|BPF_JEQ|BPF_X:
+ op = "jeq";
+ fmt = "x";
+ break;
+
+ case BPF_JMP|BPF_JSET|BPF_X:
+ op = "jset";
+ fmt = "x";
+ break;
+
+ case BPF_ALU|BPF_ADD|BPF_X:
+ op = "add";
+ fmt = "x";
+ break;
+
+ case BPF_ALU|BPF_SUB|BPF_X:
+ op = "sub";
+ fmt = "x";
+ break;
+
+ case BPF_ALU|BPF_MUL|BPF_X:
+ op = "mul";
+ fmt = "x";
+ break;
+
+ case BPF_ALU|BPF_DIV|BPF_X:
+ op = "div";
+ fmt = "x";
+ break;
+
+ case BPF_ALU|BPF_AND|BPF_X:
+ op = "and";
+ fmt = "x";
+ break;
+
+ case BPF_ALU|BPF_OR|BPF_X:
+ op = "or";
+ fmt = "x";
+ break;
+
+ case BPF_ALU|BPF_LSH|BPF_X:
+ op = "lsh";
+ fmt = "x";
+ break;
+
+ case BPF_ALU|BPF_RSH|BPF_X:
+ op = "rsh";
+ fmt = "x";
+ break;
+
+ case BPF_ALU|BPF_ADD|BPF_K:
+ op = "add";
+ fmt = "#%d";
+ break;
+
+ case BPF_ALU|BPF_SUB|BPF_K:
+ op = "sub";
+ fmt = "#%d";
+ break;
+
+ case BPF_ALU|BPF_MUL|BPF_K:
+ op = "mul";
+ fmt = "#%d";
+ break;
+
+ case BPF_ALU|BPF_DIV|BPF_K:
+ op = "div";
+ fmt = "#%d";
+ break;
+
+ case BPF_ALU|BPF_AND|BPF_K:
+ op = "and";
+ fmt = "#0x%x";
+ break;
+
+ case BPF_ALU|BPF_OR|BPF_K:
+ op = "or";
+ fmt = "#0x%x";
+ break;
+
+ case BPF_ALU|BPF_LSH|BPF_K:
+ op = "lsh";
+ fmt = "#%d";
+ break;
+
+ case BPF_ALU|BPF_RSH|BPF_K:
+ op = "rsh";
+ fmt = "#%d";
+ break;
+
+ case BPF_ALU|BPF_NEG:
+ op = "neg";
+ fmt = "";
+ break;
+
+ case BPF_MISC|BPF_TAX:
+ op = "tax";
+ fmt = "";
+ break;
+
+ case BPF_MISC|BPF_TXA:
+ op = "txa";
+ fmt = "";
+ break;
+ }
+ (void)snprintf(operand, sizeof operand, fmt, v);
+ if (BPF_CLASS(p->code) == BPF_JMP && BPF_OP(p->code) != BPF_JA) {
+ (void)snprintf(image, sizeof image,
+ "(%03d) %-8s %-16s jt %d\tjf %d",
+ n, op, operand, n + 1 + p->jt, n + 1 + p->jf);
+ } else {
+ (void)snprintf(image, sizeof image,
+ "(%03d) %-8s %s",
+ n, op, operand);
+ }
+ return image;
+}
diff --git a/freebsd/contrib/libpcap/etherent.c b/freebsd/contrib/libpcap/etherent.c
new file mode 100644
index 00000000..166eb3a4
--- /dev/null
+++ b/freebsd/contrib/libpcap/etherent.c
@@ -0,0 +1,176 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1990, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/etherent.c,v 1.23 2006-10-04 18:09:22 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <rtems/bsd/sys/types.h>
+#endif /* WIN32 */
+
+#include <ctype.h>
+#include <memory.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "pcap-int.h"
+
+#include <pcap/namedb.h>
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+static inline int xdtoi(int);
+static inline int skip_space(FILE *);
+static inline int skip_line(FILE *);
+
+/* Hex digit to integer. */
+static inline int
+xdtoi(c)
+ register int c;
+{
+ if (isdigit(c))
+ return c - '0';
+ else if (islower(c))
+ return c - 'a' + 10;
+ else
+ return c - 'A' + 10;
+}
+
+static inline int
+skip_space(f)
+ FILE *f;
+{
+ int c;
+
+ do {
+ c = getc(f);
+ } while (isspace(c) && c != '\n');
+
+ return c;
+}
+
+static inline int
+skip_line(f)
+ FILE *f;
+{
+ int c;
+
+ do
+ c = getc(f);
+ while (c != '\n' && c != EOF);
+
+ return c;
+}
+
+struct pcap_etherent *
+pcap_next_etherent(FILE *fp)
+{
+ register int c, d, i;
+ char *bp;
+ static struct pcap_etherent e;
+
+ memset((char *)&e, 0, sizeof(e));
+ do {
+ /* Find addr */
+ c = skip_space(fp);
+ if (c == '\n')
+ continue;
+
+ /* If this is a comment, or first thing on line
+ cannot be etehrnet address, skip the line. */
+ if (!isxdigit(c)) {
+ c = skip_line(fp);
+ continue;
+ }
+
+ /* must be the start of an address */
+ for (i = 0; i < 6; i += 1) {
+ d = xdtoi(c);
+ c = getc(fp);
+ if (isxdigit(c)) {
+ d <<= 4;
+ d |= xdtoi(c);
+ c = getc(fp);
+ }
+ e.addr[i] = d;
+ if (c != ':')
+ break;
+ c = getc(fp);
+ }
+ if (c == EOF)
+ break;
+
+ /* Must be whitespace */
+ if (!isspace(c)) {
+ c = skip_line(fp);
+ continue;
+ }
+ c = skip_space(fp);
+
+ /* hit end of line... */
+ if (c == '\n')
+ continue;
+
+ if (c == '#') {
+ c = skip_line(fp);
+ continue;
+ }
+
+ /* pick up name */
+ bp = e.name;
+ /* Use 'd' to prevent buffer overflow. */
+ d = sizeof(e.name) - 1;
+ do {
+ *bp++ = c;
+ c = getc(fp);
+ } while (!isspace(c) && c != EOF && --d > 0);
+ *bp = '\0';
+
+ /* Eat trailing junk */
+ if (c != '\n')
+ (void)skip_line(fp);
+
+ return &e;
+
+ } while (c != EOF);
+
+ return (NULL);
+}
diff --git a/freebsd/contrib/libpcap/ethertype.h b/freebsd/contrib/libpcap/ethertype.h
new file mode 100644
index 00000000..2d6bbebd
--- /dev/null
+++ b/freebsd/contrib/libpcap/ethertype.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (c) 1993, 1994, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/ethertype.h,v 1.14 2005-09-05 09:06:58 guy Exp $ (LBL)
+ */
+
+/*
+ * Ethernet types.
+ *
+ * We wrap the declarations with #ifdef, so that if a file includes
+ * <netinet/if_ether.h>, which may declare some of these, we don't
+ * get a bunch of complaints from the C compiler about redefinitions
+ * of these values.
+ *
+ * We declare all of them here so that no file has to include
+ * <netinet/if_ether.h> if all it needs are ETHERTYPE_ values.
+ */
+
+#ifndef ETHERTYPE_PUP
+#define ETHERTYPE_PUP 0x0200 /* PUP protocol */
+#endif
+#ifndef ETHERTYPE_IP
+#define ETHERTYPE_IP 0x0800 /* IP protocol */
+#endif
+#ifndef ETHERTYPE_ARP
+#define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */
+#endif
+#ifndef ETHERTYPE_REVARP
+#define ETHERTYPE_REVARP 0x8035 /* reverse Addr. resolution protocol */
+#endif
+#ifndef ETHERTYPE_NS
+#define ETHERTYPE_NS 0x0600
+#endif
+#ifndef ETHERTYPE_SPRITE
+#define ETHERTYPE_SPRITE 0x0500
+#endif
+#ifndef ETHERTYPE_TRAIL
+#define ETHERTYPE_TRAIL 0x1000
+#endif
+#ifndef ETHERTYPE_MOPDL
+#define ETHERTYPE_MOPDL 0x6001
+#endif
+#ifndef ETHERTYPE_MOPRC
+#define ETHERTYPE_MOPRC 0x6002
+#endif
+#ifndef ETHERTYPE_DN
+#define ETHERTYPE_DN 0x6003
+#endif
+#ifndef ETHERTYPE_LAT
+#define ETHERTYPE_LAT 0x6004
+#endif
+#ifndef ETHERTYPE_SCA
+#define ETHERTYPE_SCA 0x6007
+#endif
+#ifndef ETHERTYPE_REVARP
+#define ETHERTYPE_REVARP 0x8035
+#endif
+#ifndef ETHERTYPE_LANBRIDGE
+#define ETHERTYPE_LANBRIDGE 0x8038
+#endif
+#ifndef ETHERTYPE_DECDNS
+#define ETHERTYPE_DECDNS 0x803c
+#endif
+#ifndef ETHERTYPE_DECDTS
+#define ETHERTYPE_DECDTS 0x803e
+#endif
+#ifndef ETHERTYPE_VEXP
+#define ETHERTYPE_VEXP 0x805b
+#endif
+#ifndef ETHERTYPE_VPROD
+#define ETHERTYPE_VPROD 0x805c
+#endif
+#ifndef ETHERTYPE_ATALK
+#define ETHERTYPE_ATALK 0x809b
+#endif
+#ifndef ETHERTYPE_AARP
+#define ETHERTYPE_AARP 0x80f3
+#endif
+#ifndef ETHERTYPE_8021Q
+#define ETHERTYPE_8021Q 0x8100
+#endif
+#ifndef ETHERTYPE_IPX
+#define ETHERTYPE_IPX 0x8137
+#endif
+#ifndef ETHERTYPE_IPV6
+#define ETHERTYPE_IPV6 0x86dd
+#endif
+#ifndef ETHERTYPE_MPLS
+#define ETHERTYPE_MPLS 0x8847
+#endif
+#ifndef ETHERTYPE_MPLS_MULTI
+#define ETHERTYPE_MPLS_MULTI 0x8848
+#endif
+#ifndef ETHERTYPE_PPPOED
+#define ETHERTYPE_PPPOED 0x8863
+#endif
+#ifndef ETHERTYPE_PPPOES
+#define ETHERTYPE_PPPOES 0x8864
+#endif
+#ifndef ETHERTYPE_LOOPBACK
+#define ETHERTYPE_LOOPBACK 0x9000
+#endif
+#ifndef ETHERTYPE_8021QINQ
+#define ETHERTYPE_8021QINQ 0x9100
+#endif
diff --git a/freebsd/contrib/libpcap/fad-getad.c b/freebsd/contrib/libpcap/fad-getad.c
new file mode 100644
index 00000000..2a5b549a
--- /dev/null
+++ b/freebsd/contrib/libpcap/fad-getad.c
@@ -0,0 +1,288 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
+/*
+ * Copyright (c) 1994, 1995, 1996, 1997, 1998
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/fad-getad.c,v 1.12 2007-09-14 00:44:55 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/bsd/sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#include <net/if.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ifaddrs.h>
+
+#include "pcap-int.h"
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#ifdef AF_PACKET
+# ifdef HAVE_NETPACKET_PACKET_H
+/* Solaris 11 and later, Linux distributions with newer glibc */
+# include <netpacket/packet.h>
+# else /* HAVE_NETPACKET_PACKET_H */
+/* LynxOS, Linux distributions with older glibc */
+# ifdef __Lynx__
+/* LynxOS */
+# include <netpacket/if_packet.h>
+# else /* __Lynx__ */
+/* Linux */
+# include <linux/types.h>
+# include <linux/if_packet.h>
+# endif /* __Lynx__ */
+# endif /* HAVE_NETPACKET_PACKET_H */
+#endif /* AF_PACKET */
+
+/*
+ * This is fun.
+ *
+ * In older BSD systems, socket addresses were fixed-length, and
+ * "sizeof (struct sockaddr)" gave the size of the structure.
+ * All addresses fit within a "struct sockaddr".
+ *
+ * In newer BSD systems, the socket address is variable-length, and
+ * there's an "sa_len" field giving the length of the structure;
+ * this allows socket addresses to be longer than 2 bytes of family
+ * and 14 bytes of data.
+ *
+ * Some commercial UNIXes use the old BSD scheme, some use the RFC 2553
+ * variant of the old BSD scheme (with "struct sockaddr_storage" rather
+ * than "struct sockaddr"), and some use the new BSD scheme.
+ *
+ * Some versions of GNU libc use neither scheme, but has an "SA_LEN()"
+ * macro that determines the size based on the address family. Other
+ * versions don't have "SA_LEN()" (as it was in drafts of RFC 2553
+ * but not in the final version). On the latter systems, we explicitly
+ * check the AF_ type to determine the length; we assume that on
+ * all those systems we have "struct sockaddr_storage".
+ */
+#ifndef SA_LEN
+#ifdef HAVE_SOCKADDR_SA_LEN
+#define SA_LEN(addr) ((addr)->sa_len)
+#else /* HAVE_SOCKADDR_SA_LEN */
+#ifdef HAVE_SOCKADDR_STORAGE
+static size_t
+get_sa_len(struct sockaddr *addr)
+{
+ switch (addr->sa_family) {
+
+#ifdef AF_INET
+ case AF_INET:
+ return (sizeof (struct sockaddr_in));
+#endif
+
+#ifdef AF_INET6
+ case AF_INET6:
+ return (sizeof (struct sockaddr_in6));
+#endif
+
+#ifdef AF_PACKET
+ case AF_PACKET:
+ return (sizeof (struct sockaddr_ll));
+#endif
+
+ default:
+ return (sizeof (struct sockaddr));
+ }
+}
+#define SA_LEN(addr) (get_sa_len(addr))
+#else /* HAVE_SOCKADDR_STORAGE */
+#define SA_LEN(addr) (sizeof (struct sockaddr))
+#endif /* HAVE_SOCKADDR_STORAGE */
+#endif /* HAVE_SOCKADDR_SA_LEN */
+#endif /* SA_LEN */
+
+/*
+ * Get a list of all interfaces that are up and that we can open.
+ * Returns -1 on error, 0 otherwise.
+ * The list, as returned through "alldevsp", may be null if no interfaces
+ * were up and could be opened.
+ */
+int
+pcap_findalldevs_interfaces(pcap_if_t **alldevsp, char *errbuf)
+{
+ pcap_if_t *devlist = NULL;
+ struct ifaddrs *ifap, *ifa;
+ struct sockaddr *addr, *netmask, *broadaddr, *dstaddr;
+ size_t addr_size, broadaddr_size, dstaddr_size;
+ int ret = 0;
+ char *p, *q;
+
+ /*
+ * Get the list of interface addresses.
+ *
+ * Note: this won't return information about interfaces
+ * with no addresses; are there any such interfaces
+ * that would be capable of receiving packets?
+ * (Interfaces incapable of receiving packets aren't
+ * very interesting from libpcap's point of view.)
+ *
+ * LAN interfaces will probably have link-layer
+ * addresses; I don't know whether all implementations
+ * of "getifaddrs()" now, or in the future, will return
+ * those.
+ */
+ if (getifaddrs(&ifap) != 0) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "getifaddrs: %s", pcap_strerror(errno));
+ return (-1);
+ }
+ for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
+ /*
+ * Is this interface up?
+ */
+ if (!(ifa->ifa_flags & IFF_UP)) {
+ /*
+ * No, so don't add it to the list.
+ */
+ continue;
+ }
+
+ /*
+ * "ifa_addr" was apparently null on at least one
+ * interface on some system.
+ *
+ * "ifa_broadaddr" may be non-null even on
+ * non-broadcast interfaces, and was null on
+ * at least one OpenBSD 3.4 system on at least
+ * one interface with IFF_BROADCAST set.
+ *
+ * "ifa_dstaddr" was, on at least one FreeBSD 4.1
+ * system, non-null on a non-point-to-point
+ * interface.
+ *
+ * Therefore, we supply the address and netmask only
+ * if "ifa_addr" is non-null (if there's no address,
+ * there's obviously no netmask), and supply the
+ * broadcast and destination addresses if the appropriate
+ * flag is set *and* the appropriate "ifa_" entry doesn't
+ * evaluate to a null pointer.
+ */
+ if (ifa->ifa_addr != NULL) {
+ addr = ifa->ifa_addr;
+ addr_size = SA_LEN(addr);
+ netmask = ifa->ifa_netmask;
+ } else {
+ addr = NULL;
+ addr_size = 0;
+ netmask = NULL;
+ }
+ if (ifa->ifa_flags & IFF_BROADCAST &&
+ ifa->ifa_broadaddr != NULL) {
+ broadaddr = ifa->ifa_broadaddr;
+ broadaddr_size = SA_LEN(broadaddr);
+ } else {
+ broadaddr = NULL;
+ broadaddr_size = 0;
+ }
+ if (ifa->ifa_flags & IFF_POINTOPOINT &&
+ ifa->ifa_dstaddr != NULL) {
+ dstaddr = ifa->ifa_dstaddr;
+ dstaddr_size = SA_LEN(ifa->ifa_dstaddr);
+ } else {
+ dstaddr = NULL;
+ dstaddr_size = 0;
+ }
+
+ /*
+ * If this entry has a colon followed by a number at
+ * the end, we assume it's a logical interface. Those
+ * are just the way you assign multiple IP addresses to
+ * a real interface on Linux, so an entry for a logical
+ * interface should be treated like the entry for the
+ * real interface; we do that by stripping off the ":"
+ * and the number.
+ *
+ * XXX - should we do this only on Linux?
+ */
+ p = strchr(ifa->ifa_name, ':');
+ if (p != NULL) {
+ /*
+ * We have a ":"; is it followed by a number?
+ */
+ q = p + 1;
+ while (isdigit((unsigned char)*q))
+ q++;
+ if (*q == '\0') {
+ /*
+ * All digits after the ":" until the end.
+ * Strip off the ":" and everything after
+ * it.
+ */
+ *p = '\0';
+ }
+ }
+
+ /*
+ * Add information for this address to the list.
+ */
+ if (add_addr_to_iflist(&devlist, ifa->ifa_name,
+ ifa->ifa_flags, addr, addr_size, netmask, addr_size,
+ broadaddr, broadaddr_size, dstaddr, dstaddr_size,
+ errbuf) < 0) {
+ ret = -1;
+ break;
+ }
+ }
+
+ freeifaddrs(ifap);
+
+ if (ret == -1) {
+ /*
+ * We had an error; free the list we've been constructing.
+ */
+ if (devlist != NULL) {
+ pcap_freealldevs(devlist);
+ devlist = NULL;
+ }
+ }
+
+ *alldevsp = devlist;
+ return (ret);
+}
diff --git a/freebsd/contrib/libpcap/gencode.c b/freebsd/contrib/libpcap/gencode.c
new file mode 100644
index 00000000..8bee7904
--- /dev/null
+++ b/freebsd/contrib/libpcap/gencode.c
@@ -0,0 +1,8493 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*#define CHASE_CHAIN*/
+/*
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/gencode.c,v 1.309 2008-12-23 20:13:29 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <rtems/bsd/sys/types.h>
+#include <sys/socket.h>
+#endif /* WIN32 */
+
+/*
+ * XXX - why was this included even on UNIX?
+ */
+#ifdef __MINGW32__
+#include "ip6_misc.h"
+#endif
+
+#ifndef WIN32
+
+#ifdef __NetBSD__
+#include <rtems/bsd/sys/param.h>
+#endif
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#endif /* WIN32 */
+
+#include <stdlib.h>
+#include <string.h>
+#include <memory.h>
+#include <setjmp.h>
+#include <stdarg.h>
+
+#ifdef MSDOS
+#include "pcap-dos.h"
+#endif
+
+#include "pcap-int.h"
+
+#include "ethertype.h"
+#include "nlpid.h"
+#include "llc.h"
+#include "gencode.h"
+#include "ieee80211.h"
+#include "atmuni31.h"
+#include "sunatmpos.h"
+#include "ppp.h"
+#include "pcap/sll.h"
+#include "pcap/ipnet.h"
+#include "arcnet.h"
+#if defined(PF_PACKET) && defined(SO_ATTACH_FILTER)
+#include <linux/types.h>
+#include <linux/if_packet.h>
+#include <linux/filter.h>
+#endif
+#ifdef HAVE_NET_PFVAR_H
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/pfvar.h>
+#include <net/if_pflog.h>
+#endif
+#ifndef offsetof
+#define offsetof(s, e) ((size_t)&((s *)0)->e)
+#endif
+#ifdef INET6
+#ifndef WIN32
+#include <netdb.h> /* for "struct addrinfo" */
+#endif /* WIN32 */
+#endif /*INET6*/
+#include <pcap/namedb.h>
+
+#define ETHERMTU 1500
+
+#ifndef IPPROTO_HOPOPTS
+#define IPPROTO_HOPOPTS 0
+#endif
+#ifndef IPPROTO_ROUTING
+#define IPPROTO_ROUTING 43
+#endif
+#ifndef IPPROTO_FRAGMENT
+#define IPPROTO_FRAGMENT 44
+#endif
+#ifndef IPPROTO_DSTOPTS
+#define IPPROTO_DSTOPTS 60
+#endif
+#ifndef IPPROTO_SCTP
+#define IPPROTO_SCTP 132
+#endif
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#define JMP(c) ((c)|BPF_JMP|BPF_K)
+
+/* Locals */
+static jmp_buf top_ctx;
+static pcap_t *bpf_pcap;
+
+/* Hack for updating VLAN, MPLS, and PPPoE offsets. */
+#ifdef WIN32
+static u_int orig_linktype = (u_int)-1, orig_nl = (u_int)-1, label_stack_depth = (u_int)-1;
+#else
+static u_int orig_linktype = -1U, orig_nl = -1U, label_stack_depth = -1U;
+#endif
+
+/* XXX */
+#ifdef PCAP_FDDIPAD
+static int pcap_fddipad;
+#endif
+
+/* VARARGS */
+void
+bpf_error(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ if (bpf_pcap != NULL)
+ (void)vsnprintf(pcap_geterr(bpf_pcap), PCAP_ERRBUF_SIZE,
+ fmt, ap);
+ va_end(ap);
+ longjmp(top_ctx, 1);
+ /* NOTREACHED */
+}
+
+static void init_linktype(pcap_t *);
+
+static void init_regs(void);
+static int alloc_reg(void);
+static void free_reg(int);
+
+static struct block *root;
+
+/*
+ * Value passed to gen_load_a() to indicate what the offset argument
+ * is relative to.
+ */
+enum e_offrel {
+ OR_PACKET, /* relative to the beginning of the packet */
+ OR_LINK, /* relative to the beginning of the link-layer header */
+ OR_MACPL, /* relative to the end of the MAC-layer header */
+ OR_NET, /* relative to the network-layer header */
+ OR_NET_NOSNAP, /* relative to the network-layer header, with no SNAP header at the link layer */
+ OR_TRAN_IPV4, /* relative to the transport-layer header, with IPv4 network layer */
+ OR_TRAN_IPV6 /* relative to the transport-layer header, with IPv6 network layer */
+};
+
+#ifdef INET6
+/*
+ * As errors are handled by a longjmp, anything allocated must be freed
+ * in the longjmp handler, so it must be reachable from that handler.
+ * One thing that's allocated is the result of pcap_nametoaddrinfo();
+ * it must be freed with freeaddrinfo(). This variable points to any
+ * addrinfo structure that would need to be freed.
+ */
+static struct addrinfo *ai;
+#endif
+
+/*
+ * We divy out chunks of memory rather than call malloc each time so
+ * we don't have to worry about leaking memory. It's probably
+ * not a big deal if all this memory was wasted but if this ever
+ * goes into a library that would probably not be a good idea.
+ *
+ * XXX - this *is* in a library....
+ */
+#define NCHUNKS 16
+#define CHUNK0SIZE 1024
+struct chunk {
+ u_int n_left;
+ void *m;
+};
+
+static struct chunk chunks[NCHUNKS];
+static int cur_chunk;
+
+static void *newchunk(u_int);
+static void freechunks(void);
+static inline struct block *new_block(int);
+static inline struct slist *new_stmt(int);
+static struct block *gen_retblk(int);
+static inline void syntax(void);
+
+static void backpatch(struct block *, struct block *);
+static void merge(struct block *, struct block *);
+static struct block *gen_cmp(enum e_offrel, u_int, u_int, bpf_int32);
+static struct block *gen_cmp_gt(enum e_offrel, u_int, u_int, bpf_int32);
+static struct block *gen_cmp_ge(enum e_offrel, u_int, u_int, bpf_int32);
+static struct block *gen_cmp_lt(enum e_offrel, u_int, u_int, bpf_int32);
+static struct block *gen_cmp_le(enum e_offrel, u_int, u_int, bpf_int32);
+static struct block *gen_mcmp(enum e_offrel, u_int, u_int, bpf_int32,
+ bpf_u_int32);
+static struct block *gen_bcmp(enum e_offrel, u_int, u_int, const u_char *);
+static struct block *gen_ncmp(enum e_offrel, bpf_u_int32, bpf_u_int32,
+ bpf_u_int32, bpf_u_int32, int, bpf_int32);
+static struct slist *gen_load_llrel(u_int, u_int);
+static struct slist *gen_load_macplrel(u_int, u_int);
+static struct slist *gen_load_a(enum e_offrel, u_int, u_int);
+static struct slist *gen_loadx_iphdrlen(void);
+static struct block *gen_uncond(int);
+static inline struct block *gen_true(void);
+static inline struct block *gen_false(void);
+static struct block *gen_ether_linktype(int);
+static struct block *gen_ipnet_linktype(int);
+static struct block *gen_linux_sll_linktype(int);
+static struct slist *gen_load_prism_llprefixlen(void);
+static struct slist *gen_load_avs_llprefixlen(void);
+static struct slist *gen_load_radiotap_llprefixlen(void);
+static struct slist *gen_load_ppi_llprefixlen(void);
+static void insert_compute_vloffsets(struct block *);
+static struct slist *gen_llprefixlen(void);
+static struct slist *gen_off_macpl(void);
+static int ethertype_to_ppptype(int);
+static struct block *gen_linktype(int);
+static struct block *gen_snap(bpf_u_int32, bpf_u_int32);
+static struct block *gen_llc_linktype(int);
+static struct block *gen_hostop(bpf_u_int32, bpf_u_int32, int, int, u_int, u_int);
+#ifdef INET6
+static struct block *gen_hostop6(struct in6_addr *, struct in6_addr *, int, int, u_int, u_int);
+#endif
+static struct block *gen_ahostop(const u_char *, int);
+static struct block *gen_ehostop(const u_char *, int);
+static struct block *gen_fhostop(const u_char *, int);
+static struct block *gen_thostop(const u_char *, int);
+static struct block *gen_wlanhostop(const u_char *, int);
+static struct block *gen_ipfchostop(const u_char *, int);
+static struct block *gen_dnhostop(bpf_u_int32, int);
+static struct block *gen_mpls_linktype(int);
+static struct block *gen_host(bpf_u_int32, bpf_u_int32, int, int, int);
+#ifdef INET6
+static struct block *gen_host6(struct in6_addr *, struct in6_addr *, int, int, int);
+#endif
+#ifndef INET6
+static struct block *gen_gateway(const u_char *, bpf_u_int32 **, int, int);
+#endif
+static struct block *gen_ipfrag(void);
+static struct block *gen_portatom(int, bpf_int32);
+static struct block *gen_portrangeatom(int, bpf_int32, bpf_int32);
+static struct block *gen_portatom6(int, bpf_int32);
+static struct block *gen_portrangeatom6(int, bpf_int32, bpf_int32);
+struct block *gen_portop(int, int, int);
+static struct block *gen_port(int, int, int);
+struct block *gen_portrangeop(int, int, int, int);
+static struct block *gen_portrange(int, int, int, int);
+struct block *gen_portop6(int, int, int);
+static struct block *gen_port6(int, int, int);
+struct block *gen_portrangeop6(int, int, int, int);
+static struct block *gen_portrange6(int, int, int, int);
+static int lookup_proto(const char *, int);
+static struct block *gen_protochain(int, int, int);
+static struct block *gen_proto(int, int, int);
+static struct slist *xfer_to_x(struct arth *);
+static struct slist *xfer_to_a(struct arth *);
+static struct block *gen_mac_multicast(int);
+static struct block *gen_len(int, int);
+static struct block *gen_check_802_11_data_frame(void);
+
+static struct block *gen_ppi_dlt_check(void);
+static struct block *gen_msg_abbrev(int type);
+
+static void *
+newchunk(n)
+ u_int n;
+{
+ struct chunk *cp;
+ int k;
+ size_t size;
+
+#ifndef __NetBSD__
+ /* XXX Round up to nearest long. */
+ n = (n + sizeof(long) - 1) & ~(sizeof(long) - 1);
+#else
+ /* XXX Round up to structure boundary. */
+ n = ALIGN(n);
+#endif
+
+ cp = &chunks[cur_chunk];
+ if (n > cp->n_left) {
+ ++cp, k = ++cur_chunk;
+ if (k >= NCHUNKS)
+ bpf_error("out of memory");
+ size = CHUNK0SIZE << k;
+ cp->m = (void *)malloc(size);
+ if (cp->m == NULL)
+ bpf_error("out of memory");
+ memset((char *)cp->m, 0, size);
+ cp->n_left = size;
+ if (n > size)
+ bpf_error("out of memory");
+ }
+ cp->n_left -= n;
+ return (void *)((char *)cp->m + cp->n_left);
+}
+
+static void
+freechunks()
+{
+ int i;
+
+ cur_chunk = 0;
+ for (i = 0; i < NCHUNKS; ++i)
+ if (chunks[i].m != NULL) {
+ free(chunks[i].m);
+ chunks[i].m = NULL;
+ }
+}
+
+/*
+ * A strdup whose allocations are freed after code generation is over.
+ */
+char *
+sdup(s)
+ register const char *s;
+{
+ int n = strlen(s) + 1;
+ char *cp = newchunk(n);
+
+ strlcpy(cp, s, n);
+ return (cp);
+}
+
+static inline struct block *
+new_block(code)
+ int code;
+{
+ struct block *p;
+
+ p = (struct block *)newchunk(sizeof(*p));
+ p->s.code = code;
+ p->head = p;
+
+ return p;
+}
+
+static inline struct slist *
+new_stmt(code)
+ int code;
+{
+ struct slist *p;
+
+ p = (struct slist *)newchunk(sizeof(*p));
+ p->s.code = code;
+
+ return p;
+}
+
+static struct block *
+gen_retblk(v)
+ int v;
+{
+ struct block *b = new_block(BPF_RET|BPF_K);
+
+ b->s.k = v;
+ return b;
+}
+
+static inline void
+syntax()
+{
+ bpf_error("syntax error in filter expression");
+}
+
+static bpf_u_int32 netmask;
+static int snaplen;
+int no_optimize;
+#ifdef WIN32
+static int
+pcap_compile_unsafe(pcap_t *p, struct bpf_program *program,
+ const char *buf, int optimize, bpf_u_int32 mask);
+
+int
+pcap_compile(pcap_t *p, struct bpf_program *program,
+ const char *buf, int optimize, bpf_u_int32 mask)
+{
+ int result;
+
+ EnterCriticalSection(&g_PcapCompileCriticalSection);
+
+ result = pcap_compile_unsafe(p, program, buf, optimize, mask);
+
+ LeaveCriticalSection(&g_PcapCompileCriticalSection);
+
+ return result;
+}
+
+static int
+pcap_compile_unsafe(pcap_t *p, struct bpf_program *program,
+ const char *buf, int optimize, bpf_u_int32 mask)
+#else /* WIN32 */
+int
+pcap_compile(pcap_t *p, struct bpf_program *program,
+ const char *buf, int optimize, bpf_u_int32 mask)
+#endif /* WIN32 */
+{
+#if __rtems__
+ int n_errors;
+#else
+ extern int n_errors;
+#endif
+ const char * volatile xbuf = buf;
+ u_int len;
+
+ /*
+ * If this pcap_t hasn't been activated, it doesn't have a
+ * link-layer type, so we can't use it.
+ */
+ if (!p->activated) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "not-yet-activated pcap_t passed to pcap_compile");
+ return (-1);
+ }
+ no_optimize = 0;
+ n_errors = 0;
+ root = NULL;
+ bpf_pcap = p;
+ init_regs();
+ if (setjmp(top_ctx)) {
+#ifdef INET6
+ if (ai != NULL) {
+ freeaddrinfo(ai);
+ ai = NULL;
+ }
+#endif
+ lex_cleanup();
+ freechunks();
+ return (-1);
+ }
+
+ netmask = mask;
+
+ snaplen = pcap_snapshot(p);
+ if (snaplen == 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "snaplen of 0 rejects all packets");
+ return -1;
+ }
+
+ lex_init(xbuf ? xbuf : "");
+ init_linktype(p);
+ (void)pcap_parse();
+
+ if (n_errors)
+ syntax();
+
+ if (root == NULL)
+ root = gen_retblk(snaplen);
+
+ if (optimize && !no_optimize) {
+ bpf_optimize(&root);
+ if (root == NULL ||
+ (root->s.code == (BPF_RET|BPF_K) && root->s.k == 0))
+ bpf_error("expression rejects all packets");
+ }
+ program->bf_insns = icode_to_fcode(root, &len);
+ program->bf_len = len;
+
+ lex_cleanup();
+ freechunks();
+ return (0);
+}
+
+/*
+ * entry point for using the compiler with no pcap open
+ * pass in all the stuff that is needed explicitly instead.
+ */
+int
+pcap_compile_nopcap(int snaplen_arg, int linktype_arg,
+ struct bpf_program *program,
+ const char *buf, int optimize, bpf_u_int32 mask)
+{
+ pcap_t *p;
+ int ret;
+
+ p = pcap_open_dead(linktype_arg, snaplen_arg);
+ if (p == NULL)
+ return (-1);
+ ret = pcap_compile(p, program, buf, optimize, mask);
+ pcap_close(p);
+ return (ret);
+}
+
+/*
+ * Clean up a "struct bpf_program" by freeing all the memory allocated
+ * in it.
+ */
+void
+pcap_freecode(struct bpf_program *program)
+{
+ program->bf_len = 0;
+ if (program->bf_insns != NULL) {
+ free((char *)program->bf_insns);
+ program->bf_insns = NULL;
+ }
+}
+
+/*
+ * Backpatch the blocks in 'list' to 'target'. The 'sense' field indicates
+ * which of the jt and jf fields has been resolved and which is a pointer
+ * back to another unresolved block (or nil). At least one of the fields
+ * in each block is already resolved.
+ */
+static void
+backpatch(list, target)
+ struct block *list, *target;
+{
+ struct block *next;
+
+ while (list) {
+ if (!list->sense) {
+ next = JT(list);
+ JT(list) = target;
+ } else {
+ next = JF(list);
+ JF(list) = target;
+ }
+ list = next;
+ }
+}
+
+/*
+ * Merge the lists in b0 and b1, using the 'sense' field to indicate
+ * which of jt and jf is the link.
+ */
+static void
+merge(b0, b1)
+ struct block *b0, *b1;
+{
+ register struct block **p = &b0;
+
+ /* Find end of list. */
+ while (*p)
+ p = !((*p)->sense) ? &JT(*p) : &JF(*p);
+
+ /* Concatenate the lists. */
+ *p = b1;
+}
+
+void
+finish_parse(p)
+ struct block *p;
+{
+ struct block *ppi_dlt_check;
+
+ /*
+ * Insert before the statements of the first (root) block any
+ * statements needed to load the lengths of any variable-length
+ * headers into registers.
+ *
+ * XXX - a fancier strategy would be to insert those before the
+ * statements of all blocks that use those lengths and that
+ * have no predecessors that use them, so that we only compute
+ * the lengths if we need them. There might be even better
+ * approaches than that.
+ *
+ * However, those strategies would be more complicated, and
+ * as we don't generate code to compute a length if the
+ * program has no tests that use the length, and as most
+ * tests will probably use those lengths, we would just
+ * postpone computing the lengths so that it's not done
+ * for tests that fail early, and it's not clear that's
+ * worth the effort.
+ */
+ insert_compute_vloffsets(p->head);
+
+ /*
+ * For DLT_PPI captures, generate a check of the per-packet
+ * DLT value to make sure it's DLT_IEEE802_11.
+ */
+ ppi_dlt_check = gen_ppi_dlt_check();
+ if (ppi_dlt_check != NULL)
+ gen_and(ppi_dlt_check, p);
+
+ backpatch(p, gen_retblk(snaplen));
+ p->sense = !p->sense;
+ backpatch(p, gen_retblk(0));
+ root = p->head;
+}
+
+void
+gen_and(b0, b1)
+ struct block *b0, *b1;
+{
+ backpatch(b0, b1->head);
+ b0->sense = !b0->sense;
+ b1->sense = !b1->sense;
+ merge(b1, b0);
+ b1->sense = !b1->sense;
+ b1->head = b0->head;
+}
+
+void
+gen_or(b0, b1)
+ struct block *b0, *b1;
+{
+ b0->sense = !b0->sense;
+ backpatch(b0, b1->head);
+ b0->sense = !b0->sense;
+ merge(b1, b0);
+ b1->head = b0->head;
+}
+
+void
+gen_not(b)
+ struct block *b;
+{
+ b->sense = !b->sense;
+}
+
+static struct block *
+gen_cmp(offrel, offset, size, v)
+ enum e_offrel offrel;
+ u_int offset, size;
+ bpf_int32 v;
+{
+ return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JEQ, 0, v);
+}
+
+static struct block *
+gen_cmp_gt(offrel, offset, size, v)
+ enum e_offrel offrel;
+ u_int offset, size;
+ bpf_int32 v;
+{
+ return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGT, 0, v);
+}
+
+static struct block *
+gen_cmp_ge(offrel, offset, size, v)
+ enum e_offrel offrel;
+ u_int offset, size;
+ bpf_int32 v;
+{
+ return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGE, 0, v);
+}
+
+static struct block *
+gen_cmp_lt(offrel, offset, size, v)
+ enum e_offrel offrel;
+ u_int offset, size;
+ bpf_int32 v;
+{
+ return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGE, 1, v);
+}
+
+static struct block *
+gen_cmp_le(offrel, offset, size, v)
+ enum e_offrel offrel;
+ u_int offset, size;
+ bpf_int32 v;
+{
+ return gen_ncmp(offrel, offset, size, 0xffffffff, BPF_JGT, 1, v);
+}
+
+static struct block *
+gen_mcmp(offrel, offset, size, v, mask)
+ enum e_offrel offrel;
+ u_int offset, size;
+ bpf_int32 v;
+ bpf_u_int32 mask;
+{
+ return gen_ncmp(offrel, offset, size, mask, BPF_JEQ, 0, v);
+}
+
+static struct block *
+gen_bcmp(offrel, offset, size, v)
+ enum e_offrel offrel;
+ register u_int offset, size;
+ register const u_char *v;
+{
+ register struct block *b, *tmp;
+
+ b = NULL;
+ while (size >= 4) {
+ register const u_char *p = &v[size - 4];
+ bpf_int32 w = ((bpf_int32)p[0] << 24) |
+ ((bpf_int32)p[1] << 16) | ((bpf_int32)p[2] << 8) | p[3];
+
+ tmp = gen_cmp(offrel, offset + size - 4, BPF_W, w);
+ if (b != NULL)
+ gen_and(b, tmp);
+ b = tmp;
+ size -= 4;
+ }
+ while (size >= 2) {
+ register const u_char *p = &v[size - 2];
+ bpf_int32 w = ((bpf_int32)p[0] << 8) | p[1];
+
+ tmp = gen_cmp(offrel, offset + size - 2, BPF_H, w);
+ if (b != NULL)
+ gen_and(b, tmp);
+ b = tmp;
+ size -= 2;
+ }
+ if (size > 0) {
+ tmp = gen_cmp(offrel, offset, BPF_B, (bpf_int32)v[0]);
+ if (b != NULL)
+ gen_and(b, tmp);
+ b = tmp;
+ }
+ return b;
+}
+
+/*
+ * AND the field of size "size" at offset "offset" relative to the header
+ * specified by "offrel" with "mask", and compare it with the value "v"
+ * with the test specified by "jtype"; if "reverse" is true, the test
+ * should test the opposite of "jtype".
+ */
+static struct block *
+gen_ncmp(offrel, offset, size, mask, jtype, reverse, v)
+ enum e_offrel offrel;
+ bpf_int32 v;
+ bpf_u_int32 offset, size, mask, jtype;
+ int reverse;
+{
+ struct slist *s, *s2;
+ struct block *b;
+
+ s = gen_load_a(offrel, offset, size);
+
+ if (mask != 0xffffffff) {
+ s2 = new_stmt(BPF_ALU|BPF_AND|BPF_K);
+ s2->s.k = mask;
+ sappend(s, s2);
+ }
+
+ b = new_block(JMP(jtype));
+ b->stmts = s;
+ b->s.k = v;
+ if (reverse && (jtype == BPF_JGT || jtype == BPF_JGE))
+ gen_not(b);
+ return b;
+}
+
+/*
+ * Various code constructs need to know the layout of the data link
+ * layer. These variables give the necessary offsets from the beginning
+ * of the packet data.
+ */
+
+/*
+ * This is the offset of the beginning of the link-layer header from
+ * the beginning of the raw packet data.
+ *
+ * It's usually 0, except for 802.11 with a fixed-length radio header.
+ * (For 802.11 with a variable-length radio header, we have to generate
+ * code to compute that offset; off_ll is 0 in that case.)
+ */
+static u_int off_ll;
+
+/*
+ * If there's a variable-length header preceding the link-layer header,
+ * "reg_off_ll" is the register number for a register containing the
+ * length of that header, and therefore the offset of the link-layer
+ * header from the beginning of the raw packet data. Otherwise,
+ * "reg_off_ll" is -1.
+ */
+static int reg_off_ll;
+
+/*
+ * This is the offset of the beginning of the MAC-layer header from
+ * the beginning of the link-layer header.
+ * It's usually 0, except for ATM LANE, where it's the offset, relative
+ * to the beginning of the raw packet data, of the Ethernet header, and
+ * for Ethernet with various additional information.
+ */
+static u_int off_mac;
+
+/*
+ * This is the offset of the beginning of the MAC-layer payload,
+ * from the beginning of the raw packet data.
+ *
+ * I.e., it's the sum of the length of the link-layer header (without,
+ * for example, any 802.2 LLC header, so it's the MAC-layer
+ * portion of that header), plus any prefix preceding the
+ * link-layer header.
+ */
+static u_int off_macpl;
+
+/*
+ * This is 1 if the offset of the beginning of the MAC-layer payload
+ * from the beginning of the link-layer header is variable-length.
+ */
+static int off_macpl_is_variable;
+
+/*
+ * If the link layer has variable_length headers, "reg_off_macpl"
+ * is the register number for a register containing the length of the
+ * link-layer header plus the length of any variable-length header
+ * preceding the link-layer header. Otherwise, "reg_off_macpl"
+ * is -1.
+ */
+static int reg_off_macpl;
+
+/*
+ * "off_linktype" is the offset to information in the link-layer header
+ * giving the packet type. This offset is relative to the beginning
+ * of the link-layer header (i.e., it doesn't include off_ll).
+ *
+ * For Ethernet, it's the offset of the Ethernet type field.
+ *
+ * For link-layer types that always use 802.2 headers, it's the
+ * offset of the LLC header.
+ *
+ * For PPP, it's the offset of the PPP type field.
+ *
+ * For Cisco HDLC, it's the offset of the CHDLC type field.
+ *
+ * For BSD loopback, it's the offset of the AF_ value.
+ *
+ * For Linux cooked sockets, it's the offset of the type field.
+ *
+ * It's set to -1 for no encapsulation, in which case, IP is assumed.
+ */
+static u_int off_linktype;
+
+/*
+ * TRUE if "pppoes" appeared in the filter; it causes link-layer type
+ * checks to check the PPP header, assumed to follow a LAN-style link-
+ * layer header and a PPPoE session header.
+ */
+static int is_pppoes = 0;
+
+/*
+ * TRUE if the link layer includes an ATM pseudo-header.
+ */
+static int is_atm = 0;
+
+/*
+ * TRUE if "lane" appeared in the filter; it causes us to generate
+ * code that assumes LANE rather than LLC-encapsulated traffic in SunATM.
+ */
+static int is_lane = 0;
+
+/*
+ * These are offsets for the ATM pseudo-header.
+ */
+static u_int off_vpi;
+static u_int off_vci;
+static u_int off_proto;
+
+/*
+ * These are offsets for the MTP2 fields.
+ */
+static u_int off_li;
+
+/*
+ * These are offsets for the MTP3 fields.
+ */
+static u_int off_sio;
+static u_int off_opc;
+static u_int off_dpc;
+static u_int off_sls;
+
+/*
+ * This is the offset of the first byte after the ATM pseudo_header,
+ * or -1 if there is no ATM pseudo-header.
+ */
+static u_int off_payload;
+
+/*
+ * These are offsets to the beginning of the network-layer header.
+ * They are relative to the beginning of the MAC-layer payload (i.e.,
+ * they don't include off_ll or off_macpl).
+ *
+ * If the link layer never uses 802.2 LLC:
+ *
+ * "off_nl" and "off_nl_nosnap" are the same.
+ *
+ * If the link layer always uses 802.2 LLC:
+ *
+ * "off_nl" is the offset if there's a SNAP header following
+ * the 802.2 header;
+ *
+ * "off_nl_nosnap" is the offset if there's no SNAP header.
+ *
+ * If the link layer is Ethernet:
+ *
+ * "off_nl" is the offset if the packet is an Ethernet II packet
+ * (we assume no 802.3+802.2+SNAP);
+ *
+ * "off_nl_nosnap" is the offset if the packet is an 802.3 packet
+ * with an 802.2 header following it.
+ */
+static u_int off_nl;
+static u_int off_nl_nosnap;
+
+static int linktype;
+
+static void
+init_linktype(p)
+ pcap_t *p;
+{
+ linktype = pcap_datalink(p);
+#ifdef PCAP_FDDIPAD
+ pcap_fddipad = p->fddipad;
+#endif
+
+ /*
+ * Assume it's not raw ATM with a pseudo-header, for now.
+ */
+ off_mac = 0;
+ is_atm = 0;
+ is_lane = 0;
+ off_vpi = -1;
+ off_vci = -1;
+ off_proto = -1;
+ off_payload = -1;
+
+ /*
+ * And that we're not doing PPPoE.
+ */
+ is_pppoes = 0;
+
+ /*
+ * And assume we're not doing SS7.
+ */
+ off_li = -1;
+ off_sio = -1;
+ off_opc = -1;
+ off_dpc = -1;
+ off_sls = -1;
+
+ /*
+ * Also assume it's not 802.11.
+ */
+ off_ll = 0;
+ off_macpl = 0;
+ off_macpl_is_variable = 0;
+
+ orig_linktype = -1;
+ orig_nl = -1;
+ label_stack_depth = 0;
+
+ reg_off_ll = -1;
+ reg_off_macpl = -1;
+
+ switch (linktype) {
+
+ case DLT_ARCNET:
+ off_linktype = 2;
+ off_macpl = 6;
+ off_nl = 0; /* XXX in reality, variable! */
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_ARCNET_LINUX:
+ off_linktype = 4;
+ off_macpl = 8;
+ off_nl = 0; /* XXX in reality, variable! */
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_EN10MB:
+ off_linktype = 12;
+ off_macpl = 14; /* Ethernet header length */
+ off_nl = 0; /* Ethernet II */
+ off_nl_nosnap = 3; /* 802.3+802.2 */
+ return;
+
+ case DLT_SLIP:
+ /*
+ * SLIP doesn't have a link level type. The 16 byte
+ * header is hacked into our SLIP driver.
+ */
+ off_linktype = -1;
+ off_macpl = 16;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_SLIP_BSDOS:
+ /* XXX this may be the same as the DLT_PPP_BSDOS case */
+ off_linktype = -1;
+ /* XXX end */
+ off_macpl = 24;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_NULL:
+ case DLT_LOOP:
+ off_linktype = 0;
+ off_macpl = 4;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_ENC:
+ off_linktype = 0;
+ off_macpl = 12;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_PPP:
+ case DLT_PPP_PPPD:
+ case DLT_C_HDLC: /* BSD/OS Cisco HDLC */
+ case DLT_PPP_SERIAL: /* NetBSD sync/async serial PPP */
+ off_linktype = 2;
+ off_macpl = 4;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_PPP_ETHER:
+ /*
+ * This does no include the Ethernet header, and
+ * only covers session state.
+ */
+ off_linktype = 6;
+ off_macpl = 8;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_PPP_BSDOS:
+ off_linktype = 5;
+ off_macpl = 24;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_FDDI:
+ /*
+ * FDDI doesn't really have a link-level type field.
+ * We set "off_linktype" to the offset of the LLC header.
+ *
+ * To check for Ethernet types, we assume that SSAP = SNAP
+ * is being used and pick out the encapsulated Ethernet type.
+ * XXX - should we generate code to check for SNAP?
+ */
+ off_linktype = 13;
+#ifdef PCAP_FDDIPAD
+ off_linktype += pcap_fddipad;
+#endif
+ off_macpl = 13; /* FDDI MAC header length */
+#ifdef PCAP_FDDIPAD
+ off_macpl += pcap_fddipad;
+#endif
+ off_nl = 8; /* 802.2+SNAP */
+ off_nl_nosnap = 3; /* 802.2 */
+ return;
+
+ case DLT_IEEE802:
+ /*
+ * Token Ring doesn't really have a link-level type field.
+ * We set "off_linktype" to the offset of the LLC header.
+ *
+ * To check for Ethernet types, we assume that SSAP = SNAP
+ * is being used and pick out the encapsulated Ethernet type.
+ * XXX - should we generate code to check for SNAP?
+ *
+ * XXX - the header is actually variable-length.
+ * Some various Linux patched versions gave 38
+ * as "off_linktype" and 40 as "off_nl"; however,
+ * if a token ring packet has *no* routing
+ * information, i.e. is not source-routed, the correct
+ * values are 20 and 22, as they are in the vanilla code.
+ *
+ * A packet is source-routed iff the uppermost bit
+ * of the first byte of the source address, at an
+ * offset of 8, has the uppermost bit set. If the
+ * packet is source-routed, the total number of bytes
+ * of routing information is 2 plus bits 0x1F00 of
+ * the 16-bit value at an offset of 14 (shifted right
+ * 8 - figure out which byte that is).
+ */
+ off_linktype = 14;
+ off_macpl = 14; /* Token Ring MAC header length */
+ off_nl = 8; /* 802.2+SNAP */
+ off_nl_nosnap = 3; /* 802.2 */
+ return;
+
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ case DLT_IEEE802_11_RADIO:
+ /*
+ * 802.11 doesn't really have a link-level type field.
+ * We set "off_linktype" to the offset of the LLC header.
+ *
+ * To check for Ethernet types, we assume that SSAP = SNAP
+ * is being used and pick out the encapsulated Ethernet type.
+ * XXX - should we generate code to check for SNAP?
+ *
+ * We also handle variable-length radio headers here.
+ * The Prism header is in theory variable-length, but in
+ * practice it's always 144 bytes long. However, some
+ * drivers on Linux use ARPHRD_IEEE80211_PRISM, but
+ * sometimes or always supply an AVS header, so we
+ * have to check whether the radio header is a Prism
+ * header or an AVS header, so, in practice, it's
+ * variable-length.
+ */
+ off_linktype = 24;
+ off_macpl = 0; /* link-layer header is variable-length */
+ off_macpl_is_variable = 1;
+ off_nl = 8; /* 802.2+SNAP */
+ off_nl_nosnap = 3; /* 802.2 */
+ return;
+
+ case DLT_PPI:
+ /*
+ * At the moment we treat PPI the same way that we treat
+ * normal Radiotap encoded packets. The difference is in
+ * the function that generates the code at the beginning
+ * to compute the header length. Since this code generator
+ * of PPI supports bare 802.11 encapsulation only (i.e.
+ * the encapsulated DLT should be DLT_IEEE802_11) we
+ * generate code to check for this too.
+ */
+ off_linktype = 24;
+ off_macpl = 0; /* link-layer header is variable-length */
+ off_macpl_is_variable = 1;
+ off_nl = 8; /* 802.2+SNAP */
+ off_nl_nosnap = 3; /* 802.2 */
+ return;
+
+ case DLT_ATM_RFC1483:
+ case DLT_ATM_CLIP: /* Linux ATM defines this */
+ /*
+ * assume routed, non-ISO PDUs
+ * (i.e., LLC = 0xAA-AA-03, OUT = 0x00-00-00)
+ *
+ * XXX - what about ISO PDUs, e.g. CLNP, ISIS, ESIS,
+ * or PPP with the PPP NLPID (e.g., PPPoA)? The
+ * latter would presumably be treated the way PPPoE
+ * should be, so you can do "pppoe and udp port 2049"
+ * or "pppoa and tcp port 80" and have it check for
+ * PPPo{A,E} and a PPP protocol of IP and....
+ */
+ off_linktype = 0;
+ off_macpl = 0; /* packet begins with LLC header */
+ off_nl = 8; /* 802.2+SNAP */
+ off_nl_nosnap = 3; /* 802.2 */
+ return;
+
+ case DLT_SUNATM:
+ /*
+ * Full Frontal ATM; you get AALn PDUs with an ATM
+ * pseudo-header.
+ */
+ is_atm = 1;
+ off_vpi = SUNATM_VPI_POS;
+ off_vci = SUNATM_VCI_POS;
+ off_proto = PROTO_POS;
+ off_mac = -1; /* assume LLC-encapsulated, so no MAC-layer header */
+ off_payload = SUNATM_PKT_BEGIN_POS;
+ off_linktype = off_payload;
+ off_macpl = off_payload; /* if LLC-encapsulated */
+ off_nl = 8; /* 802.2+SNAP */
+ off_nl_nosnap = 3; /* 802.2 */
+ return;
+
+ case DLT_RAW:
+ case DLT_IPV4:
+ case DLT_IPV6:
+ off_linktype = -1;
+ off_macpl = 0;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_LINUX_SLL: /* fake header for Linux cooked socket */
+ off_linktype = 14;
+ off_macpl = 16;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_LTALK:
+ /*
+ * LocalTalk does have a 1-byte type field in the LLAP header,
+ * but really it just indicates whether there is a "short" or
+ * "long" DDP packet following.
+ */
+ off_linktype = -1;
+ off_macpl = 0;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_IP_OVER_FC:
+ /*
+ * RFC 2625 IP-over-Fibre-Channel doesn't really have a
+ * link-level type field. We set "off_linktype" to the
+ * offset of the LLC header.
+ *
+ * To check for Ethernet types, we assume that SSAP = SNAP
+ * is being used and pick out the encapsulated Ethernet type.
+ * XXX - should we generate code to check for SNAP? RFC
+ * 2625 says SNAP should be used.
+ */
+ off_linktype = 16;
+ off_macpl = 16;
+ off_nl = 8; /* 802.2+SNAP */
+ off_nl_nosnap = 3; /* 802.2 */
+ return;
+
+ case DLT_FRELAY:
+ /*
+ * XXX - we should set this to handle SNAP-encapsulated
+ * frames (NLPID of 0x80).
+ */
+ off_linktype = -1;
+ off_macpl = 0;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ /*
+ * the only BPF-interesting FRF.16 frames are non-control frames;
+ * Frame Relay has a variable length link-layer
+ * so lets start with offset 4 for now and increments later on (FIXME);
+ */
+ case DLT_MFR:
+ off_linktype = -1;
+ off_macpl = 0;
+ off_nl = 4;
+ off_nl_nosnap = 0; /* XXX - for now -> no 802.2 LLC */
+ return;
+
+ case DLT_APPLE_IP_OVER_IEEE1394:
+ off_linktype = 16;
+ off_macpl = 18;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+
+ case DLT_SYMANTEC_FIREWALL:
+ off_linktype = 6;
+ off_macpl = 44;
+ off_nl = 0; /* Ethernet II */
+ off_nl_nosnap = 0; /* XXX - what does it do with 802.3 packets? */
+ return;
+
+#ifdef HAVE_NET_PFVAR_H
+ case DLT_PFLOG:
+ off_linktype = 0;
+ off_macpl = PFLOG_HDRLEN;
+ off_nl = 0;
+ off_nl_nosnap = 0; /* no 802.2 LLC */
+ return;
+#endif
+
+ case DLT_JUNIPER_MFR:
+ case DLT_JUNIPER_MLFR:
+ case DLT_JUNIPER_MLPPP:
+ case DLT_JUNIPER_PPP:
+ case DLT_JUNIPER_CHDLC:
+ case DLT_JUNIPER_FRELAY:
+ off_linktype = 4;
+ off_macpl = 4;
+ off_nl = 0;
+ off_nl_nosnap = -1; /* no 802.2 LLC */
+ return;
+
+ case DLT_JUNIPER_ATM1:
+ off_linktype = 4; /* in reality variable between 4-8 */
+ off_macpl = 4; /* in reality variable between 4-8 */
+ off_nl = 0;
+ off_nl_nosnap = 10;
+ return;
+
+ case DLT_JUNIPER_ATM2:
+ off_linktype = 8; /* in reality variable between 8-12 */
+ off_macpl = 8; /* in reality variable between 8-12 */
+ off_nl = 0;
+ off_nl_nosnap = 10;
+ return;
+
+ /* frames captured on a Juniper PPPoE service PIC
+ * contain raw ethernet frames */
+ case DLT_JUNIPER_PPPOE:
+ case DLT_JUNIPER_ETHER:
+ off_macpl = 14;
+ off_linktype = 16;
+ off_nl = 18; /* Ethernet II */
+ off_nl_nosnap = 21; /* 802.3+802.2 */
+ return;
+
+ case DLT_JUNIPER_PPPOE_ATM:
+ off_linktype = 4;
+ off_macpl = 6;
+ off_nl = 0;
+ off_nl_nosnap = -1; /* no 802.2 LLC */
+ return;
+
+ case DLT_JUNIPER_GGSN:
+ off_linktype = 6;
+ off_macpl = 12;
+ off_nl = 0;
+ off_nl_nosnap = -1; /* no 802.2 LLC */
+ return;
+
+ case DLT_JUNIPER_ES:
+ off_linktype = 6;
+ off_macpl = -1; /* not really a network layer but raw IP addresses */
+ off_nl = -1; /* not really a network layer but raw IP addresses */
+ off_nl_nosnap = -1; /* no 802.2 LLC */
+ return;
+
+ case DLT_JUNIPER_MONITOR:
+ off_linktype = 12;
+ off_macpl = 12;
+ off_nl = 0; /* raw IP/IP6 header */
+ off_nl_nosnap = -1; /* no 802.2 LLC */
+ return;
+
+ case DLT_JUNIPER_SERVICES:
+ off_linktype = 12;
+ off_macpl = -1; /* L3 proto location dep. on cookie type */
+ off_nl = -1; /* L3 proto location dep. on cookie type */
+ off_nl_nosnap = -1; /* no 802.2 LLC */
+ return;
+
+ case DLT_JUNIPER_VP:
+ off_linktype = 18;
+ off_macpl = -1;
+ off_nl = -1;
+ off_nl_nosnap = -1;
+ return;
+
+ case DLT_JUNIPER_ST:
+ off_linktype = 18;
+ off_macpl = -1;
+ off_nl = -1;
+ off_nl_nosnap = -1;
+ return;
+
+ case DLT_JUNIPER_ISM:
+ off_linktype = 8;
+ off_macpl = -1;
+ off_nl = -1;
+ off_nl_nosnap = -1;
+ return;
+
+ case DLT_JUNIPER_VS:
+ case DLT_JUNIPER_SRX_E2E:
+ case DLT_JUNIPER_FIBRECHANNEL:
+ case DLT_JUNIPER_ATM_CEMIC:
+ off_linktype = 8;
+ off_macpl = -1;
+ off_nl = -1;
+ off_nl_nosnap = -1;
+ return;
+
+ case DLT_MTP2:
+ off_li = 2;
+ off_sio = 3;
+ off_opc = 4;
+ off_dpc = 4;
+ off_sls = 7;
+ off_linktype = -1;
+ off_macpl = -1;
+ off_nl = -1;
+ off_nl_nosnap = -1;
+ return;
+
+ case DLT_MTP2_WITH_PHDR:
+ off_li = 6;
+ off_sio = 7;
+ off_opc = 8;
+ off_dpc = 8;
+ off_sls = 11;
+ off_linktype = -1;
+ off_macpl = -1;
+ off_nl = -1;
+ off_nl_nosnap = -1;
+ return;
+
+ case DLT_ERF:
+ off_li = 22;
+ off_sio = 23;
+ off_opc = 24;
+ off_dpc = 24;
+ off_sls = 27;
+ off_linktype = -1;
+ off_macpl = -1;
+ off_nl = -1;
+ off_nl_nosnap = -1;
+ return;
+
+ case DLT_PFSYNC:
+ off_linktype = -1;
+ off_macpl = 4;
+ off_nl = 0;
+ off_nl_nosnap = 0;
+ return;
+
+ case DLT_AX25_KISS:
+ /*
+ * Currently, only raw "link[N:M]" filtering is supported.
+ */
+ off_linktype = -1; /* variable, min 15, max 71 steps of 7 */
+ off_macpl = -1;
+ off_nl = -1; /* variable, min 16, max 71 steps of 7 */
+ off_nl_nosnap = -1; /* no 802.2 LLC */
+ off_mac = 1; /* step over the kiss length byte */
+ return;
+
+ case DLT_IPNET:
+ off_linktype = 1;
+ off_macpl = 24; /* ipnet header length */
+ off_nl = 0;
+ off_nl_nosnap = -1;
+ return;
+
+ case DLT_NETANALYZER:
+ off_mac = 4; /* MAC header is past 4-byte pseudo-header */
+ off_linktype = 16; /* includes 4-byte pseudo-header */
+ off_macpl = 18; /* pseudo-header+Ethernet header length */
+ off_nl = 0; /* Ethernet II */
+ off_nl_nosnap = 3; /* 802.3+802.2 */
+ return;
+
+ case DLT_NETANALYZER_TRANSPARENT:
+ off_mac = 12; /* MAC header is past 4-byte pseudo-header, preamble, and SFD */
+ off_linktype = 24; /* includes 4-byte pseudo-header+preamble+SFD */
+ off_macpl = 26; /* pseudo-header+preamble+SFD+Ethernet header length */
+ off_nl = 0; /* Ethernet II */
+ off_nl_nosnap = 3; /* 802.3+802.2 */
+ return;
+
+ default:
+ /*
+ * For values in the range in which we've assigned new
+ * DLT_ values, only raw "link[N:M]" filtering is supported.
+ */
+ if (linktype >= DLT_MATCHING_MIN &&
+ linktype <= DLT_MATCHING_MAX) {
+ off_linktype = -1;
+ off_macpl = -1;
+ off_nl = -1;
+ off_nl_nosnap = -1;
+ return;
+ }
+
+ }
+ bpf_error("unknown data link type %d", linktype);
+ /* NOTREACHED */
+}
+
+/*
+ * Load a value relative to the beginning of the link-layer header.
+ * The link-layer header doesn't necessarily begin at the beginning
+ * of the packet data; there might be a variable-length prefix containing
+ * radio information.
+ */
+static struct slist *
+gen_load_llrel(offset, size)
+ u_int offset, size;
+{
+ struct slist *s, *s2;
+
+ s = gen_llprefixlen();
+
+ /*
+ * If "s" is non-null, it has code to arrange that the X register
+ * contains the length of the prefix preceding the link-layer
+ * header.
+ *
+ * Otherwise, the length of the prefix preceding the link-layer
+ * header is "off_ll".
+ */
+ if (s != NULL) {
+ /*
+ * There's a variable-length prefix preceding the
+ * link-layer header. "s" points to a list of statements
+ * that put the length of that prefix into the X register.
+ * do an indirect load, to use the X register as an offset.
+ */
+ s2 = new_stmt(BPF_LD|BPF_IND|size);
+ s2->s.k = offset;
+ sappend(s, s2);
+ } else {
+ /*
+ * There is no variable-length header preceding the
+ * link-layer header; add in off_ll, which, if there's
+ * a fixed-length header preceding the link-layer header,
+ * is the length of that header.
+ */
+ s = new_stmt(BPF_LD|BPF_ABS|size);
+ s->s.k = offset + off_ll;
+ }
+ return s;
+}
+
+/*
+ * Load a value relative to the beginning of the MAC-layer payload.
+ */
+static struct slist *
+gen_load_macplrel(offset, size)
+ u_int offset, size;
+{
+ struct slist *s, *s2;
+
+ s = gen_off_macpl();
+
+ /*
+ * If s is non-null, the offset of the MAC-layer payload is
+ * variable, and s points to a list of instructions that
+ * arrange that the X register contains that offset.
+ *
+ * Otherwise, the offset of the MAC-layer payload is constant,
+ * and is in off_macpl.
+ */
+ if (s != NULL) {
+ /*
+ * The offset of the MAC-layer payload is in the X
+ * register. Do an indirect load, to use the X register
+ * as an offset.
+ */
+ s2 = new_stmt(BPF_LD|BPF_IND|size);
+ s2->s.k = offset;
+ sappend(s, s2);
+ } else {
+ /*
+ * The offset of the MAC-layer payload is constant,
+ * and is in off_macpl; load the value at that offset
+ * plus the specified offset.
+ */
+ s = new_stmt(BPF_LD|BPF_ABS|size);
+ s->s.k = off_macpl + offset;
+ }
+ return s;
+}
+
+/*
+ * Load a value relative to the beginning of the specified header.
+ */
+static struct slist *
+gen_load_a(offrel, offset, size)
+ enum e_offrel offrel;
+ u_int offset, size;
+{
+ struct slist *s, *s2;
+
+ switch (offrel) {
+
+ case OR_PACKET:
+ s = new_stmt(BPF_LD|BPF_ABS|size);
+ s->s.k = offset;
+ break;
+
+ case OR_LINK:
+ s = gen_load_llrel(offset, size);
+ break;
+
+ case OR_MACPL:
+ s = gen_load_macplrel(offset, size);
+ break;
+
+ case OR_NET:
+ s = gen_load_macplrel(off_nl + offset, size);
+ break;
+
+ case OR_NET_NOSNAP:
+ s = gen_load_macplrel(off_nl_nosnap + offset, size);
+ break;
+
+ case OR_TRAN_IPV4:
+ /*
+ * Load the X register with the length of the IPv4 header
+ * (plus the offset of the link-layer header, if it's
+ * preceded by a variable-length header such as a radio
+ * header), in bytes.
+ */
+ s = gen_loadx_iphdrlen();
+
+ /*
+ * Load the item at {offset of the MAC-layer payload} +
+ * {offset, relative to the start of the MAC-layer
+ * paylod, of the IPv4 header} + {length of the IPv4 header} +
+ * {specified offset}.
+ *
+ * (If the offset of the MAC-layer payload is variable,
+ * it's included in the value in the X register, and
+ * off_macpl is 0.)
+ */
+ s2 = new_stmt(BPF_LD|BPF_IND|size);
+ s2->s.k = off_macpl + off_nl + offset;
+ sappend(s, s2);
+ break;
+
+ case OR_TRAN_IPV6:
+ s = gen_load_macplrel(off_nl + 40 + offset, size);
+ break;
+
+ default:
+ abort();
+ return NULL;
+ }
+ return s;
+}
+
+/*
+ * Generate code to load into the X register the sum of the length of
+ * the IPv4 header and any variable-length header preceding the link-layer
+ * header.
+ */
+static struct slist *
+gen_loadx_iphdrlen()
+{
+ struct slist *s, *s2;
+
+ s = gen_off_macpl();
+ if (s != NULL) {
+ /*
+ * There's a variable-length prefix preceding the
+ * link-layer header, or the link-layer header is itself
+ * variable-length. "s" points to a list of statements
+ * that put the offset of the MAC-layer payload into
+ * the X register.
+ *
+ * The 4*([k]&0xf) addressing mode can't be used, as we
+ * don't have a constant offset, so we have to load the
+ * value in question into the A register and add to it
+ * the value from the X register.
+ */
+ s2 = new_stmt(BPF_LD|BPF_IND|BPF_B);
+ s2->s.k = off_nl;
+ sappend(s, s2);
+ s2 = new_stmt(BPF_ALU|BPF_AND|BPF_K);
+ s2->s.k = 0xf;
+ sappend(s, s2);
+ s2 = new_stmt(BPF_ALU|BPF_LSH|BPF_K);
+ s2->s.k = 2;
+ sappend(s, s2);
+
+ /*
+ * The A register now contains the length of the
+ * IP header. We need to add to it the offset of
+ * the MAC-layer payload, which is still in the X
+ * register, and move the result into the X register.
+ */
+ sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X));
+ sappend(s, new_stmt(BPF_MISC|BPF_TAX));
+ } else {
+ /*
+ * There is no variable-length header preceding the
+ * link-layer header, and the link-layer header is
+ * fixed-length; load the length of the IPv4 header,
+ * which is at an offset of off_nl from the beginning
+ * of the MAC-layer payload, and thus at an offset
+ * of off_mac_pl + off_nl from the beginning of the
+ * raw packet data.
+ */
+ s = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
+ s->s.k = off_macpl + off_nl;
+ }
+ return s;
+}
+
+static struct block *
+gen_uncond(rsense)
+ int rsense;
+{
+ struct block *b;
+ struct slist *s;
+
+ s = new_stmt(BPF_LD|BPF_IMM);
+ s->s.k = !rsense;
+ b = new_block(JMP(BPF_JEQ));
+ b->stmts = s;
+
+ return b;
+}
+
+static inline struct block *
+gen_true()
+{
+ return gen_uncond(1);
+}
+
+static inline struct block *
+gen_false()
+{
+ return gen_uncond(0);
+}
+
+/*
+ * Byte-swap a 32-bit number.
+ * ("htonl()" or "ntohl()" won't work - we want to byte-swap even on
+ * big-endian platforms.)
+ */
+#define SWAPLONG(y) \
+((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
+
+/*
+ * Generate code to match a particular packet type.
+ *
+ * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP
+ * value, if <= ETHERMTU. We use that to determine whether to
+ * match the type/length field or to check the type/length field for
+ * a value <= ETHERMTU to see whether it's a type field and then do
+ * the appropriate test.
+ */
+static struct block *
+gen_ether_linktype(proto)
+ register int proto;
+{
+ struct block *b0, *b1;
+
+ switch (proto) {
+
+ case LLCSAP_ISONS:
+ case LLCSAP_IP:
+ case LLCSAP_NETBEUI:
+ /*
+ * OSI protocols and NetBEUI always use 802.2 encapsulation,
+ * so we check the DSAP and SSAP.
+ *
+ * LLCSAP_IP checks for IP-over-802.2, rather
+ * than IP-over-Ethernet or IP-over-SNAP.
+ *
+ * XXX - should we check both the DSAP and the
+ * SSAP, like this, or should we check just the
+ * DSAP, as we do for other types <= ETHERMTU
+ * (i.e., other SAP values)?
+ */
+ b0 = gen_cmp_gt(OR_LINK, off_linktype, BPF_H, ETHERMTU);
+ gen_not(b0);
+ b1 = gen_cmp(OR_MACPL, 0, BPF_H, (bpf_int32)
+ ((proto << 8) | proto));
+ gen_and(b0, b1);
+ return b1;
+
+ case LLCSAP_IPX:
+ /*
+ * Check for;
+ *
+ * Ethernet_II frames, which are Ethernet
+ * frames with a frame type of ETHERTYPE_IPX;
+ *
+ * Ethernet_802.3 frames, which are 802.3
+ * frames (i.e., the type/length field is
+ * a length field, <= ETHERMTU, rather than
+ * a type field) with the first two bytes
+ * after the Ethernet/802.3 header being
+ * 0xFFFF;
+ *
+ * Ethernet_802.2 frames, which are 802.3
+ * frames with an 802.2 LLC header and
+ * with the IPX LSAP as the DSAP in the LLC
+ * header;
+ *
+ * Ethernet_SNAP frames, which are 802.3
+ * frames with an LLC header and a SNAP
+ * header and with an OUI of 0x000000
+ * (encapsulated Ethernet) and a protocol
+ * ID of ETHERTYPE_IPX in the SNAP header.
+ *
+ * XXX - should we generate the same code both
+ * for tests for LLCSAP_IPX and for ETHERTYPE_IPX?
+ */
+
+ /*
+ * This generates code to check both for the
+ * IPX LSAP (Ethernet_802.2) and for Ethernet_802.3.
+ */
+ b0 = gen_cmp(OR_MACPL, 0, BPF_B, (bpf_int32)LLCSAP_IPX);
+ b1 = gen_cmp(OR_MACPL, 0, BPF_H, (bpf_int32)0xFFFF);
+ gen_or(b0, b1);
+
+ /*
+ * Now we add code to check for SNAP frames with
+ * ETHERTYPE_IPX, i.e. Ethernet_SNAP.
+ */
+ b0 = gen_snap(0x000000, ETHERTYPE_IPX);
+ gen_or(b0, b1);
+
+ /*
+ * Now we generate code to check for 802.3
+ * frames in general.
+ */
+ b0 = gen_cmp_gt(OR_LINK, off_linktype, BPF_H, ETHERMTU);
+ gen_not(b0);
+
+ /*
+ * Now add the check for 802.3 frames before the
+ * check for Ethernet_802.2 and Ethernet_802.3,
+ * as those checks should only be done on 802.3
+ * frames, not on Ethernet frames.
+ */
+ gen_and(b0, b1);
+
+ /*
+ * Now add the check for Ethernet_II frames, and
+ * do that before checking for the other frame
+ * types.
+ */
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H,
+ (bpf_int32)ETHERTYPE_IPX);
+ gen_or(b0, b1);
+ return b1;
+
+ case ETHERTYPE_ATALK:
+ case ETHERTYPE_AARP:
+ /*
+ * EtherTalk (AppleTalk protocols on Ethernet link
+ * layer) may use 802.2 encapsulation.
+ */
+
+ /*
+ * Check for 802.2 encapsulation (EtherTalk phase 2?);
+ * we check for an Ethernet type field less than
+ * 1500, which means it's an 802.3 length field.
+ */
+ b0 = gen_cmp_gt(OR_LINK, off_linktype, BPF_H, ETHERMTU);
+ gen_not(b0);
+
+ /*
+ * 802.2-encapsulated ETHERTYPE_ATALK packets are
+ * SNAP packets with an organization code of
+ * 0x080007 (Apple, for Appletalk) and a protocol
+ * type of ETHERTYPE_ATALK (Appletalk).
+ *
+ * 802.2-encapsulated ETHERTYPE_AARP packets are
+ * SNAP packets with an organization code of
+ * 0x000000 (encapsulated Ethernet) and a protocol
+ * type of ETHERTYPE_AARP (Appletalk ARP).
+ */
+ if (proto == ETHERTYPE_ATALK)
+ b1 = gen_snap(0x080007, ETHERTYPE_ATALK);
+ else /* proto == ETHERTYPE_AARP */
+ b1 = gen_snap(0x000000, ETHERTYPE_AARP);
+ gen_and(b0, b1);
+
+ /*
+ * Check for Ethernet encapsulation (Ethertalk
+ * phase 1?); we just check for the Ethernet
+ * protocol type.
+ */
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto);
+
+ gen_or(b0, b1);
+ return b1;
+
+ default:
+ if (proto <= ETHERMTU) {
+ /*
+ * This is an LLC SAP value, so the frames
+ * that match would be 802.2 frames.
+ * Check that the frame is an 802.2 frame
+ * (i.e., that the length/type field is
+ * a length field, <= ETHERMTU) and
+ * then check the DSAP.
+ */
+ b0 = gen_cmp_gt(OR_LINK, off_linktype, BPF_H, ETHERMTU);
+ gen_not(b0);
+ b1 = gen_cmp(OR_LINK, off_linktype + 2, BPF_B,
+ (bpf_int32)proto);
+ gen_and(b0, b1);
+ return b1;
+ } else {
+ /*
+ * This is an Ethernet type, so compare
+ * the length/type field with it (if
+ * the frame is an 802.2 frame, the length
+ * field will be <= ETHERMTU, and, as
+ * "proto" is > ETHERMTU, this test
+ * will fail and the frame won't match,
+ * which is what we want).
+ */
+ return gen_cmp(OR_LINK, off_linktype, BPF_H,
+ (bpf_int32)proto);
+ }
+ }
+}
+
+/*
+ * "proto" is an Ethernet type value and for IPNET, if it is not IPv4
+ * or IPv6 then we have an error.
+ */
+static struct block *
+gen_ipnet_linktype(proto)
+ register int proto;
+{
+ switch (proto) {
+
+ case ETHERTYPE_IP:
+ return gen_cmp(OR_LINK, off_linktype, BPF_B,
+ (bpf_int32)IPH_AF_INET);
+ /* NOTREACHED */
+
+ case ETHERTYPE_IPV6:
+ return gen_cmp(OR_LINK, off_linktype, BPF_B,
+ (bpf_int32)IPH_AF_INET6);
+ /* NOTREACHED */
+
+ default:
+ break;
+ }
+
+ return gen_false();
+}
+
+/*
+ * Generate code to match a particular packet type.
+ *
+ * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP
+ * value, if <= ETHERMTU. We use that to determine whether to
+ * match the type field or to check the type field for the special
+ * LINUX_SLL_P_802_2 value and then do the appropriate test.
+ */
+static struct block *
+gen_linux_sll_linktype(proto)
+ register int proto;
+{
+ struct block *b0, *b1;
+
+ switch (proto) {
+
+ case LLCSAP_ISONS:
+ case LLCSAP_IP:
+ case LLCSAP_NETBEUI:
+ /*
+ * OSI protocols and NetBEUI always use 802.2 encapsulation,
+ * so we check the DSAP and SSAP.
+ *
+ * LLCSAP_IP checks for IP-over-802.2, rather
+ * than IP-over-Ethernet or IP-over-SNAP.
+ *
+ * XXX - should we check both the DSAP and the
+ * SSAP, like this, or should we check just the
+ * DSAP, as we do for other types <= ETHERMTU
+ * (i.e., other SAP values)?
+ */
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_2);
+ b1 = gen_cmp(OR_MACPL, 0, BPF_H, (bpf_int32)
+ ((proto << 8) | proto));
+ gen_and(b0, b1);
+ return b1;
+
+ case LLCSAP_IPX:
+ /*
+ * Ethernet_II frames, which are Ethernet
+ * frames with a frame type of ETHERTYPE_IPX;
+ *
+ * Ethernet_802.3 frames, which have a frame
+ * type of LINUX_SLL_P_802_3;
+ *
+ * Ethernet_802.2 frames, which are 802.3
+ * frames with an 802.2 LLC header (i.e, have
+ * a frame type of LINUX_SLL_P_802_2) and
+ * with the IPX LSAP as the DSAP in the LLC
+ * header;
+ *
+ * Ethernet_SNAP frames, which are 802.3
+ * frames with an LLC header and a SNAP
+ * header and with an OUI of 0x000000
+ * (encapsulated Ethernet) and a protocol
+ * ID of ETHERTYPE_IPX in the SNAP header.
+ *
+ * First, do the checks on LINUX_SLL_P_802_2
+ * frames; generate the check for either
+ * Ethernet_802.2 or Ethernet_SNAP frames, and
+ * then put a check for LINUX_SLL_P_802_2 frames
+ * before it.
+ */
+ b0 = gen_cmp(OR_MACPL, 0, BPF_B, (bpf_int32)LLCSAP_IPX);
+ b1 = gen_snap(0x000000, ETHERTYPE_IPX);
+ gen_or(b0, b1);
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_2);
+ gen_and(b0, b1);
+
+ /*
+ * Now check for 802.3 frames and OR that with
+ * the previous test.
+ */
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_3);
+ gen_or(b0, b1);
+
+ /*
+ * Now add the check for Ethernet_II frames, and
+ * do that before checking for the other frame
+ * types.
+ */
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H,
+ (bpf_int32)ETHERTYPE_IPX);
+ gen_or(b0, b1);
+ return b1;
+
+ case ETHERTYPE_ATALK:
+ case ETHERTYPE_AARP:
+ /*
+ * EtherTalk (AppleTalk protocols on Ethernet link
+ * layer) may use 802.2 encapsulation.
+ */
+
+ /*
+ * Check for 802.2 encapsulation (EtherTalk phase 2?);
+ * we check for the 802.2 protocol type in the
+ * "Ethernet type" field.
+ */
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, LINUX_SLL_P_802_2);
+
+ /*
+ * 802.2-encapsulated ETHERTYPE_ATALK packets are
+ * SNAP packets with an organization code of
+ * 0x080007 (Apple, for Appletalk) and a protocol
+ * type of ETHERTYPE_ATALK (Appletalk).
+ *
+ * 802.2-encapsulated ETHERTYPE_AARP packets are
+ * SNAP packets with an organization code of
+ * 0x000000 (encapsulated Ethernet) and a protocol
+ * type of ETHERTYPE_AARP (Appletalk ARP).
+ */
+ if (proto == ETHERTYPE_ATALK)
+ b1 = gen_snap(0x080007, ETHERTYPE_ATALK);
+ else /* proto == ETHERTYPE_AARP */
+ b1 = gen_snap(0x000000, ETHERTYPE_AARP);
+ gen_and(b0, b1);
+
+ /*
+ * Check for Ethernet encapsulation (Ethertalk
+ * phase 1?); we just check for the Ethernet
+ * protocol type.
+ */
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto);
+
+ gen_or(b0, b1);
+ return b1;
+
+ default:
+ if (proto <= ETHERMTU) {
+ /*
+ * This is an LLC SAP value, so the frames
+ * that match would be 802.2 frames.
+ * Check for the 802.2 protocol type
+ * in the "Ethernet type" field, and
+ * then check the DSAP.
+ */
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H,
+ LINUX_SLL_P_802_2);
+ b1 = gen_cmp(OR_LINK, off_macpl, BPF_B,
+ (bpf_int32)proto);
+ gen_and(b0, b1);
+ return b1;
+ } else {
+ /*
+ * This is an Ethernet type, so compare
+ * the length/type field with it (if
+ * the frame is an 802.2 frame, the length
+ * field will be <= ETHERMTU, and, as
+ * "proto" is > ETHERMTU, this test
+ * will fail and the frame won't match,
+ * which is what we want).
+ */
+ return gen_cmp(OR_LINK, off_linktype, BPF_H,
+ (bpf_int32)proto);
+ }
+ }
+}
+
+static struct slist *
+gen_load_prism_llprefixlen()
+{
+ struct slist *s1, *s2;
+ struct slist *sjeq_avs_cookie;
+ struct slist *sjcommon;
+
+ /*
+ * This code is not compatible with the optimizer, as
+ * we are generating jmp instructions within a normal
+ * slist of instructions
+ */
+ no_optimize = 1;
+
+ /*
+ * Generate code to load the length of the radio header into
+ * the register assigned to hold that length, if one has been
+ * assigned. (If one hasn't been assigned, no code we've
+ * generated uses that prefix, so we don't need to generate any
+ * code to load it.)
+ *
+ * Some Linux drivers use ARPHRD_IEEE80211_PRISM but sometimes
+ * or always use the AVS header rather than the Prism header.
+ * We load a 4-byte big-endian value at the beginning of the
+ * raw packet data, and see whether, when masked with 0xFFFFF000,
+ * it's equal to 0x80211000. If so, that indicates that it's
+ * an AVS header (the masked-out bits are the version number).
+ * Otherwise, it's a Prism header.
+ *
+ * XXX - the Prism header is also, in theory, variable-length,
+ * but no known software generates headers that aren't 144
+ * bytes long.
+ */
+ if (reg_off_ll != -1) {
+ /*
+ * Load the cookie.
+ */
+ s1 = new_stmt(BPF_LD|BPF_W|BPF_ABS);
+ s1->s.k = 0;
+
+ /*
+ * AND it with 0xFFFFF000.
+ */
+ s2 = new_stmt(BPF_ALU|BPF_AND|BPF_K);
+ s2->s.k = 0xFFFFF000;
+ sappend(s1, s2);
+
+ /*
+ * Compare with 0x80211000.
+ */
+ sjeq_avs_cookie = new_stmt(JMP(BPF_JEQ));
+ sjeq_avs_cookie->s.k = 0x80211000;
+ sappend(s1, sjeq_avs_cookie);
+
+ /*
+ * If it's AVS:
+ *
+ * The 4 bytes at an offset of 4 from the beginning of
+ * the AVS header are the length of the AVS header.
+ * That field is big-endian.
+ */
+ s2 = new_stmt(BPF_LD|BPF_W|BPF_ABS);
+ s2->s.k = 4;
+ sappend(s1, s2);
+ sjeq_avs_cookie->s.jt = s2;
+
+ /*
+ * Now jump to the code to allocate a register
+ * into which to save the header length and
+ * store the length there. (The "jump always"
+ * instruction needs to have the k field set;
+ * it's added to the PC, so, as we're jumping
+ * over a single instruction, it should be 1.)
+ */
+ sjcommon = new_stmt(JMP(BPF_JA));
+ sjcommon->s.k = 1;
+ sappend(s1, sjcommon);
+
+ /*
+ * Now for the code that handles the Prism header.
+ * Just load the length of the Prism header (144)
+ * into the A register. Have the test for an AVS
+ * header branch here if we don't have an AVS header.
+ */
+ s2 = new_stmt(BPF_LD|BPF_W|BPF_IMM);
+ s2->s.k = 144;
+ sappend(s1, s2);
+ sjeq_avs_cookie->s.jf = s2;
+
+ /*
+ * Now allocate a register to hold that value and store
+ * it. The code for the AVS header will jump here after
+ * loading the length of the AVS header.
+ */
+ s2 = new_stmt(BPF_ST);
+ s2->s.k = reg_off_ll;
+ sappend(s1, s2);
+ sjcommon->s.jf = s2;
+
+ /*
+ * Now move it into the X register.
+ */
+ s2 = new_stmt(BPF_MISC|BPF_TAX);
+ sappend(s1, s2);
+
+ return (s1);
+ } else
+ return (NULL);
+}
+
+static struct slist *
+gen_load_avs_llprefixlen()
+{
+ struct slist *s1, *s2;
+
+ /*
+ * Generate code to load the length of the AVS header into
+ * the register assigned to hold that length, if one has been
+ * assigned. (If one hasn't been assigned, no code we've
+ * generated uses that prefix, so we don't need to generate any
+ * code to load it.)
+ */
+ if (reg_off_ll != -1) {
+ /*
+ * The 4 bytes at an offset of 4 from the beginning of
+ * the AVS header are the length of the AVS header.
+ * That field is big-endian.
+ */
+ s1 = new_stmt(BPF_LD|BPF_W|BPF_ABS);
+ s1->s.k = 4;
+
+ /*
+ * Now allocate a register to hold that value and store
+ * it.
+ */
+ s2 = new_stmt(BPF_ST);
+ s2->s.k = reg_off_ll;
+ sappend(s1, s2);
+
+ /*
+ * Now move it into the X register.
+ */
+ s2 = new_stmt(BPF_MISC|BPF_TAX);
+ sappend(s1, s2);
+
+ return (s1);
+ } else
+ return (NULL);
+}
+
+static struct slist *
+gen_load_radiotap_llprefixlen()
+{
+ struct slist *s1, *s2;
+
+ /*
+ * Generate code to load the length of the radiotap header into
+ * the register assigned to hold that length, if one has been
+ * assigned. (If one hasn't been assigned, no code we've
+ * generated uses that prefix, so we don't need to generate any
+ * code to load it.)
+ */
+ if (reg_off_ll != -1) {
+ /*
+ * The 2 bytes at offsets of 2 and 3 from the beginning
+ * of the radiotap header are the length of the radiotap
+ * header; unfortunately, it's little-endian, so we have
+ * to load it a byte at a time and construct the value.
+ */
+
+ /*
+ * Load the high-order byte, at an offset of 3, shift it
+ * left a byte, and put the result in the X register.
+ */
+ s1 = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ s1->s.k = 3;
+ s2 = new_stmt(BPF_ALU|BPF_LSH|BPF_K);
+ sappend(s1, s2);
+ s2->s.k = 8;
+ s2 = new_stmt(BPF_MISC|BPF_TAX);
+ sappend(s1, s2);
+
+ /*
+ * Load the next byte, at an offset of 2, and OR the
+ * value from the X register into it.
+ */
+ s2 = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ sappend(s1, s2);
+ s2->s.k = 2;
+ s2 = new_stmt(BPF_ALU|BPF_OR|BPF_X);
+ sappend(s1, s2);
+
+ /*
+ * Now allocate a register to hold that value and store
+ * it.
+ */
+ s2 = new_stmt(BPF_ST);
+ s2->s.k = reg_off_ll;
+ sappend(s1, s2);
+
+ /*
+ * Now move it into the X register.
+ */
+ s2 = new_stmt(BPF_MISC|BPF_TAX);
+ sappend(s1, s2);
+
+ return (s1);
+ } else
+ return (NULL);
+}
+
+/*
+ * At the moment we treat PPI as normal Radiotap encoded
+ * packets. The difference is in the function that generates
+ * the code at the beginning to compute the header length.
+ * Since this code generator of PPI supports bare 802.11
+ * encapsulation only (i.e. the encapsulated DLT should be
+ * DLT_IEEE802_11) we generate code to check for this too;
+ * that's done in finish_parse().
+ */
+static struct slist *
+gen_load_ppi_llprefixlen()
+{
+ struct slist *s1, *s2;
+
+ /*
+ * Generate code to load the length of the radiotap header
+ * into the register assigned to hold that length, if one has
+ * been assigned.
+ */
+ if (reg_off_ll != -1) {
+ /*
+ * The 2 bytes at offsets of 2 and 3 from the beginning
+ * of the radiotap header are the length of the radiotap
+ * header; unfortunately, it's little-endian, so we have
+ * to load it a byte at a time and construct the value.
+ */
+
+ /*
+ * Load the high-order byte, at an offset of 3, shift it
+ * left a byte, and put the result in the X register.
+ */
+ s1 = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ s1->s.k = 3;
+ s2 = new_stmt(BPF_ALU|BPF_LSH|BPF_K);
+ sappend(s1, s2);
+ s2->s.k = 8;
+ s2 = new_stmt(BPF_MISC|BPF_TAX);
+ sappend(s1, s2);
+
+ /*
+ * Load the next byte, at an offset of 2, and OR the
+ * value from the X register into it.
+ */
+ s2 = new_stmt(BPF_LD|BPF_B|BPF_ABS);
+ sappend(s1, s2);
+ s2->s.k = 2;
+ s2 = new_stmt(BPF_ALU|BPF_OR|BPF_X);
+ sappend(s1, s2);
+
+ /*
+ * Now allocate a register to hold that value and store
+ * it.
+ */
+ s2 = new_stmt(BPF_ST);
+ s2->s.k = reg_off_ll;
+ sappend(s1, s2);
+
+ /*
+ * Now move it into the X register.
+ */
+ s2 = new_stmt(BPF_MISC|BPF_TAX);
+ sappend(s1, s2);
+
+ return (s1);
+ } else
+ return (NULL);
+}
+
+/*
+ * Load a value relative to the beginning of the link-layer header after the 802.11
+ * header, i.e. LLC_SNAP.
+ * The link-layer header doesn't necessarily begin at the beginning
+ * of the packet data; there might be a variable-length prefix containing
+ * radio information.
+ */
+static struct slist *
+gen_load_802_11_header_len(struct slist *s, struct slist *snext)
+{
+ struct slist *s2;
+ struct slist *sjset_data_frame_1;
+ struct slist *sjset_data_frame_2;
+ struct slist *sjset_qos;
+ struct slist *sjset_radiotap_flags;
+ struct slist *sjset_radiotap_tsft;
+ struct slist *sjset_tsft_datapad, *sjset_notsft_datapad;
+ struct slist *s_roundup;
+
+ if (reg_off_macpl == -1) {
+ /*
+ * No register has been assigned to the offset of
+ * the MAC-layer payload, which means nobody needs
+ * it; don't bother computing it - just return
+ * what we already have.
+ */
+ return (s);
+ }
+
+ /*
+ * This code is not compatible with the optimizer, as
+ * we are generating jmp instructions within a normal
+ * slist of instructions
+ */
+ no_optimize = 1;
+
+ /*
+ * If "s" is non-null, it has code to arrange that the X register
+ * contains the length of the prefix preceding the link-layer
+ * header.
+ *
+ * Otherwise, the length of the prefix preceding the link-layer
+ * header is "off_ll".
+ */
+ if (s == NULL) {
+ /*
+ * There is no variable-length header preceding the
+ * link-layer header.
+ *
+ * Load the length of the fixed-length prefix preceding
+ * the link-layer header (if any) into the X register,
+ * and store it in the reg_off_macpl register.
+ * That length is off_ll.
+ */
+ s = new_stmt(BPF_LDX|BPF_IMM);
+ s->s.k = off_ll;
+ }
+
+ /*
+ * The X register contains the offset of the beginning of the
+ * link-layer header; add 24, which is the minimum length
+ * of the MAC header for a data frame, to that, and store it
+ * in reg_off_macpl, and then load the Frame Control field,
+ * which is at the offset in the X register, with an indexed load.
+ */
+ s2 = new_stmt(BPF_MISC|BPF_TXA);
+ sappend(s, s2);
+ s2 = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
+ s2->s.k = 24;
+ sappend(s, s2);
+ s2 = new_stmt(BPF_ST);
+ s2->s.k = reg_off_macpl;
+ sappend(s, s2);
+
+ s2 = new_stmt(BPF_LD|BPF_IND|BPF_B);
+ s2->s.k = 0;
+ sappend(s, s2);
+
+ /*
+ * Check the Frame Control field to see if this is a data frame;
+ * a data frame has the 0x08 bit (b3) in that field set and the
+ * 0x04 bit (b2) clear.
+ */
+ sjset_data_frame_1 = new_stmt(JMP(BPF_JSET));
+ sjset_data_frame_1->s.k = 0x08;
+ sappend(s, sjset_data_frame_1);
+
+ /*
+ * If b3 is set, test b2, otherwise go to the first statement of
+ * the rest of the program.
+ */
+ sjset_data_frame_1->s.jt = sjset_data_frame_2 = new_stmt(JMP(BPF_JSET));
+ sjset_data_frame_2->s.k = 0x04;
+ sappend(s, sjset_data_frame_2);
+ sjset_data_frame_1->s.jf = snext;
+
+ /*
+ * If b2 is not set, this is a data frame; test the QoS bit.
+ * Otherwise, go to the first statement of the rest of the
+ * program.
+ */
+ sjset_data_frame_2->s.jt = snext;
+ sjset_data_frame_2->s.jf = sjset_qos = new_stmt(JMP(BPF_JSET));
+ sjset_qos->s.k = 0x80; /* QoS bit */
+ sappend(s, sjset_qos);
+
+ /*
+ * If it's set, add 2 to reg_off_macpl, to skip the QoS
+ * field.
+ * Otherwise, go to the first statement of the rest of the
+ * program.
+ */
+ sjset_qos->s.jt = s2 = new_stmt(BPF_LD|BPF_MEM);
+ s2->s.k = reg_off_macpl;
+ sappend(s, s2);
+ s2 = new_stmt(BPF_ALU|BPF_ADD|BPF_IMM);
+ s2->s.k = 2;
+ sappend(s, s2);
+ s2 = new_stmt(BPF_ST);
+ s2->s.k = reg_off_macpl;
+ sappend(s, s2);
+
+ /*
+ * If we have a radiotap header, look at it to see whether
+ * there's Atheros padding between the MAC-layer header
+ * and the payload.
+ *
+ * Note: all of the fields in the radiotap header are
+ * little-endian, so we byte-swap all of the values
+ * we test against, as they will be loaded as big-endian
+ * values.
+ */
+ if (linktype == DLT_IEEE802_11_RADIO) {
+ /*
+ * Is the IEEE80211_RADIOTAP_FLAGS bit (0x0000002) set
+ * in the presence flag?
+ */
+ sjset_qos->s.jf = s2 = new_stmt(BPF_LD|BPF_ABS|BPF_W);
+ s2->s.k = 4;
+ sappend(s, s2);
+
+ sjset_radiotap_flags = new_stmt(JMP(BPF_JSET));
+ sjset_radiotap_flags->s.k = SWAPLONG(0x00000002);
+ sappend(s, sjset_radiotap_flags);
+
+ /*
+ * If not, skip all of this.
+ */
+ sjset_radiotap_flags->s.jf = snext;
+
+ /*
+ * Otherwise, is the IEEE80211_RADIOTAP_TSFT bit set?
+ */
+ sjset_radiotap_tsft = sjset_radiotap_flags->s.jt =
+ new_stmt(JMP(BPF_JSET));
+ sjset_radiotap_tsft->s.k = SWAPLONG(0x00000001);
+ sappend(s, sjset_radiotap_tsft);
+
+ /*
+ * If IEEE80211_RADIOTAP_TSFT is set, the flags field is
+ * at an offset of 16 from the beginning of the raw packet
+ * data (8 bytes for the radiotap header and 8 bytes for
+ * the TSFT field).
+ *
+ * Test whether the IEEE80211_RADIOTAP_F_DATAPAD bit (0x20)
+ * is set.
+ */
+ sjset_radiotap_tsft->s.jt = s2 = new_stmt(BPF_LD|BPF_ABS|BPF_B);
+ s2->s.k = 16;
+ sappend(s, s2);
+
+ sjset_tsft_datapad = new_stmt(JMP(BPF_JSET));
+ sjset_tsft_datapad->s.k = 0x20;
+ sappend(s, sjset_tsft_datapad);
+
+ /*
+ * If IEEE80211_RADIOTAP_TSFT is not set, the flags field is
+ * at an offset of 8 from the beginning of the raw packet
+ * data (8 bytes for the radiotap header).
+ *
+ * Test whether the IEEE80211_RADIOTAP_F_DATAPAD bit (0x20)
+ * is set.
+ */
+ sjset_radiotap_tsft->s.jf = s2 = new_stmt(BPF_LD|BPF_ABS|BPF_B);
+ s2->s.k = 8;
+ sappend(s, s2);
+
+ sjset_notsft_datapad = new_stmt(JMP(BPF_JSET));
+ sjset_notsft_datapad->s.k = 0x20;
+ sappend(s, sjset_notsft_datapad);
+
+ /*
+ * In either case, if IEEE80211_RADIOTAP_F_DATAPAD is
+ * set, round the length of the 802.11 header to
+ * a multiple of 4. Do that by adding 3 and then
+ * dividing by and multiplying by 4, which we do by
+ * ANDing with ~3.
+ */
+ s_roundup = new_stmt(BPF_LD|BPF_MEM);
+ s_roundup->s.k = reg_off_macpl;
+ sappend(s, s_roundup);
+ s2 = new_stmt(BPF_ALU|BPF_ADD|BPF_IMM);
+ s2->s.k = 3;
+ sappend(s, s2);
+ s2 = new_stmt(BPF_ALU|BPF_AND|BPF_IMM);
+ s2->s.k = ~3;
+ sappend(s, s2);
+ s2 = new_stmt(BPF_ST);
+ s2->s.k = reg_off_macpl;
+ sappend(s, s2);
+
+ sjset_tsft_datapad->s.jt = s_roundup;
+ sjset_tsft_datapad->s.jf = snext;
+ sjset_notsft_datapad->s.jt = s_roundup;
+ sjset_notsft_datapad->s.jf = snext;
+ } else
+ sjset_qos->s.jf = snext;
+
+ return s;
+}
+
+static void
+insert_compute_vloffsets(b)
+ struct block *b;
+{
+ struct slist *s;
+
+ /*
+ * For link-layer types that have a variable-length header
+ * preceding the link-layer header, generate code to load
+ * the offset of the link-layer header into the register
+ * assigned to that offset, if any.
+ */
+ switch (linktype) {
+
+ case DLT_PRISM_HEADER:
+ s = gen_load_prism_llprefixlen();
+ break;
+
+ case DLT_IEEE802_11_RADIO_AVS:
+ s = gen_load_avs_llprefixlen();
+ break;
+
+ case DLT_IEEE802_11_RADIO:
+ s = gen_load_radiotap_llprefixlen();
+ break;
+
+ case DLT_PPI:
+ s = gen_load_ppi_llprefixlen();
+ break;
+
+ default:
+ s = NULL;
+ break;
+ }
+
+ /*
+ * For link-layer types that have a variable-length link-layer
+ * header, generate code to load the offset of the MAC-layer
+ * payload into the register assigned to that offset, if any.
+ */
+ switch (linktype) {
+
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ case DLT_IEEE802_11_RADIO:
+ case DLT_PPI:
+ s = gen_load_802_11_header_len(s, b->stmts);
+ break;
+ }
+
+ /*
+ * If we have any offset-loading code, append all the
+ * existing statements in the block to those statements,
+ * and make the resulting list the list of statements
+ * for the block.
+ */
+ if (s != NULL) {
+ sappend(s, b->stmts);
+ b->stmts = s;
+ }
+}
+
+static struct block *
+gen_ppi_dlt_check(void)
+{
+ struct slist *s_load_dlt;
+ struct block *b;
+
+ if (linktype == DLT_PPI)
+ {
+ /* Create the statements that check for the DLT
+ */
+ s_load_dlt = new_stmt(BPF_LD|BPF_W|BPF_ABS);
+ s_load_dlt->s.k = 4;
+
+ b = new_block(JMP(BPF_JEQ));
+
+ b->stmts = s_load_dlt;
+ b->s.k = SWAPLONG(DLT_IEEE802_11);
+ }
+ else
+ {
+ b = NULL;
+ }
+
+ return b;
+}
+
+static struct slist *
+gen_prism_llprefixlen(void)
+{
+ struct slist *s;
+
+ if (reg_off_ll == -1) {
+ /*
+ * We haven't yet assigned a register for the length
+ * of the radio header; allocate one.
+ */
+ reg_off_ll = alloc_reg();
+ }
+
+ /*
+ * Load the register containing the radio length
+ * into the X register.
+ */
+ s = new_stmt(BPF_LDX|BPF_MEM);
+ s->s.k = reg_off_ll;
+ return s;
+}
+
+static struct slist *
+gen_avs_llprefixlen(void)
+{
+ struct slist *s;
+
+ if (reg_off_ll == -1) {
+ /*
+ * We haven't yet assigned a register for the length
+ * of the AVS header; allocate one.
+ */
+ reg_off_ll = alloc_reg();
+ }
+
+ /*
+ * Load the register containing the AVS length
+ * into the X register.
+ */
+ s = new_stmt(BPF_LDX|BPF_MEM);
+ s->s.k = reg_off_ll;
+ return s;
+}
+
+static struct slist *
+gen_radiotap_llprefixlen(void)
+{
+ struct slist *s;
+
+ if (reg_off_ll == -1) {
+ /*
+ * We haven't yet assigned a register for the length
+ * of the radiotap header; allocate one.
+ */
+ reg_off_ll = alloc_reg();
+ }
+
+ /*
+ * Load the register containing the radiotap length
+ * into the X register.
+ */
+ s = new_stmt(BPF_LDX|BPF_MEM);
+ s->s.k = reg_off_ll;
+ return s;
+}
+
+/*
+ * At the moment we treat PPI as normal Radiotap encoded
+ * packets. The difference is in the function that generates
+ * the code at the beginning to compute the header length.
+ * Since this code generator of PPI supports bare 802.11
+ * encapsulation only (i.e. the encapsulated DLT should be
+ * DLT_IEEE802_11) we generate code to check for this too.
+ */
+static struct slist *
+gen_ppi_llprefixlen(void)
+{
+ struct slist *s;
+
+ if (reg_off_ll == -1) {
+ /*
+ * We haven't yet assigned a register for the length
+ * of the radiotap header; allocate one.
+ */
+ reg_off_ll = alloc_reg();
+ }
+
+ /*
+ * Load the register containing the PPI length
+ * into the X register.
+ */
+ s = new_stmt(BPF_LDX|BPF_MEM);
+ s->s.k = reg_off_ll;
+ return s;
+}
+
+/*
+ * Generate code to compute the link-layer header length, if necessary,
+ * putting it into the X register, and to return either a pointer to a
+ * "struct slist" for the list of statements in that code, or NULL if
+ * no code is necessary.
+ */
+static struct slist *
+gen_llprefixlen(void)
+{
+ switch (linktype) {
+
+ case DLT_PRISM_HEADER:
+ return gen_prism_llprefixlen();
+
+ case DLT_IEEE802_11_RADIO_AVS:
+ return gen_avs_llprefixlen();
+
+ case DLT_IEEE802_11_RADIO:
+ return gen_radiotap_llprefixlen();
+
+ case DLT_PPI:
+ return gen_ppi_llprefixlen();
+
+ default:
+ return NULL;
+ }
+}
+
+/*
+ * Generate code to load the register containing the offset of the
+ * MAC-layer payload into the X register; if no register for that offset
+ * has been allocated, allocate it first.
+ */
+static struct slist *
+gen_off_macpl(void)
+{
+ struct slist *s;
+
+ if (off_macpl_is_variable) {
+ if (reg_off_macpl == -1) {
+ /*
+ * We haven't yet assigned a register for the offset
+ * of the MAC-layer payload; allocate one.
+ */
+ reg_off_macpl = alloc_reg();
+ }
+
+ /*
+ * Load the register containing the offset of the MAC-layer
+ * payload into the X register.
+ */
+ s = new_stmt(BPF_LDX|BPF_MEM);
+ s->s.k = reg_off_macpl;
+ return s;
+ } else {
+ /*
+ * That offset isn't variable, so we don't need to
+ * generate any code.
+ */
+ return NULL;
+ }
+}
+
+/*
+ * Map an Ethernet type to the equivalent PPP type.
+ */
+static int
+ethertype_to_ppptype(proto)
+ int proto;
+{
+ switch (proto) {
+
+ case ETHERTYPE_IP:
+ proto = PPP_IP;
+ break;
+
+ case ETHERTYPE_IPV6:
+ proto = PPP_IPV6;
+ break;
+
+ case ETHERTYPE_DN:
+ proto = PPP_DECNET;
+ break;
+
+ case ETHERTYPE_ATALK:
+ proto = PPP_APPLE;
+ break;
+
+ case ETHERTYPE_NS:
+ proto = PPP_NS;
+ break;
+
+ case LLCSAP_ISONS:
+ proto = PPP_OSI;
+ break;
+
+ case LLCSAP_8021D:
+ /*
+ * I'm assuming the "Bridging PDU"s that go
+ * over PPP are Spanning Tree Protocol
+ * Bridging PDUs.
+ */
+ proto = PPP_BRPDU;
+ break;
+
+ case LLCSAP_IPX:
+ proto = PPP_IPX;
+ break;
+ }
+ return (proto);
+}
+
+/*
+ * Generate code to match a particular packet type by matching the
+ * link-layer type field or fields in the 802.2 LLC header.
+ *
+ * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP
+ * value, if <= ETHERMTU.
+ */
+static struct block *
+gen_linktype(proto)
+ register int proto;
+{
+ struct block *b0, *b1, *b2;
+
+ /* are we checking MPLS-encapsulated packets? */
+ if (label_stack_depth > 0) {
+ switch (proto) {
+ case ETHERTYPE_IP:
+ case PPP_IP:
+ /* FIXME add other L3 proto IDs */
+ return gen_mpls_linktype(Q_IP);
+
+ case ETHERTYPE_IPV6:
+ case PPP_IPV6:
+ /* FIXME add other L3 proto IDs */
+ return gen_mpls_linktype(Q_IPV6);
+
+ default:
+ bpf_error("unsupported protocol over mpls");
+ /* NOTREACHED */
+ }
+ }
+
+ /*
+ * Are we testing PPPoE packets?
+ */
+ if (is_pppoes) {
+ /*
+ * The PPPoE session header is part of the
+ * MAC-layer payload, so all references
+ * should be relative to the beginning of
+ * that payload.
+ */
+
+ /*
+ * We use Ethernet protocol types inside libpcap;
+ * map them to the corresponding PPP protocol types.
+ */
+ proto = ethertype_to_ppptype(proto);
+ return gen_cmp(OR_MACPL, off_linktype, BPF_H, (bpf_int32)proto);
+ }
+
+ switch (linktype) {
+
+ case DLT_EN10MB:
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
+ return gen_ether_linktype(proto);
+ /*NOTREACHED*/
+ break;
+
+ case DLT_C_HDLC:
+ switch (proto) {
+
+ case LLCSAP_ISONS:
+ proto = (proto << 8 | LLCSAP_ISONS);
+ /* fall through */
+
+ default:
+ return gen_cmp(OR_LINK, off_linktype, BPF_H,
+ (bpf_int32)proto);
+ /*NOTREACHED*/
+ break;
+ }
+ break;
+
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ case DLT_IEEE802_11_RADIO:
+ case DLT_PPI:
+ /*
+ * Check that we have a data frame.
+ */
+ b0 = gen_check_802_11_data_frame();
+
+ /*
+ * Now check for the specified link-layer type.
+ */
+ b1 = gen_llc_linktype(proto);
+ gen_and(b0, b1);
+ return b1;
+ /*NOTREACHED*/
+ break;
+
+ case DLT_FDDI:
+ /*
+ * XXX - check for asynchronous frames, as per RFC 1103.
+ */
+ return gen_llc_linktype(proto);
+ /*NOTREACHED*/
+ break;
+
+ case DLT_IEEE802:
+ /*
+ * XXX - check for LLC PDUs, as per IEEE 802.5.
+ */
+ return gen_llc_linktype(proto);
+ /*NOTREACHED*/
+ break;
+
+ case DLT_ATM_RFC1483:
+ case DLT_ATM_CLIP:
+ case DLT_IP_OVER_FC:
+ return gen_llc_linktype(proto);
+ /*NOTREACHED*/
+ break;
+
+ case DLT_SUNATM:
+ /*
+ * If "is_lane" is set, check for a LANE-encapsulated
+ * version of this protocol, otherwise check for an
+ * LLC-encapsulated version of this protocol.
+ *
+ * We assume LANE means Ethernet, not Token Ring.
+ */
+ if (is_lane) {
+ /*
+ * Check that the packet doesn't begin with an
+ * LE Control marker. (We've already generated
+ * a test for LANE.)
+ */
+ b0 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, BPF_H,
+ 0xFF00);
+ gen_not(b0);
+
+ /*
+ * Now generate an Ethernet test.
+ */
+ b1 = gen_ether_linktype(proto);
+ gen_and(b0, b1);
+ return b1;
+ } else {
+ /*
+ * Check for LLC encapsulation and then check the
+ * protocol.
+ */
+ b0 = gen_atmfield_code(A_PROTOTYPE, PT_LLC, BPF_JEQ, 0);
+ b1 = gen_llc_linktype(proto);
+ gen_and(b0, b1);
+ return b1;
+ }
+ /*NOTREACHED*/
+ break;
+
+ case DLT_LINUX_SLL:
+ return gen_linux_sll_linktype(proto);
+ /*NOTREACHED*/
+ break;
+
+ case DLT_SLIP:
+ case DLT_SLIP_BSDOS:
+ case DLT_RAW:
+ /*
+ * These types don't provide any type field; packets
+ * are always IPv4 or IPv6.
+ *
+ * XXX - for IPv4, check for a version number of 4, and,
+ * for IPv6, check for a version number of 6?
+ */
+ switch (proto) {
+
+ case ETHERTYPE_IP:
+ /* Check for a version number of 4. */
+ return gen_mcmp(OR_LINK, 0, BPF_B, 0x40, 0xF0);
+
+ case ETHERTYPE_IPV6:
+ /* Check for a version number of 6. */
+ return gen_mcmp(OR_LINK, 0, BPF_B, 0x60, 0xF0);
+
+ default:
+ return gen_false(); /* always false */
+ }
+ /*NOTREACHED*/
+ break;
+
+ case DLT_IPV4:
+ /*
+ * Raw IPv4, so no type field.
+ */
+ if (proto == ETHERTYPE_IP)
+ return gen_true(); /* always true */
+
+ /* Checking for something other than IPv4; always false */
+ return gen_false();
+ /*NOTREACHED*/
+ break;
+
+ case DLT_IPV6:
+ /*
+ * Raw IPv6, so no type field.
+ */
+ if (proto == ETHERTYPE_IPV6)
+ return gen_true(); /* always true */
+
+ /* Checking for something other than IPv6; always false */
+ return gen_false();
+ /*NOTREACHED*/
+ break;
+
+ case DLT_PPP:
+ case DLT_PPP_PPPD:
+ case DLT_PPP_SERIAL:
+ case DLT_PPP_ETHER:
+ /*
+ * We use Ethernet protocol types inside libpcap;
+ * map them to the corresponding PPP protocol types.
+ */
+ proto = ethertype_to_ppptype(proto);
+ return gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto);
+ /*NOTREACHED*/
+ break;
+
+ case DLT_PPP_BSDOS:
+ /*
+ * We use Ethernet protocol types inside libpcap;
+ * map them to the corresponding PPP protocol types.
+ */
+ switch (proto) {
+
+ case ETHERTYPE_IP:
+ /*
+ * Also check for Van Jacobson-compressed IP.
+ * XXX - do this for other forms of PPP?
+ */
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, PPP_IP);
+ b1 = gen_cmp(OR_LINK, off_linktype, BPF_H, PPP_VJC);
+ gen_or(b0, b1);
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H, PPP_VJNC);
+ gen_or(b1, b0);
+ return b0;
+
+ default:
+ proto = ethertype_to_ppptype(proto);
+ return gen_cmp(OR_LINK, off_linktype, BPF_H,
+ (bpf_int32)proto);
+ }
+ /*NOTREACHED*/
+ break;
+
+ case DLT_NULL:
+ case DLT_LOOP:
+ case DLT_ENC:
+ /*
+ * For DLT_NULL, the link-layer header is a 32-bit
+ * word containing an AF_ value in *host* byte order,
+ * and for DLT_ENC, the link-layer header begins
+ * with a 32-bit work containing an AF_ value in
+ * host byte order.
+ *
+ * In addition, if we're reading a saved capture file,
+ * the host byte order in the capture may not be the
+ * same as the host byte order on this machine.
+ *
+ * For DLT_LOOP, the link-layer header is a 32-bit
+ * word containing an AF_ value in *network* byte order.
+ *
+ * XXX - AF_ values may, unfortunately, be platform-
+ * dependent; for example, FreeBSD's AF_INET6 is 24
+ * whilst NetBSD's and OpenBSD's is 26.
+ *
+ * This means that, when reading a capture file, just
+ * checking for our AF_INET6 value won't work if the
+ * capture file came from another OS.
+ */
+ switch (proto) {
+
+ case ETHERTYPE_IP:
+ proto = AF_INET;
+ break;
+
+#ifdef INET6
+ case ETHERTYPE_IPV6:
+ proto = AF_INET6;
+ break;
+#endif
+
+ default:
+ /*
+ * Not a type on which we support filtering.
+ * XXX - support those that have AF_ values
+ * #defined on this platform, at least?
+ */
+ return gen_false();
+ }
+
+ if (linktype == DLT_NULL || linktype == DLT_ENC) {
+ /*
+ * The AF_ value is in host byte order, but
+ * the BPF interpreter will convert it to
+ * network byte order.
+ *
+ * If this is a save file, and it's from a
+ * machine with the opposite byte order to
+ * ours, we byte-swap the AF_ value.
+ *
+ * Then we run it through "htonl()", and
+ * generate code to compare against the result.
+ */
+ if (bpf_pcap->sf.rfile != NULL &&
+ bpf_pcap->sf.swapped)
+ proto = SWAPLONG(proto);
+ proto = htonl(proto);
+ }
+ return (gen_cmp(OR_LINK, 0, BPF_W, (bpf_int32)proto));
+
+#ifdef HAVE_NET_PFVAR_H
+ case DLT_PFLOG:
+ /*
+ * af field is host byte order in contrast to the rest of
+ * the packet.
+ */
+ if (proto == ETHERTYPE_IP)
+ return (gen_cmp(OR_LINK, offsetof(struct pfloghdr, af),
+ BPF_B, (bpf_int32)AF_INET));
+ else if (proto == ETHERTYPE_IPV6)
+ return (gen_cmp(OR_LINK, offsetof(struct pfloghdr, af),
+ BPF_B, (bpf_int32)AF_INET6));
+ else
+ return gen_false();
+ /*NOTREACHED*/
+ break;
+#endif /* HAVE_NET_PFVAR_H */
+
+ case DLT_ARCNET:
+ case DLT_ARCNET_LINUX:
+ /*
+ * XXX should we check for first fragment if the protocol
+ * uses PHDS?
+ */
+ switch (proto) {
+
+ default:
+ return gen_false();
+
+ case ETHERTYPE_IPV6:
+ return (gen_cmp(OR_LINK, off_linktype, BPF_B,
+ (bpf_int32)ARCTYPE_INET6));
+
+ case ETHERTYPE_IP:
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_B,
+ (bpf_int32)ARCTYPE_IP);
+ b1 = gen_cmp(OR_LINK, off_linktype, BPF_B,
+ (bpf_int32)ARCTYPE_IP_OLD);
+ gen_or(b0, b1);
+ return (b1);
+
+ case ETHERTYPE_ARP:
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_B,
+ (bpf_int32)ARCTYPE_ARP);
+ b1 = gen_cmp(OR_LINK, off_linktype, BPF_B,
+ (bpf_int32)ARCTYPE_ARP_OLD);
+ gen_or(b0, b1);
+ return (b1);
+
+ case ETHERTYPE_REVARP:
+ return (gen_cmp(OR_LINK, off_linktype, BPF_B,
+ (bpf_int32)ARCTYPE_REVARP));
+
+ case ETHERTYPE_ATALK:
+ return (gen_cmp(OR_LINK, off_linktype, BPF_B,
+ (bpf_int32)ARCTYPE_ATALK));
+ }
+ /*NOTREACHED*/
+ break;
+
+ case DLT_LTALK:
+ switch (proto) {
+ case ETHERTYPE_ATALK:
+ return gen_true();
+ default:
+ return gen_false();
+ }
+ /*NOTREACHED*/
+ break;
+
+ case DLT_FRELAY:
+ /*
+ * XXX - assumes a 2-byte Frame Relay header with
+ * DLCI and flags. What if the address is longer?
+ */
+ switch (proto) {
+
+ case ETHERTYPE_IP:
+ /*
+ * Check for the special NLPID for IP.
+ */
+ return gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | 0xcc);
+
+ case ETHERTYPE_IPV6:
+ /*
+ * Check for the special NLPID for IPv6.
+ */
+ return gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | 0x8e);
+
+ case LLCSAP_ISONS:
+ /*
+ * Check for several OSI protocols.
+ *
+ * Frame Relay packets typically have an OSI
+ * NLPID at the beginning; we check for each
+ * of them.
+ *
+ * What we check for is the NLPID and a frame
+ * control field of UI, i.e. 0x03 followed
+ * by the NLPID.
+ */
+ b0 = gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | ISO8473_CLNP);
+ b1 = gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | ISO9542_ESIS);
+ b2 = gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | ISO10589_ISIS);
+ gen_or(b1, b2);
+ gen_or(b0, b2);
+ return b2;
+
+ default:
+ return gen_false();
+ }
+ /*NOTREACHED*/
+ break;
+
+ case DLT_MFR:
+ bpf_error("Multi-link Frame Relay link-layer type filtering not implemented");
+
+ case DLT_JUNIPER_MFR:
+ case DLT_JUNIPER_MLFR:
+ case DLT_JUNIPER_MLPPP:
+ case DLT_JUNIPER_ATM1:
+ case DLT_JUNIPER_ATM2:
+ case DLT_JUNIPER_PPPOE:
+ case DLT_JUNIPER_PPPOE_ATM:
+ case DLT_JUNIPER_GGSN:
+ case DLT_JUNIPER_ES:
+ case DLT_JUNIPER_MONITOR:
+ case DLT_JUNIPER_SERVICES:
+ case DLT_JUNIPER_ETHER:
+ case DLT_JUNIPER_PPP:
+ case DLT_JUNIPER_FRELAY:
+ case DLT_JUNIPER_CHDLC:
+ case DLT_JUNIPER_VP:
+ case DLT_JUNIPER_ST:
+ case DLT_JUNIPER_ISM:
+ case DLT_JUNIPER_VS:
+ case DLT_JUNIPER_SRX_E2E:
+ case DLT_JUNIPER_FIBRECHANNEL:
+ case DLT_JUNIPER_ATM_CEMIC:
+
+ /* just lets verify the magic number for now -
+ * on ATM we may have up to 6 different encapsulations on the wire
+ * and need a lot of heuristics to figure out that the payload
+ * might be;
+ *
+ * FIXME encapsulation specific BPF_ filters
+ */
+ return gen_mcmp(OR_LINK, 0, BPF_W, 0x4d474300, 0xffffff00); /* compare the magic number */
+
+ case DLT_IPNET:
+ return gen_ipnet_linktype(proto);
+
+ case DLT_LINUX_IRDA:
+ bpf_error("IrDA link-layer type filtering not implemented");
+
+ case DLT_DOCSIS:
+ bpf_error("DOCSIS link-layer type filtering not implemented");
+
+ case DLT_MTP2:
+ case DLT_MTP2_WITH_PHDR:
+ bpf_error("MTP2 link-layer type filtering not implemented");
+
+ case DLT_ERF:
+ bpf_error("ERF link-layer type filtering not implemented");
+
+ case DLT_PFSYNC:
+ bpf_error("PFSYNC link-layer type filtering not implemented");
+
+ case DLT_LINUX_LAPD:
+ bpf_error("LAPD link-layer type filtering not implemented");
+
+ case DLT_USB:
+ case DLT_USB_LINUX:
+ case DLT_USB_LINUX_MMAPPED:
+ bpf_error("USB link-layer type filtering not implemented");
+
+ case DLT_BLUETOOTH_HCI_H4:
+ case DLT_BLUETOOTH_HCI_H4_WITH_PHDR:
+ bpf_error("Bluetooth link-layer type filtering not implemented");
+
+ case DLT_CAN20B:
+ case DLT_CAN_SOCKETCAN:
+ bpf_error("CAN link-layer type filtering not implemented");
+
+ case DLT_IEEE802_15_4:
+ case DLT_IEEE802_15_4_LINUX:
+ case DLT_IEEE802_15_4_NONASK_PHY:
+ case DLT_IEEE802_15_4_NOFCS:
+ bpf_error("IEEE 802.15.4 link-layer type filtering not implemented");
+
+ case DLT_IEEE802_16_MAC_CPS_RADIO:
+ bpf_error("IEEE 802.16 link-layer type filtering not implemented");
+
+ case DLT_SITA:
+ bpf_error("SITA link-layer type filtering not implemented");
+
+ case DLT_RAIF1:
+ bpf_error("RAIF1 link-layer type filtering not implemented");
+
+ case DLT_IPMB:
+ bpf_error("IPMB link-layer type filtering not implemented");
+
+ case DLT_AX25_KISS:
+ bpf_error("AX.25 link-layer type filtering not implemented");
+ }
+
+ /*
+ * All the types that have no encapsulation should either be
+ * handled as DLT_SLIP, DLT_SLIP_BSDOS, and DLT_RAW are, if
+ * all packets are IP packets, or should be handled in some
+ * special case, if none of them are (if some are and some
+ * aren't, the lack of encapsulation is a problem, as we'd
+ * have to find some other way of determining the packet type).
+ *
+ * Therefore, if "off_linktype" is -1, there's an error.
+ */
+ if (off_linktype == (u_int)-1)
+ abort();
+
+ /*
+ * Any type not handled above should always have an Ethernet
+ * type at an offset of "off_linktype".
+ */
+ return gen_cmp(OR_LINK, off_linktype, BPF_H, (bpf_int32)proto);
+}
+
+/*
+ * Check for an LLC SNAP packet with a given organization code and
+ * protocol type; we check the entire contents of the 802.2 LLC and
+ * snap headers, checking for DSAP and SSAP of SNAP and a control
+ * field of 0x03 in the LLC header, and for the specified organization
+ * code and protocol type in the SNAP header.
+ */
+static struct block *
+gen_snap(orgcode, ptype)
+ bpf_u_int32 orgcode;
+ bpf_u_int32 ptype;
+{
+ u_char snapblock[8];
+
+ snapblock[0] = LLCSAP_SNAP; /* DSAP = SNAP */
+ snapblock[1] = LLCSAP_SNAP; /* SSAP = SNAP */
+ snapblock[2] = 0x03; /* control = UI */
+ snapblock[3] = (orgcode >> 16); /* upper 8 bits of organization code */
+ snapblock[4] = (orgcode >> 8); /* middle 8 bits of organization code */
+ snapblock[5] = (orgcode >> 0); /* lower 8 bits of organization code */
+ snapblock[6] = (ptype >> 8); /* upper 8 bits of protocol type */
+ snapblock[7] = (ptype >> 0); /* lower 8 bits of protocol type */
+ return gen_bcmp(OR_MACPL, 0, 8, snapblock);
+}
+
+/*
+ * Generate code to match a particular packet type, for link-layer types
+ * using 802.2 LLC headers.
+ *
+ * This is *NOT* used for Ethernet; "gen_ether_linktype()" is used
+ * for that - it handles the D/I/X Ethernet vs. 802.3+802.2 issues.
+ *
+ * "proto" is an Ethernet type value, if > ETHERMTU, or an LLC SAP
+ * value, if <= ETHERMTU. We use that to determine whether to
+ * match the DSAP or both DSAP and LSAP or to check the OUI and
+ * protocol ID in a SNAP header.
+ */
+static struct block *
+gen_llc_linktype(proto)
+ int proto;
+{
+ /*
+ * XXX - handle token-ring variable-length header.
+ */
+ switch (proto) {
+
+ case LLCSAP_IP:
+ case LLCSAP_ISONS:
+ case LLCSAP_NETBEUI:
+ /*
+ * XXX - should we check both the DSAP and the
+ * SSAP, like this, or should we check just the
+ * DSAP, as we do for other types <= ETHERMTU
+ * (i.e., other SAP values)?
+ */
+ return gen_cmp(OR_MACPL, 0, BPF_H, (bpf_u_int32)
+ ((proto << 8) | proto));
+
+ case LLCSAP_IPX:
+ /*
+ * XXX - are there ever SNAP frames for IPX on
+ * non-Ethernet 802.x networks?
+ */
+ return gen_cmp(OR_MACPL, 0, BPF_B,
+ (bpf_int32)LLCSAP_IPX);
+
+ case ETHERTYPE_ATALK:
+ /*
+ * 802.2-encapsulated ETHERTYPE_ATALK packets are
+ * SNAP packets with an organization code of
+ * 0x080007 (Apple, for Appletalk) and a protocol
+ * type of ETHERTYPE_ATALK (Appletalk).
+ *
+ * XXX - check for an organization code of
+ * encapsulated Ethernet as well?
+ */
+ return gen_snap(0x080007, ETHERTYPE_ATALK);
+
+ default:
+ /*
+ * XXX - we don't have to check for IPX 802.3
+ * here, but should we check for the IPX Ethertype?
+ */
+ if (proto <= ETHERMTU) {
+ /*
+ * This is an LLC SAP value, so check
+ * the DSAP.
+ */
+ return gen_cmp(OR_MACPL, 0, BPF_B, (bpf_int32)proto);
+ } else {
+ /*
+ * This is an Ethernet type; we assume that it's
+ * unlikely that it'll appear in the right place
+ * at random, and therefore check only the
+ * location that would hold the Ethernet type
+ * in a SNAP frame with an organization code of
+ * 0x000000 (encapsulated Ethernet).
+ *
+ * XXX - if we were to check for the SNAP DSAP and
+ * LSAP, as per XXX, and were also to check for an
+ * organization code of 0x000000 (encapsulated
+ * Ethernet), we'd do
+ *
+ * return gen_snap(0x000000, proto);
+ *
+ * here; for now, we don't, as per the above.
+ * I don't know whether it's worth the extra CPU
+ * time to do the right check or not.
+ */
+ return gen_cmp(OR_MACPL, 6, BPF_H, (bpf_int32)proto);
+ }
+ }
+}
+
+static struct block *
+gen_hostop(addr, mask, dir, proto, src_off, dst_off)
+ bpf_u_int32 addr;
+ bpf_u_int32 mask;
+ int dir, proto;
+ u_int src_off, dst_off;
+{
+ struct block *b0, *b1;
+ u_int offset;
+
+ switch (dir) {
+
+ case Q_SRC:
+ offset = src_off;
+ break;
+
+ case Q_DST:
+ offset = dst_off;
+ break;
+
+ case Q_AND:
+ b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off);
+ b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_OR:
+ case Q_DEFAULT:
+ b0 = gen_hostop(addr, mask, Q_SRC, proto, src_off, dst_off);
+ b1 = gen_hostop(addr, mask, Q_DST, proto, src_off, dst_off);
+ gen_or(b0, b1);
+ return b1;
+
+ default:
+ abort();
+ }
+ b0 = gen_linktype(proto);
+ b1 = gen_mcmp(OR_NET, offset, BPF_W, (bpf_int32)addr, mask);
+ gen_and(b0, b1);
+ return b1;
+}
+
+#ifdef INET6
+static struct block *
+gen_hostop6(addr, mask, dir, proto, src_off, dst_off)
+ struct in6_addr *addr;
+ struct in6_addr *mask;
+ int dir, proto;
+ u_int src_off, dst_off;
+{
+ struct block *b0, *b1;
+ u_int offset;
+ u_int32_t *a, *m;
+
+ switch (dir) {
+
+ case Q_SRC:
+ offset = src_off;
+ break;
+
+ case Q_DST:
+ offset = dst_off;
+ break;
+
+ case Q_AND:
+ b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off);
+ b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_OR:
+ case Q_DEFAULT:
+ b0 = gen_hostop6(addr, mask, Q_SRC, proto, src_off, dst_off);
+ b1 = gen_hostop6(addr, mask, Q_DST, proto, src_off, dst_off);
+ gen_or(b0, b1);
+ return b1;
+
+ default:
+ abort();
+ }
+ /* this order is important */
+ a = (u_int32_t *)addr;
+ m = (u_int32_t *)mask;
+ b1 = gen_mcmp(OR_NET, offset + 12, BPF_W, ntohl(a[3]), ntohl(m[3]));
+ b0 = gen_mcmp(OR_NET, offset + 8, BPF_W, ntohl(a[2]), ntohl(m[2]));
+ gen_and(b0, b1);
+ b0 = gen_mcmp(OR_NET, offset + 4, BPF_W, ntohl(a[1]), ntohl(m[1]));
+ gen_and(b0, b1);
+ b0 = gen_mcmp(OR_NET, offset + 0, BPF_W, ntohl(a[0]), ntohl(m[0]));
+ gen_and(b0, b1);
+ b0 = gen_linktype(proto);
+ gen_and(b0, b1);
+ return b1;
+}
+#endif
+
+static struct block *
+gen_ehostop(eaddr, dir)
+ register const u_char *eaddr;
+ register int dir;
+{
+ register struct block *b0, *b1;
+
+ switch (dir) {
+ case Q_SRC:
+ return gen_bcmp(OR_LINK, off_mac + 6, 6, eaddr);
+
+ case Q_DST:
+ return gen_bcmp(OR_LINK, off_mac + 0, 6, eaddr);
+
+ case Q_AND:
+ b0 = gen_ehostop(eaddr, Q_SRC);
+ b1 = gen_ehostop(eaddr, Q_DST);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_DEFAULT:
+ case Q_OR:
+ b0 = gen_ehostop(eaddr, Q_SRC);
+ b1 = gen_ehostop(eaddr, Q_DST);
+ gen_or(b0, b1);
+ return b1;
+
+ case Q_ADDR1:
+ bpf_error("'addr1' is only supported on 802.11 with 802.11 headers");
+ break;
+
+ case Q_ADDR2:
+ bpf_error("'addr2' is only supported on 802.11 with 802.11 headers");
+ break;
+
+ case Q_ADDR3:
+ bpf_error("'addr3' is only supported on 802.11 with 802.11 headers");
+ break;
+
+ case Q_ADDR4:
+ bpf_error("'addr4' is only supported on 802.11 with 802.11 headers");
+ break;
+
+ case Q_RA:
+ bpf_error("'ra' is only supported on 802.11 with 802.11 headers");
+ break;
+
+ case Q_TA:
+ bpf_error("'ta' is only supported on 802.11 with 802.11 headers");
+ break;
+ }
+ abort();
+ /* NOTREACHED */
+}
+
+/*
+ * Like gen_ehostop, but for DLT_FDDI
+ */
+static struct block *
+gen_fhostop(eaddr, dir)
+ register const u_char *eaddr;
+ register int dir;
+{
+ struct block *b0, *b1;
+
+ switch (dir) {
+ case Q_SRC:
+#ifdef PCAP_FDDIPAD
+ return gen_bcmp(OR_LINK, 6 + 1 + pcap_fddipad, 6, eaddr);
+#else
+ return gen_bcmp(OR_LINK, 6 + 1, 6, eaddr);
+#endif
+
+ case Q_DST:
+#ifdef PCAP_FDDIPAD
+ return gen_bcmp(OR_LINK, 0 + 1 + pcap_fddipad, 6, eaddr);
+#else
+ return gen_bcmp(OR_LINK, 0 + 1, 6, eaddr);
+#endif
+
+ case Q_AND:
+ b0 = gen_fhostop(eaddr, Q_SRC);
+ b1 = gen_fhostop(eaddr, Q_DST);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_DEFAULT:
+ case Q_OR:
+ b0 = gen_fhostop(eaddr, Q_SRC);
+ b1 = gen_fhostop(eaddr, Q_DST);
+ gen_or(b0, b1);
+ return b1;
+
+ case Q_ADDR1:
+ bpf_error("'addr1' is only supported on 802.11");
+ break;
+
+ case Q_ADDR2:
+ bpf_error("'addr2' is only supported on 802.11");
+ break;
+
+ case Q_ADDR3:
+ bpf_error("'addr3' is only supported on 802.11");
+ break;
+
+ case Q_ADDR4:
+ bpf_error("'addr4' is only supported on 802.11");
+ break;
+
+ case Q_RA:
+ bpf_error("'ra' is only supported on 802.11");
+ break;
+
+ case Q_TA:
+ bpf_error("'ta' is only supported on 802.11");
+ break;
+ }
+ abort();
+ /* NOTREACHED */
+}
+
+/*
+ * Like gen_ehostop, but for DLT_IEEE802 (Token Ring)
+ */
+static struct block *
+gen_thostop(eaddr, dir)
+ register const u_char *eaddr;
+ register int dir;
+{
+ register struct block *b0, *b1;
+
+ switch (dir) {
+ case Q_SRC:
+ return gen_bcmp(OR_LINK, 8, 6, eaddr);
+
+ case Q_DST:
+ return gen_bcmp(OR_LINK, 2, 6, eaddr);
+
+ case Q_AND:
+ b0 = gen_thostop(eaddr, Q_SRC);
+ b1 = gen_thostop(eaddr, Q_DST);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_DEFAULT:
+ case Q_OR:
+ b0 = gen_thostop(eaddr, Q_SRC);
+ b1 = gen_thostop(eaddr, Q_DST);
+ gen_or(b0, b1);
+ return b1;
+
+ case Q_ADDR1:
+ bpf_error("'addr1' is only supported on 802.11");
+ break;
+
+ case Q_ADDR2:
+ bpf_error("'addr2' is only supported on 802.11");
+ break;
+
+ case Q_ADDR3:
+ bpf_error("'addr3' is only supported on 802.11");
+ break;
+
+ case Q_ADDR4:
+ bpf_error("'addr4' is only supported on 802.11");
+ break;
+
+ case Q_RA:
+ bpf_error("'ra' is only supported on 802.11");
+ break;
+
+ case Q_TA:
+ bpf_error("'ta' is only supported on 802.11");
+ break;
+ }
+ abort();
+ /* NOTREACHED */
+}
+
+/*
+ * Like gen_ehostop, but for DLT_IEEE802_11 (802.11 wireless LAN) and
+ * various 802.11 + radio headers.
+ */
+static struct block *
+gen_wlanhostop(eaddr, dir)
+ register const u_char *eaddr;
+ register int dir;
+{
+ register struct block *b0, *b1, *b2;
+ register struct slist *s;
+
+#ifdef ENABLE_WLAN_FILTERING_PATCH
+ /*
+ * TODO GV 20070613
+ * We need to disable the optimizer because the optimizer is buggy
+ * and wipes out some LD instructions generated by the below
+ * code to validate the Frame Control bits
+ */
+ no_optimize = 1;
+#endif /* ENABLE_WLAN_FILTERING_PATCH */
+
+ switch (dir) {
+ case Q_SRC:
+ /*
+ * Oh, yuk.
+ *
+ * For control frames, there is no SA.
+ *
+ * For management frames, SA is at an
+ * offset of 10 from the beginning of
+ * the packet.
+ *
+ * For data frames, SA is at an offset
+ * of 10 from the beginning of the packet
+ * if From DS is clear, at an offset of
+ * 16 from the beginning of the packet
+ * if From DS is set and To DS is clear,
+ * and an offset of 24 from the beginning
+ * of the packet if From DS is set and To DS
+ * is set.
+ */
+
+ /*
+ * Generate the tests to be done for data frames
+ * with From DS set.
+ *
+ * First, check for To DS set, i.e. check "link[1] & 0x01".
+ */
+ s = gen_load_a(OR_LINK, 1, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x01; /* To DS */
+ b1->stmts = s;
+
+ /*
+ * If To DS is set, the SA is at 24.
+ */
+ b0 = gen_bcmp(OR_LINK, 24, 6, eaddr);
+ gen_and(b1, b0);
+
+ /*
+ * Now, check for To DS not set, i.e. check
+ * "!(link[1] & 0x01)".
+ */
+ s = gen_load_a(OR_LINK, 1, BPF_B);
+ b2 = new_block(JMP(BPF_JSET));
+ b2->s.k = 0x01; /* To DS */
+ b2->stmts = s;
+ gen_not(b2);
+
+ /*
+ * If To DS is not set, the SA is at 16.
+ */
+ b1 = gen_bcmp(OR_LINK, 16, 6, eaddr);
+ gen_and(b2, b1);
+
+ /*
+ * Now OR together the last two checks. That gives
+ * the complete set of checks for data frames with
+ * From DS set.
+ */
+ gen_or(b1, b0);
+
+ /*
+ * Now check for From DS being set, and AND that with
+ * the ORed-together checks.
+ */
+ s = gen_load_a(OR_LINK, 1, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x02; /* From DS */
+ b1->stmts = s;
+ gen_and(b1, b0);
+
+ /*
+ * Now check for data frames with From DS not set.
+ */
+ s = gen_load_a(OR_LINK, 1, BPF_B);
+ b2 = new_block(JMP(BPF_JSET));
+ b2->s.k = 0x02; /* From DS */
+ b2->stmts = s;
+ gen_not(b2);
+
+ /*
+ * If From DS isn't set, the SA is at 10.
+ */
+ b1 = gen_bcmp(OR_LINK, 10, 6, eaddr);
+ gen_and(b2, b1);
+
+ /*
+ * Now OR together the checks for data frames with
+ * From DS not set and for data frames with From DS
+ * set; that gives the checks done for data frames.
+ */
+ gen_or(b1, b0);
+
+ /*
+ * Now check for a data frame.
+ * I.e, check "link[0] & 0x08".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x08;
+ b1->stmts = s;
+
+ /*
+ * AND that with the checks done for data frames.
+ */
+ gen_and(b1, b0);
+
+ /*
+ * If the high-order bit of the type value is 0, this
+ * is a management frame.
+ * I.e, check "!(link[0] & 0x08)".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b2 = new_block(JMP(BPF_JSET));
+ b2->s.k = 0x08;
+ b2->stmts = s;
+ gen_not(b2);
+
+ /*
+ * For management frames, the SA is at 10.
+ */
+ b1 = gen_bcmp(OR_LINK, 10, 6, eaddr);
+ gen_and(b2, b1);
+
+ /*
+ * OR that with the checks done for data frames.
+ * That gives the checks done for management and
+ * data frames.
+ */
+ gen_or(b1, b0);
+
+ /*
+ * If the low-order bit of the type value is 1,
+ * this is either a control frame or a frame
+ * with a reserved type, and thus not a
+ * frame with an SA.
+ *
+ * I.e., check "!(link[0] & 0x04)".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x04;
+ b1->stmts = s;
+ gen_not(b1);
+
+ /*
+ * AND that with the checks for data and management
+ * frames.
+ */
+ gen_and(b1, b0);
+ return b0;
+
+ case Q_DST:
+ /*
+ * Oh, yuk.
+ *
+ * For control frames, there is no DA.
+ *
+ * For management frames, DA is at an
+ * offset of 4 from the beginning of
+ * the packet.
+ *
+ * For data frames, DA is at an offset
+ * of 4 from the beginning of the packet
+ * if To DS is clear and at an offset of
+ * 16 from the beginning of the packet
+ * if To DS is set.
+ */
+
+ /*
+ * Generate the tests to be done for data frames.
+ *
+ * First, check for To DS set, i.e. "link[1] & 0x01".
+ */
+ s = gen_load_a(OR_LINK, 1, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x01; /* To DS */
+ b1->stmts = s;
+
+ /*
+ * If To DS is set, the DA is at 16.
+ */
+ b0 = gen_bcmp(OR_LINK, 16, 6, eaddr);
+ gen_and(b1, b0);
+
+ /*
+ * Now, check for To DS not set, i.e. check
+ * "!(link[1] & 0x01)".
+ */
+ s = gen_load_a(OR_LINK, 1, BPF_B);
+ b2 = new_block(JMP(BPF_JSET));
+ b2->s.k = 0x01; /* To DS */
+ b2->stmts = s;
+ gen_not(b2);
+
+ /*
+ * If To DS is not set, the DA is at 4.
+ */
+ b1 = gen_bcmp(OR_LINK, 4, 6, eaddr);
+ gen_and(b2, b1);
+
+ /*
+ * Now OR together the last two checks. That gives
+ * the complete set of checks for data frames.
+ */
+ gen_or(b1, b0);
+
+ /*
+ * Now check for a data frame.
+ * I.e, check "link[0] & 0x08".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x08;
+ b1->stmts = s;
+
+ /*
+ * AND that with the checks done for data frames.
+ */
+ gen_and(b1, b0);
+
+ /*
+ * If the high-order bit of the type value is 0, this
+ * is a management frame.
+ * I.e, check "!(link[0] & 0x08)".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b2 = new_block(JMP(BPF_JSET));
+ b2->s.k = 0x08;
+ b2->stmts = s;
+ gen_not(b2);
+
+ /*
+ * For management frames, the DA is at 4.
+ */
+ b1 = gen_bcmp(OR_LINK, 4, 6, eaddr);
+ gen_and(b2, b1);
+
+ /*
+ * OR that with the checks done for data frames.
+ * That gives the checks done for management and
+ * data frames.
+ */
+ gen_or(b1, b0);
+
+ /*
+ * If the low-order bit of the type value is 1,
+ * this is either a control frame or a frame
+ * with a reserved type, and thus not a
+ * frame with an SA.
+ *
+ * I.e., check "!(link[0] & 0x04)".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x04;
+ b1->stmts = s;
+ gen_not(b1);
+
+ /*
+ * AND that with the checks for data and management
+ * frames.
+ */
+ gen_and(b1, b0);
+ return b0;
+
+ case Q_RA:
+ /*
+ * Not present in management frames; addr1 in other
+ * frames.
+ */
+
+ /*
+ * If the high-order bit of the type value is 0, this
+ * is a management frame.
+ * I.e, check "(link[0] & 0x08)".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x08;
+ b1->stmts = s;
+
+ /*
+ * Check addr1.
+ */
+ b0 = gen_bcmp(OR_LINK, 4, 6, eaddr);
+
+ /*
+ * AND that with the check of addr1.
+ */
+ gen_and(b1, b0);
+ return (b0);
+
+ case Q_TA:
+ /*
+ * Not present in management frames; addr2, if present,
+ * in other frames.
+ */
+
+ /*
+ * Not present in CTS or ACK control frames.
+ */
+ b0 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_TYPE_CTL,
+ IEEE80211_FC0_TYPE_MASK);
+ gen_not(b0);
+ b1 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_SUBTYPE_CTS,
+ IEEE80211_FC0_SUBTYPE_MASK);
+ gen_not(b1);
+ b2 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_SUBTYPE_ACK,
+ IEEE80211_FC0_SUBTYPE_MASK);
+ gen_not(b2);
+ gen_and(b1, b2);
+ gen_or(b0, b2);
+
+ /*
+ * If the high-order bit of the type value is 0, this
+ * is a management frame.
+ * I.e, check "(link[0] & 0x08)".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x08;
+ b1->stmts = s;
+
+ /*
+ * AND that with the check for frames other than
+ * CTS and ACK frames.
+ */
+ gen_and(b1, b2);
+
+ /*
+ * Check addr2.
+ */
+ b1 = gen_bcmp(OR_LINK, 10, 6, eaddr);
+ gen_and(b2, b1);
+ return b1;
+
+ /*
+ * XXX - add BSSID keyword?
+ */
+ case Q_ADDR1:
+ return (gen_bcmp(OR_LINK, 4, 6, eaddr));
+
+ case Q_ADDR2:
+ /*
+ * Not present in CTS or ACK control frames.
+ */
+ b0 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_TYPE_CTL,
+ IEEE80211_FC0_TYPE_MASK);
+ gen_not(b0);
+ b1 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_SUBTYPE_CTS,
+ IEEE80211_FC0_SUBTYPE_MASK);
+ gen_not(b1);
+ b2 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_SUBTYPE_ACK,
+ IEEE80211_FC0_SUBTYPE_MASK);
+ gen_not(b2);
+ gen_and(b1, b2);
+ gen_or(b0, b2);
+ b1 = gen_bcmp(OR_LINK, 10, 6, eaddr);
+ gen_and(b2, b1);
+ return b1;
+
+ case Q_ADDR3:
+ /*
+ * Not present in control frames.
+ */
+ b0 = gen_mcmp(OR_LINK, 0, BPF_B, IEEE80211_FC0_TYPE_CTL,
+ IEEE80211_FC0_TYPE_MASK);
+ gen_not(b0);
+ b1 = gen_bcmp(OR_LINK, 16, 6, eaddr);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_ADDR4:
+ /*
+ * Present only if the direction mask has both "From DS"
+ * and "To DS" set. Neither control frames nor management
+ * frames should have both of those set, so we don't
+ * check the frame type.
+ */
+ b0 = gen_mcmp(OR_LINK, 1, BPF_B,
+ IEEE80211_FC1_DIR_DSTODS, IEEE80211_FC1_DIR_MASK);
+ b1 = gen_bcmp(OR_LINK, 24, 6, eaddr);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_AND:
+ b0 = gen_wlanhostop(eaddr, Q_SRC);
+ b1 = gen_wlanhostop(eaddr, Q_DST);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_DEFAULT:
+ case Q_OR:
+ b0 = gen_wlanhostop(eaddr, Q_SRC);
+ b1 = gen_wlanhostop(eaddr, Q_DST);
+ gen_or(b0, b1);
+ return b1;
+ }
+ abort();
+ /* NOTREACHED */
+}
+
+/*
+ * Like gen_ehostop, but for RFC 2625 IP-over-Fibre-Channel.
+ * (We assume that the addresses are IEEE 48-bit MAC addresses,
+ * as the RFC states.)
+ */
+static struct block *
+gen_ipfchostop(eaddr, dir)
+ register const u_char *eaddr;
+ register int dir;
+{
+ register struct block *b0, *b1;
+
+ switch (dir) {
+ case Q_SRC:
+ return gen_bcmp(OR_LINK, 10, 6, eaddr);
+
+ case Q_DST:
+ return gen_bcmp(OR_LINK, 2, 6, eaddr);
+
+ case Q_AND:
+ b0 = gen_ipfchostop(eaddr, Q_SRC);
+ b1 = gen_ipfchostop(eaddr, Q_DST);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_DEFAULT:
+ case Q_OR:
+ b0 = gen_ipfchostop(eaddr, Q_SRC);
+ b1 = gen_ipfchostop(eaddr, Q_DST);
+ gen_or(b0, b1);
+ return b1;
+
+ case Q_ADDR1:
+ bpf_error("'addr1' is only supported on 802.11");
+ break;
+
+ case Q_ADDR2:
+ bpf_error("'addr2' is only supported on 802.11");
+ break;
+
+ case Q_ADDR3:
+ bpf_error("'addr3' is only supported on 802.11");
+ break;
+
+ case Q_ADDR4:
+ bpf_error("'addr4' is only supported on 802.11");
+ break;
+
+ case Q_RA:
+ bpf_error("'ra' is only supported on 802.11");
+ break;
+
+ case Q_TA:
+ bpf_error("'ta' is only supported on 802.11");
+ break;
+ }
+ abort();
+ /* NOTREACHED */
+}
+
+/*
+ * This is quite tricky because there may be pad bytes in front of the
+ * DECNET header, and then there are two possible data packet formats that
+ * carry both src and dst addresses, plus 5 packet types in a format that
+ * carries only the src node, plus 2 types that use a different format and
+ * also carry just the src node.
+ *
+ * Yuck.
+ *
+ * Instead of doing those all right, we just look for data packets with
+ * 0 or 1 bytes of padding. If you want to look at other packets, that
+ * will require a lot more hacking.
+ *
+ * To add support for filtering on DECNET "areas" (network numbers)
+ * one would want to add a "mask" argument to this routine. That would
+ * make the filter even more inefficient, although one could be clever
+ * and not generate masking instructions if the mask is 0xFFFF.
+ */
+static struct block *
+gen_dnhostop(addr, dir)
+ bpf_u_int32 addr;
+ int dir;
+{
+ struct block *b0, *b1, *b2, *tmp;
+ u_int offset_lh; /* offset if long header is received */
+ u_int offset_sh; /* offset if short header is received */
+
+ switch (dir) {
+
+ case Q_DST:
+ offset_sh = 1; /* follows flags */
+ offset_lh = 7; /* flgs,darea,dsubarea,HIORD */
+ break;
+
+ case Q_SRC:
+ offset_sh = 3; /* follows flags, dstnode */
+ offset_lh = 15; /* flgs,darea,dsubarea,did,sarea,ssub,HIORD */
+ break;
+
+ case Q_AND:
+ /* Inefficient because we do our Calvinball dance twice */
+ b0 = gen_dnhostop(addr, Q_SRC);
+ b1 = gen_dnhostop(addr, Q_DST);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_OR:
+ case Q_DEFAULT:
+ /* Inefficient because we do our Calvinball dance twice */
+ b0 = gen_dnhostop(addr, Q_SRC);
+ b1 = gen_dnhostop(addr, Q_DST);
+ gen_or(b0, b1);
+ return b1;
+
+ case Q_ISO:
+ bpf_error("ISO host filtering not implemented");
+
+ default:
+ abort();
+ }
+ b0 = gen_linktype(ETHERTYPE_DN);
+ /* Check for pad = 1, long header case */
+ tmp = gen_mcmp(OR_NET, 2, BPF_H,
+ (bpf_int32)ntohs(0x0681), (bpf_int32)ntohs(0x07FF));
+ b1 = gen_cmp(OR_NET, 2 + 1 + offset_lh,
+ BPF_H, (bpf_int32)ntohs((u_short)addr));
+ gen_and(tmp, b1);
+ /* Check for pad = 0, long header case */
+ tmp = gen_mcmp(OR_NET, 2, BPF_B, (bpf_int32)0x06, (bpf_int32)0x7);
+ b2 = gen_cmp(OR_NET, 2 + offset_lh, BPF_H, (bpf_int32)ntohs((u_short)addr));
+ gen_and(tmp, b2);
+ gen_or(b2, b1);
+ /* Check for pad = 1, short header case */
+ tmp = gen_mcmp(OR_NET, 2, BPF_H,
+ (bpf_int32)ntohs(0x0281), (bpf_int32)ntohs(0x07FF));
+ b2 = gen_cmp(OR_NET, 2 + 1 + offset_sh, BPF_H, (bpf_int32)ntohs((u_short)addr));
+ gen_and(tmp, b2);
+ gen_or(b2, b1);
+ /* Check for pad = 0, short header case */
+ tmp = gen_mcmp(OR_NET, 2, BPF_B, (bpf_int32)0x02, (bpf_int32)0x7);
+ b2 = gen_cmp(OR_NET, 2 + offset_sh, BPF_H, (bpf_int32)ntohs((u_short)addr));
+ gen_and(tmp, b2);
+ gen_or(b2, b1);
+
+ /* Combine with test for linktype */
+ gen_and(b0, b1);
+ return b1;
+}
+
+/*
+ * Generate a check for IPv4 or IPv6 for MPLS-encapsulated packets;
+ * test the bottom-of-stack bit, and then check the version number
+ * field in the IP header.
+ */
+static struct block *
+gen_mpls_linktype(proto)
+ int proto;
+{
+ struct block *b0, *b1;
+
+ switch (proto) {
+
+ case Q_IP:
+ /* match the bottom-of-stack bit */
+ b0 = gen_mcmp(OR_NET, -2, BPF_B, 0x01, 0x01);
+ /* match the IPv4 version number */
+ b1 = gen_mcmp(OR_NET, 0, BPF_B, 0x40, 0xf0);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_IPV6:
+ /* match the bottom-of-stack bit */
+ b0 = gen_mcmp(OR_NET, -2, BPF_B, 0x01, 0x01);
+ /* match the IPv4 version number */
+ b1 = gen_mcmp(OR_NET, 0, BPF_B, 0x60, 0xf0);
+ gen_and(b0, b1);
+ return b1;
+
+ default:
+ abort();
+ }
+}
+
+static struct block *
+gen_host(addr, mask, proto, dir, type)
+ bpf_u_int32 addr;
+ bpf_u_int32 mask;
+ int proto;
+ int dir;
+ int type;
+{
+ struct block *b0, *b1;
+ const char *typestr;
+
+ if (type == Q_NET)
+ typestr = "net";
+ else
+ typestr = "host";
+
+ switch (proto) {
+
+ case Q_DEFAULT:
+ b0 = gen_host(addr, mask, Q_IP, dir, type);
+ /*
+ * Only check for non-IPv4 addresses if we're not
+ * checking MPLS-encapsulated packets.
+ */
+ if (label_stack_depth == 0) {
+ b1 = gen_host(addr, mask, Q_ARP, dir, type);
+ gen_or(b0, b1);
+ b0 = gen_host(addr, mask, Q_RARP, dir, type);
+ gen_or(b1, b0);
+ }
+ return b0;
+
+ case Q_IP:
+ return gen_hostop(addr, mask, dir, ETHERTYPE_IP, 12, 16);
+
+ case Q_RARP:
+ return gen_hostop(addr, mask, dir, ETHERTYPE_REVARP, 14, 24);
+
+ case Q_ARP:
+ return gen_hostop(addr, mask, dir, ETHERTYPE_ARP, 14, 24);
+
+ case Q_TCP:
+ bpf_error("'tcp' modifier applied to %s", typestr);
+
+ case Q_SCTP:
+ bpf_error("'sctp' modifier applied to %s", typestr);
+
+ case Q_UDP:
+ bpf_error("'udp' modifier applied to %s", typestr);
+
+ case Q_ICMP:
+ bpf_error("'icmp' modifier applied to %s", typestr);
+
+ case Q_IGMP:
+ bpf_error("'igmp' modifier applied to %s", typestr);
+
+ case Q_IGRP:
+ bpf_error("'igrp' modifier applied to %s", typestr);
+
+ case Q_PIM:
+ bpf_error("'pim' modifier applied to %s", typestr);
+
+ case Q_VRRP:
+ bpf_error("'vrrp' modifier applied to %s", typestr);
+
+ case Q_CARP:
+ bpf_error("'carp' modifier applied to %s", typestr);
+
+ case Q_ATALK:
+ bpf_error("ATALK host filtering not implemented");
+
+ case Q_AARP:
+ bpf_error("AARP host filtering not implemented");
+
+ case Q_DECNET:
+ return gen_dnhostop(addr, dir);
+
+ case Q_SCA:
+ bpf_error("SCA host filtering not implemented");
+
+ case Q_LAT:
+ bpf_error("LAT host filtering not implemented");
+
+ case Q_MOPDL:
+ bpf_error("MOPDL host filtering not implemented");
+
+ case Q_MOPRC:
+ bpf_error("MOPRC host filtering not implemented");
+
+ case Q_IPV6:
+ bpf_error("'ip6' modifier applied to ip host");
+
+ case Q_ICMPV6:
+ bpf_error("'icmp6' modifier applied to %s", typestr);
+
+ case Q_AH:
+ bpf_error("'ah' modifier applied to %s", typestr);
+
+ case Q_ESP:
+ bpf_error("'esp' modifier applied to %s", typestr);
+
+ case Q_ISO:
+ bpf_error("ISO host filtering not implemented");
+
+ case Q_ESIS:
+ bpf_error("'esis' modifier applied to %s", typestr);
+
+ case Q_ISIS:
+ bpf_error("'isis' modifier applied to %s", typestr);
+
+ case Q_CLNP:
+ bpf_error("'clnp' modifier applied to %s", typestr);
+
+ case Q_STP:
+ bpf_error("'stp' modifier applied to %s", typestr);
+
+ case Q_IPX:
+ bpf_error("IPX host filtering not implemented");
+
+ case Q_NETBEUI:
+ bpf_error("'netbeui' modifier applied to %s", typestr);
+
+ case Q_RADIO:
+ bpf_error("'radio' modifier applied to %s", typestr);
+
+ default:
+ abort();
+ }
+ /* NOTREACHED */
+}
+
+#ifdef INET6
+static struct block *
+gen_host6(addr, mask, proto, dir, type)
+ struct in6_addr *addr;
+ struct in6_addr *mask;
+ int proto;
+ int dir;
+ int type;
+{
+ const char *typestr;
+
+ if (type == Q_NET)
+ typestr = "net";
+ else
+ typestr = "host";
+
+ switch (proto) {
+
+ case Q_DEFAULT:
+ return gen_host6(addr, mask, Q_IPV6, dir, type);
+
+ case Q_IP:
+ bpf_error("'ip' modifier applied to ip6 %s", typestr);
+
+ case Q_RARP:
+ bpf_error("'rarp' modifier applied to ip6 %s", typestr);
+
+ case Q_ARP:
+ bpf_error("'arp' modifier applied to ip6 %s", typestr);
+
+ case Q_SCTP:
+ bpf_error("'sctp' modifier applied to %s", typestr);
+
+ case Q_TCP:
+ bpf_error("'tcp' modifier applied to %s", typestr);
+
+ case Q_UDP:
+ bpf_error("'udp' modifier applied to %s", typestr);
+
+ case Q_ICMP:
+ bpf_error("'icmp' modifier applied to %s", typestr);
+
+ case Q_IGMP:
+ bpf_error("'igmp' modifier applied to %s", typestr);
+
+ case Q_IGRP:
+ bpf_error("'igrp' modifier applied to %s", typestr);
+
+ case Q_PIM:
+ bpf_error("'pim' modifier applied to %s", typestr);
+
+ case Q_VRRP:
+ bpf_error("'vrrp' modifier applied to %s", typestr);
+
+ case Q_CARP:
+ bpf_error("'carp' modifier applied to %s", typestr);
+
+ case Q_ATALK:
+ bpf_error("ATALK host filtering not implemented");
+
+ case Q_AARP:
+ bpf_error("AARP host filtering not implemented");
+
+ case Q_DECNET:
+ bpf_error("'decnet' modifier applied to ip6 %s", typestr);
+
+ case Q_SCA:
+ bpf_error("SCA host filtering not implemented");
+
+ case Q_LAT:
+ bpf_error("LAT host filtering not implemented");
+
+ case Q_MOPDL:
+ bpf_error("MOPDL host filtering not implemented");
+
+ case Q_MOPRC:
+ bpf_error("MOPRC host filtering not implemented");
+
+ case Q_IPV6:
+ return gen_hostop6(addr, mask, dir, ETHERTYPE_IPV6, 8, 24);
+
+ case Q_ICMPV6:
+ bpf_error("'icmp6' modifier applied to %s", typestr);
+
+ case Q_AH:
+ bpf_error("'ah' modifier applied to %s", typestr);
+
+ case Q_ESP:
+ bpf_error("'esp' modifier applied to %s", typestr);
+
+ case Q_ISO:
+ bpf_error("ISO host filtering not implemented");
+
+ case Q_ESIS:
+ bpf_error("'esis' modifier applied to %s", typestr);
+
+ case Q_ISIS:
+ bpf_error("'isis' modifier applied to %s", typestr);
+
+ case Q_CLNP:
+ bpf_error("'clnp' modifier applied to %s", typestr);
+
+ case Q_STP:
+ bpf_error("'stp' modifier applied to %s", typestr);
+
+ case Q_IPX:
+ bpf_error("IPX host filtering not implemented");
+
+ case Q_NETBEUI:
+ bpf_error("'netbeui' modifier applied to %s", typestr);
+
+ case Q_RADIO:
+ bpf_error("'radio' modifier applied to %s", typestr);
+
+ default:
+ abort();
+ }
+ /* NOTREACHED */
+}
+#endif
+
+#ifndef INET6
+static struct block *
+gen_gateway(eaddr, alist, proto, dir)
+ const u_char *eaddr;
+ bpf_u_int32 **alist;
+ int proto;
+ int dir;
+{
+ struct block *b0, *b1, *tmp;
+
+ if (dir != 0)
+ bpf_error("direction applied to 'gateway'");
+
+ switch (proto) {
+ case Q_DEFAULT:
+ case Q_IP:
+ case Q_ARP:
+ case Q_RARP:
+ switch (linktype) {
+ case DLT_EN10MB:
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
+ b0 = gen_ehostop(eaddr, Q_OR);
+ break;
+ case DLT_FDDI:
+ b0 = gen_fhostop(eaddr, Q_OR);
+ break;
+ case DLT_IEEE802:
+ b0 = gen_thostop(eaddr, Q_OR);
+ break;
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ case DLT_IEEE802_11_RADIO:
+ case DLT_PPI:
+ b0 = gen_wlanhostop(eaddr, Q_OR);
+ break;
+ case DLT_SUNATM:
+ if (!is_lane)
+ bpf_error(
+ "'gateway' supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel");
+ /*
+ * Check that the packet doesn't begin with an
+ * LE Control marker. (We've already generated
+ * a test for LANE.)
+ */
+ b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS,
+ BPF_H, 0xFF00);
+ gen_not(b1);
+
+ /*
+ * Now check the MAC address.
+ */
+ b0 = gen_ehostop(eaddr, Q_OR);
+ gen_and(b1, b0);
+ break;
+ case DLT_IP_OVER_FC:
+ b0 = gen_ipfchostop(eaddr, Q_OR);
+ break;
+ default:
+ bpf_error(
+ "'gateway' supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel");
+ }
+ b1 = gen_host(**alist++, 0xffffffff, proto, Q_OR, Q_HOST);
+ while (*alist) {
+ tmp = gen_host(**alist++, 0xffffffff, proto, Q_OR,
+ Q_HOST);
+ gen_or(b1, tmp);
+ b1 = tmp;
+ }
+ gen_not(b1);
+ gen_and(b0, b1);
+ return b1;
+ }
+ bpf_error("illegal modifier of 'gateway'");
+ /* NOTREACHED */
+}
+#endif
+
+struct block *
+gen_proto_abbrev(proto)
+ int proto;
+{
+ struct block *b0;
+ struct block *b1;
+
+ switch (proto) {
+
+ case Q_SCTP:
+ b1 = gen_proto(IPPROTO_SCTP, Q_IP, Q_DEFAULT);
+ b0 = gen_proto(IPPROTO_SCTP, Q_IPV6, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_TCP:
+ b1 = gen_proto(IPPROTO_TCP, Q_IP, Q_DEFAULT);
+ b0 = gen_proto(IPPROTO_TCP, Q_IPV6, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_UDP:
+ b1 = gen_proto(IPPROTO_UDP, Q_IP, Q_DEFAULT);
+ b0 = gen_proto(IPPROTO_UDP, Q_IPV6, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_ICMP:
+ b1 = gen_proto(IPPROTO_ICMP, Q_IP, Q_DEFAULT);
+ break;
+
+#ifndef IPPROTO_IGMP
+#define IPPROTO_IGMP 2
+#endif
+
+ case Q_IGMP:
+ b1 = gen_proto(IPPROTO_IGMP, Q_IP, Q_DEFAULT);
+ break;
+
+#ifndef IPPROTO_IGRP
+#define IPPROTO_IGRP 9
+#endif
+ case Q_IGRP:
+ b1 = gen_proto(IPPROTO_IGRP, Q_IP, Q_DEFAULT);
+ break;
+
+#ifndef IPPROTO_PIM
+#define IPPROTO_PIM 103
+#endif
+
+ case Q_PIM:
+ b1 = gen_proto(IPPROTO_PIM, Q_IP, Q_DEFAULT);
+ b0 = gen_proto(IPPROTO_PIM, Q_IPV6, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+#ifndef IPPROTO_VRRP
+#define IPPROTO_VRRP 112
+#endif
+
+ case Q_VRRP:
+ b1 = gen_proto(IPPROTO_VRRP, Q_IP, Q_DEFAULT);
+ break;
+
+#ifndef IPPROTO_CARP
+#define IPPROTO_CARP 112
+#endif
+
+ case Q_CARP:
+ b1 = gen_proto(IPPROTO_CARP, Q_IP, Q_DEFAULT);
+ break;
+
+ case Q_IP:
+ b1 = gen_linktype(ETHERTYPE_IP);
+ break;
+
+ case Q_ARP:
+ b1 = gen_linktype(ETHERTYPE_ARP);
+ break;
+
+ case Q_RARP:
+ b1 = gen_linktype(ETHERTYPE_REVARP);
+ break;
+
+ case Q_LINK:
+ bpf_error("link layer applied in wrong context");
+
+ case Q_ATALK:
+ b1 = gen_linktype(ETHERTYPE_ATALK);
+ break;
+
+ case Q_AARP:
+ b1 = gen_linktype(ETHERTYPE_AARP);
+ break;
+
+ case Q_DECNET:
+ b1 = gen_linktype(ETHERTYPE_DN);
+ break;
+
+ case Q_SCA:
+ b1 = gen_linktype(ETHERTYPE_SCA);
+ break;
+
+ case Q_LAT:
+ b1 = gen_linktype(ETHERTYPE_LAT);
+ break;
+
+ case Q_MOPDL:
+ b1 = gen_linktype(ETHERTYPE_MOPDL);
+ break;
+
+ case Q_MOPRC:
+ b1 = gen_linktype(ETHERTYPE_MOPRC);
+ break;
+
+ case Q_IPV6:
+ b1 = gen_linktype(ETHERTYPE_IPV6);
+ break;
+
+#ifndef IPPROTO_ICMPV6
+#define IPPROTO_ICMPV6 58
+#endif
+ case Q_ICMPV6:
+ b1 = gen_proto(IPPROTO_ICMPV6, Q_IPV6, Q_DEFAULT);
+ break;
+
+#ifndef IPPROTO_AH
+#define IPPROTO_AH 51
+#endif
+ case Q_AH:
+ b1 = gen_proto(IPPROTO_AH, Q_IP, Q_DEFAULT);
+ b0 = gen_proto(IPPROTO_AH, Q_IPV6, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+#ifndef IPPROTO_ESP
+#define IPPROTO_ESP 50
+#endif
+ case Q_ESP:
+ b1 = gen_proto(IPPROTO_ESP, Q_IP, Q_DEFAULT);
+ b0 = gen_proto(IPPROTO_ESP, Q_IPV6, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_ISO:
+ b1 = gen_linktype(LLCSAP_ISONS);
+ break;
+
+ case Q_ESIS:
+ b1 = gen_proto(ISO9542_ESIS, Q_ISO, Q_DEFAULT);
+ break;
+
+ case Q_ISIS:
+ b1 = gen_proto(ISO10589_ISIS, Q_ISO, Q_DEFAULT);
+ break;
+
+ case Q_ISIS_L1: /* all IS-IS Level1 PDU-Types */
+ b0 = gen_proto(ISIS_L1_LAN_IIH, Q_ISIS, Q_DEFAULT);
+ b1 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); /* FIXME extract the circuit-type bits */
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L1_LSP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_ISIS_L2: /* all IS-IS Level2 PDU-Types */
+ b0 = gen_proto(ISIS_L2_LAN_IIH, Q_ISIS, Q_DEFAULT);
+ b1 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT); /* FIXME extract the circuit-type bits */
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L2_LSP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_ISIS_IIH: /* all IS-IS Hello PDU-Types */
+ b0 = gen_proto(ISIS_L1_LAN_IIH, Q_ISIS, Q_DEFAULT);
+ b1 = gen_proto(ISIS_L2_LAN_IIH, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_PTP_IIH, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_ISIS_LSP:
+ b0 = gen_proto(ISIS_L1_LSP, Q_ISIS, Q_DEFAULT);
+ b1 = gen_proto(ISIS_L2_LSP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_ISIS_SNP:
+ b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
+ b1 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ b0 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_ISIS_CSNP:
+ b0 = gen_proto(ISIS_L1_CSNP, Q_ISIS, Q_DEFAULT);
+ b1 = gen_proto(ISIS_L2_CSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_ISIS_PSNP:
+ b0 = gen_proto(ISIS_L1_PSNP, Q_ISIS, Q_DEFAULT);
+ b1 = gen_proto(ISIS_L2_PSNP, Q_ISIS, Q_DEFAULT);
+ gen_or(b0, b1);
+ break;
+
+ case Q_CLNP:
+ b1 = gen_proto(ISO8473_CLNP, Q_ISO, Q_DEFAULT);
+ break;
+
+ case Q_STP:
+ b1 = gen_linktype(LLCSAP_8021D);
+ break;
+
+ case Q_IPX:
+ b1 = gen_linktype(LLCSAP_IPX);
+ break;
+
+ case Q_NETBEUI:
+ b1 = gen_linktype(LLCSAP_NETBEUI);
+ break;
+
+ case Q_RADIO:
+ bpf_error("'radio' is not a valid protocol type");
+
+ default:
+ abort();
+ }
+ return b1;
+}
+
+static struct block *
+gen_ipfrag()
+{
+ struct slist *s;
+ struct block *b;
+
+ /* not IPv4 frag other than the first frag */
+ s = gen_load_a(OR_NET, 6, BPF_H);
+ b = new_block(JMP(BPF_JSET));
+ b->s.k = 0x1fff;
+ b->stmts = s;
+ gen_not(b);
+
+ return b;
+}
+
+/*
+ * Generate a comparison to a port value in the transport-layer header
+ * at the specified offset from the beginning of that header.
+ *
+ * XXX - this handles a variable-length prefix preceding the link-layer
+ * header, such as the radiotap or AVS radio prefix, but doesn't handle
+ * variable-length link-layer headers (such as Token Ring or 802.11
+ * headers).
+ */
+static struct block *
+gen_portatom(off, v)
+ int off;
+ bpf_int32 v;
+{
+ return gen_cmp(OR_TRAN_IPV4, off, BPF_H, v);
+}
+
+static struct block *
+gen_portatom6(off, v)
+ int off;
+ bpf_int32 v;
+{
+ return gen_cmp(OR_TRAN_IPV6, off, BPF_H, v);
+}
+
+struct block *
+gen_portop(port, proto, dir)
+ int port, proto, dir;
+{
+ struct block *b0, *b1, *tmp;
+
+ /* ip proto 'proto' and not a fragment other than the first fragment */
+ tmp = gen_cmp(OR_NET, 9, BPF_B, (bpf_int32)proto);
+ b0 = gen_ipfrag();
+ gen_and(tmp, b0);
+
+ switch (dir) {
+ case Q_SRC:
+ b1 = gen_portatom(0, (bpf_int32)port);
+ break;
+
+ case Q_DST:
+ b1 = gen_portatom(2, (bpf_int32)port);
+ break;
+
+ case Q_OR:
+ case Q_DEFAULT:
+ tmp = gen_portatom(0, (bpf_int32)port);
+ b1 = gen_portatom(2, (bpf_int32)port);
+ gen_or(tmp, b1);
+ break;
+
+ case Q_AND:
+ tmp = gen_portatom(0, (bpf_int32)port);
+ b1 = gen_portatom(2, (bpf_int32)port);
+ gen_and(tmp, b1);
+ break;
+
+ default:
+ abort();
+ }
+ gen_and(b0, b1);
+
+ return b1;
+}
+
+static struct block *
+gen_port(port, ip_proto, dir)
+ int port;
+ int ip_proto;
+ int dir;
+{
+ struct block *b0, *b1, *tmp;
+
+ /*
+ * ether proto ip
+ *
+ * For FDDI, RFC 1188 says that SNAP encapsulation is used,
+ * not LLC encapsulation with LLCSAP_IP.
+ *
+ * For IEEE 802 networks - which includes 802.5 token ring
+ * (which is what DLT_IEEE802 means) and 802.11 - RFC 1042
+ * says that SNAP encapsulation is used, not LLC encapsulation
+ * with LLCSAP_IP.
+ *
+ * For LLC-encapsulated ATM/"Classical IP", RFC 1483 and
+ * RFC 2225 say that SNAP encapsulation is used, not LLC
+ * encapsulation with LLCSAP_IP.
+ *
+ * So we always check for ETHERTYPE_IP.
+ */
+ b0 = gen_linktype(ETHERTYPE_IP);
+
+ switch (ip_proto) {
+ case IPPROTO_UDP:
+ case IPPROTO_TCP:
+ case IPPROTO_SCTP:
+ b1 = gen_portop(port, ip_proto, dir);
+ break;
+
+ case PROTO_UNDEF:
+ tmp = gen_portop(port, IPPROTO_TCP, dir);
+ b1 = gen_portop(port, IPPROTO_UDP, dir);
+ gen_or(tmp, b1);
+ tmp = gen_portop(port, IPPROTO_SCTP, dir);
+ gen_or(tmp, b1);
+ break;
+
+ default:
+ abort();
+ }
+ gen_and(b0, b1);
+ return b1;
+}
+
+struct block *
+gen_portop6(port, proto, dir)
+ int port, proto, dir;
+{
+ struct block *b0, *b1, *tmp;
+
+ /* ip6 proto 'proto' */
+ /* XXX - catch the first fragment of a fragmented packet? */
+ b0 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)proto);
+
+ switch (dir) {
+ case Q_SRC:
+ b1 = gen_portatom6(0, (bpf_int32)port);
+ break;
+
+ case Q_DST:
+ b1 = gen_portatom6(2, (bpf_int32)port);
+ break;
+
+ case Q_OR:
+ case Q_DEFAULT:
+ tmp = gen_portatom6(0, (bpf_int32)port);
+ b1 = gen_portatom6(2, (bpf_int32)port);
+ gen_or(tmp, b1);
+ break;
+
+ case Q_AND:
+ tmp = gen_portatom6(0, (bpf_int32)port);
+ b1 = gen_portatom6(2, (bpf_int32)port);
+ gen_and(tmp, b1);
+ break;
+
+ default:
+ abort();
+ }
+ gen_and(b0, b1);
+
+ return b1;
+}
+
+static struct block *
+gen_port6(port, ip_proto, dir)
+ int port;
+ int ip_proto;
+ int dir;
+{
+ struct block *b0, *b1, *tmp;
+
+ /* link proto ip6 */
+ b0 = gen_linktype(ETHERTYPE_IPV6);
+
+ switch (ip_proto) {
+ case IPPROTO_UDP:
+ case IPPROTO_TCP:
+ case IPPROTO_SCTP:
+ b1 = gen_portop6(port, ip_proto, dir);
+ break;
+
+ case PROTO_UNDEF:
+ tmp = gen_portop6(port, IPPROTO_TCP, dir);
+ b1 = gen_portop6(port, IPPROTO_UDP, dir);
+ gen_or(tmp, b1);
+ tmp = gen_portop6(port, IPPROTO_SCTP, dir);
+ gen_or(tmp, b1);
+ break;
+
+ default:
+ abort();
+ }
+ gen_and(b0, b1);
+ return b1;
+}
+
+/* gen_portrange code */
+static struct block *
+gen_portrangeatom(off, v1, v2)
+ int off;
+ bpf_int32 v1, v2;
+{
+ struct block *b1, *b2;
+
+ if (v1 > v2) {
+ /*
+ * Reverse the order of the ports, so v1 is the lower one.
+ */
+ bpf_int32 vtemp;
+
+ vtemp = v1;
+ v1 = v2;
+ v2 = vtemp;
+ }
+
+ b1 = gen_cmp_ge(OR_TRAN_IPV4, off, BPF_H, v1);
+ b2 = gen_cmp_le(OR_TRAN_IPV4, off, BPF_H, v2);
+
+ gen_and(b1, b2);
+
+ return b2;
+}
+
+struct block *
+gen_portrangeop(port1, port2, proto, dir)
+ int port1, port2;
+ int proto;
+ int dir;
+{
+ struct block *b0, *b1, *tmp;
+
+ /* ip proto 'proto' and not a fragment other than the first fragment */
+ tmp = gen_cmp(OR_NET, 9, BPF_B, (bpf_int32)proto);
+ b0 = gen_ipfrag();
+ gen_and(tmp, b0);
+
+ switch (dir) {
+ case Q_SRC:
+ b1 = gen_portrangeatom(0, (bpf_int32)port1, (bpf_int32)port2);
+ break;
+
+ case Q_DST:
+ b1 = gen_portrangeatom(2, (bpf_int32)port1, (bpf_int32)port2);
+ break;
+
+ case Q_OR:
+ case Q_DEFAULT:
+ tmp = gen_portrangeatom(0, (bpf_int32)port1, (bpf_int32)port2);
+ b1 = gen_portrangeatom(2, (bpf_int32)port1, (bpf_int32)port2);
+ gen_or(tmp, b1);
+ break;
+
+ case Q_AND:
+ tmp = gen_portrangeatom(0, (bpf_int32)port1, (bpf_int32)port2);
+ b1 = gen_portrangeatom(2, (bpf_int32)port1, (bpf_int32)port2);
+ gen_and(tmp, b1);
+ break;
+
+ default:
+ abort();
+ }
+ gen_and(b0, b1);
+
+ return b1;
+}
+
+static struct block *
+gen_portrange(port1, port2, ip_proto, dir)
+ int port1, port2;
+ int ip_proto;
+ int dir;
+{
+ struct block *b0, *b1, *tmp;
+
+ /* link proto ip */
+ b0 = gen_linktype(ETHERTYPE_IP);
+
+ switch (ip_proto) {
+ case IPPROTO_UDP:
+ case IPPROTO_TCP:
+ case IPPROTO_SCTP:
+ b1 = gen_portrangeop(port1, port2, ip_proto, dir);
+ break;
+
+ case PROTO_UNDEF:
+ tmp = gen_portrangeop(port1, port2, IPPROTO_TCP, dir);
+ b1 = gen_portrangeop(port1, port2, IPPROTO_UDP, dir);
+ gen_or(tmp, b1);
+ tmp = gen_portrangeop(port1, port2, IPPROTO_SCTP, dir);
+ gen_or(tmp, b1);
+ break;
+
+ default:
+ abort();
+ }
+ gen_and(b0, b1);
+ return b1;
+}
+
+static struct block *
+gen_portrangeatom6(off, v1, v2)
+ int off;
+ bpf_int32 v1, v2;
+{
+ struct block *b1, *b2;
+
+ if (v1 > v2) {
+ /*
+ * Reverse the order of the ports, so v1 is the lower one.
+ */
+ bpf_int32 vtemp;
+
+ vtemp = v1;
+ v1 = v2;
+ v2 = vtemp;
+ }
+
+ b1 = gen_cmp_ge(OR_TRAN_IPV6, off, BPF_H, v1);
+ b2 = gen_cmp_le(OR_TRAN_IPV6, off, BPF_H, v2);
+
+ gen_and(b1, b2);
+
+ return b2;
+}
+
+struct block *
+gen_portrangeop6(port1, port2, proto, dir)
+ int port1, port2;
+ int proto;
+ int dir;
+{
+ struct block *b0, *b1, *tmp;
+
+ /* ip6 proto 'proto' */
+ /* XXX - catch the first fragment of a fragmented packet? */
+ b0 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)proto);
+
+ switch (dir) {
+ case Q_SRC:
+ b1 = gen_portrangeatom6(0, (bpf_int32)port1, (bpf_int32)port2);
+ break;
+
+ case Q_DST:
+ b1 = gen_portrangeatom6(2, (bpf_int32)port1, (bpf_int32)port2);
+ break;
+
+ case Q_OR:
+ case Q_DEFAULT:
+ tmp = gen_portrangeatom6(0, (bpf_int32)port1, (bpf_int32)port2);
+ b1 = gen_portrangeatom6(2, (bpf_int32)port1, (bpf_int32)port2);
+ gen_or(tmp, b1);
+ break;
+
+ case Q_AND:
+ tmp = gen_portrangeatom6(0, (bpf_int32)port1, (bpf_int32)port2);
+ b1 = gen_portrangeatom6(2, (bpf_int32)port1, (bpf_int32)port2);
+ gen_and(tmp, b1);
+ break;
+
+ default:
+ abort();
+ }
+ gen_and(b0, b1);
+
+ return b1;
+}
+
+static struct block *
+gen_portrange6(port1, port2, ip_proto, dir)
+ int port1, port2;
+ int ip_proto;
+ int dir;
+{
+ struct block *b0, *b1, *tmp;
+
+ /* link proto ip6 */
+ b0 = gen_linktype(ETHERTYPE_IPV6);
+
+ switch (ip_proto) {
+ case IPPROTO_UDP:
+ case IPPROTO_TCP:
+ case IPPROTO_SCTP:
+ b1 = gen_portrangeop6(port1, port2, ip_proto, dir);
+ break;
+
+ case PROTO_UNDEF:
+ tmp = gen_portrangeop6(port1, port2, IPPROTO_TCP, dir);
+ b1 = gen_portrangeop6(port1, port2, IPPROTO_UDP, dir);
+ gen_or(tmp, b1);
+ tmp = gen_portrangeop6(port1, port2, IPPROTO_SCTP, dir);
+ gen_or(tmp, b1);
+ break;
+
+ default:
+ abort();
+ }
+ gen_and(b0, b1);
+ return b1;
+}
+
+static int
+lookup_proto(name, proto)
+ register const char *name;
+ register int proto;
+{
+ register int v;
+
+ switch (proto) {
+
+ case Q_DEFAULT:
+ case Q_IP:
+ case Q_IPV6:
+ v = pcap_nametoproto(name);
+ if (v == PROTO_UNDEF)
+ bpf_error("unknown ip proto '%s'", name);
+ break;
+
+ case Q_LINK:
+ /* XXX should look up h/w protocol type based on linktype */
+ v = pcap_nametoeproto(name);
+ if (v == PROTO_UNDEF) {
+ v = pcap_nametollc(name);
+ if (v == PROTO_UNDEF)
+ bpf_error("unknown ether proto '%s'", name);
+ }
+ break;
+
+ case Q_ISO:
+ if (strcmp(name, "esis") == 0)
+ v = ISO9542_ESIS;
+ else if (strcmp(name, "isis") == 0)
+ v = ISO10589_ISIS;
+ else if (strcmp(name, "clnp") == 0)
+ v = ISO8473_CLNP;
+ else
+ bpf_error("unknown osi proto '%s'", name);
+ break;
+
+ default:
+ v = PROTO_UNDEF;
+ break;
+ }
+ return v;
+}
+
+#if 0
+struct stmt *
+gen_joinsp(s, n)
+ struct stmt **s;
+ int n;
+{
+ return NULL;
+}
+#endif
+
+static struct block *
+gen_protochain(v, proto, dir)
+ int v;
+ int proto;
+ int dir;
+{
+#ifdef NO_PROTOCHAIN
+ return gen_proto(v, proto, dir);
+#else
+ struct block *b0, *b;
+ struct slist *s[100];
+ int fix2, fix3, fix4, fix5;
+ int ahcheck, again, end;
+ int i, max;
+ int reg2 = alloc_reg();
+
+ memset(s, 0, sizeof(s));
+ fix2 = fix3 = fix4 = fix5 = 0;
+
+ switch (proto) {
+ case Q_IP:
+ case Q_IPV6:
+ break;
+ case Q_DEFAULT:
+ b0 = gen_protochain(v, Q_IP, dir);
+ b = gen_protochain(v, Q_IPV6, dir);
+ gen_or(b0, b);
+ return b;
+ default:
+ bpf_error("bad protocol applied for 'protochain'");
+ /*NOTREACHED*/
+ }
+
+ /*
+ * We don't handle variable-length prefixes before the link-layer
+ * header, or variable-length link-layer headers, here yet.
+ * We might want to add BPF instructions to do the protochain
+ * work, to simplify that and, on platforms that have a BPF
+ * interpreter with the new instructions, let the filtering
+ * be done in the kernel. (We already require a modified BPF
+ * engine to do the protochain stuff, to support backward
+ * branches, and backward branch support is unlikely to appear
+ * in kernel BPF engines.)
+ */
+ switch (linktype) {
+
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ case DLT_IEEE802_11_RADIO:
+ case DLT_PPI:
+ bpf_error("'protochain' not supported with 802.11");
+ }
+
+ no_optimize = 1; /*this code is not compatible with optimzer yet */
+
+ /*
+ * s[0] is a dummy entry to protect other BPF insn from damage
+ * by s[fix] = foo with uninitialized variable "fix". It is somewhat
+ * hard to find interdependency made by jump table fixup.
+ */
+ i = 0;
+ s[i] = new_stmt(0); /*dummy*/
+ i++;
+
+ switch (proto) {
+ case Q_IP:
+ b0 = gen_linktype(ETHERTYPE_IP);
+
+ /* A = ip->ip_p */
+ s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B);
+ s[i]->s.k = off_macpl + off_nl + 9;
+ i++;
+ /* X = ip->ip_hl << 2 */
+ s[i] = new_stmt(BPF_LDX|BPF_MSH|BPF_B);
+ s[i]->s.k = off_macpl + off_nl;
+ i++;
+ break;
+
+ case Q_IPV6:
+ b0 = gen_linktype(ETHERTYPE_IPV6);
+
+ /* A = ip6->ip_nxt */
+ s[i] = new_stmt(BPF_LD|BPF_ABS|BPF_B);
+ s[i]->s.k = off_macpl + off_nl + 6;
+ i++;
+ /* X = sizeof(struct ip6_hdr) */
+ s[i] = new_stmt(BPF_LDX|BPF_IMM);
+ s[i]->s.k = 40;
+ i++;
+ break;
+
+ default:
+ bpf_error("unsupported proto to gen_protochain");
+ /*NOTREACHED*/
+ }
+
+ /* again: if (A == v) goto end; else fall through; */
+ again = i;
+ s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
+ s[i]->s.k = v;
+ s[i]->s.jt = NULL; /*later*/
+ s[i]->s.jf = NULL; /*update in next stmt*/
+ fix5 = i;
+ i++;
+
+#ifndef IPPROTO_NONE
+#define IPPROTO_NONE 59
+#endif
+ /* if (A == IPPROTO_NONE) goto end */
+ s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
+ s[i]->s.jt = NULL; /*later*/
+ s[i]->s.jf = NULL; /*update in next stmt*/
+ s[i]->s.k = IPPROTO_NONE;
+ s[fix5]->s.jf = s[i];
+ fix2 = i;
+ i++;
+
+ if (proto == Q_IPV6) {
+ int v6start, v6end, v6advance, j;
+
+ v6start = i;
+ /* if (A == IPPROTO_HOPOPTS) goto v6advance */
+ s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
+ s[i]->s.jt = NULL; /*later*/
+ s[i]->s.jf = NULL; /*update in next stmt*/
+ s[i]->s.k = IPPROTO_HOPOPTS;
+ s[fix2]->s.jf = s[i];
+ i++;
+ /* if (A == IPPROTO_DSTOPTS) goto v6advance */
+ s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
+ s[i]->s.jt = NULL; /*later*/
+ s[i]->s.jf = NULL; /*update in next stmt*/
+ s[i]->s.k = IPPROTO_DSTOPTS;
+ i++;
+ /* if (A == IPPROTO_ROUTING) goto v6advance */
+ s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
+ s[i]->s.jt = NULL; /*later*/
+ s[i]->s.jf = NULL; /*update in next stmt*/
+ s[i]->s.k = IPPROTO_ROUTING;
+ i++;
+ /* if (A == IPPROTO_FRAGMENT) goto v6advance; else goto ahcheck; */
+ s[i - 1]->s.jf = s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
+ s[i]->s.jt = NULL; /*later*/
+ s[i]->s.jf = NULL; /*later*/
+ s[i]->s.k = IPPROTO_FRAGMENT;
+ fix3 = i;
+ v6end = i;
+ i++;
+
+ /* v6advance: */
+ v6advance = i;
+
+ /*
+ * in short,
+ * A = P[X + packet head];
+ * X = X + (P[X + packet head + 1] + 1) * 8;
+ */
+ /* A = P[X + packet head] */
+ s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
+ s[i]->s.k = off_macpl + off_nl;
+ i++;
+ /* MEM[reg2] = A */
+ s[i] = new_stmt(BPF_ST);
+ s[i]->s.k = reg2;
+ i++;
+ /* A = P[X + packet head + 1]; */
+ s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
+ s[i]->s.k = off_macpl + off_nl + 1;
+ i++;
+ /* A += 1 */
+ s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
+ s[i]->s.k = 1;
+ i++;
+ /* A *= 8 */
+ s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K);
+ s[i]->s.k = 8;
+ i++;
+ /* A += X */
+ s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_X);
+ s[i]->s.k = 0;
+ i++;
+ /* X = A; */
+ s[i] = new_stmt(BPF_MISC|BPF_TAX);
+ i++;
+ /* A = MEM[reg2] */
+ s[i] = new_stmt(BPF_LD|BPF_MEM);
+ s[i]->s.k = reg2;
+ i++;
+
+ /* goto again; (must use BPF_JA for backward jump) */
+ s[i] = new_stmt(BPF_JMP|BPF_JA);
+ s[i]->s.k = again - i - 1;
+ s[i - 1]->s.jf = s[i];
+ i++;
+
+ /* fixup */
+ for (j = v6start; j <= v6end; j++)
+ s[j]->s.jt = s[v6advance];
+ } else {
+ /* nop */
+ s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
+ s[i]->s.k = 0;
+ s[fix2]->s.jf = s[i];
+ i++;
+ }
+
+ /* ahcheck: */
+ ahcheck = i;
+ /* if (A == IPPROTO_AH) then fall through; else goto end; */
+ s[i] = new_stmt(BPF_JMP|BPF_JEQ|BPF_K);
+ s[i]->s.jt = NULL; /*later*/
+ s[i]->s.jf = NULL; /*later*/
+ s[i]->s.k = IPPROTO_AH;
+ if (fix3)
+ s[fix3]->s.jf = s[ahcheck];
+ fix4 = i;
+ i++;
+
+ /*
+ * in short,
+ * A = P[X];
+ * X = X + (P[X + 1] + 2) * 4;
+ */
+ /* A = X */
+ s[i - 1]->s.jt = s[i] = new_stmt(BPF_MISC|BPF_TXA);
+ i++;
+ /* A = P[X + packet head]; */
+ s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
+ s[i]->s.k = off_macpl + off_nl;
+ i++;
+ /* MEM[reg2] = A */
+ s[i] = new_stmt(BPF_ST);
+ s[i]->s.k = reg2;
+ i++;
+ /* A = X */
+ s[i - 1]->s.jt = s[i] = new_stmt(BPF_MISC|BPF_TXA);
+ i++;
+ /* A += 1 */
+ s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
+ s[i]->s.k = 1;
+ i++;
+ /* X = A */
+ s[i] = new_stmt(BPF_MISC|BPF_TAX);
+ i++;
+ /* A = P[X + packet head] */
+ s[i] = new_stmt(BPF_LD|BPF_IND|BPF_B);
+ s[i]->s.k = off_macpl + off_nl;
+ i++;
+ /* A += 2 */
+ s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
+ s[i]->s.k = 2;
+ i++;
+ /* A *= 4 */
+ s[i] = new_stmt(BPF_ALU|BPF_MUL|BPF_K);
+ s[i]->s.k = 4;
+ i++;
+ /* X = A; */
+ s[i] = new_stmt(BPF_MISC|BPF_TAX);
+ i++;
+ /* A = MEM[reg2] */
+ s[i] = new_stmt(BPF_LD|BPF_MEM);
+ s[i]->s.k = reg2;
+ i++;
+
+ /* goto again; (must use BPF_JA for backward jump) */
+ s[i] = new_stmt(BPF_JMP|BPF_JA);
+ s[i]->s.k = again - i - 1;
+ i++;
+
+ /* end: nop */
+ end = i;
+ s[i] = new_stmt(BPF_ALU|BPF_ADD|BPF_K);
+ s[i]->s.k = 0;
+ s[fix2]->s.jt = s[end];
+ s[fix4]->s.jf = s[end];
+ s[fix5]->s.jt = s[end];
+ i++;
+
+ /*
+ * make slist chain
+ */
+ max = i;
+ for (i = 0; i < max - 1; i++)
+ s[i]->next = s[i + 1];
+ s[max - 1]->next = NULL;
+
+ /*
+ * emit final check
+ */
+ b = new_block(JMP(BPF_JEQ));
+ b->stmts = s[1]; /*remember, s[0] is dummy*/
+ b->s.k = v;
+
+ free_reg(reg2);
+
+ gen_and(b0, b);
+ return b;
+#endif
+}
+
+static struct block *
+gen_check_802_11_data_frame()
+{
+ struct slist *s;
+ struct block *b0, *b1;
+
+ /*
+ * A data frame has the 0x08 bit (b3) in the frame control field set
+ * and the 0x04 bit (b2) clear.
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b0 = new_block(JMP(BPF_JSET));
+ b0->s.k = 0x08;
+ b0->stmts = s;
+
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x04;
+ b1->stmts = s;
+ gen_not(b1);
+
+ gen_and(b1, b0);
+
+ return b0;
+}
+
+/*
+ * Generate code that checks whether the packet is a packet for protocol
+ * <proto> and whether the type field in that protocol's header has
+ * the value <v>, e.g. if <proto> is Q_IP, it checks whether it's an
+ * IP packet and checks the protocol number in the IP header against <v>.
+ *
+ * If <proto> is Q_DEFAULT, i.e. just "proto" was specified, it checks
+ * against Q_IP and Q_IPV6.
+ */
+static struct block *
+gen_proto(v, proto, dir)
+ int v;
+ int proto;
+ int dir;
+{
+ struct block *b0, *b1;
+#ifndef CHASE_CHAIN
+ struct block *b2;
+#endif
+
+ if (dir != Q_DEFAULT)
+ bpf_error("direction applied to 'proto'");
+
+ switch (proto) {
+ case Q_DEFAULT:
+ b0 = gen_proto(v, Q_IP, dir);
+ b1 = gen_proto(v, Q_IPV6, dir);
+ gen_or(b0, b1);
+ return b1;
+
+ case Q_IP:
+ /*
+ * For FDDI, RFC 1188 says that SNAP encapsulation is used,
+ * not LLC encapsulation with LLCSAP_IP.
+ *
+ * For IEEE 802 networks - which includes 802.5 token ring
+ * (which is what DLT_IEEE802 means) and 802.11 - RFC 1042
+ * says that SNAP encapsulation is used, not LLC encapsulation
+ * with LLCSAP_IP.
+ *
+ * For LLC-encapsulated ATM/"Classical IP", RFC 1483 and
+ * RFC 2225 say that SNAP encapsulation is used, not LLC
+ * encapsulation with LLCSAP_IP.
+ *
+ * So we always check for ETHERTYPE_IP.
+ */
+ b0 = gen_linktype(ETHERTYPE_IP);
+#ifndef CHASE_CHAIN
+ b1 = gen_cmp(OR_NET, 9, BPF_B, (bpf_int32)v);
+#else
+ b1 = gen_protochain(v, Q_IP);
+#endif
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_ISO:
+ switch (linktype) {
+
+ case DLT_FRELAY:
+ /*
+ * Frame Relay packets typically have an OSI
+ * NLPID at the beginning; "gen_linktype(LLCSAP_ISONS)"
+ * generates code to check for all the OSI
+ * NLPIDs, so calling it and then adding a check
+ * for the particular NLPID for which we're
+ * looking is bogus, as we can just check for
+ * the NLPID.
+ *
+ * What we check for is the NLPID and a frame
+ * control field value of UI, i.e. 0x03 followed
+ * by the NLPID.
+ *
+ * XXX - assumes a 2-byte Frame Relay header with
+ * DLCI and flags. What if the address is longer?
+ *
+ * XXX - what about SNAP-encapsulated frames?
+ */
+ return gen_cmp(OR_LINK, 2, BPF_H, (0x03<<8) | v);
+ /*NOTREACHED*/
+ break;
+
+ case DLT_C_HDLC:
+ /*
+ * Cisco uses an Ethertype lookalike - for OSI,
+ * it's 0xfefe.
+ */
+ b0 = gen_linktype(LLCSAP_ISONS<<8 | LLCSAP_ISONS);
+ /* OSI in C-HDLC is stuffed with a fudge byte */
+ b1 = gen_cmp(OR_NET_NOSNAP, 1, BPF_B, (long)v);
+ gen_and(b0, b1);
+ return b1;
+
+ default:
+ b0 = gen_linktype(LLCSAP_ISONS);
+ b1 = gen_cmp(OR_NET_NOSNAP, 0, BPF_B, (long)v);
+ gen_and(b0, b1);
+ return b1;
+ }
+
+ case Q_ISIS:
+ b0 = gen_proto(ISO10589_ISIS, Q_ISO, Q_DEFAULT);
+ /*
+ * 4 is the offset of the PDU type relative to the IS-IS
+ * header.
+ */
+ b1 = gen_cmp(OR_NET_NOSNAP, 4, BPF_B, (long)v);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_ARP:
+ bpf_error("arp does not encapsulate another protocol");
+ /* NOTREACHED */
+
+ case Q_RARP:
+ bpf_error("rarp does not encapsulate another protocol");
+ /* NOTREACHED */
+
+ case Q_ATALK:
+ bpf_error("atalk encapsulation is not specifiable");
+ /* NOTREACHED */
+
+ case Q_DECNET:
+ bpf_error("decnet encapsulation is not specifiable");
+ /* NOTREACHED */
+
+ case Q_SCA:
+ bpf_error("sca does not encapsulate another protocol");
+ /* NOTREACHED */
+
+ case Q_LAT:
+ bpf_error("lat does not encapsulate another protocol");
+ /* NOTREACHED */
+
+ case Q_MOPRC:
+ bpf_error("moprc does not encapsulate another protocol");
+ /* NOTREACHED */
+
+ case Q_MOPDL:
+ bpf_error("mopdl does not encapsulate another protocol");
+ /* NOTREACHED */
+
+ case Q_LINK:
+ return gen_linktype(v);
+
+ case Q_UDP:
+ bpf_error("'udp proto' is bogus");
+ /* NOTREACHED */
+
+ case Q_TCP:
+ bpf_error("'tcp proto' is bogus");
+ /* NOTREACHED */
+
+ case Q_SCTP:
+ bpf_error("'sctp proto' is bogus");
+ /* NOTREACHED */
+
+ case Q_ICMP:
+ bpf_error("'icmp proto' is bogus");
+ /* NOTREACHED */
+
+ case Q_IGMP:
+ bpf_error("'igmp proto' is bogus");
+ /* NOTREACHED */
+
+ case Q_IGRP:
+ bpf_error("'igrp proto' is bogus");
+ /* NOTREACHED */
+
+ case Q_PIM:
+ bpf_error("'pim proto' is bogus");
+ /* NOTREACHED */
+
+ case Q_VRRP:
+ bpf_error("'vrrp proto' is bogus");
+ /* NOTREACHED */
+
+ case Q_CARP:
+ bpf_error("'carp proto' is bogus");
+ /* NOTREACHED */
+
+ case Q_IPV6:
+ b0 = gen_linktype(ETHERTYPE_IPV6);
+#ifndef CHASE_CHAIN
+ /*
+ * Also check for a fragment header before the final
+ * header.
+ */
+ b2 = gen_cmp(OR_NET, 6, BPF_B, IPPROTO_FRAGMENT);
+ b1 = gen_cmp(OR_NET, 40, BPF_B, (bpf_int32)v);
+ gen_and(b2, b1);
+ b2 = gen_cmp(OR_NET, 6, BPF_B, (bpf_int32)v);
+ gen_or(b2, b1);
+#else
+ b1 = gen_protochain(v, Q_IPV6);
+#endif
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_ICMPV6:
+ bpf_error("'icmp6 proto' is bogus");
+
+ case Q_AH:
+ bpf_error("'ah proto' is bogus");
+
+ case Q_ESP:
+ bpf_error("'ah proto' is bogus");
+
+ case Q_STP:
+ bpf_error("'stp proto' is bogus");
+
+ case Q_IPX:
+ bpf_error("'ipx proto' is bogus");
+
+ case Q_NETBEUI:
+ bpf_error("'netbeui proto' is bogus");
+
+ case Q_RADIO:
+ bpf_error("'radio proto' is bogus");
+
+ default:
+ abort();
+ /* NOTREACHED */
+ }
+ /* NOTREACHED */
+}
+
+struct block *
+gen_scode(name, q)
+ register const char *name;
+ struct qual q;
+{
+ int proto = q.proto;
+ int dir = q.dir;
+ int tproto;
+ u_char *eaddr;
+ bpf_u_int32 mask, addr;
+#ifndef INET6
+ bpf_u_int32 **alist;
+#else
+ int tproto6;
+ struct sockaddr_in *sin4;
+ struct sockaddr_in6 *sin6;
+ struct addrinfo *res, *res0;
+ struct in6_addr mask128;
+#endif /*INET6*/
+ struct block *b, *tmp;
+ int port, real_proto;
+ int port1, port2;
+
+ switch (q.addr) {
+
+ case Q_NET:
+ addr = pcap_nametonetaddr(name);
+ if (addr == 0)
+ bpf_error("unknown network '%s'", name);
+ /* Left justify network addr and calculate its network mask */
+ mask = 0xffffffff;
+ while (addr && (addr & 0xff000000) == 0) {
+ addr <<= 8;
+ mask <<= 8;
+ }
+ return gen_host(addr, mask, proto, dir, q.addr);
+
+ case Q_DEFAULT:
+ case Q_HOST:
+ if (proto == Q_LINK) {
+ switch (linktype) {
+
+ case DLT_EN10MB:
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
+ eaddr = pcap_ether_hostton(name);
+ if (eaddr == NULL)
+ bpf_error(
+ "unknown ether host '%s'", name);
+ b = gen_ehostop(eaddr, dir);
+ free(eaddr);
+ return b;
+
+ case DLT_FDDI:
+ eaddr = pcap_ether_hostton(name);
+ if (eaddr == NULL)
+ bpf_error(
+ "unknown FDDI host '%s'", name);
+ b = gen_fhostop(eaddr, dir);
+ free(eaddr);
+ return b;
+
+ case DLT_IEEE802:
+ eaddr = pcap_ether_hostton(name);
+ if (eaddr == NULL)
+ bpf_error(
+ "unknown token ring host '%s'", name);
+ b = gen_thostop(eaddr, dir);
+ free(eaddr);
+ return b;
+
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ case DLT_IEEE802_11_RADIO:
+ case DLT_PPI:
+ eaddr = pcap_ether_hostton(name);
+ if (eaddr == NULL)
+ bpf_error(
+ "unknown 802.11 host '%s'", name);
+ b = gen_wlanhostop(eaddr, dir);
+ free(eaddr);
+ return b;
+
+ case DLT_IP_OVER_FC:
+ eaddr = pcap_ether_hostton(name);
+ if (eaddr == NULL)
+ bpf_error(
+ "unknown Fibre Channel host '%s'", name);
+ b = gen_ipfchostop(eaddr, dir);
+ free(eaddr);
+ return b;
+
+ case DLT_SUNATM:
+ if (!is_lane)
+ break;
+
+ /*
+ * Check that the packet doesn't begin
+ * with an LE Control marker. (We've
+ * already generated a test for LANE.)
+ */
+ tmp = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS,
+ BPF_H, 0xFF00);
+ gen_not(tmp);
+
+ eaddr = pcap_ether_hostton(name);
+ if (eaddr == NULL)
+ bpf_error(
+ "unknown ether host '%s'", name);
+ b = gen_ehostop(eaddr, dir);
+ gen_and(tmp, b);
+ free(eaddr);
+ return b;
+ }
+
+ bpf_error("only ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel supports link-level host name");
+ } else if (proto == Q_DECNET) {
+ unsigned short dn_addr = __pcap_nametodnaddr(name);
+ /*
+ * I don't think DECNET hosts can be multihomed, so
+ * there is no need to build up a list of addresses
+ */
+ return (gen_host(dn_addr, 0, proto, dir, q.addr));
+ } else {
+#ifndef INET6
+ alist = pcap_nametoaddr(name);
+ if (alist == NULL || *alist == NULL)
+ bpf_error("unknown host '%s'", name);
+ tproto = proto;
+ if (off_linktype == (u_int)-1 && tproto == Q_DEFAULT)
+ tproto = Q_IP;
+ b = gen_host(**alist++, 0xffffffff, tproto, dir, q.addr);
+ while (*alist) {
+ tmp = gen_host(**alist++, 0xffffffff,
+ tproto, dir, q.addr);
+ gen_or(b, tmp);
+ b = tmp;
+ }
+ return b;
+#else
+ memset(&mask128, 0xff, sizeof(mask128));
+ res0 = res = pcap_nametoaddrinfo(name);
+ if (res == NULL)
+ bpf_error("unknown host '%s'", name);
+ ai = res;
+ b = tmp = NULL;
+ tproto = tproto6 = proto;
+ if (off_linktype == -1 && tproto == Q_DEFAULT) {
+ tproto = Q_IP;
+ tproto6 = Q_IPV6;
+ }
+ for (res = res0; res; res = res->ai_next) {
+ switch (res->ai_family) {
+ case AF_INET:
+ if (tproto == Q_IPV6)
+ continue;
+
+ sin4 = (struct sockaddr_in *)
+ res->ai_addr;
+ tmp = gen_host(ntohl(sin4->sin_addr.s_addr),
+ 0xffffffff, tproto, dir, q.addr);
+ break;
+ case AF_INET6:
+ if (tproto6 == Q_IP)
+ continue;
+
+ sin6 = (struct sockaddr_in6 *)
+ res->ai_addr;
+ tmp = gen_host6(&sin6->sin6_addr,
+ &mask128, tproto6, dir, q.addr);
+ break;
+ default:
+ continue;
+ }
+ if (b)
+ gen_or(b, tmp);
+ b = tmp;
+ }
+ ai = NULL;
+ freeaddrinfo(res0);
+ if (b == NULL) {
+ bpf_error("unknown host '%s'%s", name,
+ (proto == Q_DEFAULT)
+ ? ""
+ : " for specified address family");
+ }
+ return b;
+#endif /*INET6*/
+ }
+
+ case Q_PORT:
+ if (proto != Q_DEFAULT &&
+ proto != Q_UDP && proto != Q_TCP && proto != Q_SCTP)
+ bpf_error("illegal qualifier of 'port'");
+ if (pcap_nametoport(name, &port, &real_proto) == 0)
+ bpf_error("unknown port '%s'", name);
+ if (proto == Q_UDP) {
+ if (real_proto == IPPROTO_TCP)
+ bpf_error("port '%s' is tcp", name);
+ else if (real_proto == IPPROTO_SCTP)
+ bpf_error("port '%s' is sctp", name);
+ else
+ /* override PROTO_UNDEF */
+ real_proto = IPPROTO_UDP;
+ }
+ if (proto == Q_TCP) {
+ if (real_proto == IPPROTO_UDP)
+ bpf_error("port '%s' is udp", name);
+
+ else if (real_proto == IPPROTO_SCTP)
+ bpf_error("port '%s' is sctp", name);
+ else
+ /* override PROTO_UNDEF */
+ real_proto = IPPROTO_TCP;
+ }
+ if (proto == Q_SCTP) {
+ if (real_proto == IPPROTO_UDP)
+ bpf_error("port '%s' is udp", name);
+
+ else if (real_proto == IPPROTO_TCP)
+ bpf_error("port '%s' is tcp", name);
+ else
+ /* override PROTO_UNDEF */
+ real_proto = IPPROTO_SCTP;
+ }
+ if (port < 0)
+ bpf_error("illegal port number %d < 0", port);
+ if (port > 65535)
+ bpf_error("illegal port number %d > 65535", port);
+ b = gen_port(port, real_proto, dir);
+ gen_or(gen_port6(port, real_proto, dir), b);
+ return b;
+
+ case Q_PORTRANGE:
+ if (proto != Q_DEFAULT &&
+ proto != Q_UDP && proto != Q_TCP && proto != Q_SCTP)
+ bpf_error("illegal qualifier of 'portrange'");
+ if (pcap_nametoportrange(name, &port1, &port2, &real_proto) == 0)
+ bpf_error("unknown port in range '%s'", name);
+ if (proto == Q_UDP) {
+ if (real_proto == IPPROTO_TCP)
+ bpf_error("port in range '%s' is tcp", name);
+ else if (real_proto == IPPROTO_SCTP)
+ bpf_error("port in range '%s' is sctp", name);
+ else
+ /* override PROTO_UNDEF */
+ real_proto = IPPROTO_UDP;
+ }
+ if (proto == Q_TCP) {
+ if (real_proto == IPPROTO_UDP)
+ bpf_error("port in range '%s' is udp", name);
+ else if (real_proto == IPPROTO_SCTP)
+ bpf_error("port in range '%s' is sctp", name);
+ else
+ /* override PROTO_UNDEF */
+ real_proto = IPPROTO_TCP;
+ }
+ if (proto == Q_SCTP) {
+ if (real_proto == IPPROTO_UDP)
+ bpf_error("port in range '%s' is udp", name);
+ else if (real_proto == IPPROTO_TCP)
+ bpf_error("port in range '%s' is tcp", name);
+ else
+ /* override PROTO_UNDEF */
+ real_proto = IPPROTO_SCTP;
+ }
+ if (port1 < 0)
+ bpf_error("illegal port number %d < 0", port1);
+ if (port1 > 65535)
+ bpf_error("illegal port number %d > 65535", port1);
+ if (port2 < 0)
+ bpf_error("illegal port number %d < 0", port2);
+ if (port2 > 65535)
+ bpf_error("illegal port number %d > 65535", port2);
+
+ b = gen_portrange(port1, port2, real_proto, dir);
+ gen_or(gen_portrange6(port1, port2, real_proto, dir), b);
+ return b;
+
+ case Q_GATEWAY:
+#ifndef INET6
+ eaddr = pcap_ether_hostton(name);
+ if (eaddr == NULL)
+ bpf_error("unknown ether host: %s", name);
+
+ alist = pcap_nametoaddr(name);
+ if (alist == NULL || *alist == NULL)
+ bpf_error("unknown host '%s'", name);
+ b = gen_gateway(eaddr, alist, proto, dir);
+ free(eaddr);
+ return b;
+#else
+ bpf_error("'gateway' not supported in this configuration");
+#endif /*INET6*/
+
+ case Q_PROTO:
+ real_proto = lookup_proto(name, proto);
+ if (real_proto >= 0)
+ return gen_proto(real_proto, proto, dir);
+ else
+ bpf_error("unknown protocol: %s", name);
+
+ case Q_PROTOCHAIN:
+ real_proto = lookup_proto(name, proto);
+ if (real_proto >= 0)
+ return gen_protochain(real_proto, proto, dir);
+ else
+ bpf_error("unknown protocol: %s", name);
+
+ case Q_UNDEF:
+ syntax();
+ /* NOTREACHED */
+ }
+ abort();
+ /* NOTREACHED */
+}
+
+struct block *
+gen_mcode(s1, s2, masklen, q)
+ register const char *s1, *s2;
+ register int masklen;
+ struct qual q;
+{
+ register int nlen, mlen;
+ bpf_u_int32 n, m;
+
+ nlen = __pcap_atoin(s1, &n);
+ /* Promote short ipaddr */
+ n <<= 32 - nlen;
+
+ if (s2 != NULL) {
+ mlen = __pcap_atoin(s2, &m);
+ /* Promote short ipaddr */
+ m <<= 32 - mlen;
+ if ((n & ~m) != 0)
+ bpf_error("non-network bits set in \"%s mask %s\"",
+ s1, s2);
+ } else {
+ /* Convert mask len to mask */
+ if (masklen > 32)
+ bpf_error("mask length must be <= 32");
+ if (masklen == 0) {
+ /*
+ * X << 32 is not guaranteed by C to be 0; it's
+ * undefined.
+ */
+ m = 0;
+ } else
+ m = 0xffffffff << (32 - masklen);
+ if ((n & ~m) != 0)
+ bpf_error("non-network bits set in \"%s/%d\"",
+ s1, masklen);
+ }
+
+ switch (q.addr) {
+
+ case Q_NET:
+ return gen_host(n, m, q.proto, q.dir, q.addr);
+
+ default:
+ bpf_error("Mask syntax for networks only");
+ /* NOTREACHED */
+ }
+ /* NOTREACHED */
+ return NULL;
+}
+
+struct block *
+gen_ncode(s, v, q)
+ register const char *s;
+ bpf_u_int32 v;
+ struct qual q;
+{
+ bpf_u_int32 mask;
+ int proto = q.proto;
+ int dir = q.dir;
+ register int vlen;
+
+ if (s == NULL)
+ vlen = 32;
+ else if (q.proto == Q_DECNET)
+ vlen = __pcap_atodn(s, &v);
+ else
+ vlen = __pcap_atoin(s, &v);
+
+ switch (q.addr) {
+
+ case Q_DEFAULT:
+ case Q_HOST:
+ case Q_NET:
+ if (proto == Q_DECNET)
+ return gen_host(v, 0, proto, dir, q.addr);
+ else if (proto == Q_LINK) {
+ bpf_error("illegal link layer address");
+ } else {
+ mask = 0xffffffff;
+ if (s == NULL && q.addr == Q_NET) {
+ /* Promote short net number */
+ while (v && (v & 0xff000000) == 0) {
+ v <<= 8;
+ mask <<= 8;
+ }
+ } else {
+ /* Promote short ipaddr */
+ v <<= 32 - vlen;
+ mask <<= 32 - vlen;
+ }
+ return gen_host(v, mask, proto, dir, q.addr);
+ }
+
+ case Q_PORT:
+ if (proto == Q_UDP)
+ proto = IPPROTO_UDP;
+ else if (proto == Q_TCP)
+ proto = IPPROTO_TCP;
+ else if (proto == Q_SCTP)
+ proto = IPPROTO_SCTP;
+ else if (proto == Q_DEFAULT)
+ proto = PROTO_UNDEF;
+ else
+ bpf_error("illegal qualifier of 'port'");
+
+ if (v > 65535)
+ bpf_error("illegal port number %u > 65535", v);
+
+ {
+ struct block *b;
+ b = gen_port((int)v, proto, dir);
+ gen_or(gen_port6((int)v, proto, dir), b);
+ return b;
+ }
+
+ case Q_PORTRANGE:
+ if (proto == Q_UDP)
+ proto = IPPROTO_UDP;
+ else if (proto == Q_TCP)
+ proto = IPPROTO_TCP;
+ else if (proto == Q_SCTP)
+ proto = IPPROTO_SCTP;
+ else if (proto == Q_DEFAULT)
+ proto = PROTO_UNDEF;
+ else
+ bpf_error("illegal qualifier of 'portrange'");
+
+ if (v > 65535)
+ bpf_error("illegal port number %u > 65535", v);
+
+ {
+ struct block *b;
+ b = gen_portrange((int)v, (int)v, proto, dir);
+ gen_or(gen_portrange6((int)v, (int)v, proto, dir), b);
+ return b;
+ }
+
+ case Q_GATEWAY:
+ bpf_error("'gateway' requires a name");
+ /* NOTREACHED */
+
+ case Q_PROTO:
+ return gen_proto((int)v, proto, dir);
+
+ case Q_PROTOCHAIN:
+ return gen_protochain((int)v, proto, dir);
+
+ case Q_UNDEF:
+ syntax();
+ /* NOTREACHED */
+
+ default:
+ abort();
+ /* NOTREACHED */
+ }
+ /* NOTREACHED */
+}
+
+#ifdef INET6
+struct block *
+gen_mcode6(s1, s2, masklen, q)
+ register const char *s1, *s2;
+ register int masklen;
+ struct qual q;
+{
+ struct addrinfo *res;
+ struct in6_addr *addr;
+ struct in6_addr mask;
+ struct block *b;
+ u_int32_t *a, *m;
+
+ if (s2)
+ bpf_error("no mask %s supported", s2);
+
+ res = pcap_nametoaddrinfo(s1);
+ if (!res)
+ bpf_error("invalid ip6 address %s", s1);
+ ai = res;
+ if (res->ai_next)
+ bpf_error("%s resolved to multiple address", s1);
+ addr = &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr;
+
+ if (sizeof(mask) * 8 < masklen)
+ bpf_error("mask length must be <= %u", (unsigned int)(sizeof(mask) * 8));
+ memset(&mask, 0, sizeof(mask));
+ memset(&mask, 0xff, masklen / 8);
+ if (masklen % 8) {
+ mask.s6_addr[masklen / 8] =
+ (0xff << (8 - masklen % 8)) & 0xff;
+ }
+
+ a = (u_int32_t *)addr;
+ m = (u_int32_t *)&mask;
+ if ((a[0] & ~m[0]) || (a[1] & ~m[1])
+ || (a[2] & ~m[2]) || (a[3] & ~m[3])) {
+ bpf_error("non-network bits set in \"%s/%d\"", s1, masklen);
+ }
+
+ switch (q.addr) {
+
+ case Q_DEFAULT:
+ case Q_HOST:
+ if (masklen != 128)
+ bpf_error("Mask syntax for networks only");
+ /* FALLTHROUGH */
+
+ case Q_NET:
+ b = gen_host6(addr, &mask, q.proto, q.dir, q.addr);
+ ai = NULL;
+ freeaddrinfo(res);
+ return b;
+
+ default:
+ bpf_error("invalid qualifier against IPv6 address");
+ /* NOTREACHED */
+ }
+ return NULL;
+}
+#endif /*INET6*/
+
+struct block *
+gen_ecode(eaddr, q)
+ register const u_char *eaddr;
+ struct qual q;
+{
+ struct block *b, *tmp;
+
+ if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) && q.proto == Q_LINK) {
+ switch (linktype) {
+ case DLT_EN10MB:
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
+ return gen_ehostop(eaddr, (int)q.dir);
+ case DLT_FDDI:
+ return gen_fhostop(eaddr, (int)q.dir);
+ case DLT_IEEE802:
+ return gen_thostop(eaddr, (int)q.dir);
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ case DLT_IEEE802_11_RADIO:
+ case DLT_PPI:
+ return gen_wlanhostop(eaddr, (int)q.dir);
+ case DLT_SUNATM:
+ if (is_lane) {
+ /*
+ * Check that the packet doesn't begin with an
+ * LE Control marker. (We've already generated
+ * a test for LANE.)
+ */
+ tmp = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS, BPF_H,
+ 0xFF00);
+ gen_not(tmp);
+
+ /*
+ * Now check the MAC address.
+ */
+ b = gen_ehostop(eaddr, (int)q.dir);
+ gen_and(tmp, b);
+ return b;
+ }
+ break;
+ case DLT_IP_OVER_FC:
+ return gen_ipfchostop(eaddr, (int)q.dir);
+ default:
+ bpf_error("ethernet addresses supported only on ethernet/FDDI/token ring/802.11/ATM LANE/Fibre Channel");
+ break;
+ }
+ }
+ bpf_error("ethernet address used in non-ether expression");
+ /* NOTREACHED */
+ return NULL;
+}
+
+void
+sappend(s0, s1)
+ struct slist *s0, *s1;
+{
+ /*
+ * This is definitely not the best way to do this, but the
+ * lists will rarely get long.
+ */
+ while (s0->next)
+ s0 = s0->next;
+ s0->next = s1;
+}
+
+static struct slist *
+xfer_to_x(a)
+ struct arth *a;
+{
+ struct slist *s;
+
+ s = new_stmt(BPF_LDX|BPF_MEM);
+ s->s.k = a->regno;
+ return s;
+}
+
+static struct slist *
+xfer_to_a(a)
+ struct arth *a;
+{
+ struct slist *s;
+
+ s = new_stmt(BPF_LD|BPF_MEM);
+ s->s.k = a->regno;
+ return s;
+}
+
+/*
+ * Modify "index" to use the value stored into its register as an
+ * offset relative to the beginning of the header for the protocol
+ * "proto", and allocate a register and put an item "size" bytes long
+ * (1, 2, or 4) at that offset into that register, making it the register
+ * for "index".
+ */
+struct arth *
+gen_load(proto, inst, size)
+ int proto;
+ struct arth *inst;
+ int size;
+{
+ struct slist *s, *tmp;
+ struct block *b;
+ int regno = alloc_reg();
+
+ free_reg(inst->regno);
+ switch (size) {
+
+ default:
+ bpf_error("data size must be 1, 2, or 4");
+
+ case 1:
+ size = BPF_B;
+ break;
+
+ case 2:
+ size = BPF_H;
+ break;
+
+ case 4:
+ size = BPF_W;
+ break;
+ }
+ switch (proto) {
+ default:
+ bpf_error("unsupported index operation");
+
+ case Q_RADIO:
+ /*
+ * The offset is relative to the beginning of the packet
+ * data, if we have a radio header. (If we don't, this
+ * is an error.)
+ */
+ if (linktype != DLT_IEEE802_11_RADIO_AVS &&
+ linktype != DLT_IEEE802_11_RADIO &&
+ linktype != DLT_PRISM_HEADER)
+ bpf_error("radio information not present in capture");
+
+ /*
+ * Load into the X register the offset computed into the
+ * register specified by "index".
+ */
+ s = xfer_to_x(inst);
+
+ /*
+ * Load the item at that offset.
+ */
+ tmp = new_stmt(BPF_LD|BPF_IND|size);
+ sappend(s, tmp);
+ sappend(inst->s, s);
+ break;
+
+ case Q_LINK:
+ /*
+ * The offset is relative to the beginning of
+ * the link-layer header.
+ *
+ * XXX - what about ATM LANE? Should the index be
+ * relative to the beginning of the AAL5 frame, so
+ * that 0 refers to the beginning of the LE Control
+ * field, or relative to the beginning of the LAN
+ * frame, so that 0 refers, for Ethernet LANE, to
+ * the beginning of the destination address?
+ */
+ s = gen_llprefixlen();
+
+ /*
+ * If "s" is non-null, it has code to arrange that the
+ * X register contains the length of the prefix preceding
+ * the link-layer header. Add to it the offset computed
+ * into the register specified by "index", and move that
+ * into the X register. Otherwise, just load into the X
+ * register the offset computed into the register specified
+ * by "index".
+ */
+ if (s != NULL) {
+ sappend(s, xfer_to_a(inst));
+ sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X));
+ sappend(s, new_stmt(BPF_MISC|BPF_TAX));
+ } else
+ s = xfer_to_x(inst);
+
+ /*
+ * Load the item at the sum of the offset we've put in the
+ * X register and the offset of the start of the link
+ * layer header (which is 0 if the radio header is
+ * variable-length; that header length is what we put
+ * into the X register and then added to the index).
+ */
+ tmp = new_stmt(BPF_LD|BPF_IND|size);
+ tmp->s.k = off_ll;
+ sappend(s, tmp);
+ sappend(inst->s, s);
+ break;
+
+ case Q_IP:
+ case Q_ARP:
+ case Q_RARP:
+ case Q_ATALK:
+ case Q_DECNET:
+ case Q_SCA:
+ case Q_LAT:
+ case Q_MOPRC:
+ case Q_MOPDL:
+ case Q_IPV6:
+ /*
+ * The offset is relative to the beginning of
+ * the network-layer header.
+ * XXX - are there any cases where we want
+ * off_nl_nosnap?
+ */
+ s = gen_off_macpl();
+
+ /*
+ * If "s" is non-null, it has code to arrange that the
+ * X register contains the offset of the MAC-layer
+ * payload. Add to it the offset computed into the
+ * register specified by "index", and move that into
+ * the X register. Otherwise, just load into the X
+ * register the offset computed into the register specified
+ * by "index".
+ */
+ if (s != NULL) {
+ sappend(s, xfer_to_a(inst));
+ sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X));
+ sappend(s, new_stmt(BPF_MISC|BPF_TAX));
+ } else
+ s = xfer_to_x(inst);
+
+ /*
+ * Load the item at the sum of the offset we've put in the
+ * X register, the offset of the start of the network
+ * layer header from the beginning of the MAC-layer
+ * payload, and the purported offset of the start of the
+ * MAC-layer payload (which might be 0 if there's a
+ * variable-length prefix before the link-layer header
+ * or the link-layer header itself is variable-length;
+ * the variable-length offset of the start of the
+ * MAC-layer payload is what we put into the X register
+ * and then added to the index).
+ */
+ tmp = new_stmt(BPF_LD|BPF_IND|size);
+ tmp->s.k = off_macpl + off_nl;
+ sappend(s, tmp);
+ sappend(inst->s, s);
+
+ /*
+ * Do the computation only if the packet contains
+ * the protocol in question.
+ */
+ b = gen_proto_abbrev(proto);
+ if (inst->b)
+ gen_and(inst->b, b);
+ inst->b = b;
+ break;
+
+ case Q_SCTP:
+ case Q_TCP:
+ case Q_UDP:
+ case Q_ICMP:
+ case Q_IGMP:
+ case Q_IGRP:
+ case Q_PIM:
+ case Q_VRRP:
+ case Q_CARP:
+ /*
+ * The offset is relative to the beginning of
+ * the transport-layer header.
+ *
+ * Load the X register with the length of the IPv4 header
+ * (plus the offset of the link-layer header, if it's
+ * a variable-length header), in bytes.
+ *
+ * XXX - are there any cases where we want
+ * off_nl_nosnap?
+ * XXX - we should, if we're built with
+ * IPv6 support, generate code to load either
+ * IPv4, IPv6, or both, as appropriate.
+ */
+ s = gen_loadx_iphdrlen();
+
+ /*
+ * The X register now contains the sum of the length
+ * of any variable-length header preceding the link-layer
+ * header, any variable-length link-layer header, and the
+ * length of the network-layer header.
+ *
+ * Load into the A register the offset relative to
+ * the beginning of the transport layer header,
+ * add the X register to that, move that to the
+ * X register, and load with an offset from the
+ * X register equal to the offset of the network
+ * layer header relative to the beginning of
+ * the MAC-layer payload plus the fixed-length
+ * portion of the offset of the MAC-layer payload
+ * from the beginning of the raw packet data.
+ */
+ sappend(s, xfer_to_a(inst));
+ sappend(s, new_stmt(BPF_ALU|BPF_ADD|BPF_X));
+ sappend(s, new_stmt(BPF_MISC|BPF_TAX));
+ sappend(s, tmp = new_stmt(BPF_LD|BPF_IND|size));
+ tmp->s.k = off_macpl + off_nl;
+ sappend(inst->s, s);
+
+ /*
+ * Do the computation only if the packet contains
+ * the protocol in question - which is true only
+ * if this is an IP datagram and is the first or
+ * only fragment of that datagram.
+ */
+ gen_and(gen_proto_abbrev(proto), b = gen_ipfrag());
+ if (inst->b)
+ gen_and(inst->b, b);
+ gen_and(gen_proto_abbrev(Q_IP), b);
+ inst->b = b;
+ break;
+ case Q_ICMPV6:
+ bpf_error("IPv6 upper-layer protocol is not supported by proto[x]");
+ /*NOTREACHED*/
+ }
+ inst->regno = regno;
+ s = new_stmt(BPF_ST);
+ s->s.k = regno;
+ sappend(inst->s, s);
+
+ return inst;
+}
+
+struct block *
+gen_relation(code, a0, a1, reversed)
+ int code;
+ struct arth *a0, *a1;
+ int reversed;
+{
+ struct slist *s0, *s1, *s2;
+ struct block *b, *tmp;
+
+ s0 = xfer_to_x(a1);
+ s1 = xfer_to_a(a0);
+ if (code == BPF_JEQ) {
+ s2 = new_stmt(BPF_ALU|BPF_SUB|BPF_X);
+ b = new_block(JMP(code));
+ sappend(s1, s2);
+ }
+ else
+ b = new_block(BPF_JMP|code|BPF_X);
+ if (reversed)
+ gen_not(b);
+
+ sappend(s0, s1);
+ sappend(a1->s, s0);
+ sappend(a0->s, a1->s);
+
+ b->stmts = a0->s;
+
+ free_reg(a0->regno);
+ free_reg(a1->regno);
+
+ /* 'and' together protocol checks */
+ if (a0->b) {
+ if (a1->b) {
+ gen_and(a0->b, tmp = a1->b);
+ }
+ else
+ tmp = a0->b;
+ } else
+ tmp = a1->b;
+
+ if (tmp)
+ gen_and(tmp, b);
+
+ return b;
+}
+
+struct arth *
+gen_loadlen()
+{
+ int regno = alloc_reg();
+ struct arth *a = (struct arth *)newchunk(sizeof(*a));
+ struct slist *s;
+
+ s = new_stmt(BPF_LD|BPF_LEN);
+ s->next = new_stmt(BPF_ST);
+ s->next->s.k = regno;
+ a->s = s;
+ a->regno = regno;
+
+ return a;
+}
+
+struct arth *
+gen_loadi(val)
+ int val;
+{
+ struct arth *a;
+ struct slist *s;
+ int reg;
+
+ a = (struct arth *)newchunk(sizeof(*a));
+
+ reg = alloc_reg();
+
+ s = new_stmt(BPF_LD|BPF_IMM);
+ s->s.k = val;
+ s->next = new_stmt(BPF_ST);
+ s->next->s.k = reg;
+ a->s = s;
+ a->regno = reg;
+
+ return a;
+}
+
+struct arth *
+gen_neg(a)
+ struct arth *a;
+{
+ struct slist *s;
+
+ s = xfer_to_a(a);
+ sappend(a->s, s);
+ s = new_stmt(BPF_ALU|BPF_NEG);
+ s->s.k = 0;
+ sappend(a->s, s);
+ s = new_stmt(BPF_ST);
+ s->s.k = a->regno;
+ sappend(a->s, s);
+
+ return a;
+}
+
+struct arth *
+gen_arth(code, a0, a1)
+ int code;
+ struct arth *a0, *a1;
+{
+ struct slist *s0, *s1, *s2;
+
+ s0 = xfer_to_x(a1);
+ s1 = xfer_to_a(a0);
+ s2 = new_stmt(BPF_ALU|BPF_X|code);
+
+ sappend(s1, s2);
+ sappend(s0, s1);
+ sappend(a1->s, s0);
+ sappend(a0->s, a1->s);
+
+ free_reg(a0->regno);
+ free_reg(a1->regno);
+
+ s0 = new_stmt(BPF_ST);
+ a0->regno = s0->s.k = alloc_reg();
+ sappend(a0->s, s0);
+
+ return a0;
+}
+
+/*
+ * Here we handle simple allocation of the scratch registers.
+ * If too many registers are alloc'd, the allocator punts.
+ */
+static int regused[BPF_MEMWORDS];
+static int curreg;
+
+/*
+ * Initialize the table of used registers and the current register.
+ */
+static void
+init_regs()
+{
+ curreg = 0;
+ memset(regused, 0, sizeof regused);
+}
+
+/*
+ * Return the next free register.
+ */
+static int
+alloc_reg()
+{
+ int n = BPF_MEMWORDS;
+
+ while (--n >= 0) {
+ if (regused[curreg])
+ curreg = (curreg + 1) % BPF_MEMWORDS;
+ else {
+ regused[curreg] = 1;
+ return curreg;
+ }
+ }
+ bpf_error("too many registers needed to evaluate expression");
+ /* NOTREACHED */
+ return 0;
+}
+
+/*
+ * Return a register to the table so it can
+ * be used later.
+ */
+static void
+free_reg(n)
+ int n;
+{
+ regused[n] = 0;
+}
+
+static struct block *
+gen_len(jmp, n)
+ int jmp, n;
+{
+ struct slist *s;
+ struct block *b;
+
+ s = new_stmt(BPF_LD|BPF_LEN);
+ b = new_block(JMP(jmp));
+ b->stmts = s;
+ b->s.k = n;
+
+ return b;
+}
+
+struct block *
+gen_greater(n)
+ int n;
+{
+ return gen_len(BPF_JGE, n);
+}
+
+/*
+ * Actually, this is less than or equal.
+ */
+struct block *
+gen_less(n)
+ int n;
+{
+ struct block *b;
+
+ b = gen_len(BPF_JGT, n);
+ gen_not(b);
+
+ return b;
+}
+
+/*
+ * This is for "byte {idx} {op} {val}"; "idx" is treated as relative to
+ * the beginning of the link-layer header.
+ * XXX - that means you can't test values in the radiotap header, but
+ * as that header is difficult if not impossible to parse generally
+ * without a loop, that might not be a severe problem. A new keyword
+ * "radio" could be added for that, although what you'd really want
+ * would be a way of testing particular radio header values, which
+ * would generate code appropriate to the radio header in question.
+ */
+struct block *
+gen_byteop(op, idx, val)
+ int op, idx, val;
+{
+ struct block *b;
+ struct slist *s;
+
+ switch (op) {
+ default:
+ abort();
+
+ case '=':
+ return gen_cmp(OR_LINK, (u_int)idx, BPF_B, (bpf_int32)val);
+
+ case '<':
+ b = gen_cmp_lt(OR_LINK, (u_int)idx, BPF_B, (bpf_int32)val);
+ return b;
+
+ case '>':
+ b = gen_cmp_gt(OR_LINK, (u_int)idx, BPF_B, (bpf_int32)val);
+ return b;
+
+ case '|':
+ s = new_stmt(BPF_ALU|BPF_OR|BPF_K);
+ break;
+
+ case '&':
+ s = new_stmt(BPF_ALU|BPF_AND|BPF_K);
+ break;
+ }
+ s->s.k = val;
+ b = new_block(JMP(BPF_JEQ));
+ b->stmts = s;
+ gen_not(b);
+
+ return b;
+}
+
+static u_char abroadcast[] = { 0x0 };
+
+struct block *
+gen_broadcast(proto)
+ int proto;
+{
+ bpf_u_int32 hostmask;
+ struct block *b0, *b1, *b2;
+ static u_char ebroadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+
+ switch (proto) {
+
+ case Q_DEFAULT:
+ case Q_LINK:
+ switch (linktype) {
+ case DLT_ARCNET:
+ case DLT_ARCNET_LINUX:
+ return gen_ahostop(abroadcast, Q_DST);
+ case DLT_EN10MB:
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
+ return gen_ehostop(ebroadcast, Q_DST);
+ case DLT_FDDI:
+ return gen_fhostop(ebroadcast, Q_DST);
+ case DLT_IEEE802:
+ return gen_thostop(ebroadcast, Q_DST);
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ case DLT_IEEE802_11_RADIO:
+ case DLT_PPI:
+ return gen_wlanhostop(ebroadcast, Q_DST);
+ case DLT_IP_OVER_FC:
+ return gen_ipfchostop(ebroadcast, Q_DST);
+ case DLT_SUNATM:
+ if (is_lane) {
+ /*
+ * Check that the packet doesn't begin with an
+ * LE Control marker. (We've already generated
+ * a test for LANE.)
+ */
+ b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS,
+ BPF_H, 0xFF00);
+ gen_not(b1);
+
+ /*
+ * Now check the MAC address.
+ */
+ b0 = gen_ehostop(ebroadcast, Q_DST);
+ gen_and(b1, b0);
+ return b0;
+ }
+ break;
+ default:
+ bpf_error("not a broadcast link");
+ }
+ break;
+
+ case Q_IP:
+ /*
+ * We treat a netmask of PCAP_NETMASK_UNKNOWN (0xffffffff)
+ * as an indication that we don't know the netmask, and fail
+ * in that case.
+ */
+ if (netmask == PCAP_NETMASK_UNKNOWN)
+ bpf_error("netmask not known, so 'ip broadcast' not supported");
+ b0 = gen_linktype(ETHERTYPE_IP);
+ hostmask = ~netmask;
+ b1 = gen_mcmp(OR_NET, 16, BPF_W, (bpf_int32)0, hostmask);
+ b2 = gen_mcmp(OR_NET, 16, BPF_W,
+ (bpf_int32)(~0 & hostmask), hostmask);
+ gen_or(b1, b2);
+ gen_and(b0, b2);
+ return b2;
+ }
+ bpf_error("only link-layer/IP broadcast filters supported");
+ /* NOTREACHED */
+ return NULL;
+}
+
+/*
+ * Generate code to test the low-order bit of a MAC address (that's
+ * the bottom bit of the *first* byte).
+ */
+static struct block *
+gen_mac_multicast(offset)
+ int offset;
+{
+ register struct block *b0;
+ register struct slist *s;
+
+ /* link[offset] & 1 != 0 */
+ s = gen_load_a(OR_LINK, offset, BPF_B);
+ b0 = new_block(JMP(BPF_JSET));
+ b0->s.k = 1;
+ b0->stmts = s;
+ return b0;
+}
+
+struct block *
+gen_multicast(proto)
+ int proto;
+{
+ register struct block *b0, *b1, *b2;
+ register struct slist *s;
+
+ switch (proto) {
+
+ case Q_DEFAULT:
+ case Q_LINK:
+ switch (linktype) {
+ case DLT_ARCNET:
+ case DLT_ARCNET_LINUX:
+ /* all ARCnet multicasts use the same address */
+ return gen_ahostop(abroadcast, Q_DST);
+ case DLT_EN10MB:
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
+ /* ether[0] & 1 != 0 */
+ return gen_mac_multicast(0);
+ case DLT_FDDI:
+ /*
+ * XXX TEST THIS: MIGHT NOT PORT PROPERLY XXX
+ *
+ * XXX - was that referring to bit-order issues?
+ */
+ /* fddi[1] & 1 != 0 */
+ return gen_mac_multicast(1);
+ case DLT_IEEE802:
+ /* tr[2] & 1 != 0 */
+ return gen_mac_multicast(2);
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ case DLT_IEEE802_11_RADIO:
+ case DLT_PPI:
+ /*
+ * Oh, yuk.
+ *
+ * For control frames, there is no DA.
+ *
+ * For management frames, DA is at an
+ * offset of 4 from the beginning of
+ * the packet.
+ *
+ * For data frames, DA is at an offset
+ * of 4 from the beginning of the packet
+ * if To DS is clear and at an offset of
+ * 16 from the beginning of the packet
+ * if To DS is set.
+ */
+
+ /*
+ * Generate the tests to be done for data frames.
+ *
+ * First, check for To DS set, i.e. "link[1] & 0x01".
+ */
+ s = gen_load_a(OR_LINK, 1, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x01; /* To DS */
+ b1->stmts = s;
+
+ /*
+ * If To DS is set, the DA is at 16.
+ */
+ b0 = gen_mac_multicast(16);
+ gen_and(b1, b0);
+
+ /*
+ * Now, check for To DS not set, i.e. check
+ * "!(link[1] & 0x01)".
+ */
+ s = gen_load_a(OR_LINK, 1, BPF_B);
+ b2 = new_block(JMP(BPF_JSET));
+ b2->s.k = 0x01; /* To DS */
+ b2->stmts = s;
+ gen_not(b2);
+
+ /*
+ * If To DS is not set, the DA is at 4.
+ */
+ b1 = gen_mac_multicast(4);
+ gen_and(b2, b1);
+
+ /*
+ * Now OR together the last two checks. That gives
+ * the complete set of checks for data frames.
+ */
+ gen_or(b1, b0);
+
+ /*
+ * Now check for a data frame.
+ * I.e, check "link[0] & 0x08".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x08;
+ b1->stmts = s;
+
+ /*
+ * AND that with the checks done for data frames.
+ */
+ gen_and(b1, b0);
+
+ /*
+ * If the high-order bit of the type value is 0, this
+ * is a management frame.
+ * I.e, check "!(link[0] & 0x08)".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b2 = new_block(JMP(BPF_JSET));
+ b2->s.k = 0x08;
+ b2->stmts = s;
+ gen_not(b2);
+
+ /*
+ * For management frames, the DA is at 4.
+ */
+ b1 = gen_mac_multicast(4);
+ gen_and(b2, b1);
+
+ /*
+ * OR that with the checks done for data frames.
+ * That gives the checks done for management and
+ * data frames.
+ */
+ gen_or(b1, b0);
+
+ /*
+ * If the low-order bit of the type value is 1,
+ * this is either a control frame or a frame
+ * with a reserved type, and thus not a
+ * frame with an SA.
+ *
+ * I.e., check "!(link[0] & 0x04)".
+ */
+ s = gen_load_a(OR_LINK, 0, BPF_B);
+ b1 = new_block(JMP(BPF_JSET));
+ b1->s.k = 0x04;
+ b1->stmts = s;
+ gen_not(b1);
+
+ /*
+ * AND that with the checks for data and management
+ * frames.
+ */
+ gen_and(b1, b0);
+ return b0;
+ case DLT_IP_OVER_FC:
+ b0 = gen_mac_multicast(2);
+ return b0;
+ case DLT_SUNATM:
+ if (is_lane) {
+ /*
+ * Check that the packet doesn't begin with an
+ * LE Control marker. (We've already generated
+ * a test for LANE.)
+ */
+ b1 = gen_cmp(OR_LINK, SUNATM_PKT_BEGIN_POS,
+ BPF_H, 0xFF00);
+ gen_not(b1);
+
+ /* ether[off_mac] & 1 != 0 */
+ b0 = gen_mac_multicast(off_mac);
+ gen_and(b1, b0);
+ return b0;
+ }
+ break;
+ default:
+ break;
+ }
+ /* Link not known to support multicasts */
+ break;
+
+ case Q_IP:
+ b0 = gen_linktype(ETHERTYPE_IP);
+ b1 = gen_cmp_ge(OR_NET, 16, BPF_B, (bpf_int32)224);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_IPV6:
+ b0 = gen_linktype(ETHERTYPE_IPV6);
+ b1 = gen_cmp(OR_NET, 24, BPF_B, (bpf_int32)255);
+ gen_and(b0, b1);
+ return b1;
+ }
+ bpf_error("link-layer multicast filters supported only on ethernet/FDDI/token ring/ARCNET/802.11/ATM LANE/Fibre Channel");
+ /* NOTREACHED */
+ return NULL;
+}
+
+/*
+ * Filter on inbound (dir == 0) or outbound (dir == 1) traffic.
+ * Outbound traffic is sent by this machine, while inbound traffic is
+ * sent by a remote machine (and may include packets destined for a
+ * unicast or multicast link-layer address we are not subscribing to).
+ * These are the same definitions implemented by pcap_setdirection().
+ * Capturing only unicast traffic destined for this host is probably
+ * better accomplished using a higher-layer filter.
+ */
+struct block *
+gen_inbound(dir)
+ int dir;
+{
+ register struct block *b0;
+
+ /*
+ * Only some data link types support inbound/outbound qualifiers.
+ */
+ switch (linktype) {
+ case DLT_SLIP:
+ b0 = gen_relation(BPF_JEQ,
+ gen_load(Q_LINK, gen_loadi(0), 1),
+ gen_loadi(0),
+ dir);
+ break;
+
+ case DLT_IPNET:
+ if (dir) {
+ /* match outgoing packets */
+ b0 = gen_cmp(OR_LINK, 2, BPF_H, IPNET_OUTBOUND);
+ } else {
+ /* match incoming packets */
+ b0 = gen_cmp(OR_LINK, 2, BPF_H, IPNET_INBOUND);
+ }
+ break;
+
+ case DLT_LINUX_SLL:
+ /* match outgoing packets */
+ b0 = gen_cmp(OR_LINK, 0, BPF_H, LINUX_SLL_OUTGOING);
+ if (!dir) {
+ /* to filter on inbound traffic, invert the match */
+ gen_not(b0);
+ }
+ break;
+
+#ifdef HAVE_NET_PFVAR_H
+ case DLT_PFLOG:
+ b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, dir), BPF_B,
+ (bpf_int32)((dir == 0) ? PF_IN : PF_OUT));
+ break;
+#endif
+
+ case DLT_PPP_PPPD:
+ if (dir) {
+ /* match outgoing packets */
+ b0 = gen_cmp(OR_LINK, 0, BPF_B, PPP_PPPD_OUT);
+ } else {
+ /* match incoming packets */
+ b0 = gen_cmp(OR_LINK, 0, BPF_B, PPP_PPPD_IN);
+ }
+ break;
+
+ case DLT_JUNIPER_MFR:
+ case DLT_JUNIPER_MLFR:
+ case DLT_JUNIPER_MLPPP:
+ case DLT_JUNIPER_ATM1:
+ case DLT_JUNIPER_ATM2:
+ case DLT_JUNIPER_PPPOE:
+ case DLT_JUNIPER_PPPOE_ATM:
+ case DLT_JUNIPER_GGSN:
+ case DLT_JUNIPER_ES:
+ case DLT_JUNIPER_MONITOR:
+ case DLT_JUNIPER_SERVICES:
+ case DLT_JUNIPER_ETHER:
+ case DLT_JUNIPER_PPP:
+ case DLT_JUNIPER_FRELAY:
+ case DLT_JUNIPER_CHDLC:
+ case DLT_JUNIPER_VP:
+ case DLT_JUNIPER_ST:
+ case DLT_JUNIPER_ISM:
+ case DLT_JUNIPER_VS:
+ case DLT_JUNIPER_SRX_E2E:
+ case DLT_JUNIPER_FIBRECHANNEL:
+ case DLT_JUNIPER_ATM_CEMIC:
+
+ /* juniper flags (including direction) are stored
+ * the byte after the 3-byte magic number */
+ if (dir) {
+ /* match outgoing packets */
+ b0 = gen_mcmp(OR_LINK, 3, BPF_B, 0, 0x01);
+ } else {
+ /* match incoming packets */
+ b0 = gen_mcmp(OR_LINK, 3, BPF_B, 1, 0x01);
+ }
+ break;
+
+ default:
+ /*
+ * If we have packet meta-data indicating a direction,
+ * check it, otherwise give up as this link-layer type
+ * has nothing in the packet data.
+ */
+#if defined(PF_PACKET) && defined(SO_ATTACH_FILTER)
+ /*
+ * We infer that this is Linux with PF_PACKET support.
+ * If this is a *live* capture, we can look at
+ * special meta-data in the filter expression;
+ * if it's a savefile, we can't.
+ */
+ if (bpf_pcap->sf.rfile != NULL) {
+ /* We have a FILE *, so this is a savefile */
+ bpf_error("inbound/outbound not supported on linktype %d when reading savefiles",
+ linktype);
+ b0 = NULL;
+ /* NOTREACHED */
+ }
+ /* match outgoing packets */
+ b0 = gen_cmp(OR_LINK, SKF_AD_OFF + SKF_AD_PKTTYPE, BPF_H,
+ PACKET_OUTGOING);
+ if (!dir) {
+ /* to filter on inbound traffic, invert the match */
+ gen_not(b0);
+ }
+#else /* defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
+ bpf_error("inbound/outbound not supported on linktype %d",
+ linktype);
+ b0 = NULL;
+ /* NOTREACHED */
+#endif /* defined(PF_PACKET) && defined(SO_ATTACH_FILTER) */
+ }
+ return (b0);
+}
+
+#ifdef HAVE_NET_PFVAR_H
+/* PF firewall log matched interface */
+struct block *
+gen_pf_ifname(const char *ifname)
+{
+ struct block *b0;
+ u_int len, off;
+
+ if (linktype != DLT_PFLOG) {
+ bpf_error("ifname supported only on PF linktype");
+ /* NOTREACHED */
+ }
+ len = sizeof(((struct pfloghdr *)0)->ifname);
+ off = offsetof(struct pfloghdr, ifname);
+ if (strlen(ifname) >= len) {
+ bpf_error("ifname interface names can only be %d characters",
+ len-1);
+ /* NOTREACHED */
+ }
+ b0 = gen_bcmp(OR_LINK, off, strlen(ifname), (const u_char *)ifname);
+ return (b0);
+}
+
+/* PF firewall log ruleset name */
+struct block *
+gen_pf_ruleset(char *ruleset)
+{
+ struct block *b0;
+
+ if (linktype != DLT_PFLOG) {
+ bpf_error("ruleset supported only on PF linktype");
+ /* NOTREACHED */
+ }
+
+ if (strlen(ruleset) >= sizeof(((struct pfloghdr *)0)->ruleset)) {
+ bpf_error("ruleset names can only be %ld characters",
+ (long)(sizeof(((struct pfloghdr *)0)->ruleset) - 1));
+ /* NOTREACHED */
+ }
+
+ b0 = gen_bcmp(OR_LINK, offsetof(struct pfloghdr, ruleset),
+ strlen(ruleset), (const u_char *)ruleset);
+ return (b0);
+}
+
+/* PF firewall log rule number */
+struct block *
+gen_pf_rnr(int rnr)
+{
+ struct block *b0;
+
+ if (linktype != DLT_PFLOG) {
+ bpf_error("rnr supported only on PF linktype");
+ /* NOTREACHED */
+ }
+
+ b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, rulenr), BPF_W,
+ (bpf_int32)rnr);
+ return (b0);
+}
+
+/* PF firewall log sub-rule number */
+struct block *
+gen_pf_srnr(int srnr)
+{
+ struct block *b0;
+
+ if (linktype != DLT_PFLOG) {
+ bpf_error("srnr supported only on PF linktype");
+ /* NOTREACHED */
+ }
+
+ b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, subrulenr), BPF_W,
+ (bpf_int32)srnr);
+ return (b0);
+}
+
+/* PF firewall log reason code */
+struct block *
+gen_pf_reason(int reason)
+{
+ struct block *b0;
+
+ if (linktype != DLT_PFLOG) {
+ bpf_error("reason supported only on PF linktype");
+ /* NOTREACHED */
+ }
+
+ b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, reason), BPF_B,
+ (bpf_int32)reason);
+ return (b0);
+}
+
+/* PF firewall log action */
+struct block *
+gen_pf_action(int action)
+{
+ struct block *b0;
+
+ if (linktype != DLT_PFLOG) {
+ bpf_error("action supported only on PF linktype");
+ /* NOTREACHED */
+ }
+
+ b0 = gen_cmp(OR_LINK, offsetof(struct pfloghdr, action), BPF_B,
+ (bpf_int32)action);
+ return (b0);
+}
+#else /* !HAVE_NET_PFVAR_H */
+struct block *
+gen_pf_ifname(const char *ifname)
+{
+ bpf_error("libpcap was compiled without pf support");
+ /* NOTREACHED */
+ return (NULL);
+}
+
+struct block *
+gen_pf_ruleset(char *ruleset)
+{
+ bpf_error("libpcap was compiled on a machine without pf support");
+ /* NOTREACHED */
+ return (NULL);
+}
+
+struct block *
+gen_pf_rnr(int rnr)
+{
+ bpf_error("libpcap was compiled on a machine without pf support");
+ /* NOTREACHED */
+ return (NULL);
+}
+
+struct block *
+gen_pf_srnr(int srnr)
+{
+ bpf_error("libpcap was compiled on a machine without pf support");
+ /* NOTREACHED */
+ return (NULL);
+}
+
+struct block *
+gen_pf_reason(int reason)
+{
+ bpf_error("libpcap was compiled on a machine without pf support");
+ /* NOTREACHED */
+ return (NULL);
+}
+
+struct block *
+gen_pf_action(int action)
+{
+ bpf_error("libpcap was compiled on a machine without pf support");
+ /* NOTREACHED */
+ return (NULL);
+}
+#endif /* HAVE_NET_PFVAR_H */
+
+/* IEEE 802.11 wireless header */
+struct block *
+gen_p80211_type(int type, int mask)
+{
+ struct block *b0;
+
+ switch (linktype) {
+
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ case DLT_IEEE802_11_RADIO:
+ b0 = gen_mcmp(OR_LINK, 0, BPF_B, (bpf_int32)type,
+ (bpf_int32)mask);
+ break;
+
+ default:
+ bpf_error("802.11 link-layer types supported only on 802.11");
+ /* NOTREACHED */
+ }
+
+ return (b0);
+}
+
+struct block *
+gen_p80211_fcdir(int fcdir)
+{
+ struct block *b0;
+
+ switch (linktype) {
+
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ case DLT_IEEE802_11_RADIO:
+ break;
+
+ default:
+ bpf_error("frame direction supported only with 802.11 headers");
+ /* NOTREACHED */
+ }
+
+ b0 = gen_mcmp(OR_LINK, 1, BPF_B, (bpf_int32)fcdir,
+ (bpf_u_int32)IEEE80211_FC1_DIR_MASK);
+
+ return (b0);
+}
+
+struct block *
+gen_acode(eaddr, q)
+ register const u_char *eaddr;
+ struct qual q;
+{
+ switch (linktype) {
+
+ case DLT_ARCNET:
+ case DLT_ARCNET_LINUX:
+ if ((q.addr == Q_HOST || q.addr == Q_DEFAULT) &&
+ q.proto == Q_LINK)
+ return (gen_ahostop(eaddr, (int)q.dir));
+ else {
+ bpf_error("ARCnet address used in non-arc expression");
+ /* NOTREACHED */
+ }
+ break;
+
+ default:
+ bpf_error("aid supported only on ARCnet");
+ /* NOTREACHED */
+ }
+ bpf_error("ARCnet address used in non-arc expression");
+ /* NOTREACHED */
+ return NULL;
+}
+
+static struct block *
+gen_ahostop(eaddr, dir)
+ register const u_char *eaddr;
+ register int dir;
+{
+ register struct block *b0, *b1;
+
+ switch (dir) {
+ /* src comes first, different from Ethernet */
+ case Q_SRC:
+ return gen_bcmp(OR_LINK, 0, 1, eaddr);
+
+ case Q_DST:
+ return gen_bcmp(OR_LINK, 1, 1, eaddr);
+
+ case Q_AND:
+ b0 = gen_ahostop(eaddr, Q_SRC);
+ b1 = gen_ahostop(eaddr, Q_DST);
+ gen_and(b0, b1);
+ return b1;
+
+ case Q_DEFAULT:
+ case Q_OR:
+ b0 = gen_ahostop(eaddr, Q_SRC);
+ b1 = gen_ahostop(eaddr, Q_DST);
+ gen_or(b0, b1);
+ return b1;
+
+ case Q_ADDR1:
+ bpf_error("'addr1' is only supported on 802.11");
+ break;
+
+ case Q_ADDR2:
+ bpf_error("'addr2' is only supported on 802.11");
+ break;
+
+ case Q_ADDR3:
+ bpf_error("'addr3' is only supported on 802.11");
+ break;
+
+ case Q_ADDR4:
+ bpf_error("'addr4' is only supported on 802.11");
+ break;
+
+ case Q_RA:
+ bpf_error("'ra' is only supported on 802.11");
+ break;
+
+ case Q_TA:
+ bpf_error("'ta' is only supported on 802.11");
+ break;
+ }
+ abort();
+ /* NOTREACHED */
+}
+
+/*
+ * support IEEE 802.1Q VLAN trunk over ethernet
+ */
+struct block *
+gen_vlan(vlan_num)
+ int vlan_num;
+{
+ struct block *b0, *b1;
+
+ /* can't check for VLAN-encapsulated packets inside MPLS */
+ if (label_stack_depth > 0)
+ bpf_error("no VLAN match after MPLS");
+
+ /*
+ * Check for a VLAN packet, and then change the offsets to point
+ * to the type and data fields within the VLAN packet. Just
+ * increment the offsets, so that we can support a hierarchy, e.g.
+ * "vlan 300 && vlan 200" to capture VLAN 200 encapsulated within
+ * VLAN 100.
+ *
+ * XXX - this is a bit of a kludge. If we were to split the
+ * compiler into a parser that parses an expression and
+ * generates an expression tree, and a code generator that
+ * takes an expression tree (which could come from our
+ * parser or from some other parser) and generates BPF code,
+ * we could perhaps make the offsets parameters of routines
+ * and, in the handler for an "AND" node, pass to subnodes
+ * other than the VLAN node the adjusted offsets.
+ *
+ * This would mean that "vlan" would, instead of changing the
+ * behavior of *all* tests after it, change only the behavior
+ * of tests ANDed with it. That would change the documented
+ * semantics of "vlan", which might break some expressions.
+ * However, it would mean that "(vlan and ip) or ip" would check
+ * both for VLAN-encapsulated IP and IP-over-Ethernet, rather than
+ * checking only for VLAN-encapsulated IP, so that could still
+ * be considered worth doing; it wouldn't break expressions
+ * that are of the form "vlan and ..." or "vlan N and ...",
+ * which I suspect are the most common expressions involving
+ * "vlan". "vlan or ..." doesn't necessarily do what the user
+ * would really want, now, as all the "or ..." tests would
+ * be done assuming a VLAN, even though the "or" could be viewed
+ * as meaning "or, if this isn't a VLAN packet...".
+ */
+ orig_nl = off_nl;
+
+ switch (linktype) {
+
+ case DLT_EN10MB:
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
+ /* check for VLAN, including QinQ */
+ b0 = gen_cmp(OR_LINK, off_linktype, BPF_H,
+ (bpf_int32)ETHERTYPE_8021Q);
+ b1 = gen_cmp(OR_LINK, off_linktype, BPF_H,
+ (bpf_int32)ETHERTYPE_8021QINQ);
+ gen_or(b0,b1);
+ b0 = b1;
+
+ /* If a specific VLAN is requested, check VLAN id */
+ if (vlan_num >= 0) {
+ b1 = gen_mcmp(OR_MACPL, 0, BPF_H,
+ (bpf_int32)vlan_num, 0x0fff);
+ gen_and(b0, b1);
+ b0 = b1;
+ }
+
+ off_macpl += 4;
+ off_linktype += 4;
+#if 0
+ off_nl_nosnap += 4;
+ off_nl += 4;
+#endif
+ break;
+
+ default:
+ bpf_error("no VLAN support for data link type %d",
+ linktype);
+ /*NOTREACHED*/
+ }
+
+ return (b0);
+}
+
+/*
+ * support for MPLS
+ */
+struct block *
+gen_mpls(label_num)
+ int label_num;
+{
+ struct block *b0,*b1;
+
+ /*
+ * Change the offsets to point to the type and data fields within
+ * the MPLS packet. Just increment the offsets, so that we
+ * can support a hierarchy, e.g. "mpls 100000 && mpls 1024" to
+ * capture packets with an outer label of 100000 and an inner
+ * label of 1024.
+ *
+ * XXX - this is a bit of a kludge. See comments in gen_vlan().
+ */
+ orig_nl = off_nl;
+
+ if (label_stack_depth > 0) {
+ /* just match the bottom-of-stack bit clear */
+ b0 = gen_mcmp(OR_MACPL, orig_nl-2, BPF_B, 0, 0x01);
+ } else {
+ /*
+ * Indicate that we're checking MPLS-encapsulated headers,
+ * to make sure higher level code generators don't try to
+ * match against IP-related protocols such as Q_ARP, Q_RARP
+ * etc.
+ */
+ switch (linktype) {
+
+ case DLT_C_HDLC: /* fall through */
+ case DLT_EN10MB:
+ case DLT_NETANALYZER:
+ case DLT_NETANALYZER_TRANSPARENT:
+ b0 = gen_linktype(ETHERTYPE_MPLS);
+ break;
+
+ case DLT_PPP:
+ b0 = gen_linktype(PPP_MPLS_UCAST);
+ break;
+
+ /* FIXME add other DLT_s ...
+ * for Frame-Relay/and ATM this may get messy due to SNAP headers
+ * leave it for now */
+
+ default:
+ bpf_error("no MPLS support for data link type %d",
+ linktype);
+ b0 = NULL;
+ /*NOTREACHED*/
+ break;
+ }
+ }
+
+ /* If a specific MPLS label is requested, check it */
+ if (label_num >= 0) {
+ label_num = label_num << 12; /* label is shifted 12 bits on the wire */
+ b1 = gen_mcmp(OR_MACPL, orig_nl, BPF_W, (bpf_int32)label_num,
+ 0xfffff000); /* only compare the first 20 bits */
+ gen_and(b0, b1);
+ b0 = b1;
+ }
+
+ off_nl_nosnap += 4;
+ off_nl += 4;
+ label_stack_depth++;
+ return (b0);
+}
+
+/*
+ * Support PPPOE discovery and session.
+ */
+struct block *
+gen_pppoed()
+{
+ /* check for PPPoE discovery */
+ return gen_linktype((bpf_int32)ETHERTYPE_PPPOED);
+}
+
+struct block *
+gen_pppoes()
+{
+ struct block *b0;
+
+ /*
+ * Test against the PPPoE session link-layer type.
+ */
+ b0 = gen_linktype((bpf_int32)ETHERTYPE_PPPOES);
+
+ /*
+ * Change the offsets to point to the type and data fields within
+ * the PPP packet, and note that this is PPPoE rather than
+ * raw PPP.
+ *
+ * XXX - this is a bit of a kludge. If we were to split the
+ * compiler into a parser that parses an expression and
+ * generates an expression tree, and a code generator that
+ * takes an expression tree (which could come from our
+ * parser or from some other parser) and generates BPF code,
+ * we could perhaps make the offsets parameters of routines
+ * and, in the handler for an "AND" node, pass to subnodes
+ * other than the PPPoE node the adjusted offsets.
+ *
+ * This would mean that "pppoes" would, instead of changing the
+ * behavior of *all* tests after it, change only the behavior
+ * of tests ANDed with it. That would change the documented
+ * semantics of "pppoes", which might break some expressions.
+ * However, it would mean that "(pppoes and ip) or ip" would check
+ * both for VLAN-encapsulated IP and IP-over-Ethernet, rather than
+ * checking only for VLAN-encapsulated IP, so that could still
+ * be considered worth doing; it wouldn't break expressions
+ * that are of the form "pppoes and ..." which I suspect are the
+ * most common expressions involving "pppoes". "pppoes or ..."
+ * doesn't necessarily do what the user would really want, now,
+ * as all the "or ..." tests would be done assuming PPPoE, even
+ * though the "or" could be viewed as meaning "or, if this isn't
+ * a PPPoE packet...".
+ */
+ orig_linktype = off_linktype; /* save original values */
+ orig_nl = off_nl;
+ is_pppoes = 1;
+
+ /*
+ * The "network-layer" protocol is PPPoE, which has a 6-byte
+ * PPPoE header, followed by a PPP packet.
+ *
+ * There is no HDLC encapsulation for the PPP packet (it's
+ * encapsulated in PPPoES instead), so the link-layer type
+ * starts at the first byte of the PPP packet. For PPPoE,
+ * that offset is relative to the beginning of the total
+ * link-layer payload, including any 802.2 LLC header, so
+ * it's 6 bytes past off_nl.
+ */
+ off_linktype = off_nl + 6;
+
+ /*
+ * The network-layer offsets are relative to the beginning
+ * of the MAC-layer payload; that's past the 6-byte
+ * PPPoE header and the 2-byte PPP header.
+ */
+ off_nl = 6+2;
+ off_nl_nosnap = 6+2;
+
+ return b0;
+}
+
+struct block *
+gen_atmfield_code(atmfield, jvalue, jtype, reverse)
+ int atmfield;
+ bpf_int32 jvalue;
+ bpf_u_int32 jtype;
+ int reverse;
+{
+ struct block *b0;
+
+ switch (atmfield) {
+
+ case A_VPI:
+ if (!is_atm)
+ bpf_error("'vpi' supported only on raw ATM");
+ if (off_vpi == (u_int)-1)
+ abort();
+ b0 = gen_ncmp(OR_LINK, off_vpi, BPF_B, 0xffffffff, jtype,
+ reverse, jvalue);
+ break;
+
+ case A_VCI:
+ if (!is_atm)
+ bpf_error("'vci' supported only on raw ATM");
+ if (off_vci == (u_int)-1)
+ abort();
+ b0 = gen_ncmp(OR_LINK, off_vci, BPF_H, 0xffffffff, jtype,
+ reverse, jvalue);
+ break;
+
+ case A_PROTOTYPE:
+ if (off_proto == (u_int)-1)
+ abort(); /* XXX - this isn't on FreeBSD */
+ b0 = gen_ncmp(OR_LINK, off_proto, BPF_B, 0x0f, jtype,
+ reverse, jvalue);
+ break;
+
+ case A_MSGTYPE:
+ if (off_payload == (u_int)-1)
+ abort();
+ b0 = gen_ncmp(OR_LINK, off_payload + MSG_TYPE_POS, BPF_B,
+ 0xffffffff, jtype, reverse, jvalue);
+ break;
+
+ case A_CALLREFTYPE:
+ if (!is_atm)
+ bpf_error("'callref' supported only on raw ATM");
+ if (off_proto == (u_int)-1)
+ abort();
+ b0 = gen_ncmp(OR_LINK, off_proto, BPF_B, 0xffffffff,
+ jtype, reverse, jvalue);
+ break;
+
+ default:
+ abort();
+ }
+ return b0;
+}
+
+struct block *
+gen_atmtype_abbrev(type)
+ int type;
+{
+ struct block *b0, *b1;
+
+ switch (type) {
+
+ case A_METAC:
+ /* Get all packets in Meta signalling Circuit */
+ if (!is_atm)
+ bpf_error("'metac' supported only on raw ATM");
+ b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code(A_VCI, 1, BPF_JEQ, 0);
+ gen_and(b0, b1);
+ break;
+
+ case A_BCC:
+ /* Get all packets in Broadcast Circuit*/
+ if (!is_atm)
+ bpf_error("'bcc' supported only on raw ATM");
+ b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code(A_VCI, 2, BPF_JEQ, 0);
+ gen_and(b0, b1);
+ break;
+
+ case A_OAMF4SC:
+ /* Get all cells in Segment OAM F4 circuit*/
+ if (!is_atm)
+ bpf_error("'oam4sc' supported only on raw ATM");
+ b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code(A_VCI, 3, BPF_JEQ, 0);
+ gen_and(b0, b1);
+ break;
+
+ case A_OAMF4EC:
+ /* Get all cells in End-to-End OAM F4 Circuit*/
+ if (!is_atm)
+ bpf_error("'oam4ec' supported only on raw ATM");
+ b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code(A_VCI, 4, BPF_JEQ, 0);
+ gen_and(b0, b1);
+ break;
+
+ case A_SC:
+ /* Get all packets in connection Signalling Circuit */
+ if (!is_atm)
+ bpf_error("'sc' supported only on raw ATM");
+ b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code(A_VCI, 5, BPF_JEQ, 0);
+ gen_and(b0, b1);
+ break;
+
+ case A_ILMIC:
+ /* Get all packets in ILMI Circuit */
+ if (!is_atm)
+ bpf_error("'ilmic' supported only on raw ATM");
+ b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
+ b1 = gen_atmfield_code(A_VCI, 16, BPF_JEQ, 0);
+ gen_and(b0, b1);
+ break;
+
+ case A_LANE:
+ /* Get all LANE packets */
+ if (!is_atm)
+ bpf_error("'lane' supported only on raw ATM");
+ b1 = gen_atmfield_code(A_PROTOTYPE, PT_LANE, BPF_JEQ, 0);
+
+ /*
+ * Arrange that all subsequent tests assume LANE
+ * rather than LLC-encapsulated packets, and set
+ * the offsets appropriately for LANE-encapsulated
+ * Ethernet.
+ *
+ * "off_mac" is the offset of the Ethernet header,
+ * which is 2 bytes past the ATM pseudo-header
+ * (skipping the pseudo-header and 2-byte LE Client
+ * field). The other offsets are Ethernet offsets
+ * relative to "off_mac".
+ */
+ is_lane = 1;
+ off_mac = off_payload + 2; /* MAC header */
+ off_linktype = off_mac + 12;
+ off_macpl = off_mac + 14; /* Ethernet */
+ off_nl = 0; /* Ethernet II */
+ off_nl_nosnap = 3; /* 802.3+802.2 */
+ break;
+
+ case A_LLC:
+ /* Get all LLC-encapsulated packets */
+ if (!is_atm)
+ bpf_error("'llc' supported only on raw ATM");
+ b1 = gen_atmfield_code(A_PROTOTYPE, PT_LLC, BPF_JEQ, 0);
+ is_lane = 0;
+ break;
+
+ default:
+ abort();
+ }
+ return b1;
+}
+
+/*
+ * Filtering for MTP2 messages based on li value
+ * FISU, length is null
+ * LSSU, length is 1 or 2
+ * MSU, length is 3 or more
+ */
+struct block *
+gen_mtp2type_abbrev(type)
+ int type;
+{
+ struct block *b0, *b1;
+
+ switch (type) {
+
+ case M_FISU:
+ if ( (linktype != DLT_MTP2) &&
+ (linktype != DLT_ERF) &&
+ (linktype != DLT_MTP2_WITH_PHDR) )
+ bpf_error("'fisu' supported only on MTP2");
+ /* gen_ncmp(offrel, offset, size, mask, jtype, reverse, value) */
+ b0 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JEQ, 0, 0);
+ break;
+
+ case M_LSSU:
+ if ( (linktype != DLT_MTP2) &&
+ (linktype != DLT_ERF) &&
+ (linktype != DLT_MTP2_WITH_PHDR) )
+ bpf_error("'lssu' supported only on MTP2");
+ b0 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JGT, 1, 2);
+ b1 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JGT, 0, 0);
+ gen_and(b1, b0);
+ break;
+
+ case M_MSU:
+ if ( (linktype != DLT_MTP2) &&
+ (linktype != DLT_ERF) &&
+ (linktype != DLT_MTP2_WITH_PHDR) )
+ bpf_error("'msu' supported only on MTP2");
+ b0 = gen_ncmp(OR_PACKET, off_li, BPF_B, 0x3f, BPF_JGT, 0, 2);
+ break;
+
+ default:
+ abort();
+ }
+ return b0;
+}
+
+struct block *
+gen_mtp3field_code(mtp3field, jvalue, jtype, reverse)
+ int mtp3field;
+ bpf_u_int32 jvalue;
+ bpf_u_int32 jtype;
+ int reverse;
+{
+ struct block *b0;
+ bpf_u_int32 val1 , val2 , val3;
+
+ switch (mtp3field) {
+
+ case M_SIO:
+ if (off_sio == (u_int)-1)
+ bpf_error("'sio' supported only on SS7");
+ /* sio coded on 1 byte so max value 255 */
+ if(jvalue > 255)
+ bpf_error("sio value %u too big; max value = 255",
+ jvalue);
+ b0 = gen_ncmp(OR_PACKET, off_sio, BPF_B, 0xffffffff,
+ (u_int)jtype, reverse, (u_int)jvalue);
+ break;
+
+ case M_OPC:
+ if (off_opc == (u_int)-1)
+ bpf_error("'opc' supported only on SS7");
+ /* opc coded on 14 bits so max value 16383 */
+ if (jvalue > 16383)
+ bpf_error("opc value %u too big; max value = 16383",
+ jvalue);
+ /* the following instructions are made to convert jvalue
+ * to the form used to write opc in an ss7 message*/
+ val1 = jvalue & 0x00003c00;
+ val1 = val1 >>10;
+ val2 = jvalue & 0x000003fc;
+ val2 = val2 <<6;
+ val3 = jvalue & 0x00000003;
+ val3 = val3 <<22;
+ jvalue = val1 + val2 + val3;
+ b0 = gen_ncmp(OR_PACKET, off_opc, BPF_W, 0x00c0ff0f,
+ (u_int)jtype, reverse, (u_int)jvalue);
+ break;
+
+ case M_DPC:
+ if (off_dpc == (u_int)-1)
+ bpf_error("'dpc' supported only on SS7");
+ /* dpc coded on 14 bits so max value 16383 */
+ if (jvalue > 16383)
+ bpf_error("dpc value %u too big; max value = 16383",
+ jvalue);
+ /* the following instructions are made to convert jvalue
+ * to the forme used to write dpc in an ss7 message*/
+ val1 = jvalue & 0x000000ff;
+ val1 = val1 << 24;
+ val2 = jvalue & 0x00003f00;
+ val2 = val2 << 8;
+ jvalue = val1 + val2;
+ b0 = gen_ncmp(OR_PACKET, off_dpc, BPF_W, 0xff3f0000,
+ (u_int)jtype, reverse, (u_int)jvalue);
+ break;
+
+ case M_SLS:
+ if (off_sls == (u_int)-1)
+ bpf_error("'sls' supported only on SS7");
+ /* sls coded on 4 bits so max value 15 */
+ if (jvalue > 15)
+ bpf_error("sls value %u too big; max value = 15",
+ jvalue);
+ /* the following instruction is made to convert jvalue
+ * to the forme used to write sls in an ss7 message*/
+ jvalue = jvalue << 4;
+ b0 = gen_ncmp(OR_PACKET, off_sls, BPF_B, 0xf0,
+ (u_int)jtype,reverse, (u_int)jvalue);
+ break;
+
+ default:
+ abort();
+ }
+ return b0;
+}
+
+static struct block *
+gen_msg_abbrev(type)
+ int type;
+{
+ struct block *b1;
+
+ /*
+ * Q.2931 signalling protocol messages for handling virtual circuits
+ * establishment and teardown
+ */
+ switch (type) {
+
+ case A_SETUP:
+ b1 = gen_atmfield_code(A_MSGTYPE, SETUP, BPF_JEQ, 0);
+ break;
+
+ case A_CALLPROCEED:
+ b1 = gen_atmfield_code(A_MSGTYPE, CALL_PROCEED, BPF_JEQ, 0);
+ break;
+
+ case A_CONNECT:
+ b1 = gen_atmfield_code(A_MSGTYPE, CONNECT, BPF_JEQ, 0);
+ break;
+
+ case A_CONNECTACK:
+ b1 = gen_atmfield_code(A_MSGTYPE, CONNECT_ACK, BPF_JEQ, 0);
+ break;
+
+ case A_RELEASE:
+ b1 = gen_atmfield_code(A_MSGTYPE, RELEASE, BPF_JEQ, 0);
+ break;
+
+ case A_RELEASE_DONE:
+ b1 = gen_atmfield_code(A_MSGTYPE, RELEASE_DONE, BPF_JEQ, 0);
+ break;
+
+ default:
+ abort();
+ }
+ return b1;
+}
+
+struct block *
+gen_atmmulti_abbrev(type)
+ int type;
+{
+ struct block *b0, *b1;
+
+ switch (type) {
+
+ case A_OAM:
+ if (!is_atm)
+ bpf_error("'oam' supported only on raw ATM");
+ b1 = gen_atmmulti_abbrev(A_OAMF4);
+ break;
+
+ case A_OAMF4:
+ if (!is_atm)
+ bpf_error("'oamf4' supported only on raw ATM");
+ /* OAM F4 type */
+ b0 = gen_atmfield_code(A_VCI, 3, BPF_JEQ, 0);
+ b1 = gen_atmfield_code(A_VCI, 4, BPF_JEQ, 0);
+ gen_or(b0, b1);
+ b0 = gen_atmfield_code(A_VPI, 0, BPF_JEQ, 0);
+ gen_and(b0, b1);
+ break;
+
+ case A_CONNECTMSG:
+ /*
+ * Get Q.2931 signalling messages for switched
+ * virtual connection
+ */
+ if (!is_atm)
+ bpf_error("'connectmsg' supported only on raw ATM");
+ b0 = gen_msg_abbrev(A_SETUP);
+ b1 = gen_msg_abbrev(A_CALLPROCEED);
+ gen_or(b0, b1);
+ b0 = gen_msg_abbrev(A_CONNECT);
+ gen_or(b0, b1);
+ b0 = gen_msg_abbrev(A_CONNECTACK);
+ gen_or(b0, b1);
+ b0 = gen_msg_abbrev(A_RELEASE);
+ gen_or(b0, b1);
+ b0 = gen_msg_abbrev(A_RELEASE_DONE);
+ gen_or(b0, b1);
+ b0 = gen_atmtype_abbrev(A_SC);
+ gen_and(b0, b1);
+ break;
+
+ case A_METACONNECT:
+ if (!is_atm)
+ bpf_error("'metaconnect' supported only on raw ATM");
+ b0 = gen_msg_abbrev(A_SETUP);
+ b1 = gen_msg_abbrev(A_CALLPROCEED);
+ gen_or(b0, b1);
+ b0 = gen_msg_abbrev(A_CONNECT);
+ gen_or(b0, b1);
+ b0 = gen_msg_abbrev(A_RELEASE);
+ gen_or(b0, b1);
+ b0 = gen_msg_abbrev(A_RELEASE_DONE);
+ gen_or(b0, b1);
+ b0 = gen_atmtype_abbrev(A_METAC);
+ gen_and(b0, b1);
+ break;
+
+ default:
+ abort();
+ }
+ return b1;
+}
diff --git a/freebsd/contrib/libpcap/gencode.h b/freebsd/contrib/libpcap/gencode.h
new file mode 100644
index 00000000..29d2d10f
--- /dev/null
+++ b/freebsd/contrib/libpcap/gencode.h
@@ -0,0 +1,343 @@
+/*
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/gencode.h,v 1.71 2007-11-18 02:03:52 guy Exp $ (LBL)
+ */
+
+/*
+ * ATM support:
+ *
+ * Copyright (c) 1997 Yen Yen Lim and North Dakota State University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Yen Yen Lim and
+ * North Dakota State University
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HAVE___ATTRIBUTE__
+#define __attribute__(x)
+#endif /* HAVE___ATTRIBUTE__ */
+
+/* Address qualifiers. */
+
+#define Q_HOST 1
+#define Q_NET 2
+#define Q_PORT 3
+#define Q_GATEWAY 4
+#define Q_PROTO 5
+#define Q_PROTOCHAIN 6
+#define Q_PORTRANGE 7
+
+/* Protocol qualifiers. */
+
+#define Q_LINK 1
+#define Q_IP 2
+#define Q_ARP 3
+#define Q_RARP 4
+#define Q_SCTP 5
+#define Q_TCP 6
+#define Q_UDP 7
+#define Q_ICMP 8
+#define Q_IGMP 9
+#define Q_IGRP 10
+
+
+#define Q_ATALK 11
+#define Q_DECNET 12
+#define Q_LAT 13
+#define Q_SCA 14
+#define Q_MOPRC 15
+#define Q_MOPDL 16
+
+
+#define Q_IPV6 17
+#define Q_ICMPV6 18
+#define Q_AH 19
+#define Q_ESP 20
+
+#define Q_PIM 21
+#define Q_VRRP 22
+
+#define Q_AARP 23
+
+#define Q_ISO 24
+#define Q_ESIS 25
+#define Q_ISIS 26
+#define Q_CLNP 27
+
+#define Q_STP 28
+
+#define Q_IPX 29
+
+#define Q_NETBEUI 30
+
+/* IS-IS Levels */
+#define Q_ISIS_L1 31
+#define Q_ISIS_L2 32
+/* PDU types */
+#define Q_ISIS_IIH 33
+#define Q_ISIS_LAN_IIH 34
+#define Q_ISIS_PTP_IIH 35
+#define Q_ISIS_SNP 36
+#define Q_ISIS_CSNP 37
+#define Q_ISIS_PSNP 38
+#define Q_ISIS_LSP 39
+
+#define Q_RADIO 40
+
+#define Q_CARP 41
+
+/* Directional qualifiers. */
+
+#define Q_SRC 1
+#define Q_DST 2
+#define Q_OR 3
+#define Q_AND 4
+#define Q_ADDR1 5
+#define Q_ADDR2 6
+#define Q_ADDR3 7
+#define Q_ADDR4 8
+#define Q_RA 9
+#define Q_TA 10
+
+#define Q_DEFAULT 0
+#define Q_UNDEF 255
+
+/* ATM types */
+#define A_METAC 22 /* Meta signalling Circuit */
+#define A_BCC 23 /* Broadcast Circuit */
+#define A_OAMF4SC 24 /* Segment OAM F4 Circuit */
+#define A_OAMF4EC 25 /* End-to-End OAM F4 Circuit */
+#define A_SC 26 /* Signalling Circuit*/
+#define A_ILMIC 27 /* ILMI Circuit */
+#define A_OAM 28 /* OAM cells : F4 only */
+#define A_OAMF4 29 /* OAM F4 cells: Segment + End-to-end */
+#define A_LANE 30 /* LANE traffic */
+#define A_LLC 31 /* LLC-encapsulated traffic */
+
+/* Based on Q.2931 signalling protocol */
+#define A_SETUP 41 /* Setup message */
+#define A_CALLPROCEED 42 /* Call proceeding message */
+#define A_CONNECT 43 /* Connect message */
+#define A_CONNECTACK 44 /* Connect Ack message */
+#define A_RELEASE 45 /* Release message */
+#define A_RELEASE_DONE 46 /* Release message */
+
+/* ATM field types */
+#define A_VPI 51
+#define A_VCI 52
+#define A_PROTOTYPE 53
+#define A_MSGTYPE 54
+#define A_CALLREFTYPE 55
+
+#define A_CONNECTMSG 70 /* returns Q.2931 signalling messages for
+ establishing and destroying switched
+ virtual connection */
+#define A_METACONNECT 71 /* returns Q.2931 signalling messages for
+ establishing and destroying predefined
+ virtual circuits, such as broadcast
+ circuit, oamf4 segment circuit, oamf4
+ end-to-end circuits, ILMI circuits or
+ connection signalling circuit. */
+
+/* MTP2 types */
+#define M_FISU 22 /* FISU */
+#define M_LSSU 23 /* LSSU */
+#define M_MSU 24 /* MSU */
+
+/* MTP3 field types */
+#define M_SIO 1
+#define M_OPC 2
+#define M_DPC 3
+#define M_SLS 4
+
+
+struct slist;
+
+struct stmt {
+ int code;
+ struct slist *jt; /*only for relative jump in block*/
+ struct slist *jf; /*only for relative jump in block*/
+ bpf_int32 k;
+};
+
+struct slist {
+ struct stmt s;
+ struct slist *next;
+};
+
+/*
+ * A bit vector to represent definition sets. We assume TOT_REGISTERS
+ * is smaller than 8*sizeof(atomset).
+ */
+typedef bpf_u_int32 atomset;
+#define ATOMMASK(n) (1 << (n))
+#define ATOMELEM(d, n) (d & ATOMMASK(n))
+
+/*
+ * An unbounded set.
+ */
+typedef bpf_u_int32 *uset;
+
+/*
+ * Total number of atomic entities, including accumulator (A) and index (X).
+ * We treat all these guys similarly during flow analysis.
+ */
+#define N_ATOMS (BPF_MEMWORDS+2)
+
+struct edge {
+ int id;
+ int code;
+ uset edom;
+ struct block *succ;
+ struct block *pred;
+ struct edge *next; /* link list of incoming edges for a node */
+};
+
+struct block {
+ int id;
+ struct slist *stmts; /* side effect stmts */
+ struct stmt s; /* branch stmt */
+ int mark;
+ u_int longjt; /* jt branch requires long jump */
+ u_int longjf; /* jf branch requires long jump */
+ int level;
+ int offset;
+ int sense;
+ struct edge et;
+ struct edge ef;
+ struct block *head;
+ struct block *link; /* link field used by optimizer */
+ uset dom;
+ uset closure;
+ struct edge *in_edges;
+ atomset def, kill;
+ atomset in_use;
+ atomset out_use;
+ int oval;
+ int val[N_ATOMS];
+};
+
+struct arth {
+ struct block *b; /* protocol checks */
+ struct slist *s; /* stmt list */
+ int regno; /* virtual register number of result */
+};
+
+struct qual {
+ unsigned char addr;
+ unsigned char proto;
+ unsigned char dir;
+ unsigned char pad;
+};
+
+struct arth *gen_loadi(int);
+struct arth *gen_load(int, struct arth *, int);
+struct arth *gen_loadlen(void);
+struct arth *gen_neg(struct arth *);
+struct arth *gen_arth(int, struct arth *, struct arth *);
+
+void gen_and(struct block *, struct block *);
+void gen_or(struct block *, struct block *);
+void gen_not(struct block *);
+
+struct block *gen_scode(const char *, struct qual);
+struct block *gen_ecode(const u_char *, struct qual);
+struct block *gen_acode(const u_char *, struct qual);
+struct block *gen_mcode(const char *, const char *, int, struct qual);
+#ifdef INET6
+struct block *gen_mcode6(const char *, const char *, int, struct qual);
+#endif
+struct block *gen_ncode(const char *, bpf_u_int32, struct qual);
+struct block *gen_proto_abbrev(int);
+struct block *gen_relation(int, struct arth *, struct arth *, int);
+struct block *gen_less(int);
+struct block *gen_greater(int);
+struct block *gen_byteop(int, int, int);
+struct block *gen_broadcast(int);
+struct block *gen_multicast(int);
+struct block *gen_inbound(int);
+
+struct block *gen_vlan(int);
+struct block *gen_mpls(int);
+
+struct block *gen_pppoed(void);
+struct block *gen_pppoes(void);
+
+struct block *gen_atmfield_code(int atmfield, bpf_int32 jvalue, bpf_u_int32 jtype, int reverse);
+struct block *gen_atmtype_abbrev(int type);
+struct block *gen_atmmulti_abbrev(int type);
+
+struct block *gen_mtp2type_abbrev(int type);
+struct block *gen_mtp3field_code(int mtp3field, bpf_u_int32 jvalue, bpf_u_int32 jtype, int reverse);
+
+struct block *gen_pf_ifname(const char *);
+struct block *gen_pf_rnr(int);
+struct block *gen_pf_srnr(int);
+struct block *gen_pf_ruleset(char *);
+struct block *gen_pf_reason(int);
+struct block *gen_pf_action(int);
+struct block *gen_pf_dir(int);
+
+struct block *gen_p80211_type(int, int);
+struct block *gen_p80211_fcdir(int);
+
+void bpf_optimize(struct block **);
+void bpf_error(const char *, ...)
+ __attribute__((noreturn, format (printf, 1, 2)));
+
+void finish_parse(struct block *);
+char *sdup(const char *);
+
+struct bpf_insn *icode_to_fcode(struct block *, u_int *);
+int pcap_parse(void);
+void lex_init(const char *);
+void lex_cleanup(void);
+void sappend(struct slist *, struct slist *);
+
+/* XXX */
+#define JT(b) ((b)->et.succ)
+#define JF(b) ((b)->ef.succ)
+
+extern int no_optimize;
diff --git a/freebsd/contrib/libpcap/grammar.c b/freebsd/contrib/libpcap/grammar.c
new file mode 100644
index 00000000..bfd9927a
--- /dev/null
+++ b/freebsd/contrib/libpcap/grammar.c
@@ -0,0 +1,2280 @@
+/* original parser id follows */
+/* yysccsid[] = "@(#)yaccpar 1.9 (Berkeley) 02/21/93" */
+/* (use YYMAJOR/YYMINOR for ifdefs dependent on parser version) */
+
+#define YYBYACC 1
+#define YYMAJOR 1
+#define YYMINOR 9
+
+#define YYEMPTY (-1)
+#define yyclearin (yychar = YYEMPTY)
+#define yyerrok (yyerrflag = 0)
+#define YYRECOVERING() (yyerrflag != 0)
+#define YYENOMEM (-2)
+#define YYEOF 0
+
+#ifndef yyparse
+#define yyparse pcapparse
+#endif /* yyparse */
+
+#ifndef yylex
+#define yylex pcaplex
+#endif /* yylex */
+
+#ifndef yyerror
+#define yyerror pcaperror
+#endif /* yyerror */
+
+#ifndef yychar
+#define yychar pcapchar
+#endif /* yychar */
+
+#ifndef yyval
+#define yyval pcapval
+#endif /* yyval */
+
+#ifndef yylval
+#define yylval pcaplval
+#endif /* yylval */
+
+#ifndef yydebug
+#define yydebug pcapdebug
+#endif /* yydebug */
+
+#ifndef yynerrs
+#define yynerrs pcapnerrs
+#endif /* yynerrs */
+
+#ifndef yyerrflag
+#define yyerrflag pcaperrflag
+#endif /* yyerrflag */
+
+#ifndef yylhs
+#define yylhs pcaplhs
+#endif /* yylhs */
+
+#ifndef yylen
+#define yylen pcaplen
+#endif /* yylen */
+
+#ifndef yydefred
+#define yydefred pcapdefred
+#endif /* yydefred */
+
+#ifndef yydgoto
+#define yydgoto pcapdgoto
+#endif /* yydgoto */
+
+#ifndef yysindex
+#define yysindex pcapsindex
+#endif /* yysindex */
+
+#ifndef yyrindex
+#define yyrindex pcaprindex
+#endif /* yyrindex */
+
+#ifndef yygindex
+#define yygindex pcapgindex
+#endif /* yygindex */
+
+#ifndef yytable
+#define yytable pcaptable
+#endif /* yytable */
+
+#ifndef yycheck
+#define yycheck pcapcheck
+#endif /* yycheck */
+
+#ifndef yyname
+#define yyname pcapname
+#endif /* yyname */
+
+#ifndef yyrule
+#define yyrule pcaprule
+#endif /* yyrule */
+#define YYPREFIX "pcap"
+
+#define YYPURE 0
+
+#line 2 "../../freebsd/contrib/libpcap/grammar.y"
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.101 2007-11-18 02:03:52 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#include <sys/types.h>
+#include <sys/socket.h>
+#endif /* WIN32 */
+
+#include <stdlib.h>
+
+#ifndef WIN32
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif /* WIN32 */
+
+#include <stdio.h>
+
+#include "pcap-int.h"
+
+#include "gencode.h"
+#ifdef HAVE_NET_PFVAR_H
+#include <net/if.h>
+#include <net/pfvar.h>
+#include <net/if_pflog.h>
+#endif
+#include "ieee80211.h"
+#include <pcap/namedb.h>
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#define QSET(q, p, d, a) (q).proto = (p),\
+ (q).dir = (d),\
+ (q).addr = (a)
+
+struct tok {
+ int v; /* value */
+ const char *s; /* string */
+};
+
+static const struct tok ieee80211_types[] = {
+ { IEEE80211_FC0_TYPE_DATA, "data" },
+ { IEEE80211_FC0_TYPE_MGT, "mgt" },
+ { IEEE80211_FC0_TYPE_MGT, "management" },
+ { IEEE80211_FC0_TYPE_CTL, "ctl" },
+ { IEEE80211_FC0_TYPE_CTL, "control" },
+ { 0, NULL }
+};
+static const struct tok ieee80211_mgt_subtypes[] = {
+ { IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assocreq" },
+ { IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assoc-req" },
+ { IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assocresp" },
+ { IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assoc-resp" },
+ { IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassocreq" },
+ { IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassoc-req" },
+ { IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassocresp" },
+ { IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassoc-resp" },
+ { IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probereq" },
+ { IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probe-req" },
+ { IEEE80211_FC0_SUBTYPE_PROBE_RESP, "proberesp" },
+ { IEEE80211_FC0_SUBTYPE_PROBE_RESP, "probe-resp" },
+ { IEEE80211_FC0_SUBTYPE_BEACON, "beacon" },
+ { IEEE80211_FC0_SUBTYPE_ATIM, "atim" },
+ { IEEE80211_FC0_SUBTYPE_DISASSOC, "disassoc" },
+ { IEEE80211_FC0_SUBTYPE_DISASSOC, "disassociation" },
+ { IEEE80211_FC0_SUBTYPE_AUTH, "auth" },
+ { IEEE80211_FC0_SUBTYPE_AUTH, "authentication" },
+ { IEEE80211_FC0_SUBTYPE_DEAUTH, "deauth" },
+ { IEEE80211_FC0_SUBTYPE_DEAUTH, "deauthentication" },
+ { 0, NULL }
+};
+static const struct tok ieee80211_ctl_subtypes[] = {
+ { IEEE80211_FC0_SUBTYPE_PS_POLL, "ps-poll" },
+ { IEEE80211_FC0_SUBTYPE_RTS, "rts" },
+ { IEEE80211_FC0_SUBTYPE_CTS, "cts" },
+ { IEEE80211_FC0_SUBTYPE_ACK, "ack" },
+ { IEEE80211_FC0_SUBTYPE_CF_END, "cf-end" },
+ { IEEE80211_FC0_SUBTYPE_CF_END_ACK, "cf-end-ack" },
+ { 0, NULL }
+};
+static const struct tok ieee80211_data_subtypes[] = {
+ { IEEE80211_FC0_SUBTYPE_DATA, "data" },
+ { IEEE80211_FC0_SUBTYPE_CF_ACK, "data-cf-ack" },
+ { IEEE80211_FC0_SUBTYPE_CF_POLL, "data-cf-poll" },
+ { IEEE80211_FC0_SUBTYPE_CF_ACPL, "data-cf-ack-poll" },
+ { IEEE80211_FC0_SUBTYPE_NODATA, "null" },
+ { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACK, "cf-ack" },
+ { IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "cf-poll" },
+ { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "cf-ack-poll" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_DATA, "qos-data" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACK, "qos-data-cf-ack" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_POLL, "qos-data-cf-poll" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACPL, "qos-data-cf-ack-poll" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA, "qos" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "qos-cf-poll" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "qos-cf-ack-poll" },
+ { 0, NULL }
+};
+struct type2tok {
+ int type;
+ const struct tok *tok;
+};
+static const struct type2tok ieee80211_type_subtypes[] = {
+ { IEEE80211_FC0_TYPE_MGT, ieee80211_mgt_subtypes },
+ { IEEE80211_FC0_TYPE_CTL, ieee80211_ctl_subtypes },
+ { IEEE80211_FC0_TYPE_DATA, ieee80211_data_subtypes },
+ { 0, NULL }
+};
+
+static int
+str2tok(const char *str, const struct tok *toks)
+{
+ int i;
+
+ for (i = 0; toks[i].s != NULL; i++) {
+ if (pcap_strcasecmp(toks[i].s, str) == 0)
+ return (toks[i].v);
+ }
+ return (-1);
+}
+
+int n_errors = 0;
+
+static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
+
+static void
+yyerror(const char *msg)
+{
+ ++n_errors;
+ bpf_error("%s", msg);
+ /* NOTREACHED */
+}
+
+#ifdef NEED_YYPARSE_WRAPPER
+int yyparse(void);
+
+int
+pcap_parse()
+{
+ return (yyparse());
+}
+#endif
+
+#ifdef HAVE_NET_PFVAR_H
+static int
+pfreason_to_num(const char *reason)
+{
+ const char *reasons[] = PFRES_NAMES;
+ int i;
+
+ for (i = 0; reasons[i]; i++) {
+ if (pcap_strcasecmp(reason, reasons[i]) == 0)
+ return (i);
+ }
+ bpf_error("unknown PF reason");
+ /*NOTREACHED*/
+}
+
+static int
+pfaction_to_num(const char *action)
+{
+ if (pcap_strcasecmp(action, "pass") == 0 ||
+ pcap_strcasecmp(action, "accept") == 0)
+ return (PF_PASS);
+ else if (pcap_strcasecmp(action, "drop") == 0 ||
+ pcap_strcasecmp(action, "block") == 0)
+ return (PF_DROP);
+#if HAVE_PF_NAT_THROUGH_PF_NORDR
+ else if (pcap_strcasecmp(action, "rdr") == 0)
+ return (PF_RDR);
+ else if (pcap_strcasecmp(action, "nat") == 0)
+ return (PF_NAT);
+ else if (pcap_strcasecmp(action, "binat") == 0)
+ return (PF_BINAT);
+ else if (pcap_strcasecmp(action, "nordr") == 0)
+ return (PF_NORDR);
+#endif
+ else {
+ bpf_error("unknown PF action");
+ /*NOTREACHED*/
+ }
+}
+#else /* !HAVE_NET_PFVAR_H */
+static int
+pfreason_to_num(const char *reason)
+{
+ bpf_error("libpcap was compiled on a machine without pf support");
+ /*NOTREACHED*/
+
+ /* this is to make the VC compiler happy */
+ return -1;
+}
+
+static int
+pfaction_to_num(const char *action)
+{
+ bpf_error("libpcap was compiled on a machine without pf support");
+ /*NOTREACHED*/
+
+ /* this is to make the VC compiler happy */
+ return -1;
+}
+#endif /* HAVE_NET_PFVAR_H */
+#line 243 "../../freebsd/contrib/libpcap/grammar.y"
+#ifdef YYSTYPE
+#undef YYSTYPE_IS_DECLARED
+#define YYSTYPE_IS_DECLARED 1
+#endif
+#ifndef YYSTYPE_IS_DECLARED
+#define YYSTYPE_IS_DECLARED 1
+typedef union {
+ int i;
+ bpf_u_int32 h;
+ u_char *e;
+ char *s;
+ struct stmt *stmt;
+ struct arth *a;
+ struct {
+ struct qual q;
+ int atmfieldtype;
+ int mtp3fieldtype;
+ struct block *b;
+ } blk;
+ struct block *rblk;
+} YYSTYPE;
+#endif /* !YYSTYPE_IS_DECLARED */
+#line 363 "pcap.tab.c"
+
+/* compatibility with bison */
+#ifdef YYPARSE_PARAM
+/* compatibility with FreeBSD */
+# ifdef YYPARSE_PARAM_TYPE
+# define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM)
+# else
+# define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM)
+# endif
+#else
+# define YYPARSE_DECL() yyparse(void)
+#endif
+
+/* Parameters sent to lex. */
+#ifdef YYLEX_PARAM
+# define YYLEX_DECL() yylex(void *YYLEX_PARAM)
+# define YYLEX yylex(YYLEX_PARAM)
+#else
+# define YYLEX_DECL() yylex(void)
+# define YYLEX yylex()
+#endif
+
+/* Parameters sent to yyerror. */
+#ifndef YYERROR_DECL
+#define YYERROR_DECL() yyerror(const char *s)
+#endif
+#ifndef YYERROR_CALL
+#define YYERROR_CALL(msg) yyerror(msg)
+#endif
+
+extern int YYPARSE_DECL();
+
+#define DST 257
+#define SRC 258
+#define HOST 259
+#define GATEWAY 260
+#define NET 261
+#define NETMASK 262
+#define PORT 263
+#define PORTRANGE 264
+#define LESS 265
+#define GREATER 266
+#define PROTO 267
+#define PROTOCHAIN 268
+#define CBYTE 269
+#define ARP 270
+#define RARP 271
+#define IP 272
+#define SCTP 273
+#define TCP 274
+#define UDP 275
+#define ICMP 276
+#define IGMP 277
+#define IGRP 278
+#define PIM 279
+#define VRRP 280
+#define CARP 281
+#define ATALK 282
+#define AARP 283
+#define DECNET 284
+#define LAT 285
+#define SCA 286
+#define MOPRC 287
+#define MOPDL 288
+#define TK_BROADCAST 289
+#define TK_MULTICAST 290
+#define NUM 291
+#define INBOUND 292
+#define OUTBOUND 293
+#define PF_IFNAME 294
+#define PF_RSET 295
+#define PF_RNR 296
+#define PF_SRNR 297
+#define PF_REASON 298
+#define PF_ACTION 299
+#define TYPE 300
+#define SUBTYPE 301
+#define DIR 302
+#define ADDR1 303
+#define ADDR2 304
+#define ADDR3 305
+#define ADDR4 306
+#define RA 307
+#define TA 308
+#define LINK 309
+#define GEQ 310
+#define LEQ 311
+#define NEQ 312
+#define ID 313
+#define EID 314
+#define HID 315
+#define HID6 316
+#define AID 317
+#define LSH 318
+#define RSH 319
+#define LEN 320
+#define IPV6 321
+#define ICMPV6 322
+#define AH 323
+#define ESP 324
+#define VLAN 325
+#define MPLS 326
+#define PPPOED 327
+#define PPPOES 328
+#define ISO 329
+#define ESIS 330
+#define CLNP 331
+#define ISIS 332
+#define L1 333
+#define L2 334
+#define IIH 335
+#define LSP 336
+#define SNP 337
+#define CSNP 338
+#define PSNP 339
+#define STP 340
+#define IPX 341
+#define NETBEUI 342
+#define LANE 343
+#define LLC 344
+#define METAC 345
+#define BCC 346
+#define SC 347
+#define ILMIC 348
+#define OAMF4EC 349
+#define OAMF4SC 350
+#define OAM 351
+#define OAMF4 352
+#define CONNECTMSG 353
+#define METACONNECT 354
+#define VPI 355
+#define VCI 356
+#define RADIO 357
+#define FISU 358
+#define LSSU 359
+#define MSU 360
+#define SIO 361
+#define OPC 362
+#define DPC 363
+#define SLS 364
+#define OR 365
+#define AND 366
+#define UMINUS 367
+#define YYERRCODE 256
+typedef short YYINT;
+static const YYINT pcaplhs[] = { -1,
+ 0, 0, 24, 1, 1, 1, 1, 1, 20, 21,
+ 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 23, 22, 4, 4, 4, 7, 7, 5,
+ 5, 8, 8, 8, 8, 8, 8, 6, 6, 6,
+ 6, 6, 6, 6, 6, 6, 6, 6, 9, 9,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 10, 10, 11, 11, 11, 11, 12, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 25, 25, 25, 25,
+ 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+ 25, 26, 26, 26, 26, 26, 26, 27, 27, 27,
+ 27, 41, 41, 42, 42, 43, 44, 44, 40, 40,
+ 39, 18, 18, 18, 19, 19, 19, 13, 13, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 15, 15, 15, 15, 15, 17, 17, 28,
+ 28, 28, 28, 28, 28, 28, 28, 29, 29, 29,
+ 29, 30, 30, 32, 32, 32, 32, 31, 33, 33,
+ 34, 34, 34, 35, 35, 35, 35, 37, 37, 37,
+ 37, 36, 38, 38,
+};
+static const YYINT pcaplen[] = { 2,
+ 2, 1, 0, 1, 3, 3, 3, 3, 1, 1,
+ 1, 1, 3, 1, 3, 3, 1, 3, 1, 1,
+ 1, 2, 1, 1, 1, 3, 3, 1, 1, 1,
+ 2, 3, 2, 2, 2, 2, 2, 2, 3, 1,
+ 3, 3, 1, 1, 1, 2, 1, 2, 1, 0,
+ 1, 1, 3, 3, 3, 3, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
+ 4, 1, 1, 2, 1, 2, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 4, 2, 2,
+ 2, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 4,
+ 6, 3, 3, 3, 3, 3, 3, 3, 3, 2,
+ 3, 1, 1, 1, 1, 1, 1, 1, 3, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 2, 2, 3, 1, 1, 3,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,
+ 3, 1, 1, 3,
+};
+static const YYINT pcapdefred[] = { 3,
+ 0, 0, 0, 0, 0, 70, 71, 69, 72, 73,
+ 74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
+ 84, 85, 87, 86, 168, 112, 113, 0, 0, 0,
+ 0, 0, 0, 68, 162, 88, 89, 90, 91, 0,
+ 0, 118, 119, 92, 93, 102, 94, 95, 96, 97,
+ 98, 99, 101, 100, 103, 104, 105, 170, 171, 172,
+ 173, 176, 177, 174, 175, 178, 179, 180, 181, 182,
+ 183, 106, 191, 192, 193, 194, 195, 196, 197, 23,
+ 0, 24, 0, 4, 30, 0, 0, 0, 149, 0,
+ 148, 0, 0, 43, 120, 44, 45, 0, 47, 0,
+ 109, 110, 0, 122, 123, 124, 125, 139, 140, 126,
+ 141, 127, 114, 0, 116, 160, 0, 0, 10, 9,
+ 0, 0, 14, 20, 0, 0, 21, 38, 11, 12,
+ 0, 0, 0, 0, 63, 67, 64, 65, 66, 35,
+ 36, 107, 108, 0, 0, 0, 57, 58, 59, 60,
+ 61, 62, 0, 34, 37, 121, 143, 145, 147, 0,
+ 0, 0, 0, 0, 0, 0, 0, 142, 144, 146,
+ 0, 0, 0, 0, 0, 0, 31, 188, 0, 0,
+ 0, 184, 46, 202, 0, 0, 0, 198, 48, 164,
+ 163, 166, 167, 165, 0, 0, 0, 6, 5, 0,
+ 0, 0, 8, 7, 0, 0, 0, 25, 0, 0,
+ 0, 22, 0, 0, 0, 0, 132, 133, 0, 136,
+ 130, 137, 138, 131, 32, 0, 0, 0, 0, 0,
+ 0, 154, 155, 0, 0, 0, 39, 161, 169, 185,
+ 186, 189, 0, 199, 200, 203, 0, 111, 0, 16,
+ 15, 18, 13, 0, 0, 54, 56, 53, 55, 0,
+ 150, 0, 187, 0, 201, 0, 26, 27, 134, 135,
+ 128, 0, 190, 204, 151,
+};
+static const YYINT pcapdgoto[] = { 1,
+ 174, 212, 129, 209, 84, 85, 210, 86, 87, 153,
+ 154, 155, 88, 89, 195, 117, 91, 171, 172, 121,
+ 122, 118, 132, 2, 94, 95, 156, 96, 97, 98,
+ 182, 183, 243, 99, 100, 188, 189, 247, 112, 110,
+ 219, 271, 221, 224,
+};
+static const YYINT pcapsindex[] = { 0,
+ 0, 296, -268, -231, -223, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, -216, -204, -174,
+ -169, -284, -193, 0, 0, 0, 0, 0, 0, -40,
+ -40, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 396, 0, -334, 0, 0, -19, 611, 647, 0, 34,
+ 0, 296, 296, 0, 0, 0, 0, 42, 0, 651,
+ 0, 0, 96, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, -40, 0, 0, 34, 396, 0, 0,
+ 185, 185, 0, 0, -38, 88, 0, 0, 0, 0,
+ -19, -19, -236, -233, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, -258, -172, -251, 0, 0, 0, 0,
+ 0, 0, -85, 0, 0, 0, 0, 0, 0, 396,
+ 396, 396, 396, 396, 396, 396, 396, 0, 0, 0,
+ 396, 396, 396, -39, 113, 126, 0, 0, -122, -121,
+ -118, 0, 0, 0, -99, -98, -91, 0, 0, 0,
+ 0, 0, 0, 0, -86, 126, 236, 0, 0, 0,
+ 185, 185, 0, 0, -140, -84, -81, 0, 165, -334,
+ 126, 0, -42, -36, -34, -31, 0, 0, -82, 0,
+ 0, 0, 0, 0, 0, 170, 170, -8, 108, -23,
+ -23, 0, 0, 236, 236, 156, 0, 0, 0, 0,
+ 0, 0, -37, 0, 0, 0, -35, 0, 126, 0,
+ 0, 0, 0, -19, -19, 0, 0, 0, 0, -221,
+ 0, -70, 0, -118, 0, -91, 0, 0, 0, 0,
+ 0, 134, 0, 0, 0,
+};
+static const YYINT pcaprindex[] = { 0,
+ 0, 488, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,
+ 11, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 228, 0, 0, 0, 0, 0, 0, 1,
+ 0, 686, 686, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 686, 686, 0, 0, 16, 18, 0, 0, 0, 0,
+ 0, 0, -28, 520, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 132, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 725, 759, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 3,
+ 686, 686, 0, 0, 0, 0, 0, 0, -222, 0,
+ -205, 0, 0, 0, 0, 0, 0, 0, 20, 0,
+ 0, 0, 0, 0, 0, 28, 53, 87, 78, 13,
+ 38, 0, 0, 26, 36, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 121, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0,
+};
+static const YYINT pcapgindex[] = { 0,
+ 227, -14, -116, 0, 2, 0, 0, 0, 0, 0,
+ 79, 0, 24, -75, 0, 116, 724, -73, 12, 29,
+ -163, 767, 722, 0, 0, 0, 0, 0, 0, 0,
+ -171, 0, 0, 0, 0, -165, 0, 0, 0, 0,
+ 0, 0, 0, 0,
+};
+#define YYTABLESIZE 1078
+static const YYINT pcaptable[] = { 82,
+ 40, 237, 12, 263, 52, 265, 108, 115, 206, 242,
+ 117, 52, 152, 80, 208, 17, 175, 19, 166, 129,
+ 82, 246, 101, 167, 179, 41, 185, 158, 109, 163,
+ 119, 120, 217, 166, 164, 42, 165, 153, 167, 222,
+ 148, 40, 175, 12, 148, 148, 255, 148, 115, 148,
+ 152, 117, 159, 152, 218, 152, 17, 152, 19, 102,
+ 129, 223, 148, 148, 148, 158, 41, 103, 158, 269,
+ 152, 128, 152, 152, 152, 153, 42, 156, 153, 264,
+ 153, 82, 153, 266, 208, 158, 157, 158, 158, 158,
+ 159, 270, 273, 159, 177, 153, 104, 153, 153, 153,
+ 274, 170, 169, 168, 116, 152, 198, 203, 105, 180,
+ 159, 186, 159, 159, 159, 156, 106, 90, 156, 111,
+ 158, 107, 199, 204, 173, 175, 148, 157, 213, 214,
+ 153, 215, 216, 191, 207, 156, 152, 156, 156, 156,
+ 220, 197, 29, 29, 157, 159, 157, 157, 157, 166,
+ 164, 158, 165, 238, 167, 194, 193, 192, 148, 28,
+ 28, 153, 148, 148, 33, 148, 239, 148, 240, 241,
+ 156, 33, 178, 135, 250, 137, 159, 138, 139, 157,
+ 148, 148, 148, 226, 227, 228, 229, 230, 231, 232,
+ 233, 244, 245, 163, 234, 235, 236, 166, 164, 184,
+ 165, 156, 167, 177, 248, 253, 251, 90, 90, 252,
+ 157, 166, 164, 262, 165, 256, 167, 80, 260, 190,
+ 272, 257, 258, 205, 82, 259, 275, 1, 83, 81,
+ 52, 225, 52, 0, 52, 52, 90, 90, 254, 267,
+ 268, 0, 0, 0, 148, 0, 0, 0, 261, 0,
+ 25, 0, 0, 0, 0, 0, 0, 49, 49, 49,
+ 49, 49, 52, 49, 49, 0, 0, 49, 49, 0,
+ 0, 25, 0, 163, 0, 0, 0, 166, 164, 162,
+ 165, 0, 167, 0, 52, 52, 52, 52, 52, 49,
+ 49, 0, 0, 123, 124, 125, 126, 127, 0, 0,
+ 49, 49, 49, 49, 49, 49, 49, 49, 49, 160,
+ 161, 0, 148, 148, 148, 0, 90, 90, 0, 0,
+ 148, 148, 152, 152, 152, 119, 120, 119, 80, 119,
+ 152, 152, 178, 0, 0, 82, 0, 158, 158, 158,
+ 81, 0, 0, 0, 0, 158, 158, 153, 153, 153,
+ 0, 157, 158, 159, 0, 153, 153, 0, 0, 162,
+ 0, 0, 159, 159, 159, 40, 40, 12, 12, 0,
+ 159, 159, 115, 115, 0, 117, 117, 152, 152, 0,
+ 17, 17, 19, 19, 129, 129, 0, 156, 156, 156,
+ 41, 41, 158, 158, 0, 0, 157, 157, 157, 0,
+ 42, 42, 153, 153, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 159, 159, 0,
+ 0, 0, 33, 0, 0, 160, 161, 0, 0, 0,
+ 148, 148, 148, 0, 0, 82, 0, 0, 148, 148,
+ 81, 0, 156, 156, 33, 33, 33, 33, 33, 3,
+ 4, 157, 157, 5, 6, 7, 8, 9, 10, 11,
+ 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 160, 161, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 0, 28, 28, 2, 0, 0,
+ 0, 0, 0, 34, 0, 0, 0, 123, 124, 125,
+ 126, 127, 0, 0, 35, 36, 37, 38, 39, 40,
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
+ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+ 61, 62, 63, 64, 65, 66, 67, 68, 69, 70,
+ 71, 72, 73, 74, 75, 76, 77, 78, 79, 0,
+ 0, 0, 51, 160, 161, 0, 0, 0, 0, 51,
+ 3, 4, 0, 0, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 0, 0, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 34, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
+ 60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
+ 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
+ 0, 0, 0, 0, 0, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 163, 0, 25, 0, 166, 164,
+ 82, 165, 0, 167, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 34, 0, 170, 169, 168, 0,
+ 170, 169, 168, 0, 0, 35, 36, 37, 38, 39,
+ 0, 0, 0, 93, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57, 0, 0,
+ 0, 0, 0, 0, 50, 50, 50, 50, 50, 0,
+ 50, 50, 72, 0, 50, 50, 0, 0, 0, 0,
+ 0, 0, 149, 113, 115, 0, 149, 149, 92, 149,
+ 162, 149, 0, 0, 0, 0, 50, 50, 51, 0,
+ 51, 0, 51, 51, 149, 149, 149, 50, 50, 50,
+ 50, 50, 50, 50, 50, 50, 148, 0, 0, 0,
+ 148, 148, 0, 148, 0, 148, 114, 114, 0, 130,
+ 51, 0, 0, 93, 93, 176, 0, 0, 148, 148,
+ 148, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 51, 51, 51, 51, 51, 196, 0, 0,
+ 0, 176, 202, 202, 200, 200, 0, 0, 149, 0,
+ 0, 0, 131, 0, 211, 130, 0, 0, 92, 92,
+ 0, 0, 0, 0, 181, 0, 187, 133, 134, 135,
+ 136, 137, 0, 138, 139, 0, 0, 140, 141, 0,
+ 114, 0, 148, 0, 0, 0, 0, 201, 201, 0,
+ 0, 0, 0, 0, 0, 0, 0, 114, 131, 142,
+ 143, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 144, 145, 146, 147, 148, 149, 150, 151, 152, 0,
+ 0, 0, 202, 202, 249, 200, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 184, 50, 50, 50, 50, 50, 0, 50, 50,
+ 0, 0, 50, 50, 0, 0, 157, 158, 159, 0,
+ 157, 158, 159, 0, 160, 161, 0, 92, 201, 0,
+ 0, 0, 0, 0, 50, 50, 0, 130, 130, 0,
+ 0, 0, 0, 0, 0, 50, 50, 50, 50, 50,
+ 50, 50, 50, 50, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 131, 131, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 149, 149, 149, 0, 0, 0,
+ 0, 0, 149, 149, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 148, 148,
+ 148, 0, 0, 0, 0, 0, 148, 148,
+};
+static const YYINT pcapcheck[] = { 40,
+ 0, 41, 0, 41, 33, 41, 291, 0, 47, 181,
+ 0, 40, 0, 33, 131, 0, 92, 0, 42, 0,
+ 40, 187, 291, 47, 98, 0, 100, 0, 313, 38,
+ 365, 366, 291, 42, 43, 0, 45, 0, 47, 291,
+ 38, 41, 118, 41, 42, 43, 210, 45, 41, 47,
+ 38, 41, 0, 41, 313, 43, 41, 45, 41, 291,
+ 41, 313, 60, 61, 62, 38, 41, 291, 41, 291,
+ 58, 86, 60, 61, 62, 38, 41, 0, 41, 243,
+ 43, 40, 45, 247, 201, 58, 0, 60, 61, 62,
+ 38, 313, 264, 41, 93, 58, 313, 60, 61, 62,
+ 266, 60, 61, 62, 81, 93, 121, 122, 313, 98,
+ 58, 100, 60, 61, 62, 38, 291, 2, 41, 313,
+ 93, 291, 121, 122, 91, 201, 124, 41, 365, 366,
+ 93, 365, 366, 38, 47, 58, 124, 60, 61, 62,
+ 313, 118, 365, 366, 58, 93, 60, 61, 62, 42,
+ 43, 124, 45, 41, 47, 60, 61, 62, 38, 365,
+ 366, 124, 42, 43, 33, 45, 41, 47, 291, 291,
+ 93, 40, 291, 259, 315, 261, 124, 263, 264, 93,
+ 60, 61, 62, 160, 161, 162, 163, 164, 165, 166,
+ 167, 291, 291, 38, 171, 172, 173, 42, 43, 291,
+ 45, 124, 47, 202, 291, 41, 291, 92, 93, 291,
+ 124, 42, 43, 58, 45, 258, 47, 33, 301, 124,
+ 291, 258, 257, 262, 40, 257, 93, 0, 2, 45,
+ 259, 153, 261, -1, 263, 264, 121, 122, 210, 254,
+ 255, -1, -1, -1, 124, -1, -1, -1, 93, -1,
+ 291, -1, -1, -1, -1, -1, -1, 257, 258, 259,
+ 260, 261, 291, 263, 264, -1, -1, 267, 268, -1,
+ -1, 291, -1, 38, -1, -1, -1, 42, 43, 124,
+ 45, -1, 47, -1, 313, 314, 315, 316, 317, 289,
+ 290, -1, -1, 313, 314, 315, 316, 317, -1, -1,
+ 300, 301, 302, 303, 304, 305, 306, 307, 308, 318,
+ 319, -1, 310, 311, 312, -1, 201, 202, -1, -1,
+ 318, 319, 310, 311, 312, 365, 366, 365, 33, 365,
+ 318, 319, 291, -1, -1, 40, -1, 310, 311, 312,
+ 45, -1, -1, -1, -1, 318, 319, 310, 311, 312,
+ -1, 310, 311, 312, -1, 318, 319, -1, -1, 124,
+ -1, -1, 310, 311, 312, 365, 366, 365, 366, -1,
+ 318, 319, 365, 366, -1, 365, 366, 365, 366, -1,
+ 365, 366, 365, 366, 365, 366, -1, 310, 311, 312,
+ 365, 366, 365, 366, -1, -1, 310, 311, 312, -1,
+ 365, 366, 365, 366, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 365, 366, -1,
+ -1, -1, 291, -1, -1, 318, 319, -1, -1, -1,
+ 310, 311, 312, -1, -1, 40, -1, -1, 318, 319,
+ 45, -1, 365, 366, 313, 314, 315, 316, 317, 265,
+ 266, 365, 366, 269, 270, 271, 272, 273, 274, 275,
+ 276, 277, 278, 279, 280, 281, 282, 283, 284, 285,
+ 286, 287, 288, 318, 319, 291, 292, 293, 294, 295,
+ 296, 297, 298, 299, -1, 365, 366, 0, -1, -1,
+ -1, -1, -1, 309, -1, -1, -1, 313, 314, 315,
+ 316, 317, -1, -1, 320, 321, 322, 323, 324, 325,
+ 326, 327, 328, 329, 330, 331, 332, 333, 334, 335,
+ 336, 337, 338, 339, 340, 341, 342, 343, 344, 345,
+ 346, 347, 348, 349, 350, 351, 352, 353, 354, 355,
+ 356, 357, 358, 359, 360, 361, 362, 363, 364, -1,
+ -1, -1, 33, 318, 319, -1, -1, -1, -1, 40,
+ 265, 266, -1, -1, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, -1, -1, 291, 292, 293, 294,
+ 295, 296, 297, 298, 299, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 309, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 320, 321, 322, 323, 324,
+ 325, 326, 327, 328, 329, 330, 331, 332, 333, 334,
+ 335, 336, 337, 338, 339, 340, 341, 342, 343, 344,
+ 345, 346, 347, 348, 349, 350, 351, 352, 353, 354,
+ 355, 356, 357, 358, 359, 360, 361, 362, 363, 364,
+ -1, -1, -1, -1, -1, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 38, -1, 291, -1, 42, 43,
+ 40, 45, -1, 47, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 309, -1, 60, 61, 62, -1,
+ 60, 61, 62, -1, -1, 320, 321, 322, 323, 324,
+ -1, -1, -1, 2, 329, 330, 331, 332, 333, 334,
+ 335, 336, 337, 338, 339, 340, 341, 342, -1, -1,
+ -1, -1, -1, -1, 257, 258, 259, 260, 261, -1,
+ 263, 264, 357, -1, 267, 268, -1, -1, -1, -1,
+ -1, -1, 38, 40, 41, -1, 42, 43, 2, 45,
+ 124, 47, -1, -1, -1, -1, 289, 290, 259, -1,
+ 261, -1, 263, 264, 60, 61, 62, 300, 301, 302,
+ 303, 304, 305, 306, 307, 308, 38, -1, -1, -1,
+ 42, 43, -1, 45, -1, 47, 40, 41, -1, 86,
+ 291, -1, -1, 92, 93, 92, -1, -1, 60, 61,
+ 62, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 313, 314, 315, 316, 317, 114, -1, -1,
+ -1, 118, 121, 122, 121, 122, -1, -1, 124, -1,
+ -1, -1, 86, -1, 131, 132, -1, -1, 92, 93,
+ -1, -1, -1, -1, 98, -1, 100, 257, 258, 259,
+ 260, 261, -1, 263, 264, -1, -1, 267, 268, -1,
+ 114, -1, 124, -1, -1, -1, -1, 121, 122, -1,
+ -1, -1, -1, -1, -1, -1, -1, 131, 132, 289,
+ 290, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 300, 301, 302, 303, 304, 305, 306, 307, 308, -1,
+ -1, -1, 201, 202, 201, 202, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 291, 257, 258, 259, 260, 261, -1, 263, 264,
+ -1, -1, 267, 268, -1, -1, 310, 311, 312, -1,
+ 310, 311, 312, -1, 318, 319, -1, 201, 202, -1,
+ -1, -1, -1, -1, 289, 290, -1, 254, 255, -1,
+ -1, -1, -1, -1, -1, 300, 301, 302, 303, 304,
+ 305, 306, 307, 308, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 254, 255, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 310, 311, 312, -1, -1, -1,
+ -1, -1, 318, 319, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 310, 311,
+ 312, -1, -1, -1, -1, -1, 318, 319,
+};
+#define YYFINAL 1
+#ifndef YYDEBUG
+#define YYDEBUG 0
+#endif
+#define YYMAXTOKEN 367
+#define YYUNDFTOKEN 414
+#define YYTRANSLATE(a) ((a) > YYMAXTOKEN ? YYUNDFTOKEN : (a))
+#if YYDEBUG
+static const char *const pcapname[] = {
+
+"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+"'!'",0,0,0,0,"'&'",0,"'('","')'","'*'","'+'",0,"'-'",0,"'/'",0,0,0,0,0,0,0,0,0,
+0,"':'",0,"'<'","'='","'>'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,"'['",0,"']'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+"'|'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"DST","SRC","HOST","GATEWAY","NET","NETMASK",
+"PORT","PORTRANGE","LESS","GREATER","PROTO","PROTOCHAIN","CBYTE","ARP","RARP",
+"IP","SCTP","TCP","UDP","ICMP","IGMP","IGRP","PIM","VRRP","CARP","ATALK","AARP",
+"DECNET","LAT","SCA","MOPRC","MOPDL","TK_BROADCAST","TK_MULTICAST","NUM",
+"INBOUND","OUTBOUND","PF_IFNAME","PF_RSET","PF_RNR","PF_SRNR","PF_REASON",
+"PF_ACTION","TYPE","SUBTYPE","DIR","ADDR1","ADDR2","ADDR3","ADDR4","RA","TA",
+"LINK","GEQ","LEQ","NEQ","ID","EID","HID","HID6","AID","LSH","RSH","LEN","IPV6",
+"ICMPV6","AH","ESP","VLAN","MPLS","PPPOED","PPPOES","ISO","ESIS","CLNP","ISIS",
+"L1","L2","IIH","LSP","SNP","CSNP","PSNP","STP","IPX","NETBEUI","LANE","LLC",
+"METAC","BCC","SC","ILMIC","OAMF4EC","OAMF4SC","OAM","OAMF4","CONNECTMSG",
+"METACONNECT","VPI","VCI","RADIO","FISU","LSSU","MSU","SIO","OPC","DPC","SLS",
+"OR","AND","UMINUS",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"illegal-symbol",
+};
+static const char *const pcaprule[] = {
+"$accept : prog",
+"prog : null expr",
+"prog : null",
+"null :",
+"expr : term",
+"expr : expr and term",
+"expr : expr and id",
+"expr : expr or term",
+"expr : expr or id",
+"and : AND",
+"or : OR",
+"id : nid",
+"id : pnum",
+"id : paren pid ')'",
+"nid : ID",
+"nid : HID '/' NUM",
+"nid : HID NETMASK HID",
+"nid : HID",
+"nid : HID6 '/' NUM",
+"nid : HID6",
+"nid : EID",
+"nid : AID",
+"nid : not id",
+"not : '!'",
+"paren : '('",
+"pid : nid",
+"pid : qid and id",
+"pid : qid or id",
+"qid : pnum",
+"qid : pid",
+"term : rterm",
+"term : not term",
+"head : pqual dqual aqual",
+"head : pqual dqual",
+"head : pqual aqual",
+"head : pqual PROTO",
+"head : pqual PROTOCHAIN",
+"head : pqual ndaqual",
+"rterm : head id",
+"rterm : paren expr ')'",
+"rterm : pname",
+"rterm : arth relop arth",
+"rterm : arth irelop arth",
+"rterm : other",
+"rterm : atmtype",
+"rterm : atmmultitype",
+"rterm : atmfield atmvalue",
+"rterm : mtp2type",
+"rterm : mtp3field mtp3value",
+"pqual : pname",
+"pqual :",
+"dqual : SRC",
+"dqual : DST",
+"dqual : SRC OR DST",
+"dqual : DST OR SRC",
+"dqual : SRC AND DST",
+"dqual : DST AND SRC",
+"dqual : ADDR1",
+"dqual : ADDR2",
+"dqual : ADDR3",
+"dqual : ADDR4",
+"dqual : RA",
+"dqual : TA",
+"aqual : HOST",
+"aqual : NET",
+"aqual : PORT",
+"aqual : PORTRANGE",
+"ndaqual : GATEWAY",
+"pname : LINK",
+"pname : IP",
+"pname : ARP",
+"pname : RARP",
+"pname : SCTP",
+"pname : TCP",
+"pname : UDP",
+"pname : ICMP",
+"pname : IGMP",
+"pname : IGRP",
+"pname : PIM",
+"pname : VRRP",
+"pname : CARP",
+"pname : ATALK",
+"pname : AARP",
+"pname : DECNET",
+"pname : LAT",
+"pname : SCA",
+"pname : MOPDL",
+"pname : MOPRC",
+"pname : IPV6",
+"pname : ICMPV6",
+"pname : AH",
+"pname : ESP",
+"pname : ISO",
+"pname : ESIS",
+"pname : ISIS",
+"pname : L1",
+"pname : L2",
+"pname : IIH",
+"pname : LSP",
+"pname : SNP",
+"pname : PSNP",
+"pname : CSNP",
+"pname : CLNP",
+"pname : STP",
+"pname : IPX",
+"pname : NETBEUI",
+"pname : RADIO",
+"other : pqual TK_BROADCAST",
+"other : pqual TK_MULTICAST",
+"other : LESS NUM",
+"other : GREATER NUM",
+"other : CBYTE NUM byteop NUM",
+"other : INBOUND",
+"other : OUTBOUND",
+"other : VLAN pnum",
+"other : VLAN",
+"other : MPLS pnum",
+"other : MPLS",
+"other : PPPOED",
+"other : PPPOES",
+"other : pfvar",
+"other : pqual p80211",
+"pfvar : PF_IFNAME ID",
+"pfvar : PF_RSET ID",
+"pfvar : PF_RNR NUM",
+"pfvar : PF_SRNR NUM",
+"pfvar : PF_REASON reason",
+"pfvar : PF_ACTION action",
+"p80211 : TYPE type SUBTYPE subtype",
+"p80211 : TYPE type",
+"p80211 : SUBTYPE type_subtype",
+"p80211 : DIR dir",
+"type : NUM",
+"type : ID",
+"subtype : NUM",
+"subtype : ID",
+"type_subtype : ID",
+"dir : NUM",
+"dir : ID",
+"reason : NUM",
+"reason : ID",
+"action : ID",
+"relop : '>'",
+"relop : GEQ",
+"relop : '='",
+"irelop : LEQ",
+"irelop : '<'",
+"irelop : NEQ",
+"arth : pnum",
+"arth : narth",
+"narth : pname '[' arth ']'",
+"narth : pname '[' arth ':' NUM ']'",
+"narth : arth '+' arth",
+"narth : arth '-' arth",
+"narth : arth '*' arth",
+"narth : arth '/' arth",
+"narth : arth '&' arth",
+"narth : arth '|' arth",
+"narth : arth LSH arth",
+"narth : arth RSH arth",
+"narth : '-' arth",
+"narth : paren narth ')'",
+"narth : LEN",
+"byteop : '&'",
+"byteop : '|'",
+"byteop : '<'",
+"byteop : '>'",
+"byteop : '='",
+"pnum : NUM",
+"pnum : paren pnum ')'",
+"atmtype : LANE",
+"atmtype : LLC",
+"atmtype : METAC",
+"atmtype : BCC",
+"atmtype : OAMF4EC",
+"atmtype : OAMF4SC",
+"atmtype : SC",
+"atmtype : ILMIC",
+"atmmultitype : OAM",
+"atmmultitype : OAMF4",
+"atmmultitype : CONNECTMSG",
+"atmmultitype : METACONNECT",
+"atmfield : VPI",
+"atmfield : VCI",
+"atmvalue : atmfieldvalue",
+"atmvalue : relop NUM",
+"atmvalue : irelop NUM",
+"atmvalue : paren atmlistvalue ')'",
+"atmfieldvalue : NUM",
+"atmlistvalue : atmfieldvalue",
+"atmlistvalue : atmlistvalue or atmfieldvalue",
+"mtp2type : FISU",
+"mtp2type : LSSU",
+"mtp2type : MSU",
+"mtp3field : SIO",
+"mtp3field : OPC",
+"mtp3field : DPC",
+"mtp3field : SLS",
+"mtp3value : mtp3fieldvalue",
+"mtp3value : relop NUM",
+"mtp3value : irelop NUM",
+"mtp3value : paren mtp3listvalue ')'",
+"mtp3fieldvalue : NUM",
+"mtp3listvalue : mtp3fieldvalue",
+"mtp3listvalue : mtp3listvalue or mtp3fieldvalue",
+
+};
+#endif
+
+int yydebug;
+int yynerrs;
+
+int yyerrflag;
+int yychar;
+YYSTYPE yyval;
+YYSTYPE yylval;
+
+/* define the initial stack-sizes */
+#ifdef YYSTACKSIZE
+#undef YYMAXDEPTH
+#define YYMAXDEPTH YYSTACKSIZE
+#else
+#ifdef YYMAXDEPTH
+#define YYSTACKSIZE YYMAXDEPTH
+#else
+#define YYSTACKSIZE 10000
+#define YYMAXDEPTH 10000
+#endif
+#endif
+
+#define YYINITSTACKSIZE 200
+
+typedef struct {
+ unsigned stacksize;
+ YYINT *s_base;
+ YYINT *s_mark;
+ YYINT *s_last;
+ YYSTYPE *l_base;
+ YYSTYPE *l_mark;
+} YYSTACKDATA;
+/* variables for the parser stack */
+static YYSTACKDATA yystack;
+
+#if YYDEBUG
+#include <stdio.h> /* needed for printf */
+#endif
+
+#include <stdlib.h> /* needed for malloc, etc */
+#include <string.h> /* needed for memset */
+
+/* allocate initial stack or double stack size, up to YYMAXDEPTH */
+static int yygrowstack(YYSTACKDATA *data)
+{
+ int i;
+ unsigned newsize;
+ YYINT *newss;
+ YYSTYPE *newvs;
+
+ if ((newsize = data->stacksize) == 0)
+ newsize = YYINITSTACKSIZE;
+ else if (newsize >= YYMAXDEPTH)
+ return YYENOMEM;
+ else if ((newsize *= 2) > YYMAXDEPTH)
+ newsize = YYMAXDEPTH;
+
+ i = (int) (data->s_mark - data->s_base);
+ newss = (YYINT *)realloc(data->s_base, newsize * sizeof(*newss));
+ if (newss == 0)
+ return YYENOMEM;
+
+ data->s_base = newss;
+ data->s_mark = newss + i;
+
+ newvs = (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs));
+ if (newvs == 0)
+ return YYENOMEM;
+
+ data->l_base = newvs;
+ data->l_mark = newvs + i;
+
+ data->stacksize = newsize;
+ data->s_last = data->s_base + newsize - 1;
+ return 0;
+}
+
+#if YYPURE || defined(YY_NO_LEAKS)
+static void yyfreestack(YYSTACKDATA *data)
+{
+ free(data->s_base);
+ free(data->l_base);
+ memset(data, 0, sizeof(*data));
+}
+#else
+#define yyfreestack(data) /* nothing */
+#endif
+
+#define YYABORT goto yyabort
+#define YYREJECT goto yyabort
+#define YYACCEPT goto yyaccept
+#define YYERROR goto yyerrlab
+
+int
+YYPARSE_DECL()
+{
+ int yym, yyn, yystate;
+#if YYDEBUG
+ const char *yys;
+
+ if ((yys = getenv("YYDEBUG")) != 0)
+ {
+ yyn = *yys;
+ if (yyn >= '0' && yyn <= '9')
+ yydebug = yyn - '0';
+ }
+#endif
+
+ yynerrs = 0;
+ yyerrflag = 0;
+ yychar = YYEMPTY;
+ yystate = 0;
+
+#if YYPURE
+ memset(&yystack, 0, sizeof(yystack));
+#endif
+
+ if (yystack.s_base == NULL && yygrowstack(&yystack) == YYENOMEM) goto yyoverflow;
+ yystack.s_mark = yystack.s_base;
+ yystack.l_mark = yystack.l_base;
+ yystate = 0;
+ *yystack.s_mark = 0;
+
+yyloop:
+ if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
+ if (yychar < 0)
+ {
+ if ((yychar = YYLEX) < 0) yychar = YYEOF;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = yyname[YYTRANSLATE(yychar)];
+ printf("%sdebug: state %d, reading %d (%s)\n",
+ YYPREFIX, yystate, yychar, yys);
+ }
+#endif
+ }
+ if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, shifting to state %d\n",
+ YYPREFIX, yystate, yytable[yyn]);
+#endif
+ if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM)
+ {
+ goto yyoverflow;
+ }
+ yystate = yytable[yyn];
+ *++yystack.s_mark = yytable[yyn];
+ *++yystack.l_mark = yylval;
+ yychar = YYEMPTY;
+ if (yyerrflag > 0) --yyerrflag;
+ goto yyloop;
+ }
+ if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
+ {
+ yyn = yytable[yyn];
+ goto yyreduce;
+ }
+ if (yyerrflag) goto yyinrecovery;
+
+ YYERROR_CALL("syntax error");
+
+ goto yyerrlab;
+
+yyerrlab:
+ ++yynerrs;
+
+yyinrecovery:
+ if (yyerrflag < 3)
+ {
+ yyerrflag = 3;
+ for (;;)
+ {
+ if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, error recovery shifting\
+ to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]);
+#endif
+ if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM)
+ {
+ goto yyoverflow;
+ }
+ yystate = yytable[yyn];
+ *++yystack.s_mark = yytable[yyn];
+ *++yystack.l_mark = yylval;
+ goto yyloop;
+ }
+ else
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: error recovery discarding state %d\n",
+ YYPREFIX, *yystack.s_mark);
+#endif
+ if (yystack.s_mark <= yystack.s_base) goto yyabort;
+ --yystack.s_mark;
+ --yystack.l_mark;
+ }
+ }
+ }
+ else
+ {
+ if (yychar == YYEOF) goto yyabort;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = yyname[YYTRANSLATE(yychar)];
+ printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
+ YYPREFIX, yystate, yychar, yys);
+ }
+#endif
+ yychar = YYEMPTY;
+ goto yyloop;
+ }
+
+yyreduce:
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: state %d, reducing by rule %d (%s)\n",
+ YYPREFIX, yystate, yyn, yyrule[yyn]);
+#endif
+ yym = yylen[yyn];
+ if (yym)
+ yyval = yystack.l_mark[1-yym];
+ else
+ memset(&yyval, 0, sizeof yyval);
+ switch (yyn)
+ {
+case 1:
+#line 317 "../../freebsd/contrib/libpcap/grammar.y"
+ {
+ finish_parse(yystack.l_mark[0].blk.b);
+}
+break;
+case 3:
+#line 322 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.q = qerr; }
+break;
+case 5:
+#line 325 "../../freebsd/contrib/libpcap/grammar.y"
+ { gen_and(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+break;
+case 6:
+#line 326 "../../freebsd/contrib/libpcap/grammar.y"
+ { gen_and(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+break;
+case 7:
+#line 327 "../../freebsd/contrib/libpcap/grammar.y"
+ { gen_or(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+break;
+case 8:
+#line 328 "../../freebsd/contrib/libpcap/grammar.y"
+ { gen_or(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+break;
+case 9:
+#line 330 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk = yystack.l_mark[-1].blk; }
+break;
+case 10:
+#line 332 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk = yystack.l_mark[-1].blk; }
+break;
+case 12:
+#line 335 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_ncode(NULL, (bpf_u_int32)yystack.l_mark[0].i,
+ yyval.blk.q = yystack.l_mark[-1].blk.q); }
+break;
+case 13:
+#line 337 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk = yystack.l_mark[-1].blk; }
+break;
+case 14:
+#line 339 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_scode(yystack.l_mark[0].s, yyval.blk.q = yystack.l_mark[-1].blk.q); }
+break;
+case 15:
+#line 340 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_mcode(yystack.l_mark[-2].s, NULL, yystack.l_mark[0].i,
+ yyval.blk.q = yystack.l_mark[-3].blk.q); }
+break;
+case 16:
+#line 342 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_mcode(yystack.l_mark[-2].s, yystack.l_mark[0].s, 0,
+ yyval.blk.q = yystack.l_mark[-3].blk.q); }
+break;
+case 17:
+#line 344 "../../freebsd/contrib/libpcap/grammar.y"
+ {
+ /* Decide how to parse HID based on proto */
+ yyval.blk.q = yystack.l_mark[-1].blk.q;
+ if (yyval.blk.q.addr == Q_PORT)
+ bpf_error("'port' modifier applied to ip host");
+ else if (yyval.blk.q.addr == Q_PORTRANGE)
+ bpf_error("'portrange' modifier applied to ip host");
+ else if (yyval.blk.q.addr == Q_PROTO)
+ bpf_error("'proto' modifier applied to ip host");
+ else if (yyval.blk.q.addr == Q_PROTOCHAIN)
+ bpf_error("'protochain' modifier applied to ip host");
+ yyval.blk.b = gen_ncode(yystack.l_mark[0].s, 0, yyval.blk.q);
+ }
+break;
+case 18:
+#line 357 "../../freebsd/contrib/libpcap/grammar.y"
+ {
+#ifdef INET6
+ yyval.blk.b = gen_mcode6(yystack.l_mark[-2].s, NULL, yystack.l_mark[0].i,
+ yyval.blk.q = yystack.l_mark[-3].blk.q);
+#else
+ bpf_error("'ip6addr/prefixlen' not supported "
+ "in this configuration");
+#endif /*INET6*/
+ }
+break;
+case 19:
+#line 366 "../../freebsd/contrib/libpcap/grammar.y"
+ {
+#ifdef INET6
+ yyval.blk.b = gen_mcode6(yystack.l_mark[0].s, 0, 128,
+ yyval.blk.q = yystack.l_mark[-1].blk.q);
+#else
+ bpf_error("'ip6addr' not supported "
+ "in this configuration");
+#endif /*INET6*/
+ }
+break;
+case 20:
+#line 375 "../../freebsd/contrib/libpcap/grammar.y"
+ {
+ yyval.blk.b = gen_ecode(yystack.l_mark[0].e, yyval.blk.q = yystack.l_mark[-1].blk.q);
+ /*
+ * $1 was allocated by "pcap_ether_aton()",
+ * so we must free it now that we're done
+ * with it.
+ */
+ free(yystack.l_mark[0].e);
+ }
+break;
+case 21:
+#line 384 "../../freebsd/contrib/libpcap/grammar.y"
+ {
+ yyval.blk.b = gen_acode(yystack.l_mark[0].e, yyval.blk.q = yystack.l_mark[-1].blk.q);
+ /*
+ * $1 was allocated by "pcap_ether_aton()",
+ * so we must free it now that we're done
+ * with it.
+ */
+ free(yystack.l_mark[0].e);
+ }
+break;
+case 22:
+#line 393 "../../freebsd/contrib/libpcap/grammar.y"
+ { gen_not(yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+break;
+case 23:
+#line 395 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk = yystack.l_mark[-1].blk; }
+break;
+case 24:
+#line 397 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk = yystack.l_mark[-1].blk; }
+break;
+case 26:
+#line 400 "../../freebsd/contrib/libpcap/grammar.y"
+ { gen_and(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+break;
+case 27:
+#line 401 "../../freebsd/contrib/libpcap/grammar.y"
+ { gen_or(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+break;
+case 28:
+#line 403 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_ncode(NULL, (bpf_u_int32)yystack.l_mark[0].i,
+ yyval.blk.q = yystack.l_mark[-1].blk.q); }
+break;
+case 31:
+#line 408 "../../freebsd/contrib/libpcap/grammar.y"
+ { gen_not(yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+break;
+case 32:
+#line 410 "../../freebsd/contrib/libpcap/grammar.y"
+ { QSET(yyval.blk.q, yystack.l_mark[-2].i, yystack.l_mark[-1].i, yystack.l_mark[0].i); }
+break;
+case 33:
+#line 411 "../../freebsd/contrib/libpcap/grammar.y"
+ { QSET(yyval.blk.q, yystack.l_mark[-1].i, yystack.l_mark[0].i, Q_DEFAULT); }
+break;
+case 34:
+#line 412 "../../freebsd/contrib/libpcap/grammar.y"
+ { QSET(yyval.blk.q, yystack.l_mark[-1].i, Q_DEFAULT, yystack.l_mark[0].i); }
+break;
+case 35:
+#line 413 "../../freebsd/contrib/libpcap/grammar.y"
+ { QSET(yyval.blk.q, yystack.l_mark[-1].i, Q_DEFAULT, Q_PROTO); }
+break;
+case 36:
+#line 414 "../../freebsd/contrib/libpcap/grammar.y"
+ { QSET(yyval.blk.q, yystack.l_mark[-1].i, Q_DEFAULT, Q_PROTOCHAIN); }
+break;
+case 37:
+#line 415 "../../freebsd/contrib/libpcap/grammar.y"
+ { QSET(yyval.blk.q, yystack.l_mark[-1].i, Q_DEFAULT, yystack.l_mark[0].i); }
+break;
+case 38:
+#line 417 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk = yystack.l_mark[0].blk; }
+break;
+case 39:
+#line 418 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = yystack.l_mark[-1].blk.b; yyval.blk.q = yystack.l_mark[-2].blk.q; }
+break;
+case 40:
+#line 419 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_proto_abbrev(yystack.l_mark[0].i); yyval.blk.q = qerr; }
+break;
+case 41:
+#line 420 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_relation(yystack.l_mark[-1].i, yystack.l_mark[-2].a, yystack.l_mark[0].a, 0);
+ yyval.blk.q = qerr; }
+break;
+case 42:
+#line 422 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_relation(yystack.l_mark[-1].i, yystack.l_mark[-2].a, yystack.l_mark[0].a, 1);
+ yyval.blk.q = qerr; }
+break;
+case 43:
+#line 424 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = yystack.l_mark[0].rblk; yyval.blk.q = qerr; }
+break;
+case 44:
+#line 425 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_atmtype_abbrev(yystack.l_mark[0].i); yyval.blk.q = qerr; }
+break;
+case 45:
+#line 426 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_atmmulti_abbrev(yystack.l_mark[0].i); yyval.blk.q = qerr; }
+break;
+case 46:
+#line 427 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = yystack.l_mark[0].blk.b; yyval.blk.q = qerr; }
+break;
+case 47:
+#line 428 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_mtp2type_abbrev(yystack.l_mark[0].i); yyval.blk.q = qerr; }
+break;
+case 48:
+#line 429 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = yystack.l_mark[0].blk.b; yyval.blk.q = qerr; }
+break;
+case 50:
+#line 433 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_DEFAULT; }
+break;
+case 51:
+#line 436 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_SRC; }
+break;
+case 52:
+#line 437 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_DST; }
+break;
+case 53:
+#line 438 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_OR; }
+break;
+case 54:
+#line 439 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_OR; }
+break;
+case 55:
+#line 440 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_AND; }
+break;
+case 56:
+#line 441 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_AND; }
+break;
+case 57:
+#line 442 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ADDR1; }
+break;
+case 58:
+#line 443 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ADDR2; }
+break;
+case 59:
+#line 444 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ADDR3; }
+break;
+case 60:
+#line 445 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ADDR4; }
+break;
+case 61:
+#line 446 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_RA; }
+break;
+case 62:
+#line 447 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_TA; }
+break;
+case 63:
+#line 450 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_HOST; }
+break;
+case 64:
+#line 451 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_NET; }
+break;
+case 65:
+#line 452 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_PORT; }
+break;
+case 66:
+#line 453 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_PORTRANGE; }
+break;
+case 67:
+#line 456 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_GATEWAY; }
+break;
+case 68:
+#line 458 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_LINK; }
+break;
+case 69:
+#line 459 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_IP; }
+break;
+case 70:
+#line 460 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ARP; }
+break;
+case 71:
+#line 461 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_RARP; }
+break;
+case 72:
+#line 462 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_SCTP; }
+break;
+case 73:
+#line 463 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_TCP; }
+break;
+case 74:
+#line 464 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_UDP; }
+break;
+case 75:
+#line 465 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ICMP; }
+break;
+case 76:
+#line 466 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_IGMP; }
+break;
+case 77:
+#line 467 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_IGRP; }
+break;
+case 78:
+#line 468 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_PIM; }
+break;
+case 79:
+#line 469 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_VRRP; }
+break;
+case 80:
+#line 470 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_CARP; }
+break;
+case 81:
+#line 471 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ATALK; }
+break;
+case 82:
+#line 472 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_AARP; }
+break;
+case 83:
+#line 473 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_DECNET; }
+break;
+case 84:
+#line 474 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_LAT; }
+break;
+case 85:
+#line 475 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_SCA; }
+break;
+case 86:
+#line 476 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_MOPDL; }
+break;
+case 87:
+#line 477 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_MOPRC; }
+break;
+case 88:
+#line 478 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_IPV6; }
+break;
+case 89:
+#line 479 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ICMPV6; }
+break;
+case 90:
+#line 480 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_AH; }
+break;
+case 91:
+#line 481 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ESP; }
+break;
+case 92:
+#line 482 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ISO; }
+break;
+case 93:
+#line 483 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ESIS; }
+break;
+case 94:
+#line 484 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ISIS; }
+break;
+case 95:
+#line 485 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ISIS_L1; }
+break;
+case 96:
+#line 486 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ISIS_L2; }
+break;
+case 97:
+#line 487 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ISIS_IIH; }
+break;
+case 98:
+#line 488 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ISIS_LSP; }
+break;
+case 99:
+#line 489 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ISIS_SNP; }
+break;
+case 100:
+#line 490 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ISIS_PSNP; }
+break;
+case 101:
+#line 491 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_ISIS_CSNP; }
+break;
+case 102:
+#line 492 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_CLNP; }
+break;
+case 103:
+#line 493 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_STP; }
+break;
+case 104:
+#line 494 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_IPX; }
+break;
+case 105:
+#line 495 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_NETBEUI; }
+break;
+case 106:
+#line 496 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = Q_RADIO; }
+break;
+case 107:
+#line 498 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_broadcast(yystack.l_mark[-1].i); }
+break;
+case 108:
+#line 499 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_multicast(yystack.l_mark[-1].i); }
+break;
+case 109:
+#line 500 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_less(yystack.l_mark[0].i); }
+break;
+case 110:
+#line 501 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_greater(yystack.l_mark[0].i); }
+break;
+case 111:
+#line 502 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_byteop(yystack.l_mark[-1].i, yystack.l_mark[-2].i, yystack.l_mark[0].i); }
+break;
+case 112:
+#line 503 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_inbound(0); }
+break;
+case 113:
+#line 504 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_inbound(1); }
+break;
+case 114:
+#line 505 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_vlan(yystack.l_mark[0].i); }
+break;
+case 115:
+#line 506 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_vlan(-1); }
+break;
+case 116:
+#line 507 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_mpls(yystack.l_mark[0].i); }
+break;
+case 117:
+#line 508 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_mpls(-1); }
+break;
+case 118:
+#line 509 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_pppoed(); }
+break;
+case 119:
+#line 510 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_pppoes(); }
+break;
+case 120:
+#line 511 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = yystack.l_mark[0].rblk; }
+break;
+case 121:
+#line 512 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = yystack.l_mark[0].rblk; }
+break;
+case 122:
+#line 515 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_pf_ifname(yystack.l_mark[0].s); }
+break;
+case 123:
+#line 516 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_pf_ruleset(yystack.l_mark[0].s); }
+break;
+case 124:
+#line 517 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_pf_rnr(yystack.l_mark[0].i); }
+break;
+case 125:
+#line 518 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_pf_srnr(yystack.l_mark[0].i); }
+break;
+case 126:
+#line 519 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_pf_reason(yystack.l_mark[0].i); }
+break;
+case 127:
+#line 520 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_pf_action(yystack.l_mark[0].i); }
+break;
+case 128:
+#line 524 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_p80211_type(yystack.l_mark[-2].i | yystack.l_mark[0].i,
+ IEEE80211_FC0_TYPE_MASK |
+ IEEE80211_FC0_SUBTYPE_MASK);
+ }
+break;
+case 129:
+#line 528 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_p80211_type(yystack.l_mark[0].i,
+ IEEE80211_FC0_TYPE_MASK);
+ }
+break;
+case 130:
+#line 531 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_p80211_type(yystack.l_mark[0].i,
+ IEEE80211_FC0_TYPE_MASK |
+ IEEE80211_FC0_SUBTYPE_MASK);
+ }
+break;
+case 131:
+#line 535 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.rblk = gen_p80211_fcdir(yystack.l_mark[0].i); }
+break;
+case 133:
+#line 539 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = str2tok(yystack.l_mark[0].s, ieee80211_types);
+ if (yyval.i == -1)
+ bpf_error("unknown 802.11 type name");
+ }
+break;
+case 135:
+#line 546 "../../freebsd/contrib/libpcap/grammar.y"
+ { const struct tok *types = NULL;
+ int i;
+ for (i = 0;; i++) {
+ if (ieee80211_type_subtypes[i].tok == NULL) {
+ /* Ran out of types */
+ bpf_error("unknown 802.11 type");
+ break;
+ }
+ if (yystack.l_mark[-2].i == ieee80211_type_subtypes[i].type) {
+ types = ieee80211_type_subtypes[i].tok;
+ break;
+ }
+ }
+
+ yyval.i = str2tok(yystack.l_mark[0].s, types);
+ if (yyval.i == -1)
+ bpf_error("unknown 802.11 subtype name");
+ }
+break;
+case 136:
+#line 566 "../../freebsd/contrib/libpcap/grammar.y"
+ { int i;
+ for (i = 0;; i++) {
+ if (ieee80211_type_subtypes[i].tok == NULL) {
+ /* Ran out of types */
+ bpf_error("unknown 802.11 type name");
+ break;
+ }
+ yyval.i = str2tok(yystack.l_mark[0].s, ieee80211_type_subtypes[i].tok);
+ if (yyval.i != -1) {
+ yyval.i |= ieee80211_type_subtypes[i].type;
+ break;
+ }
+ }
+ }
+break;
+case 138:
+#line 583 "../../freebsd/contrib/libpcap/grammar.y"
+ { if (pcap_strcasecmp(yystack.l_mark[0].s, "nods") == 0)
+ yyval.i = IEEE80211_FC1_DIR_NODS;
+ else if (pcap_strcasecmp(yystack.l_mark[0].s, "tods") == 0)
+ yyval.i = IEEE80211_FC1_DIR_TODS;
+ else if (pcap_strcasecmp(yystack.l_mark[0].s, "fromds") == 0)
+ yyval.i = IEEE80211_FC1_DIR_FROMDS;
+ else if (pcap_strcasecmp(yystack.l_mark[0].s, "dstods") == 0)
+ yyval.i = IEEE80211_FC1_DIR_DSTODS;
+ else
+ bpf_error("unknown 802.11 direction");
+ }
+break;
+case 139:
+#line 596 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = yystack.l_mark[0].i; }
+break;
+case 140:
+#line 597 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = pfreason_to_num(yystack.l_mark[0].s); }
+break;
+case 141:
+#line 600 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = pfaction_to_num(yystack.l_mark[0].s); }
+break;
+case 142:
+#line 603 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = BPF_JGT; }
+break;
+case 143:
+#line 604 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = BPF_JGE; }
+break;
+case 144:
+#line 605 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = BPF_JEQ; }
+break;
+case 145:
+#line 607 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = BPF_JGT; }
+break;
+case 146:
+#line 608 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = BPF_JGE; }
+break;
+case 147:
+#line 609 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = BPF_JEQ; }
+break;
+case 148:
+#line 611 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_loadi(yystack.l_mark[0].i); }
+break;
+case 150:
+#line 614 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_load(yystack.l_mark[-3].i, yystack.l_mark[-1].a, 1); }
+break;
+case 151:
+#line 615 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_load(yystack.l_mark[-5].i, yystack.l_mark[-3].a, yystack.l_mark[-1].i); }
+break;
+case 152:
+#line 616 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_arth(BPF_ADD, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+break;
+case 153:
+#line 617 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_arth(BPF_SUB, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+break;
+case 154:
+#line 618 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_arth(BPF_MUL, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+break;
+case 155:
+#line 619 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_arth(BPF_DIV, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+break;
+case 156:
+#line 620 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_arth(BPF_AND, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+break;
+case 157:
+#line 621 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_arth(BPF_OR, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+break;
+case 158:
+#line 622 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_arth(BPF_LSH, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+break;
+case 159:
+#line 623 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_arth(BPF_RSH, yystack.l_mark[-2].a, yystack.l_mark[0].a); }
+break;
+case 160:
+#line 624 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_neg(yystack.l_mark[0].a); }
+break;
+case 161:
+#line 625 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = yystack.l_mark[-1].a; }
+break;
+case 162:
+#line 626 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.a = gen_loadlen(); }
+break;
+case 163:
+#line 628 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = '&'; }
+break;
+case 164:
+#line 629 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = '|'; }
+break;
+case 165:
+#line 630 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = '<'; }
+break;
+case 166:
+#line 631 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = '>'; }
+break;
+case 167:
+#line 632 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = '='; }
+break;
+case 169:
+#line 635 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = yystack.l_mark[-1].i; }
+break;
+case 170:
+#line 637 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_LANE; }
+break;
+case 171:
+#line 638 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_LLC; }
+break;
+case 172:
+#line 639 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_METAC; }
+break;
+case 173:
+#line 640 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_BCC; }
+break;
+case 174:
+#line 641 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_OAMF4EC; }
+break;
+case 175:
+#line 642 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_OAMF4SC; }
+break;
+case 176:
+#line 643 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_SC; }
+break;
+case 177:
+#line 644 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_ILMIC; }
+break;
+case 178:
+#line 646 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_OAM; }
+break;
+case 179:
+#line 647 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_OAMF4; }
+break;
+case 180:
+#line 648 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_CONNECTMSG; }
+break;
+case 181:
+#line 649 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = A_METACONNECT; }
+break;
+case 182:
+#line 652 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.atmfieldtype = A_VPI; }
+break;
+case 183:
+#line 653 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.atmfieldtype = A_VCI; }
+break;
+case 185:
+#line 656 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_atmfield_code(yystack.l_mark[-2].blk.atmfieldtype, (bpf_int32)yystack.l_mark[0].i, (bpf_u_int32)yystack.l_mark[-1].i, 0); }
+break;
+case 186:
+#line 657 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_atmfield_code(yystack.l_mark[-2].blk.atmfieldtype, (bpf_int32)yystack.l_mark[0].i, (bpf_u_int32)yystack.l_mark[-1].i, 1); }
+break;
+case 187:
+#line 658 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = yystack.l_mark[-1].blk.b; yyval.blk.q = qerr; }
+break;
+case 188:
+#line 660 "../../freebsd/contrib/libpcap/grammar.y"
+ {
+ yyval.blk.atmfieldtype = yystack.l_mark[-1].blk.atmfieldtype;
+ if (yyval.blk.atmfieldtype == A_VPI ||
+ yyval.blk.atmfieldtype == A_VCI)
+ yyval.blk.b = gen_atmfield_code(yyval.blk.atmfieldtype, (bpf_int32) yystack.l_mark[0].i, BPF_JEQ, 0);
+ }
+break;
+case 190:
+#line 668 "../../freebsd/contrib/libpcap/grammar.y"
+ { gen_or(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+break;
+case 191:
+#line 671 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = M_FISU; }
+break;
+case 192:
+#line 672 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = M_LSSU; }
+break;
+case 193:
+#line 673 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.i = M_MSU; }
+break;
+case 194:
+#line 676 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.mtp3fieldtype = M_SIO; }
+break;
+case 195:
+#line 677 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.mtp3fieldtype = M_OPC; }
+break;
+case 196:
+#line 678 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.mtp3fieldtype = M_DPC; }
+break;
+case 197:
+#line 679 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.mtp3fieldtype = M_SLS; }
+break;
+case 199:
+#line 682 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_mtp3field_code(yystack.l_mark[-2].blk.mtp3fieldtype, (u_int)yystack.l_mark[0].i, (u_int)yystack.l_mark[-1].i, 0); }
+break;
+case 200:
+#line 683 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = gen_mtp3field_code(yystack.l_mark[-2].blk.mtp3fieldtype, (u_int)yystack.l_mark[0].i, (u_int)yystack.l_mark[-1].i, 1); }
+break;
+case 201:
+#line 684 "../../freebsd/contrib/libpcap/grammar.y"
+ { yyval.blk.b = yystack.l_mark[-1].blk.b; yyval.blk.q = qerr; }
+break;
+case 202:
+#line 686 "../../freebsd/contrib/libpcap/grammar.y"
+ {
+ yyval.blk.mtp3fieldtype = yystack.l_mark[-1].blk.mtp3fieldtype;
+ if (yyval.blk.mtp3fieldtype == M_SIO ||
+ yyval.blk.mtp3fieldtype == M_OPC ||
+ yyval.blk.mtp3fieldtype == M_DPC ||
+ yyval.blk.mtp3fieldtype == M_SLS )
+ yyval.blk.b = gen_mtp3field_code(yyval.blk.mtp3fieldtype, (u_int) yystack.l_mark[0].i, BPF_JEQ, 0);
+ }
+break;
+case 204:
+#line 696 "../../freebsd/contrib/libpcap/grammar.y"
+ { gen_or(yystack.l_mark[-2].blk.b, yystack.l_mark[0].blk.b); yyval.blk = yystack.l_mark[0].blk; }
+break;
+#line 2222 "pcap.tab.c"
+ }
+ yystack.s_mark -= yym;
+ yystate = *yystack.s_mark;
+ yystack.l_mark -= yym;
+ yym = yylhs[yyn];
+ if (yystate == 0 && yym == 0)
+ {
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: after reduction, shifting from state 0 to\
+ state %d\n", YYPREFIX, YYFINAL);
+#endif
+ yystate = YYFINAL;
+ *++yystack.s_mark = YYFINAL;
+ *++yystack.l_mark = yyval;
+ if (yychar < 0)
+ {
+ if ((yychar = YYLEX) < 0) yychar = YYEOF;
+#if YYDEBUG
+ if (yydebug)
+ {
+ yys = yyname[YYTRANSLATE(yychar)];
+ printf("%sdebug: state %d, reading %d (%s)\n",
+ YYPREFIX, YYFINAL, yychar, yys);
+ }
+#endif
+ }
+ if (yychar == YYEOF) goto yyaccept;
+ goto yyloop;
+ }
+ if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
+ yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
+ yystate = yytable[yyn];
+ else
+ yystate = yydgoto[yym];
+#if YYDEBUG
+ if (yydebug)
+ printf("%sdebug: after reduction, shifting from state %d \
+to state %d\n", YYPREFIX, *yystack.s_mark, yystate);
+#endif
+ if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack) == YYENOMEM)
+ {
+ goto yyoverflow;
+ }
+ *++yystack.s_mark = (YYINT) yystate;
+ *++yystack.l_mark = yyval;
+ goto yyloop;
+
+yyoverflow:
+ YYERROR_CALL("yacc stack overflow");
+
+yyabort:
+ yyfreestack(&yystack);
+ return (1);
+
+yyaccept:
+ yyfreestack(&yystack);
+ return (0);
+}
diff --git a/freebsd/contrib/libpcap/grammar.y b/freebsd/contrib/libpcap/grammar.y
new file mode 100644
index 00000000..ac69db9f
--- /dev/null
+++ b/freebsd/contrib/libpcap/grammar.y
@@ -0,0 +1,698 @@
+%{
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/grammar.y,v 1.101 2007-11-18 02:03:52 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#include <sys/types.h>
+#include <sys/socket.h>
+#endif /* WIN32 */
+
+#include <stdlib.h>
+
+#ifndef WIN32
+#if __STDC__
+struct mbuf;
+struct rtentry;
+#endif
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif /* WIN32 */
+
+#include <stdio.h>
+
+#include "pcap-int.h"
+
+#include "gencode.h"
+#ifdef HAVE_NET_PFVAR_H
+#include <net/if.h>
+#include <net/pfvar.h>
+#include <net/if_pflog.h>
+#endif
+#include "ieee80211.h"
+#include <pcap/namedb.h>
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#define QSET(q, p, d, a) (q).proto = (p),\
+ (q).dir = (d),\
+ (q).addr = (a)
+
+struct tok {
+ int v; /* value */
+ const char *s; /* string */
+};
+
+static const struct tok ieee80211_types[] = {
+ { IEEE80211_FC0_TYPE_DATA, "data" },
+ { IEEE80211_FC0_TYPE_MGT, "mgt" },
+ { IEEE80211_FC0_TYPE_MGT, "management" },
+ { IEEE80211_FC0_TYPE_CTL, "ctl" },
+ { IEEE80211_FC0_TYPE_CTL, "control" },
+ { 0, NULL }
+};
+static const struct tok ieee80211_mgt_subtypes[] = {
+ { IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assocreq" },
+ { IEEE80211_FC0_SUBTYPE_ASSOC_REQ, "assoc-req" },
+ { IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assocresp" },
+ { IEEE80211_FC0_SUBTYPE_ASSOC_RESP, "assoc-resp" },
+ { IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassocreq" },
+ { IEEE80211_FC0_SUBTYPE_REASSOC_REQ, "reassoc-req" },
+ { IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassocresp" },
+ { IEEE80211_FC0_SUBTYPE_REASSOC_RESP, "reassoc-resp" },
+ { IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probereq" },
+ { IEEE80211_FC0_SUBTYPE_PROBE_REQ, "probe-req" },
+ { IEEE80211_FC0_SUBTYPE_PROBE_RESP, "proberesp" },
+ { IEEE80211_FC0_SUBTYPE_PROBE_RESP, "probe-resp" },
+ { IEEE80211_FC0_SUBTYPE_BEACON, "beacon" },
+ { IEEE80211_FC0_SUBTYPE_ATIM, "atim" },
+ { IEEE80211_FC0_SUBTYPE_DISASSOC, "disassoc" },
+ { IEEE80211_FC0_SUBTYPE_DISASSOC, "disassociation" },
+ { IEEE80211_FC0_SUBTYPE_AUTH, "auth" },
+ { IEEE80211_FC0_SUBTYPE_AUTH, "authentication" },
+ { IEEE80211_FC0_SUBTYPE_DEAUTH, "deauth" },
+ { IEEE80211_FC0_SUBTYPE_DEAUTH, "deauthentication" },
+ { 0, NULL }
+};
+static const struct tok ieee80211_ctl_subtypes[] = {
+ { IEEE80211_FC0_SUBTYPE_PS_POLL, "ps-poll" },
+ { IEEE80211_FC0_SUBTYPE_RTS, "rts" },
+ { IEEE80211_FC0_SUBTYPE_CTS, "cts" },
+ { IEEE80211_FC0_SUBTYPE_ACK, "ack" },
+ { IEEE80211_FC0_SUBTYPE_CF_END, "cf-end" },
+ { IEEE80211_FC0_SUBTYPE_CF_END_ACK, "cf-end-ack" },
+ { 0, NULL }
+};
+static const struct tok ieee80211_data_subtypes[] = {
+ { IEEE80211_FC0_SUBTYPE_DATA, "data" },
+ { IEEE80211_FC0_SUBTYPE_CF_ACK, "data-cf-ack" },
+ { IEEE80211_FC0_SUBTYPE_CF_POLL, "data-cf-poll" },
+ { IEEE80211_FC0_SUBTYPE_CF_ACPL, "data-cf-ack-poll" },
+ { IEEE80211_FC0_SUBTYPE_NODATA, "null" },
+ { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACK, "cf-ack" },
+ { IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "cf-poll" },
+ { IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "cf-ack-poll" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_DATA, "qos-data" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACK, "qos-data-cf-ack" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_POLL, "qos-data-cf-poll" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_CF_ACPL, "qos-data-cf-ack-poll" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA, "qos" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL, "qos-cf-poll" },
+ { IEEE80211_FC0_SUBTYPE_QOS|IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL, "qos-cf-ack-poll" },
+ { 0, NULL }
+};
+struct type2tok {
+ int type;
+ const struct tok *tok;
+};
+static const struct type2tok ieee80211_type_subtypes[] = {
+ { IEEE80211_FC0_TYPE_MGT, ieee80211_mgt_subtypes },
+ { IEEE80211_FC0_TYPE_CTL, ieee80211_ctl_subtypes },
+ { IEEE80211_FC0_TYPE_DATA, ieee80211_data_subtypes },
+ { 0, NULL }
+};
+
+static int
+str2tok(const char *str, const struct tok *toks)
+{
+ int i;
+
+ for (i = 0; toks[i].s != NULL; i++) {
+ if (pcap_strcasecmp(toks[i].s, str) == 0)
+ return (toks[i].v);
+ }
+ return (-1);
+}
+
+int n_errors = 0;
+
+static struct qual qerr = { Q_UNDEF, Q_UNDEF, Q_UNDEF, Q_UNDEF };
+
+static void
+yyerror(const char *msg)
+{
+ ++n_errors;
+ bpf_error("%s", msg);
+ /* NOTREACHED */
+}
+
+#ifdef NEED_YYPARSE_WRAPPER
+int yyparse(void);
+
+int
+pcap_parse()
+{
+ return (yyparse());
+}
+#endif
+
+#ifdef HAVE_NET_PFVAR_H
+static int
+pfreason_to_num(const char *reason)
+{
+ const char *reasons[] = PFRES_NAMES;
+ int i;
+
+ for (i = 0; reasons[i]; i++) {
+ if (pcap_strcasecmp(reason, reasons[i]) == 0)
+ return (i);
+ }
+ bpf_error("unknown PF reason");
+ /*NOTREACHED*/
+}
+
+static int
+pfaction_to_num(const char *action)
+{
+ if (pcap_strcasecmp(action, "pass") == 0 ||
+ pcap_strcasecmp(action, "accept") == 0)
+ return (PF_PASS);
+ else if (pcap_strcasecmp(action, "drop") == 0 ||
+ pcap_strcasecmp(action, "block") == 0)
+ return (PF_DROP);
+#if HAVE_PF_NAT_THROUGH_PF_NORDR
+ else if (pcap_strcasecmp(action, "rdr") == 0)
+ return (PF_RDR);
+ else if (pcap_strcasecmp(action, "nat") == 0)
+ return (PF_NAT);
+ else if (pcap_strcasecmp(action, "binat") == 0)
+ return (PF_BINAT);
+ else if (pcap_strcasecmp(action, "nordr") == 0)
+ return (PF_NORDR);
+#endif
+ else {
+ bpf_error("unknown PF action");
+ /*NOTREACHED*/
+ }
+}
+#else /* !HAVE_NET_PFVAR_H */
+static int
+pfreason_to_num(const char *reason)
+{
+ bpf_error("libpcap was compiled on a machine without pf support");
+ /*NOTREACHED*/
+
+ /* this is to make the VC compiler happy */
+ return -1;
+}
+
+static int
+pfaction_to_num(const char *action)
+{
+ bpf_error("libpcap was compiled on a machine without pf support");
+ /*NOTREACHED*/
+
+ /* this is to make the VC compiler happy */
+ return -1;
+}
+#endif /* HAVE_NET_PFVAR_H */
+%}
+
+%union {
+ int i;
+ bpf_u_int32 h;
+ u_char *e;
+ char *s;
+ struct stmt *stmt;
+ struct arth *a;
+ struct {
+ struct qual q;
+ int atmfieldtype;
+ int mtp3fieldtype;
+ struct block *b;
+ } blk;
+ struct block *rblk;
+}
+
+%type <blk> expr id nid pid term rterm qid
+%type <blk> head
+%type <i> pqual dqual aqual ndaqual
+%type <a> arth narth
+%type <i> byteop pname pnum relop irelop
+%type <blk> and or paren not null prog
+%type <rblk> other pfvar p80211
+%type <i> atmtype atmmultitype
+%type <blk> atmfield
+%type <blk> atmfieldvalue atmvalue atmlistvalue
+%type <i> mtp2type
+%type <blk> mtp3field
+%type <blk> mtp3fieldvalue mtp3value mtp3listvalue
+
+
+%token DST SRC HOST GATEWAY
+%token NET NETMASK PORT PORTRANGE LESS GREATER PROTO PROTOCHAIN CBYTE
+%token ARP RARP IP SCTP TCP UDP ICMP IGMP IGRP PIM VRRP CARP
+%token ATALK AARP DECNET LAT SCA MOPRC MOPDL
+%token TK_BROADCAST TK_MULTICAST
+%token NUM INBOUND OUTBOUND
+%token PF_IFNAME PF_RSET PF_RNR PF_SRNR PF_REASON PF_ACTION
+%token TYPE SUBTYPE DIR ADDR1 ADDR2 ADDR3 ADDR4 RA TA
+%token LINK
+%token GEQ LEQ NEQ
+%token ID EID HID HID6 AID
+%token LSH RSH
+%token LEN
+%token IPV6 ICMPV6 AH ESP
+%token VLAN MPLS
+%token PPPOED PPPOES
+%token ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
+%token STP
+%token IPX
+%token NETBEUI
+%token LANE LLC METAC BCC SC ILMIC OAMF4EC OAMF4SC
+%token OAM OAMF4 CONNECTMSG METACONNECT
+%token VPI VCI
+%token RADIO
+%token FISU LSSU MSU
+%token SIO OPC DPC SLS
+
+%type <s> ID
+%type <e> EID
+%type <e> AID
+%type <s> HID HID6
+%type <i> NUM action reason type subtype type_subtype dir
+
+%left OR AND
+%nonassoc '!'
+%left '|'
+%left '&'
+%left LSH RSH
+%left '+' '-'
+%left '*' '/'
+%nonassoc UMINUS
+%%
+prog: null expr
+{
+ finish_parse($2.b);
+}
+ | null
+ ;
+null: /* null */ { $$.q = qerr; }
+ ;
+expr: term
+ | expr and term { gen_and($1.b, $3.b); $$ = $3; }
+ | expr and id { gen_and($1.b, $3.b); $$ = $3; }
+ | expr or term { gen_or($1.b, $3.b); $$ = $3; }
+ | expr or id { gen_or($1.b, $3.b); $$ = $3; }
+ ;
+and: AND { $$ = $<blk>0; }
+ ;
+or: OR { $$ = $<blk>0; }
+ ;
+id: nid
+ | pnum { $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
+ $$.q = $<blk>0.q); }
+ | paren pid ')' { $$ = $2; }
+ ;
+nid: ID { $$.b = gen_scode($1, $$.q = $<blk>0.q); }
+ | HID '/' NUM { $$.b = gen_mcode($1, NULL, $3,
+ $$.q = $<blk>0.q); }
+ | HID NETMASK HID { $$.b = gen_mcode($1, $3, 0,
+ $$.q = $<blk>0.q); }
+ | HID {
+ /* Decide how to parse HID based on proto */
+ $$.q = $<blk>0.q;
+ if ($$.q.addr == Q_PORT)
+ bpf_error("'port' modifier applied to ip host");
+ else if ($$.q.addr == Q_PORTRANGE)
+ bpf_error("'portrange' modifier applied to ip host");
+ else if ($$.q.addr == Q_PROTO)
+ bpf_error("'proto' modifier applied to ip host");
+ else if ($$.q.addr == Q_PROTOCHAIN)
+ bpf_error("'protochain' modifier applied to ip host");
+ $$.b = gen_ncode($1, 0, $$.q);
+ }
+ | HID6 '/' NUM {
+#ifdef INET6
+ $$.b = gen_mcode6($1, NULL, $3,
+ $$.q = $<blk>0.q);
+#else
+ bpf_error("'ip6addr/prefixlen' not supported "
+ "in this configuration");
+#endif /*INET6*/
+ }
+ | HID6 {
+#ifdef INET6
+ $$.b = gen_mcode6($1, 0, 128,
+ $$.q = $<blk>0.q);
+#else
+ bpf_error("'ip6addr' not supported "
+ "in this configuration");
+#endif /*INET6*/
+ }
+ | EID {
+ $$.b = gen_ecode($1, $$.q = $<blk>0.q);
+ /*
+ * $1 was allocated by "pcap_ether_aton()",
+ * so we must free it now that we're done
+ * with it.
+ */
+ free($1);
+ }
+ | AID {
+ $$.b = gen_acode($1, $$.q = $<blk>0.q);
+ /*
+ * $1 was allocated by "pcap_ether_aton()",
+ * so we must free it now that we're done
+ * with it.
+ */
+ free($1);
+ }
+ | not id { gen_not($2.b); $$ = $2; }
+ ;
+not: '!' { $$ = $<blk>0; }
+ ;
+paren: '(' { $$ = $<blk>0; }
+ ;
+pid: nid
+ | qid and id { gen_and($1.b, $3.b); $$ = $3; }
+ | qid or id { gen_or($1.b, $3.b); $$ = $3; }
+ ;
+qid: pnum { $$.b = gen_ncode(NULL, (bpf_u_int32)$1,
+ $$.q = $<blk>0.q); }
+ | pid
+ ;
+term: rterm
+ | not term { gen_not($2.b); $$ = $2; }
+ ;
+head: pqual dqual aqual { QSET($$.q, $1, $2, $3); }
+ | pqual dqual { QSET($$.q, $1, $2, Q_DEFAULT); }
+ | pqual aqual { QSET($$.q, $1, Q_DEFAULT, $2); }
+ | pqual PROTO { QSET($$.q, $1, Q_DEFAULT, Q_PROTO); }
+ | pqual PROTOCHAIN { QSET($$.q, $1, Q_DEFAULT, Q_PROTOCHAIN); }
+ | pqual ndaqual { QSET($$.q, $1, Q_DEFAULT, $2); }
+ ;
+rterm: head id { $$ = $2; }
+ | paren expr ')' { $$.b = $2.b; $$.q = $1.q; }
+ | pname { $$.b = gen_proto_abbrev($1); $$.q = qerr; }
+ | arth relop arth { $$.b = gen_relation($2, $1, $3, 0);
+ $$.q = qerr; }
+ | arth irelop arth { $$.b = gen_relation($2, $1, $3, 1);
+ $$.q = qerr; }
+ | other { $$.b = $1; $$.q = qerr; }
+ | atmtype { $$.b = gen_atmtype_abbrev($1); $$.q = qerr; }
+ | atmmultitype { $$.b = gen_atmmulti_abbrev($1); $$.q = qerr; }
+ | atmfield atmvalue { $$.b = $2.b; $$.q = qerr; }
+ | mtp2type { $$.b = gen_mtp2type_abbrev($1); $$.q = qerr; }
+ | mtp3field mtp3value { $$.b = $2.b; $$.q = qerr; }
+ ;
+/* protocol level qualifiers */
+pqual: pname
+ | { $$ = Q_DEFAULT; }
+ ;
+/* 'direction' qualifiers */
+dqual: SRC { $$ = Q_SRC; }
+ | DST { $$ = Q_DST; }
+ | SRC OR DST { $$ = Q_OR; }
+ | DST OR SRC { $$ = Q_OR; }
+ | SRC AND DST { $$ = Q_AND; }
+ | DST AND SRC { $$ = Q_AND; }
+ | ADDR1 { $$ = Q_ADDR1; }
+ | ADDR2 { $$ = Q_ADDR2; }
+ | ADDR3 { $$ = Q_ADDR3; }
+ | ADDR4 { $$ = Q_ADDR4; }
+ | RA { $$ = Q_RA; }
+ | TA { $$ = Q_TA; }
+ ;
+/* address type qualifiers */
+aqual: HOST { $$ = Q_HOST; }
+ | NET { $$ = Q_NET; }
+ | PORT { $$ = Q_PORT; }
+ | PORTRANGE { $$ = Q_PORTRANGE; }
+ ;
+/* non-directional address type qualifiers */
+ndaqual: GATEWAY { $$ = Q_GATEWAY; }
+ ;
+pname: LINK { $$ = Q_LINK; }
+ | IP { $$ = Q_IP; }
+ | ARP { $$ = Q_ARP; }
+ | RARP { $$ = Q_RARP; }
+ | SCTP { $$ = Q_SCTP; }
+ | TCP { $$ = Q_TCP; }
+ | UDP { $$ = Q_UDP; }
+ | ICMP { $$ = Q_ICMP; }
+ | IGMP { $$ = Q_IGMP; }
+ | IGRP { $$ = Q_IGRP; }
+ | PIM { $$ = Q_PIM; }
+ | VRRP { $$ = Q_VRRP; }
+ | CARP { $$ = Q_CARP; }
+ | ATALK { $$ = Q_ATALK; }
+ | AARP { $$ = Q_AARP; }
+ | DECNET { $$ = Q_DECNET; }
+ | LAT { $$ = Q_LAT; }
+ | SCA { $$ = Q_SCA; }
+ | MOPDL { $$ = Q_MOPDL; }
+ | MOPRC { $$ = Q_MOPRC; }
+ | IPV6 { $$ = Q_IPV6; }
+ | ICMPV6 { $$ = Q_ICMPV6; }
+ | AH { $$ = Q_AH; }
+ | ESP { $$ = Q_ESP; }
+ | ISO { $$ = Q_ISO; }
+ | ESIS { $$ = Q_ESIS; }
+ | ISIS { $$ = Q_ISIS; }
+ | L1 { $$ = Q_ISIS_L1; }
+ | L2 { $$ = Q_ISIS_L2; }
+ | IIH { $$ = Q_ISIS_IIH; }
+ | LSP { $$ = Q_ISIS_LSP; }
+ | SNP { $$ = Q_ISIS_SNP; }
+ | PSNP { $$ = Q_ISIS_PSNP; }
+ | CSNP { $$ = Q_ISIS_CSNP; }
+ | CLNP { $$ = Q_CLNP; }
+ | STP { $$ = Q_STP; }
+ | IPX { $$ = Q_IPX; }
+ | NETBEUI { $$ = Q_NETBEUI; }
+ | RADIO { $$ = Q_RADIO; }
+ ;
+other: pqual TK_BROADCAST { $$ = gen_broadcast($1); }
+ | pqual TK_MULTICAST { $$ = gen_multicast($1); }
+ | LESS NUM { $$ = gen_less($2); }
+ | GREATER NUM { $$ = gen_greater($2); }
+ | CBYTE NUM byteop NUM { $$ = gen_byteop($3, $2, $4); }
+ | INBOUND { $$ = gen_inbound(0); }
+ | OUTBOUND { $$ = gen_inbound(1); }
+ | VLAN pnum { $$ = gen_vlan($2); }
+ | VLAN { $$ = gen_vlan(-1); }
+ | MPLS pnum { $$ = gen_mpls($2); }
+ | MPLS { $$ = gen_mpls(-1); }
+ | PPPOED { $$ = gen_pppoed(); }
+ | PPPOES { $$ = gen_pppoes(); }
+ | pfvar { $$ = $1; }
+ | pqual p80211 { $$ = $2; }
+ ;
+
+pfvar: PF_IFNAME ID { $$ = gen_pf_ifname($2); }
+ | PF_RSET ID { $$ = gen_pf_ruleset($2); }
+ | PF_RNR NUM { $$ = gen_pf_rnr($2); }
+ | PF_SRNR NUM { $$ = gen_pf_srnr($2); }
+ | PF_REASON reason { $$ = gen_pf_reason($2); }
+ | PF_ACTION action { $$ = gen_pf_action($2); }
+ ;
+
+p80211: TYPE type SUBTYPE subtype
+ { $$ = gen_p80211_type($2 | $4,
+ IEEE80211_FC0_TYPE_MASK |
+ IEEE80211_FC0_SUBTYPE_MASK);
+ }
+ | TYPE type { $$ = gen_p80211_type($2,
+ IEEE80211_FC0_TYPE_MASK);
+ }
+ | SUBTYPE type_subtype { $$ = gen_p80211_type($2,
+ IEEE80211_FC0_TYPE_MASK |
+ IEEE80211_FC0_SUBTYPE_MASK);
+ }
+ | DIR dir { $$ = gen_p80211_fcdir($2); }
+ ;
+
+type: NUM
+ | ID { $$ = str2tok($1, ieee80211_types);
+ if ($$ == -1)
+ bpf_error("unknown 802.11 type name");
+ }
+ ;
+
+subtype: NUM
+ | ID { const struct tok *types = NULL;
+ int i;
+ for (i = 0;; i++) {
+ if (ieee80211_type_subtypes[i].tok == NULL) {
+ /* Ran out of types */
+ bpf_error("unknown 802.11 type");
+ break;
+ }
+ if ($<i>-1 == ieee80211_type_subtypes[i].type) {
+ types = ieee80211_type_subtypes[i].tok;
+ break;
+ }
+ }
+
+ $$ = str2tok($1, types);
+ if ($$ == -1)
+ bpf_error("unknown 802.11 subtype name");
+ }
+ ;
+
+type_subtype: ID { int i;
+ for (i = 0;; i++) {
+ if (ieee80211_type_subtypes[i].tok == NULL) {
+ /* Ran out of types */
+ bpf_error("unknown 802.11 type name");
+ break;
+ }
+ $$ = str2tok($1, ieee80211_type_subtypes[i].tok);
+ if ($$ != -1) {
+ $$ |= ieee80211_type_subtypes[i].type;
+ break;
+ }
+ }
+ }
+ ;
+
+dir: NUM
+ | ID { if (pcap_strcasecmp($1, "nods") == 0)
+ $$ = IEEE80211_FC1_DIR_NODS;
+ else if (pcap_strcasecmp($1, "tods") == 0)
+ $$ = IEEE80211_FC1_DIR_TODS;
+ else if (pcap_strcasecmp($1, "fromds") == 0)
+ $$ = IEEE80211_FC1_DIR_FROMDS;
+ else if (pcap_strcasecmp($1, "dstods") == 0)
+ $$ = IEEE80211_FC1_DIR_DSTODS;
+ else
+ bpf_error("unknown 802.11 direction");
+ }
+ ;
+
+reason: NUM { $$ = $1; }
+ | ID { $$ = pfreason_to_num($1); }
+ ;
+
+action: ID { $$ = pfaction_to_num($1); }
+ ;
+
+relop: '>' { $$ = BPF_JGT; }
+ | GEQ { $$ = BPF_JGE; }
+ | '=' { $$ = BPF_JEQ; }
+ ;
+irelop: LEQ { $$ = BPF_JGT; }
+ | '<' { $$ = BPF_JGE; }
+ | NEQ { $$ = BPF_JEQ; }
+ ;
+arth: pnum { $$ = gen_loadi($1); }
+ | narth
+ ;
+narth: pname '[' arth ']' { $$ = gen_load($1, $3, 1); }
+ | pname '[' arth ':' NUM ']' { $$ = gen_load($1, $3, $5); }
+ | arth '+' arth { $$ = gen_arth(BPF_ADD, $1, $3); }
+ | arth '-' arth { $$ = gen_arth(BPF_SUB, $1, $3); }
+ | arth '*' arth { $$ = gen_arth(BPF_MUL, $1, $3); }
+ | arth '/' arth { $$ = gen_arth(BPF_DIV, $1, $3); }
+ | arth '&' arth { $$ = gen_arth(BPF_AND, $1, $3); }
+ | arth '|' arth { $$ = gen_arth(BPF_OR, $1, $3); }
+ | arth LSH arth { $$ = gen_arth(BPF_LSH, $1, $3); }
+ | arth RSH arth { $$ = gen_arth(BPF_RSH, $1, $3); }
+ | '-' arth %prec UMINUS { $$ = gen_neg($2); }
+ | paren narth ')' { $$ = $2; }
+ | LEN { $$ = gen_loadlen(); }
+ ;
+byteop: '&' { $$ = '&'; }
+ | '|' { $$ = '|'; }
+ | '<' { $$ = '<'; }
+ | '>' { $$ = '>'; }
+ | '=' { $$ = '='; }
+ ;
+pnum: NUM
+ | paren pnum ')' { $$ = $2; }
+ ;
+atmtype: LANE { $$ = A_LANE; }
+ | LLC { $$ = A_LLC; }
+ | METAC { $$ = A_METAC; }
+ | BCC { $$ = A_BCC; }
+ | OAMF4EC { $$ = A_OAMF4EC; }
+ | OAMF4SC { $$ = A_OAMF4SC; }
+ | SC { $$ = A_SC; }
+ | ILMIC { $$ = A_ILMIC; }
+ ;
+atmmultitype: OAM { $$ = A_OAM; }
+ | OAMF4 { $$ = A_OAMF4; }
+ | CONNECTMSG { $$ = A_CONNECTMSG; }
+ | METACONNECT { $$ = A_METACONNECT; }
+ ;
+ /* ATM field types quantifier */
+atmfield: VPI { $$.atmfieldtype = A_VPI; }
+ | VCI { $$.atmfieldtype = A_VCI; }
+ ;
+atmvalue: atmfieldvalue
+ | relop NUM { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 0); }
+ | irelop NUM { $$.b = gen_atmfield_code($<blk>0.atmfieldtype, (bpf_int32)$2, (bpf_u_int32)$1, 1); }
+ | paren atmlistvalue ')' { $$.b = $2.b; $$.q = qerr; }
+ ;
+atmfieldvalue: NUM {
+ $$.atmfieldtype = $<blk>0.atmfieldtype;
+ if ($$.atmfieldtype == A_VPI ||
+ $$.atmfieldtype == A_VCI)
+ $$.b = gen_atmfield_code($$.atmfieldtype, (bpf_int32) $1, BPF_JEQ, 0);
+ }
+ ;
+atmlistvalue: atmfieldvalue
+ | atmlistvalue or atmfieldvalue { gen_or($1.b, $3.b); $$ = $3; }
+ ;
+ /* MTP2 types quantifier */
+mtp2type: FISU { $$ = M_FISU; }
+ | LSSU { $$ = M_LSSU; }
+ | MSU { $$ = M_MSU; }
+ ;
+ /* MTP3 field types quantifier */
+mtp3field: SIO { $$.mtp3fieldtype = M_SIO; }
+ | OPC { $$.mtp3fieldtype = M_OPC; }
+ | DPC { $$.mtp3fieldtype = M_DPC; }
+ | SLS { $$.mtp3fieldtype = M_SLS; }
+ ;
+mtp3value: mtp3fieldvalue
+ | relop NUM { $$.b = gen_mtp3field_code($<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 0); }
+ | irelop NUM { $$.b = gen_mtp3field_code($<blk>0.mtp3fieldtype, (u_int)$2, (u_int)$1, 1); }
+ | paren mtp3listvalue ')' { $$.b = $2.b; $$.q = qerr; }
+ ;
+mtp3fieldvalue: NUM {
+ $$.mtp3fieldtype = $<blk>0.mtp3fieldtype;
+ if ($$.mtp3fieldtype == M_SIO ||
+ $$.mtp3fieldtype == M_OPC ||
+ $$.mtp3fieldtype == M_DPC ||
+ $$.mtp3fieldtype == M_SLS )
+ $$.b = gen_mtp3field_code($$.mtp3fieldtype, (u_int) $1, BPF_JEQ, 0);
+ }
+ ;
+mtp3listvalue: mtp3fieldvalue
+ | mtp3listvalue or mtp3fieldvalue { gen_or($1.b, $3.b); $$ = $3; }
+ ;
+%%
diff --git a/freebsd/contrib/libpcap/ieee80211.h b/freebsd/contrib/libpcap/ieee80211.h
new file mode 100644
index 00000000..d79f0f8e
--- /dev/null
+++ b/freebsd/contrib/libpcap/ieee80211.h
@@ -0,0 +1,146 @@
+/*-
+ * Copyright (c) 2001 Atsushi Onoe
+ * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * Alternatively, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") version 2 as published by the Free
+ * Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+#ifndef _NET80211_IEEE80211_H_
+#define _NET80211_IEEE80211_H_
+
+/*
+ * 802.11 protocol definitions.
+ */
+
+#define IEEE80211_FC0_VERSION_MASK 0x03
+#define IEEE80211_FC0_VERSION_SHIFT 0
+#define IEEE80211_FC0_VERSION_0 0x00
+#define IEEE80211_FC0_TYPE_MASK 0x0c
+#define IEEE80211_FC0_TYPE_SHIFT 2
+#define IEEE80211_FC0_TYPE_MGT 0x00
+#define IEEE80211_FC0_TYPE_CTL 0x04
+#define IEEE80211_FC0_TYPE_DATA 0x08
+
+#define IEEE80211_FC0_SUBTYPE_MASK 0xf0
+#define IEEE80211_FC0_SUBTYPE_SHIFT 4
+/* for TYPE_MGT */
+#define IEEE80211_FC0_SUBTYPE_ASSOC_REQ 0x00
+#define IEEE80211_FC0_SUBTYPE_ASSOC_RESP 0x10
+#define IEEE80211_FC0_SUBTYPE_REASSOC_REQ 0x20
+#define IEEE80211_FC0_SUBTYPE_REASSOC_RESP 0x30
+#define IEEE80211_FC0_SUBTYPE_PROBE_REQ 0x40
+#define IEEE80211_FC0_SUBTYPE_PROBE_RESP 0x50
+#define IEEE80211_FC0_SUBTYPE_BEACON 0x80
+#define IEEE80211_FC0_SUBTYPE_ATIM 0x90
+#define IEEE80211_FC0_SUBTYPE_DISASSOC 0xa0
+#define IEEE80211_FC0_SUBTYPE_AUTH 0xb0
+#define IEEE80211_FC0_SUBTYPE_DEAUTH 0xc0
+/* for TYPE_CTL */
+#define IEEE80211_FC0_SUBTYPE_PS_POLL 0xa0
+#define IEEE80211_FC0_SUBTYPE_RTS 0xb0
+#define IEEE80211_FC0_SUBTYPE_CTS 0xc0
+#define IEEE80211_FC0_SUBTYPE_ACK 0xd0
+#define IEEE80211_FC0_SUBTYPE_CF_END 0xe0
+#define IEEE80211_FC0_SUBTYPE_CF_END_ACK 0xf0
+/* for TYPE_DATA (bit combination) */
+#define IEEE80211_FC0_SUBTYPE_DATA 0x00
+#define IEEE80211_FC0_SUBTYPE_CF_ACK 0x10
+#define IEEE80211_FC0_SUBTYPE_CF_POLL 0x20
+#define IEEE80211_FC0_SUBTYPE_CF_ACPL 0x30
+#define IEEE80211_FC0_SUBTYPE_NODATA 0x40
+#define IEEE80211_FC0_SUBTYPE_NODATA_CF_ACK 0x50
+#define IEEE80211_FC0_SUBTYPE_NODATA_CF_POLL 0x60
+#define IEEE80211_FC0_SUBTYPE_NODATA_CF_ACPL 0x70
+#define IEEE80211_FC0_SUBTYPE_QOS 0x80
+#define IEEE80211_FC0_SUBTYPE_QOS_NULL 0xc0
+
+#define IEEE80211_FC1_DIR_MASK 0x03
+#define IEEE80211_FC1_DIR_NODS 0x00 /* STA->STA */
+#define IEEE80211_FC1_DIR_TODS 0x01 /* STA->AP */
+#define IEEE80211_FC1_DIR_FROMDS 0x02 /* AP ->STA */
+#define IEEE80211_FC1_DIR_DSTODS 0x03 /* AP ->AP */
+
+#define IEEE80211_FC1_MORE_FRAG 0x04
+#define IEEE80211_FC1_RETRY 0x08
+#define IEEE80211_FC1_PWR_MGT 0x10
+#define IEEE80211_FC1_MORE_DATA 0x20
+#define IEEE80211_FC1_WEP 0x40
+#define IEEE80211_FC1_ORDER 0x80
+
+#define IEEE80211_SEQ_FRAG_MASK 0x000f
+#define IEEE80211_SEQ_FRAG_SHIFT 0
+#define IEEE80211_SEQ_SEQ_MASK 0xfff0
+#define IEEE80211_SEQ_SEQ_SHIFT 4
+
+#define IEEE80211_NWID_LEN 32
+
+#define IEEE80211_QOS_TXOP 0x00ff
+/* bit 8 is reserved */
+#define IEEE80211_QOS_ACKPOLICY 0x60
+#define IEEE80211_QOS_ACKPOLICY_S 5
+#define IEEE80211_QOS_ESOP 0x10
+#define IEEE80211_QOS_ESOP_S 4
+#define IEEE80211_QOS_TID 0x0f
+
+#define IEEE80211_MGT_SUBTYPE_NAMES { \
+ "assoc-req", "assoc-resp", \
+ "reassoc-req", "reassoc-resp", \
+ "probe-req", "probe-resp", \
+ "reserved#6", "reserved#7", \
+ "beacon", "atim", \
+ "disassoc", "auth", \
+ "deauth", "reserved#13", \
+ "reserved#14", "reserved#15" \
+}
+
+#define IEEE80211_CTL_SUBTYPE_NAMES { \
+ "reserved#0", "reserved#1", \
+ "reserved#2", "reserved#3", \
+ "reserved#3", "reserved#5", \
+ "reserved#6", "reserved#7", \
+ "reserved#8", "reserved#9", \
+ "ps-poll", "rts", \
+ "cts", "ack", \
+ "cf-end", "cf-end-ack" \
+}
+
+#define IEEE80211_DATA_SUBTYPE_NAMES { \
+ "data", "data-cf-ack", \
+ "data-cf-poll", "data-cf-ack-poll", \
+ "null", "cf-ack", \
+ "cf-poll", "cf-ack-poll", \
+ "qos-data", "qos-data-cf-ack", \
+ "qos-data-cf-poll", "qos-data-cf-ack-poll", \
+ "qos", "reserved#13", \
+ "qos-cf-poll", "qos-cf-ack-poll" \
+}
+
+#define IEEE80211_TYPE_NAMES { "mgt", "ctl", "data", "reserved#4" }
+
+#endif /* _NET80211_IEEE80211_H_ */
diff --git a/freebsd/contrib/libpcap/inet.c b/freebsd/contrib/libpcap/inet.c
new file mode 100644
index 00000000..08867903
--- /dev/null
+++ b/freebsd/contrib/libpcap/inet.c
@@ -0,0 +1,935 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
+/*
+ * Copyright (c) 1994, 1995, 1996, 1997, 1998
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/inet.c,v 1.79 2008-04-20 18:19:02 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+
+#include <rtems/bsd/sys/param.h>
+#ifndef MSDOS
+#include <sys/file.h>
+#endif
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#ifdef HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h>
+#endif
+
+struct mbuf; /* Squelch compiler warnings on some platforms for */
+struct rtentry; /* declarations in <net/if.h> */
+#include <net/if.h>
+#include <netinet/in.h>
+#endif /* WIN32 */
+
+#include <ctype.h>
+#include <errno.h>
+#include <memory.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if !defined(WIN32) && !defined(__BORLANDC__)
+#include <unistd.h>
+#endif /* !WIN32 && !__BORLANDC__ */
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#else
+#define INT_MAX 2147483647
+#endif
+
+#include "pcap-int.h"
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+/* Not all systems have IFF_LOOPBACK */
+#ifdef IFF_LOOPBACK
+#define ISLOOPBACK(name, flags) ((flags) & IFF_LOOPBACK)
+#else
+#define ISLOOPBACK(name, flags) ((name)[0] == 'l' && (name)[1] == 'o' && \
+ (isdigit((unsigned char)((name)[2])) || (name)[2] == '\0'))
+#endif
+
+struct sockaddr *
+dup_sockaddr(struct sockaddr *sa, size_t sa_length)
+{
+ struct sockaddr *newsa;
+
+ if ((newsa = malloc(sa_length)) == NULL)
+ return (NULL);
+ return (memcpy(newsa, sa, sa_length));
+}
+
+static int
+get_instance(const char *name)
+{
+ const char *cp, *endcp;
+ int n;
+
+ if (strcmp(name, "any") == 0) {
+ /*
+ * Give the "any" device an artificially high instance
+ * number, so it shows up after all other non-loopback
+ * interfaces.
+ */
+ return INT_MAX;
+ }
+
+ endcp = name + strlen(name);
+ for (cp = name; cp < endcp && !isdigit((unsigned char)*cp); ++cp)
+ continue;
+
+ if (isdigit((unsigned char)*cp))
+ n = atoi(cp);
+ else
+ n = 0;
+ return (n);
+}
+
+int
+add_or_find_if(pcap_if_t **curdev_ret, pcap_if_t **alldevs, const char *name,
+ u_int flags, const char *description, char *errbuf)
+{
+ pcap_t *p;
+ pcap_if_t *curdev, *prevdev, *nextdev;
+ int this_instance;
+ char open_errbuf[PCAP_ERRBUF_SIZE];
+
+ /*
+ * Is there already an entry in the list for this interface?
+ */
+ for (curdev = *alldevs; curdev != NULL; curdev = curdev->next) {
+ if (strcmp(name, curdev->name) == 0)
+ break; /* yes, we found it */
+ }
+
+ if (curdev == NULL) {
+ /*
+ * No, we didn't find it.
+ *
+ * Can we open this interface for live capture?
+ *
+ * We do this check so that interfaces that are
+ * supplied by the interface enumeration mechanism
+ * we're using but that don't support packet capture
+ * aren't included in the list. Loopback interfaces
+ * on Solaris are an example of this; we don't just
+ * omit loopback interfaces on all platforms because
+ * you *can* capture on loopback interfaces on some
+ * OSes.
+ *
+ * On OS X, we don't do this check if the device
+ * name begins with "wlt"; at least some versions
+ * of OS X offer monitor mode capturing by having
+ * a separate "monitor mode" device for each wireless
+ * adapter, rather than by implementing the ioctls
+ * that {Free,Net,Open,DragonFly}BSD provide.
+ * Opening that device puts the adapter into monitor
+ * mode, which, at least for some adapters, causes
+ * them to deassociate from the network with which
+ * they're associated.
+ *
+ * Instead, we try to open the corresponding "en"
+ * device (so that we don't end up with, for users
+ * without sufficient privilege to open capture
+ * devices, a list of adapters that only includes
+ * the wlt devices).
+ */
+#ifdef __APPLE__
+ if (strncmp(name, "wlt", 3) == 0) {
+ char *en_name;
+ size_t en_name_len;
+
+ /*
+ * Try to allocate a buffer for the "en"
+ * device's name.
+ */
+ en_name_len = strlen(name) - 1;
+ en_name = malloc(en_name_len + 1);
+ if (en_name == NULL) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ return (-1);
+ }
+ strcpy(en_name, "en");
+ strcat(en_name, name + 3);
+ p = pcap_open_live(en_name, 68, 0, 0, open_errbuf);
+ free(en_name);
+ } else
+#endif /* __APPLE */
+ p = pcap_open_live(name, 68, 0, 0, open_errbuf);
+ if (p == NULL) {
+ /*
+ * No. Don't bother including it.
+ * Don't treat this as an error, though.
+ */
+ *curdev_ret = NULL;
+ return (0);
+ }
+ pcap_close(p);
+
+ /*
+ * Yes, we can open it.
+ * Allocate a new entry.
+ */
+ curdev = malloc(sizeof(pcap_if_t));
+ if (curdev == NULL) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ return (-1);
+ }
+
+ /*
+ * Fill in the entry.
+ */
+ curdev->next = NULL;
+ curdev->name = strdup(name);
+ if (curdev->name == NULL) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ free(curdev);
+ return (-1);
+ }
+ if (description != NULL) {
+ /*
+ * We have a description for this interface.
+ */
+ curdev->description = strdup(description);
+ if (curdev->description == NULL) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ free(curdev->name);
+ free(curdev);
+ return (-1);
+ }
+ } else {
+ /*
+ * We don't.
+ */
+ curdev->description = NULL;
+ }
+ curdev->addresses = NULL; /* list starts out as empty */
+ curdev->flags = 0;
+ if (ISLOOPBACK(name, flags))
+ curdev->flags |= PCAP_IF_LOOPBACK;
+
+ /*
+ * Add it to the list, in the appropriate location.
+ * First, get the instance number of this interface.
+ */
+ this_instance = get_instance(name);
+
+ /*
+ * Now look for the last interface with an instance number
+ * less than or equal to the new interface's instance
+ * number - except that non-loopback interfaces are
+ * arbitrarily treated as having interface numbers less
+ * than those of loopback interfaces, so the loopback
+ * interfaces are put at the end of the list.
+ *
+ * We start with "prevdev" being NULL, meaning we're before
+ * the first element in the list.
+ */
+ prevdev = NULL;
+ for (;;) {
+ /*
+ * Get the interface after this one.
+ */
+ if (prevdev == NULL) {
+ /*
+ * The next element is the first element.
+ */
+ nextdev = *alldevs;
+ } else
+ nextdev = prevdev->next;
+
+ /*
+ * Are we at the end of the list?
+ */
+ if (nextdev == NULL) {
+ /*
+ * Yes - we have to put the new entry
+ * after "prevdev".
+ */
+ break;
+ }
+
+ /*
+ * Is the new interface a non-loopback interface
+ * and the next interface a loopback interface?
+ */
+ if (!(curdev->flags & PCAP_IF_LOOPBACK) &&
+ (nextdev->flags & PCAP_IF_LOOPBACK)) {
+ /*
+ * Yes, we should put the new entry
+ * before "nextdev", i.e. after "prevdev".
+ */
+ break;
+ }
+
+ /*
+ * Is the new interface's instance number less
+ * than the next interface's instance number,
+ * and is it the case that the new interface is a
+ * non-loopback interface or the next interface is
+ * a loopback interface?
+ *
+ * (The goal of both loopback tests is to make
+ * sure that we never put a loopback interface
+ * before any non-loopback interface and that we
+ * always put a non-loopback interface before all
+ * loopback interfaces.)
+ */
+ if (this_instance < get_instance(nextdev->name) &&
+ (!(curdev->flags & PCAP_IF_LOOPBACK) ||
+ (nextdev->flags & PCAP_IF_LOOPBACK))) {
+ /*
+ * Yes - we should put the new entry
+ * before "nextdev", i.e. after "prevdev".
+ */
+ break;
+ }
+
+ prevdev = nextdev;
+ }
+
+ /*
+ * Insert before "nextdev".
+ */
+ curdev->next = nextdev;
+
+ /*
+ * Insert after "prevdev" - unless "prevdev" is null,
+ * in which case this is the first interface.
+ */
+ if (prevdev == NULL) {
+ /*
+ * This is the first interface. Pass back a
+ * pointer to it, and put "curdev" before
+ * "nextdev".
+ */
+ *alldevs = curdev;
+ } else
+ prevdev->next = curdev;
+ }
+
+ *curdev_ret = curdev;
+ return (0);
+}
+
+/*
+ * XXX - on FreeBSDs that support it, should it get the sysctl named
+ * "dev.{adapter family name}.{adapter unit}.%desc" to get a description
+ * of the adapter? Note that "dev.an.0.%desc" is "Aironet PC4500/PC4800"
+ * with my Cisco 350 card, so the name isn't entirely descriptive. The
+ * "dev.an.0.%pnpinfo" has a better description, although one might argue
+ * that the problem is really a driver bug - if it can find out that it's
+ * a Cisco 340 or 350, rather than an old Aironet card, it should use
+ * that in the description.
+ *
+ * Do NetBSD, DragonflyBSD, or OpenBSD support this as well? FreeBSD
+ * and OpenBSD let you get a description, but it's not generated by the OS,
+ * it's set with another ioctl that ifconfig supports; we use that to get
+ * a description in FreeBSD and OpenBSD, but if there is no such
+ * description available, it still might be nice to get some description
+ * string based on the device type or something such as that.
+ *
+ * In OS X, the System Configuration framework can apparently return
+ * names in 10.4 and later.
+ *
+ * It also appears that freedesktop.org's HAL offers an "info.product"
+ * string, but the HAL specification says it "should not be used in any
+ * UI" and "subsystem/capability specific properties" should be used
+ * instead and, in any case, I think HAL is being deprecated in
+ * favor of other stuff such as DeviceKit. DeviceKit doesn't appear
+ * to have any obvious product information for devices, but maybe
+ * I haven't looked hard enough.
+ *
+ * Using the System Configuration framework, or HAL, or DeviceKit, or
+ * whatever, would require that libpcap applications be linked with
+ * the frameworks/libraries in question. That shouldn't be a problem
+ * for programs linking with the shared version of libpcap (unless
+ * you're running on AIX - which I think is the only UN*X that doesn't
+ * support linking a shared library with other libraries on which it
+ * depends, and having an executable linked only with the first shared
+ * library automatically pick up the other libraries when started -
+ * and using HAL or whatever). Programs linked with the static
+ * version of libpcap would have to use pcap-config with the --static
+ * flag in order to get the right linker flags in order to pick up
+ * the additional libraries/frameworks; those programs need that anyway
+ * for libpcap 1.1 and beyond on Linux, as, by default, it requires
+ * -lnl.
+ *
+ * Do any other UN*Xes, or desktop environments support getting a
+ * description?
+ */
+int
+add_addr_to_iflist(pcap_if_t **alldevs, const char *name, u_int flags,
+ struct sockaddr *addr, size_t addr_size,
+ struct sockaddr *netmask, size_t netmask_size,
+ struct sockaddr *broadaddr, size_t broadaddr_size,
+ struct sockaddr *dstaddr, size_t dstaddr_size,
+ char *errbuf)
+{
+ pcap_if_t *curdev;
+ char *description = NULL;
+ pcap_addr_t *curaddr, *prevaddr, *nextaddr;
+#ifdef SIOCGIFDESCR
+ int s;
+ struct ifreq ifrdesc;
+#ifndef IFDESCRSIZE
+ size_t descrlen = 64;
+#else
+ size_t descrlen = IFDESCRSIZE;
+#endif /* IFDESCRSIZE */
+#endif /* SIOCGIFDESCR */
+
+#ifdef SIOCGIFDESCR
+ /*
+ * Get the description for the interface.
+ */
+ memset(&ifrdesc, 0, sizeof ifrdesc);
+ strlcpy(ifrdesc.ifr_name, name, sizeof ifrdesc.ifr_name);
+ s = socket(AF_INET, SOCK_DGRAM, 0);
+ if (s >= 0) {
+#ifdef __FreeBSD__
+ /*
+ * On FreeBSD, if the buffer isn't big enough for the
+ * description, the ioctl succeeds, but the description
+ * isn't copied, ifr_buffer.length is set to the description
+ * length, and ifr_buffer.buffer is set to NULL.
+ */
+ for (;;) {
+ free(description);
+ if ((description = malloc(descrlen)) != NULL) {
+ ifrdesc.ifr_buffer.buffer = description;
+ ifrdesc.ifr_buffer.length = descrlen;
+ if (ioctl(s, SIOCGIFDESCR, &ifrdesc) == 0) {
+ if (ifrdesc.ifr_buffer.buffer ==
+ description)
+ break;
+ else
+ descrlen = ifrdesc.ifr_buffer.length;
+ } else {
+ /*
+ * Failed to get interface description.
+ */
+ free(description);
+ description = NULL;
+ break;
+ }
+ } else
+ break;
+ }
+#else /* __FreeBSD__ */
+ /*
+ * The only other OS that currently supports
+ * SIOCGIFDESCR is OpenBSD, and it has no way
+ * to get the description length - it's clamped
+ * to a maximum of IFDESCRSIZE.
+ */
+ if ((description = malloc(descrlen)) != NULL) {
+ ifrdesc.ifr_data = (caddr_t)description;
+ if (ioctl(s, SIOCGIFDESCR, &ifrdesc) != 0) {
+ /*
+ * Failed to get interface description.
+ */
+ free(description);
+ description = NULL;
+ }
+ }
+#endif /* __FreeBSD__ */
+ close(s);
+ if (description != NULL && strlen(description) == 0) {
+ free(description);
+ description = NULL;
+ }
+ }
+#endif /* SIOCGIFDESCR */
+
+ if (add_or_find_if(&curdev, alldevs, name, flags, description,
+ errbuf) == -1) {
+ free(description);
+ /*
+ * Error - give up.
+ */
+ return (-1);
+ }
+ free(description);
+ if (curdev == NULL) {
+ /*
+ * Device wasn't added because it can't be opened.
+ * Not a fatal error.
+ */
+ return (0);
+ }
+
+ /*
+ * "curdev" is an entry for this interface; add an entry for this
+ * address to its list of addresses.
+ *
+ * Allocate the new entry and fill it in.
+ */
+ curaddr = malloc(sizeof(pcap_addr_t));
+ if (curaddr == NULL) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ return (-1);
+ }
+
+ curaddr->next = NULL;
+ if (addr != NULL) {
+ curaddr->addr = dup_sockaddr(addr, addr_size);
+ if (curaddr->addr == NULL) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ free(curaddr);
+ return (-1);
+ }
+ } else
+ curaddr->addr = NULL;
+
+ if (netmask != NULL) {
+ curaddr->netmask = dup_sockaddr(netmask, netmask_size);
+ if (curaddr->netmask == NULL) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ if (curaddr->addr != NULL)
+ free(curaddr->addr);
+ free(curaddr);
+ return (-1);
+ }
+ } else
+ curaddr->netmask = NULL;
+
+ if (broadaddr != NULL) {
+ curaddr->broadaddr = dup_sockaddr(broadaddr, broadaddr_size);
+ if (curaddr->broadaddr == NULL) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ if (curaddr->netmask != NULL)
+ free(curaddr->netmask);
+ if (curaddr->addr != NULL)
+ free(curaddr->addr);
+ free(curaddr);
+ return (-1);
+ }
+ } else
+ curaddr->broadaddr = NULL;
+
+ if (dstaddr != NULL) {
+ curaddr->dstaddr = dup_sockaddr(dstaddr, dstaddr_size);
+ if (curaddr->dstaddr == NULL) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "malloc: %s", pcap_strerror(errno));
+ if (curaddr->broadaddr != NULL)
+ free(curaddr->broadaddr);
+ if (curaddr->netmask != NULL)
+ free(curaddr->netmask);
+ if (curaddr->addr != NULL)
+ free(curaddr->addr);
+ free(curaddr);
+ return (-1);
+ }
+ } else
+ curaddr->dstaddr = NULL;
+
+ /*
+ * Find the end of the list of addresses.
+ */
+ for (prevaddr = curdev->addresses; prevaddr != NULL; prevaddr = nextaddr) {
+ nextaddr = prevaddr->next;
+ if (nextaddr == NULL) {
+ /*
+ * This is the end of the list.
+ */
+ break;
+ }
+ }
+
+ if (prevaddr == NULL) {
+ /*
+ * The list was empty; this is the first member.
+ */
+ curdev->addresses = curaddr;
+ } else {
+ /*
+ * "prevaddr" is the last member of the list; append
+ * this member to it.
+ */
+ prevaddr->next = curaddr;
+ }
+
+ return (0);
+}
+
+int
+pcap_add_if(pcap_if_t **devlist, const char *name, u_int flags,
+ const char *description, char *errbuf)
+{
+ pcap_if_t *curdev;
+
+ return (add_or_find_if(&curdev, devlist, name, flags, description,
+ errbuf));
+}
+
+
+/*
+ * Free a list of interfaces.
+ */
+void
+pcap_freealldevs(pcap_if_t *alldevs)
+{
+ pcap_if_t *curdev, *nextdev;
+ pcap_addr_t *curaddr, *nextaddr;
+
+ for (curdev = alldevs; curdev != NULL; curdev = nextdev) {
+ nextdev = curdev->next;
+
+ /*
+ * Free all addresses.
+ */
+ for (curaddr = curdev->addresses; curaddr != NULL; curaddr = nextaddr) {
+ nextaddr = curaddr->next;
+ if (curaddr->addr)
+ free(curaddr->addr);
+ if (curaddr->netmask)
+ free(curaddr->netmask);
+ if (curaddr->broadaddr)
+ free(curaddr->broadaddr);
+ if (curaddr->dstaddr)
+ free(curaddr->dstaddr);
+ free(curaddr);
+ }
+
+ /*
+ * Free the name string.
+ */
+ free(curdev->name);
+
+ /*
+ * Free the description string, if any.
+ */
+ if (curdev->description != NULL)
+ free(curdev->description);
+
+ /*
+ * Free the interface.
+ */
+ free(curdev);
+ }
+}
+
+#if !defined(WIN32) && !defined(MSDOS)
+
+/*
+ * Return the name of a network interface attached to the system, or NULL
+ * if none can be found. The interface must be configured up; the
+ * lowest unit number is preferred; loopback is ignored.
+ */
+char *
+pcap_lookupdev(errbuf)
+ register char *errbuf;
+{
+ pcap_if_t *alldevs;
+/* for old BSD systems, including bsdi3 */
+#ifndef IF_NAMESIZE
+#define IF_NAMESIZE IFNAMSIZ
+#endif
+ static char device[IF_NAMESIZE + 1];
+ char *ret;
+
+ if (pcap_findalldevs(&alldevs, errbuf) == -1)
+ return (NULL);
+
+ if (alldevs == NULL || (alldevs->flags & PCAP_IF_LOOPBACK)) {
+ /*
+ * There are no devices on the list, or the first device
+ * on the list is a loopback device, which means there
+ * are no non-loopback devices on the list. This means
+ * we can't return any device.
+ *
+ * XXX - why not return a loopback device? If we can't
+ * capture on it, it won't be on the list, and if it's
+ * on the list, there aren't any non-loopback devices,
+ * so why not just supply it as the default device?
+ */
+ (void)strlcpy(errbuf, "no suitable device found",
+ PCAP_ERRBUF_SIZE);
+ ret = NULL;
+ } else {
+ /*
+ * Return the name of the first device on the list.
+ */
+ (void)strlcpy(device, alldevs->name, sizeof(device));
+ ret = device;
+ }
+
+ pcap_freealldevs(alldevs);
+ return (ret);
+}
+
+int
+pcap_lookupnet(device, netp, maskp, errbuf)
+ register const char *device;
+ register bpf_u_int32 *netp, *maskp;
+ register char *errbuf;
+{
+ register int fd;
+ register struct sockaddr_in *sin4;
+ struct ifreq ifr;
+
+ /*
+ * The pseudo-device "any" listens on all interfaces and therefore
+ * has the network address and -mask "0.0.0.0" therefore catching
+ * all traffic. Using NULL for the interface is the same as "any".
+ */
+ if (!device || strcmp(device, "any") == 0
+#ifdef HAVE_DAG_API
+ || strstr(device, "dag") != NULL
+#endif
+#ifdef HAVE_SEPTEL_API
+ || strstr(device, "septel") != NULL
+#endif
+#ifdef PCAP_SUPPORT_BT
+ || strstr(device, "bluetooth") != NULL
+#endif
+#ifdef PCAP_SUPPORT_USB
+ || strstr(device, "usbmon") != NULL
+#endif
+#ifdef HAVE_SNF_API
+ || strstr(device, "snf") != NULL
+#endif
+ ) {
+ *netp = *maskp = 0;
+ return 0;
+ }
+
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fd < 0) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "socket: %s",
+ pcap_strerror(errno));
+ return (-1);
+ }
+ memset(&ifr, 0, sizeof(ifr));
+#ifdef linux
+ /* XXX Work around Linux kernel bug */
+ ifr.ifr_addr.sa_family = AF_INET;
+#endif
+ (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+ if (ioctl(fd, SIOCGIFADDR, (char *)&ifr) < 0) {
+ if (errno == EADDRNOTAVAIL) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "%s: no IPv4 address assigned", device);
+ } else {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "SIOCGIFADDR: %s: %s",
+ device, pcap_strerror(errno));
+ }
+ (void)close(fd);
+ return (-1);
+ }
+ sin4 = (struct sockaddr_in *)&ifr.ifr_addr;
+ *netp = sin4->sin_addr.s_addr;
+ memset(&ifr, 0, sizeof(ifr));
+#ifdef linux
+ /* XXX Work around Linux kernel bug */
+ ifr.ifr_addr.sa_family = AF_INET;
+#endif
+ (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
+ if (ioctl(fd, SIOCGIFNETMASK, (char *)&ifr) < 0) {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "SIOCGIFNETMASK: %s: %s", device, pcap_strerror(errno));
+ (void)close(fd);
+ return (-1);
+ }
+ (void)close(fd);
+ *maskp = sin4->sin_addr.s_addr;
+ if (*maskp == 0) {
+ if (IN_CLASSA(*netp))
+ *maskp = IN_CLASSA_NET;
+ else if (IN_CLASSB(*netp))
+ *maskp = IN_CLASSB_NET;
+ else if (IN_CLASSC(*netp))
+ *maskp = IN_CLASSC_NET;
+ else {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "inet class for 0x%x unknown", *netp);
+ return (-1);
+ }
+ }
+ *netp &= *maskp;
+ return (0);
+}
+
+#elif defined(WIN32)
+
+/*
+ * Return the name of a network interface attached to the system, or NULL
+ * if none can be found. The interface must be configured up; the
+ * lowest unit number is preferred; loopback is ignored.
+ */
+char *
+pcap_lookupdev(errbuf)
+ register char *errbuf;
+{
+ DWORD dwVersion;
+ DWORD dwWindowsMajorVersion;
+ dwVersion = GetVersion(); /* get the OS version */
+ dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
+
+ if (dwVersion >= 0x80000000 && dwWindowsMajorVersion >= 4) {
+ /*
+ * Windows 95, 98, ME.
+ */
+ ULONG NameLength = 8192;
+ static char AdaptersName[8192];
+
+ if (PacketGetAdapterNames(AdaptersName,&NameLength) )
+ return (AdaptersName);
+ else
+ return NULL;
+ } else {
+ /*
+ * Windows NT (NT 4.0, W2K, WXP). Convert the names to UNICODE for backward compatibility
+ */
+ ULONG NameLength = 8192;
+ static WCHAR AdaptersName[8192];
+ char *tAstr;
+ WCHAR *tUstr;
+ WCHAR *TAdaptersName = (WCHAR*)malloc(8192 * sizeof(WCHAR));
+ int NAdapts = 0;
+
+ if(TAdaptersName == NULL)
+ {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE, "memory allocation failure");
+ return NULL;
+ }
+
+ if ( !PacketGetAdapterNames((PTSTR)TAdaptersName,&NameLength) )
+ {
+ (void)snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "PacketGetAdapterNames: %s",
+ pcap_win32strerror());
+ free(TAdaptersName);
+ return NULL;
+ }
+
+
+ tAstr = (char*)TAdaptersName;
+ tUstr = (WCHAR*)AdaptersName;
+
+ /*
+ * Convert and copy the device names
+ */
+ while(sscanf(tAstr, "%S", tUstr) > 0)
+ {
+ tAstr += strlen(tAstr) + 1;
+ tUstr += wcslen(tUstr) + 1;
+ NAdapts ++;
+ }
+
+ tAstr++;
+ *tUstr = 0;
+ tUstr++;
+
+ /*
+ * Copy the descriptions
+ */
+ while(NAdapts--)
+ {
+ char* tmp = (char*)tUstr;
+ strcpy(tmp, tAstr);
+ tmp += strlen(tAstr) + 1;
+ tUstr = (WCHAR*)tmp;
+ tAstr += strlen(tAstr) + 1;
+ }
+
+ free(TAdaptersName);
+ return (char *)(AdaptersName);
+ }
+}
+
+
+int
+pcap_lookupnet(device, netp, maskp, errbuf)
+ register const char *device;
+ register bpf_u_int32 *netp, *maskp;
+ register char *errbuf;
+{
+ /*
+ * We need only the first IPv4 address, so we must scan the array returned by PacketGetNetInfo()
+ * in order to skip non IPv4 (i.e. IPv6 addresses)
+ */
+ npf_if_addr if_addrs[MAX_NETWORK_ADDRESSES];
+ LONG if_addr_size = 1;
+ struct sockaddr_in *t_addr;
+ unsigned int i;
+
+ if (!PacketGetNetInfoEx((void *)device, if_addrs, &if_addr_size)) {
+ *netp = *maskp = 0;
+ return (0);
+ }
+
+ for(i=0; i<MAX_NETWORK_ADDRESSES; i++)
+ {
+ if(if_addrs[i].IPAddress.ss_family == AF_INET)
+ {
+ t_addr = (struct sockaddr_in *) &(if_addrs[i].IPAddress);
+ *netp = t_addr->sin_addr.S_un.S_addr;
+ t_addr = (struct sockaddr_in *) &(if_addrs[i].SubnetMask);
+ *maskp = t_addr->sin_addr.S_un.S_addr;
+
+ *netp &= *maskp;
+ return (0);
+ }
+
+ }
+
+ *netp = *maskp = 0;
+ return (0);
+}
+
+#endif /* !WIN32 && !MSDOS */
diff --git a/freebsd/contrib/libpcap/llc.h b/freebsd/contrib/libpcap/llc.h
new file mode 100644
index 00000000..b8c221fa
--- /dev/null
+++ b/freebsd/contrib/libpcap/llc.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 1993, 1994, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/llc.h,v 1.2 2001-01-28 09:44:50 guy Exp $ (LBL)
+ */
+
+/*
+ * 802.2 LLC SAP values.
+ */
+
+#ifndef LLCSAP_NULL
+#define LLCSAP_NULL 0x00
+#endif
+#ifndef LLCSAP_GLOBAL
+#define LLCSAP_GLOBAL 0xff
+#endif
+#ifndef LLCSAP_8021B
+#define LLCSAP_8021B_I 0x02
+#endif
+#ifndef LLCSAP_8021B
+#define LLCSAP_8021B_G 0x03
+#endif
+#ifndef LLCSAP_IP
+#define LLCSAP_IP 0x06
+#endif
+#ifndef LLCSAP_PROWAYNM
+#define LLCSAP_PROWAYNM 0x0e
+#endif
+#ifndef LLCSAP_8021D
+#define LLCSAP_8021D 0x42
+#endif
+#ifndef LLCSAP_RS511
+#define LLCSAP_RS511 0x4e
+#endif
+#ifndef LLCSAP_ISO8208
+#define LLCSAP_ISO8208 0x7e
+#endif
+#ifndef LLCSAP_PROWAY
+#define LLCSAP_PROWAY 0x8e
+#endif
+#ifndef LLCSAP_SNAP
+#define LLCSAP_SNAP 0xaa
+#endif
+#ifndef LLCSAP_IPX
+#define LLCSAP_IPX 0xe0
+#endif
+#ifndef LLCSAP_NETBEUI
+#define LLCSAP_NETBEUI 0xf0
+#endif
+#ifndef LLCSAP_ISONS
+#define LLCSAP_ISONS 0xfe
+#endif
diff --git a/freebsd/contrib/libpcap/nametoaddr.c b/freebsd/contrib/libpcap/nametoaddr.c
new file mode 100644
index 00000000..af761744
--- /dev/null
+++ b/freebsd/contrib/libpcap/nametoaddr.c
@@ -0,0 +1,525 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Name to id translation routines used by the scanner.
+ * These functions are not time critical.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/nametoaddr.c,v 1.83 2008-02-06 10:21:30 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef DECNETLIB
+#include <rtems/bsd/sys/types.h>
+#include <netdnet/dnetdb.h>
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+
+#else /* WIN32 */
+
+#include <rtems/bsd/sys/param.h>
+#include <rtems/bsd/sys/types.h> /* concession to AIX */
+#include <sys/socket.h>
+#include <rtems/bsd/sys/time.h>
+
+#include <netinet/in.h>
+#endif /* WIN32 */
+
+#ifndef WIN32
+#ifdef HAVE_ETHER_HOSTTON
+/*
+ * XXX - do we need any of this if <netinet/if_ether.h> doesn't declare
+ * ether_hostton()?
+ */
+#ifdef HAVE_NETINET_IF_ETHER_H
+struct mbuf; /* Squelch compiler warnings on some platforms for */
+struct rtentry; /* declarations in <net/if.h> */
+#include <net/if.h> /* for "struct ifnet" in "struct arpcom" on Solaris */
+#include <netinet/if_ether.h>
+#endif /* HAVE_NETINET_IF_ETHER_H */
+#ifdef NETINET_ETHER_H_DECLARES_ETHER_HOSTTON
+#include <netinet/ether.h>
+#endif /* NETINET_ETHER_H_DECLARES_ETHER_HOSTTON */
+#endif /* HAVE_ETHER_HOSTTON */
+#include <arpa/inet.h>
+#include <netdb.h>
+#endif /* WIN32 */
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "pcap-int.h"
+
+#include "gencode.h"
+#include <pcap/namedb.h>
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#ifndef NTOHL
+#define NTOHL(x) (x) = ntohl(x)
+#define NTOHS(x) (x) = ntohs(x)
+#endif
+
+static inline int xdtoi(int);
+
+/*
+ * Convert host name to internet address.
+ * Return 0 upon failure.
+ */
+bpf_u_int32 **
+pcap_nametoaddr(const char *name)
+{
+#ifndef h_addr
+ static bpf_u_int32 *hlist[2];
+#endif
+ bpf_u_int32 **p;
+ struct hostent *hp;
+
+ if ((hp = gethostbyname(name)) != NULL) {
+#ifndef h_addr
+ hlist[0] = (bpf_u_int32 *)hp->h_addr;
+ NTOHL(hp->h_addr);
+ return hlist;
+#else
+ for (p = (bpf_u_int32 **)hp->h_addr_list; *p; ++p)
+ NTOHL(**p);
+ return (bpf_u_int32 **)hp->h_addr_list;
+#endif
+ }
+ else
+ return 0;
+}
+
+#ifdef INET6
+struct addrinfo *
+pcap_nametoaddrinfo(const char *name)
+{
+ struct addrinfo hints, *res;
+ int error;
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM; /*not really*/
+ hints.ai_protocol = IPPROTO_TCP; /*not really*/
+ error = getaddrinfo(name, NULL, &hints, &res);
+ if (error)
+ return NULL;
+ else
+ return res;
+}
+#endif /*INET6*/
+
+/*
+ * Convert net name to internet address.
+ * Return 0 upon failure.
+ */
+bpf_u_int32
+pcap_nametonetaddr(const char *name)
+{
+#ifndef WIN32
+ struct netent *np;
+
+ if ((np = getnetbyname(name)) != NULL)
+ return np->n_net;
+ else
+ return 0;
+#else
+ /*
+ * There's no "getnetbyname()" on Windows.
+ */
+ return 0;
+#endif
+}
+
+/*
+ * Convert a port name to its port and protocol numbers.
+ * We assume only TCP or UDP.
+ * Return 0 upon failure.
+ */
+int
+pcap_nametoport(const char *name, int *port, int *proto)
+{
+ struct servent *sp;
+ int tcp_port = -1;
+ int udp_port = -1;
+
+ /*
+ * We need to check /etc/services for ambiguous entries.
+ * If we find the ambiguous entry, and it has the
+ * same port number, change the proto to PROTO_UNDEF
+ * so both TCP and UDP will be checked.
+ */
+ sp = getservbyname(name, "tcp");
+ if (sp != NULL) tcp_port = ntohs(sp->s_port);
+ sp = getservbyname(name, "udp");
+ if (sp != NULL) udp_port = ntohs(sp->s_port);
+ if (tcp_port >= 0) {
+ *port = tcp_port;
+ *proto = IPPROTO_TCP;
+ if (udp_port >= 0) {
+ if (udp_port == tcp_port)
+ *proto = PROTO_UNDEF;
+#ifdef notdef
+ else
+ /* Can't handle ambiguous names that refer
+ to different port numbers. */
+ warning("ambiguous port %s in /etc/services",
+ name);
+#endif
+ }
+ return 1;
+ }
+ if (udp_port >= 0) {
+ *port = udp_port;
+ *proto = IPPROTO_UDP;
+ return 1;
+ }
+#if defined(ultrix) || defined(__osf__)
+ /* Special hack in case NFS isn't in /etc/services */
+ if (strcmp(name, "nfs") == 0) {
+ *port = 2049;
+ *proto = PROTO_UNDEF;
+ return 1;
+ }
+#endif
+ return 0;
+}
+
+/*
+ * Convert a string in the form PPP-PPP, where correspond to ports, to
+ * a starting and ending port in a port range.
+ * Return 0 on failure.
+ */
+int
+pcap_nametoportrange(const char *name, int *port1, int *port2, int *proto)
+{
+ u_int p1, p2;
+ char *off, *cpy;
+ int save_proto;
+
+ if (sscanf(name, "%d-%d", &p1, &p2) != 2) {
+ if ((cpy = strdup(name)) == NULL)
+ return 0;
+
+ if ((off = strchr(cpy, '-')) == NULL) {
+ free(cpy);
+ return 0;
+ }
+
+ *off = '\0';
+
+ if (pcap_nametoport(cpy, port1, proto) == 0) {
+ free(cpy);
+ return 0;
+ }
+ save_proto = *proto;
+
+ if (pcap_nametoport(off + 1, port2, proto) == 0) {
+ free(cpy);
+ return 0;
+ }
+ free(cpy);
+
+ if (*proto != save_proto)
+ *proto = PROTO_UNDEF;
+ } else {
+ *port1 = p1;
+ *port2 = p2;
+ *proto = PROTO_UNDEF;
+ }
+
+ return 1;
+}
+
+int
+pcap_nametoproto(const char *str)
+{
+ struct protoent *p;
+
+ p = getprotobyname(str);
+ if (p != 0)
+ return p->p_proto;
+ else
+ return PROTO_UNDEF;
+}
+
+#include "ethertype.h"
+
+struct eproto {
+ const char *s;
+ u_short p;
+};
+
+/* Static data base of ether protocol types. */
+struct eproto eproto_db[] = {
+#if 0
+ /* The FreeBSD elf linker generates a request to copy this array
+ * (including its size) when you link with -lpcap. In order to
+ * not bump the major version number of this libpcap.so, we need
+ * to ensure that the array stays the same size. Since PUP is
+ * likely never seen in real life any more, it's the first to
+ * be sacrificed (in favor of ip6).
+ */
+ { "pup", ETHERTYPE_PUP },
+#endif
+ { "xns", ETHERTYPE_NS },
+ { "ip", ETHERTYPE_IP },
+#ifdef INET6
+ { "ip6", ETHERTYPE_IPV6 },
+#endif
+ { "arp", ETHERTYPE_ARP },
+ { "rarp", ETHERTYPE_REVARP },
+ { "sprite", ETHERTYPE_SPRITE },
+ { "mopdl", ETHERTYPE_MOPDL },
+ { "moprc", ETHERTYPE_MOPRC },
+ { "decnet", ETHERTYPE_DN },
+ { "lat", ETHERTYPE_LAT },
+ { "sca", ETHERTYPE_SCA },
+ { "lanbridge", ETHERTYPE_LANBRIDGE },
+ { "vexp", ETHERTYPE_VEXP },
+ { "vprod", ETHERTYPE_VPROD },
+ { "atalk", ETHERTYPE_ATALK },
+ { "atalkarp", ETHERTYPE_AARP },
+ { "loopback", ETHERTYPE_LOOPBACK },
+ { "decdts", ETHERTYPE_DECDTS },
+ { "decdns", ETHERTYPE_DECDNS },
+ { (char *)0, 0 }
+};
+
+int
+pcap_nametoeproto(const char *s)
+{
+ struct eproto *p = eproto_db;
+
+ while (p->s != 0) {
+ if (strcmp(p->s, s) == 0)
+ return p->p;
+ p += 1;
+ }
+ return PROTO_UNDEF;
+}
+
+#include "llc.h"
+
+/* Static data base of LLC values. */
+static struct eproto llc_db[] = {
+ { "iso", LLCSAP_ISONS },
+ { "stp", LLCSAP_8021D },
+ { "ipx", LLCSAP_IPX },
+ { "netbeui", LLCSAP_NETBEUI },
+ { (char *)0, 0 }
+};
+
+int
+pcap_nametollc(const char *s)
+{
+ struct eproto *p = llc_db;
+
+ while (p->s != 0) {
+ if (strcmp(p->s, s) == 0)
+ return p->p;
+ p += 1;
+ }
+ return PROTO_UNDEF;
+}
+
+/* Hex digit to integer. */
+static inline int
+xdtoi(c)
+ register int c;
+{
+ if (isdigit(c))
+ return c - '0';
+ else if (islower(c))
+ return c - 'a' + 10;
+ else
+ return c - 'A' + 10;
+}
+
+int
+__pcap_atoin(const char *s, bpf_u_int32 *addr)
+{
+ u_int n;
+ int len;
+
+ *addr = 0;
+ len = 0;
+ while (1) {
+ n = 0;
+ while (*s && *s != '.')
+ n = n * 10 + *s++ - '0';
+ *addr <<= 8;
+ *addr |= n & 0xff;
+ len += 8;
+ if (*s == '\0')
+ return len;
+ ++s;
+ }
+ /* NOTREACHED */
+}
+
+int
+__pcap_atodn(const char *s, bpf_u_int32 *addr)
+{
+#define AREASHIFT 10
+#define AREAMASK 0176000
+#define NODEMASK 01777
+
+ u_int node, area;
+
+ if (sscanf(s, "%d.%d", &area, &node) != 2)
+ bpf_error("malformed decnet address '%s'", s);
+
+ *addr = (area << AREASHIFT) & AREAMASK;
+ *addr |= (node & NODEMASK);
+
+ return(32);
+}
+
+/*
+ * Convert 's', which can have the one of the forms:
+ *
+ * "xx:xx:xx:xx:xx:xx"
+ * "xx.xx.xx.xx.xx.xx"
+ * "xx-xx-xx-xx-xx-xx"
+ * "xxxx.xxxx.xxxx"
+ * "xxxxxxxxxxxx"
+ *
+ * (or various mixes of ':', '.', and '-') into a new
+ * ethernet address. Assumes 's' is well formed.
+ */
+u_char *
+pcap_ether_aton(const char *s)
+{
+ register u_char *ep, *e;
+ register u_int d;
+
+ e = ep = (u_char *)malloc(6);
+
+ while (*s) {
+ if (*s == ':' || *s == '.' || *s == '-')
+ s += 1;
+ d = xdtoi(*s++);
+ if (isxdigit((unsigned char)*s)) {
+ d <<= 4;
+ d |= xdtoi(*s++);
+ }
+ *ep++ = d;
+ }
+
+ return (e);
+}
+
+#ifndef HAVE_ETHER_HOSTTON
+/* Roll our own */
+u_char *
+pcap_ether_hostton(const char *name)
+{
+ register struct pcap_etherent *ep;
+ register u_char *ap;
+ static FILE *fp = NULL;
+ static int init = 0;
+
+ if (!init) {
+ fp = fopen(PCAP_ETHERS_FILE, "r");
+ ++init;
+ if (fp == NULL)
+ return (NULL);
+ } else if (fp == NULL)
+ return (NULL);
+ else
+ rewind(fp);
+
+ while ((ep = pcap_next_etherent(fp)) != NULL) {
+ if (strcmp(ep->name, name) == 0) {
+ ap = (u_char *)malloc(6);
+ if (ap != NULL) {
+ memcpy(ap, ep->addr, 6);
+ return (ap);
+ }
+ break;
+ }
+ }
+ return (NULL);
+}
+#else
+
+#if !defined(HAVE_DECL_ETHER_HOSTTON) || !HAVE_DECL_ETHER_HOSTTON
+#ifndef HAVE_STRUCT_ETHER_ADDR
+struct ether_addr {
+ unsigned char ether_addr_octet[6];
+};
+#endif
+extern int ether_hostton(const char *, struct ether_addr *);
+#endif
+
+/* Use the os supplied routines */
+u_char *
+pcap_ether_hostton(const char *name)
+{
+ register u_char *ap;
+ u_char a[6];
+
+ ap = NULL;
+ if (ether_hostton(name, (struct ether_addr *)a) == 0) {
+ ap = (u_char *)malloc(6);
+ if (ap != NULL)
+ memcpy((char *)ap, (char *)a, 6);
+ }
+ return (ap);
+}
+#endif
+
+u_short
+__pcap_nametodnaddr(const char *name)
+{
+#ifdef DECNETLIB
+ struct nodeent *getnodebyname();
+ struct nodeent *nep;
+ unsigned short res;
+
+ nep = getnodebyname(name);
+ if (nep == ((struct nodeent *)0))
+ bpf_error("unknown decnet host name '%s'\n", name);
+
+ memcpy((char *)&res, (char *)nep->n_addr, sizeof(unsigned short));
+ return(res);
+#else
+ bpf_error("decnet name support not included, '%s' cannot be translated\n",
+ name);
+ return(0);
+#endif
+}
diff --git a/freebsd/contrib/libpcap/nlpid.h b/freebsd/contrib/libpcap/nlpid.h
new file mode 100644
index 00000000..5327a362
--- /dev/null
+++ b/freebsd/contrib/libpcap/nlpid.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 1996
+ * Juniper Networks, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution. The name of Juniper Networks may not
+ * be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/nlpid.h,v 1.2 2002-12-06 00:01:34 hannes Exp $ (Juniper)
+ */
+
+/* Types missing from some systems */
+
+/*
+ * Network layer prototocol identifiers
+ */
+#ifndef ISO8473_CLNP
+#define ISO8473_CLNP 0x81
+#endif
+#ifndef ISO9542_ESIS
+#define ISO9542_ESIS 0x82
+#endif
+#ifndef ISO9542X25_ESIS
+#define ISO9542X25_ESIS 0x8a
+#endif
+#ifndef ISO10589_ISIS
+#define ISO10589_ISIS 0x83
+#endif
+/*
+ * this does not really belong in the nlpid.h file
+ * however we need it for generating nice
+ * IS-IS related BPF filters
+ */
+#define ISIS_L1_LAN_IIH 15
+#define ISIS_L2_LAN_IIH 16
+#define ISIS_PTP_IIH 17
+#define ISIS_L1_LSP 18
+#define ISIS_L2_LSP 20
+#define ISIS_L1_CSNP 24
+#define ISIS_L2_CSNP 25
+#define ISIS_L1_PSNP 26
+#define ISIS_L2_PSNP 27
+
+#ifndef ISO8878A_CONS
+#define ISO8878A_CONS 0x84
+#endif
+#ifndef ISO10747_IDRP
+#define ISO10747_IDRP 0x85
+#endif
diff --git a/freebsd/contrib/libpcap/optimize.c b/freebsd/contrib/libpcap/optimize.c
new file mode 100644
index 00000000..14eced3c
--- /dev/null
+++ b/freebsd/contrib/libpcap/optimize.c
@@ -0,0 +1,2249 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Optimization module for tcpdump intermediate representation.
+ */
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/optimize.c,v 1.91 2008-01-02 04:16:46 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <rtems/bsd/sys/types.h>
+#endif /* WIN32 */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+#include <string.h>
+
+#include <errno.h>
+
+#include "pcap-int.h"
+
+#include "gencode.h"
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#ifdef BDEBUG
+extern int dflag;
+#endif
+
+#if defined(MSDOS) && !defined(__DJGPP__)
+extern int _w32_ffs (int mask);
+#define ffs _w32_ffs
+#endif
+
+#if defined(WIN32) && defined (_MSC_VER)
+int ffs(int mask);
+#endif
+
+/*
+ * Represents a deleted instruction.
+ */
+#define NOP -1
+
+/*
+ * Register numbers for use-def values.
+ * 0 through BPF_MEMWORDS-1 represent the corresponding scratch memory
+ * location. A_ATOM is the accumulator and X_ATOM is the index
+ * register.
+ */
+#define A_ATOM BPF_MEMWORDS
+#define X_ATOM (BPF_MEMWORDS+1)
+
+/*
+ * This define is used to represent *both* the accumulator and
+ * x register in use-def computations.
+ * Currently, the use-def code assumes only one definition per instruction.
+ */
+#define AX_ATOM N_ATOMS
+
+/*
+ * A flag to indicate that further optimization is needed.
+ * Iterative passes are continued until a given pass yields no
+ * branch movement.
+ */
+static int done;
+
+/*
+ * A block is marked if only if its mark equals the current mark.
+ * Rather than traverse the code array, marking each item, 'cur_mark' is
+ * incremented. This automatically makes each element unmarked.
+ */
+static int cur_mark;
+#define isMarked(p) ((p)->mark == cur_mark)
+#define unMarkAll() cur_mark += 1
+#define Mark(p) ((p)->mark = cur_mark)
+
+static void opt_init(struct block *);
+static void opt_cleanup(void);
+
+static void intern_blocks(struct block *);
+
+static void find_inedges(struct block *);
+#ifdef BDEBUG
+static void opt_dump(struct block *);
+#endif
+
+static int n_blocks;
+struct block **blocks;
+static int n_edges;
+struct edge **edges;
+
+/*
+ * A bit vector set representation of the dominators.
+ * We round up the set size to the next power of two.
+ */
+static int nodewords;
+static int edgewords;
+struct block **levels;
+bpf_u_int32 *space;
+#define BITS_PER_WORD (8*sizeof(bpf_u_int32))
+/*
+ * True if a is in uset {p}
+ */
+#define SET_MEMBER(p, a) \
+((p)[(unsigned)(a) / BITS_PER_WORD] & (1 << ((unsigned)(a) % BITS_PER_WORD)))
+
+/*
+ * Add 'a' to uset p.
+ */
+#define SET_INSERT(p, a) \
+(p)[(unsigned)(a) / BITS_PER_WORD] |= (1 << ((unsigned)(a) % BITS_PER_WORD))
+
+/*
+ * Delete 'a' from uset p.
+ */
+#define SET_DELETE(p, a) \
+(p)[(unsigned)(a) / BITS_PER_WORD] &= ~(1 << ((unsigned)(a) % BITS_PER_WORD))
+
+/*
+ * a := a intersect b
+ */
+#define SET_INTERSECT(a, b, n)\
+{\
+ register bpf_u_int32 *_x = a, *_y = b;\
+ register int _n = n;\
+ while (--_n >= 0) *_x++ &= *_y++;\
+}
+
+/*
+ * a := a - b
+ */
+#define SET_SUBTRACT(a, b, n)\
+{\
+ register bpf_u_int32 *_x = a, *_y = b;\
+ register int _n = n;\
+ while (--_n >= 0) *_x++ &=~ *_y++;\
+}
+
+/*
+ * a := a union b
+ */
+#define SET_UNION(a, b, n)\
+{\
+ register bpf_u_int32 *_x = a, *_y = b;\
+ register int _n = n;\
+ while (--_n >= 0) *_x++ |= *_y++;\
+}
+
+static uset all_dom_sets;
+static uset all_closure_sets;
+static uset all_edge_sets;
+
+#ifndef MAX
+#define MAX(a,b) ((a)>(b)?(a):(b))
+#endif
+
+static void
+find_levels_r(struct block *b)
+{
+ int level;
+
+ if (isMarked(b))
+ return;
+
+ Mark(b);
+ b->link = 0;
+
+ if (JT(b)) {
+ find_levels_r(JT(b));
+ find_levels_r(JF(b));
+ level = MAX(JT(b)->level, JF(b)->level) + 1;
+ } else
+ level = 0;
+ b->level = level;
+ b->link = levels[level];
+ levels[level] = b;
+}
+
+/*
+ * Level graph. The levels go from 0 at the leaves to
+ * N_LEVELS at the root. The levels[] array points to the
+ * first node of the level list, whose elements are linked
+ * with the 'link' field of the struct block.
+ */
+static void
+find_levels(struct block *root)
+{
+ memset((char *)levels, 0, n_blocks * sizeof(*levels));
+ unMarkAll();
+ find_levels_r(root);
+}
+
+/*
+ * Find dominator relationships.
+ * Assumes graph has been leveled.
+ */
+static void
+find_dom(struct block *root)
+{
+ int i;
+ struct block *b;
+ bpf_u_int32 *x;
+
+ /*
+ * Initialize sets to contain all nodes.
+ */
+ x = all_dom_sets;
+ i = n_blocks * nodewords;
+ while (--i >= 0)
+ *x++ = ~0;
+ /* Root starts off empty. */
+ for (i = nodewords; --i >= 0;)
+ root->dom[i] = 0;
+
+ /* root->level is the highest level no found. */
+ for (i = root->level; i >= 0; --i) {
+ for (b = levels[i]; b; b = b->link) {
+ SET_INSERT(b->dom, b->id);
+ if (JT(b) == 0)
+ continue;
+ SET_INTERSECT(JT(b)->dom, b->dom, nodewords);
+ SET_INTERSECT(JF(b)->dom, b->dom, nodewords);
+ }
+ }
+}
+
+static void
+propedom(struct edge *ep)
+{
+ SET_INSERT(ep->edom, ep->id);
+ if (ep->succ) {
+ SET_INTERSECT(ep->succ->et.edom, ep->edom, edgewords);
+ SET_INTERSECT(ep->succ->ef.edom, ep->edom, edgewords);
+ }
+}
+
+/*
+ * Compute edge dominators.
+ * Assumes graph has been leveled and predecessors established.
+ */
+static void
+find_edom(struct block *root)
+{
+ int i;
+ uset x;
+ struct block *b;
+
+ x = all_edge_sets;
+ for (i = n_edges * edgewords; --i >= 0; )
+ x[i] = ~0;
+
+ /* root->level is the highest level no found. */
+ memset(root->et.edom, 0, edgewords * sizeof(*(uset)0));
+ memset(root->ef.edom, 0, edgewords * sizeof(*(uset)0));
+ for (i = root->level; i >= 0; --i) {
+ for (b = levels[i]; b != 0; b = b->link) {
+ propedom(&b->et);
+ propedom(&b->ef);
+ }
+ }
+}
+
+/*
+ * Find the backwards transitive closure of the flow graph. These sets
+ * are backwards in the sense that we find the set of nodes that reach
+ * a given node, not the set of nodes that can be reached by a node.
+ *
+ * Assumes graph has been leveled.
+ */
+static void
+find_closure(struct block *root)
+{
+ int i;
+ struct block *b;
+
+ /*
+ * Initialize sets to contain no nodes.
+ */
+ memset((char *)all_closure_sets, 0,
+ n_blocks * nodewords * sizeof(*all_closure_sets));
+
+ /* root->level is the highest level no found. */
+ for (i = root->level; i >= 0; --i) {
+ for (b = levels[i]; b; b = b->link) {
+ SET_INSERT(b->closure, b->id);
+ if (JT(b) == 0)
+ continue;
+ SET_UNION(JT(b)->closure, b->closure, nodewords);
+ SET_UNION(JF(b)->closure, b->closure, nodewords);
+ }
+ }
+}
+
+/*
+ * Return the register number that is used by s. If A and X are both
+ * used, return AX_ATOM. If no register is used, return -1.
+ *
+ * The implementation should probably change to an array access.
+ */
+static int
+atomuse(struct stmt *s)
+{
+ register int c = s->code;
+
+ if (c == NOP)
+ return -1;
+
+ switch (BPF_CLASS(c)) {
+
+ case BPF_RET:
+ return (BPF_RVAL(c) == BPF_A) ? A_ATOM :
+ (BPF_RVAL(c) == BPF_X) ? X_ATOM : -1;
+
+ case BPF_LD:
+ case BPF_LDX:
+ return (BPF_MODE(c) == BPF_IND) ? X_ATOM :
+ (BPF_MODE(c) == BPF_MEM) ? s->k : -1;
+
+ case BPF_ST:
+ return A_ATOM;
+
+ case BPF_STX:
+ return X_ATOM;
+
+ case BPF_JMP:
+ case BPF_ALU:
+ if (BPF_SRC(c) == BPF_X)
+ return AX_ATOM;
+ return A_ATOM;
+
+ case BPF_MISC:
+ return BPF_MISCOP(c) == BPF_TXA ? X_ATOM : A_ATOM;
+ }
+ abort();
+ /* NOTREACHED */
+}
+
+/*
+ * Return the register number that is defined by 's'. We assume that
+ * a single stmt cannot define more than one register. If no register
+ * is defined, return -1.
+ *
+ * The implementation should probably change to an array access.
+ */
+static int
+atomdef(struct stmt *s)
+{
+ if (s->code == NOP)
+ return -1;
+
+ switch (BPF_CLASS(s->code)) {
+
+ case BPF_LD:
+ case BPF_ALU:
+ return A_ATOM;
+
+ case BPF_LDX:
+ return X_ATOM;
+
+ case BPF_ST:
+ case BPF_STX:
+ return s->k;
+
+ case BPF_MISC:
+ return BPF_MISCOP(s->code) == BPF_TAX ? X_ATOM : A_ATOM;
+ }
+ return -1;
+}
+
+/*
+ * Compute the sets of registers used, defined, and killed by 'b'.
+ *
+ * "Used" means that a statement in 'b' uses the register before any
+ * statement in 'b' defines it, i.e. it uses the value left in
+ * that register by a predecessor block of this block.
+ * "Defined" means that a statement in 'b' defines it.
+ * "Killed" means that a statement in 'b' defines it before any
+ * statement in 'b' uses it, i.e. it kills the value left in that
+ * register by a predecessor block of this block.
+ */
+static void
+compute_local_ud(struct block *b)
+{
+ struct slist *s;
+ atomset def = 0, use = 0, kill = 0;
+ int atom;
+
+ for (s = b->stmts; s; s = s->next) {
+ if (s->s.code == NOP)
+ continue;
+ atom = atomuse(&s->s);
+ if (atom >= 0) {
+ if (atom == AX_ATOM) {
+ if (!ATOMELEM(def, X_ATOM))
+ use |= ATOMMASK(X_ATOM);
+ if (!ATOMELEM(def, A_ATOM))
+ use |= ATOMMASK(A_ATOM);
+ }
+ else if (atom < N_ATOMS) {
+ if (!ATOMELEM(def, atom))
+ use |= ATOMMASK(atom);
+ }
+ else
+ abort();
+ }
+ atom = atomdef(&s->s);
+ if (atom >= 0) {
+ if (!ATOMELEM(use, atom))
+ kill |= ATOMMASK(atom);
+ def |= ATOMMASK(atom);
+ }
+ }
+ if (BPF_CLASS(b->s.code) == BPF_JMP) {
+ /*
+ * XXX - what about RET?
+ */
+ atom = atomuse(&b->s);
+ if (atom >= 0) {
+ if (atom == AX_ATOM) {
+ if (!ATOMELEM(def, X_ATOM))
+ use |= ATOMMASK(X_ATOM);
+ if (!ATOMELEM(def, A_ATOM))
+ use |= ATOMMASK(A_ATOM);
+ }
+ else if (atom < N_ATOMS) {
+ if (!ATOMELEM(def, atom))
+ use |= ATOMMASK(atom);
+ }
+ else
+ abort();
+ }
+ }
+
+ b->def = def;
+ b->kill = kill;
+ b->in_use = use;
+}
+
+/*
+ * Assume graph is already leveled.
+ */
+static void
+find_ud(struct block *root)
+{
+ int i, maxlevel;
+ struct block *p;
+
+ /*
+ * root->level is the highest level no found;
+ * count down from there.
+ */
+ maxlevel = root->level;
+ for (i = maxlevel; i >= 0; --i)
+ for (p = levels[i]; p; p = p->link) {
+ compute_local_ud(p);
+ p->out_use = 0;
+ }
+
+ for (i = 1; i <= maxlevel; ++i) {
+ for (p = levels[i]; p; p = p->link) {
+ p->out_use |= JT(p)->in_use | JF(p)->in_use;
+ p->in_use |= p->out_use &~ p->kill;
+ }
+ }
+}
+
+/*
+ * These data structures are used in a Cocke and Shwarz style
+ * value numbering scheme. Since the flowgraph is acyclic,
+ * exit values can be propagated from a node's predecessors
+ * provided it is uniquely defined.
+ */
+struct valnode {
+ int code;
+ int v0, v1;
+ int val;
+ struct valnode *next;
+};
+
+#define MODULUS 213
+static struct valnode *hashtbl[MODULUS];
+static int curval;
+static int maxval;
+
+/* Integer constants mapped with the load immediate opcode. */
+#define K(i) F(BPF_LD|BPF_IMM|BPF_W, i, 0L)
+
+struct vmapinfo {
+ int is_const;
+ bpf_int32 const_val;
+};
+
+struct vmapinfo *vmap;
+struct valnode *vnode_base;
+struct valnode *next_vnode;
+
+static void
+init_val(void)
+{
+ curval = 0;
+ next_vnode = vnode_base;
+ memset((char *)vmap, 0, maxval * sizeof(*vmap));
+ memset((char *)hashtbl, 0, sizeof hashtbl);
+}
+
+/* Because we really don't have an IR, this stuff is a little messy. */
+static int
+F(int code, int v0, int v1)
+{
+ u_int hash;
+ int val;
+ struct valnode *p;
+
+ hash = (u_int)code ^ (v0 << 4) ^ (v1 << 8);
+ hash %= MODULUS;
+
+ for (p = hashtbl[hash]; p; p = p->next)
+ if (p->code == code && p->v0 == v0 && p->v1 == v1)
+ return p->val;
+
+ val = ++curval;
+ if (BPF_MODE(code) == BPF_IMM &&
+ (BPF_CLASS(code) == BPF_LD || BPF_CLASS(code) == BPF_LDX)) {
+ vmap[val].const_val = v0;
+ vmap[val].is_const = 1;
+ }
+ p = next_vnode++;
+ p->val = val;
+ p->code = code;
+ p->v0 = v0;
+ p->v1 = v1;
+ p->next = hashtbl[hash];
+ hashtbl[hash] = p;
+
+ return val;
+}
+
+static inline void
+vstore(struct stmt *s, int *valp, int newval, int alter)
+{
+ if (alter && *valp == newval)
+ s->code = NOP;
+ else
+ *valp = newval;
+}
+
+static void
+fold_op(struct stmt *s, int v0, int v1)
+{
+ bpf_u_int32 a, b;
+
+ a = vmap[v0].const_val;
+ b = vmap[v1].const_val;
+
+ switch (BPF_OP(s->code)) {
+ case BPF_ADD:
+ a += b;
+ break;
+
+ case BPF_SUB:
+ a -= b;
+ break;
+
+ case BPF_MUL:
+ a *= b;
+ break;
+
+ case BPF_DIV:
+ if (b == 0)
+ bpf_error("division by zero");
+ a /= b;
+ break;
+
+ case BPF_AND:
+ a &= b;
+ break;
+
+ case BPF_OR:
+ a |= b;
+ break;
+
+ case BPF_LSH:
+ a <<= b;
+ break;
+
+ case BPF_RSH:
+ a >>= b;
+ break;
+
+ case BPF_NEG:
+ a = -a;
+ break;
+
+ default:
+ abort();
+ }
+ s->k = a;
+ s->code = BPF_LD|BPF_IMM;
+ done = 0;
+}
+
+static inline struct slist *
+this_op(struct slist *s)
+{
+ while (s != 0 && s->s.code == NOP)
+ s = s->next;
+ return s;
+}
+
+static void
+opt_not(struct block *b)
+{
+ struct block *tmp = JT(b);
+
+ JT(b) = JF(b);
+ JF(b) = tmp;
+}
+
+static void
+opt_peep(struct block *b)
+{
+ struct slist *s;
+ struct slist *next, *last;
+ int val;
+
+ s = b->stmts;
+ if (s == 0)
+ return;
+
+ last = s;
+ for (/*empty*/; /*empty*/; s = next) {
+ /*
+ * Skip over nops.
+ */
+ s = this_op(s);
+ if (s == 0)
+ break; /* nothing left in the block */
+
+ /*
+ * Find the next real instruction after that one
+ * (skipping nops).
+ */
+ next = this_op(s->next);
+ if (next == 0)
+ break; /* no next instruction */
+ last = next;
+
+ /*
+ * st M[k] --> st M[k]
+ * ldx M[k] tax
+ */
+ if (s->s.code == BPF_ST &&
+ next->s.code == (BPF_LDX|BPF_MEM) &&
+ s->s.k == next->s.k) {
+ done = 0;
+ next->s.code = BPF_MISC|BPF_TAX;
+ }
+ /*
+ * ld #k --> ldx #k
+ * tax txa
+ */
+ if (s->s.code == (BPF_LD|BPF_IMM) &&
+ next->s.code == (BPF_MISC|BPF_TAX)) {
+ s->s.code = BPF_LDX|BPF_IMM;
+ next->s.code = BPF_MISC|BPF_TXA;
+ done = 0;
+ }
+ /*
+ * This is an ugly special case, but it happens
+ * when you say tcp[k] or udp[k] where k is a constant.
+ */
+ if (s->s.code == (BPF_LD|BPF_IMM)) {
+ struct slist *add, *tax, *ild;
+
+ /*
+ * Check that X isn't used on exit from this
+ * block (which the optimizer might cause).
+ * We know the code generator won't generate
+ * any local dependencies.
+ */
+ if (ATOMELEM(b->out_use, X_ATOM))
+ continue;
+
+ /*
+ * Check that the instruction following the ldi
+ * is an addx, or it's an ldxms with an addx
+ * following it (with 0 or more nops between the
+ * ldxms and addx).
+ */
+ if (next->s.code != (BPF_LDX|BPF_MSH|BPF_B))
+ add = next;
+ else
+ add = this_op(next->next);
+ if (add == 0 || add->s.code != (BPF_ALU|BPF_ADD|BPF_X))
+ continue;
+
+ /*
+ * Check that a tax follows that (with 0 or more
+ * nops between them).
+ */
+ tax = this_op(add->next);
+ if (tax == 0 || tax->s.code != (BPF_MISC|BPF_TAX))
+ continue;
+
+ /*
+ * Check that an ild follows that (with 0 or more
+ * nops between them).
+ */
+ ild = this_op(tax->next);
+ if (ild == 0 || BPF_CLASS(ild->s.code) != BPF_LD ||
+ BPF_MODE(ild->s.code) != BPF_IND)
+ continue;
+ /*
+ * We want to turn this sequence:
+ *
+ * (004) ldi #0x2 {s}
+ * (005) ldxms [14] {next} -- optional
+ * (006) addx {add}
+ * (007) tax {tax}
+ * (008) ild [x+0] {ild}
+ *
+ * into this sequence:
+ *
+ * (004) nop
+ * (005) ldxms [14]
+ * (006) nop
+ * (007) nop
+ * (008) ild [x+2]
+ *
+ * XXX We need to check that X is not
+ * subsequently used, because we want to change
+ * what'll be in it after this sequence.
+ *
+ * We know we can eliminate the accumulator
+ * modifications earlier in the sequence since
+ * it is defined by the last stmt of this sequence
+ * (i.e., the last statement of the sequence loads
+ * a value into the accumulator, so we can eliminate
+ * earlier operations on the accumulator).
+ */
+ ild->s.k += s->s.k;
+ s->s.code = NOP;
+ add->s.code = NOP;
+ tax->s.code = NOP;
+ done = 0;
+ }
+ }
+ /*
+ * If the comparison at the end of a block is an equality
+ * comparison against a constant, and nobody uses the value
+ * we leave in the A register at the end of a block, and
+ * the operation preceding the comparison is an arithmetic
+ * operation, we can sometime optimize it away.
+ */
+ if (b->s.code == (BPF_JMP|BPF_JEQ|BPF_K) &&
+ !ATOMELEM(b->out_use, A_ATOM)) {
+ /*
+ * We can optimize away certain subtractions of the
+ * X register.
+ */
+ if (last->s.code == (BPF_ALU|BPF_SUB|BPF_X)) {
+ val = b->val[X_ATOM];
+ if (vmap[val].is_const) {
+ /*
+ * If we have a subtract to do a comparison,
+ * and the X register is a known constant,
+ * we can merge this value into the
+ * comparison:
+ *
+ * sub x -> nop
+ * jeq #y jeq #(x+y)
+ */
+ b->s.k += vmap[val].const_val;
+ last->s.code = NOP;
+ done = 0;
+ } else if (b->s.k == 0) {
+ /*
+ * If the X register isn't a constant,
+ * and the comparison in the test is
+ * against 0, we can compare with the
+ * X register, instead:
+ *
+ * sub x -> nop
+ * jeq #0 jeq x
+ */
+ last->s.code = NOP;
+ b->s.code = BPF_JMP|BPF_JEQ|BPF_X;
+ done = 0;
+ }
+ }
+ /*
+ * Likewise, a constant subtract can be simplified:
+ *
+ * sub #x -> nop
+ * jeq #y -> jeq #(x+y)
+ */
+ else if (last->s.code == (BPF_ALU|BPF_SUB|BPF_K)) {
+ last->s.code = NOP;
+ b->s.k += last->s.k;
+ done = 0;
+ }
+ /*
+ * And, similarly, a constant AND can be simplified
+ * if we're testing against 0, i.e.:
+ *
+ * and #k nop
+ * jeq #0 -> jset #k
+ */
+ else if (last->s.code == (BPF_ALU|BPF_AND|BPF_K) &&
+ b->s.k == 0) {
+ b->s.k = last->s.k;
+ b->s.code = BPF_JMP|BPF_K|BPF_JSET;
+ last->s.code = NOP;
+ done = 0;
+ opt_not(b);
+ }
+ }
+ /*
+ * jset #0 -> never
+ * jset #ffffffff -> always
+ */
+ if (b->s.code == (BPF_JMP|BPF_K|BPF_JSET)) {
+ if (b->s.k == 0)
+ JT(b) = JF(b);
+ if (b->s.k == 0xffffffff)
+ JF(b) = JT(b);
+ }
+ /*
+ * If we're comparing against the index register, and the index
+ * register is a known constant, we can just compare against that
+ * constant.
+ */
+ val = b->val[X_ATOM];
+ if (vmap[val].is_const && BPF_SRC(b->s.code) == BPF_X) {
+ bpf_int32 v = vmap[val].const_val;
+ b->s.code &= ~BPF_X;
+ b->s.k = v;
+ }
+ /*
+ * If the accumulator is a known constant, we can compute the
+ * comparison result.
+ */
+ val = b->val[A_ATOM];
+ if (vmap[val].is_const && BPF_SRC(b->s.code) == BPF_K) {
+ bpf_int32 v = vmap[val].const_val;
+ switch (BPF_OP(b->s.code)) {
+
+ case BPF_JEQ:
+ v = v == b->s.k;
+ break;
+
+ case BPF_JGT:
+ v = (unsigned)v > b->s.k;
+ break;
+
+ case BPF_JGE:
+ v = (unsigned)v >= b->s.k;
+ break;
+
+ case BPF_JSET:
+ v &= b->s.k;
+ break;
+
+ default:
+ abort();
+ }
+ if (JF(b) != JT(b))
+ done = 0;
+ if (v)
+ JF(b) = JT(b);
+ else
+ JT(b) = JF(b);
+ }
+}
+
+/*
+ * Compute the symbolic value of expression of 's', and update
+ * anything it defines in the value table 'val'. If 'alter' is true,
+ * do various optimizations. This code would be cleaner if symbolic
+ * evaluation and code transformations weren't folded together.
+ */
+static void
+opt_stmt(struct stmt *s, int val[], int alter)
+{
+ int op;
+ int v;
+
+ switch (s->code) {
+
+ case BPF_LD|BPF_ABS|BPF_W:
+ case BPF_LD|BPF_ABS|BPF_H:
+ case BPF_LD|BPF_ABS|BPF_B:
+ v = F(s->code, s->k, 0L);
+ vstore(s, &val[A_ATOM], v, alter);
+ break;
+
+ case BPF_LD|BPF_IND|BPF_W:
+ case BPF_LD|BPF_IND|BPF_H:
+ case BPF_LD|BPF_IND|BPF_B:
+ v = val[X_ATOM];
+ if (alter && vmap[v].is_const) {
+ s->code = BPF_LD|BPF_ABS|BPF_SIZE(s->code);
+ s->k += vmap[v].const_val;
+ v = F(s->code, s->k, 0L);
+ done = 0;
+ }
+ else
+ v = F(s->code, s->k, v);
+ vstore(s, &val[A_ATOM], v, alter);
+ break;
+
+ case BPF_LD|BPF_LEN:
+ v = F(s->code, 0L, 0L);
+ vstore(s, &val[A_ATOM], v, alter);
+ break;
+
+ case BPF_LD|BPF_IMM:
+ v = K(s->k);
+ vstore(s, &val[A_ATOM], v, alter);
+ break;
+
+ case BPF_LDX|BPF_IMM:
+ v = K(s->k);
+ vstore(s, &val[X_ATOM], v, alter);
+ break;
+
+ case BPF_LDX|BPF_MSH|BPF_B:
+ v = F(s->code, s->k, 0L);
+ vstore(s, &val[X_ATOM], v, alter);
+ break;
+
+ case BPF_ALU|BPF_NEG:
+ if (alter && vmap[val[A_ATOM]].is_const) {
+ s->code = BPF_LD|BPF_IMM;
+ s->k = -vmap[val[A_ATOM]].const_val;
+ val[A_ATOM] = K(s->k);
+ }
+ else
+ val[A_ATOM] = F(s->code, val[A_ATOM], 0L);
+ break;
+
+ case BPF_ALU|BPF_ADD|BPF_K:
+ case BPF_ALU|BPF_SUB|BPF_K:
+ case BPF_ALU|BPF_MUL|BPF_K:
+ case BPF_ALU|BPF_DIV|BPF_K:
+ case BPF_ALU|BPF_AND|BPF_K:
+ case BPF_ALU|BPF_OR|BPF_K:
+ case BPF_ALU|BPF_LSH|BPF_K:
+ case BPF_ALU|BPF_RSH|BPF_K:
+ op = BPF_OP(s->code);
+ if (alter) {
+ if (s->k == 0) {
+ /* don't optimize away "sub #0"
+ * as it may be needed later to
+ * fixup the generated math code */
+ if (op == BPF_ADD ||
+ op == BPF_LSH || op == BPF_RSH ||
+ op == BPF_OR) {
+ s->code = NOP;
+ break;
+ }
+ if (op == BPF_MUL || op == BPF_AND) {
+ s->code = BPF_LD|BPF_IMM;
+ val[A_ATOM] = K(s->k);
+ break;
+ }
+ }
+ if (vmap[val[A_ATOM]].is_const) {
+ fold_op(s, val[A_ATOM], K(s->k));
+ val[A_ATOM] = K(s->k);
+ break;
+ }
+ }
+ val[A_ATOM] = F(s->code, val[A_ATOM], K(s->k));
+ break;
+
+ case BPF_ALU|BPF_ADD|BPF_X:
+ case BPF_ALU|BPF_SUB|BPF_X:
+ case BPF_ALU|BPF_MUL|BPF_X:
+ case BPF_ALU|BPF_DIV|BPF_X:
+ case BPF_ALU|BPF_AND|BPF_X:
+ case BPF_ALU|BPF_OR|BPF_X:
+ case BPF_ALU|BPF_LSH|BPF_X:
+ case BPF_ALU|BPF_RSH|BPF_X:
+ op = BPF_OP(s->code);
+ if (alter && vmap[val[X_ATOM]].is_const) {
+ if (vmap[val[A_ATOM]].is_const) {
+ fold_op(s, val[A_ATOM], val[X_ATOM]);
+ val[A_ATOM] = K(s->k);
+ }
+ else {
+ s->code = BPF_ALU|BPF_K|op;
+ s->k = vmap[val[X_ATOM]].const_val;
+ done = 0;
+ val[A_ATOM] =
+ F(s->code, val[A_ATOM], K(s->k));
+ }
+ break;
+ }
+ /*
+ * Check if we're doing something to an accumulator
+ * that is 0, and simplify. This may not seem like
+ * much of a simplification but it could open up further
+ * optimizations.
+ * XXX We could also check for mul by 1, etc.
+ */
+ if (alter && vmap[val[A_ATOM]].is_const
+ && vmap[val[A_ATOM]].const_val == 0) {
+ if (op == BPF_ADD || op == BPF_OR) {
+ s->code = BPF_MISC|BPF_TXA;
+ vstore(s, &val[A_ATOM], val[X_ATOM], alter);
+ break;
+ }
+ else if (op == BPF_MUL || op == BPF_DIV ||
+ op == BPF_AND || op == BPF_LSH || op == BPF_RSH) {
+ s->code = BPF_LD|BPF_IMM;
+ s->k = 0;
+ vstore(s, &val[A_ATOM], K(s->k), alter);
+ break;
+ }
+ else if (op == BPF_NEG) {
+ s->code = NOP;
+ break;
+ }
+ }
+ val[A_ATOM] = F(s->code, val[A_ATOM], val[X_ATOM]);
+ break;
+
+ case BPF_MISC|BPF_TXA:
+ vstore(s, &val[A_ATOM], val[X_ATOM], alter);
+ break;
+
+ case BPF_LD|BPF_MEM:
+ v = val[s->k];
+ if (alter && vmap[v].is_const) {
+ s->code = BPF_LD|BPF_IMM;
+ s->k = vmap[v].const_val;
+ done = 0;
+ }
+ vstore(s, &val[A_ATOM], v, alter);
+ break;
+
+ case BPF_MISC|BPF_TAX:
+ vstore(s, &val[X_ATOM], val[A_ATOM], alter);
+ break;
+
+ case BPF_LDX|BPF_MEM:
+ v = val[s->k];
+ if (alter && vmap[v].is_const) {
+ s->code = BPF_LDX|BPF_IMM;
+ s->k = vmap[v].const_val;
+ done = 0;
+ }
+ vstore(s, &val[X_ATOM], v, alter);
+ break;
+
+ case BPF_ST:
+ vstore(s, &val[s->k], val[A_ATOM], alter);
+ break;
+
+ case BPF_STX:
+ vstore(s, &val[s->k], val[X_ATOM], alter);
+ break;
+ }
+}
+
+static void
+deadstmt(register struct stmt *s, register struct stmt *last[])
+{
+ register int atom;
+
+ atom = atomuse(s);
+ if (atom >= 0) {
+ if (atom == AX_ATOM) {
+ last[X_ATOM] = 0;
+ last[A_ATOM] = 0;
+ }
+ else
+ last[atom] = 0;
+ }
+ atom = atomdef(s);
+ if (atom >= 0) {
+ if (last[atom]) {
+ done = 0;
+ last[atom]->code = NOP;
+ }
+ last[atom] = s;
+ }
+}
+
+static void
+opt_deadstores(register struct block *b)
+{
+ register struct slist *s;
+ register int atom;
+ struct stmt *last[N_ATOMS];
+
+ memset((char *)last, 0, sizeof last);
+
+ for (s = b->stmts; s != 0; s = s->next)
+ deadstmt(&s->s, last);
+ deadstmt(&b->s, last);
+
+ for (atom = 0; atom < N_ATOMS; ++atom)
+ if (last[atom] && !ATOMELEM(b->out_use, atom)) {
+ last[atom]->code = NOP;
+ done = 0;
+ }
+}
+
+static void
+opt_blk(struct block *b, int do_stmts)
+{
+ struct slist *s;
+ struct edge *p;
+ int i;
+ bpf_int32 aval, xval;
+
+#if 0
+ for (s = b->stmts; s && s->next; s = s->next)
+ if (BPF_CLASS(s->s.code) == BPF_JMP) {
+ do_stmts = 0;
+ break;
+ }
+#endif
+
+ /*
+ * Initialize the atom values.
+ */
+ p = b->in_edges;
+ if (p == 0) {
+ /*
+ * We have no predecessors, so everything is undefined
+ * upon entry to this block.
+ */
+ memset((char *)b->val, 0, sizeof(b->val));
+ } else {
+ /*
+ * Inherit values from our predecessors.
+ *
+ * First, get the values from the predecessor along the
+ * first edge leading to this node.
+ */
+ memcpy((char *)b->val, (char *)p->pred->val, sizeof(b->val));
+ /*
+ * Now look at all the other nodes leading to this node.
+ * If, for the predecessor along that edge, a register
+ * has a different value from the one we have (i.e.,
+ * control paths are merging, and the merging paths
+ * assign different values to that register), give the
+ * register the undefined value of 0.
+ */
+ while ((p = p->next) != NULL) {
+ for (i = 0; i < N_ATOMS; ++i)
+ if (b->val[i] != p->pred->val[i])
+ b->val[i] = 0;
+ }
+ }
+ aval = b->val[A_ATOM];
+ xval = b->val[X_ATOM];
+ for (s = b->stmts; s; s = s->next)
+ opt_stmt(&s->s, b->val, do_stmts);
+
+ /*
+ * This is a special case: if we don't use anything from this
+ * block, and we load the accumulator or index register with a
+ * value that is already there, or if this block is a return,
+ * eliminate all the statements.
+ *
+ * XXX - what if it does a store?
+ *
+ * XXX - why does it matter whether we use anything from this
+ * block? If the accumulator or index register doesn't change
+ * its value, isn't that OK even if we use that value?
+ *
+ * XXX - if we load the accumulator with a different value,
+ * and the block ends with a conditional branch, we obviously
+ * can't eliminate it, as the branch depends on that value.
+ * For the index register, the conditional branch only depends
+ * on the index register value if the test is against the index
+ * register value rather than a constant; if nothing uses the
+ * value we put into the index register, and we're not testing
+ * against the index register's value, and there aren't any
+ * other problems that would keep us from eliminating this
+ * block, can we eliminate it?
+ */
+ if (do_stmts &&
+ ((b->out_use == 0 && aval != 0 && b->val[A_ATOM] == aval &&
+ xval != 0 && b->val[X_ATOM] == xval) ||
+ BPF_CLASS(b->s.code) == BPF_RET)) {
+ if (b->stmts != 0) {
+ b->stmts = 0;
+ done = 0;
+ }
+ } else {
+ opt_peep(b);
+ opt_deadstores(b);
+ }
+ /*
+ * Set up values for branch optimizer.
+ */
+ if (BPF_SRC(b->s.code) == BPF_K)
+ b->oval = K(b->s.k);
+ else
+ b->oval = b->val[X_ATOM];
+ b->et.code = b->s.code;
+ b->ef.code = -b->s.code;
+}
+
+/*
+ * Return true if any register that is used on exit from 'succ', has
+ * an exit value that is different from the corresponding exit value
+ * from 'b'.
+ */
+static int
+use_conflict(struct block *b, struct block *succ)
+{
+ int atom;
+ atomset use = succ->out_use;
+
+ if (use == 0)
+ return 0;
+
+ for (atom = 0; atom < N_ATOMS; ++atom)
+ if (ATOMELEM(use, atom))
+ if (b->val[atom] != succ->val[atom])
+ return 1;
+ return 0;
+}
+
+static struct block *
+fold_edge(struct block *child, struct edge *ep)
+{
+ int sense;
+ int aval0, aval1, oval0, oval1;
+ int code = ep->code;
+
+ if (code < 0) {
+ code = -code;
+ sense = 0;
+ } else
+ sense = 1;
+
+ if (child->s.code != code)
+ return 0;
+
+ aval0 = child->val[A_ATOM];
+ oval0 = child->oval;
+ aval1 = ep->pred->val[A_ATOM];
+ oval1 = ep->pred->oval;
+
+ if (aval0 != aval1)
+ return 0;
+
+ if (oval0 == oval1)
+ /*
+ * The operands of the branch instructions are
+ * identical, so the result is true if a true
+ * branch was taken to get here, otherwise false.
+ */
+ return sense ? JT(child) : JF(child);
+
+ if (sense && code == (BPF_JMP|BPF_JEQ|BPF_K))
+ /*
+ * At this point, we only know the comparison if we
+ * came down the true branch, and it was an equality
+ * comparison with a constant.
+ *
+ * I.e., if we came down the true branch, and the branch
+ * was an equality comparison with a constant, we know the
+ * accumulator contains that constant. If we came down
+ * the false branch, or the comparison wasn't with a
+ * constant, we don't know what was in the accumulator.
+ *
+ * We rely on the fact that distinct constants have distinct
+ * value numbers.
+ */
+ return JF(child);
+
+ return 0;
+}
+
+static void
+opt_j(struct edge *ep)
+{
+ register int i, k;
+ register struct block *target;
+
+ if (JT(ep->succ) == 0)
+ return;
+
+ if (JT(ep->succ) == JF(ep->succ)) {
+ /*
+ * Common branch targets can be eliminated, provided
+ * there is no data dependency.
+ */
+ if (!use_conflict(ep->pred, ep->succ->et.succ)) {
+ done = 0;
+ ep->succ = JT(ep->succ);
+ }
+ }
+ /*
+ * For each edge dominator that matches the successor of this
+ * edge, promote the edge successor to the its grandchild.
+ *
+ * XXX We violate the set abstraction here in favor a reasonably
+ * efficient loop.
+ */
+ top:
+ for (i = 0; i < edgewords; ++i) {
+ register bpf_u_int32 x = ep->edom[i];
+
+ while (x != 0) {
+ k = ffs(x) - 1;
+ x &=~ (1 << k);
+ k += i * BITS_PER_WORD;
+
+ target = fold_edge(ep->succ, edges[k]);
+ /*
+ * Check that there is no data dependency between
+ * nodes that will be violated if we move the edge.
+ */
+ if (target != 0 && !use_conflict(ep->pred, target)) {
+ done = 0;
+ ep->succ = target;
+ if (JT(target) != 0)
+ /*
+ * Start over unless we hit a leaf.
+ */
+ goto top;
+ return;
+ }
+ }
+ }
+}
+
+
+static void
+or_pullup(struct block *b)
+{
+ int val, at_top;
+ struct block *pull;
+ struct block **diffp, **samep;
+ struct edge *ep;
+
+ ep = b->in_edges;
+ if (ep == 0)
+ return;
+
+ /*
+ * Make sure each predecessor loads the same value.
+ * XXX why?
+ */
+ val = ep->pred->val[A_ATOM];
+ for (ep = ep->next; ep != 0; ep = ep->next)
+ if (val != ep->pred->val[A_ATOM])
+ return;
+
+ if (JT(b->in_edges->pred) == b)
+ diffp = &JT(b->in_edges->pred);
+ else
+ diffp = &JF(b->in_edges->pred);
+
+ at_top = 1;
+ while (1) {
+ if (*diffp == 0)
+ return;
+
+ if (JT(*diffp) != JT(b))
+ return;
+
+ if (!SET_MEMBER((*diffp)->dom, b->id))
+ return;
+
+ if ((*diffp)->val[A_ATOM] != val)
+ break;
+
+ diffp = &JF(*diffp);
+ at_top = 0;
+ }
+ samep = &JF(*diffp);
+ while (1) {
+ if (*samep == 0)
+ return;
+
+ if (JT(*samep) != JT(b))
+ return;
+
+ if (!SET_MEMBER((*samep)->dom, b->id))
+ return;
+
+ if ((*samep)->val[A_ATOM] == val)
+ break;
+
+ /* XXX Need to check that there are no data dependencies
+ between dp0 and dp1. Currently, the code generator
+ will not produce such dependencies. */
+ samep = &JF(*samep);
+ }
+#ifdef notdef
+ /* XXX This doesn't cover everything. */
+ for (i = 0; i < N_ATOMS; ++i)
+ if ((*samep)->val[i] != pred->val[i])
+ return;
+#endif
+ /* Pull up the node. */
+ pull = *samep;
+ *samep = JF(pull);
+ JF(pull) = *diffp;
+
+ /*
+ * At the top of the chain, each predecessor needs to point at the
+ * pulled up node. Inside the chain, there is only one predecessor
+ * to worry about.
+ */
+ if (at_top) {
+ for (ep = b->in_edges; ep != 0; ep = ep->next) {
+ if (JT(ep->pred) == b)
+ JT(ep->pred) = pull;
+ else
+ JF(ep->pred) = pull;
+ }
+ }
+ else
+ *diffp = pull;
+
+ done = 0;
+}
+
+static void
+and_pullup(struct block *b)
+{
+ int val, at_top;
+ struct block *pull;
+ struct block **diffp, **samep;
+ struct edge *ep;
+
+ ep = b->in_edges;
+ if (ep == 0)
+ return;
+
+ /*
+ * Make sure each predecessor loads the same value.
+ */
+ val = ep->pred->val[A_ATOM];
+ for (ep = ep->next; ep != 0; ep = ep->next)
+ if (val != ep->pred->val[A_ATOM])
+ return;
+
+ if (JT(b->in_edges->pred) == b)
+ diffp = &JT(b->in_edges->pred);
+ else
+ diffp = &JF(b->in_edges->pred);
+
+ at_top = 1;
+ while (1) {
+ if (*diffp == 0)
+ return;
+
+ if (JF(*diffp) != JF(b))
+ return;
+
+ if (!SET_MEMBER((*diffp)->dom, b->id))
+ return;
+
+ if ((*diffp)->val[A_ATOM] != val)
+ break;
+
+ diffp = &JT(*diffp);
+ at_top = 0;
+ }
+ samep = &JT(*diffp);
+ while (1) {
+ if (*samep == 0)
+ return;
+
+ if (JF(*samep) != JF(b))
+ return;
+
+ if (!SET_MEMBER((*samep)->dom, b->id))
+ return;
+
+ if ((*samep)->val[A_ATOM] == val)
+ break;
+
+ /* XXX Need to check that there are no data dependencies
+ between diffp and samep. Currently, the code generator
+ will not produce such dependencies. */
+ samep = &JT(*samep);
+ }
+#ifdef notdef
+ /* XXX This doesn't cover everything. */
+ for (i = 0; i < N_ATOMS; ++i)
+ if ((*samep)->val[i] != pred->val[i])
+ return;
+#endif
+ /* Pull up the node. */
+ pull = *samep;
+ *samep = JT(pull);
+ JT(pull) = *diffp;
+
+ /*
+ * At the top of the chain, each predecessor needs to point at the
+ * pulled up node. Inside the chain, there is only one predecessor
+ * to worry about.
+ */
+ if (at_top) {
+ for (ep = b->in_edges; ep != 0; ep = ep->next) {
+ if (JT(ep->pred) == b)
+ JT(ep->pred) = pull;
+ else
+ JF(ep->pred) = pull;
+ }
+ }
+ else
+ *diffp = pull;
+
+ done = 0;
+}
+
+static void
+opt_blks(struct block *root, int do_stmts)
+{
+ int i, maxlevel;
+ struct block *p;
+
+ init_val();
+ maxlevel = root->level;
+
+ find_inedges(root);
+ for (i = maxlevel; i >= 0; --i)
+ for (p = levels[i]; p; p = p->link)
+ opt_blk(p, do_stmts);
+
+ if (do_stmts)
+ /*
+ * No point trying to move branches; it can't possibly
+ * make a difference at this point.
+ */
+ return;
+
+ for (i = 1; i <= maxlevel; ++i) {
+ for (p = levels[i]; p; p = p->link) {
+ opt_j(&p->et);
+ opt_j(&p->ef);
+ }
+ }
+
+ find_inedges(root);
+ for (i = 1; i <= maxlevel; ++i) {
+ for (p = levels[i]; p; p = p->link) {
+ or_pullup(p);
+ and_pullup(p);
+ }
+ }
+}
+
+static inline void
+link_inedge(struct edge *parent, struct block *child)
+{
+ parent->next = child->in_edges;
+ child->in_edges = parent;
+}
+
+static void
+find_inedges(struct block *root)
+{
+ int i;
+ struct block *b;
+
+ for (i = 0; i < n_blocks; ++i)
+ blocks[i]->in_edges = 0;
+
+ /*
+ * Traverse the graph, adding each edge to the predecessor
+ * list of its successors. Skip the leaves (i.e. level 0).
+ */
+ for (i = root->level; i > 0; --i) {
+ for (b = levels[i]; b != 0; b = b->link) {
+ link_inedge(&b->et, JT(b));
+ link_inedge(&b->ef, JF(b));
+ }
+ }
+}
+
+static void
+opt_root(struct block **b)
+{
+ struct slist *tmp, *s;
+
+ s = (*b)->stmts;
+ (*b)->stmts = 0;
+ while (BPF_CLASS((*b)->s.code) == BPF_JMP && JT(*b) == JF(*b))
+ *b = JT(*b);
+
+ tmp = (*b)->stmts;
+ if (tmp != 0)
+ sappend(s, tmp);
+ (*b)->stmts = s;
+
+ /*
+ * If the root node is a return, then there is no
+ * point executing any statements (since the bpf machine
+ * has no side effects).
+ */
+ if (BPF_CLASS((*b)->s.code) == BPF_RET)
+ (*b)->stmts = 0;
+}
+
+static void
+opt_loop(struct block *root, int do_stmts)
+{
+
+#ifdef BDEBUG
+ if (dflag > 1) {
+ printf("opt_loop(root, %d) begin\n", do_stmts);
+ opt_dump(root);
+ }
+#endif
+ do {
+ done = 1;
+ find_levels(root);
+ find_dom(root);
+ find_closure(root);
+ find_ud(root);
+ find_edom(root);
+ opt_blks(root, do_stmts);
+#ifdef BDEBUG
+ if (dflag > 1) {
+ printf("opt_loop(root, %d) bottom, done=%d\n", do_stmts, done);
+ opt_dump(root);
+ }
+#endif
+ } while (!done);
+}
+
+/*
+ * Optimize the filter code in its dag representation.
+ */
+void
+bpf_optimize(struct block **rootp)
+{
+ struct block *root;
+
+ root = *rootp;
+
+ opt_init(root);
+ opt_loop(root, 0);
+ opt_loop(root, 1);
+ intern_blocks(root);
+#ifdef BDEBUG
+ if (dflag > 1) {
+ printf("after intern_blocks()\n");
+ opt_dump(root);
+ }
+#endif
+ opt_root(rootp);
+#ifdef BDEBUG
+ if (dflag > 1) {
+ printf("after opt_root()\n");
+ opt_dump(root);
+ }
+#endif
+ opt_cleanup();
+}
+
+static void
+make_marks(struct block *p)
+{
+ if (!isMarked(p)) {
+ Mark(p);
+ if (BPF_CLASS(p->s.code) != BPF_RET) {
+ make_marks(JT(p));
+ make_marks(JF(p));
+ }
+ }
+}
+
+/*
+ * Mark code array such that isMarked(i) is true
+ * only for nodes that are alive.
+ */
+static void
+mark_code(struct block *p)
+{
+ cur_mark += 1;
+ make_marks(p);
+}
+
+/*
+ * True iff the two stmt lists load the same value from the packet into
+ * the accumulator.
+ */
+static int
+eq_slist(struct slist *x, struct slist *y)
+{
+ while (1) {
+ while (x && x->s.code == NOP)
+ x = x->next;
+ while (y && y->s.code == NOP)
+ y = y->next;
+ if (x == 0)
+ return y == 0;
+ if (y == 0)
+ return x == 0;
+ if (x->s.code != y->s.code || x->s.k != y->s.k)
+ return 0;
+ x = x->next;
+ y = y->next;
+ }
+}
+
+static inline int
+eq_blk(struct block *b0, struct block *b1)
+{
+ if (b0->s.code == b1->s.code &&
+ b0->s.k == b1->s.k &&
+ b0->et.succ == b1->et.succ &&
+ b0->ef.succ == b1->ef.succ)
+ return eq_slist(b0->stmts, b1->stmts);
+ return 0;
+}
+
+static void
+intern_blocks(struct block *root)
+{
+ struct block *p;
+ int i, j;
+ int done1; /* don't shadow global */
+ top:
+ done1 = 1;
+ for (i = 0; i < n_blocks; ++i)
+ blocks[i]->link = 0;
+
+ mark_code(root);
+
+ for (i = n_blocks - 1; --i >= 0; ) {
+ if (!isMarked(blocks[i]))
+ continue;
+ for (j = i + 1; j < n_blocks; ++j) {
+ if (!isMarked(blocks[j]))
+ continue;
+ if (eq_blk(blocks[i], blocks[j])) {
+ blocks[i]->link = blocks[j]->link ?
+ blocks[j]->link : blocks[j];
+ break;
+ }
+ }
+ }
+ for (i = 0; i < n_blocks; ++i) {
+ p = blocks[i];
+ if (JT(p) == 0)
+ continue;
+ if (JT(p)->link) {
+ done1 = 0;
+ JT(p) = JT(p)->link;
+ }
+ if (JF(p)->link) {
+ done1 = 0;
+ JF(p) = JF(p)->link;
+ }
+ }
+ if (!done1)
+ goto top;
+}
+
+static void
+opt_cleanup(void)
+{
+ free((void *)vnode_base);
+ free((void *)vmap);
+ free((void *)edges);
+ free((void *)space);
+ free((void *)levels);
+ free((void *)blocks);
+}
+
+/*
+ * Return the number of stmts in 's'.
+ */
+static u_int
+slength(struct slist *s)
+{
+ u_int n = 0;
+
+ for (; s; s = s->next)
+ if (s->s.code != NOP)
+ ++n;
+ return n;
+}
+
+/*
+ * Return the number of nodes reachable by 'p'.
+ * All nodes should be initially unmarked.
+ */
+static int
+count_blocks(struct block *p)
+{
+ if (p == 0 || isMarked(p))
+ return 0;
+ Mark(p);
+ return count_blocks(JT(p)) + count_blocks(JF(p)) + 1;
+}
+
+/*
+ * Do a depth first search on the flow graph, numbering the
+ * the basic blocks, and entering them into the 'blocks' array.`
+ */
+static void
+number_blks_r(struct block *p)
+{
+ int n;
+
+ if (p == 0 || isMarked(p))
+ return;
+
+ Mark(p);
+ n = n_blocks++;
+ p->id = n;
+ blocks[n] = p;
+
+ number_blks_r(JT(p));
+ number_blks_r(JF(p));
+}
+
+/*
+ * Return the number of stmts in the flowgraph reachable by 'p'.
+ * The nodes should be unmarked before calling.
+ *
+ * Note that "stmts" means "instructions", and that this includes
+ *
+ * side-effect statements in 'p' (slength(p->stmts));
+ *
+ * statements in the true branch from 'p' (count_stmts(JT(p)));
+ *
+ * statements in the false branch from 'p' (count_stmts(JF(p)));
+ *
+ * the conditional jump itself (1);
+ *
+ * an extra long jump if the true branch requires it (p->longjt);
+ *
+ * an extra long jump if the false branch requires it (p->longjf).
+ */
+static u_int
+count_stmts(struct block *p)
+{
+ u_int n;
+
+ if (p == 0 || isMarked(p))
+ return 0;
+ Mark(p);
+ n = count_stmts(JT(p)) + count_stmts(JF(p));
+ return slength(p->stmts) + n + 1 + p->longjt + p->longjf;
+}
+
+/*
+ * Allocate memory. All allocation is done before optimization
+ * is begun. A linear bound on the size of all data structures is computed
+ * from the total number of blocks and/or statements.
+ */
+static void
+opt_init(struct block *root)
+{
+ bpf_u_int32 *p;
+ int i, n, max_stmts;
+
+ /*
+ * First, count the blocks, so we can malloc an array to map
+ * block number to block. Then, put the blocks into the array.
+ */
+ unMarkAll();
+ n = count_blocks(root);
+ blocks = (struct block **)calloc(n, sizeof(*blocks));
+ if (blocks == NULL)
+ bpf_error("malloc");
+ unMarkAll();
+ n_blocks = 0;
+ number_blks_r(root);
+
+ n_edges = 2 * n_blocks;
+ edges = (struct edge **)calloc(n_edges, sizeof(*edges));
+ if (edges == NULL)
+ bpf_error("malloc");
+
+ /*
+ * The number of levels is bounded by the number of nodes.
+ */
+ levels = (struct block **)calloc(n_blocks, sizeof(*levels));
+ if (levels == NULL)
+ bpf_error("malloc");
+
+ edgewords = n_edges / (8 * sizeof(bpf_u_int32)) + 1;
+ nodewords = n_blocks / (8 * sizeof(bpf_u_int32)) + 1;
+
+ /* XXX */
+ space = (bpf_u_int32 *)malloc(2 * n_blocks * nodewords * sizeof(*space)
+ + n_edges * edgewords * sizeof(*space));
+ if (space == NULL)
+ bpf_error("malloc");
+ p = space;
+ all_dom_sets = p;
+ for (i = 0; i < n; ++i) {
+ blocks[i]->dom = p;
+ p += nodewords;
+ }
+ all_closure_sets = p;
+ for (i = 0; i < n; ++i) {
+ blocks[i]->closure = p;
+ p += nodewords;
+ }
+ all_edge_sets = p;
+ for (i = 0; i < n; ++i) {
+ register struct block *b = blocks[i];
+
+ b->et.edom = p;
+ p += edgewords;
+ b->ef.edom = p;
+ p += edgewords;
+ b->et.id = i;
+ edges[i] = &b->et;
+ b->ef.id = n_blocks + i;
+ edges[n_blocks + i] = &b->ef;
+ b->et.pred = b;
+ b->ef.pred = b;
+ }
+ max_stmts = 0;
+ for (i = 0; i < n; ++i)
+ max_stmts += slength(blocks[i]->stmts) + 1;
+ /*
+ * We allocate at most 3 value numbers per statement,
+ * so this is an upper bound on the number of valnodes
+ * we'll need.
+ */
+ maxval = 3 * max_stmts;
+ vmap = (struct vmapinfo *)calloc(maxval, sizeof(*vmap));
+ vnode_base = (struct valnode *)calloc(maxval, sizeof(*vnode_base));
+ if (vmap == NULL || vnode_base == NULL)
+ bpf_error("malloc");
+}
+
+/*
+ * Some pointers used to convert the basic block form of the code,
+ * into the array form that BPF requires. 'fstart' will point to
+ * the malloc'd array while 'ftail' is used during the recursive traversal.
+ */
+static struct bpf_insn *fstart;
+static struct bpf_insn *ftail;
+
+#ifdef BDEBUG
+int bids[1000];
+#endif
+
+/*
+ * Returns true if successful. Returns false if a branch has
+ * an offset that is too large. If so, we have marked that
+ * branch so that on a subsequent iteration, it will be treated
+ * properly.
+ */
+static int
+convert_code_r(struct block *p)
+{
+ struct bpf_insn *dst;
+ struct slist *src;
+ int slen;
+ u_int off;
+ int extrajmps; /* number of extra jumps inserted */
+ struct slist **offset = NULL;
+
+ if (p == 0 || isMarked(p))
+ return (1);
+ Mark(p);
+
+ if (convert_code_r(JF(p)) == 0)
+ return (0);
+ if (convert_code_r(JT(p)) == 0)
+ return (0);
+
+ slen = slength(p->stmts);
+ dst = ftail -= (slen + 1 + p->longjt + p->longjf);
+ /* inflate length by any extra jumps */
+
+ p->offset = dst - fstart;
+
+ /* generate offset[] for convenience */
+ if (slen) {
+ offset = (struct slist **)calloc(slen, sizeof(struct slist *));
+ if (!offset) {
+ bpf_error("not enough core");
+ /*NOTREACHED*/
+ }
+ }
+ src = p->stmts;
+ for (off = 0; off < slen && src; off++) {
+#if 0
+ printf("off=%d src=%x\n", off, src);
+#endif
+ offset[off] = src;
+ src = src->next;
+ }
+
+ off = 0;
+ for (src = p->stmts; src; src = src->next) {
+ if (src->s.code == NOP)
+ continue;
+ dst->code = (u_short)src->s.code;
+ dst->k = src->s.k;
+
+ /* fill block-local relative jump */
+ if (BPF_CLASS(src->s.code) != BPF_JMP || src->s.code == (BPF_JMP|BPF_JA)) {
+#if 0
+ if (src->s.jt || src->s.jf) {
+ bpf_error("illegal jmp destination");
+ /*NOTREACHED*/
+ }
+#endif
+ goto filled;
+ }
+ if (off == slen - 2) /*???*/
+ goto filled;
+
+ {
+ int i;
+ int jt, jf;
+ const char *ljerr = "%s for block-local relative jump: off=%d";
+
+#if 0
+ printf("code=%x off=%d %x %x\n", src->s.code,
+ off, src->s.jt, src->s.jf);
+#endif
+
+ if (!src->s.jt || !src->s.jf) {
+ bpf_error(ljerr, "no jmp destination", off);
+ /*NOTREACHED*/
+ }
+
+ jt = jf = 0;
+ for (i = 0; i < slen; i++) {
+ if (offset[i] == src->s.jt) {
+ if (jt) {
+ bpf_error(ljerr, "multiple matches", off);
+ /*NOTREACHED*/
+ }
+
+ dst->jt = i - off - 1;
+ jt++;
+ }
+ if (offset[i] == src->s.jf) {
+ if (jf) {
+ bpf_error(ljerr, "multiple matches", off);
+ /*NOTREACHED*/
+ }
+ dst->jf = i - off - 1;
+ jf++;
+ }
+ }
+ if (!jt || !jf) {
+ bpf_error(ljerr, "no destination found", off);
+ /*NOTREACHED*/
+ }
+ }
+filled:
+ ++dst;
+ ++off;
+ }
+ if (offset)
+ free(offset);
+
+#ifdef BDEBUG
+ bids[dst - fstart] = p->id + 1;
+#endif
+ dst->code = (u_short)p->s.code;
+ dst->k = p->s.k;
+ if (JT(p)) {
+ extrajmps = 0;
+ off = JT(p)->offset - (p->offset + slen) - 1;
+ if (off >= 256) {
+ /* offset too large for branch, must add a jump */
+ if (p->longjt == 0) {
+ /* mark this instruction and retry */
+ p->longjt++;
+ return(0);
+ }
+ /* branch if T to following jump */
+ dst->jt = extrajmps;
+ extrajmps++;
+ dst[extrajmps].code = BPF_JMP|BPF_JA;
+ dst[extrajmps].k = off - extrajmps;
+ }
+ else
+ dst->jt = off;
+ off = JF(p)->offset - (p->offset + slen) - 1;
+ if (off >= 256) {
+ /* offset too large for branch, must add a jump */
+ if (p->longjf == 0) {
+ /* mark this instruction and retry */
+ p->longjf++;
+ return(0);
+ }
+ /* branch if F to following jump */
+ /* if two jumps are inserted, F goes to second one */
+ dst->jf = extrajmps;
+ extrajmps++;
+ dst[extrajmps].code = BPF_JMP|BPF_JA;
+ dst[extrajmps].k = off - extrajmps;
+ }
+ else
+ dst->jf = off;
+ }
+ return (1);
+}
+
+
+/*
+ * Convert flowgraph intermediate representation to the
+ * BPF array representation. Set *lenp to the number of instructions.
+ *
+ * This routine does *NOT* leak the memory pointed to by fp. It *must
+ * not* do free(fp) before returning fp; doing so would make no sense,
+ * as the BPF array pointed to by the return value of icode_to_fcode()
+ * must be valid - it's being returned for use in a bpf_program structure.
+ *
+ * If it appears that icode_to_fcode() is leaking, the problem is that
+ * the program using pcap_compile() is failing to free the memory in
+ * the BPF program when it's done - the leak is in the program, not in
+ * the routine that happens to be allocating the memory. (By analogy, if
+ * a program calls fopen() without ever calling fclose() on the FILE *,
+ * it will leak the FILE structure; the leak is not in fopen(), it's in
+ * the program.) Change the program to use pcap_freecode() when it's
+ * done with the filter program. See the pcap man page.
+ */
+struct bpf_insn *
+icode_to_fcode(struct block *root, u_int *lenp)
+{
+ u_int n;
+ struct bpf_insn *fp;
+
+ /*
+ * Loop doing convert_code_r() until no branches remain
+ * with too-large offsets.
+ */
+ while (1) {
+ unMarkAll();
+ n = *lenp = count_stmts(root);
+
+ fp = (struct bpf_insn *)malloc(sizeof(*fp) * n);
+ if (fp == NULL)
+ bpf_error("malloc");
+ memset((char *)fp, 0, sizeof(*fp) * n);
+ fstart = fp;
+ ftail = fp + n;
+
+ unMarkAll();
+ if (convert_code_r(root))
+ break;
+ free(fp);
+ }
+
+ return fp;
+}
+
+/*
+ * Make a copy of a BPF program and put it in the "fcode" member of
+ * a "pcap_t".
+ *
+ * If we fail to allocate memory for the copy, fill in the "errbuf"
+ * member of the "pcap_t" with an error message, and return -1;
+ * otherwise, return 0.
+ */
+int
+install_bpf_program(pcap_t *p, struct bpf_program *fp)
+{
+ size_t prog_size;
+
+ /*
+ * Validate the program.
+ */
+ if (!bpf_validate(fp->bf_insns, fp->bf_len)) {
+ snprintf(p->errbuf, sizeof(p->errbuf),
+ "BPF program is not valid");
+ return (-1);
+ }
+
+ /*
+ * Free up any already installed program.
+ */
+ pcap_freecode(&p->fcode);
+
+ prog_size = sizeof(*fp->bf_insns) * fp->bf_len;
+ p->fcode.bf_len = fp->bf_len;
+ p->fcode.bf_insns = (struct bpf_insn *)malloc(prog_size);
+ if (p->fcode.bf_insns == NULL) {
+ snprintf(p->errbuf, sizeof(p->errbuf),
+ "malloc: %s", pcap_strerror(errno));
+ return (-1);
+ }
+ memcpy(p->fcode.bf_insns, fp->bf_insns, prog_size);
+ return (0);
+}
+
+#ifdef BDEBUG
+static void
+opt_dump(struct block *root)
+{
+ struct bpf_program f;
+
+ memset(bids, 0, sizeof bids);
+ f.bf_insns = icode_to_fcode(root, &f.bf_len);
+ bpf_dump(&f, 1);
+ putchar('\n');
+ free((char *)f.bf_insns);
+}
+#endif
diff --git a/freebsd/contrib/libpcap/pcap-bpf.c b/freebsd/contrib/libpcap/pcap-bpf.c
new file mode 100644
index 00000000..0a942601
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap-bpf.c
@@ -0,0 +1,2719 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1998
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/pcap-bpf.c,v 1.116 2008-09-16 18:42:29 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <rtems/bsd/sys/param.h> /* optionally get BSD define */
+#ifdef HAVE_ZEROCOPY_BPF
+#include <sys/mman.h>
+#endif
+#include <sys/socket.h>
+#include <time.h>
+/*
+ * <net/bpf.h> defines ioctls, but doesn't include <sys/ioccom.h>.
+ *
+ * We include <sys/ioctl.h> as it might be necessary to declare ioctl();
+ * at least on *BSD and Mac OS X, it also defines various SIOC ioctls -
+ * we could include <sys/sockio.h>, but if we're already including
+ * <sys/ioctl.h>, which includes <sys/sockio.h> on those platforms,
+ * there's not much point in doing so.
+ *
+ * If we have <sys/ioccom.h>, we include it as well, to handle systems
+ * such as Solaris which don't arrange to include <sys/ioccom.h> if you
+ * include <sys/ioctl.h>
+ */
+#include <sys/ioctl.h>
+#ifdef HAVE_SYS_IOCCOM_H
+#include <sys/ioccom.h>
+#endif
+#include <sys/utsname.h>
+
+#ifdef HAVE_ZEROCOPY_BPF
+#include <machine/atomic.h>
+#endif
+
+#include <net/if.h>
+
+#ifdef _AIX
+
+/*
+ * Make "pcap.h" not include "pcap/bpf.h"; we are going to include the
+ * native OS version, as we need "struct bpf_config" from it.
+ */
+#define PCAP_DONT_INCLUDE_PCAP_BPF_H
+
+#include <rtems/bsd/sys/types.h>
+
+/*
+ * Prevent bpf.h from redefining the DLT_ values to their
+ * IFT_ values, as we're going to return the standard libpcap
+ * values, not IBM's non-standard IFT_ values.
+ */
+#undef _AIX
+#include <net/bpf.h>
+#define _AIX
+
+#include <net/if_types.h> /* for IFT_ values */
+#include <sys/sysconfig.h>
+#include <sys/device.h>
+#include <sys/cfgodm.h>
+#include <cf.h>
+
+#ifdef __64BIT__
+#define domakedev makedev64
+#define getmajor major64
+#define bpf_hdr bpf_hdr32
+#else /* __64BIT__ */
+#define domakedev makedev
+#define getmajor major
+#endif /* __64BIT__ */
+
+#define BPF_NAME "bpf"
+#define BPF_MINORS 4
+#define DRIVER_PATH "/usr/lib/drivers"
+#define BPF_NODE "/dev/bpf"
+static int bpfloadedflag = 0;
+static int odmlockid = 0;
+
+static int bpf_load(char *errbuf);
+
+#else /* _AIX */
+
+#include <net/bpf.h>
+
+#endif /* _AIX */
+
+#include <ctype.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#ifdef HAVE_NET_IF_MEDIA_H
+# include <net/if_media.h>
+#endif
+
+#include "pcap-int.h"
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#ifdef BIOCGDLTLIST
+# if (defined(HAVE_NET_IF_MEDIA_H) && defined(IFM_IEEE80211)) && !defined(__APPLE__)
+#define HAVE_BSD_IEEE80211
+# endif
+
+# if defined(__APPLE__) || defined(HAVE_BSD_IEEE80211)
+static int find_802_11(struct bpf_dltlist *);
+
+# ifdef HAVE_BSD_IEEE80211
+static int monitor_mode(pcap_t *, int);
+# endif
+
+# if defined(__APPLE__)
+static void remove_en(pcap_t *);
+static void remove_802_11(pcap_t *);
+# endif
+
+# endif /* defined(__APPLE__) || defined(HAVE_BSD_IEEE80211) */
+
+#endif /* BIOCGDLTLIST */
+
+#if defined(sun) && defined(LIFNAMSIZ) && defined(lifr_zoneid)
+#include <zone.h>
+#endif
+
+/*
+ * We include the OS's <net/bpf.h>, not our "pcap/bpf.h", so we probably
+ * don't get DLT_DOCSIS defined.
+ */
+#ifndef DLT_DOCSIS
+#define DLT_DOCSIS 143
+#endif
+
+/*
+ * On OS X, we don't even get any of the 802.11-plus-radio-header DLT_'s
+ * defined, even though some of them are used by various Airport drivers.
+ */
+#ifndef DLT_PRISM_HEADER
+#define DLT_PRISM_HEADER 119
+#endif
+#ifndef DLT_AIRONET_HEADER
+#define DLT_AIRONET_HEADER 120
+#endif
+#ifndef DLT_IEEE802_11_RADIO
+#define DLT_IEEE802_11_RADIO 127
+#endif
+#ifndef DLT_IEEE802_11_RADIO_AVS
+#define DLT_IEEE802_11_RADIO_AVS 163
+#endif
+
+static int pcap_can_set_rfmon_bpf(pcap_t *p);
+static int pcap_activate_bpf(pcap_t *p);
+static int pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp);
+static int pcap_setdirection_bpf(pcap_t *, pcap_direction_t);
+static int pcap_set_datalink_bpf(pcap_t *p, int dlt);
+
+/*
+ * For zerocopy bpf, the setnonblock/getnonblock routines need to modify
+ * p->md.timeout so we don't call select(2) if the pcap handle is in non-
+ * blocking mode. We preserve the timeout supplied by pcap_open functions
+ * to make sure it does not get clobbered if the pcap handle moves between
+ * blocking and non-blocking mode.
+ */
+static int
+pcap_getnonblock_bpf(pcap_t *p, char *errbuf)
+{
+#ifdef HAVE_ZEROCOPY_BPF
+ if (p->md.zerocopy) {
+ /*
+ * Use a negative value for the timeout to represent that the
+ * pcap handle is in non-blocking mode.
+ */
+ return (p->md.timeout < 0);
+ }
+#endif
+ return (pcap_getnonblock_fd(p, errbuf));
+}
+
+static int
+pcap_setnonblock_bpf(pcap_t *p, int nonblock, char *errbuf)
+{
+#ifdef HAVE_ZEROCOPY_BPF
+ if (p->md.zerocopy) {
+ /*
+ * Map each value to their corresponding negation to
+ * preserve the timeout value provided with pcap_set_timeout.
+ * (from pcap-linux.c).
+ */
+ if (nonblock) {
+ if (p->md.timeout >= 0) {
+ /*
+ * Indicate that we're switching to
+ * non-blocking mode.
+ */
+ p->md.timeout = ~p->md.timeout;
+ }
+ } else {
+ if (p->md.timeout < 0) {
+ p->md.timeout = ~p->md.timeout;
+ }
+ }
+ return (0);
+ }
+#endif
+ return (pcap_setnonblock_fd(p, nonblock, errbuf));
+}
+
+#ifdef HAVE_ZEROCOPY_BPF
+/*
+ * Zero-copy BPF buffer routines to check for and acknowledge BPF data in
+ * shared memory buffers.
+ *
+ * pcap_next_zbuf_shm(): Check for a newly available shared memory buffer,
+ * and set up p->buffer and cc to reflect one if available. Notice that if
+ * there was no prior buffer, we select zbuf1 as this will be the first
+ * buffer filled for a fresh BPF session.
+ */
+static int
+pcap_next_zbuf_shm(pcap_t *p, int *cc)
+{
+ struct bpf_zbuf_header *bzh;
+
+ if (p->md.zbuffer == p->md.zbuf2 || p->md.zbuffer == NULL) {
+ bzh = (struct bpf_zbuf_header *)p->md.zbuf1;
+ if (bzh->bzh_user_gen !=
+ atomic_load_acq_int(&bzh->bzh_kernel_gen)) {
+ p->md.bzh = bzh;
+ p->md.zbuffer = (u_char *)p->md.zbuf1;
+ p->buffer = p->md.zbuffer + sizeof(*bzh);
+ *cc = bzh->bzh_kernel_len;
+ return (1);
+ }
+ } else if (p->md.zbuffer == p->md.zbuf1) {
+ bzh = (struct bpf_zbuf_header *)p->md.zbuf2;
+ if (bzh->bzh_user_gen !=
+ atomic_load_acq_int(&bzh->bzh_kernel_gen)) {
+ p->md.bzh = bzh;
+ p->md.zbuffer = (u_char *)p->md.zbuf2;
+ p->buffer = p->md.zbuffer + sizeof(*bzh);
+ *cc = bzh->bzh_kernel_len;
+ return (1);
+ }
+ }
+ *cc = 0;
+ return (0);
+}
+
+/*
+ * pcap_next_zbuf() -- Similar to pcap_next_zbuf_shm(), except wait using
+ * select() for data or a timeout, and possibly force rotation of the buffer
+ * in the event we time out or are in immediate mode. Invoke the shared
+ * memory check before doing system calls in order to avoid doing avoidable
+ * work.
+ */
+static int
+pcap_next_zbuf(pcap_t *p, int *cc)
+{
+ struct bpf_zbuf bz;
+ struct timeval tv;
+ struct timespec cur;
+ fd_set r_set;
+ int data, r;
+ int expire, tmout;
+
+#define TSTOMILLI(ts) (((ts)->tv_sec * 1000) + ((ts)->tv_nsec / 1000000))
+ /*
+ * Start out by seeing whether anything is waiting by checking the
+ * next shared memory buffer for data.
+ */
+ data = pcap_next_zbuf_shm(p, cc);
+ if (data)
+ return (data);
+ /*
+ * If a previous sleep was interrupted due to signal delivery, make
+ * sure that the timeout gets adjusted accordingly. This requires
+ * that we analyze when the timeout should be been expired, and
+ * subtract the current time from that. If after this operation,
+ * our timeout is less then or equal to zero, handle it like a
+ * regular timeout.
+ */
+ tmout = p->md.timeout;
+ if (tmout)
+ (void) clock_gettime(CLOCK_MONOTONIC, &cur);
+ if (p->md.interrupted && p->md.timeout) {
+ expire = TSTOMILLI(&p->md.firstsel) + p->md.timeout;
+ tmout = expire - TSTOMILLI(&cur);
+#undef TSTOMILLI
+ if (tmout <= 0) {
+ p->md.interrupted = 0;
+ data = pcap_next_zbuf_shm(p, cc);
+ if (data)
+ return (data);
+ if (ioctl(p->fd, BIOCROTZBUF, &bz) < 0) {
+ (void) snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "BIOCROTZBUF: %s", strerror(errno));
+ return (PCAP_ERROR);
+ }
+ return (pcap_next_zbuf_shm(p, cc));
+ }
+ }
+ /*
+ * No data in the buffer, so must use select() to wait for data or
+ * the next timeout. Note that we only call select if the handle
+ * is in blocking mode.
+ */
+ if (p->md.timeout >= 0) {
+ FD_ZERO(&r_set);
+ FD_SET(p->fd, &r_set);
+ if (tmout != 0) {
+ tv.tv_sec = tmout / 1000;
+ tv.tv_usec = (tmout * 1000) % 1000000;
+ }
+ r = select(p->fd + 1, &r_set, NULL, NULL,
+ p->md.timeout != 0 ? &tv : NULL);
+ if (r < 0 && errno == EINTR) {
+ if (!p->md.interrupted && p->md.timeout) {
+ p->md.interrupted = 1;
+ p->md.firstsel = cur;
+ }
+ return (0);
+ } else if (r < 0) {
+ (void) snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "select: %s", strerror(errno));
+ return (PCAP_ERROR);
+ }
+ }
+ p->md.interrupted = 0;
+ /*
+ * Check again for data, which may exist now that we've either been
+ * woken up as a result of data or timed out. Try the "there's data"
+ * case first since it doesn't require a system call.
+ */
+ data = pcap_next_zbuf_shm(p, cc);
+ if (data)
+ return (data);
+ /*
+ * Try forcing a buffer rotation to dislodge timed out or immediate
+ * data.
+ */
+ if (ioctl(p->fd, BIOCROTZBUF, &bz) < 0) {
+ (void) snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "BIOCROTZBUF: %s", strerror(errno));
+ return (PCAP_ERROR);
+ }
+ return (pcap_next_zbuf_shm(p, cc));
+}
+
+/*
+ * Notify kernel that we are done with the buffer. We don't reset zbuffer so
+ * that we know which buffer to use next time around.
+ */
+static int
+pcap_ack_zbuf(pcap_t *p)
+{
+
+ atomic_store_rel_int(&p->md.bzh->bzh_user_gen,
+ p->md.bzh->bzh_kernel_gen);
+ p->md.bzh = NULL;
+ p->buffer = NULL;
+ return (0);
+}
+#endif /* HAVE_ZEROCOPY_BPF */
+
+pcap_t *
+pcap_create_interface(const char *device, char *ebuf)
+{
+ pcap_t *p;
+
+ p = pcap_create_common(device, ebuf);
+ if (p == NULL)
+ return (NULL);
+
+ p->activate_op = pcap_activate_bpf;
+ p->can_set_rfmon_op = pcap_can_set_rfmon_bpf;
+ return (p);
+}
+
+/*
+ * On success, returns a file descriptor for a BPF device.
+ * On failure, returns a PCAP_ERROR_ value, and sets p->errbuf.
+ */
+static int
+bpf_open(pcap_t *p)
+{
+ int fd;
+#ifdef HAVE_CLONING_BPF
+ static const char device[] = "/dev/bpf";
+#else
+ int n = 0;
+ char device[sizeof "/dev/bpf0000000000"];
+#endif
+
+#ifdef _AIX
+ /*
+ * Load the bpf driver, if it isn't already loaded,
+ * and create the BPF device entries, if they don't
+ * already exist.
+ */
+ if (bpf_load(p->errbuf) == PCAP_ERROR)
+ return (PCAP_ERROR);
+#endif
+
+#ifdef HAVE_CLONING_BPF
+ if ((fd = open(device, O_RDWR)) == -1 &&
+ (errno != EACCES || (fd = open(device, O_RDONLY)) == -1)) {
+ if (errno == EACCES)
+ fd = PCAP_ERROR_PERM_DENIED;
+ else
+ fd = PCAP_ERROR;
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "(cannot open device) %s: %s", device, pcap_strerror(errno));
+ }
+#else
+ /*
+ * Go through all the minors and find one that isn't in use.
+ */
+ do {
+ (void)snprintf(device, sizeof(device), "/dev/bpf%d", n++);
+ /*
+ * Initially try a read/write open (to allow the inject
+ * method to work). If that fails due to permission
+ * issues, fall back to read-only. This allows a
+ * non-root user to be granted specific access to pcap
+ * capabilities via file permissions.
+ *
+ * XXX - we should have an API that has a flag that
+ * controls whether to open read-only or read-write,
+ * so that denial of permission to send (or inability
+ * to send, if sending packets isn't supported on
+ * the device in question) can be indicated at open
+ * time.
+ */
+ fd = open(device, O_RDWR);
+ if (fd == -1 && errno == EACCES)
+ fd = open(device, O_RDONLY);
+ } while (fd < 0 && errno == EBUSY);
+
+ /*
+ * XXX better message for all minors used
+ */
+ if (fd < 0) {
+ switch (errno) {
+
+ case ENOENT:
+ fd = PCAP_ERROR;
+ if (n == 1) {
+ /*
+ * /dev/bpf0 doesn't exist, which
+ * means we probably have no BPF
+ * devices.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "(there are no BPF devices)");
+ } else {
+ /*
+ * We got EBUSY on at least one
+ * BPF device, so we have BPF
+ * devices, but all the ones
+ * that exist are busy.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "(all BPF devices are busy)");
+ }
+ break;
+
+ case EACCES:
+ /*
+ * Got EACCES on the last device we tried,
+ * and EBUSY on all devices before that,
+ * if any.
+ */
+ fd = PCAP_ERROR_PERM_DENIED;
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "(cannot open BPF device) %s: %s", device,
+ pcap_strerror(errno));
+ break;
+
+ default:
+ /*
+ * Some other problem.
+ */
+ fd = PCAP_ERROR;
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "(cannot open BPF device) %s: %s", device,
+ pcap_strerror(errno));
+ break;
+ }
+ }
+#endif
+
+ return (fd);
+}
+
+#ifdef BIOCGDLTLIST
+static int
+get_dlt_list(int fd, int v, struct bpf_dltlist *bdlp, char *ebuf)
+{
+ memset(bdlp, 0, sizeof(*bdlp));
+ if (ioctl(fd, BIOCGDLTLIST, (caddr_t)bdlp) == 0) {
+ u_int i;
+ int is_ethernet;
+
+ bdlp->bfl_list = (u_int *) malloc(sizeof(u_int) * (bdlp->bfl_len + 1));
+ if (bdlp->bfl_list == NULL) {
+ (void)snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
+ pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+
+ if (ioctl(fd, BIOCGDLTLIST, (caddr_t)bdlp) < 0) {
+ (void)snprintf(ebuf, PCAP_ERRBUF_SIZE,
+ "BIOCGDLTLIST: %s", pcap_strerror(errno));
+ free(bdlp->bfl_list);
+ return (PCAP_ERROR);
+ }
+
+ /*
+ * OK, for real Ethernet devices, add DLT_DOCSIS to the
+ * list, so that an application can let you choose it,
+ * in case you're capturing DOCSIS traffic that a Cisco
+ * Cable Modem Termination System is putting out onto
+ * an Ethernet (it doesn't put an Ethernet header onto
+ * the wire, it puts raw DOCSIS frames out on the wire
+ * inside the low-level Ethernet framing).
+ *
+ * A "real Ethernet device" is defined here as a device
+ * that has a link-layer type of DLT_EN10MB and that has
+ * no alternate link-layer types; that's done to exclude
+ * 802.11 interfaces (which might or might not be the
+ * right thing to do, but I suspect it is - Ethernet <->
+ * 802.11 bridges would probably badly mishandle frames
+ * that don't have Ethernet headers).
+ *
+ * On Solaris with BPF, Ethernet devices also offer
+ * DLT_IPNET, so we, if DLT_IPNET is defined, we don't
+ * treat it as an indication that the device isn't an
+ * Ethernet.
+ */
+ if (v == DLT_EN10MB) {
+ is_ethernet = 1;
+ for (i = 0; i < bdlp->bfl_len; i++) {
+ if (bdlp->bfl_list[i] != DLT_EN10MB
+#ifdef DLT_IPNET
+ && bdlp->bfl_list[i] != DLT_IPNET
+#endif
+ ) {
+ is_ethernet = 0;
+ break;
+ }
+ }
+ if (is_ethernet) {
+ /*
+ * We reserved one more slot at the end of
+ * the list.
+ */
+ bdlp->bfl_list[bdlp->bfl_len] = DLT_DOCSIS;
+ bdlp->bfl_len++;
+ }
+ }
+ } else {
+ /*
+ * EINVAL just means "we don't support this ioctl on
+ * this device"; don't treat it as an error.
+ */
+ if (errno != EINVAL) {
+ (void)snprintf(ebuf, PCAP_ERRBUF_SIZE,
+ "BIOCGDLTLIST: %s", pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+ }
+ return (0);
+}
+#endif
+
+static int
+pcap_can_set_rfmon_bpf(pcap_t *p)
+{
+#if defined(__APPLE__)
+ struct utsname osinfo;
+ struct ifreq ifr;
+ int fd;
+#ifdef BIOCGDLTLIST
+ struct bpf_dltlist bdl;
+#endif
+
+ /*
+ * The joys of monitor mode on OS X.
+ *
+ * Prior to 10.4, it's not supported at all.
+ *
+ * In 10.4, if adapter enN supports monitor mode, there's a
+ * wltN adapter corresponding to it; you open it, instead of
+ * enN, to get monitor mode. You get whatever link-layer
+ * headers it supplies.
+ *
+ * In 10.5, and, we assume, later releases, if adapter enN
+ * supports monitor mode, it offers, among its selectable
+ * DLT_ values, values that let you get the 802.11 header;
+ * selecting one of those values puts the adapter into monitor
+ * mode (i.e., you can't get 802.11 headers except in monitor
+ * mode, and you can't get Ethernet headers in monitor mode).
+ */
+ if (uname(&osinfo) == -1) {
+ /*
+ * Can't get the OS version; just say "no".
+ */
+ return (0);
+ }
+ /*
+ * We assume osinfo.sysname is "Darwin", because
+ * __APPLE__ is defined. We just check the version.
+ */
+ if (osinfo.release[0] < '8' && osinfo.release[1] == '.') {
+ /*
+ * 10.3 (Darwin 7.x) or earlier.
+ * Monitor mode not supported.
+ */
+ return (0);
+ }
+ if (osinfo.release[0] == '8' && osinfo.release[1] == '.') {
+ /*
+ * 10.4 (Darwin 8.x). s/en/wlt/, and check
+ * whether the device exists.
+ */
+ if (strncmp(p->opt.source, "en", 2) != 0) {
+ /*
+ * Not an enN device; no monitor mode.
+ */
+ return (0);
+ }
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fd == -1) {
+ (void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "socket: %s", pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+ strlcpy(ifr.ifr_name, "wlt", sizeof(ifr.ifr_name));
+ strlcat(ifr.ifr_name, p->opt.source + 2, sizeof(ifr.ifr_name));
+ if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) {
+ /*
+ * No such device?
+ */
+ close(fd);
+ return (0);
+ }
+ close(fd);
+ return (1);
+ }
+
+#ifdef BIOCGDLTLIST
+ /*
+ * Everything else is 10.5 or later; for those,
+ * we just open the enN device, and check whether
+ * we have any 802.11 devices.
+ *
+ * First, open a BPF device.
+ */
+ fd = bpf_open(p);
+ if (fd < 0)
+ return (fd); /* fd is the appropriate error code */
+
+ /*
+ * Now bind to the device.
+ */
+ (void)strncpy(ifr.ifr_name, p->opt.source, sizeof(ifr.ifr_name));
+ if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) {
+ switch (errno) {
+
+ case ENXIO:
+ /*
+ * There's no such device.
+ */
+ close(fd);
+ return (PCAP_ERROR_NO_SUCH_DEVICE);
+
+ case ENETDOWN:
+ /*
+ * Return a "network down" indication, so that
+ * the application can report that rather than
+ * saying we had a mysterious failure and
+ * suggest that they report a problem to the
+ * libpcap developers.
+ */
+ close(fd);
+ return (PCAP_ERROR_IFACE_NOT_UP);
+
+ default:
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "BIOCSETIF: %s: %s",
+ p->opt.source, pcap_strerror(errno));
+ close(fd);
+ return (PCAP_ERROR);
+ }
+ }
+
+ /*
+ * We know the default link type -- now determine all the DLTs
+ * this interface supports. If this fails with EINVAL, it's
+ * not fatal; we just don't get to use the feature later.
+ * (We don't care about DLT_DOCSIS, so we pass DLT_NULL
+ * as the default DLT for this adapter.)
+ */
+ if (get_dlt_list(fd, DLT_NULL, &bdl, p->errbuf) == PCAP_ERROR) {
+ close(fd);
+ return (PCAP_ERROR);
+ }
+ if (find_802_11(&bdl) != -1) {
+ /*
+ * We have an 802.11 DLT, so we can set monitor mode.
+ */
+ free(bdl.bfl_list);
+ close(fd);
+ return (1);
+ }
+ free(bdl.bfl_list);
+#endif /* BIOCGDLTLIST */
+ return (0);
+#elif defined(HAVE_BSD_IEEE80211)
+ int ret;
+
+ ret = monitor_mode(p, 0);
+ if (ret == PCAP_ERROR_RFMON_NOTSUP)
+ return (0); /* not an error, just a "can't do" */
+ if (ret == 0)
+ return (1); /* success */
+ return (ret);
+#else
+ return (0);
+#endif
+}
+
+static int
+pcap_stats_bpf(pcap_t *p, struct pcap_stat *ps)
+{
+ struct bpf_stat s;
+
+ /*
+ * "ps_recv" counts packets handed to the filter, not packets
+ * that passed the filter. This includes packets later dropped
+ * because we ran out of buffer space.
+ *
+ * "ps_drop" counts packets dropped inside the BPF device
+ * because we ran out of buffer space. It doesn't count
+ * packets dropped by the interface driver. It counts
+ * only packets that passed the filter.
+ *
+ * Both statistics include packets not yet read from the kernel
+ * by libpcap, and thus not yet seen by the application.
+ */
+ if (ioctl(p->fd, BIOCGSTATS, (caddr_t)&s) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGSTATS: %s",
+ pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+
+ ps->ps_recv = s.bs_recv;
+ ps->ps_drop = s.bs_drop;
+ ps->ps_ifdrop = 0;
+ return (0);
+}
+
+static int
+pcap_read_bpf(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
+{
+ int cc;
+ int n = 0;
+ register u_char *bp, *ep;
+ u_char *datap;
+#ifdef PCAP_FDDIPAD
+ register int pad;
+#endif
+#ifdef HAVE_ZEROCOPY_BPF
+ int i;
+#endif
+
+ again:
+ /*
+ * Has "pcap_breakloop()" been called?
+ */
+ if (p->break_loop) {
+ /*
+ * Yes - clear the flag that indicates that it
+ * has, and return PCAP_ERROR_BREAK to indicate
+ * that we were told to break out of the loop.
+ */
+ p->break_loop = 0;
+ return (PCAP_ERROR_BREAK);
+ }
+ cc = p->cc;
+ if (p->cc == 0) {
+ /*
+ * When reading without zero-copy from a file descriptor, we
+ * use a single buffer and return a length of data in the
+ * buffer. With zero-copy, we update the p->buffer pointer
+ * to point at whatever underlying buffer contains the next
+ * data and update cc to reflect the data found in the
+ * buffer.
+ */
+#ifdef HAVE_ZEROCOPY_BPF
+ if (p->md.zerocopy) {
+ if (p->buffer != NULL)
+ pcap_ack_zbuf(p);
+ i = pcap_next_zbuf(p, &cc);
+ if (i == 0)
+ goto again;
+ if (i < 0)
+ return (PCAP_ERROR);
+ } else
+#endif
+ {
+ cc = read(p->fd, (char *)p->buffer, p->bufsize);
+ }
+ if (cc < 0) {
+ /* Don't choke when we get ptraced */
+ switch (errno) {
+
+ case EINTR:
+ goto again;
+
+#ifdef _AIX
+ case EFAULT:
+ /*
+ * Sigh. More AIX wonderfulness.
+ *
+ * For some unknown reason the uiomove()
+ * operation in the bpf kernel extension
+ * used to copy the buffer into user
+ * space sometimes returns EFAULT. I have
+ * no idea why this is the case given that
+ * a kernel debugger shows the user buffer
+ * is correct. This problem appears to
+ * be mostly mitigated by the memset of
+ * the buffer before it is first used.
+ * Very strange.... Shaun Clowes
+ *
+ * In any case this means that we shouldn't
+ * treat EFAULT as a fatal error; as we
+ * don't have an API for returning
+ * a "some packets were dropped since
+ * the last packet you saw" indication,
+ * we just ignore EFAULT and keep reading.
+ */
+ goto again;
+#endif
+
+ case EWOULDBLOCK:
+ return (0);
+
+ case ENXIO:
+ /*
+ * The device on which we're capturing
+ * went away.
+ *
+ * XXX - we should really return
+ * PCAP_ERROR_IFACE_NOT_UP, but
+ * pcap_dispatch() etc. aren't
+ * defined to retur that.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "The interface went down");
+ return (PCAP_ERROR);
+
+#if defined(sun) && !defined(BSD) && !defined(__svr4__) && !defined(__SVR4)
+ /*
+ * Due to a SunOS bug, after 2^31 bytes, the kernel
+ * file offset overflows and read fails with EINVAL.
+ * The lseek() to 0 will fix things.
+ */
+ case EINVAL:
+ if (lseek(p->fd, 0L, SEEK_CUR) +
+ p->bufsize < 0) {
+ (void)lseek(p->fd, 0L, SEEK_SET);
+ goto again;
+ }
+ /* fall through */
+#endif
+ }
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "read: %s",
+ pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+ bp = p->buffer;
+ } else
+ bp = p->bp;
+
+ /*
+ * Loop through each packet.
+ */
+#define bhp ((struct bpf_hdr *)bp)
+ ep = bp + cc;
+#ifdef PCAP_FDDIPAD
+ pad = p->fddipad;
+#endif
+ while (bp < ep) {
+ register int caplen, hdrlen;
+
+ /*
+ * Has "pcap_breakloop()" been called?
+ * If so, return immediately - if we haven't read any
+ * packets, clear the flag and return PCAP_ERROR_BREAK
+ * to indicate that we were told to break out of the loop,
+ * otherwise leave the flag set, so that the *next* call
+ * will break out of the loop without having read any
+ * packets, and return the number of packets we've
+ * processed so far.
+ */
+ if (p->break_loop) {
+ p->bp = bp;
+ p->cc = ep - bp;
+ /*
+ * ep is set based on the return value of read(),
+ * but read() from a BPF device doesn't necessarily
+ * return a value that's a multiple of the alignment
+ * value for BPF_WORDALIGN(). However, whenever we
+ * increment bp, we round up the increment value by
+ * a value rounded up by BPF_WORDALIGN(), so we
+ * could increment bp past ep after processing the
+ * last packet in the buffer.
+ *
+ * We treat ep < bp as an indication that this
+ * happened, and just set p->cc to 0.
+ */
+ if (p->cc < 0)
+ p->cc = 0;
+ if (n == 0) {
+ p->break_loop = 0;
+ return (PCAP_ERROR_BREAK);
+ } else
+ return (n);
+ }
+
+ caplen = bhp->bh_caplen;
+ hdrlen = bhp->bh_hdrlen;
+ datap = bp + hdrlen;
+ /*
+ * Short-circuit evaluation: if using BPF filter
+ * in kernel, no need to do it now - we already know
+ * the packet passed the filter.
+ *
+#ifdef PCAP_FDDIPAD
+ * Note: the filter code was generated assuming
+ * that p->fddipad was the amount of padding
+ * before the header, as that's what's required
+ * in the kernel, so we run the filter before
+ * skipping that padding.
+#endif
+ */
+ if (p->md.use_bpf ||
+ bpf_filter(p->fcode.bf_insns, datap, bhp->bh_datalen, caplen)) {
+ struct pcap_pkthdr pkthdr;
+
+ pkthdr.ts.tv_sec = bhp->bh_tstamp.tv_sec;
+#ifdef _AIX
+ /*
+ * AIX's BPF returns seconds/nanoseconds time
+ * stamps, not seconds/microseconds time stamps.
+ */
+ pkthdr.ts.tv_usec = bhp->bh_tstamp.tv_usec/1000;
+#else
+ pkthdr.ts.tv_usec = bhp->bh_tstamp.tv_usec;
+#endif
+#ifdef PCAP_FDDIPAD
+ if (caplen > pad)
+ pkthdr.caplen = caplen - pad;
+ else
+ pkthdr.caplen = 0;
+ if (bhp->bh_datalen > pad)
+ pkthdr.len = bhp->bh_datalen - pad;
+ else
+ pkthdr.len = 0;
+ datap += pad;
+#else
+ pkthdr.caplen = caplen;
+ pkthdr.len = bhp->bh_datalen;
+#endif
+ (*callback)(user, &pkthdr, datap);
+ bp += BPF_WORDALIGN(caplen + hdrlen);
+ if (++n >= cnt && cnt > 0) {
+ p->bp = bp;
+ p->cc = ep - bp;
+ /*
+ * See comment above about p->cc < 0.
+ */
+ if (p->cc < 0)
+ p->cc = 0;
+ return (n);
+ }
+ } else {
+ /*
+ * Skip this packet.
+ */
+ bp += BPF_WORDALIGN(caplen + hdrlen);
+ }
+ }
+#undef bhp
+ p->cc = 0;
+ return (n);
+}
+
+static int
+pcap_inject_bpf(pcap_t *p, const void *buf, size_t size)
+{
+ int ret;
+
+ ret = write(p->fd, buf, size);
+#ifdef __APPLE__
+ if (ret == -1 && errno == EAFNOSUPPORT) {
+ /*
+ * In Mac OS X, there's a bug wherein setting the
+ * BIOCSHDRCMPLT flag causes writes to fail; see,
+ * for example:
+ *
+ * http://cerberus.sourcefire.com/~jeff/archives/patches/macosx/BIOCSHDRCMPLT-10.3.3.patch
+ *
+ * So, if, on OS X, we get EAFNOSUPPORT from the write, we
+ * assume it's due to that bug, and turn off that flag
+ * and try again. If we succeed, it either means that
+ * somebody applied the fix from that URL, or other patches
+ * for that bug from
+ *
+ * http://cerberus.sourcefire.com/~jeff/archives/patches/macosx/
+ *
+ * and are running a Darwin kernel with those fixes, or
+ * that Apple fixed the problem in some OS X release.
+ */
+ u_int spoof_eth_src = 0;
+
+ if (ioctl(p->fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) {
+ (void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "send: can't turn off BIOCSHDRCMPLT: %s",
+ pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+
+ /*
+ * Now try the write again.
+ */
+ ret = write(p->fd, buf, size);
+ }
+#endif /* __APPLE__ */
+ if (ret == -1) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "send: %s",
+ pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+ return (ret);
+}
+
+#ifdef _AIX
+static int
+bpf_odminit(char *errbuf)
+{
+ char *errstr;
+
+ if (odm_initialize() == -1) {
+ if (odm_err_msg(odmerrno, &errstr) == -1)
+ errstr = "Unknown error";
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "bpf_load: odm_initialize failed: %s",
+ errstr);
+ return (PCAP_ERROR);
+ }
+
+ if ((odmlockid = odm_lock("/etc/objrepos/config_lock", ODM_WAIT)) == -1) {
+ if (odm_err_msg(odmerrno, &errstr) == -1)
+ errstr = "Unknown error";
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "bpf_load: odm_lock of /etc/objrepos/config_lock failed: %s",
+ errstr);
+ (void)odm_terminate();
+ return (PCAP_ERROR);
+ }
+
+ return (0);
+}
+
+static int
+bpf_odmcleanup(char *errbuf)
+{
+ char *errstr;
+
+ if (odm_unlock(odmlockid) == -1) {
+ if (errbuf != NULL) {
+ if (odm_err_msg(odmerrno, &errstr) == -1)
+ errstr = "Unknown error";
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "bpf_load: odm_unlock failed: %s",
+ errstr);
+ }
+ return (PCAP_ERROR);
+ }
+
+ if (odm_terminate() == -1) {
+ if (errbuf != NULL) {
+ if (odm_err_msg(odmerrno, &errstr) == -1)
+ errstr = "Unknown error";
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "bpf_load: odm_terminate failed: %s",
+ errstr);
+ }
+ return (PCAP_ERROR);
+ }
+
+ return (0);
+}
+
+static int
+bpf_load(char *errbuf)
+{
+ long major;
+ int *minors;
+ int numminors, i, rc;
+ char buf[1024];
+ struct stat sbuf;
+ struct bpf_config cfg_bpf;
+ struct cfg_load cfg_ld;
+ struct cfg_kmod cfg_km;
+
+ /*
+ * This is very very close to what happens in the real implementation
+ * but I've fixed some (unlikely) bug situations.
+ */
+ if (bpfloadedflag)
+ return (0);
+
+ if (bpf_odminit(errbuf) == PCAP_ERROR)
+ return (PCAP_ERROR);
+
+ major = genmajor(BPF_NAME);
+ if (major == -1) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "bpf_load: genmajor failed: %s", pcap_strerror(errno));
+ (void)bpf_odmcleanup(NULL);
+ return (PCAP_ERROR);
+ }
+
+ minors = getminor(major, &numminors, BPF_NAME);
+ if (!minors) {
+ minors = genminor("bpf", major, 0, BPF_MINORS, 1, 1);
+ if (!minors) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "bpf_load: genminor failed: %s",
+ pcap_strerror(errno));
+ (void)bpf_odmcleanup(NULL);
+ return (PCAP_ERROR);
+ }
+ }
+
+ if (bpf_odmcleanup(errbuf) == PCAP_ERROR)
+ return (PCAP_ERROR);
+
+ rc = stat(BPF_NODE "0", &sbuf);
+ if (rc == -1 && errno != ENOENT) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "bpf_load: can't stat %s: %s",
+ BPF_NODE "0", pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+
+ if (rc == -1 || getmajor(sbuf.st_rdev) != major) {
+ for (i = 0; i < BPF_MINORS; i++) {
+ sprintf(buf, "%s%d", BPF_NODE, i);
+ unlink(buf);
+ if (mknod(buf, S_IRUSR | S_IFCHR, domakedev(major, i)) == -1) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "bpf_load: can't mknod %s: %s",
+ buf, pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+ }
+ }
+
+ /* Check if the driver is loaded */
+ memset(&cfg_ld, 0x0, sizeof(cfg_ld));
+ cfg_ld.path = buf;
+ sprintf(cfg_ld.path, "%s/%s", DRIVER_PATH, BPF_NAME);
+ if ((sysconfig(SYS_QUERYLOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) ||
+ (cfg_ld.kmid == 0)) {
+ /* Driver isn't loaded, load it now */
+ if (sysconfig(SYS_SINGLELOAD, (void *)&cfg_ld, sizeof(cfg_ld)) == -1) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "bpf_load: could not load driver: %s",
+ strerror(errno));
+ return (PCAP_ERROR);
+ }
+ }
+
+ /* Configure the driver */
+ cfg_km.cmd = CFG_INIT;
+ cfg_km.kmid = cfg_ld.kmid;
+ cfg_km.mdilen = sizeof(cfg_bpf);
+ cfg_km.mdiptr = (void *)&cfg_bpf;
+ for (i = 0; i < BPF_MINORS; i++) {
+ cfg_bpf.devno = domakedev(major, i);
+ if (sysconfig(SYS_CFGKMOD, (void *)&cfg_km, sizeof(cfg_km)) == -1) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "bpf_load: could not configure driver: %s",
+ strerror(errno));
+ return (PCAP_ERROR);
+ }
+ }
+
+ bpfloadedflag = 1;
+
+ return (0);
+}
+#endif
+
+/*
+ * Turn off rfmon mode if necessary.
+ */
+static void
+pcap_cleanup_bpf(pcap_t *p)
+{
+#ifdef HAVE_BSD_IEEE80211
+ int sock;
+ struct ifmediareq req;
+ struct ifreq ifr;
+#endif
+
+ if (p->md.must_do_on_close != 0) {
+ /*
+ * There's something we have to do when closing this
+ * pcap_t.
+ */
+#ifdef HAVE_BSD_IEEE80211
+ if (p->md.must_do_on_close & MUST_CLEAR_RFMON) {
+ /*
+ * We put the interface into rfmon mode;
+ * take it out of rfmon mode.
+ *
+ * XXX - if somebody else wants it in rfmon
+ * mode, this code cannot know that, so it'll take
+ * it out of rfmon mode.
+ */
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sock == -1) {
+ fprintf(stderr,
+ "Can't restore interface flags (socket() failed: %s).\n"
+ "Please adjust manually.\n",
+ strerror(errno));
+ } else {
+ memset(&req, 0, sizeof(req));
+ strncpy(req.ifm_name, p->md.device,
+ sizeof(req.ifm_name));
+ if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) {
+ fprintf(stderr,
+ "Can't restore interface flags (SIOCGIFMEDIA failed: %s).\n"
+ "Please adjust manually.\n",
+ strerror(errno));
+ } else {
+ if (req.ifm_current & IFM_IEEE80211_MONITOR) {
+ /*
+ * Rfmon mode is currently on;
+ * turn it off.
+ */
+ memset(&ifr, 0, sizeof(ifr));
+ (void)strncpy(ifr.ifr_name,
+ p->md.device,
+ sizeof(ifr.ifr_name));
+ ifr.ifr_media =
+ req.ifm_current & ~IFM_IEEE80211_MONITOR;
+ if (ioctl(sock, SIOCSIFMEDIA,
+ &ifr) == -1) {
+ fprintf(stderr,
+ "Can't restore interface flags (SIOCSIFMEDIA failed: %s).\n"
+ "Please adjust manually.\n",
+ strerror(errno));
+ }
+ }
+ }
+ close(sock);
+ }
+ }
+#endif /* HAVE_BSD_IEEE80211 */
+
+ /*
+ * Take this pcap out of the list of pcaps for which we
+ * have to take the interface out of some mode.
+ */
+ pcap_remove_from_pcaps_to_close(p);
+ p->md.must_do_on_close = 0;
+ }
+
+#ifdef HAVE_ZEROCOPY_BPF
+ if (p->md.zerocopy) {
+ /*
+ * Delete the mappings. Note that p->buffer gets
+ * initialized to one of the mmapped regions in
+ * this case, so do not try and free it directly;
+ * null it out so that pcap_cleanup_live_common()
+ * doesn't try to free it.
+ */
+ if (p->md.zbuf1 != MAP_FAILED && p->md.zbuf1 != NULL)
+ (void) munmap(p->md.zbuf1, p->md.zbufsize);
+ if (p->md.zbuf2 != MAP_FAILED && p->md.zbuf2 != NULL)
+ (void) munmap(p->md.zbuf2, p->md.zbufsize);
+ p->buffer = NULL;
+ p->buffer = NULL;
+ }
+#endif
+ if (p->md.device != NULL) {
+ free(p->md.device);
+ p->md.device = NULL;
+ }
+ pcap_cleanup_live_common(p);
+}
+
+static int
+check_setif_failure(pcap_t *p, int error)
+{
+#ifdef __APPLE__
+ int fd;
+ struct ifreq ifr;
+ int err;
+#endif
+
+ if (error == ENXIO) {
+ /*
+ * No such device exists.
+ */
+#ifdef __APPLE__
+ if (p->opt.rfmon && strncmp(p->opt.source, "wlt", 3) == 0) {
+ /*
+ * Monitor mode was requested, and we're trying
+ * to open a "wltN" device. Assume that this
+ * is 10.4 and that we were asked to open an
+ * "enN" device; if that device exists, return
+ * "monitor mode not supported on the device".
+ */
+ fd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (fd != -1) {
+ strlcpy(ifr.ifr_name, "en",
+ sizeof(ifr.ifr_name));
+ strlcat(ifr.ifr_name, p->opt.source + 3,
+ sizeof(ifr.ifr_name));
+ if (ioctl(fd, SIOCGIFFLAGS, (char *)&ifr) < 0) {
+ /*
+ * We assume this failed because
+ * the underlying device doesn't
+ * exist.
+ */
+ err = PCAP_ERROR_NO_SUCH_DEVICE;
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "SIOCGIFFLAGS on %s failed: %s",
+ ifr.ifr_name, pcap_strerror(errno));
+ } else {
+ /*
+ * The underlying "enN" device
+ * exists, but there's no
+ * corresponding "wltN" device;
+ * that means that the "enN"
+ * device doesn't support
+ * monitor mode, probably because
+ * it's an Ethernet device rather
+ * than a wireless device.
+ */
+ err = PCAP_ERROR_RFMON_NOTSUP;
+ }
+ close(fd);
+ } else {
+ /*
+ * We can't find out whether there's
+ * an underlying "enN" device, so
+ * just report "no such device".
+ */
+ err = PCAP_ERROR_NO_SUCH_DEVICE;
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "socket() failed: %s",
+ pcap_strerror(errno));
+ }
+ return (err);
+ }
+#endif
+ /*
+ * No such device.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETIF failed: %s",
+ pcap_strerror(errno));
+ return (PCAP_ERROR_NO_SUCH_DEVICE);
+ } else if (errno == ENETDOWN) {
+ /*
+ * Return a "network down" indication, so that
+ * the application can report that rather than
+ * saying we had a mysterious failure and
+ * suggest that they report a problem to the
+ * libpcap developers.
+ */
+ return (PCAP_ERROR_IFACE_NOT_UP);
+ } else {
+ /*
+ * Some other error; fill in the error string, and
+ * return PCAP_ERROR.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s",
+ p->opt.source, pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+}
+
+/*
+ * Default capture buffer size.
+ * 32K isn't very much for modern machines with fast networks; we
+ * pick .5M, as that's the maximum on at least some systems with BPF.
+ *
+ * However, on AIX 3.5, the larger buffer sized caused unrecoverable
+ * read failures under stress, so we leave it as 32K; yet another
+ * place where AIX's BPF is broken.
+ */
+#ifdef _AIX
+#define DEFAULT_BUFSIZE 32768
+#else
+#define DEFAULT_BUFSIZE 524288
+#endif
+
+static int
+pcap_activate_bpf(pcap_t *p)
+{
+ int status = 0;
+ int fd;
+#ifdef LIFNAMSIZ
+ char *zonesep;
+ struct lifreq ifr;
+ char *ifrname = ifr.lifr_name;
+ const size_t ifnamsiz = sizeof(ifr.lifr_name);
+#else
+ struct ifreq ifr;
+ char *ifrname = ifr.ifr_name;
+ const size_t ifnamsiz = sizeof(ifr.ifr_name);
+#endif
+ struct bpf_version bv;
+#ifdef __APPLE__
+ int sockfd;
+ char *wltdev = NULL;
+#endif
+#ifdef BIOCGDLTLIST
+ struct bpf_dltlist bdl;
+#if defined(__APPLE__) || defined(HAVE_BSD_IEEE80211)
+ int new_dlt;
+#endif
+#endif /* BIOCGDLTLIST */
+#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT)
+ u_int spoof_eth_src = 1;
+#endif
+ u_int v;
+ struct bpf_insn total_insn;
+ struct bpf_program total_prog;
+ struct utsname osinfo;
+
+#ifdef HAVE_DAG_API
+ if (strstr(device, "dag")) {
+ return dag_open_live(device, snaplen, promisc, to_ms, ebuf);
+ }
+#endif /* HAVE_DAG_API */
+
+#ifdef BIOCGDLTLIST
+ memset(&bdl, 0, sizeof(bdl));
+ int have_osinfo = 0;
+#ifdef HAVE_ZEROCOPY_BPF
+ struct bpf_zbuf bz;
+ u_int bufmode, zbufmax;
+#endif
+
+ fd = bpf_open(p);
+ if (fd < 0) {
+ status = fd;
+ goto bad;
+ }
+
+ p->fd = fd;
+
+ if (ioctl(fd, BIOCVERSION, (caddr_t)&bv) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCVERSION: %s",
+ pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+ if (bv.bv_major != BPF_MAJOR_VERSION ||
+ bv.bv_minor < BPF_MINOR_VERSION) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "kernel bpf filter out of date");
+ status = PCAP_ERROR;
+ goto bad;
+ }
+
+#if defined(LIFNAMSIZ) && defined(ZONENAME_MAX) && defined(lifr_zoneid)
+ /*
+ * Check if the given source network device has a '/' separated
+ * zonename prefix string. The zonename prefixed source device
+ * can be used by libpcap consumers to capture network traffic
+ * in non-global zones from the global zone on Solaris 11 and
+ * above. If the zonename prefix is present then we strip the
+ * prefix and pass the zone ID as part of lifr_zoneid.
+ */
+ if ((zonesep = strchr(p->opt.source, '/')) != NULL) {
+ char zonename[ZONENAME_MAX];
+ int znamelen;
+ char *lnamep;
+
+ znamelen = zonesep - p->opt.source;
+ (void) strlcpy(zonename, p->opt.source, znamelen + 1);
+ lnamep = strdup(zonesep + 1);
+ ifr.lifr_zoneid = getzoneidbyname(zonename);
+ free(p->opt.source);
+ p->opt.source = lnamep;
+ }
+#endif
+
+ p->md.device = strdup(p->opt.source);
+ if (p->md.device == NULL) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "strdup: %s",
+ pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+
+ /*
+ * Try finding a good size for the buffer; 32768 may be too
+ * big, so keep cutting it in half until we find a size
+ * that works, or run out of sizes to try. If the default
+ * is larger, don't make it smaller.
+ *
+ * XXX - there should be a user-accessible hook to set the
+ * initial buffer size.
+ * Attempt to find out the version of the OS on which we're running.
+ */
+ if (uname(&osinfo) == 0)
+ have_osinfo = 1;
+
+#ifdef __APPLE__
+ /*
+ * See comment in pcap_can_set_rfmon_bpf() for an explanation
+ * of why we check the version number.
+ */
+ if (p->opt.rfmon) {
+ if (have_osinfo) {
+ /*
+ * We assume osinfo.sysname is "Darwin", because
+ * __APPLE__ is defined. We just check the version.
+ */
+ if (osinfo.release[0] < '8' &&
+ osinfo.release[1] == '.') {
+ /*
+ * 10.3 (Darwin 7.x) or earlier.
+ */
+ status = PCAP_ERROR_RFMON_NOTSUP;
+ goto bad;
+ }
+ if (osinfo.release[0] == '8' &&
+ osinfo.release[1] == '.') {
+ /*
+ * 10.4 (Darwin 8.x). s/en/wlt/
+ */
+ if (strncmp(p->opt.source, "en", 2) != 0) {
+ /*
+ * Not an enN device; check
+ * whether the device even exists.
+ */
+ sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sockfd != -1) {
+ strlcpy(ifrname,
+ p->opt.source, ifnamsiz);
+ if (ioctl(sockfd, SIOCGIFFLAGS,
+ (char *)&ifr) < 0) {
+ /*
+ * We assume this
+ * failed because
+ * the underlying
+ * device doesn't
+ * exist.
+ */
+ status = PCAP_ERROR_NO_SUCH_DEVICE;
+ snprintf(p->errbuf,
+ PCAP_ERRBUF_SIZE,
+ "SIOCGIFFLAGS failed: %s",
+ pcap_strerror(errno));
+ } else
+ status = PCAP_ERROR_RFMON_NOTSUP;
+ close(sockfd);
+ } else {
+ /*
+ * We can't find out whether
+ * the device exists, so just
+ * report "no such device".
+ */
+ status = PCAP_ERROR_NO_SUCH_DEVICE;
+ snprintf(p->errbuf,
+ PCAP_ERRBUF_SIZE,
+ "socket() failed: %s",
+ pcap_strerror(errno));
+ }
+ goto bad;
+ }
+ wltdev = malloc(strlen(p->opt.source) + 2);
+ if (wltdev == NULL) {
+ (void)snprintf(p->errbuf,
+ PCAP_ERRBUF_SIZE, "malloc: %s",
+ pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+ strcpy(wltdev, "wlt");
+ strcat(wltdev, p->opt.source + 2);
+ free(p->opt.source);
+ p->opt.source = wltdev;
+ }
+ /*
+ * Everything else is 10.5 or later; for those,
+ * we just open the enN device, and set the DLT.
+ */
+ }
+ }
+#endif /* __APPLE__ */
+#ifdef HAVE_ZEROCOPY_BPF
+ /*
+ * If the BPF extension to set buffer mode is present, try setting
+ * the mode to zero-copy. If that fails, use regular buffering. If
+ * it succeeds but other setup fails, return an error to the user.
+ */
+ bufmode = BPF_BUFMODE_ZBUF;
+ if (ioctl(fd, BIOCSETBUFMODE, (caddr_t)&bufmode) == 0) {
+ /*
+ * We have zerocopy BPF; use it.
+ */
+ p->md.zerocopy = 1;
+
+ /*
+ * How to pick a buffer size: first, query the maximum buffer
+ * size supported by zero-copy. This also lets us quickly
+ * determine whether the kernel generally supports zero-copy.
+ * Then, if a buffer size was specified, use that, otherwise
+ * query the default buffer size, which reflects kernel
+ * policy for a desired default. Round to the nearest page
+ * size.
+ */
+ if (ioctl(fd, BIOCGETZMAX, (caddr_t)&zbufmax) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGETZMAX: %s",
+ pcap_strerror(errno));
+ goto bad;
+ }
+
+ if (p->opt.buffer_size != 0) {
+ /*
+ * A buffer size was explicitly specified; use it.
+ */
+ v = p->opt.buffer_size;
+ } else {
+ if ((ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) ||
+ v < DEFAULT_BUFSIZE)
+ v = DEFAULT_BUFSIZE;
+ }
+#ifndef roundup
+#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) /* to any y */
+#endif
+ p->md.zbufsize = roundup(v, getpagesize());
+ if (p->md.zbufsize > zbufmax)
+ p->md.zbufsize = zbufmax;
+ p->md.zbuf1 = mmap(NULL, p->md.zbufsize, PROT_READ | PROT_WRITE,
+ MAP_ANON, -1, 0);
+ p->md.zbuf2 = mmap(NULL, p->md.zbufsize, PROT_READ | PROT_WRITE,
+ MAP_ANON, -1, 0);
+ if (p->md.zbuf1 == MAP_FAILED || p->md.zbuf2 == MAP_FAILED) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "mmap: %s",
+ pcap_strerror(errno));
+ goto bad;
+ }
+ memset(&bz, 0, sizeof(bz)); /* bzero() deprecated, replaced with memset() */
+ bz.bz_bufa = p->md.zbuf1;
+ bz.bz_bufb = p->md.zbuf2;
+ bz.bz_buflen = p->md.zbufsize;
+ if (ioctl(fd, BIOCSETZBUF, (caddr_t)&bz) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETZBUF: %s",
+ pcap_strerror(errno));
+ goto bad;
+ }
+ (void)strncpy(ifrname, p->opt.source, ifnamsiz);
+ if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETIF: %s: %s",
+ p->opt.source, pcap_strerror(errno));
+ goto bad;
+ }
+ v = p->md.zbufsize - sizeof(struct bpf_zbuf_header);
+ } else
+#endif
+ {
+ /*
+ * We don't have zerocopy BPF.
+ * Set the buffer size.
+ */
+ if (p->opt.buffer_size != 0) {
+ /*
+ * A buffer size was explicitly specified; use it.
+ */
+ if (ioctl(fd, BIOCSBLEN,
+ (caddr_t)&p->opt.buffer_size) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "BIOCSBLEN: %s: %s", p->opt.source,
+ pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+
+ /*
+ * Now bind to the device.
+ */
+ (void)strncpy(ifrname, p->opt.source, ifnamsiz);
+#ifdef BIOCSETLIF
+ if (ioctl(fd, BIOCSETLIF, (caddr_t)&ifr) < 0)
+#else
+ if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0)
+#endif
+ {
+ status = check_setif_failure(p, errno);
+ goto bad;
+ }
+ } else {
+ /*
+ * No buffer size was explicitly specified.
+ *
+ * Try finding a good size for the buffer;
+ * DEFAULT_BUFSIZE may be too big, so keep
+ * cutting it in half until we find a size
+ * that works, or run out of sizes to try.
+ * If the default is larger, don't make it smaller.
+ */
+ if ((ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) ||
+ v < DEFAULT_BUFSIZE)
+ v = DEFAULT_BUFSIZE;
+ for ( ; v != 0; v >>= 1) {
+ /*
+ * Ignore the return value - this is because the
+ * call fails on BPF systems that don't have
+ * kernel malloc. And if the call fails, it's
+ * no big deal, we just continue to use the
+ * standard buffer size.
+ */
+ (void) ioctl(fd, BIOCSBLEN, (caddr_t)&v);
+
+ (void)strncpy(ifrname, p->opt.source, ifnamsiz);
+#ifdef BIOCSETLIF
+ if (ioctl(fd, BIOCSETLIF, (caddr_t)&ifr) >= 0)
+#else
+ if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) >= 0)
+#endif
+ break; /* that size worked; we're done */
+
+ if (errno != ENOBUFS) {
+ status = check_setif_failure(p, errno);
+ goto bad;
+ }
+ }
+
+ if (v == 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "BIOCSBLEN: %s: No buffer size worked",
+ p->opt.source);
+ status = PCAP_ERROR;
+ goto bad;
+ }
+ }
+ }
+#endif
+
+ /* Get the data link layer type. */
+ if (ioctl(fd, BIOCGDLT, (caddr_t)&v) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGDLT: %s",
+ pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+
+#ifdef _AIX
+ /*
+ * AIX's BPF returns IFF_ types, not DLT_ types, in BIOCGDLT.
+ */
+ switch (v) {
+
+ case IFT_ETHER:
+ case IFT_ISO88023:
+ v = DLT_EN10MB;
+ break;
+
+ case IFT_FDDI:
+ v = DLT_FDDI;
+ break;
+
+ case IFT_ISO88025:
+ v = DLT_IEEE802;
+ break;
+
+ case IFT_LOOP:
+ v = DLT_NULL;
+ break;
+
+ default:
+ /*
+ * We don't know what to map this to yet.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "unknown interface type %u",
+ v);
+ status = PCAP_ERROR;
+ goto bad;
+ }
+#endif
+#if _BSDI_VERSION - 0 >= 199510
+ /* The SLIP and PPP link layer header changed in BSD/OS 2.1 */
+ switch (v) {
+
+ case DLT_SLIP:
+ v = DLT_SLIP_BSDOS;
+ break;
+
+ case DLT_PPP:
+ v = DLT_PPP_BSDOS;
+ break;
+
+ case 11: /*DLT_FR*/
+ v = DLT_FRELAY;
+ break;
+
+ case 12: /*DLT_C_HDLC*/
+ v = DLT_CHDLC;
+ break;
+ }
+#endif
+
+#ifdef BIOCGDLTLIST
+ /*
+ * We know the default link type -- now determine all the DLTs
+ * this interface supports. If this fails with EINVAL, it's
+ * not fatal; we just don't get to use the feature later.
+ */
+ if (get_dlt_list(fd, v, &bdl, p->errbuf) == -1) {
+ status = PCAP_ERROR;
+ goto bad;
+ }
+ p->dlt_count = bdl.bfl_len;
+ p->dlt_list = bdl.bfl_list;
+
+#ifdef __APPLE__
+ /*
+ * Monitor mode fun, continued.
+ *
+ * For 10.5 and, we're assuming, later releases, as noted above,
+ * 802.1 adapters that support monitor mode offer both DLT_EN10MB,
+ * DLT_IEEE802_11, and possibly some 802.11-plus-radio-information
+ * DLT_ value. Choosing one of the 802.11 DLT_ values will turn
+ * monitor mode on.
+ *
+ * Therefore, if the user asked for monitor mode, we filter out
+ * the DLT_EN10MB value, as you can't get that in monitor mode,
+ * and, if the user didn't ask for monitor mode, we filter out
+ * the 802.11 DLT_ values, because selecting those will turn
+ * monitor mode on. Then, for monitor mode, if an 802.11-plus-
+ * radio DLT_ value is offered, we try to select that, otherwise
+ * we try to select DLT_IEEE802_11.
+ */
+ if (have_osinfo) {
+ if (isdigit((unsigned)osinfo.release[0]) &&
+ (osinfo.release[0] == '9' ||
+ isdigit((unsigned)osinfo.release[1]))) {
+ /*
+ * 10.5 (Darwin 9.x), or later.
+ */
+ new_dlt = find_802_11(&bdl);
+ if (new_dlt != -1) {
+ /*
+ * We have at least one 802.11 DLT_ value,
+ * so this is an 802.11 interface.
+ * new_dlt is the best of the 802.11
+ * DLT_ values in the list.
+ */
+ if (p->opt.rfmon) {
+ /*
+ * Our caller wants monitor mode.
+ * Purge DLT_EN10MB from the list
+ * of link-layer types, as selecting
+ * it will keep monitor mode off.
+ */
+ remove_en(p);
+
+ /*
+ * If the new mode we want isn't
+ * the default mode, attempt to
+ * select the new mode.
+ */
+ if (new_dlt != v) {
+ if (ioctl(p->fd, BIOCSDLT,
+ &new_dlt) != -1) {
+ /*
+ * We succeeded;
+ * make this the
+ * new DLT_ value.
+ */
+ v = new_dlt;
+ }
+ }
+ } else {
+ /*
+ * Our caller doesn't want
+ * monitor mode. Unless this
+ * is being done by pcap_open_live(),
+ * purge the 802.11 link-layer types
+ * from the list, as selecting
+ * one of them will turn monitor
+ * mode on.
+ */
+ if (!p->oldstyle)
+ remove_802_11(p);
+ }
+ } else {
+ if (p->opt.rfmon) {
+ /*
+ * The caller requested monitor
+ * mode, but we have no 802.11
+ * link-layer types, so they
+ * can't have it.
+ */
+ status = PCAP_ERROR_RFMON_NOTSUP;
+ goto bad;
+ }
+ }
+ }
+ }
+#elif defined(HAVE_BSD_IEEE80211)
+ /*
+ * *BSD with the new 802.11 ioctls.
+ * Do we want monitor mode?
+ */
+ if (p->opt.rfmon) {
+ /*
+ * Try to put the interface into monitor mode.
+ */
+ status = monitor_mode(p, 1);
+ if (status != 0) {
+ /*
+ * We failed.
+ */
+ goto bad;
+ }
+
+ /*
+ * We're in monitor mode.
+ * Try to find the best 802.11 DLT_ value and, if we
+ * succeed, try to switch to that mode if we're not
+ * already in that mode.
+ */
+ new_dlt = find_802_11(&bdl);
+ if (new_dlt != -1) {
+ /*
+ * We have at least one 802.11 DLT_ value.
+ * new_dlt is the best of the 802.11
+ * DLT_ values in the list.
+ *
+ * If the new mode we want isn't the default mode,
+ * attempt to select the new mode.
+ */
+ if (new_dlt != v) {
+ if (ioctl(p->fd, BIOCSDLT, &new_dlt) != -1) {
+ /*
+ * We succeeded; make this the
+ * new DLT_ value.
+ */
+ v = new_dlt;
+ }
+ }
+ }
+ }
+#endif /* various platforms */
+#endif /* BIOCGDLTLIST */
+
+ /*
+ * If this is an Ethernet device, and we don't have a DLT_ list,
+ * give it a list with DLT_EN10MB and DLT_DOCSIS. (That'd give
+ * 802.11 interfaces DLT_DOCSIS, which isn't the right thing to
+ * do, but there's not much we can do about that without finding
+ * some other way of determining whether it's an Ethernet or 802.11
+ * device.)
+ */
+ if (v == DLT_EN10MB && p->dlt_count == 0) {
+ p->dlt_list = (u_int *) malloc(sizeof(u_int) * 2);
+ /*
+ * If that fails, just leave the list empty.
+ */
+ if (p->dlt_list != NULL) {
+ p->dlt_list[0] = DLT_EN10MB;
+ p->dlt_list[1] = DLT_DOCSIS;
+ p->dlt_count = 2;
+ }
+ }
+#ifdef PCAP_FDDIPAD
+ if (v == DLT_FDDI)
+ p->fddipad = PCAP_FDDIPAD;
+ else
+ p->fddipad = 0;
+#endif
+ p->linktype = v;
+
+#if defined(BIOCGHDRCMPLT) && defined(BIOCSHDRCMPLT)
+ /*
+ * Do a BIOCSHDRCMPLT, if defined, to turn that flag on, so
+ * the link-layer source address isn't forcibly overwritten.
+ * (Should we ignore errors? Should we do this only if
+ * we're open for writing?)
+ *
+ * XXX - I seem to remember some packet-sending bug in some
+ * BSDs - check CVS log for "bpf.c"?
+ */
+ if (ioctl(fd, BIOCSHDRCMPLT, &spoof_eth_src) == -1) {
+ (void)snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "BIOCSHDRCMPLT: %s", pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+#endif
+ /* set timeout */
+#ifdef HAVE_ZEROCOPY_BPF
+ if (p->md.timeout != 0 && !p->md.zerocopy) {
+#else
+ if (p->md.timeout) {
+#endif
+ /*
+ * XXX - is this seconds/nanoseconds in AIX?
+ * (Treating it as such doesn't fix the timeout
+ * problem described below.)
+ *
+ * XXX - Mac OS X 10.6 mishandles BIOCSRTIMEOUT in
+ * 64-bit userland - it takes, as an argument, a
+ * "struct BPF_TIMEVAL", which has 32-bit tv_sec
+ * and tv_usec, rather than a "struct timeval".
+ *
+ * If this platform defines "struct BPF_TIMEVAL",
+ * we check whether the structure size in BIOCSRTIMEOUT
+ * is that of a "struct timeval" and, if not, we use
+ * a "struct BPF_TIMEVAL" rather than a "struct timeval".
+ * (That way, if the bug is fixed in a future release,
+ * we will still do the right thing.)
+ */
+ struct timeval to;
+#ifdef HAVE_STRUCT_BPF_TIMEVAL
+ struct BPF_TIMEVAL bpf_to;
+
+ if (IOCPARM_LEN(BIOCSRTIMEOUT) != sizeof(struct timeval)) {
+ bpf_to.tv_sec = p->md.timeout / 1000;
+ bpf_to.tv_usec = (p->md.timeout * 1000) % 1000000;
+ if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&bpf_to) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "BIOCSRTIMEOUT: %s", pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+ } else {
+#endif
+ to.tv_sec = p->md.timeout / 1000;
+ to.tv_usec = (p->md.timeout * 1000) % 1000000;
+ if (ioctl(p->fd, BIOCSRTIMEOUT, (caddr_t)&to) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "BIOCSRTIMEOUT: %s", pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+#ifdef HAVE_STRUCT_BPF_TIMEVAL
+ }
+#endif
+ }
+
+#ifdef _AIX
+#ifdef BIOCIMMEDIATE
+ /*
+ * Darren Reed notes that
+ *
+ * On AIX (4.2 at least), if BIOCIMMEDIATE is not set, the
+ * timeout appears to be ignored and it waits until the buffer
+ * is filled before returning. The result of not having it
+ * set is almost worse than useless if your BPF filter
+ * is reducing things to only a few packets (i.e. one every
+ * second or so).
+ *
+ * so we turn BIOCIMMEDIATE mode on if this is AIX.
+ *
+ * We don't turn it on for other platforms, as that means we
+ * get woken up for every packet, which may not be what we want;
+ * in the Winter 1993 USENIX paper on BPF, they say:
+ *
+ * Since a process might want to look at every packet on a
+ * network and the time between packets can be only a few
+ * microseconds, it is not possible to do a read system call
+ * per packet and BPF must collect the data from several
+ * packets and return it as a unit when the monitoring
+ * application does a read.
+ *
+ * which I infer is the reason for the timeout - it means we
+ * wait that amount of time, in the hopes that more packets
+ * will arrive and we'll get them all with one read.
+ *
+ * Setting BIOCIMMEDIATE mode on FreeBSD (and probably other
+ * BSDs) causes the timeout to be ignored.
+ *
+ * On the other hand, some platforms (e.g., Linux) don't support
+ * timeouts, they just hand stuff to you as soon as it arrives;
+ * if that doesn't cause a problem on those platforms, it may
+ * be OK to have BIOCIMMEDIATE mode on BSD as well.
+ *
+ * (Note, though, that applications may depend on the read
+ * completing, even if no packets have arrived, when the timeout
+ * expires, e.g. GUI applications that have to check for input
+ * while waiting for packets to arrive; a non-zero timeout
+ * prevents "select()" from working right on FreeBSD and
+ * possibly other BSDs, as the timer doesn't start until a
+ * "read()" is done, so the timer isn't in effect if the
+ * application is blocked on a "select()", and the "select()"
+ * doesn't get woken up for a BPF device until the buffer
+ * fills up.)
+ */
+ v = 1;
+ if (ioctl(p->fd, BIOCIMMEDIATE, &v) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCIMMEDIATE: %s",
+ pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+#endif /* BIOCIMMEDIATE */
+#endif /* _AIX */
+
+ if (p->opt.promisc) {
+ /* set promiscuous mode, just warn if it fails */
+ if (ioctl(p->fd, BIOCPROMISC, NULL) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCPROMISC: %s",
+ pcap_strerror(errno));
+ status = PCAP_WARNING_PROMISC_NOTSUP;
+ }
+ }
+
+ if (ioctl(fd, BIOCGBLEN, (caddr_t)&v) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCGBLEN: %s",
+ pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+ p->bufsize = v;
+#ifdef HAVE_ZEROCOPY_BPF
+ if (!p->md.zerocopy) {
+#endif
+ p->buffer = (u_char *)malloc(p->bufsize);
+ if (p->buffer == NULL) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s",
+ pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+#ifdef _AIX
+ /* For some strange reason this seems to prevent the EFAULT
+ * problems we have experienced from AIX BPF. */
+ memset(p->buffer, 0x0, p->bufsize);
+#endif
+#ifdef HAVE_ZEROCOPY_BPF
+ }
+#endif
+
+ /*
+ * If there's no filter program installed, there's
+ * no indication to the kernel of what the snapshot
+ * length should be, so no snapshotting is done.
+ *
+ * Therefore, when we open the device, we install
+ * an "accept everything" filter with the specified
+ * snapshot length.
+ */
+ total_insn.code = (u_short)(BPF_RET | BPF_K);
+ total_insn.jt = 0;
+ total_insn.jf = 0;
+ total_insn.k = p->snapshot;
+
+ total_prog.bf_len = 1;
+ total_prog.bf_insns = &total_insn;
+ if (ioctl(p->fd, BIOCSETF, (caddr_t)&total_prog) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
+ pcap_strerror(errno));
+ status = PCAP_ERROR;
+ goto bad;
+ }
+
+ /*
+ * On most BPF platforms, either you can do a "select()" or
+ * "poll()" on a BPF file descriptor and it works correctly,
+ * or you can do it and it will return "readable" if the
+ * hold buffer is full but not if the timeout expires *and*
+ * a non-blocking read will, if the hold buffer is empty
+ * but the store buffer isn't empty, rotate the buffers
+ * and return what packets are available.
+ *
+ * In the latter case, the fact that a non-blocking read
+ * will give you the available packets means you can work
+ * around the failure of "select()" and "poll()" to wake up
+ * and return "readable" when the timeout expires by using
+ * the timeout as the "select()" or "poll()" timeout, putting
+ * the BPF descriptor into non-blocking mode, and read from
+ * it regardless of whether "select()" reports it as readable
+ * or not.
+ *
+ * However, in FreeBSD 4.3 and 4.4, "select()" and "poll()"
+ * won't wake up and return "readable" if the timer expires
+ * and non-blocking reads return EWOULDBLOCK if the hold
+ * buffer is empty, even if the store buffer is non-empty.
+ *
+ * This means the workaround in question won't work.
+ *
+ * Therefore, on FreeBSD 4.3 and 4.4, we set "p->selectable_fd"
+ * to -1, which means "sorry, you can't use 'select()' or 'poll()'
+ * here". On all other BPF platforms, we set it to the FD for
+ * the BPF device; in NetBSD, OpenBSD, and Darwin, a non-blocking
+ * read will, if the hold buffer is empty and the store buffer
+ * isn't empty, rotate the buffers and return what packets are
+ * there (and in sufficiently recent versions of OpenBSD
+ * "select()" and "poll()" should work correctly).
+ *
+ * XXX - what about AIX?
+ */
+ p->selectable_fd = p->fd; /* assume select() works until we know otherwise */
+ if (have_osinfo) {
+ /*
+ * We can check what OS this is.
+ */
+ if (strcmp(osinfo.sysname, "FreeBSD") == 0) {
+ if (strncmp(osinfo.release, "4.3-", 4) == 0 ||
+ strncmp(osinfo.release, "4.4-", 4) == 0)
+ p->selectable_fd = -1;
+ }
+ }
+
+ p->read_op = pcap_read_bpf;
+ p->inject_op = pcap_inject_bpf;
+ p->setfilter_op = pcap_setfilter_bpf;
+ p->setdirection_op = pcap_setdirection_bpf;
+ p->set_datalink_op = pcap_set_datalink_bpf;
+ p->getnonblock_op = pcap_getnonblock_bpf;
+ p->setnonblock_op = pcap_setnonblock_bpf;
+ p->stats_op = pcap_stats_bpf;
+ p->cleanup_op = pcap_cleanup_bpf;
+
+ return (status);
+ bad:
+ pcap_cleanup_bpf(p);
+ return (status);
+}
+
+int
+pcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf)
+{
+ return (0);
+}
+
+#ifdef HAVE_BSD_IEEE80211
+static int
+monitor_mode(pcap_t *p, int set)
+{
+ int sock;
+ struct ifmediareq req;
+ int *media_list;
+ int i;
+ int can_do;
+ struct ifreq ifr;
+
+ sock = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sock == -1) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "can't open socket: %s",
+ pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+
+ memset(&req, 0, sizeof req);
+ strncpy(req.ifm_name, p->opt.source, sizeof req.ifm_name);
+
+ /*
+ * Find out how many media types we have.
+ */
+ if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) {
+ /*
+ * Can't get the media types.
+ */
+ switch (errno) {
+
+ case ENXIO:
+ /*
+ * There's no such device.
+ */
+ close(sock);
+ return (PCAP_ERROR_NO_SUCH_DEVICE);
+
+ case EINVAL:
+ /*
+ * Interface doesn't support SIOC{G,S}IFMEDIA.
+ */
+ close(sock);
+ return (PCAP_ERROR_RFMON_NOTSUP);
+
+ default:
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "SIOCGIFMEDIA 1: %s", pcap_strerror(errno));
+ close(sock);
+ return (PCAP_ERROR);
+ }
+ }
+ if (req.ifm_count == 0) {
+ /*
+ * No media types.
+ */
+ close(sock);
+ return (PCAP_ERROR_RFMON_NOTSUP);
+ }
+
+ /*
+ * Allocate a buffer to hold all the media types, and
+ * get the media types.
+ */
+ media_list = malloc(req.ifm_count * sizeof(int));
+ if (media_list == NULL) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "malloc: %s",
+ pcap_strerror(errno));
+ close(sock);
+ return (PCAP_ERROR);
+ }
+ req.ifm_ulist = media_list;
+ if (ioctl(sock, SIOCGIFMEDIA, &req) < 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "SIOCGIFMEDIA: %s",
+ pcap_strerror(errno));
+ free(media_list);
+ close(sock);
+ return (PCAP_ERROR);
+ }
+
+ /*
+ * Look for an 802.11 "automatic" media type.
+ * We assume that all 802.11 adapters have that media type,
+ * and that it will carry the monitor mode supported flag.
+ */
+ can_do = 0;
+ for (i = 0; i < req.ifm_count; i++) {
+ if (IFM_TYPE(media_list[i]) == IFM_IEEE80211
+ && IFM_SUBTYPE(media_list[i]) == IFM_AUTO) {
+ /* OK, does it do monitor mode? */
+ if (media_list[i] & IFM_IEEE80211_MONITOR) {
+ can_do = 1;
+ break;
+ }
+ }
+ }
+ free(media_list);
+ if (!can_do) {
+ /*
+ * This adapter doesn't support monitor mode.
+ */
+ close(sock);
+ return (PCAP_ERROR_RFMON_NOTSUP);
+ }
+
+ if (set) {
+ /*
+ * Don't just check whether we can enable monitor mode,
+ * do so, if it's not already enabled.
+ */
+ if ((req.ifm_current & IFM_IEEE80211_MONITOR) == 0) {
+ /*
+ * Monitor mode isn't currently on, so turn it on,
+ * and remember that we should turn it off when the
+ * pcap_t is closed.
+ */
+
+ /*
+ * If we haven't already done so, arrange to have
+ * "pcap_close_all()" called when we exit.
+ */
+ if (!pcap_do_addexit(p)) {
+ /*
+ * "atexit()" failed; don't put the interface
+ * in monitor mode, just give up.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "atexit failed");
+ close(sock);
+ return (PCAP_ERROR);
+ }
+ memset(&ifr, 0, sizeof(ifr));
+ (void)strncpy(ifr.ifr_name, p->opt.source,
+ sizeof(ifr.ifr_name));
+ ifr.ifr_media = req.ifm_current | IFM_IEEE80211_MONITOR;
+ if (ioctl(sock, SIOCSIFMEDIA, &ifr) == -1) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "SIOCSIFMEDIA: %s", pcap_strerror(errno));
+ close(sock);
+ return (PCAP_ERROR);
+ }
+
+ p->md.must_do_on_close |= MUST_CLEAR_RFMON;
+
+ /*
+ * Add this to the list of pcaps to close when we exit.
+ */
+ pcap_add_to_pcaps_to_close(p);
+ }
+ }
+ return (0);
+}
+#endif /* HAVE_BSD_IEEE80211 */
+
+#if defined(BIOCGDLTLIST) && (defined(__APPLE__) || defined(HAVE_BSD_IEEE80211))
+/*
+ * Check whether we have any 802.11 link-layer types; return the best
+ * of the 802.11 link-layer types if we find one, and return -1
+ * otherwise.
+ *
+ * DLT_IEEE802_11_RADIO, with the radiotap header, is considered the
+ * best 802.11 link-layer type; any of the other 802.11-plus-radio
+ * headers are second-best; 802.11 with no radio information is
+ * the least good.
+ */
+static int
+find_802_11(struct bpf_dltlist *bdlp)
+{
+ int new_dlt;
+ int i;
+
+ /*
+ * Scan the list of DLT_ values, looking for 802.11 values,
+ * and, if we find any, choose the best of them.
+ */
+ new_dlt = -1;
+ for (i = 0; i < bdlp->bfl_len; i++) {
+ switch (bdlp->bfl_list[i]) {
+
+ case DLT_IEEE802_11:
+ /*
+ * 802.11, but no radio.
+ *
+ * Offer this, and select it as the new mode
+ * unless we've already found an 802.11
+ * header with radio information.
+ */
+ if (new_dlt == -1)
+ new_dlt = bdlp->bfl_list[i];
+ break;
+
+ case DLT_PRISM_HEADER:
+ case DLT_AIRONET_HEADER:
+ case DLT_IEEE802_11_RADIO_AVS:
+ /*
+ * 802.11 with radio, but not radiotap.
+ *
+ * Offer this, and select it as the new mode
+ * unless we've already found the radiotap DLT_.
+ */
+ if (new_dlt != DLT_IEEE802_11_RADIO)
+ new_dlt = bdlp->bfl_list[i];
+ break;
+
+ case DLT_IEEE802_11_RADIO:
+ /*
+ * 802.11 with radiotap.
+ *
+ * Offer this, and select it as the new mode.
+ */
+ new_dlt = bdlp->bfl_list[i];
+ break;
+
+ default:
+ /*
+ * Not 802.11.
+ */
+ break;
+ }
+ }
+
+ return (new_dlt);
+}
+#endif /* defined(BIOCGDLTLIST) && (defined(__APPLE__) || defined(HAVE_BSD_IEEE80211)) */
+
+#if defined(__APPLE__) && defined(BIOCGDLTLIST)
+/*
+ * Remove DLT_EN10MB from the list of DLT_ values, as we're in monitor mode,
+ * and DLT_EN10MB isn't supported in monitor mode.
+ */
+static void
+remove_en(pcap_t *p)
+{
+ int i, j;
+
+ /*
+ * Scan the list of DLT_ values and discard DLT_EN10MB.
+ */
+ j = 0;
+ for (i = 0; i < p->dlt_count; i++) {
+ switch (p->dlt_list[i]) {
+
+ case DLT_EN10MB:
+ /*
+ * Don't offer this one.
+ */
+ continue;
+
+ default:
+ /*
+ * Just copy this mode over.
+ */
+ break;
+ }
+
+ /*
+ * Copy this DLT_ value to its new position.
+ */
+ p->dlt_list[j] = p->dlt_list[i];
+ j++;
+ }
+
+ /*
+ * Set the DLT_ count to the number of entries we copied.
+ */
+ p->dlt_count = j;
+}
+
+/*
+ * Remove 802.11 link-layer types from the list of DLT_ values, as
+ * we're not in monitor mode, and those DLT_ values will switch us
+ * to monitor mode.
+ */
+static void
+remove_802_11(pcap_t *p)
+{
+ int i, j;
+
+ /*
+ * Scan the list of DLT_ values and discard 802.11 values.
+ */
+ j = 0;
+ for (i = 0; i < p->dlt_count; i++) {
+ switch (p->dlt_list[i]) {
+
+ case DLT_IEEE802_11:
+ case DLT_PRISM_HEADER:
+ case DLT_AIRONET_HEADER:
+ case DLT_IEEE802_11_RADIO:
+ case DLT_IEEE802_11_RADIO_AVS:
+ /*
+ * 802.11. Don't offer this one.
+ */
+ continue;
+
+ default:
+ /*
+ * Just copy this mode over.
+ */
+ break;
+ }
+
+ /*
+ * Copy this DLT_ value to its new position.
+ */
+ p->dlt_list[j] = p->dlt_list[i];
+ j++;
+ }
+
+ /*
+ * Set the DLT_ count to the number of entries we copied.
+ */
+ p->dlt_count = j;
+}
+#endif /* defined(__APPLE__) && defined(BIOCGDLTLIST) */
+
+static int
+pcap_setfilter_bpf(pcap_t *p, struct bpf_program *fp)
+{
+ /*
+ * Free any user-mode filter we might happen to have installed.
+ */
+ pcap_freecode(&p->fcode);
+
+ /*
+ * Try to install the kernel filter.
+ */
+ if (ioctl(p->fd, BIOCSETF, (caddr_t)fp) == 0) {
+ /*
+ * It worked.
+ */
+ p->md.use_bpf = 1; /* filtering in the kernel */
+
+ /*
+ * Discard any previously-received packets, as they might
+ * have passed whatever filter was formerly in effect, but
+ * might not pass this filter (BIOCSETF discards packets
+ * buffered in the kernel, so you can lose packets in any
+ * case).
+ */
+ p->cc = 0;
+ return (0);
+ }
+
+ /*
+ * We failed.
+ *
+ * If it failed with EINVAL, that's probably because the program
+ * is invalid or too big. Validate it ourselves; if we like it
+ * (we currently allow backward branches, to support protochain),
+ * run it in userland. (There's no notion of "too big" for
+ * userland.)
+ *
+ * Otherwise, just give up.
+ * XXX - if the copy of the program into the kernel failed,
+ * we will get EINVAL rather than, say, EFAULT on at least
+ * some kernels.
+ */
+ if (errno != EINVAL) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "BIOCSETF: %s",
+ pcap_strerror(errno));
+ return (-1);
+ }
+
+ /*
+ * install_bpf_program() validates the program.
+ *
+ * XXX - what if we already have a filter in the kernel?
+ */
+ if (install_bpf_program(p, fp) < 0)
+ return (-1);
+ p->md.use_bpf = 0; /* filtering in userland */
+ return (0);
+}
+
+/*
+ * Set direction flag: Which packets do we accept on a forwarding
+ * single device? IN, OUT or both?
+ */
+static int
+pcap_setdirection_bpf(pcap_t *p, pcap_direction_t d)
+{
+#if defined(BIOCSDIRECTION)
+ u_int direction;
+
+ direction = (d == PCAP_D_IN) ? BPF_D_IN :
+ ((d == PCAP_D_OUT) ? BPF_D_OUT : BPF_D_INOUT);
+ if (ioctl(p->fd, BIOCSDIRECTION, &direction) == -1) {
+ (void) snprintf(p->errbuf, sizeof(p->errbuf),
+ "Cannot set direction to %s: %s",
+ (d == PCAP_D_IN) ? "PCAP_D_IN" :
+ ((d == PCAP_D_OUT) ? "PCAP_D_OUT" : "PCAP_D_INOUT"),
+ strerror(errno));
+ return (-1);
+ }
+ return (0);
+#elif defined(BIOCSSEESENT)
+ u_int seesent;
+
+ /*
+ * We don't support PCAP_D_OUT.
+ */
+ if (d == PCAP_D_OUT) {
+ snprintf(p->errbuf, sizeof(p->errbuf),
+ "Setting direction to PCAP_D_OUT is not supported on BPF");
+ return -1;
+ }
+
+ seesent = (d == PCAP_D_INOUT);
+ if (ioctl(p->fd, BIOCSSEESENT, &seesent) == -1) {
+ (void) snprintf(p->errbuf, sizeof(p->errbuf),
+ "Cannot set direction to %s: %s",
+ (d == PCAP_D_INOUT) ? "PCAP_D_INOUT" : "PCAP_D_IN",
+ strerror(errno));
+ return (-1);
+ }
+ return (0);
+#else
+ (void) snprintf(p->errbuf, sizeof(p->errbuf),
+ "This system doesn't support BIOCSSEESENT, so the direction can't be set");
+ return (-1);
+#endif
+}
+
+static int
+pcap_set_datalink_bpf(pcap_t *p, int dlt)
+{
+#ifdef BIOCSDLT
+ if (ioctl(p->fd, BIOCSDLT, &dlt) == -1) {
+ (void) snprintf(p->errbuf, sizeof(p->errbuf),
+ "Cannot set DLT %d: %s", dlt, strerror(errno));
+ return (-1);
+ }
+#endif
+ return (0);
+}
diff --git a/freebsd/contrib/libpcap/pcap-common.c b/freebsd/contrib/libpcap/pcap-common.c
new file mode 100644
index 00000000..7b683a9e
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap-common.c
@@ -0,0 +1,1174 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * pcap-common.c - common code for pcap and pcap-ng files
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <rtems/bsd/sys/types.h>
+#endif /* WIN32 */
+
+#include "pcap-int.h"
+#include "pcap/usb.h"
+
+#include "pcap-common.h"
+
+/*
+ * We don't write DLT_* values to capture files, because they're not the
+ * same on all platforms.
+ *
+ * Unfortunately, the various flavors of BSD have not always used the same
+ * numerical values for the same data types, and various patches to
+ * libpcap for non-BSD OSes have added their own DLT_* codes for link
+ * layer encapsulation types seen on those OSes, and those codes have had,
+ * in some cases, values that were also used, on other platforms, for other
+ * link layer encapsulation types.
+ *
+ * This means that capture files of a type whose numerical DLT_* code
+ * means different things on different BSDs, or with different versions
+ * of libpcap, can't always be read on systems other than those like
+ * the one running on the machine on which the capture was made.
+ *
+ * Instead, we define here a set of LINKTYPE_* codes, and map DLT_* codes
+ * to LINKTYPE_* codes when writing a savefile header, and map LINKTYPE_*
+ * codes to DLT_* codes when reading a savefile header.
+ *
+ * For those DLT_* codes that have, as far as we know, the same values on
+ * all platforms (DLT_NULL through DLT_FDDI), we define LINKTYPE_xxx as
+ * DLT_xxx; that way, captures of those types can still be read by
+ * versions of libpcap that map LINKTYPE_* values to DLT_* values, and
+ * captures of those types written by versions of libpcap that map DLT_
+ * values to LINKTYPE_ values can still be read by older versions
+ * of libpcap.
+ *
+ * The other LINKTYPE_* codes are given values starting at 100, in the
+ * hopes that no DLT_* code will be given one of those values.
+ *
+ * In order to ensure that a given LINKTYPE_* code's value will refer to
+ * the same encapsulation type on all platforms, you should not allocate
+ * a new LINKTYPE_* value without consulting
+ * "tcpdump-workers@lists.tcpdump.org". The tcpdump developers will
+ * allocate a value for you, and will not subsequently allocate it to
+ * anybody else; that value will be added to the "pcap.h" in the
+ * tcpdump.org Git repository, so that a future libpcap release will
+ * include it.
+ *
+ * You should, if possible, also contribute patches to libpcap and tcpdump
+ * to handle the new encapsulation type, so that they can also be checked
+ * into the tcpdump.org Git repository and so that they will appear in
+ * future libpcap and tcpdump releases.
+ *
+ * Do *NOT* assume that any values after the largest value in this file
+ * are available; you might not have the most up-to-date version of this
+ * file, and new values after that one might have been assigned. Also,
+ * do *NOT* use any values below 100 - those might already have been
+ * taken by one (or more!) organizations.
+ *
+ * Any platform that defines additional DLT_* codes should:
+ *
+ * request a LINKTYPE_* code and value from tcpdump.org,
+ * as per the above;
+ *
+ * add, in their version of libpcap, an entry to map
+ * those DLT_* codes to the corresponding LINKTYPE_*
+ * code;
+ *
+ * redefine, in their "net/bpf.h", any DLT_* values
+ * that collide with the values used by their additional
+ * DLT_* codes, to remove those collisions (but without
+ * making them collide with any of the LINKTYPE_*
+ * values equal to 50 or above; they should also avoid
+ * defining DLT_* values that collide with those
+ * LINKTYPE_* values, either).
+ */
+#define LINKTYPE_NULL DLT_NULL
+#define LINKTYPE_ETHERNET DLT_EN10MB /* also for 100Mb and up */
+#define LINKTYPE_EXP_ETHERNET DLT_EN3MB /* 3Mb experimental Ethernet */
+#define LINKTYPE_AX25 DLT_AX25
+#define LINKTYPE_PRONET DLT_PRONET
+#define LINKTYPE_CHAOS DLT_CHAOS
+#define LINKTYPE_IEEE802_5 DLT_IEEE802 /* DLT_IEEE802 is used for 802.5 Token Ring */
+#define LINKTYPE_ARCNET_BSD DLT_ARCNET /* BSD-style headers */
+#define LINKTYPE_SLIP DLT_SLIP
+#define LINKTYPE_PPP DLT_PPP
+#define LINKTYPE_FDDI DLT_FDDI
+
+/*
+ * LINKTYPE_PPP is for use when there might, or might not, be an RFC 1662
+ * PPP in HDLC-like framing header (with 0xff 0x03 before the PPP protocol
+ * field) at the beginning of the packet.
+ *
+ * This is for use when there is always such a header; the address field
+ * might be 0xff, for regular PPP, or it might be an address field for Cisco
+ * point-to-point with HDLC framing as per section 4.3.1 of RFC 1547 ("Cisco
+ * HDLC"). This is, for example, what you get with NetBSD's DLT_PPP_SERIAL.
+ *
+ * We give it the same value as NetBSD's DLT_PPP_SERIAL, in the hopes that
+ * nobody else will choose a DLT_ value of 50, and so that DLT_PPP_SERIAL
+ * captures will be written out with a link type that NetBSD's tcpdump
+ * can read.
+ */
+#define LINKTYPE_PPP_HDLC 50 /* PPP in HDLC-like framing */
+
+#define LINKTYPE_PPP_ETHER 51 /* NetBSD PPP-over-Ethernet */
+
+#define LINKTYPE_SYMANTEC_FIREWALL 99 /* Symantec Enterprise Firewall */
+
+/*
+ * These correspond to DLT_s that have different values on different
+ * platforms; we map between these values in capture files and
+ * the DLT_ values as returned by pcap_datalink() and passed to
+ * pcap_open_dead().
+ */
+#define LINKTYPE_ATM_RFC1483 100 /* LLC/SNAP-encapsulated ATM */
+#define LINKTYPE_RAW 101 /* raw IP */
+#define LINKTYPE_SLIP_BSDOS 102 /* BSD/OS SLIP BPF header */
+#define LINKTYPE_PPP_BSDOS 103 /* BSD/OS PPP BPF header */
+
+/*
+ * Values starting with 104 are used for newly-assigned link-layer
+ * header type values; for those link-layer header types, the DLT_
+ * value returned by pcap_datalink() and passed to pcap_open_dead(),
+ * and the LINKTYPE_ value that appears in capture files, are the
+ * same.
+ *
+ * LINKTYPE_MATCHING_MIN is the lowest such value; LINKTYPE_MATCHING_MAX
+ * is the highest such value.
+ */
+#define LINKTYPE_MATCHING_MIN 104 /* lowest value in the "matching" range */
+
+#define LINKTYPE_C_HDLC 104 /* Cisco HDLC */
+#define LINKTYPE_IEEE802_11 105 /* IEEE 802.11 (wireless) */
+#define LINKTYPE_ATM_CLIP 106 /* Linux Classical IP over ATM */
+#define LINKTYPE_FRELAY 107 /* Frame Relay */
+#define LINKTYPE_LOOP 108 /* OpenBSD loopback */
+#define LINKTYPE_ENC 109 /* OpenBSD IPSEC enc */
+
+/*
+ * These three types are reserved for future use.
+ */
+#define LINKTYPE_LANE8023 110 /* ATM LANE + 802.3 */
+#define LINKTYPE_HIPPI 111 /* NetBSD HIPPI */
+#define LINKTYPE_HDLC 112 /* NetBSD HDLC framing */
+
+#define LINKTYPE_LINUX_SLL 113 /* Linux cooked socket capture */
+#define LINKTYPE_LTALK 114 /* Apple LocalTalk hardware */
+#define LINKTYPE_ECONET 115 /* Acorn Econet */
+
+/*
+ * Reserved for use with OpenBSD ipfilter.
+ */
+#define LINKTYPE_IPFILTER 116
+
+#define LINKTYPE_PFLOG 117 /* OpenBSD DLT_PFLOG */
+#define LINKTYPE_CISCO_IOS 118 /* For Cisco-internal use */
+#define LINKTYPE_IEEE802_11_PRISM 119 /* 802.11 plus Prism II monitor mode radio metadata header */
+#define LINKTYPE_IEEE802_11_AIRONET 120 /* 802.11 plus FreeBSD Aironet driver radio metadata header */
+
+/*
+ * Reserved for Siemens HiPath HDLC.
+ */
+#define LINKTYPE_HHDLC 121
+
+#define LINKTYPE_IP_OVER_FC 122 /* RFC 2625 IP-over-Fibre Channel */
+#define LINKTYPE_SUNATM 123 /* Solaris+SunATM */
+
+/*
+ * Reserved as per request from Kent Dahlgren <kent@praesum.com>
+ * for private use.
+ */
+#define LINKTYPE_RIO 124 /* RapidIO */
+#define LINKTYPE_PCI_EXP 125 /* PCI Express */
+#define LINKTYPE_AURORA 126 /* Xilinx Aurora link layer */
+
+#define LINKTYPE_IEEE802_11_RADIOTAP 127 /* 802.11 plus radiotap radio metadata header */
+
+/*
+ * Reserved for the TZSP encapsulation, as per request from
+ * Chris Waters <chris.waters@networkchemistry.com>
+ * TZSP is a generic encapsulation for any other link type,
+ * which includes a means to include meta-information
+ * with the packet, e.g. signal strength and channel
+ * for 802.11 packets.
+ */
+#define LINKTYPE_TZSP 128 /* Tazmen Sniffer Protocol */
+
+#define LINKTYPE_ARCNET_LINUX 129 /* Linux-style headers */
+
+/*
+ * Juniper-private data link types, as per request from
+ * Hannes Gredler <hannes@juniper.net>. The corresponding
+ * DLT_s are used for passing on chassis-internal
+ * metainformation such as QOS profiles, etc..
+ */
+#define LINKTYPE_JUNIPER_MLPPP 130
+#define LINKTYPE_JUNIPER_MLFR 131
+#define LINKTYPE_JUNIPER_ES 132
+#define LINKTYPE_JUNIPER_GGSN 133
+#define LINKTYPE_JUNIPER_MFR 134
+#define LINKTYPE_JUNIPER_ATM2 135
+#define LINKTYPE_JUNIPER_SERVICES 136
+#define LINKTYPE_JUNIPER_ATM1 137
+
+#define LINKTYPE_APPLE_IP_OVER_IEEE1394 138 /* Apple IP-over-IEEE 1394 cooked header */
+
+#define LINKTYPE_MTP2_WITH_PHDR 139
+#define LINKTYPE_MTP2 140
+#define LINKTYPE_MTP3 141
+#define LINKTYPE_SCCP 142
+
+#define LINKTYPE_DOCSIS 143 /* DOCSIS MAC frames */
+
+#define LINKTYPE_LINUX_IRDA 144 /* Linux-IrDA */
+
+/*
+ * Reserved for IBM SP switch and IBM Next Federation switch.
+ */
+#define LINKTYPE_IBM_SP 145
+#define LINKTYPE_IBM_SN 146
+
+/*
+ * Reserved for private use. If you have some link-layer header type
+ * that you want to use within your organization, with the capture files
+ * using that link-layer header type not ever be sent outside your
+ * organization, you can use these values.
+ *
+ * No libpcap release will use these for any purpose, nor will any
+ * tcpdump release use them, either.
+ *
+ * Do *NOT* use these in capture files that you expect anybody not using
+ * your private versions of capture-file-reading tools to read; in
+ * particular, do *NOT* use them in products, otherwise you may find that
+ * people won't be able to use tcpdump, or snort, or Ethereal, or... to
+ * read capture files from your firewall/intrusion detection/traffic
+ * monitoring/etc. appliance, or whatever product uses that LINKTYPE_ value,
+ * and you may also find that the developers of those applications will
+ * not accept patches to let them read those files.
+ *
+ * Also, do not use them if somebody might send you a capture using them
+ * for *their* private type and tools using them for *your* private type
+ * would have to read them.
+ *
+ * Instead, in those cases, ask "tcpdump-workers@lists.tcpdump.org" for a
+ * new DLT_ and LINKTYPE_ value, as per the comment in pcap/bpf.h, and use
+ * the type you're given.
+ */
+#define LINKTYPE_USER0 147
+#define LINKTYPE_USER1 148
+#define LINKTYPE_USER2 149
+#define LINKTYPE_USER3 150
+#define LINKTYPE_USER4 151
+#define LINKTYPE_USER5 152
+#define LINKTYPE_USER6 153
+#define LINKTYPE_USER7 154
+#define LINKTYPE_USER8 155
+#define LINKTYPE_USER9 156
+#define LINKTYPE_USER10 157
+#define LINKTYPE_USER11 158
+#define LINKTYPE_USER12 159
+#define LINKTYPE_USER13 160
+#define LINKTYPE_USER14 161
+#define LINKTYPE_USER15 162
+
+/*
+ * For future use with 802.11 captures - defined by AbsoluteValue
+ * Systems to store a number of bits of link-layer information
+ * including radio information:
+ *
+ * http://www.shaftnet.org/~pizza/software/capturefrm.txt
+ */
+#define LINKTYPE_IEEE802_11_AVS 163 /* 802.11 plus AVS radio metadata header */
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>. The corresponding
+ * DLT_s are used for passing on chassis-internal
+ * metainformation such as QOS profiles, etc..
+ */
+#define LINKTYPE_JUNIPER_MONITOR 164
+
+/*
+ * BACnet MS/TP frames.
+ */
+#define LINKTYPE_BACNET_MS_TP 165
+
+/*
+ * Another PPP variant as per request from Karsten Keil <kkeil@suse.de>.
+ *
+ * This is used in some OSes to allow a kernel socket filter to distinguish
+ * between incoming and outgoing packets, on a socket intended to
+ * supply pppd with outgoing packets so it can do dial-on-demand and
+ * hangup-on-lack-of-demand; incoming packets are filtered out so they
+ * don't cause pppd to hold the connection up (you don't want random
+ * input packets such as port scans, packets from old lost connections,
+ * etc. to force the connection to stay up).
+ *
+ * The first byte of the PPP header (0xff03) is modified to accomodate
+ * the direction - 0x00 = IN, 0x01 = OUT.
+ */
+#define LINKTYPE_PPP_PPPD 166
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>. The DLT_s are used
+ * for passing on chassis-internal metainformation such as
+ * QOS profiles, cookies, etc..
+ */
+#define LINKTYPE_JUNIPER_PPPOE 167
+#define LINKTYPE_JUNIPER_PPPOE_ATM 168
+
+#define LINKTYPE_GPRS_LLC 169 /* GPRS LLC */
+#define LINKTYPE_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */
+#define LINKTYPE_GPF_F 171 /* GPF-T (ITU-T G.7041/Y.1303) */
+
+/*
+ * Requested by Oolan Zimmer <oz@gcom.com> for use in Gcom's T1/E1 line
+ * monitoring equipment.
+ */
+#define LINKTYPE_GCOM_T1E1 172
+#define LINKTYPE_GCOM_SERIAL 173
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>. The DLT_ is used
+ * for internal communication to Physical Interface Cards (PIC)
+ */
+#define LINKTYPE_JUNIPER_PIC_PEER 174
+
+/*
+ * Link types requested by Gregor Maier <gregor@endace.com> of Endace
+ * Measurement Systems. They add an ERF header (see
+ * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of
+ * the link-layer header.
+ */
+#define LINKTYPE_ERF_ETH 175 /* Ethernet */
+#define LINKTYPE_ERF_POS 176 /* Packet-over-SONET */
+
+/*
+ * Requested by Daniele Orlandi <daniele@orlandi.com> for raw LAPD
+ * for vISDN (http://www.orlandi.com/visdn/). Its link-layer header
+ * includes additional information before the LAPD header, so it's
+ * not necessarily a generic LAPD header.
+ */
+#define LINKTYPE_LINUX_LAPD 177
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>.
+ * The Link Types are used for prepending meta-information
+ * like interface index, interface name
+ * before standard Ethernet, PPP, Frelay & C-HDLC Frames
+ */
+#define LINKTYPE_JUNIPER_ETHER 178
+#define LINKTYPE_JUNIPER_PPP 179
+#define LINKTYPE_JUNIPER_FRELAY 180
+#define LINKTYPE_JUNIPER_CHDLC 181
+
+/*
+ * Multi Link Frame Relay (FRF.16)
+ */
+#define LINKTYPE_MFR 182
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>.
+ * The DLT_ is used for internal communication with a
+ * voice Adapter Card (PIC)
+ */
+#define LINKTYPE_JUNIPER_VP 183
+
+/*
+ * Arinc 429 frames.
+ * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
+ * Every frame contains a 32bit A429 label.
+ * More documentation on Arinc 429 can be found at
+ * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf
+ */
+#define LINKTYPE_A429 184
+
+/*
+ * Arinc 653 Interpartition Communication messages.
+ * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
+ * Please refer to the A653-1 standard for more information.
+ */
+#define LINKTYPE_A653_ICM 185
+
+/*
+ * USB packets, beginning with a USB setup header; requested by
+ * Paolo Abeni <paolo.abeni@email.it>.
+ */
+#define LINKTYPE_USB 186
+
+/*
+ * Bluetooth HCI UART transport layer (part H:4); requested by
+ * Paolo Abeni.
+ */
+#define LINKTYPE_BLUETOOTH_HCI_H4 187
+
+/*
+ * IEEE 802.16 MAC Common Part Sublayer; requested by Maria Cruz
+ * <cruz_petagay@bah.com>.
+ */
+#define LINKTYPE_IEEE802_16_MAC_CPS 188
+
+/*
+ * USB packets, beginning with a Linux USB header; requested by
+ * Paolo Abeni <paolo.abeni@email.it>.
+ */
+#define LINKTYPE_USB_LINUX 189
+
+/*
+ * Controller Area Network (CAN) v. 2.0B packets.
+ * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
+ * Used to dump CAN packets coming from a CAN Vector board.
+ * More documentation on the CAN v2.0B frames can be found at
+ * http://www.can-cia.org/downloads/?269
+ */
+#define LINKTYPE_CAN20B 190
+
+/*
+ * IEEE 802.15.4, with address fields padded, as is done by Linux
+ * drivers; requested by Juergen Schimmer.
+ */
+#define LINKTYPE_IEEE802_15_4_LINUX 191
+
+/*
+ * Per Packet Information encapsulated packets.
+ * LINKTYPE_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
+ */
+#define LINKTYPE_PPI 192
+
+/*
+ * Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header;
+ * requested by Charles Clancy.
+ */
+#define LINKTYPE_IEEE802_16_MAC_CPS_RADIO 193
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>.
+ * The DLT_ is used for internal communication with a
+ * integrated service module (ISM).
+ */
+#define LINKTYPE_JUNIPER_ISM 194
+
+/*
+ * IEEE 802.15.4, exactly as it appears in the spec (no padding, no
+ * nothing); requested by Mikko Saarnivala <mikko.saarnivala@sensinode.com>.
+ */
+#define LINKTYPE_IEEE802_15_4 195
+
+/*
+ * Various link-layer types, with a pseudo-header, for SITA
+ * (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com).
+ */
+#define LINKTYPE_SITA 196
+
+/*
+ * Various link-layer types, with a pseudo-header, for Endace DAG cards;
+ * encapsulates Endace ERF records. Requested by Stephen Donnelly
+ * <stephen@endace.com>.
+ */
+#define LINKTYPE_ERF 197
+
+/*
+ * Special header prepended to Ethernet packets when capturing from a
+ * u10 Networks board. Requested by Phil Mulholland
+ * <phil@u10networks.com>.
+ */
+#define LINKTYPE_RAIF1 198
+
+/*
+ * IPMB packet for IPMI, beginning with the I2C slave address, followed
+ * by the netFn and LUN, etc.. Requested by Chanthy Toeung
+ * <chanthy.toeung@ca.kontron.com>.
+ */
+#define LINKTYPE_IPMB 199
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>.
+ * The DLT_ is used for capturing data on a secure tunnel interface.
+ */
+#define LINKTYPE_JUNIPER_ST 200
+
+/*
+ * Bluetooth HCI UART transport layer (part H:4), with pseudo-header
+ * that includes direction information; requested by Paolo Abeni.
+ */
+#define LINKTYPE_BLUETOOTH_HCI_H4_WITH_PHDR 201
+
+/*
+ * AX.25 packet with a 1-byte KISS header; see
+ *
+ * http://www.ax25.net/kiss.htm
+ *
+ * as per Richard Stearn <richard@rns-stearn.demon.co.uk>.
+ */
+#define LINKTYPE_AX25_KISS 202
+
+/*
+ * LAPD packets from an ISDN channel, starting with the address field,
+ * with no pseudo-header.
+ * Requested by Varuna De Silva <varunax@gmail.com>.
+ */
+#define LINKTYPE_LAPD 203
+
+/*
+ * Variants of various link-layer headers, with a one-byte direction
+ * pseudo-header prepended - zero means "received by this host",
+ * non-zero (any non-zero value) means "sent by this host" - as per
+ * Will Barker <w.barker@zen.co.uk>.
+ */
+#define LINKTYPE_PPP_WITH_DIR 204 /* PPP */
+#define LINKTYPE_C_HDLC_WITH_DIR 205 /* Cisco HDLC */
+#define LINKTYPE_FRELAY_WITH_DIR 206 /* Frame Relay */
+#define LINKTYPE_LAPB_WITH_DIR 207 /* LAPB */
+
+/*
+ * 208 is reserved for an as-yet-unspecified proprietary link-layer
+ * type, as requested by Will Barker.
+ */
+
+/*
+ * IPMB with a Linux-specific pseudo-header; as requested by Alexey Neyman
+ * <avn@pigeonpoint.com>.
+ */
+#define LINKTYPE_IPMB_LINUX 209
+
+/*
+ * FlexRay automotive bus - http://www.flexray.com/ - as requested
+ * by Hannes Kaelber <hannes.kaelber@x2e.de>.
+ */
+#define LINKTYPE_FLEXRAY 210
+
+/*
+ * Media Oriented Systems Transport (MOST) bus for multimedia
+ * transport - http://www.mostcooperation.com/ - as requested
+ * by Hannes Kaelber <hannes.kaelber@x2e.de>.
+ */
+#define LINKTYPE_MOST 211
+
+/*
+ * Local Interconnect Network (LIN) bus for vehicle networks -
+ * http://www.lin-subbus.org/ - as requested by Hannes Kaelber
+ * <hannes.kaelber@x2e.de>.
+ */
+#define LINKTYPE_LIN 212
+
+/*
+ * X2E-private data link type used for serial line capture,
+ * as requested by Hannes Kaelber <hannes.kaelber@x2e.de>.
+ */
+#define LINKTYPE_X2E_SERIAL 213
+
+/*
+ * X2E-private data link type used for the Xoraya data logger
+ * family, as requested by Hannes Kaelber <hannes.kaelber@x2e.de>.
+ */
+#define LINKTYPE_X2E_XORAYA 214
+
+/*
+ * IEEE 802.15.4, exactly as it appears in the spec (no padding, no
+ * nothing), but with the PHY-level data for non-ASK PHYs (4 octets
+ * of 0 as preamble, one octet of SFD, one octet of frame length+
+ * reserved bit, and then the MAC-layer data, starting with the
+ * frame control field).
+ *
+ * Requested by Max Filippov <jcmvbkbc@gmail.com>.
+ */
+#define LINKTYPE_IEEE802_15_4_NONASK_PHY 215
+
+/*
+ * David Gibson <david@gibson.dropbear.id.au> requested this for
+ * captures from the Linux kernel /dev/input/eventN devices. This
+ * is used to communicate keystrokes and mouse movements from the
+ * Linux kernel to display systems, such as Xorg.
+ */
+#define LINKTYPE_LINUX_EVDEV 216
+
+/*
+ * GSM Um and Abis interfaces, preceded by a "gsmtap" header.
+ *
+ * Requested by Harald Welte <laforge@gnumonks.org>.
+ */
+#define LINKTYPE_GSMTAP_UM 217
+#define LINKTYPE_GSMTAP_ABIS 218
+
+/*
+ * MPLS, with an MPLS label as the link-layer header.
+ * Requested by Michele Marchetto <michele@openbsd.org> on behalf
+ * of OpenBSD.
+ */
+#define LINKTYPE_MPLS 219
+
+/*
+ * USB packets, beginning with a Linux USB header, with the USB header
+ * padded to 64 bytes; required for memory-mapped access.
+ */
+#define LINKTYPE_USB_LINUX_MMAPPED 220
+
+/*
+ * DECT packets, with a pseudo-header; requested by
+ * Matthias Wenzel <tcpdump@mazzoo.de>.
+ */
+#define LINKTYPE_DECT 221
+
+/*
+ * From: "Lidwa, Eric (GSFC-582.0)[SGT INC]" <eric.lidwa-1@nasa.gov>
+ * Date: Mon, 11 May 2009 11:18:30 -0500
+ *
+ * DLT_AOS. We need it for AOS Space Data Link Protocol.
+ * I have already written dissectors for but need an OK from
+ * legal before I can submit a patch.
+ *
+ */
+#define LINKTYPE_AOS 222
+
+/*
+ * Wireless HART (Highway Addressable Remote Transducer)
+ * From the HART Communication Foundation
+ * IES/PAS 62591
+ *
+ * Requested by Sam Roberts <vieuxtech@gmail.com>.
+ */
+#define LINKTYPE_WIHART 223
+
+/*
+ * Fibre Channel FC-2 frames, beginning with a Frame_Header.
+ * Requested by Kahou Lei <kahou82@gmail.com>.
+ */
+#define LINKTYPE_FC_2 224
+
+/*
+ * Fibre Channel FC-2 frames, beginning with an encoding of the
+ * SOF, and ending with an encoding of the EOF.
+ *
+ * The encodings represent the frame delimiters as 4-byte sequences
+ * representing the corresponding ordered sets, with K28.5
+ * represented as 0xBC, and the D symbols as the corresponding
+ * byte values; for example, SOFi2, which is K28.5 - D21.5 - D1.2 - D21.2,
+ * is represented as 0xBC 0xB5 0x55 0x55.
+ *
+ * Requested by Kahou Lei <kahou82@gmail.com>.
+ */
+#define LINKTYPE_FC_2_WITH_FRAME_DELIMS 225
+
+/*
+ * Solaris ipnet pseudo-header; requested by Darren Reed <Darren.Reed@Sun.COM>.
+ *
+ * The pseudo-header starts with a one-byte version number; for version 2,
+ * the pseudo-header is:
+ *
+ * struct dl_ipnetinfo {
+ * u_int8_t dli_version;
+ * u_int8_t dli_family;
+ * u_int16_t dli_htype;
+ * u_int32_t dli_pktlen;
+ * u_int32_t dli_ifindex;
+ * u_int32_t dli_grifindex;
+ * u_int32_t dli_zsrc;
+ * u_int32_t dli_zdst;
+ * };
+ *
+ * dli_version is 2 for the current version of the pseudo-header.
+ *
+ * dli_family is a Solaris address family value, so it's 2 for IPv4
+ * and 26 for IPv6.
+ *
+ * dli_htype is a "hook type" - 0 for incoming packets, 1 for outgoing
+ * packets, and 2 for packets arriving from another zone on the same
+ * machine.
+ *
+ * dli_pktlen is the length of the packet data following the pseudo-header
+ * (so the captured length minus dli_pktlen is the length of the
+ * pseudo-header, assuming the entire pseudo-header was captured).
+ *
+ * dli_ifindex is the interface index of the interface on which the
+ * packet arrived.
+ *
+ * dli_grifindex is the group interface index number (for IPMP interfaces).
+ *
+ * dli_zsrc is the zone identifier for the source of the packet.
+ *
+ * dli_zdst is the zone identifier for the destination of the packet.
+ *
+ * A zone number of 0 is the global zone; a zone number of 0xffffffff
+ * means that the packet arrived from another host on the network, not
+ * from another zone on the same machine.
+ *
+ * An IPv4 or IPv6 datagram follows the pseudo-header; dli_family indicates
+ * which of those it is.
+ */
+#define LINKTYPE_IPNET 226
+
+/*
+ * CAN (Controller Area Network) frames, with a pseudo-header as supplied
+ * by Linux SocketCAN. See Documentation/networking/can.txt in the Linux
+ * source.
+ *
+ * Requested by Felix Obenhuber <felix@obenhuber.de>.
+ */
+#define LINKTYPE_CAN_SOCKETCAN 227
+
+/*
+ * Raw IPv4/IPv6; different from DLT_RAW in that the DLT_ value specifies
+ * whether it's v4 or v6. Requested by Darren Reed <Darren.Reed@Sun.COM>.
+ */
+#define LINKTYPE_IPV4 228
+#define LINKTYPE_IPV6 229
+
+/*
+ * IEEE 802.15.4, exactly as it appears in the spec (no padding, no
+ * nothing), and with no FCS at the end of the frame; requested by
+ * Jon Smirl <jonsmirl@gmail.com>.
+ */
+#define LINKTYPE_IEEE802_15_4_NOFCS 230
+
+/*
+ * Raw D-Bus:
+ *
+ * http://www.freedesktop.org/wiki/Software/dbus
+ *
+ * messages:
+ *
+ * http://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-messages
+ *
+ * starting with the endianness flag, followed by the message type, etc.,
+ * but without the authentication handshake before the message sequence:
+ *
+ * http://dbus.freedesktop.org/doc/dbus-specification.html#auth-protocol
+ *
+ * Requested by Martin Vidner <martin@vidner.net>.
+ */
+#define LINKTYPE_DBUS 231
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>.
+ */
+#define LINKTYPE_JUNIPER_VS 232
+#define LINKTYPE_JUNIPER_SRX_E2E 233
+#define LINKTYPE_JUNIPER_FIBRECHANNEL 234
+
+/*
+ * DVB-CI (DVB Common Interface for communication between a PC Card
+ * module and a DVB receiver). See
+ *
+ * http://www.kaiser.cx/pcap-dvbci.html
+ *
+ * for the specification.
+ *
+ * Requested by Martin Kaiser <martin@kaiser.cx>.
+ */
+#define LINKTYPE_DVB_CI 235
+
+/*
+ * Variant of 3GPP TS 27.010 multiplexing protocol. Requested
+ * by Hans-Christoph Schemmel <hans-christoph.schemmel@cinterion.com>.
+ */
+#define LINKTYPE_MUX27010 236
+
+/*
+ * STANAG 5066 D_PDUs. Requested by M. Baris Demiray
+ * <barisdemiray@gmail.com>.
+ */
+#define LINKTYPE_STANAG_5066_D_PDU 237
+
+/*
+ * Juniper-private data link type, as per request from
+ * Hannes Gredler <hannes@juniper.net>.
+ */
+#define LINKTYPE_JUNIPER_ATM_CEMIC 238
+
+/*
+ * NetFilter LOG messages
+ * (payload of netlink NFNL_SUBSYS_ULOG/NFULNL_MSG_PACKET packets)
+ *
+ * Requested by Jakub Zawadzki <darkjames-ws@darkjames.pl>
+ */
+#define LINKTYPE_NFLOG 239
+
+/*
+ * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type
+ * for Ethernet packets with a 4-byte pseudo-header and always
+ * with the payload including the FCS, as supplied by their
+ * netANALYZER hardware and software.
+ *
+ * Requested by Holger P. Frommer <HPfrommer@hilscher.com>
+ */
+#define LINKTYPE_NETANALYZER 240
+
+/*
+ * Hilscher Gesellschaft fuer Systemautomation mbH link-layer type
+ * for Ethernet packets with a 4-byte pseudo-header and FCS and
+ * 1 byte of SFD, as supplied by their netANALYZER hardware and
+ * software.
+ *
+ * Requested by Holger P. Frommer <HPfrommer@hilscher.com>
+ */
+#define LINKTYPE_NETANALYZER_TRANSPARENT 241
+
+/*
+ * IP-over-InfiniBand, as specified by RFC 4391.
+ *
+ * Requested by Petr Sumbera <petr.sumbera@oracle.com>.
+ */
+#define LINKTYPE_IPOIB 242
+
+/*
+ * MPEG-2 transport stream (ISO 13818-1/ITU-T H.222.0).
+ *
+ * Requested by Guy Martin <gmsoft@tuxicoman.be>.
+ */
+#define LINKTYPE_MPEG_2_TS 243
+
+/*
+ * ng4T GmbH's UMTS Iub/Iur-over-ATM and Iub/Iur-over-IP format as
+ * used by their ng40 protocol tester.
+ *
+ * Requested by Jens Grimmer <jens.grimmer@ng4t.com>.
+ */
+#define LINKTYPE_NG40 244
+
+/*
+ * Pseudo-header giving adapter number and flags, followed by an NFC
+ * (Near-Field Communications) Logical Link Control Protocol (LLCP) PDU,
+ * as specified by NFC Forum Logical Link Control Protocol Technical
+ * Specification LLCP 1.1.
+ *
+ * Requested by Mike Wakerly <mikey@google.com>.
+ */
+#define LINKTYPE_NFC_LLCP 245
+
+/*
+ * pfsync output; DLT_PFSYNC is 18, which collides with DLT_CIP in
+ * SuSE 6.3, on OpenBSD, NetBSD, DragonFly BSD, and Mac OS X, and
+ * is 121, which collides with DLT_HHDLC, in FreeBSD. We pick a
+ * shiny new link-layer header type value that doesn't collide with
+ * anything, in the hopes that future pfsync savefiles, if any,
+ * won't require special hacks to distinguish from other savefiles.
+ *
+ */
+#define LINKTYPE_PFSYNC 246
+
+/*
+ * Raw InfiniBand packets, starting with the Local Routing Header.
+ *
+ * Requested by Oren Kladnitsky <orenk@mellanox.com>.
+ */
+#define LINKTYPE_INFINIBAND 247
+
+/*
+ * SCTP, with no lower-level protocols (i.e., no IPv4 or IPv6).
+ *
+ * Requested by Michael Tuexen <Michael.Tuexen@lurchi.franken.de>.
+ */
+#define LINKTYPE_SCTP 248
+
+#define LINKTYPE_MATCHING_MAX 248 /* highest value in the "matching" range */
+
+static struct linktype_map {
+ int dlt;
+ int linktype;
+} map[] = {
+ /*
+ * These DLT_* codes have LINKTYPE_* codes with values identical
+ * to the values of the corresponding DLT_* code.
+ */
+ { DLT_NULL, LINKTYPE_NULL },
+ { DLT_EN10MB, LINKTYPE_ETHERNET },
+ { DLT_EN3MB, LINKTYPE_EXP_ETHERNET },
+ { DLT_AX25, LINKTYPE_AX25 },
+ { DLT_PRONET, LINKTYPE_PRONET },
+ { DLT_CHAOS, LINKTYPE_CHAOS },
+ { DLT_IEEE802, LINKTYPE_IEEE802_5 },
+ { DLT_ARCNET, LINKTYPE_ARCNET_BSD },
+ { DLT_SLIP, LINKTYPE_SLIP },
+ { DLT_PPP, LINKTYPE_PPP },
+ { DLT_FDDI, LINKTYPE_FDDI },
+ { DLT_SYMANTEC_FIREWALL, LINKTYPE_SYMANTEC_FIREWALL },
+
+ /*
+ * These DLT_* codes have different values on different
+ * platforms; we map them to LINKTYPE_* codes that
+ * have values that should never be equal to any DLT_*
+ * code.
+ */
+#ifdef DLT_FR
+ /* BSD/OS Frame Relay */
+ { DLT_FR, LINKTYPE_FRELAY },
+#endif
+
+ { DLT_ATM_RFC1483, LINKTYPE_ATM_RFC1483 },
+ { DLT_RAW, LINKTYPE_RAW },
+ { DLT_SLIP_BSDOS, LINKTYPE_SLIP_BSDOS },
+ { DLT_PPP_BSDOS, LINKTYPE_PPP_BSDOS },
+
+ /* BSD/OS Cisco HDLC */
+ { DLT_C_HDLC, LINKTYPE_C_HDLC },
+
+ /*
+ * These DLT_* codes are not on all platforms, but, so far,
+ * there don't appear to be any platforms that define
+ * other codes with those values; we map them to
+ * different LINKTYPE_* values anyway, just in case.
+ */
+
+ /* Linux ATM Classical IP */
+ { DLT_ATM_CLIP, LINKTYPE_ATM_CLIP },
+
+ /* NetBSD sync/async serial PPP (or Cisco HDLC) */
+ { DLT_PPP_SERIAL, LINKTYPE_PPP_HDLC },
+
+ /* NetBSD PPP over Ethernet */
+ { DLT_PPP_ETHER, LINKTYPE_PPP_ETHER },
+
+ /*
+ * All LINKTYPE_ values between LINKTYPE_MATCHING_MIN
+ * and LINKTYPE_MATCHING_MAX are mapped to identical
+ * DLT_ values.
+ */
+
+ { -1, -1 }
+};
+
+int
+dlt_to_linktype(int dlt)
+{
+ int i;
+
+ /*
+ * Map DLT_PFSYNC, whatever it might be, to LINKTYPE_PFSYNC.
+ */
+ if (dlt == DLT_PFSYNC)
+ return (LINKTYPE_PFSYNC);
+
+ /*
+ * Map the values in the matching range.
+ */
+ if (dlt >= DLT_MATCHING_MIN && dlt <= DLT_MATCHING_MAX)
+ return (dlt);
+
+ /*
+ * Map the values outside that range.
+ */
+ for (i = 0; map[i].dlt != -1; i++) {
+ if (map[i].dlt == dlt)
+ return (map[i].linktype);
+ }
+
+ /*
+ * If we don't have a mapping for this DLT_ code, return an
+ * error; that means that this is a value with no corresponding
+ * LINKTYPE_ code, and we need to assign one.
+ */
+ return (-1);
+}
+
+int
+linktype_to_dlt(int linktype)
+{
+ int i;
+
+ /*
+ * Map LINKTYPE_PFSYNC to DLT_PFSYNC, whatever it might be.
+ * LINKTYPE_PFSYNC is in the matching range, to make sure
+ * it's as safe from reuse as we can arrange, so we do
+ * this test first.
+ */
+ if (linktype == LINKTYPE_PFSYNC)
+ return (DLT_PFSYNC);
+
+ /*
+ * Map the values in the matching range.
+ */
+ if (linktype >= LINKTYPE_MATCHING_MIN &&
+ linktype <= LINKTYPE_MATCHING_MAX)
+ return (linktype);
+
+ /*
+ * Map the values outside that range.
+ */
+ for (i = 0; map[i].linktype != -1; i++) {
+ if (map[i].linktype == linktype)
+ return (map[i].dlt);
+ }
+
+ /*
+ * If we don't have an entry for this link type, return
+ * the link type value; it may be a DLT_ value from an
+ * older version of libpcap.
+ */
+ return linktype;
+}
+
+/*
+ * The DLT_USB_LINUX and DLT_USB_LINUX_MMAPPED headers are in host
+ * byte order when capturing (it's supplied directly from a
+ * memory-mapped buffer shared by the kernel).
+ *
+ * When reading a DLT_USB_LINUX or DLT_USB_LINUX_MMAPPED capture file,
+ * we need to convert it from the capturing host's byte order to
+ * the reading host's byte order.
+ */
+void
+swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
+ int header_len_64_bytes)
+{
+ pcap_usb_header_mmapped *uhdr = (pcap_usb_header_mmapped *)buf;
+ bpf_u_int32 offset = 0;
+ usb_isodesc *pisodesc;
+ int32_t numdesc, i;
+
+ /*
+ * "offset" is the offset *past* the field we're swapping;
+ * we skip the field *before* checking to make sure
+ * the captured data length includes the entire field.
+ */
+
+ /*
+ * The URB id is a totally opaque value; do we really need to
+ * convert it to the reading host's byte order???
+ */
+ offset += 8; /* skip past id */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->id = SWAPLL(uhdr->id);
+
+ offset += 4; /* skip past various 1-byte fields */
+
+ offset += 2; /* skip past bus_id */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->bus_id = SWAPSHORT(uhdr->bus_id);
+
+ offset += 2; /* skip past various 1-byte fields */
+
+ offset += 8; /* skip past ts_sec */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->ts_sec = SWAPLL(uhdr->ts_sec);
+
+ offset += 4; /* skip past ts_usec */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->ts_usec = SWAPLONG(uhdr->ts_usec);
+
+ offset += 4; /* skip past status */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->status = SWAPLONG(uhdr->status);
+
+ offset += 4; /* skip past urb_len */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->urb_len = SWAPLONG(uhdr->urb_len);
+
+ offset += 4; /* skip past data_len */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->data_len = SWAPLONG(uhdr->data_len);
+
+ if (uhdr->transfer_type == URB_ISOCHRONOUS) {
+ offset += 4; /* skip past s.iso.error_count */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->s.iso.error_count = SWAPLONG(uhdr->s.iso.error_count);
+
+ offset += 4; /* skip past s.iso.numdesc */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->s.iso.numdesc = SWAPLONG(uhdr->s.iso.numdesc);
+ } else
+ offset += 8; /* skip USB setup header */
+
+ if (header_len_64_bytes) {
+ /*
+ * This is either the "version 1" header, with
+ * 16 bytes of additional fields at the end, or
+ * a "version 0" header from a memory-mapped
+ * capture, with 16 bytes of zeroed-out padding
+ * at the end. Byte swap them as if this were
+ * a "version 1" header.
+ */
+ offset += 4; /* skip past interval */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->interval = SWAPLONG(uhdr->interval);
+
+ offset += 4; /* skip past start_frame */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->start_frame = SWAPLONG(uhdr->start_frame);
+
+ offset += 4; /* skip past xfer_flags */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->xfer_flags = SWAPLONG(uhdr->xfer_flags);
+
+ offset += 4; /* skip past ndesc */
+ if (hdr->caplen < offset)
+ return;
+ uhdr->ndesc = SWAPLONG(uhdr->ndesc);
+ }
+
+ if (uhdr->transfer_type == URB_ISOCHRONOUS) {
+ /* swap the values in struct linux_usb_isodesc */
+ pisodesc = (usb_isodesc *)(void *)(buf+offset);
+ numdesc = uhdr->s.iso.numdesc;
+ for (i = 0; i < numdesc; i++) {
+ offset += 4; /* skip past status */
+ if (hdr->caplen < offset)
+ return;
+ pisodesc->status = SWAPLONG(pisodesc->status);
+
+ offset += 4; /* skip past offset */
+ if (hdr->caplen < offset)
+ return;
+ pisodesc->offset = SWAPLONG(pisodesc->offset);
+
+ offset += 4; /* skip past len */
+ if (hdr->caplen < offset)
+ return;
+ pisodesc->len = SWAPLONG(pisodesc->len);
+
+ offset += 4; /* skip past padding */
+
+ pisodesc++;
+ }
+ }
+}
diff --git a/freebsd/contrib/libpcap/pcap-common.h b/freebsd/contrib/libpcap/pcap-common.h
new file mode 100644
index 00000000..0c80ba32
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap-common.h
@@ -0,0 +1,25 @@
+
+/*
+ * We use the "receiver-makes-right" approach to byte order,
+ * because time is at a premium when we are writing the file.
+ * In other words, the pcap_file_header and pcap_pkthdr,
+ * records are written in host byte order.
+ * Note that the bytes of packet data are written out in the order in
+ * which they were received, so multi-byte fields in packets are not
+ * written in host byte order, they're written in whatever order the
+ * sending machine put them in.
+ *
+ * ntoh[ls] aren't sufficient because we might need to swap on a big-endian
+ * machine (if the file was written in little-end order).
+ */
+#define SWAPLONG(y) \
+((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
+#define SWAPSHORT(y) \
+ ( (((y)&0xff)<<8) | ((u_short)((y)&0xff00)>>8) )
+
+extern int dlt_to_linktype(int dlt);
+
+extern int linktype_to_dlt(int linktype);
+
+extern void swap_linux_usb_header(const struct pcap_pkthdr *hdr, u_char *buf,
+ int header_len_64_bytes);
diff --git a/freebsd/contrib/libpcap/pcap-int.h b/freebsd/contrib/libpcap/pcap-int.h
new file mode 100644
index 00000000..059b597c
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap-int.h
@@ -0,0 +1,513 @@
+/*
+ * Copyright (c) 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/pcap-int.h,v 1.94 2008-09-16 00:20:23 guy Exp $ (LBL)
+ */
+
+#ifndef pcap_int_h
+#define pcap_int_h
+
+#include <pcap/pcap.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef HAVE_LIBDLPI
+#include <libdlpi.h>
+#endif
+
+#ifdef WIN32
+#include <Packet32.h>
+extern CRITICAL_SECTION g_PcapCompileCriticalSection;
+#endif /* WIN32 */
+
+#ifdef MSDOS
+#include <fcntl.h>
+#include <io.h>
+#endif
+
+#ifdef HAVE_SNF_API
+#include <snf.h>
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER <= 1200)) /* we are compiling with Visual Studio 6, that doesn't support the LL suffix*/
+
+/*
+ * Swap byte ordering of unsigned long long timestamp on a big endian
+ * machine.
+ */
+#define SWAPLL(ull) ((ull & 0xff00000000000000) >> 56) | \
+ ((ull & 0x00ff000000000000) >> 40) | \
+ ((ull & 0x0000ff0000000000) >> 24) | \
+ ((ull & 0x000000ff00000000) >> 8) | \
+ ((ull & 0x00000000ff000000) << 8) | \
+ ((ull & 0x0000000000ff0000) << 24) | \
+ ((ull & 0x000000000000ff00) << 40) | \
+ ((ull & 0x00000000000000ff) << 56)
+
+#else /* A recent Visual studio compiler or not VC */
+
+/*
+ * Swap byte ordering of unsigned long long timestamp on a big endian
+ * machine.
+ */
+#define SWAPLL(ull) ((ull & 0xff00000000000000LL) >> 56) | \
+ ((ull & 0x00ff000000000000LL) >> 40) | \
+ ((ull & 0x0000ff0000000000LL) >> 24) | \
+ ((ull & 0x000000ff00000000LL) >> 8) | \
+ ((ull & 0x00000000ff000000LL) << 8) | \
+ ((ull & 0x0000000000ff0000LL) << 24) | \
+ ((ull & 0x000000000000ff00LL) << 40) | \
+ ((ull & 0x00000000000000ffLL) << 56)
+
+#endif /* _MSC_VER */
+
+/*
+ * Savefile
+ */
+typedef enum {
+ NOT_SWAPPED,
+ SWAPPED,
+ MAYBE_SWAPPED
+} swapped_type_t;
+
+/*
+ * Used when reading a savefile.
+ */
+struct pcap_sf {
+ FILE *rfile;
+ int (*next_packet_op)(pcap_t *, struct pcap_pkthdr *, u_char **);
+ int swapped;
+ size_t hdrsize;
+ swapped_type_t lengths_swapped;
+ int version_major;
+ int version_minor;
+ bpf_u_int32 ifcount; /* number of interfaces seen in this capture */
+ u_int tsresol; /* time stamp resolution */
+ u_int tsscale; /* scaling factor for resolution -> microseconds */
+ u_int64_t tsoffset; /* time stamp offset */
+};
+
+/*
+ * Used when doing a live capture.
+ */
+struct pcap_md {
+ struct pcap_stat stat;
+ /*XXX*/
+ int use_bpf; /* using kernel filter */
+ u_long TotPkts; /* can't oflow for 79 hrs on ether */
+ u_long TotAccepted; /* count accepted by filter */
+ u_long TotDrops; /* count of dropped packets */
+ long TotMissed; /* missed by i/f during this run */
+ long OrigMissed; /* missed by i/f before this run */
+ char *device; /* device name */
+ int timeout; /* timeout for buffering */
+ int must_do_on_close; /* stuff we must do when we close */
+ struct pcap *next; /* list of open pcaps that need stuff cleared on close */
+#ifdef linux
+ int sock_packet; /* using Linux 2.0 compatible interface */
+ int cooked; /* using SOCK_DGRAM rather than SOCK_RAW */
+ int ifindex; /* interface index of device we're bound to */
+ int lo_ifindex; /* interface index of the loopback device */
+ u_int packets_read; /* count of packets read with recvfrom() */
+ bpf_u_int32 oldmode; /* mode to restore when turning monitor mode off */
+ char *mondevice; /* mac80211 monitor device we created */
+ u_char *mmapbuf; /* memory-mapped region pointer */
+ size_t mmapbuflen; /* size of region */
+ int vlan_offset; /* offset at which to insert vlan tags; if -1, don't insert */
+ u_int tp_version; /* version of tpacket_hdr for mmaped ring */
+ u_int tp_hdrlen; /* hdrlen of tpacket_hdr for mmaped ring */
+ u_char *oneshot_buffer; /* buffer for copy of packet */
+ long proc_dropped; /* packets reported dropped by /proc/net/dev */
+#endif /* linux */
+
+#ifdef HAVE_DAG_API
+#ifdef HAVE_DAG_STREAMS_API
+ u_char *dag_mem_bottom; /* DAG card current memory bottom pointer */
+ u_char *dag_mem_top; /* DAG card current memory top pointer */
+#else /* HAVE_DAG_STREAMS_API */
+ void *dag_mem_base; /* DAG card memory base address */
+ u_int dag_mem_bottom; /* DAG card current memory bottom offset */
+ u_int dag_mem_top; /* DAG card current memory top offset */
+#endif /* HAVE_DAG_STREAMS_API */
+ int dag_fcs_bits; /* Number of checksum bits from link layer */
+ int dag_offset_flags; /* Flags to pass to dag_offset(). */
+ int dag_stream; /* DAG stream number */
+ int dag_timeout; /* timeout specified to pcap_open_live.
+ * Same as in linux above, introduce
+ * generally? */
+#endif /* HAVE_DAG_API */
+#ifdef HAVE_SNF_API
+ snf_handle_t snf_handle; /* opaque device handle */
+ snf_ring_t snf_ring; /* opaque device ring handle */
+ int snf_timeout;
+ int snf_boardnum;
+#endif /*HAVE_SNF_API*/
+
+#ifdef HAVE_ZEROCOPY_BPF
+ /*
+ * Zero-copy read buffer -- for zero-copy BPF. 'buffer' above will
+ * alternative between these two actual mmap'd buffers as required.
+ * As there is a header on the front size of the mmap'd buffer, only
+ * some of the buffer is exposed to libpcap as a whole via bufsize;
+ * zbufsize is the true size. zbuffer tracks the current zbuf
+ * assocated with buffer so that it can be used to decide which the
+ * next buffer to read will be.
+ */
+ u_char *zbuf1, *zbuf2, *zbuffer;
+ u_int zbufsize;
+ u_int zerocopy;
+ u_int interrupted;
+ struct timespec firstsel;
+ /*
+ * If there's currently a buffer being actively processed, then it is
+ * referenced here; 'buffer' is also pointed at it, but offset by the
+ * size of the header.
+ */
+ struct bpf_zbuf_header *bzh;
+#endif /* HAVE_ZEROCOPY_BPF */
+};
+
+/*
+ * Stuff to do when we close.
+ */
+#define MUST_CLEAR_PROMISC 0x00000001 /* clear promiscuous mode */
+#define MUST_CLEAR_RFMON 0x00000002 /* clear rfmon (monitor) mode */
+#define MUST_DELETE_MONIF 0x00000004 /* delete monitor-mode interface */
+
+struct pcap_opt {
+ int buffer_size;
+ char *source;
+ int promisc;
+ int rfmon;
+ int tstamp_type;
+};
+
+/*
+ * Ultrix, DEC OSF/1^H^H^H^H^H^H^H^H^HDigital UNIX^H^H^H^H^H^H^H^H^H^H^H^H
+ * Tru64 UNIX, and some versions of NetBSD pad FDDI packets to make everything
+ * line up on a nice boundary.
+ */
+#ifdef __NetBSD__
+#include <rtems/bsd/sys/param.h> /* needed to declare __NetBSD_Version__ */
+#endif
+
+#if defined(ultrix) || defined(__osf__) || (defined(__NetBSD__) && __NetBSD_Version__ > 106000000)
+#define PCAP_FDDIPAD 3
+#endif
+
+typedef int (*activate_op_t)(pcap_t *);
+typedef int (*can_set_rfmon_op_t)(pcap_t *);
+typedef int (*read_op_t)(pcap_t *, int cnt, pcap_handler, u_char *);
+typedef int (*inject_op_t)(pcap_t *, const void *, size_t);
+typedef int (*setfilter_op_t)(pcap_t *, struct bpf_program *);
+typedef int (*setdirection_op_t)(pcap_t *, pcap_direction_t);
+typedef int (*set_datalink_op_t)(pcap_t *, int);
+typedef int (*getnonblock_op_t)(pcap_t *, char *);
+typedef int (*setnonblock_op_t)(pcap_t *, int, char *);
+typedef int (*stats_op_t)(pcap_t *, struct pcap_stat *);
+#ifdef WIN32
+typedef int (*setbuff_op_t)(pcap_t *, int);
+typedef int (*setmode_op_t)(pcap_t *, int);
+typedef int (*setmintocopy_op_t)(pcap_t *, int);
+#endif
+typedef void (*cleanup_op_t)(pcap_t *);
+
+struct pcap {
+#ifdef WIN32
+ ADAPTER *adapter;
+ LPPACKET Packet;
+ int nonblock;
+#else
+ int fd;
+ int selectable_fd;
+ int send_fd;
+#endif /* WIN32 */
+
+#ifdef HAVE_LIBDLPI
+ dlpi_handle_t dlpi_hd;
+#endif
+ int snapshot;
+ int linktype; /* Network linktype */
+ int linktype_ext; /* Extended information stored in the linktype field of a file */
+ int tzoff; /* timezone offset */
+ int offset; /* offset for proper alignment */
+ int activated; /* true if the capture is really started */
+ int oldstyle; /* if we're opening with pcap_open_live() */
+
+ int break_loop; /* flag set to force break from packet-reading loop */
+
+#ifdef PCAP_FDDIPAD
+ int fddipad;
+#endif
+
+#ifdef MSDOS
+ void (*wait_proc)(void); /* call proc while waiting */
+#endif
+
+ struct pcap_sf sf;
+ struct pcap_md md;
+ struct pcap_opt opt;
+
+ /*
+ * Read buffer.
+ */
+ int bufsize;
+ u_char *buffer;
+ u_char *bp;
+ int cc;
+
+ /*
+ * Place holder for pcap_next().
+ */
+ u_char *pkt;
+
+ /* We're accepting only packets in this direction/these directions. */
+ pcap_direction_t direction;
+
+ /*
+ * Methods.
+ */
+ activate_op_t activate_op;
+ can_set_rfmon_op_t can_set_rfmon_op;
+ read_op_t read_op;
+ inject_op_t inject_op;
+ setfilter_op_t setfilter_op;
+ setdirection_op_t setdirection_op;
+ set_datalink_op_t set_datalink_op;
+ getnonblock_op_t getnonblock_op;
+ setnonblock_op_t setnonblock_op;
+ stats_op_t stats_op;
+
+ /*
+ * Routine to use as callback for pcap_next()/pcap_next_ex().
+ */
+ pcap_handler oneshot_callback;
+
+#ifdef WIN32
+ /*
+ * These are, at least currently, specific to the Win32 NPF
+ * driver.
+ */
+ setbuff_op_t setbuff_op;
+ setmode_op_t setmode_op;
+ setmintocopy_op_t setmintocopy_op;
+#endif
+ cleanup_op_t cleanup_op;
+
+ /*
+ * Placeholder for filter code if bpf not in kernel.
+ */
+ struct bpf_program fcode;
+
+ char errbuf[PCAP_ERRBUF_SIZE + 1];
+ int dlt_count;
+ u_int *dlt_list;
+ int tstamp_type_count;
+ u_int *tstamp_type_list;
+
+ struct pcap_pkthdr pcap_header; /* This is needed for the pcap_next_ex() to work */
+};
+
+/*
+ * This is a timeval as stored in a savefile.
+ * It has to use the same types everywhere, independent of the actual
+ * `struct timeval'; `struct timeval' has 32-bit tv_sec values on some
+ * platforms and 64-bit tv_sec values on other platforms, and writing
+ * out native `struct timeval' values would mean files could only be
+ * read on systems with the same tv_sec size as the system on which
+ * the file was written.
+ */
+
+struct pcap_timeval {
+ bpf_int32 tv_sec; /* seconds */
+ bpf_int32 tv_usec; /* microseconds */
+};
+
+/*
+ * This is a `pcap_pkthdr' as actually stored in a savefile.
+ *
+ * Do not change the format of this structure, in any way (this includes
+ * changes that only affect the length of fields in this structure),
+ * and do not make the time stamp anything other than seconds and
+ * microseconds (e.g., seconds and nanoseconds). Instead:
+ *
+ * introduce a new structure for the new format;
+ *
+ * send mail to "tcpdump-workers@lists.tcpdump.org", requesting
+ * a new magic number for your new capture file format, and, when
+ * you get the new magic number, put it in "savefile.c";
+ *
+ * use that magic number for save files with the changed record
+ * header;
+ *
+ * make the code in "savefile.c" capable of reading files with
+ * the old record header as well as files with the new record header
+ * (using the magic number to determine the header format).
+ *
+ * Then supply the changes by forking the branch at
+ *
+ * https://github.com/mcr/libpcap/issues
+ *
+ * and issuing a pull request, so that future versions of libpcap and
+ * programs that use it (such as tcpdump) will be able to read your new
+ * capture file format.
+ */
+
+struct pcap_sf_pkthdr {
+ struct pcap_timeval ts; /* time stamp */
+ bpf_u_int32 caplen; /* length of portion present */
+ bpf_u_int32 len; /* length this packet (off wire) */
+};
+
+/*
+ * How a `pcap_pkthdr' is actually stored in savefiles written
+ * by some patched versions of libpcap (e.g. the ones in Red
+ * Hat Linux 6.1 and 6.2).
+ *
+ * Do not change the format of this structure, in any way (this includes
+ * changes that only affect the length of fields in this structure).
+ * Instead, introduce a new structure, as per the above.
+ */
+
+struct pcap_sf_patched_pkthdr {
+ struct pcap_timeval ts; /* time stamp */
+ bpf_u_int32 caplen; /* length of portion present */
+ bpf_u_int32 len; /* length this packet (off wire) */
+ int index;
+ unsigned short protocol;
+ unsigned char pkt_type;
+};
+
+/*
+ * User data structure for the one-shot callback used for pcap_next()
+ * and pcap_next_ex().
+ */
+struct oneshot_userdata {
+ struct pcap_pkthdr *hdr;
+ const u_char **pkt;
+ pcap_t *pd;
+};
+
+int yylex(void);
+
+#ifndef min
+#define min(a, b) ((a) > (b) ? (b) : (a))
+#endif
+
+/* XXX should these be in pcap.h? */
+int pcap_offline_read(pcap_t *, int, pcap_handler, u_char *);
+int pcap_read(pcap_t *, int cnt, pcap_handler, u_char *);
+
+#ifndef HAVE_STRLCPY
+#define strlcpy(x, y, z) \
+ (strncpy((x), (y), (z)), \
+ ((z) <= 0 ? 0 : ((x)[(z) - 1] = '\0')), \
+ strlen((y)))
+#endif
+
+#include <stdarg.h>
+
+#if !defined(HAVE_SNPRINTF)
+#define snprintf pcap_snprintf
+extern int snprintf (char *, size_t, const char *, ...);
+#endif
+
+#if !defined(HAVE_VSNPRINTF)
+#define vsnprintf pcap_vsnprintf
+extern int vsnprintf (char *, size_t, const char *, va_list ap);
+#endif
+
+/*
+ * Routines that most pcap implementations can use for non-blocking mode.
+ */
+#if !defined(WIN32) && !defined(MSDOS)
+int pcap_getnonblock_fd(pcap_t *, char *);
+int pcap_setnonblock_fd(pcap_t *p, int, char *);
+#endif
+
+/*
+ * Internal interfaces for "pcap_create()".
+ *
+ * "pcap_create_interface()" is the routine to do a pcap_create on
+ * a regular network interface. There are multiple implementations
+ * of this, one for each platform type (Linux, BPF, DLPI, etc.),
+ * with the one used chosen by the configure script.
+ *
+ * "pcap_create_common()" allocates and fills in a pcap_t, for use
+ * by pcap_create routines.
+ */
+pcap_t *pcap_create_interface(const char *, char *);
+pcap_t *pcap_create_common(const char *, char *);
+int pcap_do_addexit(pcap_t *);
+void pcap_add_to_pcaps_to_close(pcap_t *);
+void pcap_remove_from_pcaps_to_close(pcap_t *);
+void pcap_cleanup_live_common(pcap_t *);
+int pcap_not_initialized(pcap_t *);
+int pcap_check_activated(pcap_t *);
+
+/*
+ * Internal interfaces for "pcap_findalldevs()".
+ *
+ * "pcap_findalldevs_interfaces()" finds interfaces using the
+ * "standard" mechanisms (SIOCGIFCONF, "getifaddrs()", etc.).
+ *
+ * "pcap_platform_finddevs()" is a platform-dependent routine to
+ * add devices not found by the "standard" mechanisms.
+ *
+ * "pcap_add_if()" adds an interface to the list of interfaces, for
+ * use by various "find interfaces" routines.
+ */
+int pcap_findalldevs_interfaces(pcap_if_t **, char *);
+int pcap_platform_finddevs(pcap_if_t **, char *);
+int add_addr_to_iflist(pcap_if_t **, const char *, u_int, struct sockaddr *,
+ size_t, struct sockaddr *, size_t, struct sockaddr *, size_t,
+ struct sockaddr *, size_t, char *);
+int pcap_add_if(pcap_if_t **, const char *, u_int, const char *, char *);
+struct sockaddr *dup_sockaddr(struct sockaddr *, size_t);
+int add_or_find_if(pcap_if_t **, pcap_if_t **, const char *, u_int,
+ const char *, char *);
+
+#ifdef WIN32
+char *pcap_win32strerror(void);
+#endif
+
+int install_bpf_program(pcap_t *, struct bpf_program *);
+
+int pcap_strcasecmp(const char *, const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/freebsd/contrib/libpcap/pcap-namedb.h b/freebsd/contrib/libpcap/pcap-namedb.h
new file mode 100644
index 00000000..d0b22310
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap-namedb.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 1994, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/pcap-namedb.h,v 1.13 2006-10-04 18:13:32 guy Exp $ (LBL)
+ */
+
+/*
+ * For backwards compatibility.
+ *
+ * Note to OS vendors: do NOT get rid of this file! Some applications
+ * might expect to be able to include <pcap-namedb.h>.
+ */
+#include <pcap/namedb.h>
diff --git a/freebsd/contrib/libpcap/pcap.c b/freebsd/contrib/libpcap/pcap.c
new file mode 100644
index 00000000..11334563
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap.c
@@ -0,0 +1,1812 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997, 1998
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if 0
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/pcap.c,v 1.128 2008-12-23 20:13:29 guy Exp $ (LBL)";
+#endif
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <rtems/bsd/sys/types.h>
+#include <sys/mman.h>
+#endif /* WIN32 */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#if !defined(_MSC_VER) && !defined(__BORLANDC__) && !defined(__MINGW32__)
+#include <unistd.h>
+#endif
+#include <fcntl.h>
+#include <errno.h>
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#ifdef MSDOS
+#include "pcap-dos.h"
+#endif
+
+#include "pcap-int.h"
+
+#ifdef HAVE_DAG_API
+#include "pcap-dag.h"
+#endif /* HAVE_DAG_API */
+
+#ifdef HAVE_SEPTEL_API
+#include "pcap-septel.h"
+#endif /* HAVE_SEPTEL_API */
+
+#ifdef HAVE_SNF_API
+#include "pcap-snf.h"
+#endif /* HAVE_SNF_API */
+
+#ifdef PCAP_SUPPORT_USB
+#include "pcap-usb-linux.h"
+#endif
+
+#ifdef PCAP_SUPPORT_BT
+#include "pcap-bt-linux.h"
+#endif
+
+#ifdef PCAP_SUPPORT_CAN
+#include "pcap-can-linux.h"
+#endif
+
+#ifdef PCAP_SUPPORT_CANUSB
+#include "pcap-canusb-linux.h"
+#endif
+
+#ifdef PCAP_SUPPORT_NETFILTER
+#include "pcap-netfilter-linux.h"
+#endif
+
+int
+pcap_not_initialized(pcap_t *pcap)
+{
+ /* this means 'not initialized' */
+ return (PCAP_ERROR_NOT_ACTIVATED);
+}
+
+/*
+ * Returns 1 if rfmon mode can be set on the pcap_t, 0 if it can't,
+ * a PCAP_ERROR value on an error.
+ */
+int
+pcap_can_set_rfmon(pcap_t *p)
+{
+ return (p->can_set_rfmon_op(p));
+}
+
+/*
+ * For systems where rfmon mode is never supported.
+ */
+static int
+pcap_cant_set_rfmon(pcap_t *p _U_)
+{
+ return (0);
+}
+
+/*
+ * Sets *tstamp_typesp to point to an array 1 or more supported time stamp
+ * types; the return value is the number of supported time stamp types.
+ * The list should be freed by a call to pcap_free_tstamp_types() when
+ * you're done with it.
+ *
+ * A return value of 0 means "you don't get a choice of time stamp type",
+ * in which case *tstamp_typesp is set to null.
+ *
+ * PCAP_ERROR is returned on error.
+ */
+int
+pcap_list_tstamp_types(pcap_t *p, int **tstamp_typesp)
+{
+ if (p->tstamp_type_count == 0) {
+ /*
+ * We don't support multiple time stamp types.
+ */
+ *tstamp_typesp = NULL;
+ } else {
+ *tstamp_typesp = (int*)calloc(sizeof(**tstamp_typesp),
+ p->tstamp_type_count);
+ if (*tstamp_typesp == NULL) {
+ (void)snprintf(p->errbuf, sizeof(p->errbuf),
+ "malloc: %s", pcap_strerror(errno));
+ return (PCAP_ERROR);
+ }
+ (void)memcpy(*tstamp_typesp, p->tstamp_type_list,
+ sizeof(**tstamp_typesp) * p->tstamp_type_count);
+ }
+ return (p->tstamp_type_count);
+}
+
+/*
+ * In Windows, you might have a library built with one version of the
+ * C runtime library and an application built with another version of
+ * the C runtime library, which means that the library might use one
+ * version of malloc() and free() and the application might use another
+ * version of malloc() and free(). If so, that means something
+ * allocated by the library cannot be freed by the application, so we
+ * need to have a pcap_free_tstamp_types() routine to free up the list
+ * allocated by pcap_list_tstamp_types(), even though it's just a wrapper
+ * around free().
+ */
+void
+pcap_free_tstamp_types(int *tstamp_type_list)
+{
+ free(tstamp_type_list);
+}
+
+/*
+ * Default one-shot callback; overridden for capture types where the
+ * packet data cannot be guaranteed to be available after the callback
+ * returns, so that a copy must be made.
+ */
+static void
+pcap_oneshot(u_char *user, const struct pcap_pkthdr *h, const u_char *pkt)
+{
+ struct oneshot_userdata *sp = (struct oneshot_userdata *)user;
+
+ *sp->hdr = *h;
+ *sp->pkt = pkt;
+}
+
+const u_char *
+pcap_next(pcap_t *p, struct pcap_pkthdr *h)
+{
+ struct oneshot_userdata s;
+ const u_char *pkt;
+
+ s.hdr = h;
+ s.pkt = &pkt;
+ s.pd = p;
+ if (pcap_dispatch(p, 1, p->oneshot_callback, (u_char *)&s) <= 0)
+ return (0);
+ return (pkt);
+}
+
+int
+pcap_next_ex(pcap_t *p, struct pcap_pkthdr **pkt_header,
+ const u_char **pkt_data)
+{
+ struct oneshot_userdata s;
+
+ s.hdr = &p->pcap_header;
+ s.pkt = pkt_data;
+ s.pd = p;
+
+ /* Saves a pointer to the packet headers */
+ *pkt_header= &p->pcap_header;
+
+ if (p->sf.rfile != NULL) {
+ int status;
+
+ /* We are on an offline capture */
+ status = pcap_offline_read(p, 1, p->oneshot_callback,
+ (u_char *)&s);
+
+ /*
+ * Return codes for pcap_offline_read() are:
+ * - 0: EOF
+ * - -1: error
+ * - >1: OK
+ * The first one ('0') conflicts with the return code of
+ * 0 from pcap_read() meaning "no packets arrived before
+ * the timeout expired", so we map it to -2 so you can
+ * distinguish between an EOF from a savefile and a
+ * "no packets arrived before the timeout expired, try
+ * again" from a live capture.
+ */
+ if (status == 0)
+ return (-2);
+ else
+ return (status);
+ }
+
+ /*
+ * Return codes for pcap_read() are:
+ * - 0: timeout
+ * - -1: error
+ * - -2: loop was broken out of with pcap_breakloop()
+ * - >1: OK
+ * The first one ('0') conflicts with the return code of 0 from
+ * pcap_offline_read() meaning "end of file".
+ */
+ return (p->read_op(p, 1, p->oneshot_callback, (u_char *)&s));
+}
+
+#if defined(DAG_ONLY)
+int
+pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
+{
+ return (dag_findalldevs(alldevsp, errbuf));
+}
+
+pcap_t *
+pcap_create(const char *source, char *errbuf)
+{
+ return (dag_create(source, errbuf));
+}
+#elif defined(SEPTEL_ONLY)
+int
+pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
+{
+ return (septel_findalldevs(alldevsp, errbuf));
+}
+
+pcap_t *
+pcap_create(const char *source, char *errbuf)
+{
+ return (septel_create(source, errbuf));
+}
+#elif defined(SNF_ONLY)
+int
+pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
+{
+ return (snf_findalldevs(alldevsp, errbuf));
+}
+
+pcap_t *
+pcap_create(const char *source, char *errbuf)
+{
+ return (snf_create(source, errbuf));
+}
+#else /* regular pcap */
+struct capture_source_type {
+ int (*findalldevs_op)(pcap_if_t **, char *);
+ pcap_t *(*create_op)(const char *, char *, int *);
+} capture_source_types[] = {
+#ifdef HAVE_DAG_API
+ { dag_findalldevs, dag_create },
+#endif
+#ifdef HAVE_SEPTEL_API
+ { septel_findalldevs, septel_create },
+#endif
+#ifdef HAVE_SNF_API
+ { snf_findalldevs, snf_create },
+#endif
+#ifdef PCAP_SUPPORT_BT
+ { bt_findalldevs, bt_create },
+#endif
+#if PCAP_SUPPORT_CANUSB
+ { canusb_findalldevs, canusb_create },
+#endif
+#ifdef PCAP_SUPPORT_CAN
+ { can_findalldevs, can_create },
+#endif
+#ifdef PCAP_SUPPORT_USB
+ { usb_findalldevs, usb_create },
+#endif
+#ifdef PCAP_SUPPORT_NETFILTER
+ { netfilter_findalldevs, netfilter_create },
+#endif
+ { NULL, NULL }
+};
+
+/*
+ * Get a list of all capture sources that are up and that we can open.
+ * Returns -1 on error, 0 otherwise.
+ * The list, as returned through "alldevsp", may be null if no interfaces
+ * were up and could be opened.
+ */
+int
+pcap_findalldevs(pcap_if_t **alldevsp, char *errbuf)
+{
+ size_t i;
+
+ /*
+ * Get the list of regular interfaces first.
+ */
+ if (pcap_findalldevs_interfaces(alldevsp, errbuf) == -1)
+ return (-1); /* failure */
+
+ /*
+ * Add any interfaces that need a platform-specific mechanism
+ * to find.
+ */
+ if (pcap_platform_finddevs(alldevsp, errbuf) == -1) {
+ /*
+ * We had an error; free the list we've been
+ * constructing.
+ */
+ if (*alldevsp != NULL) {
+ pcap_freealldevs(*alldevsp);
+ *alldevsp = NULL;
+ }
+ return (-1);
+ }
+
+ /*
+ * Ask each of the non-local-network-interface capture
+ * source types what interfaces they have.
+ */
+ for (i = 0; capture_source_types[i].findalldevs_op != NULL; i++) {
+ if (capture_source_types[i].findalldevs_op(alldevsp, errbuf) == -1) {
+ /*
+ * We had an error; free the list we've been
+ * constructing.
+ */
+ if (*alldevsp != NULL) {
+ pcap_freealldevs(*alldevsp);
+ *alldevsp = NULL;
+ }
+ return (-1);
+ }
+ }
+ return (0);
+}
+
+pcap_t *
+pcap_create(const char *source, char *errbuf)
+{
+ size_t i;
+ int is_theirs;
+ pcap_t *p;
+
+ /*
+ * A null source name is equivalent to the "any" device -
+ * which might not be supported on this platform, but
+ * this means that you'll get a "not supported" error
+ * rather than, say, a crash when we try to dereference
+ * the null pointer.
+ */
+ if (source == NULL)
+ source = "any";
+
+ /*
+ * Try each of the non-local-network-interface capture
+ * source types until we find one that works for this
+ * device or run out of types.
+ */
+ for (i = 0; capture_source_types[i].create_op != NULL; i++) {
+ is_theirs = 0;
+ p = capture_source_types[i].create_op(source, errbuf, &is_theirs);
+ if (is_theirs) {
+ /*
+ * The device name refers to a device of the
+ * type in question; either it succeeded,
+ * in which case p refers to a pcap_t to
+ * later activate for the device, or it
+ * failed, in which case p is null and we
+ * should return that to report the failure
+ * to create.
+ */
+ return (p);
+ }
+ }
+
+ /*
+ * OK, try it as a regular network interface.
+ */
+ return (pcap_create_interface(source, errbuf));
+}
+#endif
+
+static void
+initialize_ops(pcap_t *p)
+{
+ /*
+ * Set operation pointers for operations that only work on
+ * an activated pcap_t to point to a routine that returns
+ * a "this isn't activated" error.
+ */
+ p->read_op = (read_op_t)pcap_not_initialized;
+ p->inject_op = (inject_op_t)pcap_not_initialized;
+ p->setfilter_op = (setfilter_op_t)pcap_not_initialized;
+ p->setdirection_op = (setdirection_op_t)pcap_not_initialized;
+ p->set_datalink_op = (set_datalink_op_t)pcap_not_initialized;
+ p->getnonblock_op = (getnonblock_op_t)pcap_not_initialized;
+ p->setnonblock_op = (setnonblock_op_t)pcap_not_initialized;
+ p->stats_op = (stats_op_t)pcap_not_initialized;
+#ifdef WIN32
+ p->setbuff_op = (setbuff_op_t)pcap_not_initialized;
+ p->setmode_op = (setmode_op_t)pcap_not_initialized;
+ p->setmintocopy_op = (setmintocopy_op_t)pcap_not_initialized;
+#endif
+
+ /*
+ * Default cleanup operation - implementations can override
+ * this, but should call pcap_cleanup_live_common() after
+ * doing their own additional cleanup.
+ */
+ p->cleanup_op = pcap_cleanup_live_common;
+
+ /*
+ * In most cases, the standard one-short callback can
+ * be used for pcap_next()/pcap_next_ex().
+ */
+ p->oneshot_callback = pcap_oneshot;
+}
+
+pcap_t *
+pcap_create_common(const char *source, char *ebuf)
+{
+ pcap_t *p;
+
+ p = malloc(sizeof(*p));
+ if (p == NULL) {
+ snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
+ pcap_strerror(errno));
+ return (NULL);
+ }
+ memset(p, 0, sizeof(*p));
+#ifndef WIN32
+ p->fd = -1; /* not opened yet */
+ p->selectable_fd = -1;
+ p->send_fd = -1;
+#endif
+
+ p->opt.source = strdup(source);
+ if (p->opt.source == NULL) {
+ snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc: %s",
+ pcap_strerror(errno));
+ free(p);
+ return (NULL);
+ }
+
+ /*
+ * Default to "can't set rfmon mode"; if it's supported by
+ * a platform, the create routine that called us can set
+ * the op to its routine to check whether a particular
+ * device supports it.
+ */
+ p->can_set_rfmon_op = pcap_cant_set_rfmon;
+
+ initialize_ops(p);
+
+ /* put in some defaults*/
+ pcap_set_timeout(p, 0);
+ pcap_set_snaplen(p, 65535); /* max packet size */
+ p->opt.promisc = 0;
+ p->opt.buffer_size = 0;
+ p->opt.tstamp_type = -1; /* default to not setting time stamp type */
+ return (p);
+}
+
+int
+pcap_check_activated(pcap_t *p)
+{
+ if (p->activated) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "can't perform "
+ " operation on activated capture");
+ return (-1);
+ }
+ return (0);
+}
+
+int
+pcap_set_snaplen(pcap_t *p, int snaplen)
+{
+ if (pcap_check_activated(p))
+ return (PCAP_ERROR_ACTIVATED);
+ p->snapshot = snaplen;
+ return (0);
+}
+
+int
+pcap_set_promisc(pcap_t *p, int promisc)
+{
+ if (pcap_check_activated(p))
+ return (PCAP_ERROR_ACTIVATED);
+ p->opt.promisc = promisc;
+ return (0);
+}
+
+int
+pcap_set_rfmon(pcap_t *p, int rfmon)
+{
+ if (pcap_check_activated(p))
+ return (PCAP_ERROR_ACTIVATED);
+ p->opt.rfmon = rfmon;
+ return (0);
+}
+
+int
+pcap_set_timeout(pcap_t *p, int timeout_ms)
+{
+ if (pcap_check_activated(p))
+ return (PCAP_ERROR_ACTIVATED);
+ p->md.timeout = timeout_ms;
+ return (0);
+}
+
+int
+pcap_set_tstamp_type(pcap_t *p, int tstamp_type)
+{
+ int i;
+
+ if (pcap_check_activated(p))
+ return (PCAP_ERROR_ACTIVATED);
+
+ /*
+ * If p->tstamp_type_count is 0, we don't support setting
+ * the time stamp type at all.
+ */
+ if (p->tstamp_type_count == 0)
+ return (PCAP_ERROR_CANTSET_TSTAMP_TYPE);
+
+ /*
+ * Check whether we claim to support this type of time stamp.
+ */
+ for (i = 0; i < p->tstamp_type_count; i++) {
+ if (p->tstamp_type_list[i] == tstamp_type) {
+ /*
+ * Yes.
+ */
+ p->opt.tstamp_type = tstamp_type;
+ return (0);
+ }
+ }
+
+ /*
+ * No. We support setting the time stamp type, but not to this
+ * particular value.
+ */
+ return (PCAP_WARNING_TSTAMP_TYPE_NOTSUP);
+}
+
+int
+pcap_set_buffer_size(pcap_t *p, int buffer_size)
+{
+ if (pcap_check_activated(p))
+ return (PCAP_ERROR_ACTIVATED);
+ p->opt.buffer_size = buffer_size;
+ return (0);
+}
+
+int
+pcap_activate(pcap_t *p)
+{
+ int status;
+
+ /*
+ * Catch attempts to re-activate an already-activated
+ * pcap_t; this should, for example, catch code that
+ * calls pcap_open_live() followed by pcap_activate(),
+ * as some code that showed up in a Stack Exchange
+ * question did.
+ */
+ if (pcap_check_activated(p))
+ return (PCAP_ERROR_ACTIVATED);
+ status = p->activate_op(p);
+ if (status >= 0)
+ p->activated = 1;
+ else {
+ if (p->errbuf[0] == '\0') {
+ /*
+ * No error message supplied by the activate routine;
+ * for the benefit of programs that don't specially
+ * handle errors other than PCAP_ERROR, return the
+ * error message corresponding to the status.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s",
+ pcap_statustostr(status));
+ }
+
+ /*
+ * Undo any operation pointer setting, etc. done by
+ * the activate operation.
+ */
+ initialize_ops(p);
+ }
+ return (status);
+}
+
+pcap_t *
+pcap_open_live(const char *source, int snaplen, int promisc, int to_ms, char *errbuf)
+{
+ pcap_t *p;
+ int status;
+
+ p = pcap_create(source, errbuf);
+ if (p == NULL)
+ return (NULL);
+ status = pcap_set_snaplen(p, snaplen);
+ if (status < 0)
+ goto fail;
+ status = pcap_set_promisc(p, promisc);
+ if (status < 0)
+ goto fail;
+ status = pcap_set_timeout(p, to_ms);
+ if (status < 0)
+ goto fail;
+ /*
+ * Mark this as opened with pcap_open_live(), so that, for
+ * example, we show the full list of DLT_ values, rather
+ * than just the ones that are compatible with capturing
+ * when not in monitor mode. That allows existing applications
+ * to work the way they used to work, but allows new applications
+ * that know about the new open API to, for example, find out the
+ * DLT_ values that they can select without changing whether
+ * the adapter is in monitor mode or not.
+ */
+ p->oldstyle = 1;
+ status = pcap_activate(p);
+ if (status < 0)
+ goto fail;
+ return (p);
+fail:
+ if (status == PCAP_ERROR)
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source,
+ p->errbuf);
+ else if (status == PCAP_ERROR_NO_SUCH_DEVICE ||
+ status == PCAP_ERROR_PERM_DENIED ||
+ status == PCAP_ERROR_PROMISC_PERM_DENIED)
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s (%s)", source,
+ pcap_statustostr(status), p->errbuf);
+ else
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", source,
+ pcap_statustostr(status));
+ pcap_close(p);
+ return (NULL);
+}
+
+int
+pcap_dispatch(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
+{
+ return (p->read_op(p, cnt, callback, user));
+}
+
+/*
+ * XXX - is this necessary?
+ */
+int
+pcap_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
+{
+
+ return (p->read_op(p, cnt, callback, user));
+}
+
+int
+pcap_loop(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
+{
+ register int n;
+
+ for (;;) {
+ if (p->sf.rfile != NULL) {
+ /*
+ * 0 means EOF, so don't loop if we get 0.
+ */
+ n = pcap_offline_read(p, cnt, callback, user);
+ } else {
+ /*
+ * XXX keep reading until we get something
+ * (or an error occurs)
+ */
+ do {
+ n = p->read_op(p, cnt, callback, user);
+ } while (n == 0);
+ }
+ if (n <= 0)
+ return (n);
+ if (cnt > 0) {
+ cnt -= n;
+ if (cnt <= 0)
+ return (0);
+ }
+ }
+}
+
+/*
+ * Force the loop in "pcap_read()" or "pcap_read_offline()" to terminate.
+ */
+void
+pcap_breakloop(pcap_t *p)
+{
+ p->break_loop = 1;
+}
+
+int
+pcap_datalink(pcap_t *p)
+{
+ return (p->linktype);
+}
+
+int
+pcap_datalink_ext(pcap_t *p)
+{
+ return (p->linktype_ext);
+}
+
+int
+pcap_list_datalinks(pcap_t *p, int **dlt_buffer)
+{
+ if (p->dlt_count == 0) {
+ /*
+ * We couldn't fetch the list of DLTs, which means
+ * this platform doesn't support changing the
+ * DLT for an interface. Return a list of DLTs
+ * containing only the DLT this device supports.
+ */
+ *dlt_buffer = (int*)malloc(sizeof(**dlt_buffer));
+ if (*dlt_buffer == NULL) {
+ (void)snprintf(p->errbuf, sizeof(p->errbuf),
+ "malloc: %s", pcap_strerror(errno));
+ return (-1);
+ }
+ **dlt_buffer = p->linktype;
+ return (1);
+ } else {
+ *dlt_buffer = (int*)calloc(sizeof(**dlt_buffer), p->dlt_count);
+ if (*dlt_buffer == NULL) {
+ (void)snprintf(p->errbuf, sizeof(p->errbuf),
+ "malloc: %s", pcap_strerror(errno));
+ return (-1);
+ }
+ (void)memcpy(*dlt_buffer, p->dlt_list,
+ sizeof(**dlt_buffer) * p->dlt_count);
+ return (p->dlt_count);
+ }
+}
+
+/*
+ * In Windows, you might have a library built with one version of the
+ * C runtime library and an application built with another version of
+ * the C runtime library, which means that the library might use one
+ * version of malloc() and free() and the application might use another
+ * version of malloc() and free(). If so, that means something
+ * allocated by the library cannot be freed by the application, so we
+ * need to have a pcap_free_datalinks() routine to free up the list
+ * allocated by pcap_list_datalinks(), even though it's just a wrapper
+ * around free().
+ */
+void
+pcap_free_datalinks(int *dlt_list)
+{
+ free(dlt_list);
+}
+
+int
+pcap_set_datalink(pcap_t *p, int dlt)
+{
+ int i;
+ const char *dlt_name;
+
+ if (p->dlt_count == 0 || p->set_datalink_op == NULL) {
+ /*
+ * We couldn't fetch the list of DLTs, or we don't
+ * have a "set datalink" operation, which means
+ * this platform doesn't support changing the
+ * DLT for an interface. Check whether the new
+ * DLT is the one this interface supports.
+ */
+ if (p->linktype != dlt)
+ goto unsupported;
+
+ /*
+ * It is, so there's nothing we need to do here.
+ */
+ return (0);
+ }
+ for (i = 0; i < p->dlt_count; i++)
+ if (p->dlt_list[i] == dlt)
+ break;
+ if (i >= p->dlt_count)
+ goto unsupported;
+ if (p->dlt_count == 2 && p->dlt_list[0] == DLT_EN10MB &&
+ dlt == DLT_DOCSIS) {
+ /*
+ * This is presumably an Ethernet device, as the first
+ * link-layer type it offers is DLT_EN10MB, and the only
+ * other type it offers is DLT_DOCSIS. That means that
+ * we can't tell the driver to supply DOCSIS link-layer
+ * headers - we're just pretending that's what we're
+ * getting, as, presumably, we're capturing on a dedicated
+ * link to a Cisco Cable Modem Termination System, and
+ * it's putting raw DOCSIS frames on the wire inside low-level
+ * Ethernet framing.
+ */
+ p->linktype = dlt;
+ return (0);
+ }
+ if (p->set_datalink_op(p, dlt) == -1)
+ return (-1);
+ p->linktype = dlt;
+ return (0);
+
+unsupported:
+ dlt_name = pcap_datalink_val_to_name(dlt);
+ if (dlt_name != NULL) {
+ (void) snprintf(p->errbuf, sizeof(p->errbuf),
+ "%s is not one of the DLTs supported by this device",
+ dlt_name);
+ } else {
+ (void) snprintf(p->errbuf, sizeof(p->errbuf),
+ "DLT %d is not one of the DLTs supported by this device",
+ dlt);
+ }
+ return (-1);
+}
+
+/*
+ * This array is designed for mapping upper and lower case letter
+ * together for a case independent comparison. The mappings are
+ * based upon ascii character sequences.
+ */
+static const u_char charmap[] = {
+ (u_char)'\000', (u_char)'\001', (u_char)'\002', (u_char)'\003',
+ (u_char)'\004', (u_char)'\005', (u_char)'\006', (u_char)'\007',
+ (u_char)'\010', (u_char)'\011', (u_char)'\012', (u_char)'\013',
+ (u_char)'\014', (u_char)'\015', (u_char)'\016', (u_char)'\017',
+ (u_char)'\020', (u_char)'\021', (u_char)'\022', (u_char)'\023',
+ (u_char)'\024', (u_char)'\025', (u_char)'\026', (u_char)'\027',
+ (u_char)'\030', (u_char)'\031', (u_char)'\032', (u_char)'\033',
+ (u_char)'\034', (u_char)'\035', (u_char)'\036', (u_char)'\037',
+ (u_char)'\040', (u_char)'\041', (u_char)'\042', (u_char)'\043',
+ (u_char)'\044', (u_char)'\045', (u_char)'\046', (u_char)'\047',
+ (u_char)'\050', (u_char)'\051', (u_char)'\052', (u_char)'\053',
+ (u_char)'\054', (u_char)'\055', (u_char)'\056', (u_char)'\057',
+ (u_char)'\060', (u_char)'\061', (u_char)'\062', (u_char)'\063',
+ (u_char)'\064', (u_char)'\065', (u_char)'\066', (u_char)'\067',
+ (u_char)'\070', (u_char)'\071', (u_char)'\072', (u_char)'\073',
+ (u_char)'\074', (u_char)'\075', (u_char)'\076', (u_char)'\077',
+ (u_char)'\100', (u_char)'\141', (u_char)'\142', (u_char)'\143',
+ (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147',
+ (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153',
+ (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157',
+ (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163',
+ (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167',
+ (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\133',
+ (u_char)'\134', (u_char)'\135', (u_char)'\136', (u_char)'\137',
+ (u_char)'\140', (u_char)'\141', (u_char)'\142', (u_char)'\143',
+ (u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147',
+ (u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153',
+ (u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157',
+ (u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163',
+ (u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167',
+ (u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\173',
+ (u_char)'\174', (u_char)'\175', (u_char)'\176', (u_char)'\177',
+ (u_char)'\200', (u_char)'\201', (u_char)'\202', (u_char)'\203',
+ (u_char)'\204', (u_char)'\205', (u_char)'\206', (u_char)'\207',
+ (u_char)'\210', (u_char)'\211', (u_char)'\212', (u_char)'\213',
+ (u_char)'\214', (u_char)'\215', (u_char)'\216', (u_char)'\217',
+ (u_char)'\220', (u_char)'\221', (u_char)'\222', (u_char)'\223',
+ (u_char)'\224', (u_char)'\225', (u_char)'\226', (u_char)'\227',
+ (u_char)'\230', (u_char)'\231', (u_char)'\232', (u_char)'\233',
+ (u_char)'\234', (u_char)'\235', (u_char)'\236', (u_char)'\237',
+ (u_char)'\240', (u_char)'\241', (u_char)'\242', (u_char)'\243',
+ (u_char)'\244', (u_char)'\245', (u_char)'\246', (u_char)'\247',
+ (u_char)'\250', (u_char)'\251', (u_char)'\252', (u_char)'\253',
+ (u_char)'\254', (u_char)'\255', (u_char)'\256', (u_char)'\257',
+ (u_char)'\260', (u_char)'\261', (u_char)'\262', (u_char)'\263',
+ (u_char)'\264', (u_char)'\265', (u_char)'\266', (u_char)'\267',
+ (u_char)'\270', (u_char)'\271', (u_char)'\272', (u_char)'\273',
+ (u_char)'\274', (u_char)'\275', (u_char)'\276', (u_char)'\277',
+ (u_char)'\300', (u_char)'\341', (u_char)'\342', (u_char)'\343',
+ (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347',
+ (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353',
+ (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357',
+ (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363',
+ (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367',
+ (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\333',
+ (u_char)'\334', (u_char)'\335', (u_char)'\336', (u_char)'\337',
+ (u_char)'\340', (u_char)'\341', (u_char)'\342', (u_char)'\343',
+ (u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347',
+ (u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353',
+ (u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357',
+ (u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363',
+ (u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367',
+ (u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\373',
+ (u_char)'\374', (u_char)'\375', (u_char)'\376', (u_char)'\377',
+};
+
+int
+pcap_strcasecmp(const char *s1, const char *s2)
+{
+ register const u_char *cm = charmap,
+ *us1 = (const u_char *)s1,
+ *us2 = (const u_char *)s2;
+
+ while (cm[*us1] == cm[*us2++])
+ if (*us1++ == '\0')
+ return(0);
+ return (cm[*us1] - cm[*--us2]);
+}
+
+struct dlt_choice {
+ const char *name;
+ const char *description;
+ int dlt;
+};
+
+#define DLT_CHOICE(code, description) { #code, description, code }
+#define DLT_CHOICE_SENTINEL { NULL, NULL, 0 }
+
+static struct dlt_choice dlt_choices[] = {
+ DLT_CHOICE(DLT_NULL, "BSD loopback"),
+ DLT_CHOICE(DLT_EN10MB, "Ethernet"),
+ DLT_CHOICE(DLT_IEEE802, "Token ring"),
+ DLT_CHOICE(DLT_ARCNET, "BSD ARCNET"),
+ DLT_CHOICE(DLT_SLIP, "SLIP"),
+ DLT_CHOICE(DLT_PPP, "PPP"),
+ DLT_CHOICE(DLT_FDDI, "FDDI"),
+ DLT_CHOICE(DLT_ATM_RFC1483, "RFC 1483 LLC-encapsulated ATM"),
+ DLT_CHOICE(DLT_RAW, "Raw IP"),
+ DLT_CHOICE(DLT_SLIP_BSDOS, "BSD/OS SLIP"),
+ DLT_CHOICE(DLT_PPP_BSDOS, "BSD/OS PPP"),
+ DLT_CHOICE(DLT_ATM_CLIP, "Linux Classical IP-over-ATM"),
+ DLT_CHOICE(DLT_PPP_SERIAL, "PPP over serial"),
+ DLT_CHOICE(DLT_PPP_ETHER, "PPPoE"),
+ DLT_CHOICE(DLT_SYMANTEC_FIREWALL, "Symantec Firewall"),
+ DLT_CHOICE(DLT_C_HDLC, "Cisco HDLC"),
+ DLT_CHOICE(DLT_IEEE802_11, "802.11"),
+ DLT_CHOICE(DLT_FRELAY, "Frame Relay"),
+ DLT_CHOICE(DLT_LOOP, "OpenBSD loopback"),
+ DLT_CHOICE(DLT_ENC, "OpenBSD encapsulated IP"),
+ DLT_CHOICE(DLT_LINUX_SLL, "Linux cooked"),
+ DLT_CHOICE(DLT_LTALK, "Localtalk"),
+ DLT_CHOICE(DLT_PFLOG, "OpenBSD pflog file"),
+ DLT_CHOICE(DLT_PFSYNC, "Packet filter state syncing"),
+ DLT_CHOICE(DLT_PRISM_HEADER, "802.11 plus Prism header"),
+ DLT_CHOICE(DLT_IP_OVER_FC, "RFC 2625 IP-over-Fibre Channel"),
+ DLT_CHOICE(DLT_SUNATM, "Sun raw ATM"),
+ DLT_CHOICE(DLT_IEEE802_11_RADIO, "802.11 plus radiotap header"),
+ DLT_CHOICE(DLT_ARCNET_LINUX, "Linux ARCNET"),
+ DLT_CHOICE(DLT_JUNIPER_MLPPP, "Juniper Multi-Link PPP"),
+ DLT_CHOICE(DLT_JUNIPER_MLFR, "Juniper Multi-Link Frame Relay"),
+ DLT_CHOICE(DLT_JUNIPER_ES, "Juniper Encryption Services PIC"),
+ DLT_CHOICE(DLT_JUNIPER_GGSN, "Juniper GGSN PIC"),
+ DLT_CHOICE(DLT_JUNIPER_MFR, "Juniper FRF.16 Frame Relay"),
+ DLT_CHOICE(DLT_JUNIPER_ATM2, "Juniper ATM2 PIC"),
+ DLT_CHOICE(DLT_JUNIPER_SERVICES, "Juniper Advanced Services PIC"),
+ DLT_CHOICE(DLT_JUNIPER_ATM1, "Juniper ATM1 PIC"),
+ DLT_CHOICE(DLT_APPLE_IP_OVER_IEEE1394, "Apple IP-over-IEEE 1394"),
+ DLT_CHOICE(DLT_MTP2_WITH_PHDR, "SS7 MTP2 with Pseudo-header"),
+ DLT_CHOICE(DLT_MTP2, "SS7 MTP2"),
+ DLT_CHOICE(DLT_MTP3, "SS7 MTP3"),
+ DLT_CHOICE(DLT_SCCP, "SS7 SCCP"),
+ DLT_CHOICE(DLT_DOCSIS, "DOCSIS"),
+ DLT_CHOICE(DLT_LINUX_IRDA, "Linux IrDA"),
+ DLT_CHOICE(DLT_IEEE802_11_RADIO_AVS, "802.11 plus AVS radio information header"),
+ DLT_CHOICE(DLT_JUNIPER_MONITOR, "Juniper Passive Monitor PIC"),
+ DLT_CHOICE(DLT_PPP_PPPD, "PPP for pppd, with direction flag"),
+ DLT_CHOICE(DLT_JUNIPER_PPPOE, "Juniper PPPoE"),
+ DLT_CHOICE(DLT_JUNIPER_PPPOE_ATM, "Juniper PPPoE/ATM"),
+ DLT_CHOICE(DLT_GPRS_LLC, "GPRS LLC"),
+ DLT_CHOICE(DLT_GPF_T, "GPF-T"),
+ DLT_CHOICE(DLT_GPF_F, "GPF-F"),
+ DLT_CHOICE(DLT_JUNIPER_PIC_PEER, "Juniper PIC Peer"),
+ DLT_CHOICE(DLT_ERF_ETH, "Ethernet with Endace ERF header"),
+ DLT_CHOICE(DLT_ERF_POS, "Packet-over-SONET with Endace ERF header"),
+ DLT_CHOICE(DLT_LINUX_LAPD, "Linux vISDN LAPD"),
+ DLT_CHOICE(DLT_JUNIPER_ETHER, "Juniper Ethernet"),
+ DLT_CHOICE(DLT_JUNIPER_PPP, "Juniper PPP"),
+ DLT_CHOICE(DLT_JUNIPER_FRELAY, "Juniper Frame Relay"),
+ DLT_CHOICE(DLT_JUNIPER_CHDLC, "Juniper C-HDLC"),
+ DLT_CHOICE(DLT_MFR, "FRF.16 Frame Relay"),
+ DLT_CHOICE(DLT_JUNIPER_VP, "Juniper Voice PIC"),
+ DLT_CHOICE(DLT_A429, "Arinc 429"),
+ DLT_CHOICE(DLT_A653_ICM, "Arinc 653 Interpartition Communication"),
+ DLT_CHOICE(DLT_USB, "USB"),
+ DLT_CHOICE(DLT_BLUETOOTH_HCI_H4, "Bluetooth HCI UART transport layer"),
+ DLT_CHOICE(DLT_IEEE802_16_MAC_CPS, "IEEE 802.16 MAC Common Part Sublayer"),
+ DLT_CHOICE(DLT_USB_LINUX, "USB with Linux header"),
+ DLT_CHOICE(DLT_CAN20B, "Controller Area Network (CAN) v. 2.0B"),
+ DLT_CHOICE(DLT_IEEE802_15_4_LINUX, "IEEE 802.15.4 with Linux padding"),
+ DLT_CHOICE(DLT_PPI, "Per-Packet Information"),
+ DLT_CHOICE(DLT_IEEE802_16_MAC_CPS_RADIO, "IEEE 802.16 MAC Common Part Sublayer plus radiotap header"),
+ DLT_CHOICE(DLT_JUNIPER_ISM, "Juniper Integrated Service Module"),
+ DLT_CHOICE(DLT_IEEE802_15_4, "IEEE 802.15.4 with FCS"),
+ DLT_CHOICE(DLT_SITA, "SITA pseudo-header"),
+ DLT_CHOICE(DLT_ERF, "Endace ERF header"),
+ DLT_CHOICE(DLT_RAIF1, "Ethernet with u10 Networks pseudo-header"),
+ DLT_CHOICE(DLT_IPMB, "IPMB"),
+ DLT_CHOICE(DLT_JUNIPER_ST, "Juniper Secure Tunnel"),
+ DLT_CHOICE(DLT_BLUETOOTH_HCI_H4_WITH_PHDR, "Bluetooth HCI UART transport layer plus pseudo-header"),
+ DLT_CHOICE(DLT_AX25_KISS, "AX.25 with KISS header"),
+ DLT_CHOICE(DLT_IEEE802_15_4_NONASK_PHY, "IEEE 802.15.4 with non-ASK PHY data"),
+ DLT_CHOICE(DLT_MPLS, "MPLS with label as link-layer header"),
+ DLT_CHOICE(DLT_USB_LINUX_MMAPPED, "USB with padded Linux header"),
+ DLT_CHOICE(DLT_DECT, "DECT"),
+ DLT_CHOICE(DLT_AOS, "AOS Space Data Link protocol"),
+ DLT_CHOICE(DLT_WIHART, "Wireless HART"),
+ DLT_CHOICE(DLT_FC_2, "Fibre Channel FC-2"),
+ DLT_CHOICE(DLT_FC_2_WITH_FRAME_DELIMS, "Fibre Channel FC-2 with frame delimiters"),
+ DLT_CHOICE(DLT_IPNET, "Solaris ipnet"),
+ DLT_CHOICE(DLT_CAN_SOCKETCAN, "CAN-bus with SocketCAN headers"),
+ DLT_CHOICE(DLT_IPV4, "Raw IPv4"),
+ DLT_CHOICE(DLT_IPV6, "Raw IPv6"),
+ DLT_CHOICE(DLT_IEEE802_15_4_NOFCS, "IEEE 802.15.4 without FCS"),
+ DLT_CHOICE(DLT_JUNIPER_VS, "Juniper Virtual Server"),
+ DLT_CHOICE(DLT_JUNIPER_SRX_E2E, "Juniper SRX E2E"),
+ DLT_CHOICE(DLT_JUNIPER_FIBRECHANNEL, "Juniper Fibre Channel"),
+ DLT_CHOICE(DLT_DVB_CI, "DVB-CI"),
+ DLT_CHOICE(DLT_JUNIPER_ATM_CEMIC, "Juniper ATM CEMIC"),
+ DLT_CHOICE(DLT_NFLOG, "Linux netfilter log messages"),
+ DLT_CHOICE(DLT_NETANALYZER, "Ethernet with Hilscher netANALYZER pseudo-header"),
+ DLT_CHOICE(DLT_NETANALYZER_TRANSPARENT, "Ethernet with Hilscher netANALYZER pseudo-header and with preamble and SFD"),
+ DLT_CHOICE(DLT_IPOIB, "RFC 4391 IP-over-Infiniband"),
+ DLT_CHOICE_SENTINEL
+};
+
+int
+pcap_datalink_name_to_val(const char *name)
+{
+ int i;
+
+ for (i = 0; dlt_choices[i].name != NULL; i++) {
+ if (pcap_strcasecmp(dlt_choices[i].name + sizeof("DLT_") - 1,
+ name) == 0)
+ return (dlt_choices[i].dlt);
+ }
+ return (-1);
+}
+
+const char *
+pcap_datalink_val_to_name(int dlt)
+{
+ int i;
+
+ for (i = 0; dlt_choices[i].name != NULL; i++) {
+ if (dlt_choices[i].dlt == dlt)
+ return (dlt_choices[i].name + sizeof("DLT_") - 1);
+ }
+ return (NULL);
+}
+
+const char *
+pcap_datalink_val_to_description(int dlt)
+{
+ int i;
+
+ for (i = 0; dlt_choices[i].name != NULL; i++) {
+ if (dlt_choices[i].dlt == dlt)
+ return (dlt_choices[i].description);
+ }
+ return (NULL);
+}
+
+struct tstamp_type_choice {
+ const char *name;
+ const char *description;
+ int type;
+};
+
+static struct tstamp_type_choice tstamp_type_choices[] = {
+ { "host", "Host", PCAP_TSTAMP_HOST },
+ { "host_lowprec", "Host, low precision", PCAP_TSTAMP_HOST_LOWPREC },
+ { "host_hiprec", "Host, high precision", PCAP_TSTAMP_HOST_HIPREC },
+ { "adapter", "Adapter", PCAP_TSTAMP_ADAPTER },
+ { "adapter_unsynced", "Adapter, not synced with system time", PCAP_TSTAMP_ADAPTER_UNSYNCED },
+ { NULL, NULL, 0 }
+};
+
+int
+pcap_tstamp_type_name_to_val(const char *name)
+{
+ int i;
+
+ for (i = 0; tstamp_type_choices[i].name != NULL; i++) {
+ if (pcap_strcasecmp(tstamp_type_choices[i].name, name) == 0)
+ return (tstamp_type_choices[i].type);
+ }
+ return (PCAP_ERROR);
+}
+
+const char *
+pcap_tstamp_type_val_to_name(int tstamp_type)
+{
+ int i;
+
+ for (i = 0; tstamp_type_choices[i].name != NULL; i++) {
+ if (tstamp_type_choices[i].type == tstamp_type)
+ return (tstamp_type_choices[i].name);
+ }
+ return (NULL);
+}
+
+const char *
+pcap_tstamp_type_val_to_description(int tstamp_type)
+{
+ int i;
+
+ for (i = 0; tstamp_type_choices[i].name != NULL; i++) {
+ if (tstamp_type_choices[i].type == tstamp_type)
+ return (tstamp_type_choices[i].description);
+ }
+ return (NULL);
+}
+
+int
+pcap_snapshot(pcap_t *p)
+{
+ return (p->snapshot);
+}
+
+int
+pcap_is_swapped(pcap_t *p)
+{
+ return (p->sf.swapped);
+}
+
+int
+pcap_major_version(pcap_t *p)
+{
+ return (p->sf.version_major);
+}
+
+int
+pcap_minor_version(pcap_t *p)
+{
+ return (p->sf.version_minor);
+}
+
+FILE *
+pcap_file(pcap_t *p)
+{
+ return (p->sf.rfile);
+}
+
+int
+pcap_fileno(pcap_t *p)
+{
+#ifndef WIN32
+ return (p->fd);
+#else
+ if (p->adapter != NULL)
+ return ((int)(DWORD)p->adapter->hFile);
+ else
+ return (-1);
+#endif
+}
+
+#if !defined(WIN32) && !defined(MSDOS)
+int
+pcap_get_selectable_fd(pcap_t *p)
+{
+ return (p->selectable_fd);
+}
+#endif
+
+void
+pcap_perror(pcap_t *p, char *prefix)
+{
+ fprintf(stderr, "%s: %s\n", prefix, p->errbuf);
+}
+
+char *
+pcap_geterr(pcap_t *p)
+{
+ return (p->errbuf);
+}
+
+int
+pcap_getnonblock(pcap_t *p, char *errbuf)
+{
+ int ret;
+
+ ret = p->getnonblock_op(p, errbuf);
+ if (ret == -1) {
+ /*
+ * In case somebody depended on the bug wherein
+ * the error message was put into p->errbuf
+ * by pcap_getnonblock_fd().
+ */
+ strlcpy(p->errbuf, errbuf, PCAP_ERRBUF_SIZE);
+ }
+ return (ret);
+}
+
+/*
+ * Get the current non-blocking mode setting, under the assumption that
+ * it's just the standard POSIX non-blocking flag.
+ *
+ * We don't look at "p->nonblock", in case somebody tweaked the FD
+ * directly.
+ */
+#if !defined(WIN32) && !defined(MSDOS)
+int
+pcap_getnonblock_fd(pcap_t *p, char *errbuf)
+{
+ int fdflags;
+
+ fdflags = fcntl(p->fd, F_GETFL, 0);
+ if (fdflags == -1) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
+ pcap_strerror(errno));
+ return (-1);
+ }
+ if (fdflags & O_NONBLOCK)
+ return (1);
+ else
+ return (0);
+}
+#endif
+
+int
+pcap_setnonblock(pcap_t *p, int nonblock, char *errbuf)
+{
+ int ret;
+
+ ret = p->setnonblock_op(p, nonblock, errbuf);
+ if (ret == -1) {
+ /*
+ * In case somebody depended on the bug wherein
+ * the error message was put into p->errbuf
+ * by pcap_setnonblock_fd().
+ */
+ strlcpy(p->errbuf, errbuf, PCAP_ERRBUF_SIZE);
+ }
+ return (ret);
+}
+
+#if !defined(WIN32) && !defined(MSDOS)
+/*
+ * Set non-blocking mode, under the assumption that it's just the
+ * standard POSIX non-blocking flag. (This can be called by the
+ * per-platform non-blocking-mode routine if that routine also
+ * needs to do some additional work.)
+ */
+int
+pcap_setnonblock_fd(pcap_t *p, int nonblock, char *errbuf)
+{
+ int fdflags;
+
+ fdflags = fcntl(p->fd, F_GETFL, 0);
+ if (fdflags == -1) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_GETFL: %s",
+ pcap_strerror(errno));
+ return (-1);
+ }
+ if (nonblock)
+ fdflags |= O_NONBLOCK;
+ else
+ fdflags &= ~O_NONBLOCK;
+ if (fcntl(p->fd, F_SETFL, fdflags) == -1) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "F_SETFL: %s",
+ pcap_strerror(errno));
+ return (-1);
+ }
+ return (0);
+}
+#endif
+
+#ifdef WIN32
+/*
+ * Generate a string for the last Win32-specific error (i.e. an error generated when
+ * calling a Win32 API).
+ * For errors occurred during standard C calls, we still use pcap_strerror()
+ */
+char *
+pcap_win32strerror(void)
+{
+ DWORD error;
+ static char errbuf[PCAP_ERRBUF_SIZE+1];
+ int errlen;
+ char *p;
+
+ error = GetLastError();
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
+ PCAP_ERRBUF_SIZE, NULL);
+
+ /*
+ * "FormatMessage()" "helpfully" sticks CR/LF at the end of the
+ * message. Get rid of it.
+ */
+ errlen = strlen(errbuf);
+ if (errlen >= 2) {
+ errbuf[errlen - 1] = '\0';
+ errbuf[errlen - 2] = '\0';
+ }
+ p = strchr(errbuf, '\0');
+ snprintf (p, sizeof(errbuf)-(p-errbuf), " (%lu)", error);
+ return (errbuf);
+}
+#endif
+
+/*
+ * Generate error strings for PCAP_ERROR_ and PCAP_WARNING_ values.
+ */
+const char *
+pcap_statustostr(int errnum)
+{
+ static char ebuf[15+10+1];
+
+ switch (errnum) {
+
+ case PCAP_WARNING:
+ return("Generic warning");
+
+ case PCAP_WARNING_TSTAMP_TYPE_NOTSUP:
+ return ("That type of time stamp is not supported by that device");
+
+ case PCAP_WARNING_PROMISC_NOTSUP:
+ return ("That device doesn't support promiscuous mode");
+
+ case PCAP_ERROR:
+ return("Generic error");
+
+ case PCAP_ERROR_BREAK:
+ return("Loop terminated by pcap_breakloop");
+
+ case PCAP_ERROR_NOT_ACTIVATED:
+ return("The pcap_t has not been activated");
+
+ case PCAP_ERROR_ACTIVATED:
+ return ("The setting can't be changed after the pcap_t is activated");
+
+ case PCAP_ERROR_NO_SUCH_DEVICE:
+ return ("No such device exists");
+
+ case PCAP_ERROR_RFMON_NOTSUP:
+ return ("That device doesn't support monitor mode");
+
+ case PCAP_ERROR_NOT_RFMON:
+ return ("That operation is supported only in monitor mode");
+
+ case PCAP_ERROR_PERM_DENIED:
+ return ("You don't have permission to capture on that device");
+
+ case PCAP_ERROR_IFACE_NOT_UP:
+ return ("That device is not up");
+
+ case PCAP_ERROR_CANTSET_TSTAMP_TYPE:
+ return ("That device doesn't support setting the time stamp type");
+
+ case PCAP_ERROR_PROMISC_PERM_DENIED:
+ return ("You don't have permission to capture in promiscuous mode on that device");
+ }
+ (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
+ return(ebuf);
+}
+
+/*
+ * Not all systems have strerror().
+ */
+const char *
+pcap_strerror(int errnum)
+{
+#ifdef HAVE_STRERROR
+ return (strerror(errnum));
+#else
+ extern int sys_nerr;
+ extern const char *const sys_errlist[];
+ static char ebuf[15+10+1];
+
+ if ((unsigned int)errnum < sys_nerr)
+ return ((char *)sys_errlist[errnum]);
+ (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
+ return(ebuf);
+#endif
+}
+
+int
+pcap_setfilter(pcap_t *p, struct bpf_program *fp)
+{
+ return (p->setfilter_op(p, fp));
+}
+
+/*
+ * Set direction flag, which controls whether we accept only incoming
+ * packets, only outgoing packets, or both.
+ * Note that, depending on the platform, some or all direction arguments
+ * might not be supported.
+ */
+int
+pcap_setdirection(pcap_t *p, pcap_direction_t d)
+{
+ if (p->setdirection_op == NULL) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Setting direction is not implemented on this platform");
+ return (-1);
+ } else
+ return (p->setdirection_op(p, d));
+}
+
+int
+pcap_stats(pcap_t *p, struct pcap_stat *ps)
+{
+ return (p->stats_op(p, ps));
+}
+
+static int
+pcap_stats_dead(pcap_t *p, struct pcap_stat *ps _U_)
+{
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Statistics aren't available from a pcap_open_dead pcap_t");
+ return (-1);
+}
+
+#ifdef WIN32
+int
+pcap_setbuff(pcap_t *p, int dim)
+{
+ return (p->setbuff_op(p, dim));
+}
+
+static int
+pcap_setbuff_dead(pcap_t *p, int dim)
+{
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "The kernel buffer size cannot be set on a pcap_open_dead pcap_t");
+ return (-1);
+}
+
+int
+pcap_setmode(pcap_t *p, int mode)
+{
+ return (p->setmode_op(p, mode));
+}
+
+static int
+pcap_setmode_dead(pcap_t *p, int mode)
+{
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "impossible to set mode on a pcap_open_dead pcap_t");
+ return (-1);
+}
+
+int
+pcap_setmintocopy(pcap_t *p, int size)
+{
+ return (p->setmintocopy_op(p, size));
+}
+
+static int
+pcap_setmintocopy_dead(pcap_t *p, int size)
+{
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "The mintocopy parameter cannot be set on a pcap_open_dead pcap_t");
+ return (-1);
+}
+#endif
+
+/*
+ * On some platforms, we need to clean up promiscuous or monitor mode
+ * when we close a device - and we want that to happen even if the
+ * application just exits without explicitl closing devices.
+ * On those platforms, we need to register a "close all the pcaps"
+ * routine to be called when we exit, and need to maintain a list of
+ * pcaps that need to be closed to clean up modes.
+ *
+ * XXX - not thread-safe.
+ */
+
+/*
+ * List of pcaps on which we've done something that needs to be
+ * cleaned up.
+ * If there are any such pcaps, we arrange to call "pcap_close_all()"
+ * when we exit, and have it close all of them.
+ */
+static struct pcap *pcaps_to_close;
+
+/*
+ * TRUE if we've already called "atexit()" to cause "pcap_close_all()" to
+ * be called on exit.
+ */
+static int did_atexit;
+
+static void
+pcap_close_all(void)
+{
+ struct pcap *handle;
+
+ while ((handle = pcaps_to_close) != NULL)
+ pcap_close(handle);
+}
+
+int
+pcap_do_addexit(pcap_t *p)
+{
+ /*
+ * If we haven't already done so, arrange to have
+ * "pcap_close_all()" called when we exit.
+ */
+ if (!did_atexit) {
+ if (atexit(pcap_close_all) == -1) {
+ /*
+ * "atexit()" failed; let our caller know.
+ */
+ strncpy(p->errbuf, "atexit failed",
+ PCAP_ERRBUF_SIZE);
+ return (0);
+ }
+ did_atexit = 1;
+ }
+ return (1);
+}
+
+void
+pcap_add_to_pcaps_to_close(pcap_t *p)
+{
+ p->md.next = pcaps_to_close;
+ pcaps_to_close = p;
+}
+
+void
+pcap_remove_from_pcaps_to_close(pcap_t *p)
+{
+ pcap_t *pc, *prevpc;
+
+ for (pc = pcaps_to_close, prevpc = NULL; pc != NULL;
+ prevpc = pc, pc = pc->md.next) {
+ if (pc == p) {
+ /*
+ * Found it. Remove it from the list.
+ */
+ if (prevpc == NULL) {
+ /*
+ * It was at the head of the list.
+ */
+ pcaps_to_close = pc->md.next;
+ } else {
+ /*
+ * It was in the middle of the list.
+ */
+ prevpc->md.next = pc->md.next;
+ }
+ break;
+ }
+ }
+}
+
+void
+pcap_cleanup_live_common(pcap_t *p)
+{
+ if (p->buffer != NULL) {
+ free(p->buffer);
+ p->buffer = NULL;
+ }
+ if (p->dlt_list != NULL) {
+ free(p->dlt_list);
+ p->dlt_list = NULL;
+ p->dlt_count = 0;
+ }
+ if (p->tstamp_type_list != NULL) {
+ free(p->tstamp_type_list);
+ p->tstamp_type_list = NULL;
+ p->tstamp_type_count = 0;
+ }
+ pcap_freecode(&p->fcode);
+#if !defined(WIN32) && !defined(MSDOS)
+ if (p->fd >= 0) {
+ close(p->fd);
+ p->fd = -1;
+ }
+ p->selectable_fd = -1;
+ p->send_fd = -1;
+#endif
+}
+
+static void
+pcap_cleanup_dead(pcap_t *p _U_)
+{
+ /* Nothing to do. */
+}
+
+pcap_t *
+pcap_open_dead(int linktype, int snaplen)
+{
+ pcap_t *p;
+
+ p = malloc(sizeof(*p));
+ if (p == NULL)
+ return NULL;
+ memset (p, 0, sizeof(*p));
+ p->snapshot = snaplen;
+ p->linktype = linktype;
+ p->stats_op = pcap_stats_dead;
+#ifdef WIN32
+ p->setbuff_op = pcap_setbuff_dead;
+ p->setmode_op = pcap_setmode_dead;
+ p->setmintocopy_op = pcap_setmintocopy_dead;
+#endif
+ p->cleanup_op = pcap_cleanup_dead;
+ p->activated = 1;
+ return (p);
+}
+
+/*
+ * API compatible with WinPcap's "send a packet" routine - returns -1
+ * on error, 0 otherwise.
+ *
+ * XXX - what if we get a short write?
+ */
+int
+pcap_sendpacket(pcap_t *p, const u_char *buf, int size)
+{
+ if (p->inject_op(p, buf, size) == -1)
+ return (-1);
+ return (0);
+}
+
+/*
+ * API compatible with OpenBSD's "send a packet" routine - returns -1 on
+ * error, number of bytes written otherwise.
+ */
+int
+pcap_inject(pcap_t *p, const void *buf, size_t size)
+{
+ return (p->inject_op(p, buf, size));
+}
+
+void
+pcap_close(pcap_t *p)
+{
+ if (p->opt.source != NULL)
+ free(p->opt.source);
+ p->cleanup_op(p);
+ free(p);
+}
+
+/*
+ * Given a BPF program, a pcap_pkthdr structure for a packet, and the raw
+ * data for the packet, check whether the packet passes the filter.
+ * Returns the return value of the filter program, which will be zero if
+ * the packet doesn't pass and non-zero if the packet does pass.
+ */
+int
+pcap_offline_filter(const struct bpf_program *fp, const struct pcap_pkthdr *h,
+ const u_char *pkt)
+{
+ const struct bpf_insn *fcode = fp->bf_insns;
+
+ if (fcode != NULL)
+ return (bpf_filter(fcode, pkt, h->len, h->caplen));
+ else
+ return (0);
+}
+
+/*
+ * We make the version string static, and return a pointer to it, rather
+ * than exporting the version string directly. On at least some UNIXes,
+ * if you import data from a shared library into an program, the data is
+ * bound into the program binary, so if the string in the version of the
+ * library with which the program was linked isn't the same as the
+ * string in the version of the library with which the program is being
+ * run, various undesirable things may happen (warnings, the string
+ * being the one from the version of the library with which the program
+ * was linked, or even weirder things, such as the string being the one
+ * from the library but being truncated).
+ */
+#ifdef HAVE_VERSION_H
+#include "version.h"
+#else
+static const char pcap_version_string[] = "libpcap version 1.x.y";
+#endif
+
+#ifdef WIN32
+/*
+ * XXX - it'd be nice if we could somehow generate the WinPcap and libpcap
+ * version numbers when building WinPcap. (It'd be nice to do so for
+ * the packet.dll version number as well.)
+ */
+static const char wpcap_version_string[] = "4.0";
+static const char pcap_version_string_fmt[] =
+ "WinPcap version %s, based on %s";
+static const char pcap_version_string_packet_dll_fmt[] =
+ "WinPcap version %s (packet.dll version %s), based on %s";
+static char *full_pcap_version_string;
+
+const char *
+pcap_lib_version(void)
+{
+ char *packet_version_string;
+ size_t full_pcap_version_string_len;
+
+ if (full_pcap_version_string == NULL) {
+ /*
+ * Generate the version string.
+ */
+ packet_version_string = PacketGetVersion();
+ if (strcmp(wpcap_version_string, packet_version_string) == 0) {
+ /*
+ * WinPcap version string and packet.dll version
+ * string are the same; just report the WinPcap
+ * version.
+ */
+ full_pcap_version_string_len =
+ (sizeof pcap_version_string_fmt - 4) +
+ strlen(wpcap_version_string) +
+ strlen(pcap_version_string);
+ full_pcap_version_string =
+ malloc(full_pcap_version_string_len);
+ sprintf(full_pcap_version_string,
+ pcap_version_string_fmt, wpcap_version_string,
+ pcap_version_string);
+ } else {
+ /*
+ * WinPcap version string and packet.dll version
+ * string are different; that shouldn't be the
+ * case (the two libraries should come from the
+ * same version of WinPcap), so we report both
+ * versions.
+ */
+ full_pcap_version_string_len =
+ (sizeof pcap_version_string_packet_dll_fmt - 6) +
+ strlen(wpcap_version_string) +
+ strlen(packet_version_string) +
+ strlen(pcap_version_string);
+ full_pcap_version_string = malloc(full_pcap_version_string_len);
+
+ sprintf(full_pcap_version_string,
+ pcap_version_string_packet_dll_fmt,
+ wpcap_version_string, packet_version_string,
+ pcap_version_string);
+ }
+ }
+ return (full_pcap_version_string);
+}
+
+#elif defined(MSDOS)
+
+static char *full_pcap_version_string;
+
+const char *
+pcap_lib_version (void)
+{
+ char *packet_version_string;
+ size_t full_pcap_version_string_len;
+ static char dospfx[] = "DOS-";
+
+ if (full_pcap_version_string == NULL) {
+ /*
+ * Generate the version string.
+ */
+ full_pcap_version_string_len =
+ sizeof dospfx + strlen(pcap_version_string);
+ full_pcap_version_string =
+ malloc(full_pcap_version_string_len);
+ strcpy(full_pcap_version_string, dospfx);
+ strcat(full_pcap_version_string, pcap_version_string);
+ }
+ return (full_pcap_version_string);
+}
+
+#else /* UN*X */
+
+const char *
+pcap_lib_version(void)
+{
+ return (pcap_version_string);
+}
+#endif
diff --git a/freebsd/contrib/libpcap/pcap.h b/freebsd/contrib/libpcap/pcap.h
new file mode 100644
index 00000000..490a4bfb
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.59 2006-10-04 18:09:22 guy Exp $ (LBL)
+ */
+
+/*
+ * For backwards compatibility.
+ *
+ * Note to OS vendors: do NOT get rid of this file! Many applications
+ * expect to be able to include <pcap.h>, and at least some of them
+ * go through contortions in their configure scripts to try to detect
+ * OSes that have "helpfully" moved pcap.h to <pcap/pcap.h> without
+ * leaving behind a <pcap.h> file.
+ */
+#include <pcap/pcap.h>
diff --git a/freebsd/contrib/libpcap/pcap/ipnet.h b/freebsd/contrib/libpcap/pcap/ipnet.h
new file mode 100644
index 00000000..53308470
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap/ipnet.h
@@ -0,0 +1,43 @@
+/*-
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from the Stanford/CMU enet packet filter,
+ * (net/enet.c) distributed as part of 4.3BSD, and code contributed
+ * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
+ * Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define IPH_AF_INET 2 /* Matches Solaris's AF_INET */
+#define IPH_AF_INET6 26 /* Matches Solaris's AF_INET6 */
+
+#define IPNET_OUTBOUND 1
+#define IPNET_INBOUND 2
diff --git a/freebsd/contrib/libpcap/pcap/namedb.h b/freebsd/contrib/libpcap/pcap/namedb.h
new file mode 100644
index 00000000..e3145579
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap/namedb.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 1994, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/pcap/namedb.h,v 1.1 2006-10-04 18:09:22 guy Exp $ (LBL)
+ */
+
+#ifndef lib_pcap_namedb_h
+#define lib_pcap_namedb_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * As returned by the pcap_next_etherent()
+ * XXX this stuff doesn't belong in this interface, but this
+ * library already must do name to address translation, so
+ * on systems that don't have support for /etc/ethers, we
+ * export these hooks since they'll
+ */
+struct pcap_etherent {
+ u_char addr[6];
+ char name[122];
+};
+#ifndef PCAP_ETHERS_FILE
+#define PCAP_ETHERS_FILE "/etc/ethers"
+#endif
+struct pcap_etherent *pcap_next_etherent(FILE *);
+u_char *pcap_ether_hostton(const char*);
+u_char *pcap_ether_aton(const char *);
+
+bpf_u_int32 **pcap_nametoaddr(const char *);
+#ifdef INET6
+struct addrinfo *pcap_nametoaddrinfo(const char *);
+#endif
+bpf_u_int32 pcap_nametonetaddr(const char *);
+
+int pcap_nametoport(const char *, int *, int *);
+int pcap_nametoportrange(const char *, int *, int *, int *);
+int pcap_nametoproto(const char *);
+int pcap_nametoeproto(const char *);
+int pcap_nametollc(const char *);
+/*
+ * If a protocol is unknown, PROTO_UNDEF is returned.
+ * Also, pcap_nametoport() returns the protocol along with the port number.
+ * If there are ambiguous entried in /etc/services (i.e. domain
+ * can be either tcp or udp) PROTO_UNDEF is returned.
+ */
+#define PROTO_UNDEF -1
+
+/* XXX move these to pcap-int.h? */
+int __pcap_atodn(const char *, bpf_u_int32 *);
+int __pcap_atoin(const char *, bpf_u_int32 *);
+u_short __pcap_nametodnaddr(const char *);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/freebsd/contrib/libpcap/pcap/pcap.h b/freebsd/contrib/libpcap/pcap/pcap.h
new file mode 100644
index 00000000..60bb36e5
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap/pcap.h
@@ -0,0 +1,461 @@
+/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the Computer Systems
+ * Engineering Group at Lawrence Berkeley Laboratory.
+ * 4. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/pcap/pcap.h,v 1.15 2008-10-06 15:27:32 gianluca Exp $ (LBL)
+ */
+
+#ifndef lib_pcap_pcap_h
+#define lib_pcap_pcap_h
+
+#if defined(WIN32)
+ #include <pcap-stdinc.h>
+#elif defined(MSDOS)
+ #include <rtems/bsd/sys/types.h>
+ #include <sys/socket.h> /* u_int, u_char etc. */
+#else /* UN*X */
+ #include <rtems/bsd/sys/types.h>
+ #include <rtems/bsd/sys/time.h>
+#endif /* WIN32/MSDOS/UN*X */
+
+#include <net/bpf.h>
+
+#include <stdio.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Version number of the current version of the pcap file format.
+ *
+ * NOTE: this is *NOT* the version number of the libpcap library.
+ * To fetch the version information for the version of libpcap
+ * you're using, use pcap_lib_version().
+ */
+#define PCAP_VERSION_MAJOR 2
+#define PCAP_VERSION_MINOR 4
+
+#define PCAP_ERRBUF_SIZE 256
+
+/*
+ * Compatibility for systems that have a bpf.h that
+ * predates the bpf typedefs for 64-bit support.
+ */
+#if BPF_RELEASE - 0 < 199406
+typedef int bpf_int32;
+typedef u_int bpf_u_int32;
+#endif
+
+typedef struct pcap pcap_t;
+typedef struct pcap_dumper pcap_dumper_t;
+typedef struct pcap_if pcap_if_t;
+typedef struct pcap_addr pcap_addr_t;
+
+/*
+ * The first record in the file contains saved values for some
+ * of the flags used in the printout phases of tcpdump.
+ * Many fields here are 32 bit ints so compilers won't insert unwanted
+ * padding; these files need to be interchangeable across architectures.
+ *
+ * Do not change the layout of this structure, in any way (this includes
+ * changes that only affect the length of fields in this structure).
+ *
+ * Also, do not change the interpretation of any of the members of this
+ * structure, in any way (this includes using values other than
+ * LINKTYPE_ values, as defined in "savefile.c", in the "linktype"
+ * field).
+ *
+ * Instead:
+ *
+ * introduce a new structure for the new format, if the layout
+ * of the structure changed;
+ *
+ * send mail to "tcpdump-workers@lists.tcpdump.org", requesting
+ * a new magic number for your new capture file format, and, when
+ * you get the new magic number, put it in "savefile.c";
+ *
+ * use that magic number for save files with the changed file
+ * header;
+ *
+ * make the code in "savefile.c" capable of reading files with
+ * the old file header as well as files with the new file header
+ * (using the magic number to determine the header format).
+ *
+ * Then supply the changes by forking the branch at
+ *
+ * https://github.com/mcr/libpcap/issues
+ *
+ * and issuing a pull request, so that future versions of libpcap and
+ * programs that use it (such as tcpdump) will be able to read your new
+ * capture file format.
+ */
+struct pcap_file_header {
+ bpf_u_int32 magic;
+ u_short version_major;
+ u_short version_minor;
+ bpf_int32 thiszone; /* gmt to local correction */
+ bpf_u_int32 sigfigs; /* accuracy of timestamps */
+ bpf_u_int32 snaplen; /* max length saved portion of each pkt */
+ bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */
+};
+
+/*
+ * Macros for the value returned by pcap_datalink_ext().
+ *
+ * If LT_FCS_LENGTH_PRESENT(x) is true, the LT_FCS_LENGTH(x) macro
+ * gives the FCS length of packets in the capture.
+ */
+#define LT_FCS_LENGTH_PRESENT(x) ((x) & 0x04000000)
+#define LT_FCS_LENGTH(x) (((x) & 0xF0000000) >> 28)
+#define LT_FCS_DATALINK_EXT(x) ((((x) & 0xF) << 28) | 0x04000000)
+
+typedef enum {
+ PCAP_D_INOUT = 0,
+ PCAP_D_IN,
+ PCAP_D_OUT
+} pcap_direction_t;
+
+/*
+ * Generic per-packet information, as supplied by libpcap.
+ *
+ * The time stamp can and should be a "struct timeval", regardless of
+ * whether your system supports 32-bit tv_sec in "struct timeval",
+ * 64-bit tv_sec in "struct timeval", or both if it supports both 32-bit
+ * and 64-bit applications. The on-disk format of savefiles uses 32-bit
+ * tv_sec (and tv_usec); this structure is irrelevant to that. 32-bit
+ * and 64-bit versions of libpcap, even if they're on the same platform,
+ * should supply the appropriate version of "struct timeval", even if
+ * that's not what the underlying packet capture mechanism supplies.
+ */
+struct pcap_pkthdr {
+ struct timeval ts; /* time stamp */
+ bpf_u_int32 caplen; /* length of portion present */
+ bpf_u_int32 len; /* length this packet (off wire) */
+};
+
+/*
+ * As returned by the pcap_stats()
+ */
+struct pcap_stat {
+ u_int ps_recv; /* number of packets received */
+ u_int ps_drop; /* number of packets dropped */
+ u_int ps_ifdrop; /* drops by interface -- only supported on some platforms */
+#ifdef WIN32
+ u_int bs_capt; /* number of packets that reach the application */
+#endif /* WIN32 */
+};
+
+#ifdef MSDOS
+/*
+ * As returned by the pcap_stats_ex()
+ */
+struct pcap_stat_ex {
+ u_long rx_packets; /* total packets received */
+ u_long tx_packets; /* total packets transmitted */
+ u_long rx_bytes; /* total bytes received */
+ u_long tx_bytes; /* total bytes transmitted */
+ u_long rx_errors; /* bad packets received */
+ u_long tx_errors; /* packet transmit problems */
+ u_long rx_dropped; /* no space in Rx buffers */
+ u_long tx_dropped; /* no space available for Tx */
+ u_long multicast; /* multicast packets received */
+ u_long collisions;
+
+ /* detailed rx_errors: */
+ u_long rx_length_errors;
+ u_long rx_over_errors; /* receiver ring buff overflow */
+ u_long rx_crc_errors; /* recv'd pkt with crc error */
+ u_long rx_frame_errors; /* recv'd frame alignment error */
+ u_long rx_fifo_errors; /* recv'r fifo overrun */
+ u_long rx_missed_errors; /* recv'r missed packet */
+
+ /* detailed tx_errors */
+ u_long tx_aborted_errors;
+ u_long tx_carrier_errors;
+ u_long tx_fifo_errors;
+ u_long tx_heartbeat_errors;
+ u_long tx_window_errors;
+ };
+#endif
+
+/*
+ * Item in a list of interfaces.
+ */
+struct pcap_if {
+ struct pcap_if *next;
+ char *name; /* name to hand to "pcap_open_live()" */
+ char *description; /* textual description of interface, or NULL */
+ struct pcap_addr *addresses;
+ bpf_u_int32 flags; /* PCAP_IF_ interface flags */
+};
+
+#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */
+
+/*
+ * Representation of an interface address.
+ */
+struct pcap_addr {
+ struct pcap_addr *next;
+ struct sockaddr *addr; /* address */
+ struct sockaddr *netmask; /* netmask for that address */
+ struct sockaddr *broadaddr; /* broadcast address for that address */
+ struct sockaddr *dstaddr; /* P2P destination address for that address */
+};
+
+typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
+ const u_char *);
+
+/*
+ * Error codes for the pcap API.
+ * These will all be negative, so you can check for the success or
+ * failure of a call that returns these codes by checking for a
+ * negative value.
+ */
+#define PCAP_ERROR -1 /* generic error code */
+#define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */
+#define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */
+#define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */
+#define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */
+#define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */
+#define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */
+#define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */
+#define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */
+#define PCAP_ERROR_CANTSET_TSTAMP_TYPE -10 /* this device doesn't support setting the time stamp type */
+#define PCAP_ERROR_PROMISC_PERM_DENIED -11 /* you don't have permission to capture in promiscuous mode */
+
+/*
+ * Warning codes for the pcap API.
+ * These will all be positive and non-zero, so they won't look like
+ * errors.
+ */
+#define PCAP_WARNING 1 /* generic warning code */
+#define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */
+#define PCAP_WARNING_TSTAMP_TYPE_NOTSUP 3 /* the requested time stamp type is not supported */
+
+/*
+ * Value to pass to pcap_compile() as the netmask if you don't know what
+ * the netmask is.
+ */
+#define PCAP_NETMASK_UNKNOWN 0xffffffff
+
+char *pcap_lookupdev(char *);
+int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
+
+pcap_t *pcap_create(const char *, char *);
+int pcap_set_snaplen(pcap_t *, int);
+int pcap_set_promisc(pcap_t *, int);
+int pcap_can_set_rfmon(pcap_t *);
+int pcap_set_rfmon(pcap_t *, int);
+int pcap_set_timeout(pcap_t *, int);
+int pcap_set_tstamp_type(pcap_t *, int);
+int pcap_set_buffer_size(pcap_t *, int);
+int pcap_activate(pcap_t *);
+
+int pcap_list_tstamp_types(pcap_t *, int **);
+void pcap_free_tstamp_types(int *);
+int pcap_tstamp_type_name_to_val(const char *);
+const char *pcap_tstamp_type_val_to_name(int);
+const char *pcap_tstamp_type_val_to_description(int);
+
+/*
+ * Time stamp types.
+ * Not all systems and interfaces will necessarily support all of these.
+ *
+ * A system that supports PCAP_TSTAMP_HOST is offering time stamps
+ * provided by the host machine, rather than by the capture device,
+ * but not committing to any characteristics of the time stamp;
+ * it will not offer any of the PCAP_TSTAMP_HOST_ subtypes.
+ *
+ * PCAP_TSTAMP_HOST_LOWPREC is a time stamp, provided by the host machine,
+ * that's low-precision but relatively cheap to fetch; it's normally done
+ * using the system clock, so it's normally synchronized with times you'd
+ * fetch from system calls.
+ *
+ * PCAP_TSTAMP_HOST_HIPREC is a time stamp, provided by the host machine,
+ * that's high-precision; it might be more expensive to fetch. It might
+ * or might not be synchronized with the system clock, and might have
+ * problems with time stamps for packets received on different CPUs,
+ * depending on the platform.
+ *
+ * PCAP_TSTAMP_ADAPTER is a high-precision time stamp supplied by the
+ * capture device; it's synchronized with the system clock.
+ *
+ * PCAP_TSTAMP_ADAPTER_UNSYNCED is a high-precision time stamp supplied by
+ * the capture device; it's not synchronized with the system clock.
+ *
+ * Note that time stamps synchronized with the system clock can go
+ * backwards, as the system clock can go backwards. If a clock is
+ * not in sync with the system clock, that could be because the
+ * system clock isn't keeping accurate time, because the other
+ * clock isn't keeping accurate time, or both.
+ *
+ * Note that host-provided time stamps generally correspond to the
+ * time when the time-stamping code sees the packet; this could
+ * be some unknown amount of time after the first or last bit of
+ * the packet is received by the network adapter, due to batching
+ * of interrupts for packet arrival, queueing delays, etc..
+ */
+#define PCAP_TSTAMP_HOST 0 /* host-provided, unknown characteristics */
+#define PCAP_TSTAMP_HOST_LOWPREC 1 /* host-provided, low precision */
+#define PCAP_TSTAMP_HOST_HIPREC 2 /* host-provided, high precision */
+#define PCAP_TSTAMP_ADAPTER 3 /* device-provided, synced with the system clock */
+#define PCAP_TSTAMP_ADAPTER_UNSYNCED 4 /* device-provided, not synced with the system clock */
+
+pcap_t *pcap_open_live(const char *, int, int, int, char *);
+pcap_t *pcap_open_dead(int, int);
+pcap_t *pcap_open_offline(const char *, char *);
+#if defined(WIN32)
+pcap_t *pcap_hopen_offline(intptr_t, char *);
+#if !defined(LIBPCAP_EXPORTS)
+#define pcap_fopen_offline(f,b) \
+ pcap_hopen_offline(_get_osfhandle(_fileno(f)), b)
+#else /*LIBPCAP_EXPORTS*/
+static pcap_t *pcap_fopen_offline(FILE *, char *);
+#endif
+#else /*WIN32*/
+pcap_t *pcap_fopen_offline(FILE *, char *);
+#endif /*WIN32*/
+
+void pcap_close(pcap_t *);
+int pcap_loop(pcap_t *, int, pcap_handler, u_char *);
+int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *);
+const u_char*
+ pcap_next(pcap_t *, struct pcap_pkthdr *);
+int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **);
+void pcap_breakloop(pcap_t *);
+int pcap_stats(pcap_t *, struct pcap_stat *);
+int pcap_setfilter(pcap_t *, struct bpf_program *);
+int pcap_setdirection(pcap_t *, pcap_direction_t);
+int pcap_getnonblock(pcap_t *, char *);
+int pcap_setnonblock(pcap_t *, int, char *);
+int pcap_inject(pcap_t *, const void *, size_t);
+int pcap_sendpacket(pcap_t *, const u_char *, int);
+const char *pcap_statustostr(int);
+const char *pcap_strerror(int);
+char *pcap_geterr(pcap_t *);
+void pcap_perror(pcap_t *, char *);
+int pcap_compile(pcap_t *, struct bpf_program *, const char *, int,
+ bpf_u_int32);
+int pcap_compile_nopcap(int, int, struct bpf_program *,
+ const char *, int, bpf_u_int32);
+void pcap_freecode(struct bpf_program *);
+int pcap_offline_filter(const struct bpf_program *,
+ const struct pcap_pkthdr *, const u_char *);
+int pcap_datalink(pcap_t *);
+int pcap_datalink_ext(pcap_t *);
+int pcap_list_datalinks(pcap_t *, int **);
+int pcap_set_datalink(pcap_t *, int);
+void pcap_free_datalinks(int *);
+int pcap_datalink_name_to_val(const char *);
+const char *pcap_datalink_val_to_name(int);
+const char *pcap_datalink_val_to_description(int);
+int pcap_snapshot(pcap_t *);
+int pcap_is_swapped(pcap_t *);
+int pcap_major_version(pcap_t *);
+int pcap_minor_version(pcap_t *);
+
+/* XXX */
+FILE *pcap_file(pcap_t *);
+int pcap_fileno(pcap_t *);
+
+pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
+pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp);
+FILE *pcap_dump_file(pcap_dumper_t *);
+long pcap_dump_ftell(pcap_dumper_t *);
+int pcap_dump_flush(pcap_dumper_t *);
+void pcap_dump_close(pcap_dumper_t *);
+void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
+
+int pcap_findalldevs(pcap_if_t **, char *);
+void pcap_freealldevs(pcap_if_t *);
+
+const char *pcap_lib_version(void);
+
+/*
+ * On at least some versions of NetBSD, we don't want to declare
+ * bpf_filter() here, as it's also be declared in <net/bpf.h>, with a
+ * different signature, but, on other BSD-flavored UN*Xes, it's not
+ * declared in <net/bpf.h>, so we *do* want to declare it here, so it's
+ * declared when we build pcap-bpf.c.
+ */
+#ifndef __NetBSD__
+u_int bpf_filter(struct bpf_insn *, u_char *, u_int, u_int);
+#endif
+int bpf_validate(const struct bpf_insn *f, int len);
+char *bpf_image(struct bpf_insn *, int);
+void bpf_dump(const struct bpf_program *, int);
+
+#if defined(WIN32)
+
+/*
+ * Win32 definitions
+ */
+
+int pcap_setbuff(pcap_t *p, int dim);
+int pcap_setmode(pcap_t *p, int mode);
+int pcap_setmintocopy(pcap_t *p, int size);
+
+#ifdef WPCAP
+/* Include file with the wpcap-specific extensions */
+#include <Win32-Extensions.h>
+#endif /* WPCAP */
+
+#define MODE_CAPT 0
+#define MODE_STAT 1
+#define MODE_MON 2
+
+#elif defined(MSDOS)
+
+/*
+ * MS-DOS definitions
+ */
+
+int pcap_stats_ex (pcap_t *, struct pcap_stat_ex *);
+void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait);
+u_long pcap_mac_packets (void);
+
+#else /* UN*X */
+
+/*
+ * UN*X definitions
+ */
+
+int pcap_get_selectable_fd(pcap_t *);
+
+#endif /* WIN32/MSDOS/UN*X */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* lib_pcap_pcap_h */
diff --git a/freebsd/contrib/libpcap/pcap/sll.h b/freebsd/contrib/libpcap/pcap/sll.h
new file mode 100644
index 00000000..7ad811d7
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap/sll.h
@@ -0,0 +1,129 @@
+/*-
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from the Stanford/CMU enet packet filter,
+ * (net/enet.c) distributed as part of 4.3BSD, and code contributed
+ * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
+ * Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/pcap/sll.h,v 1.3 2008-05-30 01:35:33 guy Exp $ (LBL)
+ */
+
+/*
+ * For captures on Linux cooked sockets, we construct a fake header
+ * that includes:
+ *
+ * a 2-byte "packet type" which is one of:
+ *
+ * LINUX_SLL_HOST packet was sent to us
+ * LINUX_SLL_BROADCAST packet was broadcast
+ * LINUX_SLL_MULTICAST packet was multicast
+ * LINUX_SLL_OTHERHOST packet was sent to somebody else
+ * LINUX_SLL_OUTGOING packet was sent *by* us;
+ *
+ * a 2-byte Ethernet protocol field;
+ *
+ * a 2-byte link-layer type;
+ *
+ * a 2-byte link-layer address length;
+ *
+ * an 8-byte source link-layer address, whose actual length is
+ * specified by the previous value.
+ *
+ * All fields except for the link-layer address are in network byte order.
+ *
+ * DO NOT change the layout of this structure, or change any of the
+ * LINUX_SLL_ values below. If you must change the link-layer header
+ * for a "cooked" Linux capture, introduce a new DLT_ type (ask
+ * "tcpdump-workers@lists.tcpdump.org" for one, so that you don't give it
+ * a value that collides with a value already being used), and use the
+ * new header in captures of that type, so that programs that can
+ * handle DLT_LINUX_SLL captures will continue to handle them correctly
+ * without any change, and so that capture files with different headers
+ * can be told apart and programs that read them can dissect the
+ * packets in them.
+ */
+
+#ifndef lib_pcap_sll_h
+#define lib_pcap_sll_h
+
+/*
+ * A DLT_LINUX_SLL fake link-layer header.
+ */
+#define SLL_HDR_LEN 16 /* total header length */
+#define SLL_ADDRLEN 8 /* length of address field */
+
+struct sll_header {
+ u_int16_t sll_pkttype; /* packet type */
+ u_int16_t sll_hatype; /* link-layer address type */
+ u_int16_t sll_halen; /* link-layer address length */
+ u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */
+ u_int16_t sll_protocol; /* protocol */
+};
+
+/*
+ * The LINUX_SLL_ values for "sll_pkttype"; these correspond to the
+ * PACKET_ values on Linux, but are defined here so that they're
+ * available even on systems other than Linux, and so that they
+ * don't change even if the PACKET_ values change.
+ */
+#define LINUX_SLL_HOST 0
+#define LINUX_SLL_BROADCAST 1
+#define LINUX_SLL_MULTICAST 2
+#define LINUX_SLL_OTHERHOST 3
+#define LINUX_SLL_OUTGOING 4
+
+/*
+ * The LINUX_SLL_ values for "sll_protocol"; these correspond to the
+ * ETH_P_ values on Linux, but are defined here so that they're
+ * available even on systems other than Linux. We assume, for now,
+ * that the ETH_P_ values won't change in Linux; if they do, then:
+ *
+ * if we don't translate them in "pcap-linux.c", capture files
+ * won't necessarily be readable if captured on a system that
+ * defines ETH_P_ values that don't match these values;
+ *
+ * if we do translate them in "pcap-linux.c", that makes life
+ * unpleasant for the BPF code generator, as the values you test
+ * for in the kernel aren't the values that you test for when
+ * reading a capture file, so the fixup code run on BPF programs
+ * handed to the kernel ends up having to do more work.
+ *
+ * Add other values here as necessary, for handling packet types that
+ * might show up on non-Ethernet, non-802.x networks. (Not all the ones
+ * in the Linux "if_ether.h" will, I suspect, actually show up in
+ * captures.)
+ */
+#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */
+#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */
+
+#endif
diff --git a/freebsd/contrib/libpcap/pcap/usb.h b/freebsd/contrib/libpcap/pcap/usb.h
new file mode 100644
index 00000000..aa351225
--- /dev/null
+++ b/freebsd/contrib/libpcap/pcap/usb.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 2006 Paolo Abeni (Italy)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Basic USB data struct
+ * By Paolo Abeni <paolo.abeni@email.it>
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/pcap/usb.h,v 1.9 2008-12-23 20:13:29 guy Exp $
+ */
+
+#ifndef _PCAP_USB_STRUCTS_H__
+#define _PCAP_USB_STRUCTS_H__
+
+/*
+ * possible transfer mode
+ */
+#define URB_TRANSFER_IN 0x80
+#define URB_ISOCHRONOUS 0x0
+#define URB_INTERRUPT 0x1
+#define URB_CONTROL 0x2
+#define URB_BULK 0x3
+
+/*
+ * possible event type
+ */
+#define URB_SUBMIT 'S'
+#define URB_COMPLETE 'C'
+#define URB_ERROR 'E'
+
+/*
+ * USB setup header as defined in USB specification.
+ * Appears at the front of each Control S-type packet in DLT_USB captures.
+ */
+typedef struct _usb_setup {
+ u_int8_t bmRequestType;
+ u_int8_t bRequest;
+ u_int16_t wValue;
+ u_int16_t wIndex;
+ u_int16_t wLength;
+} pcap_usb_setup;
+
+/*
+ * Information from the URB for Isochronous transfers.
+ */
+typedef struct _iso_rec {
+ int32_t error_count;
+ int32_t numdesc;
+} iso_rec;
+
+/*
+ * Header prepended by linux kernel to each event.
+ * Appears at the front of each packet in DLT_USB_LINUX captures.
+ */
+typedef struct _usb_header {
+ u_int64_t id;
+ u_int8_t event_type;
+ u_int8_t transfer_type;
+ u_int8_t endpoint_number;
+ u_int8_t device_address;
+ u_int16_t bus_id;
+ char setup_flag;/*if !=0 the urb setup header is not present*/
+ char data_flag; /*if !=0 no urb data is present*/
+ int64_t ts_sec;
+ int32_t ts_usec;
+ int32_t status;
+ u_int32_t urb_len;
+ u_int32_t data_len; /* amount of urb data really present in this event*/
+ pcap_usb_setup setup;
+} pcap_usb_header;
+
+/*
+ * Header prepended by linux kernel to each event for the 2.6.31
+ * and later kernels; for the 2.6.21 through 2.6.30 kernels, the
+ * "iso_rec" information, and the fields starting with "interval"
+ * are zeroed-out padding fields.
+ *
+ * Appears at the front of each packet in DLT_USB_LINUX_MMAPPED captures.
+ */
+typedef struct _usb_header_mmapped {
+ u_int64_t id;
+ u_int8_t event_type;
+ u_int8_t transfer_type;
+ u_int8_t endpoint_number;
+ u_int8_t device_address;
+ u_int16_t bus_id;
+ char setup_flag;/*if !=0 the urb setup header is not present*/
+ char data_flag; /*if !=0 no urb data is present*/
+ int64_t ts_sec;
+ int32_t ts_usec;
+ int32_t status;
+ u_int32_t urb_len;
+ u_int32_t data_len; /* amount of urb data really present in this event*/
+ union {
+ pcap_usb_setup setup;
+ iso_rec iso;
+ } s;
+ int32_t interval; /* for Interrupt and Isochronous events */
+ int32_t start_frame; /* for Isochronous events */
+ u_int32_t xfer_flags; /* copy of URB's transfer flags */
+ u_int32_t ndesc; /* number of isochronous descriptors */
+} pcap_usb_header_mmapped;
+
+/*
+ * Isochronous descriptors; for isochronous transfers there might be
+ * one or more of these at the beginning of the packet data. The
+ * number of descriptors is given by the "ndesc" field in the header;
+ * as indicated, in older kernels that don't put the descriptors at
+ * the beginning of the packet, that field is zeroed out, so that field
+ * can be trusted even in captures from older kernels.
+ */
+typedef struct _usb_isodesc {
+ int32_t status;
+ u_int32_t offset;
+ u_int32_t len;
+ u_int8_t pad[4];
+} usb_isodesc;
+
+#endif
diff --git a/freebsd/contrib/libpcap/ppp.h b/freebsd/contrib/libpcap/ppp.h
new file mode 100644
index 00000000..4e1d08de
--- /dev/null
+++ b/freebsd/contrib/libpcap/ppp.h
@@ -0,0 +1,58 @@
+/* @(#) $Header: /tcpdump/master/libpcap/ppp.h,v 1.12 2005-02-08 19:52:19 guy Exp $ (LBL) */
+/*
+ * Point to Point Protocol (PPP) RFC1331
+ *
+ * Copyright 1989 by Carnegie Mellon.
+ *
+ * Permission to use, copy, modify, and distribute this program for any
+ * purpose and without fee is hereby granted, provided that this copyright
+ * and permission notice appear on all copies and supporting documentation,
+ * the name of Carnegie Mellon not be used in advertising or publicity
+ * pertaining to distribution of the program without specific prior
+ * permission, and notice be given in supporting documentation that copying
+ * and distribution is by permission of Carnegie Mellon and Stanford
+ * University. Carnegie Mellon makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+#define PPP_ADDRESS 0xff /* The address byte value */
+#define PPP_CONTROL 0x03 /* The control byte value */
+
+#define PPP_PPPD_IN 0x00 /* non-standard for DLT_PPP_PPPD */
+#define PPP_PPPD_OUT 0x01 /* non-standard for DLT_PPP_PPPD */
+
+/* Protocol numbers */
+#define PPP_IP 0x0021 /* Raw IP */
+#define PPP_OSI 0x0023 /* OSI Network Layer */
+#define PPP_NS 0x0025 /* Xerox NS IDP */
+#define PPP_DECNET 0x0027 /* DECnet Phase IV */
+#define PPP_APPLE 0x0029 /* Appletalk */
+#define PPP_IPX 0x002b /* Novell IPX */
+#define PPP_VJC 0x002d /* Van Jacobson Compressed TCP/IP */
+#define PPP_VJNC 0x002f /* Van Jacobson Uncompressed TCP/IP */
+#define PPP_BRPDU 0x0031 /* Bridging PDU */
+#define PPP_STII 0x0033 /* Stream Protocol (ST-II) */
+#define PPP_VINES 0x0035 /* Banyan Vines */
+#define PPP_IPV6 0x0057 /* Internet Protocol version 6 */
+
+#define PPP_HELLO 0x0201 /* 802.1d Hello Packets */
+#define PPP_LUXCOM 0x0231 /* Luxcom */
+#define PPP_SNS 0x0233 /* Sigma Network Systems */
+#define PPP_MPLS_UCAST 0x0281 /* rfc 3032 */
+#define PPP_MPLS_MCAST 0x0283 /* rfc 3022 */
+
+#define PPP_IPCP 0x8021 /* IP Control Protocol */
+#define PPP_OSICP 0x8023 /* OSI Network Layer Control Protocol */
+#define PPP_NSCP 0x8025 /* Xerox NS IDP Control Protocol */
+#define PPP_DECNETCP 0x8027 /* DECnet Control Protocol */
+#define PPP_APPLECP 0x8029 /* Appletalk Control Protocol */
+#define PPP_IPXCP 0x802b /* Novell IPX Control Protocol */
+#define PPP_STIICP 0x8033 /* Strean Protocol Control Protocol */
+#define PPP_VINESCP 0x8035 /* Banyan Vines Control Protocol */
+#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */
+#define PPP_MPLSCP 0x8281 /* rfc 3022 */
+
+#define PPP_LCP 0xc021 /* Link Control Protocol */
+#define PPP_PAP 0xc023 /* Password Authentication Protocol */
+#define PPP_LQM 0xc025 /* Link Quality Monitoring */
+#define PPP_CHAP 0xc223 /* Challenge Handshake Authentication Protocol */
diff --git a/freebsd/contrib/libpcap/savefile.c b/freebsd/contrib/libpcap/savefile.c
new file mode 100644
index 00000000..cf22f22a
--- /dev/null
+++ b/freebsd/contrib/libpcap/savefile.c
@@ -0,0 +1,396 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * savefile.c - supports offline use of tcpdump
+ * Extraction/creation by Jeffrey Mogul, DECWRL
+ * Modified by Steve McCanne, LBL.
+ *
+ * Used to save the received packet headers, after filtering, to
+ * a file, and then read them later.
+ * The first record in the file contains saved values for the machine
+ * dependent values so we can print the dump file on any architecture.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/savefile.c,v 1.183 2008-12-23 20:13:29 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <rtems/bsd/sys/types.h>
+#endif /* WIN32 */
+
+#include <errno.h>
+#include <memory.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pcap-int.h"
+#include "pcap/usb.h"
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#include "sf-pcap.h"
+#include "sf-pcap-ng.h"
+
+/*
+ * Setting O_BINARY on DOS/Windows is a bit tricky
+ */
+#if defined(WIN32)
+ #define SET_BINMODE(f) _setmode(_fileno(f), _O_BINARY)
+#elif defined(MSDOS)
+ #if defined(__HIGHC__)
+ #define SET_BINMODE(f) setmode(f, O_BINARY)
+ #else
+ #define SET_BINMODE(f) setmode(fileno(f), O_BINARY)
+ #endif
+#endif
+
+static int
+sf_getnonblock(pcap_t *p, char *errbuf)
+{
+ /*
+ * This is a savefile, not a live capture file, so never say
+ * it's in non-blocking mode.
+ */
+ return (0);
+}
+
+static int
+sf_setnonblock(pcap_t *p, int nonblock, char *errbuf)
+{
+ /*
+ * This is a savefile, not a live capture file, so reject
+ * requests to put it in non-blocking mode. (If it's a
+ * pipe, it could be put in non-blocking mode, but that
+ * would significantly complicate the code to read packets,
+ * as it would have to handle reading partial packets and
+ * keeping the state of the read.)
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Savefiles cannot be put into non-blocking mode");
+ return (-1);
+}
+
+static int
+sf_stats(pcap_t *p, struct pcap_stat *ps)
+{
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "Statistics aren't available from savefiles");
+ return (-1);
+}
+
+#ifdef WIN32
+static int
+sf_setbuff(pcap_t *p, int dim)
+{
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "The kernel buffer size cannot be set while reading from a file");
+ return (-1);
+}
+
+static int
+sf_setmode(pcap_t *p, int mode)
+{
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "impossible to set mode while reading from a file");
+ return (-1);
+}
+
+static int
+sf_setmintocopy(pcap_t *p, int size)
+{
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "The mintocopy parameter cannot be set while reading from a file");
+ return (-1);
+}
+#endif
+
+static int
+sf_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
+{
+ strlcpy(p->errbuf, "Sending packets isn't supported on savefiles",
+ PCAP_ERRBUF_SIZE);
+ return (-1);
+}
+
+/*
+ * Set direction flag: Which packets do we accept on a forwarding
+ * single device? IN, OUT or both?
+ */
+static int
+sf_setdirection(pcap_t *p, pcap_direction_t d)
+{
+ snprintf(p->errbuf, sizeof(p->errbuf),
+ "Setting direction is not supported on savefiles");
+ return (-1);
+}
+
+static void
+sf_cleanup(pcap_t *p)
+{
+ if (p->sf.rfile != stdin)
+ (void)fclose(p->sf.rfile);
+ if (p->buffer != NULL)
+ free(p->buffer);
+ pcap_freecode(&p->fcode);
+}
+
+pcap_t *
+pcap_open_offline(const char *fname, char *errbuf)
+{
+ FILE *fp;
+ pcap_t *p;
+
+ if (fname[0] == '-' && fname[1] == '\0')
+ {
+ fp = stdin;
+#if defined(WIN32) || defined(MSDOS)
+ /*
+ * We're reading from the standard input, so put it in binary
+ * mode, as savefiles are binary files.
+ */
+ SET_BINMODE(fp);
+#endif
+ }
+ else {
+#if !defined(WIN32) && !defined(MSDOS)
+ fp = fopen(fname, "r");
+#else
+ fp = fopen(fname, "rb");
+#endif
+ if (fp == NULL) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "%s: %s", fname,
+ pcap_strerror(errno));
+ return (NULL);
+ }
+ }
+ p = pcap_fopen_offline(fp, errbuf);
+ if (p == NULL) {
+ if (fp != stdin)
+ fclose(fp);
+ }
+ return (p);
+}
+
+#ifdef WIN32
+pcap_t* pcap_hopen_offline(intptr_t osfd, char *errbuf)
+{
+ int fd;
+ FILE *file;
+
+ fd = _open_osfhandle(osfd, _O_RDONLY);
+ if ( fd < 0 )
+ {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, pcap_strerror(errno));
+ return NULL;
+ }
+
+ file = _fdopen(fd, "rb");
+ if ( file == NULL )
+ {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, pcap_strerror(errno));
+ return NULL;
+ }
+
+ return pcap_fopen_offline(file, errbuf);
+}
+#endif
+
+static int (*check_headers[])(pcap_t *, bpf_u_int32, FILE *, char *) = {
+ pcap_check_header,
+ pcap_ng_check_header
+};
+
+#define N_FILE_TYPES (sizeof check_headers / sizeof check_headers[0])
+
+#ifdef WIN32
+static
+#endif
+pcap_t *
+pcap_fopen_offline(FILE *fp, char *errbuf)
+{
+ register pcap_t *p;
+ bpf_u_int32 magic;
+ size_t amt_read;
+ u_int i;
+
+ p = pcap_create_common("(savefile)", errbuf);
+ if (p == NULL)
+ return (NULL);
+
+ /*
+ * Read the first 4 bytes of the file; the network analyzer dump
+ * file formats we support (pcap and pcap-ng), and several other
+ * formats we might support in the future (such as snoop, DOS and
+ * Windows Sniffer, and Microsoft Network Monitor) all have magic
+ * numbers that are unique in their first 4 bytes.
+ */
+ amt_read = fread((char *)&magic, 1, sizeof(magic), fp);
+ if (amt_read != sizeof(magic)) {
+ if (ferror(fp)) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "error reading dump file: %s",
+ pcap_strerror(errno));
+ } else {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "truncated dump file; tried to read %lu file header bytes, only got %lu",
+ (unsigned long)sizeof(magic),
+ (unsigned long)amt_read);
+ }
+ goto bad;
+ }
+
+ /*
+ * Try all file types.
+ */
+ for (i = 0; i < N_FILE_TYPES; i++) {
+ switch ((*check_headers[i])(p, magic, fp, errbuf)) {
+
+ case -1:
+ /*
+ * Error trying to read the header.
+ */
+ goto bad;
+
+ case 1:
+ /*
+ * Yup, that's it.
+ */
+ goto found;
+ }
+ }
+
+ /*
+ * Well, who knows what this mess is....
+ */
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "unknown file format");
+ goto bad;
+
+found:
+ p->sf.rfile = fp;
+
+#ifdef PCAP_FDDIPAD
+ /* Padding only needed for live capture fcode */
+ p->fddipad = 0;
+#endif
+
+#if !defined(WIN32) && !defined(MSDOS)
+ /*
+ * You can do "select()" and "poll()" on plain files on most
+ * platforms, and should be able to do so on pipes.
+ *
+ * You can't do "select()" on anything other than sockets in
+ * Windows, so, on Win32 systems, we don't have "selectable_fd".
+ */
+ p->selectable_fd = fileno(fp);
+#endif
+
+ p->read_op = pcap_offline_read;
+ p->inject_op = sf_inject;
+ p->setfilter_op = install_bpf_program;
+ p->setdirection_op = sf_setdirection;
+ p->set_datalink_op = NULL; /* we don't support munging link-layer headers */
+ p->getnonblock_op = sf_getnonblock;
+ p->setnonblock_op = sf_setnonblock;
+ p->stats_op = sf_stats;
+#ifdef WIN32
+ p->setbuff_op = sf_setbuff;
+ p->setmode_op = sf_setmode;
+ p->setmintocopy_op = sf_setmintocopy;
+#endif
+ p->cleanup_op = sf_cleanup;
+ p->activated = 1;
+
+ return (p);
+ bad:
+ free(p);
+ return (NULL);
+}
+
+/*
+ * Read packets from a capture file, and call the callback for each
+ * packet.
+ * If cnt > 0, return after 'cnt' packets, otherwise continue until eof.
+ */
+int
+pcap_offline_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
+{
+ struct bpf_insn *fcode;
+ int status = 0;
+ int n = 0;
+ u_char *data;
+
+ while (status == 0) {
+ struct pcap_pkthdr h;
+
+ /*
+ * Has "pcap_breakloop()" been called?
+ * If so, return immediately - if we haven't read any
+ * packets, clear the flag and return -2 to indicate
+ * that we were told to break out of the loop, otherwise
+ * leave the flag set, so that the *next* call will break
+ * out of the loop without having read any packets, and
+ * return the number of packets we've processed so far.
+ */
+ if (p->break_loop) {
+ if (n == 0) {
+ p->break_loop = 0;
+ return (-2);
+ } else
+ return (n);
+ }
+
+ status = p->sf.next_packet_op(p, &h, &data);
+ if (status) {
+ if (status == 1)
+ return (0);
+ return (status);
+ }
+
+ if ((fcode = p->fcode.bf_insns) == NULL ||
+ bpf_filter(fcode, data, h.len, h.caplen)) {
+ (*callback)(user, &h, data);
+ if (++n >= cnt && cnt > 0)
+ break;
+ }
+ }
+ /*XXX this breaks semantics tcpslice expects */
+ return (n);
+}
diff --git a/freebsd/contrib/libpcap/scanner.c b/freebsd/contrib/libpcap/scanner.c
new file mode 100644
index 00000000..d6f0498d
--- /dev/null
+++ b/freebsd/contrib/libpcap/scanner.c
@@ -0,0 +1,4890 @@
+
+#line 3 "<stdout>"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define yy_create_buffer pcap_create_buffer
+#define yy_delete_buffer pcap_delete_buffer
+#define yy_flex_debug pcap_flex_debug
+#define yy_init_buffer pcap_init_buffer
+#define yy_flush_buffer pcap_flush_buffer
+#define yy_load_buffer_state pcap_load_buffer_state
+#define yy_switch_to_buffer pcap_switch_to_buffer
+#define yyin pcapin
+#define yyleng pcapleng
+#define yylex pcaplex
+#define yylineno pcaplineno
+#define yyout pcapout
+#define yyrestart pcaprestart
+#define yytext pcaptext
+#define yywrap pcapwrap
+#define yyalloc pcapalloc
+#define yyrealloc pcaprealloc
+#define yyfree pcapfree
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 37
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+#if defined(__FreeBSD__)
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS
+#endif
+#include <sys/cdefs.h>
+#include <stdint.h>
+#else
+#define __dead2
+#endif
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined(__FreeBSD__) || \
+ (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE pcaprestart(pcapin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 1024
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+extern yy_size_t pcapleng;
+
+extern FILE *pcapin, *pcapout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up pcaptext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
+ YY_RESTORE_YY_MORE_OFFSET \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up pcaptext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr) )
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ yy_size_t yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via pcaprestart()), so that the user can continue scanning by
+ * just pointing pcapin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+#define yy_current_buffer YY_CURRENT_BUFFER
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when pcaptext is formed. */
+static char yy_hold_char;
+static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */
+yy_size_t pcapleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow pcapwrap()'s to do buffer switches
+ * instead of setting up a fresh pcapin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void pcaprestart (FILE *input_file );
+void pcap_switch_to_buffer (YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE pcap_create_buffer (FILE *file,int size );
+void pcap_delete_buffer (YY_BUFFER_STATE b );
+void pcap_flush_buffer (YY_BUFFER_STATE b );
+void pcappush_buffer_state (YY_BUFFER_STATE new_buffer );
+void pcappop_buffer_state (void );
+
+static void pcapensure_buffer_stack (void );
+static void pcap_load_buffer_state (void );
+static void pcap_init_buffer (YY_BUFFER_STATE b,FILE *file );
+
+#define YY_FLUSH_BUFFER pcap_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE pcap_scan_buffer (char *base,yy_size_t size );
+YY_BUFFER_STATE pcap_scan_string (yyconst char *yy_str );
+YY_BUFFER_STATE pcap_scan_bytes (yyconst char *bytes,yy_size_t len );
+
+void *pcapalloc (yy_size_t );
+void *pcaprealloc (void *,yy_size_t );
+void pcapfree (void * );
+
+#define yy_new_buffer pcap_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ pcapensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ pcap_create_buffer(pcapin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ pcapensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ pcap_create_buffer(pcapin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+typedef unsigned char YY_CHAR;
+
+FILE *pcapin = (FILE *) 0, *pcapout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int pcaplineno;
+
+int pcaplineno = 1;
+
+extern char *pcaptext;
+#define yytext_ptr pcaptext
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[] ) __dead2;
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up pcaptext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+ pcapleng = (size_t) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+ (yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 147
+#define YY_END_OF_BUFFER 148
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[1438] =
+ { 0,
+ 0, 0, 148, 145, 105, 105, 105, 106, 145, 106,
+ 106, 106, 146, 115, 115, 106, 106, 106, 106, 143,
+ 143, 145, 143, 143, 143, 143, 143, 143, 143, 143,
+ 143, 143, 143, 143, 143, 143, 143, 143, 143, 143,
+ 143, 143, 106, 145, 109, 113, 67, 0, 143, 115,
+ 0, 143, 143, 143, 0, 117, 111, 108, 110, 107,
+ 112, 143, 144, 144, 143, 143, 143, 20, 143, 143,
+ 143, 143, 143, 143, 143, 143, 143, 143, 143, 143,
+ 143, 143, 143, 143, 143, 143, 143, 143, 143, 143,
+ 143, 143, 143, 143, 143, 7, 143, 34, 35, 143,
+
+ 143, 143, 143, 143, 143, 143, 143, 143, 143, 143,
+ 143, 143, 143, 91, 143, 68, 143, 143, 143, 143,
+ 143, 143, 60, 143, 143, 143, 143, 85, 143, 143,
+ 143, 143, 143, 143, 61, 143, 4, 143, 143, 143,
+ 143, 143, 143, 143, 68, 113, 143, 116, 116, 143,
+ 115, 143, 0, 117, 115, 117, 117, 117, 143, 143,
+ 143, 67, 5, 143, 80, 143, 143, 143, 143, 143,
+ 143, 143, 55, 103, 1, 0, 143, 21, 143, 143,
+ 143, 143, 143, 143, 143, 143, 143, 143, 36, 143,
+ 143, 18, 43, 0, 143, 29, 143, 25, 70, 143,
+
+ 143, 78, 37, 143, 99, 143, 143, 143, 143, 100,
+ 143, 46, 69, 81, 102, 143, 14, 143, 3, 143,
+ 143, 143, 143, 143, 93, 143, 143, 26, 143, 101,
+ 143, 104, 38, 2, 143, 42, 143, 9, 143, 10,
+ 88, 143, 87, 143, 143, 0, 143, 143, 116, 143,
+ 143, 143, 143, 115, 0, 143, 0, 118, 117, 117,
+ 0, 117, 0, 117, 0, 117, 0, 23, 143, 143,
+ 143, 143, 64, 16, 41, 143, 39, 143, 143, 143,
+ 30, 143, 97, 143, 143, 45, 11, 143, 12, 13,
+ 143, 143, 143, 32, 77, 143, 62, 3, 98, 47,
+
+ 143, 143, 143, 74, 143, 143, 143, 143, 48, 143,
+ 143, 40, 143, 6, 143, 92, 143, 8, 94, 143,
+ 143, 0, 143, 53, 73, 15, 143, 116, 116, 143,
+ 116, 116, 116, 143, 115, 143, 0, 117, 143, 0,
+ 0, 117, 0, 117, 118, 117, 0, 0, 0, 0,
+ 117, 117, 117, 117, 117, 0, 143, 56, 57, 58,
+ 59, 143, 22, 143, 143, 143, 143, 31, 143, 143,
+ 0, 19, 143, 143, 143, 86, 143, 33, 143, 79,
+ 28, 27, 143, 143, 82, 143, 143, 143, 50, 17,
+ 143, 143, 143, 143, 143, 143, 143, 143, 143, 143,
+
+ 143, 143, 0, 143, 143, 116, 143, 143, 143, 143,
+ 116, 116, 143, 115, 143, 0, 0, 117, 117, 117,
+ 0, 0, 118, 117, 117, 118, 117, 0, 0, 117,
+ 117, 117, 117, 117, 0, 0, 0, 0, 117, 117,
+ 0, 117, 0, 117, 0, 96, 143, 143, 143, 24,
+ 143, 143, 143, 143, 143, 143, 143, 143, 143, 143,
+ 143, 143, 143, 143, 70, 143, 143, 143, 143, 143,
+ 143, 143, 75, 76, 143, 95, 143, 143, 143, 143,
+ 143, 143, 143, 143, 143, 143, 143, 143, 116, 116,
+ 143, 116, 116, 116, 116, 143, 115, 143, 0, 117,
+
+ 117, 0, 117, 0, 0, 117, 0, 117, 118, 117,
+ 0, 0, 0, 117, 117, 0, 117, 118, 117, 0,
+ 0, 0, 0, 0, 0, 0, 117, 117, 117, 117,
+ 117, 0, 143, 143, 143, 143, 52, 63, 143, 143,
+ 143, 143, 143, 143, 143, 143, 143, 143, 143, 143,
+ 71, 143, 143, 44, 83, 84, 143, 143, 143, 143,
+ 54, 141, 137, 143, 139, 138, 142, 143, 0, 143,
+ 143, 116, 143, 143, 143, 116, 143, 115, 143, 0,
+ 0, 117, 117, 117, 117, 117, 117, 0, 0, 118,
+ 117, 117, 117, 0, 0, 117, 117, 117, 117, 117,
+
+ 0, 0, 0, 0, 0, 0, 0, 117, 117, 117,
+ 117, 117, 0, 0, 0, 0, 0, 117, 117, 0,
+ 117, 0, 117, 0, 143, 143, 143, 143, 143, 143,
+ 143, 143, 143, 143, 143, 143, 143, 120, 119, 143,
+ 143, 72, 143, 143, 143, 140, 136, 143, 143, 116,
+ 116, 116, 116, 143, 115, 143, 0, 117, 117, 0,
+ 117, 117, 0, 117, 0, 0, 117, 0, 117, 118,
+ 117, 0, 0, 0, 117, 117, 0, 117, 118, 117,
+ 0, 0, 0, 0, 0, 117, 117, 0, 117, 118,
+ 117, 0, 117, 117, 0, 0, 0, 0, 0, 0,
+
+ 0, 117, 117, 117, 117, 117, 0, 65, 143, 55,
+ 125, 132, 143, 143, 143, 143, 143, 143, 143, 143,
+ 143, 66, 49, 143, 143, 0, 143, 143, 143, 143,
+ 143, 115, 143, 0, 0, 117, 117, 117, 117, 117,
+ 117, 117, 117, 117, 0, 0, 118, 117, 117, 117,
+ 0, 0, 117, 117, 117, 117, 117, 0, 0, 0,
+ 0, 0, 0, 0, 117, 117, 117, 117, 117, 0,
+ 117, 117, 0, 0, 0, 0, 0, 0, 0, 117,
+ 117, 117, 117, 117, 0, 0, 0, 0, 0, 0,
+ 117, 117, 0, 117, 0, 117, 0, 89, 143, 143,
+
+ 143, 143, 143, 143, 143, 143, 143, 143, 143, 51,
+ 114, 114, 116, 116, 143, 115, 143, 0, 117, 117,
+ 0, 117, 117, 0, 117, 117, 0, 117, 0, 114,
+ 117, 0, 117, 118, 117, 0, 0, 0, 117, 117,
+ 0, 117, 118, 117, 0, 0, 0, 0, 0, 117,
+ 117, 0, 117, 118, 117, 0, 0, 0, 0, 0,
+ 0, 117, 117, 0, 117, 118, 117, 0, 117, 117,
+ 117, 0, 0, 0, 0, 0, 0, 0, 117, 117,
+ 117, 117, 117, 0, 143, 143, 143, 143, 143, 143,
+ 143, 143, 130, 143, 90, 114, 114, 116, 143, 114,
+
+ 114, 0, 0, 117, 117, 117, 117, 117, 117, 117,
+ 117, 117, 117, 117, 117, 0, 114, 118, 117, 117,
+ 117, 0, 0, 117, 117, 117, 117, 117, 0, 0,
+ 0, 0, 0, 0, 0, 117, 117, 117, 117, 117,
+ 0, 117, 117, 0, 0, 0, 0, 0, 0, 0,
+ 117, 117, 117, 117, 117, 0, 117, 117, 117, 0,
+ 0, 0, 0, 0, 0, 0, 117, 117, 117, 117,
+ 117, 0, 0, 0, 0, 0, 0, 117, 117, 0,
+ 117, 0, 117, 0, 143, 143, 143, 134, 143, 143,
+ 143, 143, 143, 143, 143, 122, 116, 143, 115, 0,
+
+ 117, 117, 0, 117, 117, 0, 117, 117, 0, 117,
+ 117, 0, 117, 0, 0, 0, 117, 0, 0, 117,
+ 118, 117, 0, 0, 0, 117, 117, 0, 117, 118,
+ 117, 0, 0, 0, 0, 0, 117, 117, 0, 117,
+ 118, 117, 0, 0, 0, 0, 0, 0, 117, 117,
+ 0, 117, 118, 117, 0, 0, 0, 0, 0, 0,
+ 117, 117, 0, 117, 118, 117, 0, 117, 117, 117,
+ 0, 0, 0, 0, 0, 0, 0, 117, 117, 117,
+ 117, 117, 0, 143, 143, 143, 143, 124, 143, 143,
+ 143, 128, 143, 114, 0, 0, 117, 117, 117, 117,
+
+ 117, 117, 117, 117, 117, 117, 117, 117, 117, 117,
+ 117, 0, 0, 0, 118, 0, 0, 117, 0, 0,
+ 117, 117, 117, 0, 0, 0, 0, 0, 0, 0,
+ 117, 117, 117, 0, 117, 117, 0, 0, 0, 0,
+ 0, 0, 0, 117, 117, 117, 0, 117, 117, 117,
+ 0, 0, 0, 0, 0, 0, 0, 117, 117, 117,
+ 0, 117, 117, 117, 0, 0, 0, 0, 0, 0,
+ 0, 117, 117, 117, 0, 0, 0, 0, 0, 0,
+ 117, 117, 0, 117, 0, 117, 0, 121, 133, 135,
+ 129, 143, 143, 143, 143, 0, 0, 117, 0, 117,
+
+ 0, 117, 117, 0, 117, 117, 0, 117, 117, 0,
+ 117, 117, 0, 117, 0, 0, 0, 0, 117, 117,
+ 0, 117, 0, 0, 117, 117, 117, 0, 0, 0,
+ 0, 117, 117, 117, 0, 0, 0, 0, 0, 117,
+ 117, 117, 0, 0, 0, 0, 0, 117, 117, 117,
+ 0, 0, 0, 0, 0, 117, 117, 117, 117, 117,
+ 117, 0, 0, 0, 0, 0, 0, 0, 117, 117,
+ 117, 0, 143, 143, 143, 143, 0, 0, 0, 117,
+ 117, 117, 117, 117, 117, 0, 0, 0, 0, 117,
+ 117, 0, 0, 0, 0, 117, 117, 117, 0, 0,
+
+ 0, 0, 0, 117, 117, 117, 117, 0, 0, 0,
+ 0, 0, 117, 117, 117, 117, 0, 0, 0, 0,
+ 0, 117, 117, 117, 117, 0, 0, 0, 0, 0,
+ 117, 0, 0, 0, 0, 0, 117, 117, 117, 143,
+ 143, 143, 131, 117, 117, 117, 117, 117, 117, 117,
+ 117, 0, 0, 0, 0, 117, 117, 0, 0, 117,
+ 0, 0, 0, 117, 0, 0, 0, 117, 0, 0,
+ 0, 117, 0, 0, 0, 117, 117, 117, 117, 0,
+ 0, 0, 0, 0, 117, 126, 143, 123, 117, 0,
+ 0, 117, 117, 0, 117, 117, 117, 0, 117, 117,
+
+ 117, 0, 117, 117, 117, 0, 117, 117, 117, 0,
+ 0, 0, 0, 117, 127, 117, 117, 0, 0, 0,
+ 0, 0, 0, 117, 117, 117, 0, 0, 117, 117,
+ 117, 117, 117, 0, 117, 117, 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 5, 1, 1, 6, 1, 7, 1, 8,
+ 8, 9, 9, 1, 10, 11, 9, 12, 13, 14,
+ 15, 16, 17, 18, 17, 17, 17, 19, 1, 20,
+ 21, 22, 1, 1, 23, 23, 23, 23, 23, 23,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 25, 24, 24,
+ 26, 27, 26, 1, 28, 1, 29, 30, 31, 32,
+
+ 33, 34, 35, 36, 37, 24, 38, 39, 40, 41,
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 24, 1, 53, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int32_t yy_meta[54] =
+ { 0,
+ 1, 2, 2, 1, 2, 1, 3, 2, 1, 4,
+ 5, 6, 6, 6, 6, 6, 6, 6, 7, 3,
+ 3, 3, 8, 4, 9, 3, 1, 4, 8, 8,
+ 8, 8, 8, 8, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
+ 9, 4, 3
+ } ;
+
+static yyconst flex_int16_t yy_base[1898] =
+ { 0,
+ 0, 0, 3858, 53, 7396, 7396, 54, 3836, 60, 3849,
+ 7396, 82, 7396, 100, 31, 152, 47, 3834, 49, 169,
+ 211, 169, 61, 44, 126, 61, 30, 63, 76, 3811,
+ 215, 218, 160, 32, 166, 117, 171, 228, 145, 3820,
+ 229, 3812, 3782, 276, 7396, 0, 7396, 292, 315, 339,
+ 3815, 363, 0, 370, 0, 404, 7396, 7396, 7396, 7396,
+ 7396, 274, 292, 0, 3788, 3785, 3799, 0, 3797, 3785,
+ 3798, 3781, 3769, 3763, 3764, 3767, 3765, 3764, 3773, 3743,
+ 3756, 3739, 324, 3749, 3752, 3736, 3734, 3747, 3719, 3724,
+ 3722, 82, 3726, 3721, 3729, 148, 229, 0, 0, 37,
+
+ 123, 3717, 3726, 167, 3695, 3693, 3696, 3699, 3689, 3695,
+ 3686, 3671, 3677, 0, 3685, 0, 3668, 3674, 3667, 3668,
+ 3668, 3653, 160, 3664, 3647, 3658, 3650, 56, 3645, 216,
+ 3628, 126, 3627, 3639, 0, 3625, 0, 3624, 3622, 3627,
+ 3634, 3610, 3601, 3616, 7396, 7396, 429, 453, 212, 494,
+ 518, 542, 3625, 549, 3631, 573, 269, 3621, 3581, 3586,
+ 3577, 0, 0, 3582, 0, 3591, 3585, 3574, 3573, 3559,
+ 3556, 3557, 3564, 0, 0, 3558, 3548, 0, 3560, 3540,
+ 3528, 3542, 3545, 3526, 3528, 3541, 3526, 3525, 0, 3509,
+ 3503, 0, 0, 3506, 3496, 0, 3507, 0, 3504, 3492,
+
+ 3499, 0, 0, 3474, 0, 3483, 3491, 203, 3473, 0,
+ 3469, 3485, 0, 3480, 0, 3483, 0, 3456, 3440, 3434,
+ 3437, 3441, 3433, 3429, 0, 3427, 3440, 0, 3414, 0,
+ 3413, 0, 0, 0, 3410, 0, 171, 167, 3421, 0,
+ 0, 3411, 0, 3408, 3409, 613, 3439, 636, 660, 3423,
+ 667, 476, 267, 691, 3414, 715, 3412, 3410, 723, 288,
+ 3409, 3407, 483, 764, 787, 3391, 0, 0, 3367, 327,
+ 3370, 3375, 0, 0, 0, 3371, 0, 3370, 3371, 3340,
+ 0, 3340, 0, 3334, 3334, 0, 590, 3328, 0, 0,
+ 3334, 3307, 3308, 0, 0, 3298, 0, 0, 0, 0,
+
+ 3313, 3303, 3291, 0, 3284, 3287, 3303, 3276, 3271, 3268,
+ 3248, 0, 3246, 0, 3239, 0, 192, 0, 0, 3232,
+ 3227, 715, 3218, 0, 0, 0, 812, 836, 312, 877,
+ 3245, 3244, 381, 900, 924, 948, 3235, 955, 597, 3234,
+ 3231, 978, 752, 1002, 1025, 3230, 0, 3219, 400, 403,
+ 1049, 3197, 1073, 339, 3196, 3203, 3168, 0, 0, 0,
+ 0, 3162, 0, 3161, 3159, 3142, 3141, 0, 3156, 3140,
+ 1092, 0, 3126, 3115, 3133, 0, 3108, 0, 3111, 3102,
+ 0, 0, 3101, 3080, 237, 3079, 3097, 268, 3072, 0,
+ 3050, 3039, 3053, 3046, 3041, 3050, 3043, 3031, 3032, 3025,
+
+ 3022, 3036, 1129, 3051, 1152, 1176, 3039, 1183, 859, 305,
+ 1207, 340, 1247, 1270, 1294, 3009, 3008, 1302, 364, 3007,
+ 3005, 3003, 3002, 1343, 373, 3001, 2976, 491, 607, 1384,
+ 2975, 1408, 404, 2974, 2981, 2971, 866, 0, 347, 2970,
+ 1096, 1449, 1472, 2969, 0, 0, 2926, 2942, 2923, 0,
+ 2931, 2914, 2920, 2933, 2918, 2919, 2918, 407, 2901, 411,
+ 2901, 2909, 2897, 2893, 0, 2883, 2893, 2881, 2886, 2853,
+ 2842, 2841, 0, 0, 2844, 0, 2838, 2830, 2843, 2827,
+ 2821, 2817, 2811, 2809, 2813, 2818, 2817, 1497, 1521, 405,
+ 1562, 2825, 2824, 609, 1586, 1610, 1617, 1641, 2815, 1648,
+
+ 1672, 1695, 2814, 2813, 2811, 1718, 1103, 1742, 1765, 2810,
+ 0, 1230, 0, 461, 2809, 1237, 1789, 1812, 2794, 0,
+ 734, 761, 2801, 462, 781, 812, 1836, 2792, 1860, 428,
+ 2791, 2798, 381, 2761, 2766, 2763, 0, 0, 2753, 2755,
+ 2741, 2741, 2753, 2735, 2734, 2741, 2719, 2720, 2731, 2730,
+ 0, 2721, 2714, 0, 0, 0, 2727, 2723, 2713, 2700,
+ 0, 0, 0, 2704, 0, 0, 0, 2693, 1900, 2728,
+ 1923, 1947, 2725, 1954, 324, 1978, 2002, 2009, 2033, 2716,
+ 2715, 2041, 452, 2700, 2082, 488, 2699, 2698, 2697, 2696,
+ 2123, 489, 2694, 874, 894, 2164, 2693, 2188, 493, 2692,
+
+ 2684, 1123, 1125, 2683, 2682, 1246, 1312, 2229, 2673, 2253,
+ 494, 2672, 2677, 1326, 0, 1333, 0, 527, 2668, 1366,
+ 2294, 2317, 2653, 0, 2340, 428, 79, 255, 237, 617,
+ 546, 586, 2624, 362, 522, 547, 379, 2623, 2622, 1124,
+ 2621, 2619, 1242, 849, 473, 2618, 2617, 2378, 2415, 2451,
+ 2487, 546, 2511, 588, 2519, 2543, 2629, 2550, 2574, 2597,
+ 2628, 2621, 2644, 2627, 2626, 2624, 2667, 1373, 2691, 2714,
+ 2622, 0, 1431, 0, 675, 2606, 1438, 2738, 2761, 2605,
+ 0, 1544, 0, 1551, 0, 676, 2604, 1883, 2785, 2808,
+ 2603, 0, 637, 1890, 2610, 1381, 1446, 2608, 2607, 1466,
+
+ 1497, 2832, 2598, 2856, 638, 2582, 2589, 567, 682, 591,
+ 612, 763, 1246, 2051, 1383, 628, 803, 805, 2078, 683,
+ 829, 761, 828, 2076, 2080, 2898, 830, 2921, 892, 2944,
+ 2109, 2968, 2992, 2580, 2579, 3000, 737, 2577, 3041, 873,
+ 2576, 3082, 876, 2575, 2559, 2558, 2557, 3123, 897, 2556,
+ 1559, 1689, 3164, 2555, 3188, 901, 2553, 2560, 1899, 2051,
+ 2559, 2558, 2052, 2058, 3229, 2528, 3253, 924, 2527, 2534,
+ 925, 2146, 2533, 2118, 2119, 2532, 2530, 2120, 2140, 3294,
+ 2521, 3318, 926, 2520, 2527, 0, 2211, 0, 2218, 0,
+ 732, 2496, 2276, 3359, 3382, 2495, 0, 918, 970, 971,
+
+ 972, 1899, 996, 1448, 1017, 1018, 2271, 1042, 1561, 1043,
+ 3407, 3430, 3454, 998, 3494, 3518, 3542, 2494, 3549, 3573,
+ 3596, 2493, 3620, 3643, 2492, 3667, 3690, 2490, 2489, 2488,
+ 3713, 2363, 3737, 3760, 2487, 0, 2401, 0, 1011, 2440,
+ 2438, 3784, 3807, 2439, 0, 2458, 0, 2465, 0, 1058,
+ 2438, 2472, 3831, 3854, 2424, 0, 0, 2479, 0, 2879,
+ 0, 1082, 2423, 2886, 3878, 3901, 2422, 0, 0, 1049,
+ 3023, 2429, 2161, 2226, 2378, 2351, 2290, 2291, 3925, 2342,
+ 3949, 1072, 2341, 2348, 2293, 2354, 2355, 2122, 1123, 2228,
+ 2356, 1066, 2357, 1198, 1121, 1145, 1199, 3991, 4015, 4024,
+
+ 1200, 2326, 2325, 4042, 1102, 2324, 4083, 1105, 2320, 4124,
+ 1152, 2319, 4165, 1153, 2318, 2303, 2301, 4205, 4229, 1154,
+ 2300, 2409, 2410, 4270, 2281, 4294, 1182, 2278, 2285, 2591,
+ 2638, 2284, 2268, 2894, 2895, 4335, 2256, 4359, 1241, 2254,
+ 2244, 1243, 3030, 2243, 2898, 3038, 2242, 2239, 3051, 3057,
+ 4400, 2230, 4424, 1244, 2197, 2204, 0, 1247, 3105, 2203,
+ 3058, 3079, 2199, 2198, 3099, 3118, 4465, 2170, 4489, 1271,
+ 2169, 2174, 0, 3146, 0, 3211, 0, 1161, 2154, 3218,
+ 4530, 4553, 2149, 0, 3263, 3264, 3328, 1201, 2394, 2100,
+ 1402, 2395, 2270, 1464, 1488, 1342, 4578, 4602, 4611, 2130,
+
+ 4628, 4652, 4675, 2100, 4699, 4722, 2070, 4746, 4769, 2068,
+ 4793, 4816, 2065, 2063, 4840, 1384, 2062, 2061, 3281, 4881,
+ 2059, 2049, 0, 3345, 0, 1530, 2046, 3477, 4905, 2018,
+ 2016, 0, 3484, 0, 3972, 0, 1571, 2015, 3979, 4929,
+ 2014, 2011, 0, 0, 4031, 0, 4065, 0, 1594, 1981,
+ 4072, 4953, 1980, 1906, 0, 0, 4106, 0, 4113, 0,
+ 1595, 1863, 4147, 4977, 1844, 1819, 0, 0, 1385, 4154,
+ 1822, 3120, 3140, 1806, 1802, 3159, 3161, 5001, 1771, 5025,
+ 1448, 1770, 1756, 1490, 1664, 1665, 1515, 1666, 1736, 4163,
+ 1687, 1711, 2396, 5067, 1747, 5084, 5108, 1556, 1725, 5149,
+
+ 1561, 1724, 5190, 1586, 1723, 5231, 1616, 1719, 5272, 1617,
+ 1704, 1700, 4191, 5313, 1626, 1620, 0, 1619, 3226, 3264,
+ 5337, 1617, 1569, 1576, 3289, 3328, 1572, 1536, 3355, 3376,
+ 5361, 1521, 1505, 1512, 1618, 4252, 1508, 3407, 3493, 1483,
+ 1464, 3590, 3637, 5385, 1451, 1450, 1418, 0, 1619, 4259,
+ 1397, 3684, 4175, 1394, 1393, 4176, 4200, 5409, 1352, 1350,
+ 1356, 0, 1647, 4317, 1354, 4204, 4267, 1353, 1319, 4311,
+ 4330, 5433, 1310, 1309, 1315, 0, 4382, 0, 4389, 0,
+ 1751, 1305, 4447, 5457, 0, 1271, 0, 1735, 1758, 1759,
+ 1781, 1782, 1969, 4483, 4499, 5481, 1648, 0, 1254, 5522,
+
+ 0, 1248, 5546, 0, 1216, 5570, 0, 1212, 5594, 0,
+ 1183, 5618, 0, 1109, 4332, 4397, 5642, 1107, 1103, 1076,
+ 1064, 1028, 4454, 0, 1821, 1007, 983, 4516, 0, 4618,
+ 0, 1845, 964, 960, 0, 4863, 0, 4870, 0, 1869,
+ 955, 925, 0, 5048, 0, 5055, 0, 1909, 924, 902,
+ 0, 5074, 0, 5131, 0, 1932, 885, 80, 0, 1671,
+ 5138, 180, 4462, 4526, 187, 225, 4547, 4627, 5666, 280,
+ 0, 301, 2358, 1783, 1806, 1829, 5690, 299, 340, 0,
+ 0, 0, 0, 0, 0, 5172, 0, 1962, 431, 496,
+ 0, 4669, 4716, 511, 532, 0, 1811, 5179, 559, 4763,
+
+ 4810, 563, 605, 0, 0, 1833, 5213, 606, 4878, 5083,
+ 628, 630, 0, 0, 1835, 5220, 680, 5228, 5241, 702,
+ 704, 0, 0, 1836, 5255, 705, 5269, 5282, 707, 708,
+ 0, 0, 5296, 0, 5504, 0, 1963, 728, 0, 3078,
+ 2959, 2156, 1916, 0, 7396, 0, 0, 0, 0, 0,
+ 0, 5310, 5498, 739, 773, 0, 7396, 5512, 0, 7396,
+ 0, 5713, 0, 7396, 0, 5720, 0, 7396, 0, 5727,
+ 0, 7396, 0, 5734, 0, 7396, 0, 1894, 5741, 779,
+ 5749, 5750, 796, 2017, 0, 1970, 3336, 2057, 0, 5750,
+ 0, 1896, 5764, 798, 0, 1897, 5771, 800, 0, 1924,
+
+ 5778, 803, 0, 1951, 5790, 844, 0, 1953, 5797, 851,
+ 0, 5804, 0, 7396, 2180, 1978, 5811, 853, 0, 0,
+ 0, 0, 0, 0, 1980, 5818, 886, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 7396, 5836, 5844, 5848,
+ 5851, 5854, 5857, 5860, 5863, 5866, 5869, 5872, 5875, 5878,
+ 5881, 5884, 5887, 5890, 5893, 5896, 5900, 5904, 5907, 5910,
+ 5913, 5916, 5919, 5922, 5925, 5928, 5932, 5936, 5939, 5942,
+ 5946, 5948, 5951, 5954, 5957, 5960, 5963, 5966, 5969, 5972,
+ 5976, 5978, 5981, 5985, 5990, 5994, 5997, 6001, 6004, 6007,
+ 6010, 6013, 6016, 6019, 6022, 6026, 6030, 6033, 6037, 6041,
+
+ 6046, 6050, 6052, 6056, 6059, 6063, 6066, 6069, 6073, 6075,
+ 6078, 6081, 6084, 6087, 6090, 6093, 6096, 6099, 6102, 6106,
+ 6108, 6111, 6114, 6117, 6121, 6123, 6126, 6129, 6134, 6138,
+ 6143, 6147, 6149, 6153, 6156, 6160, 6165, 6169, 6172, 6175,
+ 6178, 6181, 6184, 6187, 6190, 6194, 6198, 6201, 6205, 6209,
+ 6214, 6218, 6220, 6224, 6227, 6231, 6234, 6239, 6243, 6248,
+ 6252, 6254, 6258, 6261, 6265, 6268, 6271, 6274, 6278, 6280,
+ 6283, 6288, 6292, 6295, 6298, 6301, 6304, 6307, 6310, 6313,
+ 6316, 6320, 6322, 6325, 6328, 6331, 6335, 6337, 6340, 6343,
+ 6346, 6349, 6353, 6355, 6358, 6361, 6364, 6369, 6373, 6378,
+
+ 6382, 6384, 6388, 6391, 6395, 6400, 6404, 6407, 6410, 6413,
+ 6416, 6419, 6422, 6425, 6429, 6433, 6436, 6440, 6444, 6449,
+ 6453, 6455, 6459, 6462, 6466, 6469, 6474, 6478, 6483, 6487,
+ 6489, 6493, 6496, 6500, 6503, 6506, 6511, 6515, 6520, 6524,
+ 6526, 6530, 6533, 6537, 6540, 6543, 6546, 6550, 6552, 6555,
+ 6560, 6564, 6567, 6570, 6573, 6576, 6579, 6582, 6585, 6588,
+ 6591, 6594, 6597, 6601, 6603, 6606, 6609, 6612, 6615, 6619,
+ 6621, 6624, 6627, 6630, 6633, 6636, 6640, 6642, 6645, 6648,
+ 6651, 6654, 6657, 6661, 6663, 6666, 6669, 6672, 6675, 6680,
+ 6684, 6689, 6693, 6695, 6699, 6702, 6706, 6711, 6715, 6718,
+
+ 6721, 6724, 6727, 6730, 6733, 6736, 6739, 6742, 6746, 6750,
+ 6753, 6757, 6761, 6766, 6770, 6772, 6776, 6779, 6783, 6786,
+ 6791, 6795, 6800, 6804, 6806, 6810, 6813, 6817, 6820, 6823,
+ 6828, 6832, 6837, 6841, 6843, 6847, 6850, 6854, 6857, 6860,
+ 6865, 6869, 6874, 6878, 6880, 6884, 6887, 6891, 6894, 6897,
+ 6900, 6904, 6906, 6909, 6912, 6917, 6921, 6924, 6927, 6930,
+ 6933, 6936, 6939, 6942, 6945, 6948, 6951, 6954, 6958, 6962,
+ 6965, 6968, 6972, 6975, 6978, 6982, 6984, 6987, 6990, 6994,
+ 6996, 6999, 7002, 7005, 7009, 7011, 7014, 7017, 7020, 7024,
+ 7026, 7029, 7032, 7035, 7039, 7041, 7044, 7047, 7052, 7056,
+
+ 7061, 7065, 7067, 7071, 7074, 7078, 7083, 7087, 7090, 7093,
+ 7096, 7099, 7102, 7105, 7108, 7111, 7115, 7117, 7120, 7124,
+ 7129, 7133, 7134, 7137, 7142, 7146, 7151, 7155, 7156, 7159,
+ 7162, 7167, 7171, 7176, 7180, 7181, 7184, 7187, 7192, 7196,
+ 7201, 7205, 7206, 7209, 7212, 7217, 7221, 7226, 7230, 7231,
+ 7234, 7237, 7240, 7244, 7246, 7251, 7255, 7258, 7261, 7264,
+ 7267, 7270, 7273, 7277, 7282, 7286, 7287, 7290, 7293, 7296,
+ 7299, 7302, 7305, 7308, 7311, 7314, 7317, 7322, 7326, 7329,
+ 7332, 7335, 7339, 7343, 7347, 7351, 7355, 7358, 7361, 7365,
+ 7368, 7371, 7374, 7377, 7380, 7384, 7387
+
+ } ;
+
+static yyconst flex_int16_t yy_def[1898] =
+ { 0,
+ 1437, 1, 1437, 1437, 1437, 1437, 1437, 1437, 1438, 1437,
+ 1437, 1437, 1437, 1437, 14, 1437, 1437, 1437, 1437, 14,
+ 20, 1439, 20, 20, 20, 20, 20, 20, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 1437, 1437, 1437, 1440, 1437, 21, 21, 20,
+ 1441, 50, 21, 21, 21, 1437, 1437, 1437, 1437, 1437,
+ 1437, 49, 1439, 1439, 52, 52, 52, 21, 21, 21,
+ 21, 52, 21, 21, 52, 21, 21, 21, 52, 21,
+ 21, 21, 21, 21, 52, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 1437, 1437, 21, 21, 148, 21,
+ 21, 151, 1442, 1437, 54, 1437, 156, 1443, 21, 21,
+ 152, 21, 21, 21, 152, 21, 21, 21, 21, 21,
+ 21, 152, 21, 21, 21, 21, 21, 21, 21, 152,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 248, 249, 152, 1444, 254, 1445, 1446, 1437, 259,
+ 1447, 1448, 1437, 1437, 1437, 1449, 1450, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 328, 21,
+ 249, 251, 249, 251, 251, 335, 1451, 1437, 334, 1452,
+ 1453, 1437, 1437, 1437, 1437, 1454, 1455, 1456, 1457, 1457,
+ 1437, 1458, 1437, 353, 1459, 1450, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+
+ 21, 21, 21, 21, 21, 21, 21, 21, 405, 406,
+ 406, 411, 405, 335, 414, 1460, 1461, 1437, 418, 1462,
+ 1437, 1463, 1464, 1437, 424, 1465, 1466, 1467, 1467, 1437,
+ 1468, 1437, 432, 1469, 1455, 1437, 1437, 1470, 1471, 1437,
+ 1437, 1437, 1437, 1472, 1473, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 489,
+ 21, 406, 408, 406, 406, 495, 414, 497, 1474, 1437,
+
+ 1437, 1437, 1475, 1476, 1477, 1437, 1437, 1437, 1437, 1478,
+ 1479, 1437, 1480, 1481, 1437, 1437, 1437, 1437, 1482, 1483,
+ 1484, 1484, 1470, 1471, 1485, 1485, 1437, 1486, 1437, 529,
+ 1487, 1488, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 572, 572, 576, 497, 578, 1489,
+ 1490, 1437, 582, 1491, 1437, 585, 1492, 1437, 1493, 1494,
+ 1437, 591, 1495, 1496, 1496, 1437, 1497, 1437, 598, 1498,
+
+ 1499, 1500, 1500, 1501, 1502, 1503, 1503, 1437, 1504, 1437,
+ 610, 1505, 1506, 1437, 1507, 1437, 1508, 1509, 1437, 1437,
+ 1437, 1437, 1510, 1511, 579, 625, 625, 625, 625, 625,
+ 625, 625, 625, 625, 625, 625, 625, 625, 625, 625,
+ 625, 625, 625, 625, 625, 625, 625, 625, 625, 625,
+ 650, 650, 650, 625, 650, 655, 1512, 1437, 1437, 1437,
+ 1513, 1437, 1437, 1514, 1515, 1516, 1437, 1437, 1437, 1437,
+ 1517, 1518, 1437, 1519, 1520, 1437, 1437, 1437, 1437, 1521,
+ 1522, 1437, 1523, 1437, 1524, 1525, 1437, 1437, 1437, 1437,
+ 1526, 1527, 1528, 1437, 1529, 1530, 1530, 1531, 1532, 1533,
+
+ 1533, 1437, 1534, 1437, 704, 1535, 1536, 1537, 1537, 1537,
+ 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537, 1537,
+ 1537, 1537, 1537, 1537, 1537, 1537, 1537, 726, 1537, 726,
+ 730, 730, 732, 1538, 1539, 1437, 736, 1540, 1437, 739,
+ 1541, 1437, 742, 1542, 1437, 1543, 1544, 1437, 748, 1545,
+ 1546, 1546, 1437, 1547, 1437, 755, 1548, 1549, 1550, 1550,
+ 1551, 1552, 1553, 1553, 1437, 1554, 1437, 767, 1555, 1556,
+ 1557, 1437, 1558, 1559, 1559, 1560, 1561, 1562, 1562, 1437,
+ 1563, 1437, 782, 1564, 1565, 1566, 1437, 1567, 1437, 1568,
+ 1569, 1437, 1437, 1437, 1437, 1570, 1571, 1572, 1572, 1572,
+
+ 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572, 1572,
+ 1572, 811, 811, 813, 811, 811, 816, 1573, 1437, 1437,
+ 1437, 1574, 1437, 1437, 1575, 1437, 1437, 1576, 1577, 1578,
+ 1437, 1437, 1437, 1437, 1579, 1580, 1437, 1581, 1582, 1437,
+ 1437, 1437, 1437, 1583, 1584, 1437, 1585, 1437, 1586, 1587,
+ 1437, 1437, 1437, 1437, 1588, 1589, 1590, 1437, 1591, 1437,
+ 1592, 1593, 1437, 1437, 1437, 1437, 1594, 1595, 1596, 1597,
+ 1437, 1598, 1599, 1599, 1600, 1601, 1602, 1602, 1437, 1603,
+ 1437, 881, 1604, 1605, 1606, 1606, 1606, 1606, 1606, 1606,
+ 1606, 1606, 1606, 1606, 1606, 1606, 1606, 1606, 898, 1606,
+
+ 1606, 1607, 1608, 1437, 904, 1609, 1437, 907, 1610, 1437,
+ 910, 1611, 1437, 913, 1612, 1437, 1613, 1437, 1437, 919,
+ 1614, 1615, 1615, 1437, 1616, 1437, 926, 1617, 1618, 1619,
+ 1619, 1620, 1621, 1622, 1622, 1437, 1623, 1437, 938, 1624,
+ 1625, 1626, 1437, 1627, 1628, 1628, 1629, 1630, 1631, 1631,
+ 1437, 1632, 1437, 953, 1633, 1634, 1635, 1636, 1437, 1637,
+ 1638, 1638, 1639, 1640, 1641, 1641, 1437, 1642, 1437, 969,
+ 1643, 1644, 1645, 1437, 1646, 1437, 1647, 1648, 1437, 1437,
+ 1437, 1437, 1649, 1650, 1651, 1651, 1651, 1651, 1651, 1651,
+ 1651, 1651, 1651, 1651, 1651, 1651, 1651, 997, 1651, 1652,
+
+ 1437, 1437, 1437, 1653, 1437, 1437, 1654, 1437, 1437, 1655,
+ 1437, 1437, 1656, 1657, 1437, 1015, 1658, 1659, 1437, 1437,
+ 1660, 1661, 1662, 1437, 1663, 1664, 1437, 1437, 1437, 1665,
+ 1666, 1667, 1437, 1668, 1437, 1669, 1670, 1437, 1437, 1437,
+ 1671, 1672, 1673, 1674, 1437, 1675, 1437, 1676, 1677, 1437,
+ 1437, 1437, 1678, 1679, 1680, 1681, 1437, 1682, 1437, 1683,
+ 1684, 1437, 1437, 1437, 1685, 1686, 1687, 1688, 1689, 1437,
+ 1690, 1691, 1691, 1692, 1693, 1694, 1694, 1437, 1695, 1437,
+ 1080, 1696, 1697, 1698, 1698, 1698, 1698, 1698, 1698, 1698,
+ 1698, 1698, 1698, 1698, 1699, 1437, 1437, 1097, 1700, 1437,
+
+ 1100, 1701, 1437, 1103, 1702, 1437, 1106, 1703, 1437, 1109,
+ 1704, 1437, 1437, 1437, 1705, 1706, 1707, 1708, 1709, 1709,
+ 1437, 1710, 1711, 1712, 1713, 1713, 1714, 1715, 1716, 1716,
+ 1437, 1717, 1718, 1719, 1720, 1437, 1721, 1722, 1722, 1723,
+ 1724, 1725, 1725, 1437, 1726, 1727, 1728, 1729, 1730, 1437,
+ 1731, 1732, 1732, 1733, 1734, 1735, 1735, 1437, 1736, 1737,
+ 1738, 1739, 1740, 1437, 1741, 1742, 1742, 1743, 1744, 1745,
+ 1745, 1437, 1746, 1747, 1748, 1749, 1437, 1750, 1437, 1751,
+ 1752, 1437, 1437, 1437, 1753, 1754, 1755, 1756, 1756, 1756,
+ 1756, 1756, 1756, 1756, 1756, 1437, 1196, 1757, 1758, 1437,
+
+ 1759, 1760, 1437, 1761, 1762, 1437, 1763, 1764, 1437, 1765,
+ 1766, 1437, 1767, 1768, 1769, 1769, 1437, 1770, 1771, 1772,
+ 1773, 1774, 1437, 1775, 1776, 1437, 1777, 1437, 1778, 1437,
+ 1779, 1780, 1437, 1781, 1782, 1437, 1783, 1437, 1784, 1785,
+ 1437, 1786, 1787, 1437, 1788, 1437, 1789, 1790, 1437, 1791,
+ 1792, 1437, 1793, 1437, 1794, 1795, 1437, 1796, 1797, 1798,
+ 1437, 1799, 1800, 1800, 1801, 1802, 1803, 1803, 1437, 1804,
+ 1805, 1806, 1807, 1807, 1807, 1807, 1437, 1808, 1809, 1810,
+ 1811, 1812, 1813, 1814, 1815, 1437, 1816, 1817, 1437, 1818,
+ 1819, 1820, 1820, 1821, 1822, 1823, 1824, 1437, 1825, 1826,
+
+ 1826, 1827, 1828, 1829, 1830, 1831, 1437, 1832, 1833, 1833,
+ 1834, 1835, 1836, 1837, 1838, 1437, 1839, 1840, 1840, 1841,
+ 1842, 1843, 1844, 1845, 1437, 1846, 1847, 1847, 1848, 1849,
+ 1850, 1851, 1437, 1852, 1437, 1853, 1854, 1437, 1855, 1856,
+ 1856, 1856, 1856, 1857, 1437, 1858, 1859, 1860, 1861, 1862,
+ 1863, 1864, 1864, 1865, 1866, 1867, 1437, 1437, 1868, 1437,
+ 1869, 1437, 1870, 1437, 1871, 1437, 1872, 1437, 1873, 1437,
+ 1874, 1437, 1875, 1437, 1876, 1437, 1851, 1877, 1437, 1852,
+ 1878, 1878, 1853, 1854, 1879, 1856, 1856, 1856, 1880, 1437,
+ 1881, 1882, 1437, 1868, 1869, 1883, 1437, 1870, 1871, 1884,
+
+ 1437, 1872, 1873, 1885, 1437, 1874, 1875, 1886, 1437, 1876,
+ 1887, 1437, 1888, 1437, 1856, 1889, 1437, 1881, 1890, 1891,
+ 1892, 1893, 1894, 1887, 1895, 1437, 1888, 1896, 1890, 1891,
+ 1892, 1893, 1894, 1897, 1896, 1897, 0, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437
+
+ } ;
+
+static yyconst flex_int16_t yy_nxt[7450] =
+ { 0,
+ 4, 5, 6, 7, 8, 9, 10, 11, 12, 11,
+ 13, 14, 15, 15, 15, 15, 15, 15, 16, 17,
+ 18, 19, 20, 21, 21, 11, 22, 13, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 21, 32, 33,
+ 34, 35, 36, 21, 37, 38, 39, 40, 41, 42,
+ 21, 21, 43, 44, 44, 53, 44, 44, 44, 44,
+ 44, 44, 44, 44, 111, 44, 57, 58, 44, 60,
+ 61, 44, 44, 112, 72, 83, 84, 197, 44, 44,
+ 44, 53, 44, 198, 228, 44, 44, 44, 73, 65,
+ 44, 66, 67, 79, 85, 74, 68, 80, 426, 86,
+
+ 44, 69, 229, 81, 87, 70, 82, 71, 44, 48,
+ 49, 50, 50, 50, 50, 50, 50, 50, 51, 710,
+ 88, 187, 52, 53, 54, 53, 188, 55, 52, 52,
+ 52, 52, 52, 52, 53, 53, 53, 53, 53, 53,
+ 53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
+ 54, 53, 44, 118, 75, 44, 234, 44, 119, 120,
+ 44, 121, 122, 199, 76, 192, 235, 77, 200, 63,
+ 56, 78, 63, 135, 63, 136, 322, 63, 44, 62,
+ 52, 52, 52, 52, 52, 52, 52, 63, 105, 137,
+ 1177, 222, 106, 53, 113, 63, 138, 1179, 193, 123,
+
+ 323, 107, 108, 124, 223, 109, 114, 110, 115, 203,
+ 116, 125, 204, 117, 205, 320, 126, 321, 127, 53,
+ 55, 53, 53, 53, 53, 53, 53, 53, 53, 1437,
+ 98, 99, 392, 53, 302, 980, 53, 393, 194, 53,
+ 53, 53, 53, 53, 53, 90, 100, 303, 91, 92,
+ 101, 93, 231, 94, 102, 95, 103, 96, 128, 140,
+ 97, 232, 53, 104, 129, 195, 130, 141, 131, 469,
+ 196, 142, 132, 143, 133, 134, 44, 53, 333, 44,
+ 712, 44, 470, 53, 44, 150, 150, 150, 150, 150,
+ 150, 150, 63, 1437, 44, 63, 711, 63, 1185, 473,
+
+ 63, 53, 44, 147, 147, 147, 147, 147, 147, 147,
+ 63, 1183, 1437, 474, 147, 53, 494, 1345, 63, 1437,
+ 147, 147, 147, 147, 147, 147, 148, 149, 149, 149,
+ 149, 149, 149, 176, 53, 652, 53, 150, 1437, 358,
+ 359, 360, 361, 150, 150, 150, 150, 150, 150, 49,
+ 151, 151, 151, 151, 151, 151, 151, 263, 1278, 362,
+ 177, 152, 53, 1437, 53, 265, 178, 152, 152, 152,
+ 152, 152, 152, 62, 152, 152, 152, 152, 152, 152,
+ 152, 155, 155, 155, 155, 155, 155, 155, 1437, 1437,
+ 53, 410, 155, 358, 359, 360, 361, 1437, 155, 155,
+
+ 155, 155, 155, 155, 44, 251, 717, 44, 53, 44,
+ 437, 720, 44, 437, 1437, 156, 157, 157, 157, 157,
+ 157, 157, 44, 1437, 438, 53, 158, 1437, 1437, 53,
+ 44, 251, 158, 158, 158, 158, 158, 158, 246, 543,
+ 247, 247, 247, 247, 247, 247, 247, 546, 544, 1278,
+ 438, 247, 1437, 1437, 1437, 53, 547, 247, 247, 247,
+ 247, 247, 247, 248, 249, 249, 249, 249, 249, 249,
+ 249, 343, 263, 709, 53, 250, 1437, 251, 1437, 502,
+ 1437, 250, 250, 250, 250, 250, 250, 330, 330, 330,
+ 330, 330, 330, 330, 349, 350, 350, 350, 350, 350,
+
+ 350, 512, 1437, 251, 252, 250, 250, 250, 250, 250,
+ 250, 250, 1437, 1437, 426, 513, 250, 1437, 1437, 53,
+ 725, 1223, 250, 250, 250, 250, 250, 250, 253, 254,
+ 254, 254, 254, 254, 254, 254, 255, 441, 1437, 1437,
+ 256, 513, 1019, 1437, 1437, 443, 256, 256, 256, 256,
+ 256, 256, 53, 256, 256, 256, 256, 256, 256, 256,
+ 259, 260, 260, 260, 260, 260, 260, 261, 53, 1228,
+ 574, 262, 718, 1230, 714, 719, 55, 262, 262, 262,
+ 262, 262, 262, 263, 264, 264, 264, 264, 264, 264,
+ 264, 265, 53, 53, 55, 266, 574, 267, 731, 371,
+
+ 55, 266, 266, 266, 266, 266, 266, 372, 413, 413,
+ 413, 413, 413, 413, 413, 1028, 1236, 512, 55, 575,
+ 373, 55, 715, 267, 327, 327, 327, 327, 327, 327,
+ 327, 1437, 53, 408, 53, 327, 374, 55, 1238, 55,
+ 1039, 327, 327, 327, 327, 327, 327, 328, 329, 329,
+ 329, 329, 329, 329, 713, 55, 799, 1437, 330, 408,
+ 804, 786, 1437, 53, 330, 330, 330, 330, 330, 330,
+ 248, 331, 331, 331, 331, 331, 331, 331, 332, 332,
+ 332, 332, 332, 332, 332, 507, 516, 786, 1437, 332,
+ 1244, 55, 55, 660, 663, 332, 332, 332, 332, 332,
+
+ 332, 334, 335, 335, 335, 335, 335, 335, 335, 55,
+ 55, 808, 1246, 336, 1051, 1252, 798, 1254, 1063, 336,
+ 336, 336, 336, 336, 336, 339, 336, 336, 336, 336,
+ 336, 336, 336, 343, 344, 344, 344, 344, 344, 344,
+ 344, 345, 620, 396, 614, 346, 1185, 347, 397, 1286,
+ 622, 346, 346, 346, 346, 346, 346, 398, 615, 399,
+ 400, 1437, 401, 428, 429, 429, 429, 429, 429, 429,
+ 55, 614, 55, 347, 263, 351, 351, 351, 351, 351,
+ 351, 351, 265, 1113, 615, 1437, 352, 1437, 55, 1333,
+ 55, 616, 352, 352, 352, 352, 352, 352, 353, 354,
+
+ 354, 354, 354, 354, 354, 617, 1335, 800, 1358, 355,
+ 1362, 1437, 55, 1366, 55, 355, 355, 355, 355, 355,
+ 355, 403, 616, 404, 404, 404, 404, 404, 404, 404,
+ 55, 617, 55, 805, 404, 806, 1437, 55, 55, 726,
+ 404, 404, 404, 404, 404, 404, 405, 406, 406, 406,
+ 406, 406, 406, 406, 1370, 55, 55, 55, 407, 809,
+ 408, 1374, 1437, 1390, 407, 407, 407, 407, 407, 407,
+ 491, 491, 491, 491, 491, 491, 491, 521, 522, 522,
+ 522, 522, 522, 522, 673, 724, 408, 409, 407, 407,
+ 407, 407, 407, 407, 407, 53, 1412, 1437, 674, 407,
+
+ 1437, 55, 728, 1213, 673, 407, 407, 407, 407, 407,
+ 407, 411, 412, 412, 412, 412, 412, 412, 1437, 55,
+ 426, 1437, 413, 1437, 674, 1437, 1437, 55, 413, 413,
+ 413, 413, 413, 413, 253, 414, 414, 414, 414, 414,
+ 414, 414, 1210, 426, 1437, 55, 415, 1437, 1437, 857,
+ 1437, 1437, 415, 415, 415, 415, 415, 415, 53, 415,
+ 415, 415, 415, 415, 415, 415, 418, 419, 419, 419,
+ 419, 419, 419, 1207, 1437, 857, 1437, 420, 426, 55,
+ 55, 55, 1204, 420, 420, 420, 420, 420, 420, 424,
+ 425, 425, 425, 425, 425, 425, 426, 55, 55, 55,
+
+ 427, 426, 885, 886, 887, 55, 427, 427, 427, 427,
+ 427, 427, 343, 430, 430, 430, 430, 430, 430, 430,
+ 345, 668, 53, 55, 431, 1201, 55, 55, 889, 821,
+ 431, 431, 431, 431, 431, 431, 432, 433, 433, 433,
+ 433, 433, 433, 426, 55, 55, 426, 434, 53, 891,
+ 892, 55, 55, 434, 434, 434, 434, 434, 434, 263,
+ 439, 439, 439, 439, 439, 439, 439, 265, 677, 55,
+ 55, 440, 894, 973, 1113, 55, 824, 440, 440, 440,
+ 440, 440, 440, 441, 442, 442, 442, 442, 442, 442,
+ 442, 443, 688, 55, 426, 444, 1437, 445, 994, 973,
+
+ 827, 444, 444, 444, 444, 444, 444, 525, 526, 526,
+ 526, 526, 526, 526, 594, 595, 595, 595, 595, 595,
+ 595, 426, 1437, 445, 454, 1278, 1437, 1213, 455, 1437,
+ 55, 456, 55, 682, 457, 682, 458, 459, 460, 461,
+ 488, 488, 488, 488, 488, 488, 488, 683, 55, 1437,
+ 55, 488, 1437, 990, 55, 1437, 721, 488, 488, 488,
+ 488, 488, 488, 489, 490, 490, 490, 490, 490, 490,
+ 53, 793, 55, 683, 491, 1437, 1437, 1437, 1437, 795,
+ 491, 491, 491, 491, 491, 491, 405, 492, 492, 492,
+ 492, 492, 492, 492, 493, 493, 493, 493, 493, 493,
+
+ 493, 1210, 1437, 1437, 1437, 493, 1437, 55, 55, 55,
+ 55, 493, 493, 493, 493, 493, 493, 410, 495, 495,
+ 495, 495, 495, 495, 495, 55, 55, 55, 55, 496,
+ 1207, 251, 1437, 996, 1204, 496, 496, 496, 496, 496,
+ 496, 602, 603, 603, 603, 603, 603, 603, 606, 607,
+ 607, 607, 607, 607, 607, 55, 684, 251, 496, 496,
+ 496, 496, 496, 496, 496, 1437, 1201, 1044, 1437, 496,
+ 685, 1056, 1278, 55, 723, 496, 496, 496, 496, 496,
+ 496, 497, 497, 497, 497, 497, 497, 497, 53, 1185,
+ 801, 1437, 498, 1044, 1437, 1437, 685, 1056, 498, 498,
+
+ 498, 498, 498, 498, 53, 498, 498, 498, 498, 498,
+ 498, 498, 343, 501, 501, 501, 501, 501, 501, 501,
+ 502, 1437, 684, 982, 503, 1063, 347, 426, 1213, 864,
+ 503, 503, 503, 503, 503, 503, 1437, 693, 694, 694,
+ 694, 694, 694, 694, 696, 697, 697, 697, 697, 697,
+ 697, 55, 347, 507, 508, 508, 508, 508, 508, 508,
+ 508, 509, 1437, 1059, 1057, 510, 1051, 511, 426, 55,
+ 1210, 510, 510, 510, 510, 510, 510, 700, 701, 701,
+ 701, 701, 701, 701, 751, 752, 752, 752, 752, 752,
+ 752, 787, 55, 511, 343, 514, 514, 514, 514, 514,
+
+ 514, 514, 502, 852, 1047, 788, 515, 1045, 1437, 1176,
+ 55, 55, 515, 515, 515, 515, 515, 515, 516, 517,
+ 517, 517, 517, 517, 517, 517, 518, 803, 1039, 55,
+ 519, 788, 520, 1089, 1437, 1176, 519, 519, 519, 519,
+ 519, 519, 759, 760, 760, 760, 760, 760, 760, 763,
+ 764, 764, 764, 764, 764, 764, 787, 55, 520, 441,
+ 527, 527, 527, 527, 527, 527, 527, 443, 426, 1207,
+ 1437, 528, 1437, 55, 841, 55, 789, 528, 528, 528,
+ 528, 528, 528, 529, 530, 530, 530, 530, 530, 530,
+ 790, 55, 890, 1035, 531, 1092, 1437, 55, 1437, 55,
+
+ 531, 531, 531, 531, 531, 531, 569, 789, 570, 570,
+ 570, 570, 570, 570, 570, 55, 790, 55, 1033, 570,
+ 1093, 1437, 1028, 426, 55, 570, 570, 570, 570, 570,
+ 570, 571, 572, 572, 572, 572, 572, 572, 572, 1204,
+ 832, 1188, 55, 573, 1191, 574, 832, 1437, 1003, 573,
+ 573, 573, 573, 573, 573, 771, 772, 772, 772, 772,
+ 772, 772, 774, 775, 775, 775, 775, 775, 775, 837,
+ 55, 574, 571, 573, 573, 573, 573, 573, 573, 573,
+ 1437, 841, 1024, 838, 573, 1437, 1019, 426, 55, 1006,
+ 573, 573, 573, 573, 573, 573, 410, 576, 576, 576,
+
+ 576, 576, 576, 576, 852, 864, 1437, 895, 577, 838,
+ 1437, 1437, 1009, 1012, 577, 577, 577, 577, 577, 577,
+ 53, 577, 577, 577, 577, 577, 577, 577, 578, 578,
+ 578, 578, 578, 578, 578, 1201, 1437, 426, 1115, 579,
+ 1437, 1437, 1235, 1243, 1220, 579, 579, 579, 579, 579,
+ 579, 53, 579, 579, 579, 579, 579, 579, 579, 582,
+ 583, 583, 583, 583, 583, 583, 1437, 1437, 1235, 1243,
+ 584, 1251, 1437, 55, 55, 55, 584, 584, 584, 584,
+ 584, 584, 343, 430, 430, 430, 430, 430, 430, 430,
+ 502, 55, 55, 55, 431, 1332, 55, 1251, 1437, 837,
+
+ 431, 431, 431, 431, 431, 431, 585, 586, 586, 586,
+ 586, 586, 586, 1437, 55, 1189, 1190, 587, 1096, 1194,
+ 55, 1332, 1213, 587, 587, 587, 587, 587, 587, 591,
+ 592, 592, 592, 592, 592, 592, 426, 1210, 55, 1437,
+ 593, 1207, 1204, 1201, 55, 55, 593, 593, 593, 593,
+ 593, 593, 507, 596, 596, 596, 596, 596, 596, 596,
+ 509, 980, 55, 55, 597, 1096, 980, 55, 55, 982,
+ 597, 597, 597, 597, 597, 597, 598, 599, 599, 599,
+ 599, 599, 599, 426, 1192, 55, 55, 600, 1185, 982,
+ 55, 55, 55, 600, 600, 600, 600, 600, 600, 516,
+
+ 608, 608, 608, 608, 608, 608, 608, 518, 55, 55,
+ 55, 609, 793, 1341, 1273, 55, 976, 609, 609, 609,
+ 609, 609, 609, 610, 611, 611, 611, 611, 611, 611,
+ 426, 1019, 974, 55, 612, 1361, 1342, 1065, 55, 1201,
+ 612, 612, 612, 612, 612, 612, 441, 618, 618, 618,
+ 618, 618, 618, 618, 443, 1028, 55, 1365, 619, 1369,
+ 1373, 1361, 426, 1204, 619, 619, 619, 619, 619, 619,
+ 620, 621, 621, 621, 621, 621, 621, 621, 622, 1039,
+ 1343, 1012, 623, 1365, 624, 1369, 1373, 1207, 623, 623,
+ 623, 623, 623, 623, 778, 779, 779, 779, 779, 779,
+
+ 779, 694, 694, 694, 694, 694, 694, 694, 55, 846,
+ 624, 648, 648, 648, 648, 648, 648, 648, 1411, 1051,
+ 1419, 1420, 648, 847, 1053, 55, 55, 1210, 648, 648,
+ 648, 648, 648, 648, 649, 649, 649, 649, 649, 649,
+ 649, 888, 1063, 55, 1411, 649, 1419, 1420, 1421, 847,
+ 1213, 649, 649, 649, 649, 649, 649, 571, 650, 650,
+ 650, 650, 650, 650, 650, 651, 651, 651, 651, 651,
+ 651, 651, 1113, 1183, 1421, 1422, 651, 1423, 55, 55,
+ 1278, 1185, 651, 651, 651, 651, 651, 651, 410, 653,
+ 653, 653, 653, 653, 653, 653, 55, 55, 426, 1009,
+
+ 654, 1422, 1428, 1423, 1434, 1274, 654, 654, 654, 654,
+ 654, 654, 53, 654, 654, 654, 654, 654, 654, 654,
+ 655, 655, 655, 655, 655, 655, 655, 1183, 1428, 1041,
+ 1434, 656, 426, 1006, 1030, 1437, 426, 656, 656, 656,
+ 656, 656, 656, 53, 656, 656, 656, 656, 656, 656,
+ 656, 507, 659, 659, 659, 659, 659, 659, 659, 660,
+ 55, 846, 848, 661, 1003, 511, 55, 1021, 848, 661,
+ 661, 661, 661, 661, 661, 1437, 849, 426, 55, 1115,
+ 426, 1096, 1437, 1012, 55, 55, 1009, 55, 1006, 55,
+ 802, 511, 516, 662, 662, 662, 662, 662, 662, 662,
+
+ 663, 1437, 849, 55, 664, 55, 520, 55, 1437, 55,
+ 664, 664, 664, 664, 664, 664, 810, 807, 1003, 319,
+ 815, 815, 815, 815, 815, 815, 815, 55, 858, 858,
+ 860, 55, 520, 668, 669, 669, 669, 669, 669, 669,
+ 669, 670, 859, 1437, 861, 671, 1088, 672, 1096, 55,
+ 860, 671, 671, 671, 671, 671, 671, 772, 772, 772,
+ 772, 772, 772, 772, 1437, 55, 989, 982, 859, 1437,
+ 861, 974, 795, 672, 507, 675, 675, 675, 675, 675,
+ 675, 675, 660, 55, 864, 975, 676, 1065, 1012, 55,
+ 1437, 1388, 676, 676, 676, 676, 676, 676, 677, 678,
+
+ 678, 678, 678, 678, 678, 678, 679, 55, 688, 860,
+ 680, 975, 681, 858, 852, 1053, 680, 680, 680, 680,
+ 680, 680, 870, 871, 871, 871, 871, 871, 871, 873,
+ 874, 874, 874, 874, 874, 874, 974, 55, 681, 516,
+ 686, 686, 686, 686, 686, 686, 686, 663, 1009, 677,
+ 1437, 687, 848, 846, 841, 55, 991, 687, 687, 687,
+ 687, 687, 687, 688, 689, 689, 689, 689, 689, 689,
+ 689, 690, 1041, 992, 1006, 691, 1437, 692, 668, 55,
+ 55, 691, 691, 691, 691, 691, 691, 877, 878, 878,
+ 878, 878, 878, 878, 837, 832, 1030, 55, 55, 1003,
+
+ 976, 976, 55, 692, 620, 702, 702, 702, 702, 702,
+ 702, 702, 622, 893, 977, 1437, 703, 1091, 1021, 918,
+ 55, 903, 703, 703, 703, 703, 703, 703, 704, 705,
+ 705, 705, 705, 705, 705, 985, 1012, 1009, 1006, 706,
+ 977, 1437, 1003, 1001, 903, 706, 706, 706, 706, 706,
+ 706, 53, 53, 53, 53, 53, 53, 53, 793, 982,
+ 795, 620, 53, 55, 55, 55, 55, 55, 53, 53,
+ 53, 53, 53, 53, 922, 923, 923, 923, 923, 923,
+ 923, 55, 55, 55, 55, 55, 708, 726, 789, 727,
+ 727, 727, 727, 727, 727, 727, 986, 987, 988, 993,
+
+ 727, 995, 1340, 55, 55, 55, 727, 727, 727, 727,
+ 727, 727, 930, 931, 931, 931, 931, 931, 931, 1024,
+ 1024, 55, 55, 55, 53, 728, 729, 729, 729, 729,
+ 729, 729, 729, 1025, 1437, 1087, 1090, 729, 1195, 787,
+ 866, 827, 854, 729, 729, 729, 729, 729, 729, 934,
+ 935, 935, 935, 935, 935, 935, 824, 843, 821, 1025,
+ 1437, 53, 650, 650, 650, 650, 650, 650, 650, 942,
+ 943, 943, 943, 943, 943, 943, 945, 946, 946, 946,
+ 946, 946, 946, 949, 950, 950, 950, 950, 950, 950,
+ 958, 959, 959, 959, 959, 959, 959, 53, 651, 651,
+
+ 651, 651, 651, 651, 651, 834, 918, 903, 827, 651,
+ 824, 821, 903, 795, 622, 651, 651, 651, 651, 651,
+ 651, 730, 331, 331, 331, 331, 331, 331, 331, 253,
+ 732, 732, 732, 732, 732, 732, 732, 688, 866, 827,
+ 516, 733, 684, 682, 677, 854, 824, 733, 733, 733,
+ 733, 733, 733, 53, 733, 733, 733, 733, 733, 733,
+ 733, 736, 737, 737, 737, 737, 737, 737, 507, 673,
+ 668, 843, 738, 821, 834, 831, 747, 735, 738, 738,
+ 738, 738, 738, 738, 507, 596, 596, 596, 596, 596,
+ 596, 596, 660, 827, 824, 821, 597, 819, 735, 620,
+
+ 795, 1033, 597, 597, 597, 597, 597, 597, 739, 740,
+ 740, 740, 740, 740, 740, 1034, 622, 441, 616, 741,
+ 614, 690, 663, 679, 660, 741, 741, 741, 741, 741,
+ 741, 516, 608, 608, 608, 608, 608, 608, 608, 663,
+ 670, 1034, 747, 609, 735, 663, 660, 735, 1033, 609,
+ 609, 609, 609, 609, 609, 742, 743, 743, 743, 743,
+ 743, 743, 1437, 53, 53, 53, 744, 722, 53, 53,
+ 716, 622, 744, 744, 744, 744, 744, 744, 748, 749,
+ 749, 749, 749, 749, 749, 426, 443, 516, 1437, 750,
+ 690, 663, 343, 512, 507, 750, 750, 750, 750, 750,
+
+ 750, 668, 753, 753, 753, 753, 753, 753, 753, 670,
+ 679, 660, 670, 754, 667, 590, 581, 663, 660, 754,
+ 754, 754, 754, 754, 754, 755, 756, 756, 756, 756,
+ 756, 756, 426, 658, 581, 571, 757, 569, 647, 646,
+ 645, 644, 757, 757, 757, 757, 757, 757, 677, 765,
+ 765, 765, 765, 765, 765, 765, 679, 643, 642, 641,
+ 766, 640, 639, 638, 637, 636, 766, 766, 766, 766,
+ 766, 766, 767, 768, 768, 768, 768, 768, 768, 426,
+ 635, 634, 633, 769, 632, 631, 630, 629, 628, 769,
+ 769, 769, 769, 769, 769, 688, 780, 780, 780, 780,
+
+ 780, 780, 780, 690, 627, 626, 625, 781, 441, 622,
+ 443, 437, 518, 781, 781, 781, 781, 781, 781, 782,
+ 783, 783, 783, 783, 783, 783, 426, 502, 509, 590,
+ 784, 581, 502, 581, 575, 575, 784, 784, 784, 784,
+ 784, 784, 620, 791, 791, 791, 791, 791, 791, 791,
+ 622, 568, 567, 566, 792, 565, 564, 563, 562, 561,
+ 792, 792, 792, 792, 792, 792, 793, 794, 794, 794,
+ 794, 794, 794, 794, 795, 560, 316, 225, 796, 559,
+ 797, 558, 557, 556, 796, 796, 796, 796, 796, 796,
+ 961, 962, 962, 962, 962, 962, 962, 965, 966, 966,
+
+ 966, 966, 966, 966, 1035, 1035, 797, 55, 1045, 811,
+ 811, 811, 811, 811, 811, 811, 555, 554, 1036, 1437,
+ 811, 553, 1046, 552, 551, 55, 811, 811, 811, 811,
+ 811, 811, 812, 812, 812, 812, 812, 812, 812, 550,
+ 549, 548, 545, 812, 1036, 1437, 542, 541, 1046, 812,
+ 812, 812, 812, 812, 812, 813, 814, 814, 814, 814,
+ 814, 814, 540, 539, 538, 537, 815, 536, 55, 535,
+ 534, 533, 815, 815, 815, 815, 815, 815, 253, 816,
+ 816, 816, 816, 816, 816, 816, 55, 443, 265, 426,
+ 817, 343, 518, 502, 509, 1387, 817, 817, 817, 817,
+
+ 817, 817, 53, 817, 817, 817, 817, 817, 817, 817,
+ 668, 820, 820, 820, 820, 820, 820, 820, 821, 426,
+ 506, 423, 822, 417, 672, 502, 500, 417, 822, 822,
+ 822, 822, 822, 822, 871, 871, 871, 871, 871, 871,
+ 871, 943, 943, 943, 943, 943, 943, 943, 1045, 409,
+ 672, 677, 823, 823, 823, 823, 823, 823, 823, 824,
+ 403, 1047, 1437, 825, 487, 681, 486, 1047, 1057, 825,
+ 825, 825, 825, 825, 825, 1048, 485, 484, 483, 482,
+ 481, 1437, 1058, 480, 479, 478, 477, 55, 1437, 1057,
+ 476, 681, 688, 826, 826, 826, 826, 826, 826, 826,
+
+ 827, 1048, 475, 1437, 828, 55, 692, 1437, 1058, 1059,
+ 828, 828, 828, 828, 828, 828, 959, 959, 959, 959,
+ 959, 959, 959, 1060, 1386, 472, 471, 468, 1059, 1437,
+ 1177, 467, 692, 832, 833, 833, 833, 833, 833, 833,
+ 833, 834, 1437, 466, 1178, 835, 465, 836, 464, 1060,
+ 1177, 835, 835, 835, 835, 835, 835, 1069, 1070, 1070,
+ 1070, 1070, 1070, 1070, 1437, 114, 463, 462, 1437, 1179,
+ 1178, 1179, 453, 836, 668, 839, 839, 839, 839, 839,
+ 839, 839, 821, 1180, 452, 1437, 840, 451, 450, 449,
+ 1437, 448, 840, 840, 840, 840, 840, 840, 841, 842,
+
+ 842, 842, 842, 842, 842, 842, 843, 447, 446, 1180,
+ 844, 1437, 845, 263, 443, 265, 844, 844, 844, 844,
+ 844, 844, 1072, 1073, 1073, 1073, 1073, 1073, 1073, 1076,
+ 1077, 1077, 1077, 1077, 1077, 1077, 1223, 426, 845, 677,
+ 850, 850, 850, 850, 850, 850, 850, 824, 345, 423,
+ 1224, 851, 417, 417, 410, 410, 402, 851, 851, 851,
+ 851, 851, 851, 852, 853, 853, 853, 853, 853, 853,
+ 853, 854, 55, 55, 1223, 855, 1224, 856, 395, 394,
+ 391, 855, 855, 855, 855, 855, 855, 390, 1437, 389,
+ 55, 55, 1119, 1120, 1120, 1120, 1120, 1120, 1120, 1228,
+
+ 388, 1084, 1085, 856, 688, 862, 862, 862, 862, 862,
+ 862, 862, 827, 1229, 1437, 387, 863, 386, 385, 384,
+ 383, 382, 863, 863, 863, 863, 863, 863, 864, 865,
+ 865, 865, 865, 865, 865, 865, 866, 55, 1228, 1229,
+ 867, 381, 868, 380, 379, 55, 867, 867, 867, 867,
+ 867, 867, 1437, 378, 377, 55, 1125, 1126, 1126, 1126,
+ 1126, 1126, 1126, 55, 376, 1230, 1086, 375, 868, 793,
+ 879, 879, 879, 879, 879, 879, 879, 795, 1437, 1231,
+ 370, 880, 1415, 369, 298, 368, 1230, 880, 880, 880,
+ 880, 880, 880, 881, 882, 882, 882, 882, 882, 882,
+
+ 1437, 367, 366, 365, 883, 1231, 364, 363, 357, 265,
+ 883, 883, 883, 883, 883, 883, 55, 1236, 896, 896,
+ 896, 896, 896, 896, 896, 345, 1437, 261, 342, 896,
+ 258, 1237, 338, 252, 55, 896, 896, 896, 896, 896,
+ 896, 897, 897, 897, 897, 897, 897, 897, 246, 137,
+ 326, 325, 897, 324, 319, 298, 318, 1237, 897, 897,
+ 897, 897, 897, 897, 575, 898, 898, 898, 898, 898,
+ 898, 898, 317, 316, 315, 314, 899, 313, 408, 312,
+ 311, 310, 899, 899, 899, 899, 899, 899, 1129, 1130,
+ 1130, 1130, 1130, 1130, 1130, 1135, 1136, 1136, 1136, 1136,
+
+ 1136, 1136, 309, 1236, 408, 899, 899, 899, 899, 899,
+ 899, 899, 308, 307, 306, 305, 899, 1437, 304, 301,
+ 300, 299, 899, 899, 899, 899, 899, 899, 253, 900,
+ 900, 900, 900, 900, 900, 900, 298, 297, 296, 295,
+ 901, 294, 293, 1437, 292, 291, 901, 901, 901, 901,
+ 901, 901, 53, 901, 901, 901, 901, 901, 901, 901,
+ 904, 905, 905, 905, 905, 905, 905, 290, 289, 288,
+ 287, 906, 286, 285, 284, 283, 137, 906, 906, 906,
+ 906, 906, 906, 668, 753, 753, 753, 753, 753, 753,
+ 753, 821, 282, 281, 280, 754, 279, 278, 277, 276,
+
+ 1238, 754, 754, 754, 754, 754, 754, 907, 908, 908,
+ 908, 908, 908, 908, 1239, 275, 274, 273, 909, 272,
+ 271, 270, 269, 268, 909, 909, 909, 909, 909, 909,
+ 677, 765, 765, 765, 765, 765, 765, 765, 824, 265,
+ 1239, 253, 766, 258, 245, 244, 243, 1238, 766, 766,
+ 766, 766, 766, 766, 910, 911, 911, 911, 911, 911,
+ 911, 1437, 242, 241, 240, 912, 239, 238, 237, 236,
+ 233, 912, 912, 912, 912, 912, 912, 688, 780, 780,
+ 780, 780, 780, 780, 780, 827, 230, 1437, 227, 781,
+ 226, 225, 224, 221, 1244, 781, 781, 781, 781, 781,
+
+ 781, 913, 914, 914, 914, 914, 914, 914, 1245, 220,
+ 219, 218, 915, 217, 216, 215, 214, 213, 915, 915,
+ 915, 915, 915, 915, 919, 920, 920, 920, 920, 920,
+ 920, 426, 212, 211, 1245, 921, 210, 209, 208, 207,
+ 206, 921, 921, 921, 921, 921, 921, 832, 924, 924,
+ 924, 924, 924, 924, 924, 834, 202, 201, 191, 925,
+ 190, 189, 186, 185, 184, 925, 925, 925, 925, 925,
+ 925, 926, 927, 927, 927, 927, 927, 927, 426, 183,
+ 182, 181, 928, 180, 179, 175, 174, 173, 928, 928,
+ 928, 928, 928, 928, 841, 936, 936, 936, 936, 936,
+
+ 936, 936, 843, 172, 171, 170, 937, 169, 168, 167,
+ 166, 165, 937, 937, 937, 937, 937, 937, 938, 939,
+ 939, 939, 939, 939, 939, 426, 164, 163, 162, 940,
+ 161, 160, 159, 154, 145, 940, 940, 940, 940, 940,
+ 940, 852, 951, 951, 951, 951, 951, 951, 951, 854,
+ 144, 139, 89, 952, 59, 47, 45, 1437, 1437, 952,
+ 952, 952, 952, 952, 952, 953, 954, 954, 954, 954,
+ 954, 954, 426, 1437, 1437, 1437, 955, 1437, 1437, 1437,
+ 1437, 1437, 955, 955, 955, 955, 955, 955, 864, 967,
+ 967, 967, 967, 967, 967, 967, 866, 1437, 1437, 1437,
+
+ 968, 1437, 1437, 1437, 1437, 1437, 968, 968, 968, 968,
+ 968, 968, 969, 970, 970, 970, 970, 970, 970, 426,
+ 1437, 1437, 1437, 971, 1437, 1437, 1437, 1437, 1437, 971,
+ 971, 971, 971, 971, 971, 793, 978, 978, 978, 978,
+ 978, 978, 978, 795, 1437, 1437, 1437, 979, 1437, 1437,
+ 1437, 1437, 1437, 979, 979, 979, 979, 979, 979, 980,
+ 981, 981, 981, 981, 981, 981, 981, 982, 1437, 1437,
+ 1437, 983, 1437, 984, 1437, 1437, 1437, 983, 983, 983,
+ 983, 983, 983, 1138, 1139, 1139, 1139, 1139, 1139, 1139,
+ 1142, 1143, 1143, 1143, 1143, 1143, 1143, 1437, 1437, 984,
+
+ 55, 575, 997, 997, 997, 997, 997, 997, 997, 1437,
+ 1437, 1437, 1437, 998, 1437, 1437, 1437, 1437, 55, 998,
+ 998, 998, 998, 998, 998, 53, 998, 998, 998, 998,
+ 998, 998, 998, 55, 253, 999, 999, 999, 999, 999,
+ 999, 999, 1149, 1150, 1150, 1150, 1150, 1150, 1150, 1437,
+ 1437, 55, 832, 1002, 1002, 1002, 1002, 1002, 1002, 1002,
+ 1003, 1437, 1437, 1437, 1004, 1437, 836, 1437, 1437, 1437,
+ 1004, 1004, 1004, 1004, 1004, 1004, 1152, 1153, 1153, 1153,
+ 1153, 1153, 1153, 1156, 1157, 1157, 1157, 1157, 1157, 1157,
+ 1437, 1437, 836, 841, 1005, 1005, 1005, 1005, 1005, 1005,
+
+ 1005, 1006, 1437, 1437, 1437, 1007, 1437, 845, 1437, 1437,
+ 1437, 1007, 1007, 1007, 1007, 1007, 1007, 1163, 1164, 1164,
+ 1164, 1164, 1164, 1164, 1166, 1167, 1167, 1167, 1167, 1167,
+ 1167, 1437, 1437, 845, 852, 1008, 1008, 1008, 1008, 1008,
+ 1008, 1008, 1009, 1437, 1437, 1437, 1010, 1437, 856, 1437,
+ 1437, 1437, 1010, 1010, 1010, 1010, 1010, 1010, 1170, 1171,
+ 1171, 1171, 1171, 1171, 1171, 1070, 1070, 1070, 1070, 1070,
+ 1070, 1070, 55, 1437, 856, 864, 1011, 1011, 1011, 1011,
+ 1011, 1011, 1011, 1012, 1437, 1244, 1246, 1013, 1437, 868,
+ 55, 1437, 1437, 1013, 1013, 1013, 1013, 1013, 1013, 1437,
+
+ 1247, 1193, 1215, 1216, 1216, 1216, 1216, 1216, 1216, 1437,
+ 1246, 1437, 1437, 1437, 1252, 868, 1015, 1016, 1016, 1016,
+ 1016, 1016, 1016, 1017, 1437, 1437, 1247, 1018, 1253, 1437,
+ 1437, 1437, 1437, 1018, 1018, 1018, 1018, 1018, 1018, 1019,
+ 1020, 1020, 1020, 1020, 1020, 1020, 1020, 1021, 1437, 1437,
+ 1437, 1022, 1437, 1023, 1253, 1437, 1437, 1022, 1022, 1022,
+ 1022, 1022, 1022, 1136, 1136, 1136, 1136, 1136, 1136, 1136,
+ 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1252, 1437, 1023,
+ 832, 1026, 1026, 1026, 1026, 1026, 1026, 1026, 1003, 1437,
+ 1437, 1437, 1027, 1437, 1437, 1437, 1437, 1437, 1027, 1027,
+
+ 1027, 1027, 1027, 1027, 1028, 1029, 1029, 1029, 1029, 1029,
+ 1029, 1029, 1030, 1437, 1437, 1437, 1031, 1437, 1032, 1437,
+ 1437, 1254, 1031, 1031, 1031, 1031, 1031, 1031, 1164, 1164,
+ 1164, 1164, 1164, 1164, 1164, 1255, 1437, 1437, 1437, 1437,
+ 1254, 1437, 1286, 1437, 1032, 841, 1037, 1037, 1037, 1037,
+ 1037, 1037, 1037, 1006, 1437, 1437, 1287, 1038, 1437, 1437,
+ 1437, 1255, 1437, 1038, 1038, 1038, 1038, 1038, 1038, 1039,
+ 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1041, 1437, 1437,
+ 1437, 1042, 1287, 1043, 1437, 1437, 1437, 1042, 1042, 1042,
+ 1042, 1042, 1042, 1260, 1261, 1261, 1261, 1261, 1261, 1261,
+
+ 1263, 1264, 1264, 1264, 1264, 1264, 1264, 1286, 1437, 1043,
+ 852, 1049, 1049, 1049, 1049, 1049, 1049, 1049, 1009, 1437,
+ 1437, 1437, 1050, 1437, 1437, 1437, 1437, 1437, 1050, 1050,
+ 1050, 1050, 1050, 1050, 1051, 1052, 1052, 1052, 1052, 1052,
+ 1052, 1052, 1053, 1437, 1437, 1437, 1054, 1437, 1055, 1437,
+ 1437, 1437, 1054, 1054, 1054, 1054, 1054, 1054, 1267, 1268,
+ 1268, 1268, 1268, 1268, 1268, 1292, 1293, 1293, 1293, 1293,
+ 1293, 1293, 1333, 1437, 1055, 864, 1061, 1061, 1061, 1061,
+ 1061, 1061, 1061, 1012, 1437, 1437, 1334, 1062, 1437, 1437,
+ 1437, 1437, 55, 1062, 1062, 1062, 1062, 1062, 1062, 1063,
+
+ 1064, 1064, 1064, 1064, 1064, 1064, 1064, 1065, 55, 1437,
+ 55, 1066, 1334, 1067, 1437, 1437, 1437, 1066, 1066, 1066,
+ 1066, 1066, 1066, 1275, 1437, 1437, 55, 1297, 1298, 1298,
+ 1298, 1298, 1298, 1298, 1437, 1437, 1333, 1276, 1437, 1067,
+ 980, 1078, 1078, 1078, 1078, 1078, 1078, 1078, 982, 1437,
+ 1437, 1437, 1079, 1437, 1437, 1437, 1437, 1335, 1079, 1079,
+ 1079, 1079, 1079, 1079, 1080, 1081, 1081, 1081, 1081, 1081,
+ 1081, 1336, 1437, 1437, 1437, 1082, 1437, 1437, 1437, 1437,
+ 1437, 1082, 1082, 1082, 1082, 1082, 1082, 55, 575, 1094,
+ 1094, 1094, 1094, 1094, 1094, 1094, 1437, 1336, 1437, 1437,
+
+ 901, 1437, 1437, 1437, 1437, 55, 901, 901, 901, 901,
+ 901, 901, 53, 901, 901, 901, 901, 901, 901, 901,
+ 55, 253, 999, 999, 999, 999, 999, 999, 999, 1300,
+ 1301, 1301, 1301, 1301, 1301, 1301, 1437, 1335, 55, 1097,
+ 1098, 1098, 1098, 1098, 1098, 1098, 1437, 1437, 1437, 1437,
+ 1099, 1437, 1437, 1437, 1437, 1437, 1099, 1099, 1099, 1099,
+ 1099, 1099, 832, 924, 924, 924, 924, 924, 924, 924,
+ 1003, 1437, 1437, 1437, 925, 1437, 1437, 1437, 1437, 1358,
+ 925, 925, 925, 925, 925, 925, 1100, 1101, 1101, 1101,
+ 1101, 1101, 1101, 1359, 1437, 1437, 1437, 1102, 1437, 1437,
+
+ 1437, 1437, 1437, 1102, 1102, 1102, 1102, 1102, 1102, 841,
+ 936, 936, 936, 936, 936, 936, 936, 1006, 1437, 1359,
+ 1437, 937, 1437, 1437, 1437, 1437, 1358, 937, 937, 937,
+ 937, 937, 937, 1103, 1104, 1104, 1104, 1104, 1104, 1104,
+ 1437, 1437, 1437, 1437, 1105, 1437, 1437, 1437, 1437, 1437,
+ 1105, 1105, 1105, 1105, 1105, 1105, 852, 951, 951, 951,
+ 951, 951, 951, 951, 1009, 1437, 1437, 1437, 952, 1437,
+ 1437, 1437, 1437, 1362, 952, 952, 952, 952, 952, 952,
+ 1106, 1107, 1107, 1107, 1107, 1107, 1107, 1363, 1437, 1437,
+ 1437, 1108, 1437, 1437, 1437, 1437, 1437, 1108, 1108, 1108,
+
+ 1108, 1108, 1108, 864, 967, 967, 967, 967, 967, 967,
+ 967, 1012, 1437, 1363, 1437, 968, 1437, 1437, 1437, 1437,
+ 1362, 968, 968, 968, 968, 968, 968, 1109, 1110, 1110,
+ 1110, 1110, 1110, 1110, 1437, 1437, 1437, 1437, 1111, 1437,
+ 1437, 1437, 1437, 1437, 1111, 1111, 1111, 1111, 1111, 1111,
+ 1113, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1115, 1437,
+ 1437, 1437, 1116, 1437, 1117, 1437, 1437, 1437, 1116, 1116,
+ 1116, 1116, 1116, 1116, 1306, 1307, 1307, 1307, 1307, 1307,
+ 1307, 1309, 1310, 1310, 1310, 1310, 1310, 1310, 1366, 1437,
+ 1117, 1019, 1121, 1121, 1121, 1121, 1121, 1121, 1121, 1021,
+
+ 1437, 1437, 1367, 1122, 1437, 1437, 1437, 1437, 1437, 1122,
+ 1122, 1122, 1122, 1122, 1122, 1028, 1131, 1131, 1131, 1131,
+ 1131, 1131, 1131, 1030, 1437, 1437, 1437, 1132, 1367, 1437,
+ 1437, 1437, 1437, 1132, 1132, 1132, 1132, 1132, 1132, 1039,
+ 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1041, 1437, 1437,
+ 1437, 1145, 1437, 1437, 1437, 1437, 1437, 1145, 1145, 1145,
+ 1145, 1145, 1145, 1051, 1158, 1158, 1158, 1158, 1158, 1158,
+ 1158, 1053, 1437, 1437, 1437, 1159, 1437, 1437, 1437, 1437,
+ 1437, 1159, 1159, 1159, 1159, 1159, 1159, 1063, 1172, 1172,
+ 1172, 1172, 1172, 1172, 1172, 1065, 1437, 1437, 1437, 1173,
+
+ 1437, 1437, 1437, 1437, 1437, 1173, 1173, 1173, 1173, 1173,
+ 1173, 980, 1181, 1181, 1181, 1181, 1181, 1181, 1181, 982,
+ 1437, 1437, 1437, 1182, 1437, 1437, 1437, 1437, 1437, 1182,
+ 1182, 1182, 1182, 1182, 1182, 1183, 1184, 1184, 1184, 1184,
+ 1184, 1184, 1184, 1185, 1437, 1437, 1437, 1186, 1437, 1187,
+ 1437, 1437, 1437, 1186, 1186, 1186, 1186, 1186, 1186, 1315,
+ 1316, 1316, 1316, 1316, 1316, 1316, 1318, 1319, 1319, 1319,
+ 1319, 1319, 1319, 1437, 1437, 1187, 55, 575, 492, 492,
+ 492, 492, 492, 492, 492, 1324, 1325, 1325, 1325, 1325,
+ 1325, 1325, 1437, 1366, 55, 1196, 1197, 1197, 1197, 1197,
+
+ 1197, 1197, 1198, 1437, 1437, 1437, 1199, 1437, 1437, 1437,
+ 1437, 1437, 1199, 1199, 1199, 1199, 1199, 1199, 1019, 1200,
+ 1200, 1200, 1200, 1200, 1200, 1200, 1201, 1437, 1437, 1437,
+ 1202, 1437, 1023, 1437, 1437, 1437, 1202, 1202, 1202, 1202,
+ 1202, 1202, 1327, 1328, 1328, 1328, 1328, 1328, 1328, 1261,
+ 1261, 1261, 1261, 1261, 1261, 1261, 1437, 1437, 1023, 1028,
+ 1203, 1203, 1203, 1203, 1203, 1203, 1203, 1204, 1437, 1437,
+ 1437, 1205, 1437, 1032, 1437, 1437, 1437, 1205, 1205, 1205,
+ 1205, 1205, 1205, 1352, 1353, 1353, 1353, 1353, 1353, 1353,
+ 1298, 1298, 1298, 1298, 1298, 1298, 1298, 1437, 1437, 1032,
+
+ 1039, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1207, 1437,
+ 1437, 1437, 1208, 1437, 1043, 1437, 1437, 1437, 1208, 1208,
+ 1208, 1208, 1208, 1208, 1307, 1307, 1307, 1307, 1307, 1307,
+ 1307, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1370, 1437,
+ 1043, 1051, 1209, 1209, 1209, 1209, 1209, 1209, 1209, 1210,
+ 1437, 1370, 1371, 1211, 1437, 1055, 1437, 1437, 1437, 1211,
+ 1211, 1211, 1211, 1211, 1211, 1437, 1325, 1325, 1325, 1325,
+ 1325, 1325, 1325, 1437, 1437, 1437, 1437, 1437, 1371, 1374,
+ 1437, 1055, 1063, 1212, 1212, 1212, 1212, 1212, 1212, 1212,
+ 1213, 1437, 1374, 1375, 1214, 1437, 1067, 1437, 1437, 1437,
+
+ 1214, 1214, 1214, 1214, 1214, 1214, 1437, 1378, 1379, 1379,
+ 1379, 1379, 1379, 1379, 1437, 1437, 1437, 1437, 1437, 1375,
+ 1390, 1437, 1067, 1113, 1217, 1217, 1217, 1217, 1217, 1217,
+ 1217, 1115, 1437, 1437, 1391, 1218, 1437, 1437, 1437, 1437,
+ 1437, 1218, 1218, 1218, 1218, 1218, 1218, 1019, 1225, 1225,
+ 1225, 1225, 1225, 1225, 1225, 1201, 1437, 1437, 1437, 1226,
+ 1391, 1437, 1437, 1437, 1437, 1226, 1226, 1226, 1226, 1226,
+ 1226, 1028, 1232, 1232, 1232, 1232, 1232, 1232, 1232, 1204,
+ 1437, 1437, 1437, 1233, 1437, 1437, 1437, 1437, 1437, 1233,
+ 1233, 1233, 1233, 1233, 1233, 1039, 1240, 1240, 1240, 1240,
+
+ 1240, 1240, 1240, 1207, 1437, 1437, 1437, 1241, 1437, 1437,
+ 1437, 1437, 1437, 1241, 1241, 1241, 1241, 1241, 1241, 1051,
+ 1248, 1248, 1248, 1248, 1248, 1248, 1248, 1210, 1437, 1437,
+ 1437, 1249, 1437, 1437, 1437, 1437, 1437, 1249, 1249, 1249,
+ 1249, 1249, 1249, 1063, 1256, 1256, 1256, 1256, 1256, 1256,
+ 1256, 1213, 1437, 1437, 1437, 1257, 1437, 1437, 1437, 1437,
+ 1437, 1257, 1257, 1257, 1257, 1257, 1257, 1183, 1269, 1269,
+ 1269, 1269, 1269, 1269, 1269, 1185, 1437, 1437, 1437, 1270,
+ 1437, 1437, 1437, 1437, 1437, 1270, 1270, 1270, 1270, 1270,
+ 1270, 1113, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1278,
+
+ 1437, 1437, 1437, 1279, 1437, 1117, 1437, 1437, 1390, 1279,
+ 1279, 1279, 1279, 1279, 1279, 1381, 1382, 1382, 1382, 1382,
+ 1382, 1382, 1437, 1392, 1393, 1393, 1393, 1393, 1393, 1393,
+ 1437, 1117, 1019, 1121, 1121, 1121, 1121, 1121, 1121, 1121,
+ 1201, 1437, 1437, 1437, 1122, 1437, 1437, 1437, 1437, 1437,
+ 1122, 1122, 1122, 1122, 1122, 1122, 1028, 1131, 1131, 1131,
+ 1131, 1131, 1131, 1131, 1204, 1437, 1437, 1437, 1132, 1437,
+ 1437, 1437, 1437, 1437, 1132, 1132, 1132, 1132, 1132, 1132,
+ 1039, 1144, 1144, 1144, 1144, 1144, 1144, 1144, 1207, 1437,
+ 1437, 1437, 1145, 1437, 1437, 1437, 1437, 1437, 1145, 1145,
+
+ 1145, 1145, 1145, 1145, 1051, 1158, 1158, 1158, 1158, 1158,
+ 1158, 1158, 1210, 1437, 1437, 1437, 1159, 1437, 1437, 1437,
+ 1437, 1437, 1159, 1159, 1159, 1159, 1159, 1159, 1063, 1172,
+ 1172, 1172, 1172, 1172, 1172, 1172, 1213, 1437, 1437, 1437,
+ 1173, 1437, 1437, 1437, 1437, 1437, 1173, 1173, 1173, 1173,
+ 1173, 1173, 1113, 1288, 1288, 1288, 1288, 1288, 1288, 1288,
+ 1278, 1437, 1437, 1437, 1289, 1437, 1437, 1437, 1437, 1437,
+ 1289, 1289, 1289, 1289, 1289, 1289, 1183, 1337, 1337, 1337,
+ 1337, 1337, 1337, 1337, 1185, 1437, 1437, 1437, 1338, 1437,
+ 1437, 1437, 1437, 1437, 1338, 1338, 1338, 1338, 1338, 1338,
+
+ 1113, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1278, 1437,
+ 1437, 1437, 1218, 1437, 1437, 1437, 1437, 1437, 1218, 1218,
+ 1218, 1218, 1218, 1218, 1396, 1397, 1397, 1397, 1397, 1397,
+ 1397, 1400, 1401, 1401, 1401, 1401, 1401, 1401, 1404, 1405,
+ 1405, 1405, 1405, 1405, 1405, 1408, 1409, 1409, 1409, 1409,
+ 1409, 1409, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1412,
+ 1412, 1416, 1417, 1417, 1417, 1417, 1417, 1417, 1437, 1437,
+ 1437, 1437, 1437, 1413, 1437, 1393, 1393, 1393, 1393, 1393,
+ 1393, 1393, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1401,
+ 1401, 1401, 1401, 1401, 1401, 1401, 1437, 1437, 1437, 1413,
+
+ 1437, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1409, 1409,
+ 1409, 1409, 1409, 1409, 1409, 1425, 1426, 1426, 1426, 1426,
+ 1426, 1426, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1426,
+ 1426, 1426, 1426, 1426, 1426, 1426, 46, 1437, 1437, 1437,
+ 1437, 46, 46, 46, 64, 1437, 64, 64, 64, 64,
+ 64, 64, 64, 146, 1437, 146, 153, 153, 153, 257,
+ 257, 257, 266, 266, 266, 337, 337, 337, 340, 340,
+ 340, 341, 341, 341, 348, 348, 348, 346, 346, 346,
+ 352, 352, 352, 356, 1437, 356, 416, 416, 416, 421,
+ 421, 421, 422, 422, 422, 431, 431, 431, 435, 1437,
+
+ 435, 436, 436, 436, 350, 350, 1437, 1437, 350, 440,
+ 440, 440, 444, 444, 444, 340, 340, 340, 499, 499,
+ 499, 503, 503, 503, 504, 504, 504, 505, 505, 505,
+ 348, 348, 348, 510, 510, 510, 429, 429, 1437, 1437,
+ 429, 515, 515, 515, 519, 519, 519, 523, 1437, 523,
+ 524, 524, 524, 528, 528, 528, 532, 1437, 532, 580,
+ 580, 580, 431, 431, 431, 588, 588, 588, 589, 589,
+ 589, 597, 597, 597, 601, 1437, 601, 604, 1437, 604,
+ 605, 605, 605, 609, 609, 609, 613, 1437, 613, 522,
+ 522, 1437, 1437, 522, 526, 526, 1437, 1437, 526, 619,
+
+ 619, 619, 623, 623, 623, 532, 532, 1437, 532, 504,
+ 504, 504, 657, 657, 657, 661, 661, 661, 664, 664,
+ 664, 665, 665, 665, 666, 666, 666, 671, 671, 671,
+ 595, 595, 1437, 1437, 595, 676, 676, 676, 680, 680,
+ 680, 601, 601, 1437, 601, 603, 603, 1437, 1437, 603,
+ 604, 604, 1437, 604, 605, 605, 607, 607, 1437, 1437,
+ 607, 687, 687, 687, 691, 691, 691, 613, 613, 1437,
+ 613, 695, 1437, 695, 698, 1437, 698, 699, 699, 699,
+ 703, 703, 703, 707, 1437, 707, 734, 734, 734, 597,
+ 597, 597, 609, 609, 609, 745, 745, 745, 746, 746,
+
+ 746, 754, 754, 754, 758, 1437, 758, 761, 1437, 761,
+ 762, 762, 762, 766, 766, 766, 770, 1437, 770, 773,
+ 1437, 773, 776, 1437, 776, 777, 777, 777, 781, 781,
+ 781, 785, 1437, 785, 694, 1437, 1437, 694, 695, 695,
+ 1437, 695, 697, 697, 1437, 1437, 697, 698, 698, 1437,
+ 698, 699, 699, 701, 701, 1437, 1437, 701, 792, 792,
+ 792, 796, 796, 796, 707, 707, 1437, 707, 53, 53,
+ 53, 1437, 53, 53, 665, 665, 665, 818, 818, 818,
+ 822, 822, 822, 825, 825, 825, 828, 828, 828, 829,
+ 829, 829, 830, 830, 830, 835, 835, 835, 752, 752,
+
+ 1437, 1437, 752, 840, 840, 840, 844, 844, 844, 758,
+ 758, 1437, 758, 760, 760, 1437, 1437, 760, 761, 761,
+ 1437, 761, 762, 762, 764, 764, 1437, 1437, 764, 851,
+ 851, 851, 855, 855, 855, 770, 770, 1437, 770, 772,
+ 1437, 1437, 772, 773, 773, 1437, 773, 775, 775, 1437,
+ 1437, 775, 776, 776, 1437, 776, 777, 777, 779, 779,
+ 1437, 1437, 779, 863, 863, 863, 867, 867, 867, 785,
+ 785, 1437, 785, 869, 1437, 869, 872, 1437, 872, 875,
+ 1437, 875, 876, 876, 876, 880, 880, 880, 884, 1437,
+ 884, 53, 53, 53, 1437, 53, 53, 902, 902, 902,
+
+ 754, 754, 754, 766, 766, 766, 781, 781, 781, 916,
+ 916, 916, 917, 917, 917, 925, 925, 925, 929, 1437,
+ 929, 932, 1437, 932, 933, 933, 933, 937, 937, 937,
+ 941, 1437, 941, 944, 1437, 944, 947, 1437, 947, 948,
+ 948, 948, 952, 952, 952, 956, 1437, 956, 957, 1437,
+ 957, 960, 1437, 960, 963, 1437, 963, 964, 964, 964,
+ 968, 968, 968, 972, 1437, 972, 869, 1437, 869, 871,
+ 1437, 1437, 871, 872, 872, 1437, 872, 874, 874, 1437,
+ 1437, 874, 875, 875, 1437, 875, 876, 876, 878, 878,
+ 1437, 1437, 878, 979, 979, 979, 983, 983, 983, 884,
+
+ 884, 1437, 884, 53, 53, 53, 1437, 53, 53, 829,
+ 829, 829, 1000, 1000, 1000, 1004, 1004, 1004, 1007, 1007,
+ 1007, 1010, 1010, 1010, 1013, 1013, 1013, 1014, 1014, 1014,
+ 1022, 1022, 1022, 923, 923, 1437, 1437, 923, 1027, 1027,
+ 1027, 1031, 1031, 1031, 929, 929, 1437, 929, 931, 931,
+ 1437, 1437, 931, 932, 932, 1437, 932, 933, 933, 935,
+ 935, 1437, 1437, 935, 1038, 1038, 1038, 1042, 1042, 1042,
+ 941, 941, 1437, 941, 943, 1437, 1437, 943, 944, 944,
+ 1437, 944, 946, 946, 1437, 1437, 946, 947, 947, 1437,
+ 947, 948, 948, 950, 950, 1437, 1437, 950, 1050, 1050,
+
+ 1050, 1054, 1054, 1054, 956, 956, 1437, 956, 957, 1437,
+ 957, 959, 1437, 1437, 959, 960, 960, 1437, 960, 962,
+ 962, 1437, 1437, 962, 963, 963, 1437, 963, 964, 964,
+ 966, 966, 1437, 1437, 966, 1062, 1062, 1062, 1066, 1066,
+ 1066, 972, 972, 1437, 972, 1068, 1437, 1068, 1071, 1437,
+ 1071, 1074, 1437, 1074, 1075, 1075, 1075, 1079, 1079, 1079,
+ 1083, 1437, 1083, 53, 53, 53, 1437, 53, 53, 1095,
+ 1095, 1095, 925, 925, 925, 937, 937, 937, 952, 952,
+ 952, 968, 968, 968, 1112, 1112, 1112, 1118, 1118, 1118,
+ 1116, 1116, 1116, 1123, 1123, 1123, 1122, 1122, 1122, 1124,
+
+ 1437, 1124, 1127, 1437, 1127, 1128, 1128, 1128, 1133, 1133,
+ 1133, 1132, 1132, 1132, 1134, 1437, 1134, 1137, 1437, 1137,
+ 1140, 1437, 1140, 1141, 1141, 1141, 1146, 1146, 1146, 1145,
+ 1145, 1145, 1147, 1437, 1147, 1148, 1437, 1148, 1151, 1437,
+ 1151, 1154, 1437, 1154, 1155, 1155, 1155, 1160, 1160, 1160,
+ 1159, 1159, 1159, 1161, 1437, 1161, 1162, 1437, 1162, 1165,
+ 1437, 1165, 1168, 1437, 1168, 1169, 1169, 1169, 1174, 1174,
+ 1174, 1173, 1173, 1173, 1175, 1437, 1175, 1068, 1437, 1068,
+ 1070, 1437, 1437, 1070, 1071, 1071, 1437, 1071, 1073, 1073,
+ 1437, 1437, 1073, 1074, 1074, 1437, 1074, 1075, 1075, 1077,
+
+ 1077, 1437, 1437, 1077, 1182, 1182, 1182, 1186, 1186, 1186,
+ 1083, 1083, 1437, 1083, 53, 53, 53, 1437, 53, 53,
+ 1014, 1014, 1014, 1202, 1202, 1202, 1205, 1205, 1205, 1208,
+ 1208, 1208, 1211, 1211, 1211, 1214, 1214, 1214, 1219, 1219,
+ 1219, 1218, 1218, 1218, 1221, 1437, 1221, 1222, 1222, 1222,
+ 1120, 1120, 1437, 1437, 1120, 1226, 1226, 1226, 1227, 1227,
+ 1227, 1124, 1124, 1437, 1124, 1126, 1126, 1437, 1437, 1126,
+ 1127, 1127, 1437, 1127, 1128, 1128, 1130, 1130, 1437, 1437,
+ 1130, 1233, 1233, 1233, 1234, 1234, 1234, 1134, 1134, 1437,
+ 1134, 1136, 1437, 1437, 1136, 1137, 1137, 1437, 1137, 1139,
+
+ 1139, 1437, 1437, 1139, 1140, 1140, 1437, 1140, 1141, 1141,
+ 1143, 1143, 1437, 1437, 1143, 1241, 1241, 1241, 1242, 1242,
+ 1242, 1147, 1147, 1437, 1147, 1148, 1437, 1148, 1150, 1437,
+ 1437, 1150, 1151, 1151, 1437, 1151, 1153, 1153, 1437, 1437,
+ 1153, 1154, 1154, 1437, 1154, 1155, 1155, 1157, 1157, 1437,
+ 1437, 1157, 1249, 1249, 1249, 1250, 1250, 1250, 1161, 1161,
+ 1437, 1161, 1162, 1437, 1162, 1164, 1437, 1437, 1164, 1165,
+ 1165, 1437, 1165, 1167, 1167, 1437, 1437, 1167, 1168, 1168,
+ 1437, 1168, 1169, 1169, 1171, 1171, 1437, 1437, 1171, 1257,
+ 1257, 1257, 1258, 1258, 1258, 1175, 1175, 1437, 1175, 1259,
+
+ 1437, 1259, 1262, 1437, 1262, 1265, 1437, 1265, 1266, 1266,
+ 1266, 1271, 1437, 1271, 1270, 1270, 1270, 1272, 1437, 1272,
+ 53, 53, 53, 1437, 53, 53, 1280, 1437, 1280, 1279,
+ 1279, 1279, 1281, 1437, 1281, 1122, 1122, 1122, 1282, 1437,
+ 1282, 1132, 1132, 1132, 1283, 1437, 1283, 1145, 1145, 1145,
+ 1284, 1437, 1284, 1159, 1159, 1159, 1285, 1437, 1285, 1173,
+ 1173, 1173, 1216, 1216, 1437, 1437, 1216, 1289, 1289, 1289,
+ 1290, 1290, 1290, 348, 348, 348, 1221, 1221, 1437, 1221,
+ 1291, 1291, 1291, 1294, 1437, 1294, 1295, 1295, 1295, 1296,
+ 1296, 1296, 1299, 1437, 1299, 1302, 1437, 1302, 1303, 1303,
+
+ 1303, 1304, 1304, 1304, 1305, 1437, 1305, 1308, 1437, 1308,
+ 1311, 1437, 1311, 1312, 1312, 1312, 1313, 1313, 1313, 1314,
+ 1437, 1314, 1317, 1437, 1317, 1320, 1437, 1320, 1321, 1321,
+ 1321, 1322, 1322, 1322, 1323, 1437, 1323, 1326, 1437, 1326,
+ 1329, 1437, 1329, 1330, 1330, 1330, 1331, 1331, 1331, 1259,
+ 1437, 1259, 1261, 1437, 1437, 1261, 1262, 1262, 1437, 1262,
+ 1264, 1264, 1437, 1437, 1264, 1265, 1265, 1437, 1265, 1266,
+ 1266, 1268, 1268, 1437, 1437, 1268, 1338, 1338, 1338, 1339,
+ 1437, 1339, 1272, 1272, 1437, 1272, 53, 53, 53, 1437,
+ 53, 53, 1344, 1344, 1344, 1218, 1218, 1218, 1346, 1437,
+
+ 1346, 1347, 1437, 1347, 1348, 1437, 1348, 1349, 1437, 1349,
+ 1350, 1437, 1350, 1351, 1437, 1351, 1354, 1437, 1354, 1355,
+ 1355, 1355, 1356, 1356, 1356, 1357, 1437, 1357, 1293, 1293,
+ 1437, 1437, 1293, 1294, 1294, 1437, 1294, 1295, 1295, 1360,
+ 1437, 1360, 1298, 1437, 1437, 1298, 1299, 1299, 1437, 1299,
+ 1301, 1301, 1437, 1437, 1301, 1302, 1302, 1437, 1302, 1303,
+ 1303, 1364, 1437, 1364, 1305, 1437, 1305, 1307, 1437, 1437,
+ 1307, 1308, 1308, 1437, 1308, 1310, 1310, 1437, 1437, 1310,
+ 1311, 1311, 1437, 1311, 1312, 1312, 1368, 1437, 1368, 1314,
+ 1437, 1314, 1316, 1437, 1437, 1316, 1317, 1317, 1437, 1317,
+
+ 1319, 1319, 1437, 1437, 1319, 1320, 1320, 1437, 1320, 1321,
+ 1321, 1372, 1437, 1372, 1323, 1437, 1323, 1325, 1437, 1437,
+ 1325, 1326, 1326, 1437, 1326, 1328, 1328, 1437, 1437, 1328,
+ 1329, 1329, 1437, 1329, 1330, 1330, 1376, 1437, 1376, 1377,
+ 1437, 1377, 1380, 1437, 1380, 1383, 1437, 1383, 1384, 1384,
+ 1384, 1385, 1437, 1385, 53, 53, 53, 1437, 53, 53,
+ 1389, 1437, 1389, 1291, 1437, 1291, 1296, 1437, 1296, 1304,
+ 1437, 1304, 1313, 1437, 1313, 1322, 1437, 1322, 1331, 1437,
+ 1331, 1353, 1353, 1437, 1437, 1353, 1354, 1354, 1437, 1354,
+ 1355, 1355, 1345, 1437, 1345, 1394, 1437, 1394, 1395, 1437,
+
+ 1395, 1398, 1437, 1398, 1399, 1437, 1399, 1402, 1437, 1402,
+ 1403, 1437, 1403, 1406, 1437, 1406, 1407, 1437, 1407, 1410,
+ 1437, 1410, 1379, 1437, 1437, 1379, 1382, 1382, 1437, 1437,
+ 1382, 1414, 1437, 1414, 1356, 1437, 1356, 1418, 1437, 1418,
+ 1393, 1437, 1437, 1393, 1397, 1437, 1437, 1397, 1401, 1437,
+ 1437, 1401, 1405, 1437, 1437, 1405, 1409, 1437, 1437, 1409,
+ 1424, 1437, 1424, 1427, 1437, 1427, 1417, 1437, 1437, 1417,
+ 1429, 1437, 1429, 1430, 1437, 1430, 1431, 1437, 1431, 1432,
+ 1437, 1432, 1433, 1437, 1433, 1426, 1437, 1437, 1426, 1435,
+ 1437, 1435, 1436, 1437, 1436, 3, 1437, 1437, 1437, 1437,
+
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437
+ } ;
+
+static yyconst flex_int16_t yy_chk[7450] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 4, 7, 15, 4, 7, 4, 7,
+ 9, 4, 7, 9, 34, 9, 17, 17, 9, 19,
+ 19, 4, 7, 34, 24, 27, 27, 100, 9, 4,
+ 7, 15, 12, 100, 128, 12, 9, 12, 24, 23,
+ 12, 23, 23, 26, 28, 24, 23, 26, 1258, 28,
+
+ 12, 23, 128, 26, 29, 23, 26, 23, 12, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 627,
+ 29, 92, 14, 14, 14, 627, 92, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 16, 36, 25, 16, 132, 16, 36, 36,
+ 16, 36, 36, 101, 25, 96, 132, 25, 101, 22,
+ 16, 25, 22, 39, 22, 39, 238, 22, 16, 20,
+ 20, 20, 20, 20, 20, 20, 20, 22, 33, 39,
+ 1262, 123, 33, 20, 35, 22, 39, 1265, 96, 37,
+
+ 238, 33, 33, 37, 123, 33, 35, 33, 35, 104,
+ 35, 37, 104, 35, 104, 237, 37, 237, 37, 20,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 32, 32, 317, 21, 208, 1266, 149, 317, 97, 21,
+ 21, 21, 21, 21, 21, 31, 32, 208, 31, 31,
+ 32, 31, 130, 31, 32, 31, 32, 31, 38, 41,
+ 31, 130, 149, 32, 38, 97, 38, 41, 38, 385,
+ 97, 41, 38, 41, 38, 38, 44, 253, 253, 44,
+ 629, 44, 385, 629, 44, 62, 62, 62, 62, 62,
+ 62, 62, 63, 157, 44, 63, 628, 63, 1270, 388,
+
+ 63, 628, 44, 48, 48, 48, 48, 48, 48, 48,
+ 63, 1272, 260, 388, 48, 410, 410, 1278, 63, 157,
+ 48, 48, 48, 48, 48, 48, 49, 49, 49, 49,
+ 49, 49, 49, 83, 575, 575, 329, 49, 260, 270,
+ 270, 270, 270, 49, 49, 49, 49, 49, 49, 50,
+ 50, 50, 50, 50, 50, 50, 50, 439, 1279, 270,
+ 83, 50, 329, 354, 412, 439, 83, 50, 50, 50,
+ 50, 50, 50, 52, 52, 52, 52, 52, 52, 52,
+ 52, 54, 54, 54, 54, 54, 54, 54, 419, 354,
+ 412, 333, 54, 533, 533, 533, 533, 425, 54, 54,
+
+ 54, 54, 54, 54, 56, 333, 634, 56, 634, 56,
+ 349, 637, 56, 350, 419, 56, 56, 56, 56, 56,
+ 56, 56, 56, 425, 349, 637, 56, 350, 433, 490,
+ 56, 333, 56, 56, 56, 56, 56, 56, 147, 458,
+ 147, 147, 147, 147, 147, 147, 147, 460, 458, 1289,
+ 349, 147, 530, 350, 433, 490, 460, 147, 147, 147,
+ 147, 147, 147, 148, 148, 148, 148, 148, 148, 148,
+ 148, 514, 524, 626, 626, 148, 583, 148, 530, 514,
+ 524, 148, 148, 148, 148, 148, 148, 252, 252, 252,
+ 252, 252, 252, 252, 263, 263, 263, 263, 263, 263,
+
+ 263, 428, 583, 148, 150, 150, 150, 150, 150, 150,
+ 150, 150, 586, 592, 1290, 428, 150, 599, 611, 645,
+ 645, 1294, 150, 150, 150, 150, 150, 150, 151, 151,
+ 151, 151, 151, 151, 151, 151, 151, 618, 586, 592,
+ 151, 428, 1295, 599, 611, 618, 151, 151, 151, 151,
+ 151, 151, 152, 152, 152, 152, 152, 152, 152, 152,
+ 154, 154, 154, 154, 154, 154, 154, 154, 635, 1299,
+ 652, 154, 635, 1302, 631, 636, 708, 154, 154, 154,
+ 154, 154, 154, 156, 156, 156, 156, 156, 156, 156,
+ 156, 156, 631, 636, 708, 156, 652, 156, 654, 287,
+
+ 710, 156, 156, 156, 156, 156, 156, 287, 339, 339,
+ 339, 339, 339, 339, 339, 1303, 1308, 429, 710, 494,
+ 287, 711, 632, 156, 246, 246, 246, 246, 246, 246,
+ 246, 429, 632, 494, 654, 246, 287, 716, 1311, 711,
+ 1312, 246, 246, 246, 246, 246, 246, 248, 248, 248,
+ 248, 248, 248, 248, 630, 716, 711, 429, 248, 494,
+ 716, 693, 705, 630, 248, 248, 248, 248, 248, 248,
+ 249, 249, 249, 249, 249, 249, 249, 249, 251, 251,
+ 251, 251, 251, 251, 251, 675, 686, 693, 705, 251,
+ 1317, 709, 720, 675, 686, 251, 251, 251, 251, 251,
+
+ 251, 254, 254, 254, 254, 254, 254, 254, 254, 709,
+ 720, 720, 1320, 254, 1321, 1326, 709, 1329, 1330, 254,
+ 254, 254, 254, 254, 254, 256, 256, 256, 256, 256,
+ 256, 256, 256, 259, 259, 259, 259, 259, 259, 259,
+ 259, 259, 791, 322, 521, 259, 1338, 259, 322, 1354,
+ 791, 259, 259, 259, 259, 259, 259, 322, 521, 322,
+ 322, 737, 322, 343, 343, 343, 343, 343, 343, 343,
+ 722, 522, 712, 259, 264, 264, 264, 264, 264, 264,
+ 264, 264, 264, 1355, 521, 522, 264, 737, 722, 1380,
+ 712, 525, 264, 264, 264, 264, 264, 264, 265, 265,
+
+ 265, 265, 265, 265, 265, 525, 1383, 712, 1394, 265,
+ 1398, 522, 717, 1402, 718, 265, 265, 265, 265, 265,
+ 265, 327, 526, 327, 327, 327, 327, 327, 327, 327,
+ 717, 525, 718, 717, 327, 718, 526, 723, 721, 727,
+ 327, 327, 327, 327, 327, 327, 328, 328, 328, 328,
+ 328, 328, 328, 328, 1406, 723, 721, 727, 328, 721,
+ 328, 1410, 526, 1418, 328, 328, 328, 328, 328, 328,
+ 409, 409, 409, 409, 409, 409, 409, 437, 437, 437,
+ 437, 437, 437, 437, 594, 644, 328, 330, 330, 330,
+ 330, 330, 330, 330, 330, 644, 1427, 740, 594, 330,
+
+ 743, 729, 729, 1257, 595, 330, 330, 330, 330, 330,
+ 330, 334, 334, 334, 334, 334, 334, 334, 595, 729,
+ 1250, 749, 334, 740, 594, 756, 743, 798, 334, 334,
+ 334, 334, 334, 334, 335, 335, 335, 335, 335, 335,
+ 335, 335, 1249, 1242, 595, 798, 335, 749, 768, 771,
+ 783, 756, 335, 335, 335, 335, 335, 335, 336, 336,
+ 336, 336, 336, 336, 336, 336, 338, 338, 338, 338,
+ 338, 338, 338, 1241, 768, 771, 783, 338, 1234, 799,
+ 800, 801, 1233, 338, 338, 338, 338, 338, 338, 342,
+ 342, 342, 342, 342, 342, 342, 342, 799, 800, 801,
+
+ 342, 1227, 799, 800, 801, 803, 342, 342, 342, 342,
+ 342, 342, 344, 344, 344, 344, 344, 344, 344, 344,
+ 344, 839, 814, 803, 344, 1226, 805, 806, 803, 839,
+ 344, 344, 344, 344, 344, 344, 345, 345, 345, 345,
+ 345, 345, 345, 345, 805, 806, 1222, 345, 814, 805,
+ 806, 808, 810, 345, 345, 345, 345, 345, 345, 351,
+ 351, 351, 351, 351, 351, 351, 351, 351, 850, 808,
+ 810, 351, 808, 870, 1221, 892, 850, 351, 351, 351,
+ 351, 351, 351, 353, 353, 353, 353, 353, 353, 353,
+ 353, 353, 862, 892, 1220, 353, 882, 353, 892, 870,
+
+ 862, 353, 353, 353, 353, 353, 353, 441, 441, 441,
+ 441, 441, 441, 441, 507, 507, 507, 507, 507, 507,
+ 507, 1219, 882, 353, 371, 1218, 905, 1214, 371, 908,
+ 895, 371, 889, 602, 371, 603, 371, 371, 371, 371,
+ 403, 403, 403, 403, 403, 403, 403, 602, 895, 603,
+ 889, 403, 905, 889, 896, 908, 640, 403, 403, 403,
+ 403, 403, 403, 405, 405, 405, 405, 405, 405, 405,
+ 640, 978, 896, 602, 405, 603, 911, 914, 920, 978,
+ 405, 405, 405, 405, 405, 405, 406, 406, 406, 406,
+ 406, 406, 406, 406, 408, 408, 408, 408, 408, 408,
+
+ 408, 1211, 911, 914, 920, 408, 927, 894, 897, 901,
+ 988, 408, 408, 408, 408, 408, 408, 411, 411, 411,
+ 411, 411, 411, 411, 411, 894, 897, 901, 988, 411,
+ 1208, 411, 927, 894, 1205, 411, 411, 411, 411, 411,
+ 411, 512, 512, 512, 512, 512, 512, 512, 516, 516,
+ 516, 516, 516, 516, 516, 713, 606, 411, 413, 413,
+ 413, 413, 413, 413, 413, 939, 1202, 942, 954, 413,
+ 606, 958, 1199, 713, 643, 413, 413, 413, 413, 413,
+ 413, 414, 414, 414, 414, 414, 414, 414, 643, 1186,
+ 713, 939, 414, 942, 954, 970, 606, 958, 414, 414,
+
+ 414, 414, 414, 414, 415, 415, 415, 415, 415, 415,
+ 415, 415, 418, 418, 418, 418, 418, 418, 418, 418,
+ 418, 970, 607, 1182, 418, 1175, 418, 1174, 1173, 1169,
+ 418, 418, 418, 418, 418, 418, 607, 614, 614, 614,
+ 614, 614, 614, 614, 616, 616, 616, 616, 616, 616,
+ 616, 996, 418, 424, 424, 424, 424, 424, 424, 424,
+ 424, 424, 607, 1168, 1165, 424, 1161, 424, 1160, 996,
+ 1159, 424, 424, 424, 424, 424, 424, 620, 620, 620,
+ 620, 620, 620, 620, 668, 668, 668, 668, 668, 668,
+ 668, 696, 715, 424, 430, 430, 430, 430, 430, 430,
+
+ 430, 430, 430, 1155, 1154, 696, 430, 1151, 1016, 1069,
+ 715, 991, 430, 430, 430, 430, 430, 430, 432, 432,
+ 432, 432, 432, 432, 432, 432, 432, 715, 1147, 991,
+ 432, 696, 432, 991, 1016, 1069, 432, 432, 432, 432,
+ 432, 432, 673, 673, 673, 673, 673, 673, 673, 677,
+ 677, 677, 677, 677, 677, 677, 697, 804, 432, 442,
+ 442, 442, 442, 442, 442, 442, 442, 442, 1146, 1145,
+ 697, 442, 1081, 994, 1141, 804, 700, 442, 442, 442,
+ 442, 442, 442, 443, 443, 443, 443, 443, 443, 443,
+ 700, 994, 804, 1140, 443, 994, 697, 995, 1081, 1084,
+
+ 443, 443, 443, 443, 443, 443, 488, 701, 488, 488,
+ 488, 488, 488, 488, 488, 995, 700, 1084, 1137, 488,
+ 995, 701, 1134, 1133, 1087, 488, 488, 488, 488, 488,
+ 488, 489, 489, 489, 489, 489, 489, 489, 489, 1132,
+ 1026, 1084, 1087, 489, 1087, 489, 1128, 701, 1026, 489,
+ 489, 489, 489, 489, 489, 682, 682, 682, 682, 682,
+ 682, 682, 684, 684, 684, 684, 684, 684, 684, 751,
+ 809, 489, 491, 491, 491, 491, 491, 491, 491, 491,
+ 1098, 1037, 1127, 751, 491, 1101, 1124, 1123, 809, 1037,
+ 491, 491, 491, 491, 491, 491, 495, 495, 495, 495,
+
+ 495, 495, 495, 495, 1049, 1061, 1098, 809, 495, 751,
+ 1104, 1101, 1049, 1061, 495, 495, 495, 495, 495, 495,
+ 496, 496, 496, 496, 496, 496, 496, 496, 497, 497,
+ 497, 497, 497, 497, 497, 1122, 1104, 1118, 1116, 497,
+ 1107, 1110, 1135, 1149, 1115, 497, 497, 497, 497, 497,
+ 497, 498, 498, 498, 498, 498, 498, 498, 498, 500,
+ 500, 500, 500, 500, 500, 500, 1107, 1110, 1135, 1149,
+ 500, 1163, 1197, 1085, 1086, 1088, 500, 500, 500, 500,
+ 500, 500, 501, 501, 501, 501, 501, 501, 501, 501,
+ 501, 1085, 1086, 1088, 501, 1260, 1091, 1163, 1197, 752,
+
+ 501, 501, 501, 501, 501, 501, 502, 502, 502, 502,
+ 502, 502, 502, 752, 1091, 1085, 1086, 502, 1112, 1091,
+ 1092, 1260, 1111, 502, 502, 502, 502, 502, 502, 506,
+ 506, 506, 506, 506, 506, 506, 506, 1108, 1092, 752,
+ 506, 1105, 1102, 1099, 1188, 1089, 506, 506, 506, 506,
+ 506, 506, 508, 508, 508, 508, 508, 508, 508, 508,
+ 508, 1181, 1188, 1089, 508, 1095, 1083, 1189, 1190, 1181,
+ 508, 508, 508, 508, 508, 508, 509, 509, 509, 509,
+ 509, 509, 509, 509, 1089, 1189, 1190, 509, 1082, 1079,
+ 1191, 1192, 1274, 509, 509, 509, 509, 509, 509, 517,
+
+ 517, 517, 517, 517, 517, 517, 517, 517, 1191, 1192,
+ 1274, 517, 1075, 1274, 1192, 1275, 1074, 517, 517, 517,
+ 517, 517, 517, 518, 518, 518, 518, 518, 518, 518,
+ 518, 1225, 1071, 1275, 518, 1297, 1275, 1066, 1276, 1225,
+ 518, 518, 518, 518, 518, 518, 527, 527, 527, 527,
+ 527, 527, 527, 527, 527, 1232, 1276, 1306, 527, 1315,
+ 1324, 1297, 1065, 1232, 527, 527, 527, 527, 527, 527,
+ 529, 529, 529, 529, 529, 529, 529, 529, 529, 1240,
+ 1276, 1062, 529, 1306, 529, 1315, 1324, 1240, 529, 529,
+ 529, 529, 529, 529, 688, 688, 688, 688, 688, 688,
+
+ 688, 694, 694, 694, 694, 694, 694, 694, 802, 759,
+ 529, 569, 569, 569, 569, 569, 569, 569, 1378, 1248,
+ 1392, 1396, 569, 759, 1054, 1343, 802, 1248, 569, 569,
+ 569, 569, 569, 569, 571, 571, 571, 571, 571, 571,
+ 571, 802, 1256, 1343, 1378, 571, 1392, 1396, 1400, 759,
+ 1256, 571, 571, 571, 571, 571, 571, 572, 572, 572,
+ 572, 572, 572, 572, 572, 574, 574, 574, 574, 574,
+ 574, 574, 1288, 1337, 1400, 1404, 574, 1408, 1193, 1386,
+ 1288, 1337, 574, 574, 574, 574, 574, 574, 576, 576,
+ 576, 576, 576, 576, 576, 576, 1193, 1386, 1053, 1050,
+
+ 576, 1404, 1416, 1408, 1425, 1193, 576, 576, 576, 576,
+ 576, 576, 577, 577, 577, 577, 577, 577, 577, 577,
+ 578, 578, 578, 578, 578, 578, 578, 1384, 1416, 1042,
+ 1425, 578, 1041, 1038, 1031, 1384, 1030, 578, 578, 578,
+ 578, 578, 578, 579, 579, 579, 579, 579, 579, 579,
+ 579, 582, 582, 582, 582, 582, 582, 582, 582, 582,
+ 714, 760, 763, 582, 1027, 582, 1388, 1022, 764, 582,
+ 582, 582, 582, 582, 582, 760, 763, 1021, 714, 1018,
+ 1017, 1014, 764, 1013, 1388, 724, 1010, 719, 1007, 725,
+ 714, 582, 585, 585, 585, 585, 585, 585, 585, 585,
+
+ 585, 760, 763, 724, 585, 719, 585, 725, 764, 990,
+ 585, 585, 585, 585, 585, 585, 724, 719, 1004, 725,
+ 731, 731, 731, 731, 731, 731, 731, 990, 774, 775,
+ 778, 888, 585, 591, 591, 591, 591, 591, 591, 591,
+ 591, 591, 774, 775, 778, 591, 990, 591, 1000, 888,
+ 779, 591, 591, 591, 591, 591, 591, 772, 772, 772,
+ 772, 772, 772, 772, 779, 1342, 888, 983, 774, 775,
+ 778, 873, 979, 591, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 1342, 972, 873, 596, 971, 968, 1415,
+ 779, 1342, 596, 596, 596, 596, 596, 596, 598, 598,
+
+ 598, 598, 598, 598, 598, 598, 598, 1415, 964, 963,
+ 598, 873, 598, 960, 956, 955, 598, 598, 598, 598,
+ 598, 598, 787, 787, 787, 787, 787, 787, 787, 789,
+ 789, 789, 789, 789, 789, 789, 874, 890, 598, 608,
+ 608, 608, 608, 608, 608, 608, 608, 608, 952, 948,
+ 874, 608, 947, 944, 941, 890, 890, 608, 608, 608,
+ 608, 608, 608, 610, 610, 610, 610, 610, 610, 610,
+ 610, 610, 940, 890, 937, 610, 874, 610, 933, 993,
+ 807, 610, 610, 610, 610, 610, 610, 793, 793, 793,
+ 793, 793, 793, 793, 932, 929, 928, 993, 807, 925,
+
+ 877, 878, 885, 610, 621, 621, 621, 621, 621, 621,
+ 621, 621, 621, 807, 877, 878, 621, 993, 921, 917,
+ 885, 916, 621, 621, 621, 621, 621, 621, 622, 622,
+ 622, 622, 622, 622, 622, 885, 915, 912, 909, 622,
+ 877, 878, 906, 903, 902, 622, 622, 622, 622, 622,
+ 622, 625, 625, 625, 625, 625, 625, 625, 884, 883,
+ 880, 876, 625, 886, 887, 891, 893, 1273, 625, 625,
+ 625, 625, 625, 625, 832, 832, 832, 832, 832, 832,
+ 832, 886, 887, 891, 893, 1273, 625, 648, 875, 648,
+ 648, 648, 648, 648, 648, 648, 886, 887, 887, 891,
+
+ 648, 893, 1273, 989, 992, 1093, 648, 648, 648, 648,
+ 648, 648, 837, 837, 837, 837, 837, 837, 837, 922,
+ 923, 989, 992, 1093, 648, 649, 649, 649, 649, 649,
+ 649, 649, 649, 922, 923, 989, 992, 649, 1093, 872,
+ 867, 863, 855, 649, 649, 649, 649, 649, 649, 841,
+ 841, 841, 841, 841, 841, 841, 851, 844, 840, 922,
+ 923, 649, 650, 650, 650, 650, 650, 650, 650, 846,
+ 846, 846, 846, 846, 846, 846, 848, 848, 848, 848,
+ 848, 848, 848, 852, 852, 852, 852, 852, 852, 852,
+ 858, 858, 858, 858, 858, 858, 858, 650, 651, 651,
+
+ 651, 651, 651, 651, 651, 835, 830, 829, 828, 651,
+ 825, 822, 818, 796, 792, 651, 651, 651, 651, 651,
+ 651, 653, 653, 653, 653, 653, 653, 653, 653, 655,
+ 655, 655, 655, 655, 655, 655, 655, 785, 784, 781,
+ 777, 655, 776, 773, 770, 769, 766, 655, 655, 655,
+ 655, 655, 655, 656, 656, 656, 656, 656, 656, 656,
+ 656, 658, 658, 658, 658, 658, 658, 658, 762, 761,
+ 758, 757, 658, 754, 750, 747, 746, 745, 658, 658,
+ 658, 658, 658, 658, 659, 659, 659, 659, 659, 659,
+ 659, 659, 659, 744, 741, 738, 659, 735, 734, 707,
+
+ 706, 930, 659, 659, 659, 659, 659, 659, 660, 660,
+ 660, 660, 660, 660, 660, 930, 703, 699, 698, 660,
+ 695, 691, 687, 680, 676, 660, 660, 660, 660, 660,
+ 660, 662, 662, 662, 662, 662, 662, 662, 662, 662,
+ 671, 930, 666, 662, 665, 664, 661, 657, 931, 662,
+ 662, 662, 662, 662, 662, 663, 663, 663, 663, 663,
+ 663, 663, 931, 647, 646, 642, 663, 641, 639, 638,
+ 633, 623, 663, 663, 663, 663, 663, 663, 667, 667,
+ 667, 667, 667, 667, 667, 667, 619, 613, 931, 667,
+ 612, 609, 605, 604, 601, 667, 667, 667, 667, 667,
+
+ 667, 669, 669, 669, 669, 669, 669, 669, 669, 669,
+ 600, 597, 593, 669, 590, 589, 588, 587, 584, 669,
+ 669, 669, 669, 669, 669, 670, 670, 670, 670, 670,
+ 670, 670, 670, 581, 580, 573, 670, 570, 568, 564,
+ 560, 559, 670, 670, 670, 670, 670, 670, 678, 678,
+ 678, 678, 678, 678, 678, 678, 678, 558, 557, 553,
+ 678, 552, 550, 549, 548, 547, 678, 678, 678, 678,
+ 678, 678, 679, 679, 679, 679, 679, 679, 679, 679,
+ 546, 545, 544, 679, 543, 542, 541, 540, 539, 679,
+ 679, 679, 679, 679, 679, 689, 689, 689, 689, 689,
+
+ 689, 689, 689, 689, 536, 535, 534, 689, 532, 531,
+ 528, 523, 519, 689, 689, 689, 689, 689, 689, 690,
+ 690, 690, 690, 690, 690, 690, 690, 515, 510, 505,
+ 690, 504, 503, 499, 493, 492, 690, 690, 690, 690,
+ 690, 690, 702, 702, 702, 702, 702, 702, 702, 702,
+ 702, 487, 486, 485, 702, 484, 483, 482, 481, 480,
+ 702, 702, 702, 702, 702, 702, 704, 704, 704, 704,
+ 704, 704, 704, 704, 704, 479, 478, 477, 704, 475,
+ 704, 472, 471, 470, 704, 704, 704, 704, 704, 704,
+ 860, 860, 860, 860, 860, 860, 860, 864, 864, 864,
+
+ 864, 864, 864, 864, 934, 935, 704, 726, 945, 726,
+ 726, 726, 726, 726, 726, 726, 469, 468, 934, 935,
+ 726, 467, 945, 466, 464, 726, 726, 726, 726, 726,
+ 726, 726, 728, 728, 728, 728, 728, 728, 728, 463,
+ 462, 461, 459, 728, 934, 935, 457, 456, 945, 728,
+ 728, 728, 728, 728, 728, 730, 730, 730, 730, 730,
+ 730, 730, 455, 454, 453, 452, 730, 451, 1341, 449,
+ 448, 447, 730, 730, 730, 730, 730, 730, 732, 732,
+ 732, 732, 732, 732, 732, 732, 1341, 444, 440, 436,
+ 732, 435, 434, 431, 427, 1341, 732, 732, 732, 732,
+
+ 732, 732, 733, 733, 733, 733, 733, 733, 733, 733,
+ 736, 736, 736, 736, 736, 736, 736, 736, 736, 426,
+ 423, 422, 736, 421, 736, 420, 417, 416, 736, 736,
+ 736, 736, 736, 736, 871, 871, 871, 871, 871, 871,
+ 871, 943, 943, 943, 943, 943, 943, 943, 946, 407,
+ 736, 739, 739, 739, 739, 739, 739, 739, 739, 739,
+ 404, 949, 946, 739, 402, 739, 401, 950, 961, 739,
+ 739, 739, 739, 739, 739, 949, 400, 399, 398, 397,
+ 396, 950, 961, 395, 394, 393, 392, 1340, 946, 962,
+ 391, 739, 742, 742, 742, 742, 742, 742, 742, 742,
+
+ 742, 949, 389, 962, 742, 1340, 742, 950, 961, 965,
+ 742, 742, 742, 742, 742, 742, 959, 959, 959, 959,
+ 959, 959, 959, 965, 1340, 387, 386, 384, 966, 962,
+ 1072, 383, 742, 748, 748, 748, 748, 748, 748, 748,
+ 748, 748, 966, 380, 1072, 748, 379, 748, 377, 965,
+ 1073, 748, 748, 748, 748, 748, 748, 974, 974, 974,
+ 974, 974, 974, 974, 1073, 375, 374, 373, 966, 1076,
+ 1072, 1077, 370, 748, 753, 753, 753, 753, 753, 753,
+ 753, 753, 753, 1076, 369, 1077, 753, 367, 366, 365,
+ 1073, 364, 753, 753, 753, 753, 753, 753, 755, 755,
+
+ 755, 755, 755, 755, 755, 755, 755, 362, 357, 1076,
+ 755, 1077, 755, 356, 355, 352, 755, 755, 755, 755,
+ 755, 755, 976, 976, 976, 976, 976, 976, 976, 980,
+ 980, 980, 980, 980, 980, 980, 1119, 348, 755, 765,
+ 765, 765, 765, 765, 765, 765, 765, 765, 346, 341,
+ 1119, 765, 340, 337, 332, 331, 323, 765, 765, 765,
+ 765, 765, 765, 767, 767, 767, 767, 767, 767, 767,
+ 767, 767, 985, 986, 1120, 767, 1119, 767, 321, 320,
+ 315, 767, 767, 767, 767, 767, 767, 313, 1120, 311,
+ 985, 986, 1019, 1019, 1019, 1019, 1019, 1019, 1019, 1125,
+
+ 310, 985, 986, 767, 780, 780, 780, 780, 780, 780,
+ 780, 780, 780, 1125, 1120, 309, 780, 308, 307, 306,
+ 305, 303, 780, 780, 780, 780, 780, 780, 782, 782,
+ 782, 782, 782, 782, 782, 782, 782, 987, 1126, 1125,
+ 782, 302, 782, 301, 296, 1387, 782, 782, 782, 782,
+ 782, 782, 1126, 293, 292, 987, 1024, 1024, 1024, 1024,
+ 1024, 1024, 1024, 1387, 291, 1129, 987, 288, 782, 794,
+ 794, 794, 794, 794, 794, 794, 794, 794, 1126, 1129,
+ 285, 794, 1387, 284, 282, 280, 1130, 794, 794, 794,
+ 794, 794, 794, 795, 795, 795, 795, 795, 795, 795,
+
+ 1130, 279, 278, 276, 795, 1129, 272, 271, 269, 266,
+ 795, 795, 795, 795, 795, 795, 811, 1138, 811, 811,
+ 811, 811, 811, 811, 811, 262, 1130, 261, 258, 811,
+ 257, 1138, 255, 250, 811, 811, 811, 811, 811, 811,
+ 811, 812, 812, 812, 812, 812, 812, 812, 247, 245,
+ 244, 242, 812, 239, 235, 231, 229, 1138, 812, 812,
+ 812, 812, 812, 812, 813, 813, 813, 813, 813, 813,
+ 813, 813, 227, 226, 224, 223, 813, 222, 813, 221,
+ 220, 219, 813, 813, 813, 813, 813, 813, 1028, 1028,
+ 1028, 1028, 1028, 1028, 1028, 1033, 1033, 1033, 1033, 1033,
+
+ 1033, 1033, 218, 1139, 813, 815, 815, 815, 815, 815,
+ 815, 815, 216, 214, 212, 211, 815, 1139, 209, 207,
+ 206, 204, 815, 815, 815, 815, 815, 815, 816, 816,
+ 816, 816, 816, 816, 816, 816, 201, 200, 199, 197,
+ 816, 195, 194, 1139, 191, 190, 816, 816, 816, 816,
+ 816, 816, 817, 817, 817, 817, 817, 817, 817, 817,
+ 819, 819, 819, 819, 819, 819, 819, 188, 187, 186,
+ 185, 819, 184, 183, 182, 181, 180, 819, 819, 819,
+ 819, 819, 819, 820, 820, 820, 820, 820, 820, 820,
+ 820, 820, 179, 177, 176, 820, 173, 172, 171, 170,
+
+ 1142, 820, 820, 820, 820, 820, 820, 821, 821, 821,
+ 821, 821, 821, 821, 1142, 169, 168, 167, 821, 166,
+ 164, 161, 160, 159, 821, 821, 821, 821, 821, 821,
+ 823, 823, 823, 823, 823, 823, 823, 823, 823, 158,
+ 1142, 155, 823, 153, 144, 143, 142, 1143, 823, 823,
+ 823, 823, 823, 823, 824, 824, 824, 824, 824, 824,
+ 824, 1143, 141, 140, 139, 824, 138, 136, 134, 133,
+ 131, 824, 824, 824, 824, 824, 824, 826, 826, 826,
+ 826, 826, 826, 826, 826, 826, 129, 1143, 127, 826,
+ 126, 125, 124, 122, 1152, 826, 826, 826, 826, 826,
+
+ 826, 827, 827, 827, 827, 827, 827, 827, 1152, 121,
+ 120, 119, 827, 118, 117, 115, 113, 112, 827, 827,
+ 827, 827, 827, 827, 831, 831, 831, 831, 831, 831,
+ 831, 831, 111, 110, 1152, 831, 109, 108, 107, 106,
+ 105, 831, 831, 831, 831, 831, 831, 833, 833, 833,
+ 833, 833, 833, 833, 833, 833, 103, 102, 95, 833,
+ 94, 93, 91, 90, 89, 833, 833, 833, 833, 833,
+ 833, 834, 834, 834, 834, 834, 834, 834, 834, 88,
+ 87, 86, 834, 85, 84, 82, 81, 80, 834, 834,
+ 834, 834, 834, 834, 842, 842, 842, 842, 842, 842,
+
+ 842, 842, 842, 79, 78, 77, 842, 76, 75, 74,
+ 73, 72, 842, 842, 842, 842, 842, 842, 843, 843,
+ 843, 843, 843, 843, 843, 843, 71, 70, 69, 843,
+ 67, 66, 65, 51, 43, 843, 843, 843, 843, 843,
+ 843, 853, 853, 853, 853, 853, 853, 853, 853, 853,
+ 42, 40, 30, 853, 18, 10, 8, 3, 0, 853,
+ 853, 853, 853, 853, 853, 854, 854, 854, 854, 854,
+ 854, 854, 854, 0, 0, 0, 854, 0, 0, 0,
+ 0, 0, 854, 854, 854, 854, 854, 854, 865, 865,
+ 865, 865, 865, 865, 865, 865, 865, 0, 0, 0,
+
+ 865, 0, 0, 0, 0, 0, 865, 865, 865, 865,
+ 865, 865, 866, 866, 866, 866, 866, 866, 866, 866,
+ 0, 0, 0, 866, 0, 0, 0, 0, 0, 866,
+ 866, 866, 866, 866, 866, 879, 879, 879, 879, 879,
+ 879, 879, 879, 879, 0, 0, 0, 879, 0, 0,
+ 0, 0, 0, 879, 879, 879, 879, 879, 879, 881,
+ 881, 881, 881, 881, 881, 881, 881, 881, 0, 0,
+ 0, 881, 0, 881, 0, 0, 0, 881, 881, 881,
+ 881, 881, 881, 1035, 1035, 1035, 1035, 1035, 1035, 1035,
+ 1039, 1039, 1039, 1039, 1039, 1039, 1039, 0, 0, 881,
+
+ 898, 898, 898, 898, 898, 898, 898, 898, 898, 0,
+ 0, 0, 0, 898, 0, 0, 0, 0, 898, 898,
+ 898, 898, 898, 898, 898, 899, 899, 899, 899, 899,
+ 899, 899, 899, 900, 900, 900, 900, 900, 900, 900,
+ 900, 900, 1045, 1045, 1045, 1045, 1045, 1045, 1045, 0,
+ 0, 900, 904, 904, 904, 904, 904, 904, 904, 904,
+ 904, 0, 0, 0, 904, 0, 904, 0, 0, 0,
+ 904, 904, 904, 904, 904, 904, 1047, 1047, 1047, 1047,
+ 1047, 1047, 1047, 1051, 1051, 1051, 1051, 1051, 1051, 1051,
+ 0, 0, 904, 907, 907, 907, 907, 907, 907, 907,
+
+ 907, 907, 0, 0, 0, 907, 0, 907, 0, 0,
+ 0, 907, 907, 907, 907, 907, 907, 1057, 1057, 1057,
+ 1057, 1057, 1057, 1057, 1059, 1059, 1059, 1059, 1059, 1059,
+ 1059, 0, 0, 907, 910, 910, 910, 910, 910, 910,
+ 910, 910, 910, 0, 0, 0, 910, 0, 910, 0,
+ 0, 0, 910, 910, 910, 910, 910, 910, 1063, 1063,
+ 1063, 1063, 1063, 1063, 1063, 1070, 1070, 1070, 1070, 1070,
+ 1070, 1070, 1090, 0, 910, 913, 913, 913, 913, 913,
+ 913, 913, 913, 913, 0, 1153, 1156, 913, 0, 913,
+ 1090, 0, 0, 913, 913, 913, 913, 913, 913, 1153,
+
+ 1156, 1090, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 0,
+ 1157, 0, 0, 0, 1166, 913, 918, 918, 918, 918,
+ 918, 918, 918, 918, 1157, 1153, 1156, 918, 1166, 0,
+ 0, 0, 0, 918, 918, 918, 918, 918, 918, 919,
+ 919, 919, 919, 919, 919, 919, 919, 919, 0, 0,
+ 1157, 919, 0, 919, 1166, 0, 0, 919, 919, 919,
+ 919, 919, 919, 1136, 1136, 1136, 1136, 1136, 1136, 1136,
+ 1150, 1150, 1150, 1150, 1150, 1150, 1150, 1167, 0, 919,
+ 924, 924, 924, 924, 924, 924, 924, 924, 924, 0,
+ 0, 1167, 924, 0, 0, 0, 0, 0, 924, 924,
+
+ 924, 924, 924, 924, 926, 926, 926, 926, 926, 926,
+ 926, 926, 926, 0, 0, 0, 926, 1167, 926, 0,
+ 0, 1170, 926, 926, 926, 926, 926, 926, 1164, 1164,
+ 1164, 1164, 1164, 1164, 1164, 1170, 0, 0, 0, 0,
+ 1171, 0, 1215, 0, 926, 936, 936, 936, 936, 936,
+ 936, 936, 936, 936, 1171, 0, 1215, 936, 0, 0,
+ 0, 1170, 0, 936, 936, 936, 936, 936, 936, 938,
+ 938, 938, 938, 938, 938, 938, 938, 938, 0, 0,
+ 1171, 938, 1215, 938, 0, 0, 0, 938, 938, 938,
+ 938, 938, 938, 1177, 1177, 1177, 1177, 1177, 1177, 1177,
+
+ 1179, 1179, 1179, 1179, 1179, 1179, 1179, 1216, 0, 938,
+ 951, 951, 951, 951, 951, 951, 951, 951, 951, 0,
+ 0, 1216, 951, 0, 0, 0, 0, 0, 951, 951,
+ 951, 951, 951, 951, 953, 953, 953, 953, 953, 953,
+ 953, 953, 953, 0, 0, 0, 953, 1216, 953, 0,
+ 0, 0, 953, 953, 953, 953, 953, 953, 1183, 1183,
+ 1183, 1183, 1183, 1183, 1183, 1223, 1223, 1223, 1223, 1223,
+ 1223, 1223, 1263, 0, 953, 967, 967, 967, 967, 967,
+ 967, 967, 967, 967, 0, 0, 1263, 967, 0, 0,
+ 0, 0, 1194, 967, 967, 967, 967, 967, 967, 969,
+
+ 969, 969, 969, 969, 969, 969, 969, 969, 1195, 0,
+ 1194, 969, 1263, 969, 0, 0, 0, 969, 969, 969,
+ 969, 969, 969, 1194, 0, 0, 1195, 1228, 1228, 1228,
+ 1228, 1228, 1228, 1228, 0, 0, 1264, 1195, 0, 969,
+ 981, 981, 981, 981, 981, 981, 981, 981, 981, 0,
+ 1264, 0, 981, 0, 0, 0, 0, 1267, 981, 981,
+ 981, 981, 981, 981, 982, 982, 982, 982, 982, 982,
+ 982, 1267, 0, 0, 0, 982, 1264, 0, 0, 0,
+ 0, 982, 982, 982, 982, 982, 982, 997, 997, 997,
+ 997, 997, 997, 997, 997, 997, 0, 1267, 0, 0,
+
+ 997, 0, 0, 0, 0, 997, 997, 997, 997, 997,
+ 997, 997, 998, 998, 998, 998, 998, 998, 998, 998,
+ 999, 999, 999, 999, 999, 999, 999, 999, 999, 1230,
+ 1230, 1230, 1230, 1230, 1230, 1230, 0, 1268, 999, 1001,
+ 1001, 1001, 1001, 1001, 1001, 1001, 0, 0, 0, 0,
+ 1001, 1268, 0, 0, 0, 0, 1001, 1001, 1001, 1001,
+ 1001, 1001, 1002, 1002, 1002, 1002, 1002, 1002, 1002, 1002,
+ 1002, 0, 0, 0, 1002, 0, 0, 1268, 0, 1292,
+ 1002, 1002, 1002, 1002, 1002, 1002, 1003, 1003, 1003, 1003,
+ 1003, 1003, 1003, 1292, 0, 0, 0, 1003, 0, 0,
+
+ 0, 0, 0, 1003, 1003, 1003, 1003, 1003, 1003, 1005,
+ 1005, 1005, 1005, 1005, 1005, 1005, 1005, 1005, 0, 1292,
+ 0, 1005, 0, 0, 0, 0, 1293, 1005, 1005, 1005,
+ 1005, 1005, 1005, 1006, 1006, 1006, 1006, 1006, 1006, 1006,
+ 1293, 0, 0, 0, 1006, 0, 0, 0, 0, 0,
+ 1006, 1006, 1006, 1006, 1006, 1006, 1008, 1008, 1008, 1008,
+ 1008, 1008, 1008, 1008, 1008, 0, 1293, 0, 1008, 0,
+ 0, 0, 0, 1300, 1008, 1008, 1008, 1008, 1008, 1008,
+ 1009, 1009, 1009, 1009, 1009, 1009, 1009, 1300, 0, 0,
+ 0, 1009, 0, 0, 0, 0, 0, 1009, 1009, 1009,
+
+ 1009, 1009, 1009, 1011, 1011, 1011, 1011, 1011, 1011, 1011,
+ 1011, 1011, 0, 1300, 0, 1011, 0, 0, 0, 0,
+ 1301, 1011, 1011, 1011, 1011, 1011, 1011, 1012, 1012, 1012,
+ 1012, 1012, 1012, 1012, 1301, 0, 0, 0, 1012, 0,
+ 0, 0, 0, 0, 1012, 1012, 1012, 1012, 1012, 1012,
+ 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 1015, 0,
+ 1301, 0, 1015, 0, 1015, 0, 0, 0, 1015, 1015,
+ 1015, 1015, 1015, 1015, 1236, 1236, 1236, 1236, 1236, 1236,
+ 1236, 1238, 1238, 1238, 1238, 1238, 1238, 1238, 1309, 0,
+ 1015, 1020, 1020, 1020, 1020, 1020, 1020, 1020, 1020, 1020,
+
+ 0, 0, 1309, 1020, 0, 0, 0, 0, 0, 1020,
+ 1020, 1020, 1020, 1020, 1020, 1029, 1029, 1029, 1029, 1029,
+ 1029, 1029, 1029, 1029, 0, 0, 0, 1029, 1309, 0,
+ 0, 0, 0, 1029, 1029, 1029, 1029, 1029, 1029, 1040,
+ 1040, 1040, 1040, 1040, 1040, 1040, 1040, 1040, 0, 0,
+ 0, 1040, 0, 0, 0, 0, 0, 1040, 1040, 1040,
+ 1040, 1040, 1040, 1052, 1052, 1052, 1052, 1052, 1052, 1052,
+ 1052, 1052, 0, 0, 0, 1052, 0, 0, 0, 0,
+ 0, 1052, 1052, 1052, 1052, 1052, 1052, 1064, 1064, 1064,
+ 1064, 1064, 1064, 1064, 1064, 1064, 0, 0, 0, 1064,
+
+ 0, 0, 0, 0, 0, 1064, 1064, 1064, 1064, 1064,
+ 1064, 1078, 1078, 1078, 1078, 1078, 1078, 1078, 1078, 1078,
+ 0, 0, 0, 1078, 0, 0, 0, 0, 0, 1078,
+ 1078, 1078, 1078, 1078, 1078, 1080, 1080, 1080, 1080, 1080,
+ 1080, 1080, 1080, 1080, 0, 0, 0, 1080, 0, 1080,
+ 0, 0, 0, 1080, 1080, 1080, 1080, 1080, 1080, 1244,
+ 1244, 1244, 1244, 1244, 1244, 1244, 1246, 1246, 1246, 1246,
+ 1246, 1246, 1246, 0, 0, 1080, 1094, 1094, 1094, 1094,
+ 1094, 1094, 1094, 1094, 1094, 1252, 1252, 1252, 1252, 1252,
+ 1252, 1252, 0, 1310, 1094, 1096, 1096, 1096, 1096, 1096,
+
+ 1096, 1096, 1096, 0, 0, 0, 1096, 1310, 0, 0,
+ 0, 0, 1096, 1096, 1096, 1096, 1096, 1096, 1097, 1097,
+ 1097, 1097, 1097, 1097, 1097, 1097, 1097, 0, 0, 0,
+ 1097, 0, 1097, 1310, 0, 0, 1097, 1097, 1097, 1097,
+ 1097, 1097, 1254, 1254, 1254, 1254, 1254, 1254, 1254, 1261,
+ 1261, 1261, 1261, 1261, 1261, 1261, 0, 0, 1097, 1100,
+ 1100, 1100, 1100, 1100, 1100, 1100, 1100, 1100, 0, 0,
+ 0, 1100, 0, 1100, 0, 0, 0, 1100, 1100, 1100,
+ 1100, 1100, 1100, 1286, 1286, 1286, 1286, 1286, 1286, 1286,
+ 1298, 1298, 1298, 1298, 1298, 1298, 1298, 0, 0, 1100,
+
+ 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 1103, 0,
+ 0, 0, 1103, 0, 1103, 0, 0, 0, 1103, 1103,
+ 1103, 1103, 1103, 1103, 1307, 1307, 1307, 1307, 1307, 1307,
+ 1307, 1316, 1316, 1316, 1316, 1316, 1316, 1316, 1318, 0,
+ 1103, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106, 1106,
+ 0, 1319, 1318, 1106, 0, 1106, 0, 0, 0, 1106,
+ 1106, 1106, 1106, 1106, 1106, 1319, 1325, 1325, 1325, 1325,
+ 1325, 1325, 1325, 0, 0, 0, 0, 0, 1318, 1327,
+ 0, 1106, 1109, 1109, 1109, 1109, 1109, 1109, 1109, 1109,
+ 1109, 1319, 1328, 1327, 1109, 0, 1109, 0, 0, 0,
+
+ 1109, 1109, 1109, 1109, 1109, 1109, 1328, 1333, 1333, 1333,
+ 1333, 1333, 1333, 1333, 0, 0, 0, 0, 0, 1327,
+ 1352, 0, 1109, 1114, 1114, 1114, 1114, 1114, 1114, 1114,
+ 1114, 1114, 1328, 0, 1352, 1114, 0, 0, 0, 0,
+ 0, 1114, 1114, 1114, 1114, 1114, 1114, 1121, 1121, 1121,
+ 1121, 1121, 1121, 1121, 1121, 1121, 0, 0, 0, 1121,
+ 1352, 0, 0, 0, 0, 1121, 1121, 1121, 1121, 1121,
+ 1121, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131, 1131,
+ 0, 0, 0, 1131, 0, 0, 0, 0, 0, 1131,
+ 1131, 1131, 1131, 1131, 1131, 1144, 1144, 1144, 1144, 1144,
+
+ 1144, 1144, 1144, 1144, 0, 0, 0, 1144, 0, 0,
+ 0, 0, 0, 1144, 1144, 1144, 1144, 1144, 1144, 1158,
+ 1158, 1158, 1158, 1158, 1158, 1158, 1158, 1158, 0, 0,
+ 0, 1158, 0, 0, 0, 0, 0, 1158, 1158, 1158,
+ 1158, 1158, 1158, 1172, 1172, 1172, 1172, 1172, 1172, 1172,
+ 1172, 1172, 0, 0, 0, 1172, 0, 0, 0, 0,
+ 0, 1172, 1172, 1172, 1172, 1172, 1172, 1184, 1184, 1184,
+ 1184, 1184, 1184, 1184, 1184, 1184, 0, 0, 0, 1184,
+ 0, 0, 0, 0, 0, 1184, 1184, 1184, 1184, 1184,
+ 1184, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196, 1196,
+
+ 0, 0, 0, 1196, 0, 1196, 0, 0, 1353, 1196,
+ 1196, 1196, 1196, 1196, 1196, 1335, 1335, 1335, 1335, 1335,
+ 1335, 1335, 1353, 1358, 1358, 1358, 1358, 1358, 1358, 1358,
+ 0, 1196, 1200, 1200, 1200, 1200, 1200, 1200, 1200, 1200,
+ 1200, 0, 0, 0, 1200, 0, 0, 0, 1353, 0,
+ 1200, 1200, 1200, 1200, 1200, 1200, 1203, 1203, 1203, 1203,
+ 1203, 1203, 1203, 1203, 1203, 0, 0, 0, 1203, 0,
+ 0, 0, 0, 0, 1203, 1203, 1203, 1203, 1203, 1203,
+ 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 1206, 0,
+ 0, 0, 1206, 0, 0, 0, 0, 0, 1206, 1206,
+
+ 1206, 1206, 1206, 1206, 1209, 1209, 1209, 1209, 1209, 1209,
+ 1209, 1209, 1209, 0, 0, 0, 1209, 0, 0, 0,
+ 0, 0, 1209, 1209, 1209, 1209, 1209, 1209, 1212, 1212,
+ 1212, 1212, 1212, 1212, 1212, 1212, 1212, 0, 0, 0,
+ 1212, 0, 0, 0, 0, 0, 1212, 1212, 1212, 1212,
+ 1212, 1212, 1217, 1217, 1217, 1217, 1217, 1217, 1217, 1217,
+ 1217, 0, 0, 0, 1217, 0, 0, 0, 0, 0,
+ 1217, 1217, 1217, 1217, 1217, 1217, 1269, 1269, 1269, 1269,
+ 1269, 1269, 1269, 1269, 1269, 0, 0, 0, 1269, 0,
+ 0, 0, 0, 0, 1269, 1269, 1269, 1269, 1269, 1269,
+
+ 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 1277, 0,
+ 0, 0, 1277, 0, 0, 0, 0, 0, 1277, 1277,
+ 1277, 1277, 1277, 1277, 1362, 1362, 1362, 1362, 1362, 1362,
+ 1362, 1366, 1366, 1366, 1366, 1366, 1366, 1366, 1370, 1370,
+ 1370, 1370, 1370, 1370, 1370, 1374, 1374, 1374, 1374, 1374,
+ 1374, 1374, 1379, 1379, 1379, 1379, 1379, 1379, 1379, 1381,
+ 1382, 1390, 1390, 1390, 1390, 1390, 1390, 1390, 0, 0,
+ 0, 0, 0, 1381, 1382, 1393, 1393, 1393, 1393, 1393,
+ 1393, 1393, 1397, 1397, 1397, 1397, 1397, 1397, 1397, 1401,
+ 1401, 1401, 1401, 1401, 1401, 1401, 0, 0, 0, 1381,
+
+ 1382, 1405, 1405, 1405, 1405, 1405, 1405, 1405, 1409, 1409,
+ 1409, 1409, 1409, 1409, 1409, 1412, 1412, 1412, 1412, 1412,
+ 1412, 1412, 1417, 1417, 1417, 1417, 1417, 1417, 1417, 1426,
+ 1426, 1426, 1426, 1426, 1426, 1426, 1438, 0, 0, 0,
+ 0, 1438, 1438, 1438, 1439, 0, 1439, 1439, 1439, 1439,
+ 1439, 1439, 1439, 1440, 0, 1440, 1441, 1441, 1441, 1442,
+ 1442, 1442, 1443, 1443, 1443, 1444, 1444, 1444, 1445, 1445,
+ 1445, 1446, 1446, 1446, 1447, 1447, 1447, 1448, 1448, 1448,
+ 1449, 1449, 1449, 1450, 0, 1450, 1451, 1451, 1451, 1452,
+ 1452, 1452, 1453, 1453, 1453, 1454, 1454, 1454, 1455, 0,
+
+ 1455, 1456, 1456, 1456, 1457, 1457, 0, 0, 1457, 1458,
+ 1458, 1458, 1459, 1459, 1459, 1460, 1460, 1460, 1461, 1461,
+ 1461, 1462, 1462, 1462, 1463, 1463, 1463, 1464, 1464, 1464,
+ 1465, 1465, 1465, 1466, 1466, 1466, 1467, 1467, 0, 0,
+ 1467, 1468, 1468, 1468, 1469, 1469, 1469, 1470, 0, 1470,
+ 1471, 1471, 1471, 1472, 1472, 1472, 1473, 0, 1473, 1474,
+ 1474, 1474, 1475, 1475, 1475, 1476, 1476, 1476, 1477, 1477,
+ 1477, 1478, 1478, 1478, 1479, 0, 1479, 1480, 0, 1480,
+ 1481, 1481, 1481, 1482, 1482, 1482, 1483, 0, 1483, 1484,
+ 1484, 0, 0, 1484, 1485, 1485, 0, 0, 1485, 1486,
+
+ 1486, 1486, 1487, 1487, 1487, 1488, 1488, 0, 1488, 1489,
+ 1489, 1489, 1490, 1490, 1490, 1491, 1491, 1491, 1492, 1492,
+ 1492, 1493, 1493, 1493, 1494, 1494, 1494, 1495, 1495, 1495,
+ 1496, 1496, 0, 0, 1496, 1497, 1497, 1497, 1498, 1498,
+ 1498, 1499, 1499, 0, 1499, 1500, 1500, 0, 0, 1500,
+ 1501, 1501, 0, 1501, 1502, 1502, 1503, 1503, 0, 0,
+ 1503, 1504, 1504, 1504, 1505, 1505, 1505, 1506, 1506, 0,
+ 1506, 1507, 0, 1507, 1508, 0, 1508, 1509, 1509, 1509,
+ 1510, 1510, 1510, 1511, 0, 1511, 1512, 1512, 1512, 1513,
+ 1513, 1513, 1514, 1514, 1514, 1515, 1515, 1515, 1516, 1516,
+
+ 1516, 1517, 1517, 1517, 1518, 0, 1518, 1519, 0, 1519,
+ 1520, 1520, 1520, 1521, 1521, 1521, 1522, 0, 1522, 1523,
+ 0, 1523, 1524, 0, 1524, 1525, 1525, 1525, 1526, 1526,
+ 1526, 1527, 0, 1527, 1528, 0, 0, 1528, 1529, 1529,
+ 0, 1529, 1530, 1530, 0, 0, 1530, 1531, 1531, 0,
+ 1531, 1532, 1532, 1533, 1533, 0, 0, 1533, 1534, 1534,
+ 1534, 1535, 1535, 1535, 1536, 1536, 0, 1536, 1537, 1537,
+ 1537, 0, 1537, 1537, 1538, 1538, 1538, 1539, 1539, 1539,
+ 1540, 1540, 1540, 1541, 1541, 1541, 1542, 1542, 1542, 1543,
+ 1543, 1543, 1544, 1544, 1544, 1545, 1545, 1545, 1546, 1546,
+
+ 0, 0, 1546, 1547, 1547, 1547, 1548, 1548, 1548, 1549,
+ 1549, 0, 1549, 1550, 1550, 0, 0, 1550, 1551, 1551,
+ 0, 1551, 1552, 1552, 1553, 1553, 0, 0, 1553, 1554,
+ 1554, 1554, 1555, 1555, 1555, 1556, 1556, 0, 1556, 1557,
+ 0, 0, 1557, 1558, 1558, 0, 1558, 1559, 1559, 0,
+ 0, 1559, 1560, 1560, 0, 1560, 1561, 1561, 1562, 1562,
+ 0, 0, 1562, 1563, 1563, 1563, 1564, 1564, 1564, 1565,
+ 1565, 0, 1565, 1566, 0, 1566, 1567, 0, 1567, 1568,
+ 0, 1568, 1569, 1569, 1569, 1570, 1570, 1570, 1571, 0,
+ 1571, 1572, 1572, 1572, 0, 1572, 1572, 1573, 1573, 1573,
+
+ 1574, 1574, 1574, 1575, 1575, 1575, 1576, 1576, 1576, 1577,
+ 1577, 1577, 1578, 1578, 1578, 1579, 1579, 1579, 1580, 0,
+ 1580, 1581, 0, 1581, 1582, 1582, 1582, 1583, 1583, 1583,
+ 1584, 0, 1584, 1585, 0, 1585, 1586, 0, 1586, 1587,
+ 1587, 1587, 1588, 1588, 1588, 1589, 0, 1589, 1590, 0,
+ 1590, 1591, 0, 1591, 1592, 0, 1592, 1593, 1593, 1593,
+ 1594, 1594, 1594, 1595, 0, 1595, 1596, 0, 1596, 1597,
+ 0, 0, 1597, 1598, 1598, 0, 1598, 1599, 1599, 0,
+ 0, 1599, 1600, 1600, 0, 1600, 1601, 1601, 1602, 1602,
+ 0, 0, 1602, 1603, 1603, 1603, 1604, 1604, 1604, 1605,
+
+ 1605, 0, 1605, 1606, 1606, 1606, 0, 1606, 1606, 1607,
+ 1607, 1607, 1608, 1608, 1608, 1609, 1609, 1609, 1610, 1610,
+ 1610, 1611, 1611, 1611, 1612, 1612, 1612, 1613, 1613, 1613,
+ 1614, 1614, 1614, 1615, 1615, 0, 0, 1615, 1616, 1616,
+ 1616, 1617, 1617, 1617, 1618, 1618, 0, 1618, 1619, 1619,
+ 0, 0, 1619, 1620, 1620, 0, 1620, 1621, 1621, 1622,
+ 1622, 0, 0, 1622, 1623, 1623, 1623, 1624, 1624, 1624,
+ 1625, 1625, 0, 1625, 1626, 0, 0, 1626, 1627, 1627,
+ 0, 1627, 1628, 1628, 0, 0, 1628, 1629, 1629, 0,
+ 1629, 1630, 1630, 1631, 1631, 0, 0, 1631, 1632, 1632,
+
+ 1632, 1633, 1633, 1633, 1634, 1634, 0, 1634, 1635, 0,
+ 1635, 1636, 0, 0, 1636, 1637, 1637, 0, 1637, 1638,
+ 1638, 0, 0, 1638, 1639, 1639, 0, 1639, 1640, 1640,
+ 1641, 1641, 0, 0, 1641, 1642, 1642, 1642, 1643, 1643,
+ 1643, 1644, 1644, 0, 1644, 1645, 0, 1645, 1646, 0,
+ 1646, 1647, 0, 1647, 1648, 1648, 1648, 1649, 1649, 1649,
+ 1650, 0, 1650, 1651, 1651, 1651, 0, 1651, 1651, 1652,
+ 1652, 1652, 1653, 1653, 1653, 1654, 1654, 1654, 1655, 1655,
+ 1655, 1656, 1656, 1656, 1657, 1657, 1657, 1658, 1658, 1658,
+ 1659, 1659, 1659, 1660, 1660, 1660, 1661, 1661, 1661, 1662,
+
+ 0, 1662, 1663, 0, 1663, 1664, 1664, 1664, 1665, 1665,
+ 1665, 1666, 1666, 1666, 1667, 0, 1667, 1668, 0, 1668,
+ 1669, 0, 1669, 1670, 1670, 1670, 1671, 1671, 1671, 1672,
+ 1672, 1672, 1673, 0, 1673, 1674, 0, 1674, 1675, 0,
+ 1675, 1676, 0, 1676, 1677, 1677, 1677, 1678, 1678, 1678,
+ 1679, 1679, 1679, 1680, 0, 1680, 1681, 0, 1681, 1682,
+ 0, 1682, 1683, 0, 1683, 1684, 1684, 1684, 1685, 1685,
+ 1685, 1686, 1686, 1686, 1687, 0, 1687, 1688, 0, 1688,
+ 1689, 0, 0, 1689, 1690, 1690, 0, 1690, 1691, 1691,
+ 0, 0, 1691, 1692, 1692, 0, 1692, 1693, 1693, 1694,
+
+ 1694, 0, 0, 1694, 1695, 1695, 1695, 1696, 1696, 1696,
+ 1697, 1697, 0, 1697, 1698, 1698, 1698, 0, 1698, 1698,
+ 1699, 1699, 1699, 1700, 1700, 1700, 1701, 1701, 1701, 1702,
+ 1702, 1702, 1703, 1703, 1703, 1704, 1704, 1704, 1705, 1705,
+ 1705, 1706, 1706, 1706, 1707, 0, 1707, 1708, 1708, 1708,
+ 1709, 1709, 0, 0, 1709, 1710, 1710, 1710, 1711, 1711,
+ 1711, 1712, 1712, 0, 1712, 1713, 1713, 0, 0, 1713,
+ 1714, 1714, 0, 1714, 1715, 1715, 1716, 1716, 0, 0,
+ 1716, 1717, 1717, 1717, 1718, 1718, 1718, 1719, 1719, 0,
+ 1719, 1720, 0, 0, 1720, 1721, 1721, 0, 1721, 1722,
+
+ 1722, 0, 0, 1722, 1723, 1723, 0, 1723, 1724, 1724,
+ 1725, 1725, 0, 0, 1725, 1726, 1726, 1726, 1727, 1727,
+ 1727, 1728, 1728, 0, 1728, 1729, 0, 1729, 1730, 0,
+ 0, 1730, 1731, 1731, 0, 1731, 1732, 1732, 0, 0,
+ 1732, 1733, 1733, 0, 1733, 1734, 1734, 1735, 1735, 0,
+ 0, 1735, 1736, 1736, 1736, 1737, 1737, 1737, 1738, 1738,
+ 0, 1738, 1739, 0, 1739, 1740, 0, 0, 1740, 1741,
+ 1741, 0, 1741, 1742, 1742, 0, 0, 1742, 1743, 1743,
+ 0, 1743, 1744, 1744, 1745, 1745, 0, 0, 1745, 1746,
+ 1746, 1746, 1747, 1747, 1747, 1748, 1748, 0, 1748, 1749,
+
+ 0, 1749, 1750, 0, 1750, 1751, 0, 1751, 1752, 1752,
+ 1752, 1753, 0, 1753, 1754, 1754, 1754, 1755, 0, 1755,
+ 1756, 1756, 1756, 0, 1756, 1756, 1757, 0, 1757, 1758,
+ 1758, 1758, 1759, 0, 1759, 1760, 1760, 1760, 1761, 0,
+ 1761, 1762, 1762, 1762, 1763, 0, 1763, 1764, 1764, 1764,
+ 1765, 0, 1765, 1766, 1766, 1766, 1767, 0, 1767, 1768,
+ 1768, 1768, 1769, 1769, 0, 0, 1769, 1770, 1770, 1770,
+ 1771, 1771, 1771, 1772, 1772, 1772, 1773, 1773, 0, 1773,
+ 1774, 1774, 1774, 1775, 0, 1775, 1776, 1776, 1776, 1777,
+ 1777, 1777, 1778, 0, 1778, 1779, 0, 1779, 1780, 1780,
+
+ 1780, 1781, 1781, 1781, 1782, 0, 1782, 1783, 0, 1783,
+ 1784, 0, 1784, 1785, 1785, 1785, 1786, 1786, 1786, 1787,
+ 0, 1787, 1788, 0, 1788, 1789, 0, 1789, 1790, 1790,
+ 1790, 1791, 1791, 1791, 1792, 0, 1792, 1793, 0, 1793,
+ 1794, 0, 1794, 1795, 1795, 1795, 1796, 1796, 1796, 1797,
+ 0, 1797, 1798, 0, 0, 1798, 1799, 1799, 0, 1799,
+ 1800, 1800, 0, 0, 1800, 1801, 1801, 0, 1801, 1802,
+ 1802, 1803, 1803, 0, 0, 1803, 1804, 1804, 1804, 1805,
+ 0, 1805, 1806, 1806, 0, 1806, 1807, 1807, 1807, 0,
+ 1807, 1807, 1808, 1808, 1808, 1809, 1809, 1809, 1810, 0,
+
+ 1810, 1811, 0, 1811, 1812, 0, 1812, 1813, 0, 1813,
+ 1814, 0, 1814, 1815, 0, 1815, 1816, 0, 1816, 1817,
+ 1817, 1817, 1818, 1818, 1818, 1819, 0, 1819, 1820, 1820,
+ 0, 0, 1820, 1821, 1821, 0, 1821, 1822, 1822, 1823,
+ 0, 1823, 1824, 0, 0, 1824, 1825, 1825, 0, 1825,
+ 1826, 1826, 0, 0, 1826, 1827, 1827, 0, 1827, 1828,
+ 1828, 1829, 0, 1829, 1830, 0, 1830, 1831, 0, 0,
+ 1831, 1832, 1832, 0, 1832, 1833, 1833, 0, 0, 1833,
+ 1834, 1834, 0, 1834, 1835, 1835, 1836, 0, 1836, 1837,
+ 0, 1837, 1838, 0, 0, 1838, 1839, 1839, 0, 1839,
+
+ 1840, 1840, 0, 0, 1840, 1841, 1841, 0, 1841, 1842,
+ 1842, 1843, 0, 1843, 1844, 0, 1844, 1845, 0, 0,
+ 1845, 1846, 1846, 0, 1846, 1847, 1847, 0, 0, 1847,
+ 1848, 1848, 0, 1848, 1849, 1849, 1850, 0, 1850, 1851,
+ 0, 1851, 1852, 0, 1852, 1853, 0, 1853, 1854, 1854,
+ 1854, 1855, 0, 1855, 1856, 1856, 1856, 0, 1856, 1856,
+ 1857, 0, 1857, 1858, 0, 1858, 1859, 0, 1859, 1860,
+ 0, 1860, 1861, 0, 1861, 1862, 0, 1862, 1863, 0,
+ 1863, 1864, 1864, 0, 0, 1864, 1865, 1865, 0, 1865,
+ 1866, 1866, 1867, 0, 1867, 1868, 0, 1868, 1869, 0,
+
+ 1869, 1870, 0, 1870, 1871, 0, 1871, 1872, 0, 1872,
+ 1873, 0, 1873, 1874, 0, 1874, 1875, 0, 1875, 1876,
+ 0, 1876, 1877, 0, 0, 1877, 1878, 1878, 0, 0,
+ 1878, 1879, 0, 1879, 1880, 0, 1880, 1881, 0, 1881,
+ 1882, 0, 0, 1882, 1883, 0, 0, 1883, 1884, 0,
+ 0, 1884, 1885, 0, 0, 1885, 1886, 0, 0, 1886,
+ 1887, 0, 1887, 1888, 0, 1888, 1889, 0, 0, 1889,
+ 1890, 0, 1890, 1891, 0, 1891, 1892, 0, 1892, 1893,
+ 0, 1893, 1894, 0, 1894, 1895, 0, 0, 1895, 1896,
+ 0, 1896, 1897, 0, 1897, 1437, 1437, 1437, 1437, 1437,
+
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437,
+ 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437, 1437
+ } ;
+
+static yy_state_type yy_last_accepting_state;
+static char *yy_last_accepting_cpos;
+
+extern int pcap_flex_debug;
+int pcap_flex_debug = 0;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *pcaptext;
+#line 1 "../../freebsd/contrib/libpcap/scanner.l"
+#line 2 "../../freebsd/contrib/libpcap/scanner.l"
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.112 2008-02-06 10:21:30 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <sys/types.h>
+#endif /* WIN32 */
+
+#include <ctype.h>
+#include <string.h>
+
+#include "pcap-int.h"
+
+#include "gencode.h"
+#ifdef INET6
+#ifdef WIN32
+#include <pcap-stdinc.h>
+
+#ifdef __MINGW32__
+#include "ip6_misc.h"
+#endif
+#else /* WIN32 */
+#include <sys/socket.h> /* for "struct sockaddr" in "struct addrinfo" */
+#include <netdb.h> /* for "struct addrinfo" */
+#endif /* WIN32 */
+
+/* Workaround for AIX 4.3 */
+#if !defined(AI_NUMERICHOST)
+#define AI_NUMERICHOST 0x04
+#endif
+#endif /*INET6*/
+#include <pcap/namedb.h>
+#include "tokdefs.h"
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+static int stoi(char *);
+static inline int xdtoi(int);
+
+#ifdef FLEX_SCANNER
+#define YY_NO_INPUT
+#define YY_NO_UNPUT
+static YY_BUFFER_STATE in_buffer;
+#else
+static const char *in_buffer;
+
+#undef getc
+#define getc(fp) (*in_buffer == 0 ? EOF : *in_buffer++)
+#endif
+
+extern YYSTYPE yylval;
+
+#line 2788 "<stdout>"
+
+#define INITIAL 0
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int pcaplex_destroy (void );
+
+int pcapget_debug (void );
+
+void pcapset_debug (int debug_flag );
+
+YY_EXTRA_TYPE pcapget_extra (void );
+
+void pcapset_extra (YY_EXTRA_TYPE user_defined );
+
+FILE *pcapget_in (void );
+
+void pcapset_in (FILE * in_str );
+
+FILE *pcapget_out (void );
+
+void pcapset_out (FILE * out_str );
+
+yy_size_t pcapget_leng (void );
+
+char *pcapget_text (void );
+
+int pcapget_lineno (void );
+
+void pcapset_lineno (int line_number );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int pcapwrap (void );
+#else
+extern int pcapwrap (void );
+#endif
+#endif
+
+#ifndef YY_NO_UNPUT
+ static void yyunput (int c,char *buf_ptr );
+#endif
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( pcaptext, pcapleng, 1, pcapout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ size_t n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( pcapin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( pcapin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, pcapin))==0 && ferror(pcapin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(pcapin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int pcaplex (void);
+
+#define YY_DECL int pcaplex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after pcaptext and pcapleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ yy_state_type yy_current_state;
+ char *yy_cp, *yy_bp;
+ int yy_act;
+
+#line 190 "../../freebsd/contrib/libpcap/scanner.l"
+
+#line 2974 "<stdout>"
+
+ if ( !(yy_init) )
+ {
+ (yy_init) = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! (yy_start) )
+ (yy_start) = 1; /* first start state */
+
+ if ( ! pcapin )
+ pcapin = stdin;
+
+ if ( ! pcapout )
+ pcapout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ pcapensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ pcap_create_buffer(pcapin,YY_BUF_SIZE );
+ }
+
+ pcap_load_buffer_state( );
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = (yy_c_buf_p);
+
+ /* Support of pcaptext. */
+ *yy_cp = (yy_hold_char);
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = (yy_start);
+yy_match:
+ do
+ {
+ YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 1438 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 7396 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = (yy_hold_char);
+ yy_cp = (yy_last_accepting_cpos);
+ yy_current_state = (yy_last_accepting_state);
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 191 "../../freebsd/contrib/libpcap/scanner.l"
+return DST;
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 192 "../../freebsd/contrib/libpcap/scanner.l"
+return SRC;
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 194 "../../freebsd/contrib/libpcap/scanner.l"
+return LINK;
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 195 "../../freebsd/contrib/libpcap/scanner.l"
+return LINK;
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 196 "../../freebsd/contrib/libpcap/scanner.l"
+return ARP;
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 197 "../../freebsd/contrib/libpcap/scanner.l"
+return RARP;
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 198 "../../freebsd/contrib/libpcap/scanner.l"
+return IP;
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 199 "../../freebsd/contrib/libpcap/scanner.l"
+return SCTP;
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 200 "../../freebsd/contrib/libpcap/scanner.l"
+return TCP;
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 201 "../../freebsd/contrib/libpcap/scanner.l"
+return UDP;
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 202 "../../freebsd/contrib/libpcap/scanner.l"
+return ICMP;
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 203 "../../freebsd/contrib/libpcap/scanner.l"
+return IGMP;
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 204 "../../freebsd/contrib/libpcap/scanner.l"
+return IGRP;
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 205 "../../freebsd/contrib/libpcap/scanner.l"
+return PIM;
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 206 "../../freebsd/contrib/libpcap/scanner.l"
+return VRRP;
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 207 "../../freebsd/contrib/libpcap/scanner.l"
+return CARP;
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 208 "../../freebsd/contrib/libpcap/scanner.l"
+return RADIO;
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 210 "../../freebsd/contrib/libpcap/scanner.l"
+return IPV6;
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 211 "../../freebsd/contrib/libpcap/scanner.l"
+return ICMPV6;
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 212 "../../freebsd/contrib/libpcap/scanner.l"
+return AH;
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 213 "../../freebsd/contrib/libpcap/scanner.l"
+return ESP;
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 215 "../../freebsd/contrib/libpcap/scanner.l"
+return ATALK;
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 216 "../../freebsd/contrib/libpcap/scanner.l"
+return AARP;
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 217 "../../freebsd/contrib/libpcap/scanner.l"
+return DECNET;
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 218 "../../freebsd/contrib/libpcap/scanner.l"
+return LAT;
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 219 "../../freebsd/contrib/libpcap/scanner.l"
+return SCA;
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 220 "../../freebsd/contrib/libpcap/scanner.l"
+return MOPRC;
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 221 "../../freebsd/contrib/libpcap/scanner.l"
+return MOPDL;
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 223 "../../freebsd/contrib/libpcap/scanner.l"
+return ISO;
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 224 "../../freebsd/contrib/libpcap/scanner.l"
+return ESIS;
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 225 "../../freebsd/contrib/libpcap/scanner.l"
+return ESIS;
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 226 "../../freebsd/contrib/libpcap/scanner.l"
+return ISIS;
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 227 "../../freebsd/contrib/libpcap/scanner.l"
+return ISIS;
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 228 "../../freebsd/contrib/libpcap/scanner.l"
+return L1;
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 229 "../../freebsd/contrib/libpcap/scanner.l"
+return L2;
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 230 "../../freebsd/contrib/libpcap/scanner.l"
+return IIH;
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 231 "../../freebsd/contrib/libpcap/scanner.l"
+return LSP;
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 232 "../../freebsd/contrib/libpcap/scanner.l"
+return SNP;
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 233 "../../freebsd/contrib/libpcap/scanner.l"
+return CSNP;
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 234 "../../freebsd/contrib/libpcap/scanner.l"
+return PSNP;
+ YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 236 "../../freebsd/contrib/libpcap/scanner.l"
+return CLNP;
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 238 "../../freebsd/contrib/libpcap/scanner.l"
+return STP;
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 240 "../../freebsd/contrib/libpcap/scanner.l"
+return IPX;
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 242 "../../freebsd/contrib/libpcap/scanner.l"
+return NETBEUI;
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 244 "../../freebsd/contrib/libpcap/scanner.l"
+return HOST;
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 245 "../../freebsd/contrib/libpcap/scanner.l"
+return NET;
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 246 "../../freebsd/contrib/libpcap/scanner.l"
+return NETMASK;
+ YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 247 "../../freebsd/contrib/libpcap/scanner.l"
+return PORT;
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 248 "../../freebsd/contrib/libpcap/scanner.l"
+return PORTRANGE;
+ YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 249 "../../freebsd/contrib/libpcap/scanner.l"
+return PROTO;
+ YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 250 "../../freebsd/contrib/libpcap/scanner.l"
+{
+#ifdef NO_PROTOCHAIN
+ bpf_error("%s not supported", pcaptext);
+#else
+ return PROTOCHAIN;
+#endif
+ }
+ YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 258 "../../freebsd/contrib/libpcap/scanner.l"
+return GATEWAY;
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 260 "../../freebsd/contrib/libpcap/scanner.l"
+return TYPE;
+ YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 261 "../../freebsd/contrib/libpcap/scanner.l"
+return SUBTYPE;
+ YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 262 "../../freebsd/contrib/libpcap/scanner.l"
+return DIR;
+ YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 263 "../../freebsd/contrib/libpcap/scanner.l"
+return ADDR1;
+ YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 264 "../../freebsd/contrib/libpcap/scanner.l"
+return ADDR2;
+ YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 265 "../../freebsd/contrib/libpcap/scanner.l"
+return ADDR3;
+ YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 266 "../../freebsd/contrib/libpcap/scanner.l"
+return ADDR4;
+ YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 267 "../../freebsd/contrib/libpcap/scanner.l"
+return RA;
+ YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 268 "../../freebsd/contrib/libpcap/scanner.l"
+return TA;
+ YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 270 "../../freebsd/contrib/libpcap/scanner.l"
+return LESS;
+ YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 271 "../../freebsd/contrib/libpcap/scanner.l"
+return GREATER;
+ YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 272 "../../freebsd/contrib/libpcap/scanner.l"
+return CBYTE;
+ YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 273 "../../freebsd/contrib/libpcap/scanner.l"
+return TK_BROADCAST;
+ YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 274 "../../freebsd/contrib/libpcap/scanner.l"
+return TK_MULTICAST;
+ YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 276 "../../freebsd/contrib/libpcap/scanner.l"
+return AND;
+ YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 277 "../../freebsd/contrib/libpcap/scanner.l"
+return OR;
+ YY_BREAK
+case 69:
+YY_RULE_SETUP
+#line 278 "../../freebsd/contrib/libpcap/scanner.l"
+return '!';
+ YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 280 "../../freebsd/contrib/libpcap/scanner.l"
+return LEN;
+ YY_BREAK
+case 71:
+YY_RULE_SETUP
+#line 281 "../../freebsd/contrib/libpcap/scanner.l"
+return INBOUND;
+ YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 282 "../../freebsd/contrib/libpcap/scanner.l"
+return OUTBOUND;
+ YY_BREAK
+case 73:
+YY_RULE_SETUP
+#line 284 "../../freebsd/contrib/libpcap/scanner.l"
+return VLAN;
+ YY_BREAK
+case 74:
+YY_RULE_SETUP
+#line 285 "../../freebsd/contrib/libpcap/scanner.l"
+return MPLS;
+ YY_BREAK
+case 75:
+YY_RULE_SETUP
+#line 286 "../../freebsd/contrib/libpcap/scanner.l"
+return PPPOED;
+ YY_BREAK
+case 76:
+YY_RULE_SETUP
+#line 287 "../../freebsd/contrib/libpcap/scanner.l"
+return PPPOES;
+ YY_BREAK
+case 77:
+YY_RULE_SETUP
+#line 289 "../../freebsd/contrib/libpcap/scanner.l"
+return LANE;
+ YY_BREAK
+case 78:
+YY_RULE_SETUP
+#line 290 "../../freebsd/contrib/libpcap/scanner.l"
+return LLC;
+ YY_BREAK
+case 79:
+YY_RULE_SETUP
+#line 291 "../../freebsd/contrib/libpcap/scanner.l"
+return METAC;
+ YY_BREAK
+case 80:
+YY_RULE_SETUP
+#line 292 "../../freebsd/contrib/libpcap/scanner.l"
+return BCC;
+ YY_BREAK
+case 81:
+YY_RULE_SETUP
+#line 293 "../../freebsd/contrib/libpcap/scanner.l"
+return OAM;
+ YY_BREAK
+case 82:
+YY_RULE_SETUP
+#line 294 "../../freebsd/contrib/libpcap/scanner.l"
+return OAMF4;
+ YY_BREAK
+case 83:
+YY_RULE_SETUP
+#line 295 "../../freebsd/contrib/libpcap/scanner.l"
+return OAMF4EC;
+ YY_BREAK
+case 84:
+YY_RULE_SETUP
+#line 296 "../../freebsd/contrib/libpcap/scanner.l"
+return OAMF4SC;
+ YY_BREAK
+case 85:
+YY_RULE_SETUP
+#line 297 "../../freebsd/contrib/libpcap/scanner.l"
+return SC;
+ YY_BREAK
+case 86:
+YY_RULE_SETUP
+#line 298 "../../freebsd/contrib/libpcap/scanner.l"
+return ILMIC;
+ YY_BREAK
+case 87:
+YY_RULE_SETUP
+#line 299 "../../freebsd/contrib/libpcap/scanner.l"
+return VPI;
+ YY_BREAK
+case 88:
+YY_RULE_SETUP
+#line 300 "../../freebsd/contrib/libpcap/scanner.l"
+return VCI;
+ YY_BREAK
+case 89:
+YY_RULE_SETUP
+#line 301 "../../freebsd/contrib/libpcap/scanner.l"
+return CONNECTMSG;
+ YY_BREAK
+case 90:
+YY_RULE_SETUP
+#line 302 "../../freebsd/contrib/libpcap/scanner.l"
+return METACONNECT;
+ YY_BREAK
+case 91:
+YY_RULE_SETUP
+#line 304 "../../freebsd/contrib/libpcap/scanner.l"
+return PF_IFNAME;
+ YY_BREAK
+case 92:
+YY_RULE_SETUP
+#line 305 "../../freebsd/contrib/libpcap/scanner.l"
+return PF_RSET;
+ YY_BREAK
+case 93:
+YY_RULE_SETUP
+#line 306 "../../freebsd/contrib/libpcap/scanner.l"
+return PF_RNR;
+ YY_BREAK
+case 94:
+YY_RULE_SETUP
+#line 307 "../../freebsd/contrib/libpcap/scanner.l"
+return PF_SRNR;
+ YY_BREAK
+case 95:
+YY_RULE_SETUP
+#line 308 "../../freebsd/contrib/libpcap/scanner.l"
+return PF_REASON;
+ YY_BREAK
+case 96:
+YY_RULE_SETUP
+#line 309 "../../freebsd/contrib/libpcap/scanner.l"
+return PF_ACTION;
+ YY_BREAK
+case 97:
+YY_RULE_SETUP
+#line 311 "../../freebsd/contrib/libpcap/scanner.l"
+return FISU;
+ YY_BREAK
+case 98:
+YY_RULE_SETUP
+#line 312 "../../freebsd/contrib/libpcap/scanner.l"
+return LSSU;
+ YY_BREAK
+case 99:
+YY_RULE_SETUP
+#line 313 "../../freebsd/contrib/libpcap/scanner.l"
+return LSSU;
+ YY_BREAK
+case 100:
+YY_RULE_SETUP
+#line 314 "../../freebsd/contrib/libpcap/scanner.l"
+return MSU;
+ YY_BREAK
+case 101:
+YY_RULE_SETUP
+#line 315 "../../freebsd/contrib/libpcap/scanner.l"
+return SIO;
+ YY_BREAK
+case 102:
+YY_RULE_SETUP
+#line 316 "../../freebsd/contrib/libpcap/scanner.l"
+return OPC;
+ YY_BREAK
+case 103:
+YY_RULE_SETUP
+#line 317 "../../freebsd/contrib/libpcap/scanner.l"
+return DPC;
+ YY_BREAK
+case 104:
+YY_RULE_SETUP
+#line 318 "../../freebsd/contrib/libpcap/scanner.l"
+return SLS;
+ YY_BREAK
+case 105:
+/* rule 105 can match eol */
+YY_RULE_SETUP
+#line 320 "../../freebsd/contrib/libpcap/scanner.l"
+;
+ YY_BREAK
+case 106:
+YY_RULE_SETUP
+#line 321 "../../freebsd/contrib/libpcap/scanner.l"
+return pcaptext[0];
+ YY_BREAK
+case 107:
+YY_RULE_SETUP
+#line 322 "../../freebsd/contrib/libpcap/scanner.l"
+return GEQ;
+ YY_BREAK
+case 108:
+YY_RULE_SETUP
+#line 323 "../../freebsd/contrib/libpcap/scanner.l"
+return LEQ;
+ YY_BREAK
+case 109:
+YY_RULE_SETUP
+#line 324 "../../freebsd/contrib/libpcap/scanner.l"
+return NEQ;
+ YY_BREAK
+case 110:
+YY_RULE_SETUP
+#line 325 "../../freebsd/contrib/libpcap/scanner.l"
+return '=';
+ YY_BREAK
+case 111:
+YY_RULE_SETUP
+#line 326 "../../freebsd/contrib/libpcap/scanner.l"
+return LSH;
+ YY_BREAK
+case 112:
+YY_RULE_SETUP
+#line 327 "../../freebsd/contrib/libpcap/scanner.l"
+return RSH;
+ YY_BREAK
+case 113:
+YY_RULE_SETUP
+#line 328 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.e = pcap_ether_aton(((char *)pcaptext)+1);
+ return AID; }
+ YY_BREAK
+case 114:
+YY_RULE_SETUP
+#line 330 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.e = pcap_ether_aton((char *)pcaptext);
+ return EID; }
+ YY_BREAK
+case 115:
+YY_RULE_SETUP
+#line 332 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = stoi((char *)pcaptext); return NUM; }
+ YY_BREAK
+case 116:
+YY_RULE_SETUP
+#line 333 "../../freebsd/contrib/libpcap/scanner.l"
+{
+ yylval.s = sdup((char *)pcaptext); return HID; }
+ YY_BREAK
+case 117:
+YY_RULE_SETUP
+#line 335 "../../freebsd/contrib/libpcap/scanner.l"
+{
+#ifdef INET6
+ struct addrinfo hints, *res;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET6;
+ hints.ai_flags = AI_NUMERICHOST;
+ if (getaddrinfo(pcaptext, NULL, &hints, &res))
+ bpf_error("bogus IPv6 address %s", pcaptext);
+ else {
+ freeaddrinfo(res);
+ yylval.s = sdup((char *)pcaptext); return HID6;
+ }
+#else
+ bpf_error("IPv6 address %s not supported", pcaptext);
+#endif /*INET6*/
+ }
+ YY_BREAK
+case 118:
+YY_RULE_SETUP
+#line 351 "../../freebsd/contrib/libpcap/scanner.l"
+{ bpf_error("bogus ethernet address %s", pcaptext); }
+ YY_BREAK
+case 119:
+YY_RULE_SETUP
+#line 352 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 0; return NUM; }
+ YY_BREAK
+case 120:
+YY_RULE_SETUP
+#line 353 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 1; return NUM; }
+ YY_BREAK
+case 121:
+YY_RULE_SETUP
+#line 354 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 0; return NUM; }
+ YY_BREAK
+case 122:
+YY_RULE_SETUP
+#line 355 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 3; return NUM; }
+ YY_BREAK
+case 123:
+YY_RULE_SETUP
+#line 356 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 4; return NUM; }
+ YY_BREAK
+case 124:
+YY_RULE_SETUP
+#line 357 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 5; return NUM; }
+ YY_BREAK
+case 125:
+YY_RULE_SETUP
+#line 358 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 8; return NUM; }
+ YY_BREAK
+case 126:
+YY_RULE_SETUP
+#line 359 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 9; return NUM; }
+ YY_BREAK
+case 127:
+YY_RULE_SETUP
+#line 360 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 10; return NUM; }
+ YY_BREAK
+case 128:
+YY_RULE_SETUP
+#line 361 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 11; return NUM; }
+ YY_BREAK
+case 129:
+YY_RULE_SETUP
+#line 362 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 12; return NUM; }
+ YY_BREAK
+case 130:
+YY_RULE_SETUP
+#line 363 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 13; return NUM; }
+ YY_BREAK
+case 131:
+YY_RULE_SETUP
+#line 364 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 14; return NUM; }
+ YY_BREAK
+case 132:
+YY_RULE_SETUP
+#line 365 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 15; return NUM; }
+ YY_BREAK
+case 133:
+YY_RULE_SETUP
+#line 366 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 16; return NUM; }
+ YY_BREAK
+case 134:
+YY_RULE_SETUP
+#line 367 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 17; return NUM; }
+ YY_BREAK
+case 135:
+YY_RULE_SETUP
+#line 368 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 18; return NUM; }
+ YY_BREAK
+case 136:
+YY_RULE_SETUP
+#line 369 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 13; return NUM; }
+ YY_BREAK
+case 137:
+YY_RULE_SETUP
+#line 370 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 0x01; return NUM; }
+ YY_BREAK
+case 138:
+YY_RULE_SETUP
+#line 371 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 0x02; return NUM; }
+ YY_BREAK
+case 139:
+YY_RULE_SETUP
+#line 372 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 0x04; return NUM; }
+ YY_BREAK
+case 140:
+YY_RULE_SETUP
+#line 373 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 0x08; return NUM; }
+ YY_BREAK
+case 141:
+YY_RULE_SETUP
+#line 374 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 0x10; return NUM; }
+ YY_BREAK
+case 142:
+YY_RULE_SETUP
+#line 375 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.i = 0x20; return NUM; }
+ YY_BREAK
+case 143:
+YY_RULE_SETUP
+#line 376 "../../freebsd/contrib/libpcap/scanner.l"
+{
+ yylval.s = sdup((char *)pcaptext); return ID; }
+ YY_BREAK
+case 144:
+YY_RULE_SETUP
+#line 378 "../../freebsd/contrib/libpcap/scanner.l"
+{ yylval.s = sdup((char *)pcaptext + 1); return ID; }
+ YY_BREAK
+case 145:
+YY_RULE_SETUP
+#line 379 "../../freebsd/contrib/libpcap/scanner.l"
+{
+ bpf_error("illegal token: %s", pcaptext); }
+ YY_BREAK
+case 146:
+YY_RULE_SETUP
+#line 381 "../../freebsd/contrib/libpcap/scanner.l"
+{ bpf_error("illegal char '%c'", *pcaptext); }
+ YY_BREAK
+case 147:
+YY_RULE_SETUP
+#line 382 "../../freebsd/contrib/libpcap/scanner.l"
+ECHO;
+ YY_BREAK
+#line 3819 "<stdout>"
+case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = (yy_hold_char);
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed pcapin at a new source and called
+ * pcaplex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = pcapin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++(yy_c_buf_p);
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = (yy_c_buf_p);
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ (yy_did_buffer_switch_on_eof) = 0;
+
+ if ( pcapwrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * pcaptext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ (yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of pcaplex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+ char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ char *source = (yytext_ptr);
+ int number_to_move, i;
+ int ret_val;
+
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+ else
+ {
+ yy_size_t num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER_LVALUE;
+
+ int yy_c_buf_p_offset =
+ (int) ((yy_c_buf_p) - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ yy_size_t new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ pcaprealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ (yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ if ( (yy_n_chars) == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ pcaprestart(pcapin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) pcaprealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (void)
+{
+ yy_state_type yy_current_state;
+ char *yy_cp;
+
+ yy_current_state = (yy_start);
+
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+ {
+ YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 1438 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+{
+ int yy_is_jam;
+ char *yy_cp = (yy_c_buf_p);
+
+ YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ (yy_last_accepting_state) = yy_current_state;
+ (yy_last_accepting_cpos) = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 1438 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 1437);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+#ifndef YY_NO_UNPUT
+ static void yyunput (int c, char * yy_bp )
+{
+ char *yy_cp;
+
+ yy_cp = (yy_c_buf_p);
+
+ /* undo effects of setting up pcaptext */
+ *yy_cp = (yy_hold_char);
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ yy_size_t number_to_move = (yy_n_chars) + 2;
+ char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+ (yytext_ptr) = yy_bp;
+ (yy_hold_char) = *yy_cp;
+ (yy_c_buf_p) = yy_cp;
+}
+#endif /* ifndef YY_NO_UNPUT */
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (void)
+#else
+ static int input (void)
+#endif
+
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
+
+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ /* This was really a NUL. */
+ *(yy_c_buf_p) = '\0';
+
+ else
+ { /* need more input */
+ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
+ ++(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ pcaprestart(pcapin );
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( pcapwrap( ) )
+ return EOF;
+
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) = (yytext_ptr) + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
+ *(yy_c_buf_p) = '\0'; /* preserve pcaptext */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void pcaprestart (FILE * input_file )
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ pcapensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ pcap_create_buffer(pcapin,YY_BUF_SIZE );
+ }
+
+ pcap_init_buffer(YY_CURRENT_BUFFER,input_file );
+ pcap_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+ void pcap_switch_to_buffer (YY_BUFFER_STATE new_buffer )
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * pcappop_buffer_state();
+ * pcappush_buffer_state(new_buffer);
+ */
+ pcapensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ pcap_load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (pcapwrap()) processing, but the only time this flag
+ * is looked at is after pcapwrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void pcap_load_buffer_state (void)
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ pcapin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE pcap_create_buffer (FILE * file, int size )
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) pcapalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in pcap_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) pcapalloc(b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in pcap_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ pcap_init_buffer(b,file );
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with pcap_create_buffer()
+ *
+ */
+ void pcap_delete_buffer (YY_BUFFER_STATE b )
+{
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ pcapfree((void *) b->yy_ch_buf );
+
+ pcapfree((void *) b );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a pcaprestart() or at EOF.
+ */
+ static void pcap_init_buffer (YY_BUFFER_STATE b, FILE * file )
+
+{
+ int oerrno = errno;
+
+ pcap_flush_buffer(b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then pcap_init_buffer was _probably_
+ * called from pcaprestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+ void pcap_flush_buffer (YY_BUFFER_STATE b )
+{
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ pcap_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+void pcappush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+ if (new_buffer == NULL)
+ return;
+
+ pcapensure_buffer_stack();
+
+ /* This block is copied from pcap_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from pcap_switch_to_buffer. */
+ pcap_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+void pcappop_buffer_state (void)
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ pcap_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ pcap_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void pcapensure_buffer_stack (void)
+{
+ yy_size_t num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ (yy_buffer_stack) = (struct yy_buffer_state**)pcapalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in pcapensure_buffer_stack()" );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
+
+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)pcaprealloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in pcapensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE pcap_scan_buffer (char * base, yy_size_t size )
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) pcapalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in pcap_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ pcap_switch_to_buffer(b );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to pcaplex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * pcap_scan_bytes() instead.
+ */
+YY_BUFFER_STATE pcap_scan_string (yyconst char * yystr )
+{
+
+ return pcap_scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to pcaplex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE pcap_scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len )
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ yy_size_t i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = _yybytes_len + 2;
+ buf = (char *) pcapalloc(n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in pcap_scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = pcap_scan_buffer(buf,n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in pcap_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up pcaptext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ pcaptext[pcapleng] = (yy_hold_char); \
+ (yy_c_buf_p) = pcaptext + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ pcapleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ *
+ */
+int pcapget_lineno (void)
+{
+
+ return pcaplineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *pcapget_in (void)
+{
+ return pcapin;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *pcapget_out (void)
+{
+ return pcapout;
+}
+
+/** Get the length of the current token.
+ *
+ */
+yy_size_t pcapget_leng (void)
+{
+ return pcapleng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *pcapget_text (void)
+{
+ return pcaptext;
+}
+
+/** Set the current line number.
+ * @param line_number
+ *
+ */
+void pcapset_lineno (int line_number )
+{
+
+ pcaplineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ *
+ * @see pcap_switch_to_buffer
+ */
+void pcapset_in (FILE * in_str )
+{
+ pcapin = in_str ;
+}
+
+void pcapset_out (FILE * out_str )
+{
+ pcapout = out_str ;
+}
+
+int pcapget_debug (void)
+{
+ return pcap_flex_debug;
+}
+
+void pcapset_debug (int bdebug )
+{
+ pcap_flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from pcaplex_destroy(), so don't allocate here.
+ */
+
+ (yy_buffer_stack) = 0;
+ (yy_buffer_stack_top) = 0;
+ (yy_buffer_stack_max) = 0;
+ (yy_c_buf_p) = (char *) 0;
+ (yy_init) = 0;
+ (yy_start) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ pcapin = stdin;
+ pcapout = stdout;
+#else
+ pcapin = (FILE *) 0;
+ pcapout = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * pcaplex_init()
+ */
+ return 0;
+}
+
+/* pcaplex_destroy is for both reentrant and non-reentrant scanners. */
+int pcaplex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ pcap_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ pcappop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ pcapfree((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * pcaplex() is called, initialization will occur. */
+ yy_init_globals( );
+
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+ int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+ int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *pcapalloc (yy_size_t size )
+{
+ return (void *) malloc( size );
+}
+
+void *pcaprealloc (void * ptr, yy_size_t size )
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void pcapfree (void * ptr )
+{
+ free( (char *) ptr ); /* see pcaprealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 382 "../../freebsd/contrib/libpcap/scanner.l"
+
+
+void
+lex_init(buf)
+ const char *buf;
+{
+#ifdef FLEX_SCANNER
+ in_buffer = pcap_scan_string(buf);
+#else
+ in_buffer = buf;
+#endif
+}
+
+/*
+ * Do any cleanup necessary after parsing.
+ */
+void
+lex_cleanup()
+{
+#ifdef FLEX_SCANNER
+ if (in_buffer != NULL)
+ pcap_delete_buffer(in_buffer);
+ in_buffer = NULL;
+#endif
+}
+
+/*
+ * Also define a pcapwrap. Note that if we're using flex, it will
+ * define a macro to map this identifier to pcap_wrap.
+ */
+int
+pcapwrap()
+{
+ return 1;
+}
+
+/* Hex digit to integer. */
+static inline int
+xdtoi(c)
+ register int c;
+{
+ if (isdigit(c))
+ return c - '0';
+ else if (islower(c))
+ return c - 'a' + 10;
+ else
+ return c - 'A' + 10;
+}
+
+/*
+ * Convert string to integer. Just like atoi(), but checks for
+ * preceding 0x or 0 and uses hex or octal instead of decimal.
+ */
+static int
+stoi(s)
+ char *s;
+{
+ int base = 10;
+ int n = 0;
+
+ if (*s == '0') {
+ if (s[1] == 'x' || s[1] == 'X') {
+ s += 2;
+ base = 16;
+ }
+ else {
+ base = 8;
+ s += 1;
+ }
+ }
+ while (*s)
+ n = n * base + xdtoi(*s++);
+
+ return n;
+}
+
diff --git a/freebsd/contrib/libpcap/scanner.l b/freebsd/contrib/libpcap/scanner.l
new file mode 100644
index 00000000..4879c1f3
--- /dev/null
+++ b/freebsd/contrib/libpcap/scanner.l
@@ -0,0 +1,455 @@
+%{
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/libpcap/scanner.l,v 1.112 2008-02-06 10:21:30 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <sys/types.h>
+#endif /* WIN32 */
+
+#include <ctype.h>
+#include <string.h>
+
+#include "pcap-int.h"
+
+#include "gencode.h"
+#ifdef INET6
+#ifdef WIN32
+#include <pcap-stdinc.h>
+
+#ifdef __MINGW32__
+#include "ip6_misc.h"
+#endif
+#else /* WIN32 */
+#include <sys/socket.h> /* for "struct sockaddr" in "struct addrinfo" */
+#include <netdb.h> /* for "struct addrinfo" */
+#endif /* WIN32 */
+
+/* Workaround for AIX 4.3 */
+#if !defined(AI_NUMERICHOST)
+#define AI_NUMERICHOST 0x04
+#endif
+#endif /*INET6*/
+#include <pcap/namedb.h>
+#include "tokdefs.h"
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+static int stoi(char *);
+static inline int xdtoi(int);
+
+#ifdef FLEX_SCANNER
+#define YY_NO_INPUT
+#define YY_NO_UNPUT
+static YY_BUFFER_STATE in_buffer;
+#else
+static const char *in_buffer;
+
+#undef getc
+#define getc(fp) (*in_buffer == 0 ? EOF : *in_buffer++)
+#endif
+
+extern YYSTYPE yylval;
+
+%}
+
+N ([0-9]+|(0X|0x)[0-9A-Fa-f]+)
+B ([0-9A-Fa-f][0-9A-Fa-f]?)
+B2 ([0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f][0-9A-Fa-f])
+W ([0-9A-Fa-f][0-9A-Fa-f]?[0-9A-Fa-f]?[0-9A-Fa-f]?)
+
+%a 18400
+%o 21500
+%e 7600
+%k 4550
+%p 27600
+%n 2000
+
+V680 {W}:{W}:{W}:{W}:{W}:{W}:{W}:{W}
+
+V670 ::{W}:{W}:{W}:{W}:{W}:{W}:{W}
+V671 {W}::{W}:{W}:{W}:{W}:{W}:{W}
+V672 {W}:{W}::{W}:{W}:{W}:{W}:{W}
+V673 {W}:{W}:{W}::{W}:{W}:{W}:{W}
+V674 {W}:{W}:{W}:{W}::{W}:{W}:{W}
+V675 {W}:{W}:{W}:{W}:{W}::{W}:{W}
+V676 {W}:{W}:{W}:{W}:{W}:{W}::{W}
+V677 {W}:{W}:{W}:{W}:{W}:{W}:{W}::
+
+V660 ::{W}:{W}:{W}:{W}:{W}:{W}
+V661 {W}::{W}:{W}:{W}:{W}:{W}
+V662 {W}:{W}::{W}:{W}:{W}:{W}
+V663 {W}:{W}:{W}::{W}:{W}:{W}
+V664 {W}:{W}:{W}:{W}::{W}:{W}
+V665 {W}:{W}:{W}:{W}:{W}::{W}
+V666 {W}:{W}:{W}:{W}:{W}:{W}::
+
+V650 ::{W}:{W}:{W}:{W}:{W}
+V651 {W}::{W}:{W}:{W}:{W}
+V652 {W}:{W}::{W}:{W}:{W}
+V653 {W}:{W}:{W}::{W}:{W}
+V654 {W}:{W}:{W}:{W}::{W}
+V655 {W}:{W}:{W}:{W}:{W}::
+
+V640 ::{W}:{W}:{W}:{W}
+V641 {W}::{W}:{W}:{W}
+V642 {W}:{W}::{W}:{W}
+V643 {W}:{W}:{W}::{W}
+V644 {W}:{W}:{W}:{W}::
+
+V630 ::{W}:{W}:{W}
+V631 {W}::{W}:{W}
+V632 {W}:{W}::{W}
+V633 {W}:{W}:{W}::
+
+V620 ::{W}:{W}
+V621 {W}::{W}
+V622 {W}:{W}::
+
+V610 ::{W}
+V611 {W}::
+
+V600 ::
+
+V6604 {W}:{W}:{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
+
+V6504 ::{W}:{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
+V6514 {W}::{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
+V6524 {W}:{W}::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
+V6534 {W}:{W}:{W}::{W}:{W}:{N}\.{N}\.{N}\.{N}
+V6544 {W}:{W}:{W}:{W}::{W}:{N}\.{N}\.{N}\.{N}
+V6554 {W}:{W}:{W}:{W}:{W}::{N}\.{N}\.{N}\.{N}
+
+V6404 ::{W}:{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
+V6414 {W}::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
+V6424 {W}:{W}::{W}:{W}:{N}\.{N}\.{N}\.{N}
+V6434 {W}:{W}:{W}::{W}:{N}\.{N}\.{N}\.{N}
+V6444 {W}:{W}:{W}:{W}::{N}\.{N}\.{N}\.{N}
+
+V6304 ::{W}:{W}:{W}:{N}\.{N}\.{N}\.{N}
+V6314 {W}::{W}:{W}:{N}\.{N}\.{N}\.{N}
+V6324 {W}:{W}::{W}:{N}\.{N}\.{N}\.{N}
+V6334 {W}:{W}:{W}::{N}\.{N}\.{N}\.{N}
+
+V6204 ::{W}:{W}:{N}\.{N}\.{N}\.{N}
+V6214 {W}::{W}:{N}\.{N}\.{N}\.{N}
+V6224 {W}:{W}::{N}\.{N}\.{N}\.{N}
+
+V6104 ::{W}:{N}\.{N}\.{N}\.{N}
+V6114 {W}::{N}\.{N}\.{N}\.{N}
+
+V6004 ::{N}\.{N}\.{N}\.{N}
+
+
+V6 ({V680}|{V670}|{V671}|{V672}|{V673}|{V674}|{V675}|{V676}|{V677}|{V660}|{V661}|{V662}|{V663}|{V664}|{V665}|{V666}|{V650}|{V651}|{V652}|{V653}|{V654}|{V655}|{V640}|{V641}|{V642}|{V643}|{V644}|{V630}|{V631}|{V632}|{V633}|{V620}|{V621}|{V622}|{V610}|{V611}|{V600}|{V6604}|{V6504}|{V6514}|{V6524}|{V6534}|{V6544}|{V6554}|{V6404}|{V6414}|{V6424}|{V6434}|{V6444}|{V6304}|{V6314}|{V6324}|{V6334}|{V6204}|{V6214}|{V6224}|{V6104}|{V6114}|{V6004})
+
+MAC ({B}:{B}:{B}:{B}:{B}:{B}|{B}\-{B}\-{B}\-{B}\-{B}\-{B}|{B}\.{B}\.{B}\.{B}\.{B}\.{B}|{B2}\.{B2}\.{B2}|{B2}{3})
+
+
+
+%%
+dst return DST;
+src return SRC;
+
+link|ether|ppp|slip return LINK;
+fddi|tr|wlan return LINK;
+arp return ARP;
+rarp return RARP;
+ip return IP;
+sctp return SCTP;
+tcp return TCP;
+udp return UDP;
+icmp return ICMP;
+igmp return IGMP;
+igrp return IGRP;
+pim return PIM;
+vrrp return VRRP;
+carp return CARP;
+radio return RADIO;
+
+ip6 return IPV6;
+icmp6 return ICMPV6;
+ah return AH;
+esp return ESP;
+
+atalk return ATALK;
+aarp return AARP;
+decnet return DECNET;
+lat return LAT;
+sca return SCA;
+moprc return MOPRC;
+mopdl return MOPDL;
+
+iso return ISO;
+esis return ESIS;
+es-is return ESIS;
+isis return ISIS;
+is-is return ISIS;
+l1 return L1;
+l2 return L2;
+iih return IIH;
+lsp return LSP;
+snp return SNP;
+csnp return CSNP;
+psnp return PSNP;
+
+clnp return CLNP;
+
+stp return STP;
+
+ipx return IPX;
+
+netbeui return NETBEUI;
+
+host return HOST;
+net return NET;
+mask return NETMASK;
+port return PORT;
+portrange return PORTRANGE;
+proto return PROTO;
+protochain {
+#ifdef NO_PROTOCHAIN
+ bpf_error("%s not supported", yytext);
+#else
+ return PROTOCHAIN;
+#endif
+ }
+
+gateway return GATEWAY;
+
+type return TYPE;
+subtype return SUBTYPE;
+direction|dir return DIR;
+address1|addr1 return ADDR1;
+address2|addr2 return ADDR2;
+address3|addr3 return ADDR3;
+address4|addr4 return ADDR4;
+ra return RA;
+ta return TA;
+
+less return LESS;
+greater return GREATER;
+byte return CBYTE;
+broadcast return TK_BROADCAST;
+multicast return TK_MULTICAST;
+
+and|"&&" return AND;
+or|"||" return OR;
+not return '!';
+
+len|length return LEN;
+inbound return INBOUND;
+outbound return OUTBOUND;
+
+vlan return VLAN;
+mpls return MPLS;
+pppoed return PPPOED;
+pppoes return PPPOES;
+
+lane return LANE;
+llc return LLC;
+metac return METAC;
+bcc return BCC;
+oam return OAM;
+oamf4 return OAMF4;
+oamf4ec return OAMF4EC;
+oamf4sc return OAMF4SC;
+sc return SC;
+ilmic return ILMIC;
+vpi return VPI;
+vci return VCI;
+connectmsg return CONNECTMSG;
+metaconnect return METACONNECT;
+
+on|ifname return PF_IFNAME;
+rset|ruleset return PF_RSET;
+rnr|rulenum return PF_RNR;
+srnr|subrulenum return PF_SRNR;
+reason return PF_REASON;
+action return PF_ACTION;
+
+fisu return FISU;
+lssu return LSSU;
+lsu return LSSU;
+msu return MSU;
+sio return SIO;
+opc return OPC;
+dpc return DPC;
+sls return SLS;
+
+[ \r\n\t] ;
+[+\-*/:\[\]!<>()&|=] return yytext[0];
+">=" return GEQ;
+"<=" return LEQ;
+"!=" return NEQ;
+"==" return '=';
+"<<" return LSH;
+">>" return RSH;
+${B} { yylval.e = pcap_ether_aton(((char *)yytext)+1);
+ return AID; }
+{MAC} { yylval.e = pcap_ether_aton((char *)yytext);
+ return EID; }
+{N} { yylval.i = stoi((char *)yytext); return NUM; }
+({N}\.{N})|({N}\.{N}\.{N})|({N}\.{N}\.{N}\.{N}) {
+ yylval.s = sdup((char *)yytext); return HID; }
+{V6} {
+#ifdef INET6
+ struct addrinfo hints, *res;
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET6;
+ hints.ai_flags = AI_NUMERICHOST;
+ if (getaddrinfo(yytext, NULL, &hints, &res))
+ bpf_error("bogus IPv6 address %s", yytext);
+ else {
+ freeaddrinfo(res);
+ yylval.s = sdup((char *)yytext); return HID6;
+ }
+#else
+ bpf_error("IPv6 address %s not supported", yytext);
+#endif /*INET6*/
+ }
+{B}:+({B}:+)+ { bpf_error("bogus ethernet address %s", yytext); }
+icmptype { yylval.i = 0; return NUM; }
+icmpcode { yylval.i = 1; return NUM; }
+icmp-echoreply { yylval.i = 0; return NUM; }
+icmp-unreach { yylval.i = 3; return NUM; }
+icmp-sourcequench { yylval.i = 4; return NUM; }
+icmp-redirect { yylval.i = 5; return NUM; }
+icmp-echo { yylval.i = 8; return NUM; }
+icmp-routeradvert { yylval.i = 9; return NUM; }
+icmp-routersolicit { yylval.i = 10; return NUM; }
+icmp-timxceed { yylval.i = 11; return NUM; }
+icmp-paramprob { yylval.i = 12; return NUM; }
+icmp-tstamp { yylval.i = 13; return NUM; }
+icmp-tstampreply { yylval.i = 14; return NUM; }
+icmp-ireq { yylval.i = 15; return NUM; }
+icmp-ireqreply { yylval.i = 16; return NUM; }
+icmp-maskreq { yylval.i = 17; return NUM; }
+icmp-maskreply { yylval.i = 18; return NUM; }
+tcpflags { yylval.i = 13; return NUM; }
+tcp-fin { yylval.i = 0x01; return NUM; }
+tcp-syn { yylval.i = 0x02; return NUM; }
+tcp-rst { yylval.i = 0x04; return NUM; }
+tcp-push { yylval.i = 0x08; return NUM; }
+tcp-ack { yylval.i = 0x10; return NUM; }
+tcp-urg { yylval.i = 0x20; return NUM; }
+[A-Za-z0-9]([-_.A-Za-z0-9]*[.A-Za-z0-9])? {
+ yylval.s = sdup((char *)yytext); return ID; }
+"\\"[^ !()\n\t]+ { yylval.s = sdup((char *)yytext + 1); return ID; }
+[^ \[\]\t\n\-_.A-Za-z0-9!<>()&|=]+ {
+ bpf_error("illegal token: %s", yytext); }
+. { bpf_error("illegal char '%c'", *yytext); }
+%%
+void
+lex_init(buf)
+ const char *buf;
+{
+#ifdef FLEX_SCANNER
+ in_buffer = yy_scan_string(buf);
+#else
+ in_buffer = buf;
+#endif
+}
+
+/*
+ * Do any cleanup necessary after parsing.
+ */
+void
+lex_cleanup()
+{
+#ifdef FLEX_SCANNER
+ if (in_buffer != NULL)
+ yy_delete_buffer(in_buffer);
+ in_buffer = NULL;
+#endif
+}
+
+/*
+ * Also define a yywrap. Note that if we're using flex, it will
+ * define a macro to map this identifier to pcap_wrap.
+ */
+int
+yywrap()
+{
+ return 1;
+}
+
+/* Hex digit to integer. */
+static inline int
+xdtoi(c)
+ register int c;
+{
+ if (isdigit(c))
+ return c - '0';
+ else if (islower(c))
+ return c - 'a' + 10;
+ else
+ return c - 'A' + 10;
+}
+
+/*
+ * Convert string to integer. Just like atoi(), but checks for
+ * preceding 0x or 0 and uses hex or octal instead of decimal.
+ */
+static int
+stoi(s)
+ char *s;
+{
+ int base = 10;
+ int n = 0;
+
+ if (*s == '0') {
+ if (s[1] == 'x' || s[1] == 'X') {
+ s += 2;
+ base = 16;
+ }
+ else {
+ base = 8;
+ s += 1;
+ }
+ }
+ while (*s)
+ n = n * base + xdtoi(*s++);
+
+ return n;
+}
diff --git a/freebsd/contrib/libpcap/sf-pcap-ng.c b/freebsd/contrib/libpcap/sf-pcap-ng.c
new file mode 100644
index 00000000..f2ee14cb
--- /dev/null
+++ b/freebsd/contrib/libpcap/sf-pcap-ng.c
@@ -0,0 +1,1111 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * sf-pcap-ng.c - pcap-ng-file-format-specific code from savefile.c
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header$ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <rtems/bsd/sys/types.h>
+#endif /* WIN32 */
+
+#include <errno.h>
+#include <memory.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pcap-int.h"
+
+#include "pcap-common.h"
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#include "sf-pcap-ng.h"
+
+/*
+ * Block types.
+ */
+
+/*
+ * Common part at the beginning of all blocks.
+ */
+struct block_header {
+ bpf_u_int32 block_type;
+ bpf_u_int32 total_length;
+};
+
+/*
+ * Common trailer at the end of all blocks.
+ */
+struct block_trailer {
+ bpf_u_int32 total_length;
+};
+
+/*
+ * Common options.
+ */
+#define OPT_ENDOFOPT 0 /* end of options */
+#define OPT_COMMENT 1 /* comment string */
+
+/*
+ * Option header.
+ */
+struct option_header {
+ u_short option_code;
+ u_short option_length;
+};
+
+/*
+ * Structures for the part of each block type following the common
+ * part.
+ */
+
+/*
+ * Section Header Block.
+ */
+#define BT_SHB 0x0A0D0D0A
+
+struct section_header_block {
+ bpf_u_int32 byte_order_magic;
+ u_short major_version;
+ u_short minor_version;
+ u_int64_t section_length;
+ /* followed by options and trailer */
+};
+
+/*
+ * Byte-order magic value.
+ */
+#define BYTE_ORDER_MAGIC 0x1A2B3C4D
+
+/*
+ * Current version number. If major_version isn't PCAP_NG_VERSION_MAJOR,
+ * that means that this code can't read the file.
+ */
+#define PCAP_NG_VERSION_MAJOR 1
+
+/*
+ * Interface Description Block.
+ */
+#define BT_IDB 0x00000001
+
+struct interface_description_block {
+ u_short linktype;
+ u_short reserved;
+ bpf_u_int32 snaplen;
+ /* followed by options and trailer */
+};
+
+/*
+ * Options in the IDB.
+ */
+#define IF_NAME 2 /* interface name string */
+#define IF_DESCRIPTION 3 /* interface description string */
+#define IF_IPV4ADDR 4 /* interface's IPv4 address and netmask */
+#define IF_IPV6ADDR 5 /* interface's IPv6 address and prefix length */
+#define IF_MACADDR 6 /* interface's MAC address */
+#define IF_EUIADDR 7 /* interface's EUI address */
+#define IF_SPEED 8 /* interface's speed, in bits/s */
+#define IF_TSRESOL 9 /* interface's time stamp resolution */
+#define IF_TZONE 10 /* interface's time zone */
+#define IF_FILTER 11 /* filter used when capturing on interface */
+#define IF_OS 12 /* string OS on which capture on this interface was done */
+#define IF_FCSLEN 13 /* FCS length for this interface */
+#define IF_TSOFFSET 14 /* time stamp offset for this interface */
+
+/*
+ * Enhanced Packet Block.
+ */
+#define BT_EPB 0x00000006
+
+struct enhanced_packet_block {
+ bpf_u_int32 interface_id;
+ bpf_u_int32 timestamp_high;
+ bpf_u_int32 timestamp_low;
+ bpf_u_int32 caplen;
+ bpf_u_int32 len;
+ /* followed by packet data, options, and trailer */
+};
+
+/*
+ * Simple Packet Block.
+ */
+#define BT_SPB 0x00000003
+
+struct simple_packet_block {
+ bpf_u_int32 len;
+ /* followed by packet data and trailer */
+};
+
+/*
+ * Packet Block.
+ */
+#define BT_PB 0x00000002
+
+struct packet_block {
+ u_short interface_id;
+ u_short drops_count;
+ bpf_u_int32 timestamp_high;
+ bpf_u_int32 timestamp_low;
+ bpf_u_int32 caplen;
+ bpf_u_int32 len;
+ /* followed by packet data, options, and trailer */
+};
+
+/*
+ * Block cursor - used when processing the contents of a block.
+ * Contains a pointer into the data being processed and a count
+ * of bytes remaining in the block.
+ */
+struct block_cursor {
+ u_char *data;
+ size_t data_remaining;
+ bpf_u_int32 block_type;
+};
+
+static int pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr,
+ u_char **data);
+
+static int
+read_bytes(FILE *fp, void *buf, size_t bytes_to_read, int fail_on_eof,
+ char *errbuf)
+{
+ size_t amt_read;
+
+ amt_read = fread(buf, 1, bytes_to_read, fp);
+ if (amt_read != bytes_to_read) {
+ if (ferror(fp)) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "error reading dump file: %s",
+ pcap_strerror(errno));
+ } else {
+ if (amt_read == 0 && !fail_on_eof)
+ return (0); /* EOF */
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "truncated dump file; tried to read %lu bytes, only got %lu",
+ (unsigned long)bytes_to_read,
+ (unsigned long)amt_read);
+ }
+ return (-1);
+ }
+ return (1);
+}
+
+static int
+read_block(FILE *fp, pcap_t *p, struct block_cursor *cursor, char *errbuf)
+{
+ int status;
+ struct block_header bhdr;
+
+ status = read_bytes(fp, &bhdr, sizeof(bhdr), 0, errbuf);
+ if (status <= 0)
+ return (status); /* error or EOF */
+
+ if (p->sf.swapped) {
+ bhdr.block_type = SWAPLONG(bhdr.block_type);
+ bhdr.total_length = SWAPLONG(bhdr.total_length);
+ }
+
+ /*
+ * Is this block "too big"?
+ *
+ * We choose 16MB as "too big", for now, so that we handle
+ * "reasonably" large buffers but don't chew up all the
+ * memory if we read a malformed file.
+ */
+ if (bhdr.total_length > 16*1024*1024) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "pcap-ng block size %u > maximum %u",
+ bhdr.total_length, 16*1024*1024);
+ return (-1);
+ }
+
+ /*
+ * Is this block "too small" - i.e., is it shorter than a block
+ * header plus a block trailer?
+ */
+ if (bhdr.total_length < sizeof(struct block_header) +
+ sizeof(struct block_trailer)) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "block in pcap-ng dump file has a length of %u < %lu",
+ bhdr.total_length,
+ (unsigned long)(sizeof(struct block_header) + sizeof(struct block_trailer)));
+ return (-1);
+ }
+
+ /*
+ * Is the buffer big enough?
+ */
+ if (p->bufsize < bhdr.total_length) {
+ /*
+ * No - make it big enough.
+ */
+ p->buffer = realloc(p->buffer, bhdr.total_length);
+ if (p->buffer == NULL) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory");
+ return (-1);
+ }
+ }
+
+ /*
+ * Copy the stuff we've read to the buffer, and read the rest
+ * of the block.
+ */
+ memcpy(p->buffer, &bhdr, sizeof(bhdr));
+ if (read_bytes(fp, p->buffer + sizeof(bhdr),
+ bhdr.total_length - sizeof(bhdr), 1, errbuf) == -1)
+ return (-1);
+
+ /*
+ * Initialize the cursor.
+ */
+ cursor->data = p->buffer + sizeof(bhdr);
+ cursor->data_remaining = bhdr.total_length - sizeof(bhdr) -
+ sizeof(struct block_trailer);
+ cursor->block_type = bhdr.block_type;
+ return (1);
+}
+
+static void *
+get_from_block_data(struct block_cursor *cursor, size_t chunk_size,
+ char *errbuf)
+{
+ void *data;
+
+ /*
+ * Make sure we have the specified amount of data remaining in
+ * the block data.
+ */
+ if (cursor->data_remaining < chunk_size) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "block of type %u in pcap-ng dump file is too short",
+ cursor->block_type);
+ return (NULL);
+ }
+
+ /*
+ * Return the current pointer, and skip past the chunk.
+ */
+ data = cursor->data;
+ cursor->data += chunk_size;
+ cursor->data_remaining -= chunk_size;
+ return (data);
+}
+
+static struct option_header *
+get_opthdr_from_block_data(pcap_t *p, struct block_cursor *cursor, char *errbuf)
+{
+ struct option_header *opthdr;
+
+ opthdr = get_from_block_data(cursor, sizeof(*opthdr), errbuf);
+ if (opthdr == NULL) {
+ /*
+ * Option header is cut short.
+ */
+ return (NULL);
+ }
+
+ /*
+ * Byte-swap it if necessary.
+ */
+ if (p->sf.swapped) {
+ opthdr->option_code = SWAPSHORT(opthdr->option_code);
+ opthdr->option_length = SWAPSHORT(opthdr->option_length);
+ }
+
+ return (opthdr);
+}
+
+static void *
+get_optvalue_from_block_data(struct block_cursor *cursor,
+ struct option_header *opthdr, char *errbuf)
+{
+ size_t padded_option_len;
+ void *optvalue;
+
+ /* Pad option length to 4-byte boundary */
+ padded_option_len = opthdr->option_length;
+ padded_option_len = ((padded_option_len + 3)/4)*4;
+
+ optvalue = get_from_block_data(cursor, padded_option_len, errbuf);
+ if (optvalue == NULL) {
+ /*
+ * Option value is cut short.
+ */
+ return (NULL);
+ }
+
+ return (optvalue);
+}
+
+static int
+process_idb_options(pcap_t *p, struct block_cursor *cursor, u_int *tsresol,
+ u_int64_t *tsoffset, char *errbuf)
+{
+ struct option_header *opthdr;
+ void *optvalue;
+ int saw_tsresol, saw_tsoffset;
+ u_char tsresol_opt;
+ u_int i;
+
+ saw_tsresol = 0;
+ saw_tsoffset = 0;
+ while (cursor->data_remaining != 0) {
+ /*
+ * Get the option header.
+ */
+ opthdr = get_opthdr_from_block_data(p, cursor, errbuf);
+ if (opthdr == NULL) {
+ /*
+ * Option header is cut short.
+ */
+ return (-1);
+ }
+
+ /*
+ * Get option value.
+ */
+ optvalue = get_optvalue_from_block_data(cursor, opthdr,
+ errbuf);
+ if (optvalue == NULL) {
+ /*
+ * Option value is cut short.
+ */
+ return (-1);
+ }
+
+ switch (opthdr->option_code) {
+
+ case OPT_ENDOFOPT:
+ if (opthdr->option_length != 0) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Interface Description Block has opt_endofopt option with length %u != 0",
+ opthdr->option_length);
+ return (-1);
+ }
+ goto done;
+
+ case IF_TSRESOL:
+ if (opthdr->option_length != 1) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Interface Description Block has if_tsresol option with length %u != 1",
+ opthdr->option_length);
+ return (-1);
+ }
+ if (saw_tsresol) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Interface Description Block has more than one if_tsresol option");
+ return (-1);
+ }
+ saw_tsresol = 1;
+ tsresol_opt = *(u_int *)optvalue;
+ if (tsresol_opt & 0x80) {
+ /*
+ * Resolution is negative power of 2.
+ */
+ *tsresol = 1 << (tsresol_opt & 0x7F);
+ } else {
+ /*
+ * Resolution is negative power of 10.
+ */
+ *tsresol = 1;
+ for (i = 0; i < tsresol_opt; i++)
+ *tsresol *= 10;
+ }
+ if (*tsresol == 0) {
+ /*
+ * Resolution is too high.
+ */
+ if (tsresol_opt & 0x80) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Interface Description Block if_tsresol option resolution 2^-%u is too high",
+ tsresol_opt & 0x7F);
+ } else {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Interface Description Block if_tsresol option resolution 10^-%u is too high",
+ tsresol_opt);
+ }
+ return (-1);
+ }
+ break;
+
+ case IF_TSOFFSET:
+ if (opthdr->option_length != 8) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Interface Description Block has if_tsoffset option with length %u != 8",
+ opthdr->option_length);
+ return (-1);
+ }
+ if (saw_tsoffset) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Interface Description Block has more than one if_tsoffset option");
+ return (-1);
+ }
+ saw_tsoffset = 1;
+ memcpy(tsoffset, optvalue, sizeof(*tsoffset));
+ if (p->sf.swapped)
+ *tsoffset = SWAPLL(*tsoffset);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+done:
+ return (0);
+}
+
+/*
+ * Check whether this is a pcap-ng savefile and, if it is, extract the
+ * relevant information from the header.
+ */
+int
+pcap_ng_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
+{
+ size_t amt_read;
+ bpf_u_int32 total_length;
+ bpf_u_int32 byte_order_magic;
+ struct block_header *bhdrp;
+ struct section_header_block *shbp;
+ int status;
+ struct block_cursor cursor;
+ struct interface_description_block *idbp;
+
+ /*
+ * Check whether the first 4 bytes of the file are the block
+ * type for a pcap-ng savefile.
+ */
+ if (magic != BT_SHB) {
+ /*
+ * XXX - check whether this looks like what the block
+ * type would be after being munged by mapping between
+ * UN*X and DOS/Windows text file format and, if it
+ * does, look for the byte-order magic number in
+ * the appropriate place and, if we find it, report
+ * this as possibly being a pcap-ng file transferred
+ * between UN*X and Windows in text file format?
+ */
+ return (0); /* nope */
+ }
+
+ /*
+ * OK, they are. However, that's just \n\r\r\n, so it could,
+ * conceivably, be an ordinary text file.
+ *
+ * It could not, however, conceivably be any other type of
+ * capture file, so we can read the rest of the putative
+ * Section Header Block; put the block type in the common
+ * header, read the rest of the common header and the
+ * fixed-length portion of the SHB, and look for the byte-order
+ * magic value.
+ */
+ amt_read = fread(&total_length, 1, sizeof(total_length), fp);
+ if (amt_read < sizeof(total_length)) {
+ if (ferror(fp)) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "error reading dump file: %s",
+ pcap_strerror(errno));
+ return (-1); /* fail */
+ }
+
+ /*
+ * Possibly a weird short text file, so just say
+ * "not pcap-ng".
+ */
+ return (0);
+ }
+ amt_read = fread(&byte_order_magic, 1, sizeof(byte_order_magic), fp);
+ if (amt_read < sizeof(byte_order_magic)) {
+ if (ferror(fp)) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "error reading dump file: %s",
+ pcap_strerror(errno));
+ return (-1); /* fail */
+ }
+
+ /*
+ * Possibly a weird short text file, so just say
+ * "not pcap-ng".
+ */
+ return (0);
+ }
+ if (byte_order_magic != BYTE_ORDER_MAGIC) {
+ byte_order_magic = SWAPLONG(byte_order_magic);
+ if (byte_order_magic != BYTE_ORDER_MAGIC) {
+ /*
+ * Not a pcap-ng file.
+ */
+ return (0);
+ }
+ p->sf.swapped = 1;
+ total_length = SWAPLONG(total_length);
+ }
+
+ /*
+ * Check the sanity of the total length.
+ */
+ if (total_length < sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer)) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "Section Header Block in pcap-ng dump file has a length of %u < %lu",
+ total_length,
+ (unsigned long)(sizeof(*bhdrp) + sizeof(*shbp) + sizeof(struct block_trailer)));
+ return (-1);
+ }
+
+ /*
+ * Allocate a buffer into which to read blocks. We default to
+ * the maximum of:
+ *
+ * the total length of the SHB for which we read the header;
+ *
+ * 2K, which should be more than large enough for an Enhanced
+ * Packet Block containing a full-size Ethernet frame, and
+ * leaving room for some options.
+ *
+ * If we find a bigger block, we reallocate the buffer.
+ */
+ p->bufsize = 2048;
+ if (p->bufsize < total_length)
+ p->bufsize = total_length;
+ p->buffer = malloc(p->bufsize);
+ if (p->buffer == NULL) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory");
+ return (-1);
+ }
+
+ /*
+ * Copy the stuff we've read to the buffer, and read the rest
+ * of the SHB.
+ */
+ bhdrp = (struct block_header *)p->buffer;
+ shbp = (struct section_header_block *)(p->buffer + sizeof(struct block_header));
+ bhdrp->block_type = magic;
+ bhdrp->total_length = total_length;
+ shbp->byte_order_magic = byte_order_magic;
+ if (read_bytes(fp,
+ p->buffer + (sizeof(magic) + sizeof(total_length) + sizeof(byte_order_magic)),
+ total_length - (sizeof(magic) + sizeof(total_length) + sizeof(byte_order_magic)),
+ 1, errbuf) == -1)
+ goto fail;
+
+ if (p->sf.swapped) {
+ /*
+ * Byte-swap the fields we've read.
+ */
+ shbp->major_version = SWAPSHORT(shbp->major_version);
+ shbp->minor_version = SWAPSHORT(shbp->minor_version);
+
+ /*
+ * XXX - we don't care about the section length.
+ */
+ }
+ if (shbp->major_version != PCAP_NG_VERSION_MAJOR) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "unknown pcap-ng savefile major version number %u",
+ shbp->major_version);
+ goto fail;
+ }
+ p->sf.version_major = shbp->major_version;
+ p->sf.version_minor = shbp->minor_version;
+
+ /*
+ * Set the default time stamp resolution and offset.
+ */
+ p->sf.tsresol = 1000000; /* microsecond resolution */
+ p->sf.tsscale = 1; /* multiply by 1 to scale to microseconds */
+ p->sf.tsoffset = 0; /* absolute timestamps */
+
+ /*
+ * Now start looking for an Interface Description Block.
+ */
+ for (;;) {
+ /*
+ * Read the next block.
+ */
+ status = read_block(fp, p, &cursor, errbuf);
+ if (status == 0) {
+ /* EOF - no IDB in this file */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "the capture file has no Interface Description Blocks");
+ goto fail;
+ }
+ if (status == -1)
+ goto fail; /* error */
+ switch (cursor.block_type) {
+
+ case BT_IDB:
+ /*
+ * Get a pointer to the fixed-length portion of the
+ * IDB.
+ */
+ idbp = get_from_block_data(&cursor, sizeof(*idbp),
+ errbuf);
+ if (idbp == NULL)
+ goto fail; /* error */
+
+ /*
+ * Byte-swap it if necessary.
+ */
+ if (p->sf.swapped) {
+ idbp->linktype = SWAPSHORT(idbp->linktype);
+ idbp->snaplen = SWAPLONG(idbp->snaplen);
+ }
+
+ /*
+ * Count this interface.
+ */
+ p->sf.ifcount++;
+
+ /*
+ * Now look for various time stamp options, so
+ * we know how to interpret the time stamps.
+ */
+ if (process_idb_options(p, &cursor, &p->sf.tsresol,
+ &p->sf.tsoffset, errbuf) == -1)
+ goto fail;
+
+ /*
+ * Compute the scaling factor to convert the
+ * sub-second part of the time stamp to
+ * microseconds.
+ */
+ if (p->sf.tsresol > 1000000) {
+ /*
+ * Higher than microsecond resolution;
+ * scale down to microseconds.
+ */
+ p->sf.tsscale = (p->sf.tsresol / 1000000);
+ } else {
+ /*
+ * Lower than microsecond resolution;
+ * scale up to microseconds.
+ */
+ p->sf.tsscale = (1000000 / p->sf.tsresol);
+ }
+ goto done;
+
+ case BT_EPB:
+ case BT_SPB:
+ case BT_PB:
+ /*
+ * Saw a packet before we saw any IDBs. That's
+ * not valid, as we don't know what link-layer
+ * encapsulation the packet has.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "the capture file has a packet block before any Interface Description Blocks");
+ goto fail;
+
+ default:
+ /*
+ * Just ignore it.
+ */
+ break;
+ }
+ }
+
+done:
+ p->tzoff = 0; /* XXX - not used in pcap */
+ p->snapshot = idbp->snaplen;
+ p->linktype = linktype_to_dlt(idbp->linktype);
+ p->linktype_ext = 0;
+
+ p->sf.next_packet_op = pcap_ng_next_packet;
+
+ return (1);
+
+fail:
+ free(p->buffer);
+ return (-1);
+}
+
+/*
+ * Read and return the next packet from the savefile. Return the header
+ * in hdr and a pointer to the contents in data. Return 0 on success, 1
+ * if there were no more packets, and -1 on an error.
+ */
+static int
+pcap_ng_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
+{
+ struct block_cursor cursor;
+ int status;
+ struct enhanced_packet_block *epbp;
+ struct simple_packet_block *spbp;
+ struct packet_block *pbp;
+ bpf_u_int32 interface_id = 0xFFFFFFFF;
+ struct interface_description_block *idbp;
+ struct section_header_block *shbp;
+ FILE *fp = p->sf.rfile;
+ u_int tsresol;
+ u_int64_t tsoffset;
+ u_int64_t t, sec, frac;
+
+ /*
+ * Look for an Enhanced Packet Block, a Simple Packet Block,
+ * or a Packet Block.
+ */
+ for (;;) {
+ /*
+ * Read the block type and length; those are common
+ * to all blocks.
+ */
+ status = read_block(fp, p, &cursor, p->errbuf);
+ if (status == 0)
+ return (1); /* EOF */
+ if (status == -1)
+ return (-1); /* error */
+ switch (cursor.block_type) {
+
+ case BT_EPB:
+ /*
+ * Get a pointer to the fixed-length portion of the
+ * EPB.
+ */
+ epbp = get_from_block_data(&cursor, sizeof(*epbp),
+ p->errbuf);
+ if (epbp == NULL)
+ return (-1); /* error */
+
+ /*
+ * Byte-swap it if necessary.
+ */
+ if (p->sf.swapped) {
+ /* these were written in opposite byte order */
+ interface_id = SWAPLONG(epbp->interface_id);
+ hdr->caplen = SWAPLONG(epbp->caplen);
+ hdr->len = SWAPLONG(epbp->len);
+ t = ((u_int64_t)SWAPLONG(epbp->timestamp_high)) << 32 |
+ SWAPLONG(epbp->timestamp_low);
+ } else {
+ interface_id = epbp->interface_id;
+ hdr->caplen = epbp->caplen;
+ hdr->len = epbp->len;
+ t = ((u_int64_t)epbp->timestamp_high) << 32 |
+ epbp->timestamp_low;
+ }
+ goto found;
+
+ case BT_SPB:
+ /*
+ * Get a pointer to the fixed-length portion of the
+ * SPB.
+ */
+ spbp = get_from_block_data(&cursor, sizeof(*spbp),
+ p->errbuf);
+ if (spbp == NULL)
+ return (-1); /* error */
+
+ /*
+ * SPB packets are assumed to have arrived on
+ * the first interface.
+ */
+ interface_id = 0;
+
+ /*
+ * Byte-swap it if necessary.
+ */
+ if (p->sf.swapped) {
+ /* these were written in opposite byte order */
+ hdr->len = SWAPLONG(spbp->len);
+ } else
+ hdr->len = spbp->len;
+
+ /*
+ * The SPB doesn't give the captured length;
+ * it's the minimum of the snapshot length
+ * and the packet length.
+ */
+ hdr->caplen = hdr->len;
+ if (hdr->caplen > p->snapshot)
+ hdr->caplen = p->snapshot;
+ t = 0; /* no time stamps */
+ goto found;
+
+ case BT_PB:
+ /*
+ * Get a pointer to the fixed-length portion of the
+ * PB.
+ */
+ pbp = get_from_block_data(&cursor, sizeof(*pbp),
+ p->errbuf);
+ if (pbp == NULL)
+ return (-1); /* error */
+
+ /*
+ * Byte-swap it if necessary.
+ */
+ if (p->sf.swapped) {
+ /* these were written in opposite byte order */
+ interface_id = SWAPSHORT(pbp->interface_id);
+ hdr->caplen = SWAPLONG(pbp->caplen);
+ hdr->len = SWAPLONG(pbp->len);
+ t = ((u_int64_t)SWAPLONG(pbp->timestamp_high)) << 32 |
+ SWAPLONG(pbp->timestamp_low);
+ } else {
+ interface_id = pbp->interface_id;
+ hdr->caplen = pbp->caplen;
+ hdr->len = pbp->len;
+ t = ((u_int64_t)pbp->timestamp_high) << 32 |
+ pbp->timestamp_low;
+ }
+ goto found;
+
+ case BT_IDB:
+ /*
+ * Interface Description Block. Get a pointer
+ * to its fixed-length portion.
+ */
+ idbp = get_from_block_data(&cursor, sizeof(*idbp),
+ p->errbuf);
+ if (idbp == NULL)
+ return (-1); /* error */
+
+ /*
+ * Byte-swap it if necessary.
+ */
+ if (p->sf.swapped) {
+ idbp->linktype = SWAPSHORT(idbp->linktype);
+ idbp->snaplen = SWAPLONG(idbp->snaplen);
+ }
+
+ /*
+ * If the link-layer type or snapshot length
+ * differ from the ones for the first IDB we
+ * saw, quit.
+ *
+ * XXX - just discard packets from those
+ * interfaces?
+ */
+ if (p->linktype != idbp->linktype) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "an interface has a type %u different from the type of the first interface",
+ idbp->linktype);
+ return (-1);
+ }
+ if (p->snapshot != idbp->snaplen) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "an interface has a snapshot length %u different from the type of the first interface",
+ idbp->snaplen);
+ return (-1);
+ }
+
+ /*
+ * Count this interface.
+ */
+ p->sf.ifcount++;
+
+ /*
+ * Set the default time stamp resolution and offset.
+ */
+ tsresol = 1000000; /* microsecond resolution */
+ tsoffset = 0; /* absolute timestamps */
+
+ /*
+ * Now look for various time stamp options, to
+ * make sure they're the same.
+ *
+ * XXX - we could, in theory, handle multiple
+ * different resolutions and offsets, but we
+ * don't do so for now.
+ */
+ if (process_idb_options(p, &cursor, &tsresol, &tsoffset,
+ p->errbuf) == -1)
+ return (-1);
+ if (tsresol != p->sf.tsresol) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "an interface has a time stamp resolution different from the time stamp resolution of the first interface");
+ return (-1);
+ }
+ if (tsoffset != p->sf.tsoffset) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "an interface has a time stamp offset different from the time stamp offset of the first interface");
+ return (-1);
+ }
+ break;
+
+ case BT_SHB:
+ /*
+ * Section Header Block. Get a pointer
+ * to its fixed-length portion.
+ */
+ shbp = get_from_block_data(&cursor, sizeof(*shbp),
+ p->errbuf);
+ if (shbp == NULL)
+ return (-1); /* error */
+
+ /*
+ * Assume the byte order of this section is
+ * the same as that of the previous section.
+ * We'll check for that later.
+ */
+ if (p->sf.swapped) {
+ shbp->byte_order_magic =
+ SWAPLONG(shbp->byte_order_magic);
+ shbp->major_version =
+ SWAPSHORT(shbp->major_version);
+ }
+
+ /*
+ * Make sure the byte order doesn't change;
+ * pcap_is_swapped() shouldn't change its
+ * return value in the middle of reading a capture.
+ */
+ switch (shbp->byte_order_magic) {
+
+ case BYTE_ORDER_MAGIC:
+ /*
+ * OK.
+ */
+ break;
+
+ case SWAPLONG(BYTE_ORDER_MAGIC):
+ /*
+ * Byte order changes.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "the file has sections with different byte orders");
+ return (-1);
+
+ default:
+ /*
+ * Not a valid SHB.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "the file has a section with a bad byte order magic field");
+ return (-1);
+ }
+
+ /*
+ * Make sure the major version is the version
+ * we handle.
+ */
+ if (shbp->major_version != PCAP_NG_VERSION_MAJOR) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "unknown pcap-ng savefile major version number %u",
+ shbp->major_version);
+ return (-1);
+ }
+
+ /*
+ * Reset the interface count; this section should
+ * have its own set of IDBs. If any of them
+ * don't have the same interface type, snapshot
+ * length, or resolution as the first interface
+ * we saw, we'll fail. (And if we don't see
+ * any IDBs, we'll fail when we see a packet
+ * block.)
+ */
+ p->sf.ifcount = 0;
+ break;
+
+ default:
+ /*
+ * Not a packet block, IDB, or SHB; ignore it.
+ */
+ break;
+ }
+ }
+
+found:
+ /*
+ * Is the interface ID an interface we know?
+ */
+ if (interface_id >= p->sf.ifcount) {
+ /*
+ * Yes. Fail.
+ */
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "a packet arrived on interface %u, but there's no Interface Description Block for that interface",
+ interface_id);
+ return (-1);
+ }
+
+ /*
+ * Convert the time stamp to a struct timeval.
+ */
+ sec = t / p->sf.tsresol + p->sf.tsoffset;
+ frac = t % p->sf.tsresol;
+ if (p->sf.tsresol > 1000000) {
+ /*
+ * Higher than microsecond resolution; scale down to
+ * microseconds.
+ */
+ frac /= p->sf.tsscale;
+ } else {
+ /*
+ * Lower than microsecond resolution; scale up to
+ * microseconds.
+ */
+ frac *= p->sf.tsscale;
+ }
+ hdr->ts.tv_sec = sec;
+ hdr->ts.tv_usec = frac;
+
+ /*
+ * Get a pointer to the packet data.
+ */
+ *data = get_from_block_data(&cursor, hdr->caplen, p->errbuf);
+ if (*data == NULL)
+ return (-1);
+
+ if (p->sf.swapped) {
+ /*
+ * Convert pseudo-headers from the byte order of
+ * the host on which the file was saved to our
+ * byte order, as necessary.
+ */
+ switch (p->linktype) {
+
+ case DLT_USB_LINUX:
+ swap_linux_usb_header(hdr, *data, 0);
+ break;
+
+ case DLT_USB_LINUX_MMAPPED:
+ swap_linux_usb_header(hdr, *data, 1);
+ break;
+ }
+ }
+
+ return (0);
+}
diff --git a/freebsd/contrib/libpcap/sf-pcap-ng.h b/freebsd/contrib/libpcap/sf-pcap-ng.h
new file mode 100644
index 00000000..cc551824
--- /dev/null
+++ b/freebsd/contrib/libpcap/sf-pcap-ng.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * sf-pcap-ng.h - pcap-ng-file-format-specific routines
+ *
+ * Used to read pcap-ng savefiles.
+ */
+
+#ifndef sf_pcap_ng_h
+#define sf_pcap_ng_h
+
+extern int pcap_ng_check_header(pcap_t *, bpf_u_int32, FILE *, char *);
+
+#endif
diff --git a/freebsd/contrib/libpcap/sf-pcap.c b/freebsd/contrib/libpcap/sf-pcap.c
new file mode 100644
index 00000000..6f967c58
--- /dev/null
+++ b/freebsd/contrib/libpcap/sf-pcap.c
@@ -0,0 +1,620 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * sf-pcap.c - libpcap-file-format-specific code from savefile.c
+ * Extraction/creation by Jeffrey Mogul, DECWRL
+ * Modified by Steve McCanne, LBL.
+ *
+ * Used to save the received packet headers, after filtering, to
+ * a file, and then read them later.
+ * The first record in the file contains saved values for the machine
+ * dependent values so we can print the dump file on any architecture.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header$ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef WIN32
+#include <pcap-stdinc.h>
+#else /* WIN32 */
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#elif HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <rtems/bsd/sys/types.h>
+#endif /* WIN32 */
+
+#include <errno.h>
+#include <memory.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pcap-int.h"
+
+#include "pcap-common.h"
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#include "sf-pcap.h"
+
+/*
+ * Setting O_BINARY on DOS/Windows is a bit tricky
+ */
+#if defined(WIN32)
+ #define SET_BINMODE(f) _setmode(_fileno(f), _O_BINARY)
+#elif defined(MSDOS)
+ #if defined(__HIGHC__)
+ #define SET_BINMODE(f) setmode(f, O_BINARY)
+ #else
+ #define SET_BINMODE(f) setmode(fileno(f), O_BINARY)
+ #endif
+#endif
+
+/*
+ * Standard libpcap format.
+ */
+#define TCPDUMP_MAGIC 0xa1b2c3d4
+
+/*
+ * Alexey Kuznetzov's modified libpcap format.
+ */
+#define KUZNETZOV_TCPDUMP_MAGIC 0xa1b2cd34
+
+/*
+ * Reserved for Francisco Mesquita <francisco.mesquita@radiomovel.pt>
+ * for another modified format.
+ */
+#define FMESQUITA_TCPDUMP_MAGIC 0xa1b234cd
+
+/*
+ * Navtel Communcations' format, with nanosecond timestamps,
+ * as per a request from Dumas Hwang <dumas.hwang@navtelcom.com>.
+ */
+#define NAVTEL_TCPDUMP_MAGIC 0xa12b3c4d
+
+/*
+ * Normal libpcap format, except for seconds/nanoseconds timestamps,
+ * as per a request by Ulf Lamping <ulf.lamping@web.de>
+ */
+#define NSEC_TCPDUMP_MAGIC 0xa1b23c4d
+
+/*
+ * Mechanism for storing information about a capture in the upper
+ * 6 bits of a linktype value in a capture file.
+ *
+ * LT_LINKTYPE_EXT(x) extracts the additional information.
+ *
+ * The rest of the bits are for a value describing the link-layer
+ * value. LT_LINKTYPE(x) extracts that value.
+ */
+#define LT_LINKTYPE(x) ((x) & 0x03FFFFFF)
+#define LT_LINKTYPE_EXT(x) ((x) & 0xFC000000)
+
+static int pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **datap);
+
+/*
+ * Check whether this is a pcap savefile and, if it is, extract the
+ * relevant information from the header.
+ */
+int
+pcap_check_header(pcap_t *p, bpf_u_int32 magic, FILE *fp, char *errbuf)
+{
+ struct pcap_file_header hdr;
+ size_t amt_read;
+
+ /*
+ * Check whether the first 4 bytes of the file are the magic
+ * number for a pcap savefile, or for a byte-swapped pcap
+ * savefile.
+ */
+ if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC) {
+ magic = SWAPLONG(magic);
+ if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC)
+ return (0); /* nope */
+ p->sf.swapped = 1;
+ }
+
+ /*
+ * They are. Put the magic number in the header, and read
+ * the rest of the header.
+ */
+ hdr.magic = magic;
+ amt_read = fread(((char *)&hdr) + sizeof hdr.magic, 1,
+ sizeof(hdr) - sizeof(hdr.magic), fp);
+ if (amt_read != sizeof(hdr) - sizeof(hdr.magic)) {
+ if (ferror(fp)) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "error reading dump file: %s",
+ pcap_strerror(errno));
+ } else {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "truncated dump file; tried to read %lu file header bytes, only got %lu",
+ (unsigned long)sizeof(hdr),
+ (unsigned long)amt_read);
+ }
+ return (-1);
+ }
+
+ /*
+ * If it's a byte-swapped capture file, byte-swap the header.
+ */
+ if (p->sf.swapped) {
+ hdr.version_major = SWAPSHORT(hdr.version_major);
+ hdr.version_minor = SWAPSHORT(hdr.version_minor);
+ hdr.thiszone = SWAPLONG(hdr.thiszone);
+ hdr.sigfigs = SWAPLONG(hdr.sigfigs);
+ hdr.snaplen = SWAPLONG(hdr.snaplen);
+ hdr.linktype = SWAPLONG(hdr.linktype);
+ }
+
+ if (hdr.version_major < PCAP_VERSION_MAJOR) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE,
+ "archaic pcap savefile format");
+ return (-1);
+ }
+ p->sf.version_major = hdr.version_major;
+ p->sf.version_minor = hdr.version_minor;
+ p->tzoff = hdr.thiszone;
+ p->snapshot = hdr.snaplen;
+ p->linktype = linktype_to_dlt(LT_LINKTYPE(hdr.linktype));
+ p->linktype_ext = LT_LINKTYPE_EXT(hdr.linktype);
+
+ p->sf.next_packet_op = pcap_next_packet;
+
+ /*
+ * We interchanged the caplen and len fields at version 2.3,
+ * in order to match the bpf header layout. But unfortunately
+ * some files were written with version 2.3 in their headers
+ * but without the interchanged fields.
+ *
+ * In addition, DG/UX tcpdump writes out files with a version
+ * number of 543.0, and with the caplen and len fields in the
+ * pre-2.3 order.
+ */
+ switch (hdr.version_major) {
+
+ case 2:
+ if (hdr.version_minor < 3)
+ p->sf.lengths_swapped = SWAPPED;
+ else if (hdr.version_minor == 3)
+ p->sf.lengths_swapped = MAYBE_SWAPPED;
+ else
+ p->sf.lengths_swapped = NOT_SWAPPED;
+ break;
+
+ case 543:
+ p->sf.lengths_swapped = SWAPPED;
+ break;
+
+ default:
+ p->sf.lengths_swapped = NOT_SWAPPED;
+ break;
+ }
+
+ if (magic == KUZNETZOV_TCPDUMP_MAGIC) {
+ /*
+ * XXX - the patch that's in some versions of libpcap
+ * changes the packet header but not the magic number,
+ * and some other versions with this magic number have
+ * some extra debugging information in the packet header;
+ * we'd have to use some hacks^H^H^H^H^Hheuristics to
+ * detect those variants.
+ *
+ * Ethereal does that, but it does so by trying to read
+ * the first two packets of the file with each of the
+ * record header formats. That currently means it seeks
+ * backwards and retries the reads, which doesn't work
+ * on pipes. We want to be able to read from a pipe, so
+ * that strategy won't work; we'd have to buffer some
+ * data ourselves and read from that buffer in order to
+ * make that work.
+ */
+ p->sf.hdrsize = sizeof(struct pcap_sf_patched_pkthdr);
+
+ if (p->linktype == DLT_EN10MB) {
+ /*
+ * This capture might have been done in raw mode
+ * or cooked mode.
+ *
+ * If it was done in cooked mode, p->snapshot was
+ * passed to recvfrom() as the buffer size, meaning
+ * that the most packet data that would be copied
+ * would be p->snapshot. However, a faked Ethernet
+ * header would then have been added to it, so the
+ * most data that would be in a packet in the file
+ * would be p->snapshot + 14.
+ *
+ * We can't easily tell whether the capture was done
+ * in raw mode or cooked mode, so we'll assume it was
+ * cooked mode, and add 14 to the snapshot length.
+ * That means that, for a raw capture, the snapshot
+ * length will be misleading if you use it to figure
+ * out why a capture doesn't have all the packet data,
+ * but there's not much we can do to avoid that.
+ */
+ p->snapshot += 14;
+ }
+ } else
+ p->sf.hdrsize = sizeof(struct pcap_sf_pkthdr);
+
+ /*
+ * Allocate a buffer for the packet data.
+ */
+ p->bufsize = p->snapshot;
+ if (p->bufsize <= 0) {
+ /*
+ * Bogus snapshot length; use 64KiB as a fallback.
+ */
+ p->bufsize = 65536;
+ }
+ p->buffer = malloc(p->bufsize);
+ if (p->buffer == NULL) {
+ snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory");
+ return (-1);
+ }
+
+ return (1);
+}
+
+/*
+ * Read and return the next packet from the savefile. Return the header
+ * in hdr and a pointer to the contents in data. Return 0 on success, 1
+ * if there were no more packets, and -1 on an error.
+ */
+static int
+pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
+{
+ struct pcap_sf_patched_pkthdr sf_hdr;
+ FILE *fp = p->sf.rfile;
+ size_t amt_read;
+ bpf_u_int32 t;
+
+ /*
+ * Read the packet header; the structure we use as a buffer
+ * is the longer structure for files generated by the patched
+ * libpcap, but if the file has the magic number for an
+ * unpatched libpcap we only read as many bytes as the regular
+ * header has.
+ */
+ amt_read = fread(&sf_hdr, 1, p->sf.hdrsize, fp);
+ if (amt_read != p->sf.hdrsize) {
+ if (ferror(fp)) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "error reading dump file: %s",
+ pcap_strerror(errno));
+ return (-1);
+ } else {
+ if (amt_read != 0) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "truncated dump file; tried to read %lu header bytes, only got %lu",
+ (unsigned long)p->sf.hdrsize,
+ (unsigned long)amt_read);
+ return (-1);
+ }
+ /* EOF */
+ return (1);
+ }
+ }
+
+ if (p->sf.swapped) {
+ /* these were written in opposite byte order */
+ hdr->caplen = SWAPLONG(sf_hdr.caplen);
+ hdr->len = SWAPLONG(sf_hdr.len);
+ hdr->ts.tv_sec = SWAPLONG(sf_hdr.ts.tv_sec);
+ hdr->ts.tv_usec = SWAPLONG(sf_hdr.ts.tv_usec);
+ } else {
+ hdr->caplen = sf_hdr.caplen;
+ hdr->len = sf_hdr.len;
+ hdr->ts.tv_sec = sf_hdr.ts.tv_sec;
+ hdr->ts.tv_usec = sf_hdr.ts.tv_usec;
+ }
+ /* Swap the caplen and len fields, if necessary. */
+ switch (p->sf.lengths_swapped) {
+
+ case NOT_SWAPPED:
+ break;
+
+ case MAYBE_SWAPPED:
+ if (hdr->caplen <= hdr->len) {
+ /*
+ * The captured length is <= the actual length,
+ * so presumably they weren't swapped.
+ */
+ break;
+ }
+ /* FALLTHROUGH */
+
+ case SWAPPED:
+ t = hdr->caplen;
+ hdr->caplen = hdr->len;
+ hdr->len = t;
+ break;
+ }
+
+ if (hdr->caplen > p->bufsize) {
+ /*
+ * This can happen due to Solaris 2.3 systems tripping
+ * over the BUFMOD problem and not setting the snapshot
+ * correctly in the savefile header. If the caplen isn't
+ * grossly wrong, try to salvage.
+ */
+ static u_char *tp = NULL;
+ static size_t tsize = 0;
+
+ if (hdr->caplen > 65535) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "bogus savefile header");
+ return (-1);
+ }
+
+ if (tsize < hdr->caplen) {
+ tsize = ((hdr->caplen + 1023) / 1024) * 1024;
+ if (tp != NULL)
+ free((u_char *)tp);
+ tp = (u_char *)malloc(tsize);
+ if (tp == NULL) {
+ tsize = 0;
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "BUFMOD hack malloc");
+ return (-1);
+ }
+ }
+ amt_read = fread((char *)tp, 1, hdr->caplen, fp);
+ if (amt_read != hdr->caplen) {
+ if (ferror(fp)) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "error reading dump file: %s",
+ pcap_strerror(errno));
+ } else {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "truncated dump file; tried to read %u captured bytes, only got %lu",
+ hdr->caplen, (unsigned long)amt_read);
+ }
+ return (-1);
+ }
+ /*
+ * We can only keep up to p->bufsize bytes. Since
+ * caplen > p->bufsize is exactly how we got here,
+ * we know we can only keep the first p->bufsize bytes
+ * and must drop the remainder. Adjust caplen accordingly,
+ * so we don't get confused later as to how many bytes we
+ * have to play with.
+ */
+ hdr->caplen = p->bufsize;
+ memcpy(p->buffer, (char *)tp, p->bufsize);
+ } else {
+ /* read the packet itself */
+ amt_read = fread(p->buffer, 1, hdr->caplen, fp);
+ if (amt_read != hdr->caplen) {
+ if (ferror(fp)) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "error reading dump file: %s",
+ pcap_strerror(errno));
+ } else {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "truncated dump file; tried to read %u captured bytes, only got %lu",
+ hdr->caplen, (unsigned long)amt_read);
+ }
+ return (-1);
+ }
+ }
+ *data = p->buffer;
+
+ if (p->sf.swapped) {
+ /*
+ * Convert pseudo-headers from the byte order of
+ * the host on which the file was saved to our
+ * byte order, as necessary.
+ */
+ switch (p->linktype) {
+
+ case DLT_USB_LINUX:
+ swap_linux_usb_header(hdr, *data, 0);
+ break;
+
+ case DLT_USB_LINUX_MMAPPED:
+ swap_linux_usb_header(hdr, *data, 1);
+ break;
+ }
+ }
+
+ return (0);
+}
+
+static int
+sf_write_header(FILE *fp, int linktype, int thiszone, int snaplen)
+{
+ struct pcap_file_header hdr;
+
+ hdr.magic = TCPDUMP_MAGIC;
+ hdr.version_major = PCAP_VERSION_MAJOR;
+ hdr.version_minor = PCAP_VERSION_MINOR;
+
+ hdr.thiszone = thiszone;
+ hdr.snaplen = snaplen;
+ hdr.sigfigs = 0;
+ hdr.linktype = linktype;
+
+ if (fwrite((char *)&hdr, sizeof(hdr), 1, fp) != 1)
+ return (-1);
+
+ return (0);
+}
+
+/*
+ * Output a packet to the initialized dump file.
+ */
+void
+pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
+{
+ register FILE *f;
+ struct pcap_sf_pkthdr sf_hdr;
+
+ f = (FILE *)user;
+ sf_hdr.ts.tv_sec = h->ts.tv_sec;
+ sf_hdr.ts.tv_usec = h->ts.tv_usec;
+ sf_hdr.caplen = h->caplen;
+ sf_hdr.len = h->len;
+ /* XXX we should check the return status */
+ (void)fwrite(&sf_hdr, sizeof(sf_hdr), 1, f);
+ (void)fwrite(sp, h->caplen, 1, f);
+}
+
+static pcap_dumper_t *
+pcap_setup_dump(pcap_t *p, int linktype, FILE *f, const char *fname)
+{
+
+#if defined(WIN32) || defined(MSDOS)
+ /*
+ * If we're writing to the standard output, put it in binary
+ * mode, as savefiles are binary files.
+ *
+ * Otherwise, we turn off buffering.
+ * XXX - why? And why not on the standard output?
+ */
+ if (f == stdout)
+ SET_BINMODE(f);
+ else
+ setbuf(f, NULL);
+#endif
+ if (sf_write_header(f, linktype, p->tzoff, p->snapshot) == -1) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't write to %s: %s",
+ fname, pcap_strerror(errno));
+ if (f != stdout)
+ (void)fclose(f);
+ return (NULL);
+ }
+ return ((pcap_dumper_t *)f);
+}
+
+/*
+ * Initialize so that sf_write() will output to the file named 'fname'.
+ */
+pcap_dumper_t *
+pcap_dump_open(pcap_t *p, const char *fname)
+{
+ FILE *f;
+ int linktype;
+
+ /*
+ * If this pcap_t hasn't been activated, it doesn't have a
+ * link-layer type, so we can't use it.
+ */
+ if (!p->activated) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "%s: not-yet-activated pcap_t passed to pcap_dump_open",
+ fname);
+ return (NULL);
+ }
+ linktype = dlt_to_linktype(p->linktype);
+ if (linktype == -1) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "%s: link-layer type %d isn't supported in savefiles",
+ fname, p->linktype);
+ return (NULL);
+ }
+ linktype |= p->linktype_ext;
+
+ if (fname[0] == '-' && fname[1] == '\0') {
+ f = stdout;
+ fname = "standard output";
+ } else {
+#if !defined(WIN32) && !defined(MSDOS)
+ f = fopen(fname, "w");
+#else
+ f = fopen(fname, "wb");
+#endif
+ if (f == NULL) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
+ fname, pcap_strerror(errno));
+ return (NULL);
+ }
+ }
+ return (pcap_setup_dump(p, linktype, f, fname));
+}
+
+/*
+ * Initialize so that sf_write() will output to the given stream.
+ */
+pcap_dumper_t *
+pcap_dump_fopen(pcap_t *p, FILE *f)
+{
+ int linktype;
+
+ linktype = dlt_to_linktype(p->linktype);
+ if (linktype == -1) {
+ snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
+ "stream: link-layer type %d isn't supported in savefiles",
+ p->linktype);
+ return (NULL);
+ }
+ linktype |= p->linktype_ext;
+
+ return (pcap_setup_dump(p, linktype, f, "stream"));
+}
+
+FILE *
+pcap_dump_file(pcap_dumper_t *p)
+{
+ return ((FILE *)p);
+}
+
+long
+pcap_dump_ftell(pcap_dumper_t *p)
+{
+ return (ftell((FILE *)p));
+}
+
+int
+pcap_dump_flush(pcap_dumper_t *p)
+{
+
+ if (fflush((FILE *)p) == EOF)
+ return (-1);
+ else
+ return (0);
+}
+
+void
+pcap_dump_close(pcap_dumper_t *p)
+{
+
+#ifdef notyet
+ if (ferror((FILE *)p))
+ return-an-error;
+ /* XXX should check return from fclose() too */
+#endif
+ (void)fclose((FILE *)p);
+}
diff --git a/freebsd/contrib/libpcap/sf-pcap.h b/freebsd/contrib/libpcap/sf-pcap.h
new file mode 100644
index 00000000..3b3fbe89
--- /dev/null
+++ b/freebsd/contrib/libpcap/sf-pcap.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * sf-pcap.h - libpcap-file-format-specific routines
+ * Extraction/creation by Jeffrey Mogul, DECWRL
+ * Modified by Steve McCanne, LBL.
+ *
+ * Used to save the received packet headers, after filtering, to
+ * a file, and then read them later.
+ * The first record in the file contains saved values for the machine
+ * dependent values so we can print the dump file on any architecture.
+ */
+
+#ifndef sf_pcap_h
+#define sf_pcap_h
+
+extern int pcap_check_header(pcap_t *, bpf_u_int32, FILE *, char *);
+
+#endif
diff --git a/freebsd/contrib/libpcap/sunatmpos.h b/freebsd/contrib/libpcap/sunatmpos.h
new file mode 100644
index 00000000..916017fa
--- /dev/null
+++ b/freebsd/contrib/libpcap/sunatmpos.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1997 Yen Yen Lim and North Dakota State University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Yen Yen Lim and
+ North Dakota State University
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * @(#) $Header: /tcpdump/master/libpcap/sunatmpos.h,v 1.1 2002-07-11 09:06:47 guy Exp $ (LBL)
+ */
+
+/* SunATM header for ATM packet */
+#define SUNATM_DIR_POS 0
+#define SUNATM_VPI_POS 1
+#define SUNATM_VCI_POS 2
+#define SUNATM_PKT_BEGIN_POS 4 /* Start of ATM packet */
+
+/* Protocol type values in the bottom for bits of the byte at SUNATM_DIR_POS. */
+#define PT_LANE 0x01 /* LANE */
+#define PT_LLC 0x02 /* LLC encapsulation */
+#define PT_ILMI 0x05 /* ILMI */
+#define PT_QSAAL 0x06 /* Q.SAAL */
diff --git a/freebsd/contrib/tcpdump/addrtoname.c b/freebsd/contrib/tcpdump/addrtoname.c
new file mode 100644
index 00000000..cd5963d5
--- /dev/null
+++ b/freebsd/contrib/tcpdump/addrtoname.c
@@ -0,0 +1,1218 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Internet, ethernet, port, and protocol string to address
+ * and address to string conversion routines
+ *
+ * $FreeBSD$
+ */
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/addrtoname.c,v 1.119 2007-08-08 14:06:34 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#ifdef USE_ETHER_NTOHOST
+#ifdef HAVE_NETINET_IF_ETHER_H
+struct mbuf; /* Squelch compiler warnings on some platforms for */
+struct rtentry; /* declarations in <net/if.h> */
+#include <net/if.h> /* for "struct ifnet" in "struct arpcom" on Solaris */
+#include <netinet/if_ether.h>
+#endif /* HAVE_NETINET_IF_ETHER_H */
+#ifdef NETINET_ETHER_H_DECLARES_ETHER_NTOHOST
+#include <netinet/ether.h>
+#endif /* NETINET_ETHER_H_DECLARES_ETHER_NTOHOST */
+
+#if !defined(HAVE_DECL_ETHER_NTOHOST) || !HAVE_DECL_ETHER_NTOHOST
+#ifndef HAVE_STRUCT_ETHER_ADDR
+struct ether_addr {
+ unsigned char ether_addr_octet[6];
+};
+#endif
+extern int ether_ntohost(char *, const struct ether_addr *);
+#endif
+
+#endif /* USE_ETHER_NTOHOST */
+
+#include <pcap.h>
+#include <pcap-namedb.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "llc.h"
+#include "setsignal.h"
+#include "extract.h"
+#include "oui.h"
+
+#ifndef ETHER_ADDR_LEN
+#define ETHER_ADDR_LEN 6
+#endif
+
+/*
+ * hash tables for whatever-to-name translations
+ *
+ * XXX there has to be error checks against strdup(3) failure
+ */
+
+#define HASHNAMESIZE 4096
+
+struct hnamemem {
+ u_int32_t addr;
+ const char *name;
+ struct hnamemem *nxt;
+};
+
+static struct hnamemem hnametable[HASHNAMESIZE];
+static struct hnamemem tporttable[HASHNAMESIZE];
+static struct hnamemem uporttable[HASHNAMESIZE];
+static struct hnamemem eprototable[HASHNAMESIZE];
+static struct hnamemem dnaddrtable[HASHNAMESIZE];
+static struct hnamemem ipxsaptable[HASHNAMESIZE];
+
+#if defined(INET6) && defined(WIN32)
+/*
+ * fake gethostbyaddr for Win2k/XP
+ * gethostbyaddr() returns incorrect value when AF_INET6 is passed
+ * to 3rd argument.
+ *
+ * h_name in struct hostent is only valid.
+ */
+static struct hostent *
+win32_gethostbyaddr(const char *addr, int len, int type)
+{
+ static struct hostent host;
+ static char hostbuf[NI_MAXHOST];
+ char hname[NI_MAXHOST];
+ struct sockaddr_in6 addr6;
+
+ host.h_name = hostbuf;
+ switch (type) {
+ case AF_INET:
+ return gethostbyaddr(addr, len, type);
+ break;
+ case AF_INET6:
+ memset(&addr6, 0, sizeof(addr6));
+ addr6.sin6_family = AF_INET6;
+ memcpy(&addr6.sin6_addr, addr, len);
+ if (getnameinfo((struct sockaddr *)&addr6, sizeof(addr6),
+ hname, sizeof(hname), NULL, 0, 0)) {
+ return NULL;
+ } else {
+ strcpy(host.h_name, hname);
+ return &host;
+ }
+ break;
+ default:
+ return NULL;
+ }
+}
+#define gethostbyaddr win32_gethostbyaddr
+#endif /* INET6 & WIN32 */
+
+#ifdef INET6
+struct h6namemem {
+ struct in6_addr addr;
+ char *name;
+ struct h6namemem *nxt;
+};
+
+static struct h6namemem h6nametable[HASHNAMESIZE];
+#endif /* INET6 */
+
+struct enamemem {
+ u_short e_addr0;
+ u_short e_addr1;
+ u_short e_addr2;
+ const char *e_name;
+ u_char *e_nsap; /* used only for nsaptable[] */
+#define e_bs e_nsap /* for bytestringtable */
+ struct enamemem *e_nxt;
+};
+
+static struct enamemem enametable[HASHNAMESIZE];
+static struct enamemem nsaptable[HASHNAMESIZE];
+static struct enamemem bytestringtable[HASHNAMESIZE];
+
+struct protoidmem {
+ u_int32_t p_oui;
+ u_short p_proto;
+ const char *p_name;
+ struct protoidmem *p_nxt;
+};
+
+static struct protoidmem protoidtable[HASHNAMESIZE];
+
+/*
+ * A faster replacement for inet_ntoa().
+ */
+const char *
+intoa(u_int32_t addr)
+{
+ register char *cp;
+ register u_int byte;
+ register int n;
+ static char buf[sizeof(".xxx.xxx.xxx.xxx")];
+
+ NTOHL(addr);
+ cp = buf + sizeof(buf);
+ *--cp = '\0';
+
+ n = 4;
+ do {
+ byte = addr & 0xff;
+ *--cp = byte % 10 + '0';
+ byte /= 10;
+ if (byte > 0) {
+ *--cp = byte % 10 + '0';
+ byte /= 10;
+ if (byte > 0)
+ *--cp = byte + '0';
+ }
+ *--cp = '.';
+ addr >>= 8;
+ } while (--n > 0);
+
+ return cp + 1;
+}
+
+static u_int32_t f_netmask;
+static u_int32_t f_localnet;
+
+/*
+ * Return a name for the IP address pointed to by ap. This address
+ * is assumed to be in network byte order.
+ *
+ * NOTE: ap is *NOT* necessarily part of the packet data (not even if
+ * this is being called with the "ipaddr_string()" macro), so you
+ * *CANNOT* use the TCHECK{2}/TTEST{2} macros on it. Furthermore,
+ * even in cases where it *is* part of the packet data, the caller
+ * would still have to check for a null return value, even if it's
+ * just printing the return value with "%s" - not all versions of
+ * printf print "(null)" with "%s" and a null pointer, some of them
+ * don't check for a null pointer and crash in that case.
+ *
+ * The callers of this routine should, before handing this routine
+ * a pointer to packet data, be sure that the data is present in
+ * the packet buffer. They should probably do those checks anyway,
+ * as other data at that layer might not be IP addresses, and it
+ * also needs to check whether they're present in the packet buffer.
+ */
+const char *
+getname(const u_char *ap)
+{
+ register struct hostent *hp;
+ u_int32_t addr;
+ static struct hnamemem *p; /* static for longjmp() */
+
+ memcpy(&addr, ap, sizeof(addr));
+ p = &hnametable[addr & (HASHNAMESIZE-1)];
+ for (; p->nxt; p = p->nxt) {
+ if (p->addr == addr)
+ return (p->name);
+ }
+ p->addr = addr;
+ p->nxt = newhnamemem();
+
+ /*
+ * Print names unless:
+ * (1) -n was given.
+ * (2) Address is foreign and -f was given. (If -f was not
+ * given, f_netmask and f_localnet are 0 and the test
+ * evaluates to true)
+ */
+ if (!nflag &&
+ (addr & f_netmask) == f_localnet) {
+ hp = gethostbyaddr((char *)&addr, 4, AF_INET);
+ if (hp) {
+ char *dotp;
+
+ p->name = strdup(hp->h_name);
+ if (Nflag) {
+ /* Remove domain qualifications */
+ dotp = strchr(p->name, '.');
+ if (dotp)
+ *dotp = '\0';
+ }
+ return (p->name);
+ }
+ }
+ p->name = strdup(intoa(addr));
+ return (p->name);
+}
+
+#ifdef INET6
+/*
+ * Return a name for the IP6 address pointed to by ap. This address
+ * is assumed to be in network byte order.
+ */
+const char *
+getname6(const u_char *ap)
+{
+ register struct hostent *hp;
+ struct in6_addr addr;
+ static struct h6namemem *p; /* static for longjmp() */
+ register const char *cp;
+ char ntop_buf[INET6_ADDRSTRLEN];
+
+ memcpy(&addr, ap, sizeof(addr));
+ p = &h6nametable[*(u_int16_t *)&addr.s6_addr[14] & (HASHNAMESIZE-1)];
+ for (; p->nxt; p = p->nxt) {
+ if (memcmp(&p->addr, &addr, sizeof(addr)) == 0)
+ return (p->name);
+ }
+ p->addr = addr;
+ p->nxt = newh6namemem();
+
+ /*
+ * Do not print names if -n was given.
+ */
+ if (!nflag) {
+ hp = gethostbyaddr((char *)&addr, sizeof(addr), AF_INET6);
+ if (hp) {
+ char *dotp;
+
+ p->name = strdup(hp->h_name);
+ if (Nflag) {
+ /* Remove domain qualifications */
+ dotp = strchr(p->name, '.');
+ if (dotp)
+ *dotp = '\0';
+ }
+ return (p->name);
+ }
+ }
+ cp = inet_ntop(AF_INET6, &addr, ntop_buf, sizeof(ntop_buf));
+ p->name = strdup(cp);
+ return (p->name);
+}
+#endif /* INET6 */
+
+static const char hex[] = "0123456789abcdef";
+
+
+/* Find the hash node that corresponds the ether address 'ep' */
+
+static inline struct enamemem *
+lookup_emem(const u_char *ep)
+{
+ register u_int i, j, k;
+ struct enamemem *tp;
+
+ k = (ep[0] << 8) | ep[1];
+ j = (ep[2] << 8) | ep[3];
+ i = (ep[4] << 8) | ep[5];
+
+ tp = &enametable[(i ^ j) & (HASHNAMESIZE-1)];
+ while (tp->e_nxt)
+ if (tp->e_addr0 == i &&
+ tp->e_addr1 == j &&
+ tp->e_addr2 == k)
+ return tp;
+ else
+ tp = tp->e_nxt;
+ tp->e_addr0 = i;
+ tp->e_addr1 = j;
+ tp->e_addr2 = k;
+ tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
+ if (tp->e_nxt == NULL)
+ error("lookup_emem: calloc");
+
+ return tp;
+}
+
+/*
+ * Find the hash node that corresponds to the bytestring 'bs'
+ * with length 'nlen'
+ */
+
+static inline struct enamemem *
+lookup_bytestring(register const u_char *bs, const unsigned int nlen)
+{
+ struct enamemem *tp;
+ register u_int i, j, k;
+
+ if (nlen >= 6) {
+ k = (bs[0] << 8) | bs[1];
+ j = (bs[2] << 8) | bs[3];
+ i = (bs[4] << 8) | bs[5];
+ } else if (nlen >= 4) {
+ k = (bs[0] << 8) | bs[1];
+ j = (bs[2] << 8) | bs[3];
+ i = 0;
+ } else
+ i = j = k = 0;
+
+ tp = &bytestringtable[(i ^ j) & (HASHNAMESIZE-1)];
+ while (tp->e_nxt)
+ if (tp->e_addr0 == i &&
+ tp->e_addr1 == j &&
+ tp->e_addr2 == k &&
+ memcmp((const char *)bs, (const char *)(tp->e_bs), nlen) == 0)
+ return tp;
+ else
+ tp = tp->e_nxt;
+
+ tp->e_addr0 = i;
+ tp->e_addr1 = j;
+ tp->e_addr2 = k;
+
+ tp->e_bs = (u_char *) calloc(1, nlen + 1);
+ if (tp->e_bs == NULL)
+ error("lookup_bytestring: calloc");
+
+ memcpy(tp->e_bs, bs, nlen);
+ tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
+ if (tp->e_nxt == NULL)
+ error("lookup_bytestring: calloc");
+
+ return tp;
+}
+
+/* Find the hash node that corresponds the NSAP 'nsap' */
+
+static inline struct enamemem *
+lookup_nsap(register const u_char *nsap)
+{
+ register u_int i, j, k;
+ unsigned int nlen = *nsap;
+ struct enamemem *tp;
+ const u_char *ensap = nsap + nlen - 6;
+
+ if (nlen > 6) {
+ k = (ensap[0] << 8) | ensap[1];
+ j = (ensap[2] << 8) | ensap[3];
+ i = (ensap[4] << 8) | ensap[5];
+ }
+ else
+ i = j = k = 0;
+
+ tp = &nsaptable[(i ^ j) & (HASHNAMESIZE-1)];
+ while (tp->e_nxt)
+ if (tp->e_addr0 == i &&
+ tp->e_addr1 == j &&
+ tp->e_addr2 == k &&
+ tp->e_nsap[0] == nlen &&
+ memcmp((const char *)&(nsap[1]),
+ (char *)&(tp->e_nsap[1]), nlen) == 0)
+ return tp;
+ else
+ tp = tp->e_nxt;
+ tp->e_addr0 = i;
+ tp->e_addr1 = j;
+ tp->e_addr2 = k;
+ tp->e_nsap = (u_char *)malloc(nlen + 1);
+ if (tp->e_nsap == NULL)
+ error("lookup_nsap: malloc");
+ memcpy((char *)tp->e_nsap, (const char *)nsap, nlen + 1);
+ tp->e_nxt = (struct enamemem *)calloc(1, sizeof(*tp));
+ if (tp->e_nxt == NULL)
+ error("lookup_nsap: calloc");
+
+ return tp;
+}
+
+/* Find the hash node that corresponds the protoid 'pi'. */
+
+static inline struct protoidmem *
+lookup_protoid(const u_char *pi)
+{
+ register u_int i, j;
+ struct protoidmem *tp;
+
+ /* 5 octets won't be aligned */
+ i = (((pi[0] << 8) + pi[1]) << 8) + pi[2];
+ j = (pi[3] << 8) + pi[4];
+ /* XXX should be endian-insensitive, but do big-endian testing XXX */
+
+ tp = &protoidtable[(i ^ j) & (HASHNAMESIZE-1)];
+ while (tp->p_nxt)
+ if (tp->p_oui == i && tp->p_proto == j)
+ return tp;
+ else
+ tp = tp->p_nxt;
+ tp->p_oui = i;
+ tp->p_proto = j;
+ tp->p_nxt = (struct protoidmem *)calloc(1, sizeof(*tp));
+ if (tp->p_nxt == NULL)
+ error("lookup_protoid: calloc");
+
+ return tp;
+}
+
+const char *
+etheraddr_string(register const u_char *ep)
+{
+ register int i;
+ register char *cp;
+ register struct enamemem *tp;
+ int oui;
+ char buf[BUFSIZE];
+
+ tp = lookup_emem(ep);
+ if (tp->e_name)
+ return (tp->e_name);
+#ifdef USE_ETHER_NTOHOST
+ if (!nflag) {
+ char buf2[BUFSIZE];
+
+ /*
+ * We don't cast it to "const struct ether_addr *"
+ * because some systems fail to declare the second
+ * argument as a "const" pointer, even though they
+ * don't modify what it points to.
+ */
+ if (ether_ntohost(buf2, (struct ether_addr *)ep) == 0) {
+ tp->e_name = strdup(buf2);
+ return (tp->e_name);
+ }
+ }
+#endif
+ cp = buf;
+ oui = EXTRACT_24BITS(ep);
+ *cp++ = hex[*ep >> 4 ];
+ *cp++ = hex[*ep++ & 0xf];
+ for (i = 5; --i >= 0;) {
+ *cp++ = ':';
+ *cp++ = hex[*ep >> 4 ];
+ *cp++ = hex[*ep++ & 0xf];
+ }
+
+ if (!nflag) {
+ snprintf(cp, BUFSIZE - (2 + 5*3), " (oui %s)",
+ tok2str(oui_values, "Unknown", oui));
+ } else
+ *cp = '\0';
+ tp->e_name = strdup(buf);
+ return (tp->e_name);
+}
+
+const char *
+le64addr_string(const u_char *ep)
+{
+ const unsigned int len = 8;
+ register u_int i;
+ register char *cp;
+ register struct enamemem *tp;
+ char buf[BUFSIZE];
+
+ tp = lookup_bytestring(ep, len);
+ if (tp->e_name)
+ return (tp->e_name);
+
+ cp = buf;
+ for (i = len; i > 0 ; --i) {
+ *cp++ = hex[*(ep + i - 1) >> 4];
+ *cp++ = hex[*(ep + i - 1) & 0xf];
+ *cp++ = ':';
+ }
+ cp --;
+
+ *cp = '\0';
+
+ tp->e_name = strdup(buf);
+
+ return (tp->e_name);
+}
+
+const char *
+linkaddr_string(const u_char *ep, const unsigned int type, const unsigned int len)
+{
+ register u_int i;
+ register char *cp;
+ register struct enamemem *tp;
+
+ if (len == 0)
+ return ("<empty>");
+
+ if (type == LINKADDR_ETHER && len == ETHER_ADDR_LEN)
+ return (etheraddr_string(ep));
+
+ if (type == LINKADDR_FRELAY)
+ return (q922_string(ep));
+
+ tp = lookup_bytestring(ep, len);
+ if (tp->e_name)
+ return (tp->e_name);
+
+ tp->e_name = cp = (char *)malloc(len*3);
+ if (tp->e_name == NULL)
+ error("linkaddr_string: malloc");
+ *cp++ = hex[*ep >> 4];
+ *cp++ = hex[*ep++ & 0xf];
+ for (i = len-1; i > 0 ; --i) {
+ *cp++ = ':';
+ *cp++ = hex[*ep >> 4];
+ *cp++ = hex[*ep++ & 0xf];
+ }
+ *cp = '\0';
+ return (tp->e_name);
+}
+
+const char *
+etherproto_string(u_short port)
+{
+ register char *cp;
+ register struct hnamemem *tp;
+ register u_int32_t i = port;
+ char buf[sizeof("0000")];
+
+ for (tp = &eprototable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
+ if (tp->addr == i)
+ return (tp->name);
+
+ tp->addr = i;
+ tp->nxt = newhnamemem();
+
+ cp = buf;
+ NTOHS(port);
+ *cp++ = hex[port >> 12 & 0xf];
+ *cp++ = hex[port >> 8 & 0xf];
+ *cp++ = hex[port >> 4 & 0xf];
+ *cp++ = hex[port & 0xf];
+ *cp++ = '\0';
+ tp->name = strdup(buf);
+ return (tp->name);
+}
+
+const char *
+protoid_string(register const u_char *pi)
+{
+ register u_int i, j;
+ register char *cp;
+ register struct protoidmem *tp;
+ char buf[sizeof("00:00:00:00:00")];
+
+ tp = lookup_protoid(pi);
+ if (tp->p_name)
+ return tp->p_name;
+
+ cp = buf;
+ if ((j = *pi >> 4) != 0)
+ *cp++ = hex[j];
+ *cp++ = hex[*pi++ & 0xf];
+ for (i = 4; (int)--i >= 0;) {
+ *cp++ = ':';
+ if ((j = *pi >> 4) != 0)
+ *cp++ = hex[j];
+ *cp++ = hex[*pi++ & 0xf];
+ }
+ *cp = '\0';
+ tp->p_name = strdup(buf);
+ return (tp->p_name);
+}
+
+#define ISONSAP_MAX_LENGTH 20
+const char *
+isonsap_string(const u_char *nsap, register u_int nsap_length)
+{
+ register u_int nsap_idx;
+ register char *cp;
+ register struct enamemem *tp;
+
+ if (nsap_length < 1 || nsap_length > ISONSAP_MAX_LENGTH)
+ return ("isonsap_string: illegal length");
+
+ tp = lookup_nsap(nsap);
+ if (tp->e_name)
+ return tp->e_name;
+
+ tp->e_name = cp = (char *)malloc(sizeof("xx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xx"));
+ if (cp == NULL)
+ error("isonsap_string: malloc");
+
+ for (nsap_idx = 0; nsap_idx < nsap_length; nsap_idx++) {
+ *cp++ = hex[*nsap >> 4];
+ *cp++ = hex[*nsap++ & 0xf];
+ if (((nsap_idx & 1) == 0) &&
+ (nsap_idx + 1 < nsap_length)) {
+ *cp++ = '.';
+ }
+ }
+ *cp = '\0';
+ return (tp->e_name);
+}
+
+const char *
+tcpport_string(u_short port)
+{
+ register struct hnamemem *tp;
+ register u_int32_t i = port;
+ char buf[sizeof("00000")];
+
+ for (tp = &tporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
+ if (tp->addr == i)
+ return (tp->name);
+
+ tp->addr = i;
+ tp->nxt = newhnamemem();
+
+ (void)snprintf(buf, sizeof(buf), "%u", i);
+ tp->name = strdup(buf);
+ return (tp->name);
+}
+
+const char *
+udpport_string(register u_short port)
+{
+ register struct hnamemem *tp;
+ register u_int32_t i = port;
+ char buf[sizeof("00000")];
+
+ for (tp = &uporttable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
+ if (tp->addr == i)
+ return (tp->name);
+
+ tp->addr = i;
+ tp->nxt = newhnamemem();
+
+ (void)snprintf(buf, sizeof(buf), "%u", i);
+ tp->name = strdup(buf);
+ return (tp->name);
+}
+
+const char *
+ipxsap_string(u_short port)
+{
+ register char *cp;
+ register struct hnamemem *tp;
+ register u_int32_t i = port;
+ char buf[sizeof("0000")];
+
+ for (tp = &ipxsaptable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
+ if (tp->addr == i)
+ return (tp->name);
+
+ tp->addr = i;
+ tp->nxt = newhnamemem();
+
+ cp = buf;
+ NTOHS(port);
+ *cp++ = hex[port >> 12 & 0xf];
+ *cp++ = hex[port >> 8 & 0xf];
+ *cp++ = hex[port >> 4 & 0xf];
+ *cp++ = hex[port & 0xf];
+ *cp++ = '\0';
+ tp->name = strdup(buf);
+ return (tp->name);
+}
+
+static void
+init_servarray(void)
+{
+ struct servent *sv;
+ register struct hnamemem *table;
+ register int i;
+ char buf[sizeof("0000000000")];
+
+ while ((sv = getservent()) != NULL) {
+ int port = ntohs(sv->s_port);
+ i = port & (HASHNAMESIZE-1);
+ if (strcmp(sv->s_proto, "tcp") == 0)
+ table = &tporttable[i];
+ else if (strcmp(sv->s_proto, "udp") == 0)
+ table = &uporttable[i];
+ else
+ continue;
+
+ while (table->name)
+ table = table->nxt;
+ if (nflag) {
+ (void)snprintf(buf, sizeof(buf), "%d", port);
+ table->name = strdup(buf);
+ } else
+ table->name = strdup(sv->s_name);
+ table->addr = port;
+ table->nxt = newhnamemem();
+ }
+ endservent();
+}
+
+/* in libpcap.a (nametoaddr.c) */
+#if defined(WIN32) && !defined(USE_STATIC_LIBPCAP)
+__declspec(dllimport)
+#else
+extern
+#endif
+const struct eproto {
+ const char *s;
+ u_short p;
+} eproto_db[];
+
+static void
+init_eprotoarray(void)
+{
+ register int i;
+ register struct hnamemem *table;
+
+ for (i = 0; eproto_db[i].s; i++) {
+ int j = htons(eproto_db[i].p) & (HASHNAMESIZE-1);
+ table = &eprototable[j];
+ while (table->name)
+ table = table->nxt;
+ table->name = eproto_db[i].s;
+ table->addr = htons(eproto_db[i].p);
+ table->nxt = newhnamemem();
+ }
+}
+
+static const struct protoidlist {
+ const u_char protoid[5];
+ const char *name;
+} protoidlist[] = {
+ {{ 0x00, 0x00, 0x0c, 0x01, 0x07 }, "CiscoMLS" },
+ {{ 0x00, 0x00, 0x0c, 0x20, 0x00 }, "CiscoCDP" },
+ {{ 0x00, 0x00, 0x0c, 0x20, 0x01 }, "CiscoCGMP" },
+ {{ 0x00, 0x00, 0x0c, 0x20, 0x03 }, "CiscoVTP" },
+ {{ 0x00, 0xe0, 0x2b, 0x00, 0xbb }, "ExtremeEDP" },
+ {{ 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL }
+};
+
+/*
+ * SNAP proto IDs with org code 0:0:0 are actually encapsulated Ethernet
+ * types.
+ */
+static void
+init_protoidarray(void)
+{
+ register int i;
+ register struct protoidmem *tp;
+ const struct protoidlist *pl;
+ u_char protoid[5];
+
+ protoid[0] = 0;
+ protoid[1] = 0;
+ protoid[2] = 0;
+ for (i = 0; eproto_db[i].s; i++) {
+ u_short etype = htons(eproto_db[i].p);
+
+ memcpy((char *)&protoid[3], (char *)&etype, 2);
+ tp = lookup_protoid(protoid);
+ tp->p_name = strdup(eproto_db[i].s);
+ }
+ /* Hardwire some SNAP proto ID names */
+ for (pl = protoidlist; pl->name != NULL; ++pl) {
+ tp = lookup_protoid(pl->protoid);
+ /* Don't override existing name */
+ if (tp->p_name != NULL)
+ continue;
+
+ tp->p_name = pl->name;
+ }
+}
+
+static const struct etherlist {
+ const u_char addr[6];
+ const char *name;
+} etherlist[] = {
+ {{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }, "Broadcast" },
+ {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, NULL }
+};
+
+/*
+ * Initialize the ethers hash table. We take two different approaches
+ * depending on whether or not the system provides the ethers name
+ * service. If it does, we just wire in a few names at startup,
+ * and etheraddr_string() fills in the table on demand. If it doesn't,
+ * then we suck in the entire /etc/ethers file at startup. The idea
+ * is that parsing the local file will be fast, but spinning through
+ * all the ethers entries via NIS & next_etherent might be very slow.
+ *
+ * XXX pcap_next_etherent doesn't belong in the pcap interface, but
+ * since the pcap module already does name-to-address translation,
+ * it's already does most of the work for the ethernet address-to-name
+ * translation, so we just pcap_next_etherent as a convenience.
+ */
+static void
+init_etherarray(void)
+{
+ register const struct etherlist *el;
+ register struct enamemem *tp;
+#ifdef USE_ETHER_NTOHOST
+ char name[256];
+#else
+ register struct pcap_etherent *ep;
+ register FILE *fp;
+
+ /* Suck in entire ethers file */
+ fp = fopen(PCAP_ETHERS_FILE, "r");
+ if (fp != NULL) {
+ while ((ep = pcap_next_etherent(fp)) != NULL) {
+ tp = lookup_emem(ep->addr);
+ tp->e_name = strdup(ep->name);
+ }
+ (void)fclose(fp);
+ }
+#endif
+
+ /* Hardwire some ethernet names */
+ for (el = etherlist; el->name != NULL; ++el) {
+ tp = lookup_emem(el->addr);
+ /* Don't override existing name */
+ if (tp->e_name != NULL)
+ continue;
+
+#ifdef USE_ETHER_NTOHOST
+ /*
+ * Use YP/NIS version of name if available.
+ *
+ * We don't cast it to "const struct ether_addr *"
+ * because some systems don't modify the Ethernet
+ * address but fail to declare the second argument
+ * as a "const" pointer.
+ */
+ if (ether_ntohost(name, (struct ether_addr *)el->addr) == 0) {
+ tp->e_name = strdup(name);
+ continue;
+ }
+#endif
+ tp->e_name = el->name;
+ }
+}
+
+static const struct tok ipxsap_db[] = {
+ { 0x0000, "Unknown" },
+ { 0x0001, "User" },
+ { 0x0002, "User Group" },
+ { 0x0003, "PrintQueue" },
+ { 0x0004, "FileServer" },
+ { 0x0005, "JobServer" },
+ { 0x0006, "Gateway" },
+ { 0x0007, "PrintServer" },
+ { 0x0008, "ArchiveQueue" },
+ { 0x0009, "ArchiveServer" },
+ { 0x000a, "JobQueue" },
+ { 0x000b, "Administration" },
+ { 0x000F, "Novell TI-RPC" },
+ { 0x0017, "Diagnostics" },
+ { 0x0020, "NetBIOS" },
+ { 0x0021, "NAS SNA Gateway" },
+ { 0x0023, "NACS AsyncGateway" },
+ { 0x0024, "RemoteBridge/RoutingService" },
+ { 0x0026, "BridgeServer" },
+ { 0x0027, "TCP/IP Gateway" },
+ { 0x0028, "Point-to-point X.25 BridgeServer" },
+ { 0x0029, "3270 Gateway" },
+ { 0x002a, "CHI Corp" },
+ { 0x002c, "PC Chalkboard" },
+ { 0x002d, "TimeSynchServer" },
+ { 0x002e, "ARCserve5.0/PalindromeBackup" },
+ { 0x0045, "DI3270 Gateway" },
+ { 0x0047, "AdvertisingPrintServer" },
+ { 0x004a, "NetBlazerModems" },
+ { 0x004b, "BtrieveVAP" },
+ { 0x004c, "NetwareSQL" },
+ { 0x004d, "XtreeNetwork" },
+ { 0x0050, "BtrieveVAP4.11" },
+ { 0x0052, "QuickLink" },
+ { 0x0053, "PrintQueueUser" },
+ { 0x0058, "Multipoint X.25 Router" },
+ { 0x0060, "STLB/NLM" },
+ { 0x0064, "ARCserve" },
+ { 0x0066, "ARCserve3.0" },
+ { 0x0072, "WAN CopyUtility" },
+ { 0x007a, "TES-NetwareVMS" },
+ { 0x0092, "WATCOM Debugger/EmeraldTapeBackupServer" },
+ { 0x0095, "DDA OBGYN" },
+ { 0x0098, "NetwareAccessServer" },
+ { 0x009a, "Netware for VMS II/NamedPipeServer" },
+ { 0x009b, "NetwareAccessServer" },
+ { 0x009e, "PortableNetwareServer/SunLinkNVT" },
+ { 0x00a1, "PowerchuteAPC UPS" },
+ { 0x00aa, "LAWserve" },
+ { 0x00ac, "CompaqIDA StatusMonitor" },
+ { 0x0100, "PIPE STAIL" },
+ { 0x0102, "LAN ProtectBindery" },
+ { 0x0103, "OracleDataBaseServer" },
+ { 0x0107, "Netware386/RSPX RemoteConsole" },
+ { 0x010f, "NovellSNA Gateway" },
+ { 0x0111, "TestServer" },
+ { 0x0112, "HP PrintServer" },
+ { 0x0114, "CSA MUX" },
+ { 0x0115, "CSA LCA" },
+ { 0x0116, "CSA CM" },
+ { 0x0117, "CSA SMA" },
+ { 0x0118, "CSA DBA" },
+ { 0x0119, "CSA NMA" },
+ { 0x011a, "CSA SSA" },
+ { 0x011b, "CSA STATUS" },
+ { 0x011e, "CSA APPC" },
+ { 0x0126, "SNA TEST SSA Profile" },
+ { 0x012a, "CSA TRACE" },
+ { 0x012b, "NetwareSAA" },
+ { 0x012e, "IKARUS VirusScan" },
+ { 0x0130, "CommunicationsExecutive" },
+ { 0x0133, "NNS DomainServer/NetwareNamingServicesDomain" },
+ { 0x0135, "NetwareNamingServicesProfile" },
+ { 0x0137, "Netware386 PrintQueue/NNS PrintQueue" },
+ { 0x0141, "LAN SpoolServer" },
+ { 0x0152, "IRMALAN Gateway" },
+ { 0x0154, "NamedPipeServer" },
+ { 0x0166, "NetWareManagement" },
+ { 0x0168, "Intel PICKIT CommServer/Intel CAS TalkServer" },
+ { 0x0173, "Compaq" },
+ { 0x0174, "Compaq SNMP Agent" },
+ { 0x0175, "Compaq" },
+ { 0x0180, "XTreeServer/XTreeTools" },
+ { 0x018A, "NASI ServicesBroadcastServer" },
+ { 0x01b0, "GARP Gateway" },
+ { 0x01b1, "Binfview" },
+ { 0x01bf, "IntelLanDeskManager" },
+ { 0x01ca, "AXTEC" },
+ { 0x01cb, "ShivaNetModem/E" },
+ { 0x01cc, "ShivaLanRover/E" },
+ { 0x01cd, "ShivaLanRover/T" },
+ { 0x01ce, "ShivaUniversal" },
+ { 0x01d8, "CastelleFAXPressServer" },
+ { 0x01da, "CastelleLANPressPrintServer" },
+ { 0x01dc, "CastelleFAX/Xerox7033 FaxServer/ExcelLanFax" },
+ { 0x01f0, "LEGATO" },
+ { 0x01f5, "LEGATO" },
+ { 0x0233, "NMS Agent/NetwareManagementAgent" },
+ { 0x0237, "NMS IPX Discovery/LANternReadWriteChannel" },
+ { 0x0238, "NMS IP Discovery/LANternTrapAlarmChannel" },
+ { 0x023a, "LANtern" },
+ { 0x023c, "MAVERICK" },
+ { 0x023f, "NovellSMDR" },
+ { 0x024e, "NetwareConnect" },
+ { 0x024f, "NASI ServerBroadcast Cisco" },
+ { 0x026a, "NMS ServiceConsole" },
+ { 0x026b, "TimeSynchronizationServer Netware 4.x" },
+ { 0x0278, "DirectoryServer Netware 4.x" },
+ { 0x027b, "NetwareManagementAgent" },
+ { 0x0280, "Novell File and Printer Sharing Service for PC" },
+ { 0x0304, "NovellSAA Gateway" },
+ { 0x0308, "COM/VERMED" },
+ { 0x030a, "GalacticommWorldgroupServer" },
+ { 0x030c, "IntelNetport2/HP JetDirect/HP Quicksilver" },
+ { 0x0320, "AttachmateGateway" },
+ { 0x0327, "MicrosoftDiagnostiocs" },
+ { 0x0328, "WATCOM SQL Server" },
+ { 0x0335, "MultiTechSystems MultisynchCommServer" },
+ { 0x0343, "Xylogics RemoteAccessServer/LANModem" },
+ { 0x0355, "ArcadaBackupExec" },
+ { 0x0358, "MSLCD1" },
+ { 0x0361, "NETINELO" },
+ { 0x037e, "Powerchute UPS Monitoring" },
+ { 0x037f, "ViruSafeNotify" },
+ { 0x0386, "HP Bridge" },
+ { 0x0387, "HP Hub" },
+ { 0x0394, "NetWare SAA Gateway" },
+ { 0x039b, "LotusNotes" },
+ { 0x03b7, "CertusAntiVirus" },
+ { 0x03c4, "ARCserve4.0" },
+ { 0x03c7, "LANspool3.5" },
+ { 0x03d7, "LexmarkPrinterServer" },
+ { 0x03d8, "LexmarkXLE PrinterServer" },
+ { 0x03dd, "BanyanENS NetwareClient" },
+ { 0x03de, "GuptaSequelBaseServer/NetWareSQL" },
+ { 0x03e1, "UnivelUnixware" },
+ { 0x03e4, "UnivelUnixware" },
+ { 0x03fc, "IntelNetport" },
+ { 0x03fd, "PrintServerQueue" },
+ { 0x040A, "ipnServer" },
+ { 0x040D, "LVERRMAN" },
+ { 0x040E, "LVLIC" },
+ { 0x0414, "NET Silicon (DPI)/Kyocera" },
+ { 0x0429, "SiteLockVirus" },
+ { 0x0432, "UFHELPR???" },
+ { 0x0433, "Synoptics281xAdvancedSNMPAgent" },
+ { 0x0444, "MicrosoftNT SNA Server" },
+ { 0x0448, "Oracle" },
+ { 0x044c, "ARCserve5.01" },
+ { 0x0457, "CanonGP55" },
+ { 0x045a, "QMS Printers" },
+ { 0x045b, "DellSCSI Array" },
+ { 0x0491, "NetBlazerModems" },
+ { 0x04ac, "OnTimeScheduler" },
+ { 0x04b0, "CD-Net" },
+ { 0x0513, "EmulexNQA" },
+ { 0x0520, "SiteLockChecks" },
+ { 0x0529, "SiteLockChecks" },
+ { 0x052d, "CitrixOS2 AppServer" },
+ { 0x0535, "Tektronix" },
+ { 0x0536, "Milan" },
+ { 0x055d, "Attachmate SNA gateway" },
+ { 0x056b, "IBM8235 ModemServer" },
+ { 0x056c, "ShivaLanRover/E PLUS" },
+ { 0x056d, "ShivaLanRover/T PLUS" },
+ { 0x0580, "McAfeeNetShield" },
+ { 0x05B8, "NLM to workstation communication (Revelation Software)" },
+ { 0x05BA, "CompatibleSystemsRouters" },
+ { 0x05BE, "CheyenneHierarchicalStorageManager" },
+ { 0x0606, "JCWatermarkImaging" },
+ { 0x060c, "AXISNetworkPrinter" },
+ { 0x0610, "AdaptecSCSIManagement" },
+ { 0x0621, "IBM AntiVirus" },
+ { 0x0640, "Windows95 RemoteRegistryService" },
+ { 0x064e, "MicrosoftIIS" },
+ { 0x067b, "Microsoft Win95/98 File and Print Sharing for NetWare" },
+ { 0x067c, "Microsoft Win95/98 File and Print Sharing for NetWare" },
+ { 0x076C, "Xerox" },
+ { 0x079b, "ShivaLanRover/E 115" },
+ { 0x079c, "ShivaLanRover/T 115" },
+ { 0x07B4, "CubixWorldDesk" },
+ { 0x07c2, "Quarterdeck IWare Connect V2.x NLM" },
+ { 0x07c1, "Quarterdeck IWare Connect V3.x NLM" },
+ { 0x0810, "ELAN License Server Demo" },
+ { 0x0824, "ShivaLanRoverAccessSwitch/E" },
+ { 0x086a, "ISSC Collector" },
+ { 0x087f, "ISSC DAS AgentAIX" },
+ { 0x0880, "Intel Netport PRO" },
+ { 0x0881, "Intel Netport PRO" },
+ { 0x0b29, "SiteLock" },
+ { 0x0c29, "SiteLockApplications" },
+ { 0x0c2c, "LicensingServer" },
+ { 0x2101, "PerformanceTechnologyInstantInternet" },
+ { 0x2380, "LAI SiteLock" },
+ { 0x238c, "MeetingMaker" },
+ { 0x4808, "SiteLockServer/SiteLockMetering" },
+ { 0x5555, "SiteLockUser" },
+ { 0x6312, "Tapeware" },
+ { 0x6f00, "RabbitGateway" },
+ { 0x7703, "MODEM" },
+ { 0x8002, "NetPortPrinters" },
+ { 0x8008, "WordPerfectNetworkVersion" },
+ { 0x85BE, "Cisco EIGRP" },
+ { 0x8888, "WordPerfectNetworkVersion/QuickNetworkManagement" },
+ { 0x9000, "McAfeeNetShield" },
+ { 0x9604, "CSA-NT_MON" },
+ { 0xb6a8, "OceanIsleReachoutRemoteControl" },
+ { 0xf11f, "SiteLockMetering" },
+ { 0xf1ff, "SiteLock" },
+ { 0xf503, "Microsoft SQL Server" },
+ { 0xF905, "IBM TimeAndPlace" },
+ { 0xfbfb, "TopCallIII FaxServer" },
+ { 0xffff, "AnyService/Wildcard" },
+ { 0, (char *)0 }
+};
+
+static void
+init_ipxsaparray(void)
+{
+ register int i;
+ register struct hnamemem *table;
+
+ for (i = 0; ipxsap_db[i].s != NULL; i++) {
+ int j = htons(ipxsap_db[i].v) & (HASHNAMESIZE-1);
+ table = &ipxsaptable[j];
+ while (table->name)
+ table = table->nxt;
+ table->name = ipxsap_db[i].s;
+ table->addr = htons(ipxsap_db[i].v);
+ table->nxt = newhnamemem();
+ }
+}
+
+/*
+ * Initialize the address to name translation machinery. We map all
+ * non-local IP addresses to numeric addresses if fflag is true (i.e.,
+ * to prevent blocking on the nameserver). localnet is the IP address
+ * of the local network. mask is its subnet mask.
+ */
+void
+init_addrtoname(u_int32_t localnet, u_int32_t mask)
+{
+ if (fflag) {
+ f_localnet = localnet;
+ f_netmask = mask;
+ }
+ if (nflag)
+ /*
+ * Simplest way to suppress names.
+ */
+ return;
+
+ init_etherarray();
+ init_servarray();
+ init_eprotoarray();
+ init_protoidarray();
+ init_ipxsaparray();
+}
+
+const char *
+dnaddr_string(u_short dnaddr)
+{
+ register struct hnamemem *tp;
+
+ for (tp = &dnaddrtable[dnaddr & (HASHNAMESIZE-1)]; tp->nxt != 0;
+ tp = tp->nxt)
+ if (tp->addr == dnaddr)
+ return (tp->name);
+
+ tp->addr = dnaddr;
+ tp->nxt = newhnamemem();
+ if (nflag)
+ tp->name = dnnum_string(dnaddr);
+ else
+ tp->name = dnname_string(dnaddr);
+
+ return(tp->name);
+}
+
+/* Return a zero'ed hnamemem struct and cuts down on calloc() overhead */
+struct hnamemem *
+newhnamemem(void)
+{
+ register struct hnamemem *p;
+ static struct hnamemem *ptr = NULL;
+ static u_int num = 0;
+
+ if (num <= 0) {
+ num = 64;
+ ptr = (struct hnamemem *)calloc(num, sizeof (*ptr));
+ if (ptr == NULL)
+ error("newhnamemem: calloc");
+ }
+ --num;
+ p = ptr++;
+ return (p);
+}
+
+#ifdef INET6
+/* Return a zero'ed h6namemem struct and cuts down on calloc() overhead */
+struct h6namemem *
+newh6namemem(void)
+{
+ register struct h6namemem *p;
+ static struct h6namemem *ptr = NULL;
+ static u_int num = 0;
+
+ if (num <= 0) {
+ num = 64;
+ ptr = (struct h6namemem *)calloc(num, sizeof (*ptr));
+ if (ptr == NULL)
+ error("newh6namemem: calloc");
+ }
+ --num;
+ p = ptr++;
+ return (p);
+}
+#endif /* INET6 */
diff --git a/freebsd/contrib/tcpdump/addrtoname.h b/freebsd/contrib/tcpdump/addrtoname.h
new file mode 100644
index 00000000..cd5c41f4
--- /dev/null
+++ b/freebsd/contrib/tcpdump/addrtoname.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 1990, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /tcpdump/master/tcpdump/addrtoname.h,v 1.20 2007-08-08 14:06:34 hannes Exp $ (LBL)
+ */
+
+/* Name to address translation routines. */
+
+enum {
+ LINKADDR_ETHER,
+ LINKADDR_FRELAY,
+ LINKADDR_IEEE1394,
+ LINKADDR_ATM
+};
+
+#define BUFSIZE 128
+
+extern const char *linkaddr_string(const u_char *, const unsigned int, const unsigned int);
+extern const char *etheraddr_string(const u_char *);
+extern const char *le64addr_string(const u_char *);
+extern const char *etherproto_string(u_short);
+extern const char *tcpport_string(u_short);
+extern const char *udpport_string(u_short);
+extern const char *getname(const u_char *);
+#ifdef INET6
+extern const char *getname6(const u_char *);
+#endif
+extern const char *intoa(u_int32_t);
+
+extern void init_addrtoname(u_int32_t, u_int32_t);
+extern struct hnamemem *newhnamemem(void);
+#ifdef INET6
+extern struct h6namemem *newh6namemem(void);
+#endif
+
+#define ipaddr_string(p) getname((const u_char *)(p))
+#ifdef INET6
+#define ip6addr_string(p) getname6((const u_char *)(p))
+#endif
diff --git a/freebsd/contrib/tcpdump/af.c b/freebsd/contrib/tcpdump/af.c
new file mode 100644
index 00000000..4e307a02
--- /dev/null
+++ b/freebsd/contrib/tcpdump/af.c
@@ -0,0 +1,65 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1998-2006 The TCPDUMP project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/af.c,v 1.3 2006-03-23 14:58:44 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+#include "interface.h"
+#include "af.h"
+
+const struct tok af_values[] = {
+ { 0, "Reserved"},
+ { AFNUM_INET, "IPv4"},
+ { AFNUM_INET6, "IPv6"},
+ { AFNUM_NSAP, "NSAP"},
+ { AFNUM_HDLC, "HDLC"},
+ { AFNUM_BBN1822, "BBN 1822"},
+ { AFNUM_802, "802"},
+ { AFNUM_E163, "E.163"},
+ { AFNUM_E164, "E.164"},
+ { AFNUM_F69, "F.69"},
+ { AFNUM_X121, "X.121"},
+ { AFNUM_IPX, "Novell IPX"},
+ { AFNUM_ATALK, "Appletalk"},
+ { AFNUM_DECNET, "Decnet IV"},
+ { AFNUM_BANYAN, "Banyan Vines"},
+ { AFNUM_E164NSAP, "E.164 with NSAP subaddress"},
+ { AFNUM_L2VPN, "Layer-2 VPN"},
+ { AFNUM_VPLS, "VPLS"},
+ { 0, NULL},
+};
+
+const struct tok bsd_af_values[] = {
+ { BSD_AFNUM_INET, "IPv4" },
+ { BSD_AFNUM_NS, "NS" },
+ { BSD_AFNUM_ISO, "ISO" },
+ { BSD_AFNUM_APPLETALK, "Appletalk" },
+ { BSD_AFNUM_IPX, "IPX" },
+ { BSD_AFNUM_INET6_BSD, "IPv6" },
+ { BSD_AFNUM_INET6_FREEBSD, "IPv6" },
+ { BSD_AFNUM_INET6_DARWIN, "IPv6" },
+ { 0, NULL}
+};
diff --git a/freebsd/contrib/tcpdump/af.h b/freebsd/contrib/tcpdump/af.h
new file mode 100644
index 00000000..679cc8e5
--- /dev/null
+++ b/freebsd/contrib/tcpdump/af.h
@@ -0,0 +1,57 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/af.h,v 1.3 2006-03-23 14:58:44 hannes Exp $ (LBL) */
+
+/*
+ * Copyright (c) 1998-2006 The TCPDUMP project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+extern const struct tok af_values[];
+extern const struct tok bsd_af_values[];
+
+/* RFC1700 address family numbers */
+#define AFNUM_INET 1
+#define AFNUM_INET6 2
+#define AFNUM_NSAP 3
+#define AFNUM_HDLC 4
+#define AFNUM_BBN1822 5
+#define AFNUM_802 6
+#define AFNUM_E163 7
+#define AFNUM_E164 8
+#define AFNUM_F69 9
+#define AFNUM_X121 10
+#define AFNUM_IPX 11
+#define AFNUM_ATALK 12
+#define AFNUM_DECNET 13
+#define AFNUM_BANYAN 14
+#define AFNUM_E164NSAP 15
+#define AFNUM_VPLS 25
+/* draft-kompella-ppvpn-l2vpn */
+#define AFNUM_L2VPN 196 /* still to be approved by IANA */
+
+/*
+ * BSD AF_ values.
+ *
+ * Unfortunately, the BSDs don't all use the same value for AF_INET6,
+ * so, because we want to be able to read captures from all of the BSDs,
+ * we check for all of them.
+ */
+#define BSD_AFNUM_INET 2
+#define BSD_AFNUM_NS 6 /* XEROX NS protocols */
+#define BSD_AFNUM_ISO 7
+#define BSD_AFNUM_APPLETALK 16
+#define BSD_AFNUM_IPX 23
+#define BSD_AFNUM_INET6_BSD 24 /* OpenBSD (and probably NetBSD), BSD/OS */
+#define BSD_AFNUM_INET6_FREEBSD 28
+#define BSD_AFNUM_INET6_DARWIN 30
diff --git a/freebsd/contrib/tcpdump/ah.h b/freebsd/contrib/tcpdump/ah.h
new file mode 100644
index 00000000..c22806af
--- /dev/null
+++ b/freebsd/contrib/tcpdump/ah.h
@@ -0,0 +1,57 @@
+/* $NetBSD: ah.h,v 1.12 2000/07/23 05:23:04 itojun Exp $ */
+/* $KAME: ah.h,v 1.12 2000/07/20 17:41:01 itojun Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * RFC1826/2402 authentication header.
+ */
+
+#ifndef _NETINET6_AH_H_
+#define _NETINET6_AH_H_
+
+struct ah {
+ u_int8_t ah_nxt; /* Next Header */
+ u_int8_t ah_len; /* Length of data, in 32bit */
+ u_int16_t ah_reserve; /* Reserved for future use */
+ u_int32_t ah_spi; /* Security parameter index */
+ /* variable size, 32bit bound*/ /* Authentication data */
+};
+
+struct newah {
+ u_int8_t ah_nxt; /* Next Header */
+ u_int8_t ah_len; /* Length of data + 1, in 32bit */
+ u_int16_t ah_reserve; /* Reserved for future use */
+ u_int32_t ah_spi; /* Security parameter index */
+ u_int32_t ah_seq; /* Sequence number field */
+ /* variable size, 32bit bound*/ /* Authentication data */
+};
+
+#endif /*_NETINET6_AH_H_*/
diff --git a/freebsd/contrib/tcpdump/aodv.h b/freebsd/contrib/tcpdump/aodv.h
new file mode 100644
index 00000000..456ec8b3
--- /dev/null
+++ b/freebsd/contrib/tcpdump/aodv.h
@@ -0,0 +1,190 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/aodv.h,v 1.3 2003-09-13 01:34:42 guy Exp $ (LBL) */
+/*
+ * Copyright (c) 2003 Bruce M. Simpson <bms@spc.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bruce M. Simpson.
+ * 4. Neither the name of Bruce M. Simpson nor the names of co-
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bruce M. Simpson AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Bruce M. Simpson OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _AODV_H_
+#define _AODV_H_
+
+struct aodv_rreq {
+ u_int8_t rreq_type; /* AODV message type (1) */
+ u_int8_t rreq_flags; /* various flags */
+ u_int8_t rreq_zero0; /* reserved, set to zero */
+ u_int8_t rreq_hops; /* number of hops from originator */
+ u_int32_t rreq_id; /* request ID */
+ u_int32_t rreq_da; /* destination IPv4 address */
+ u_int32_t rreq_ds; /* destination sequence number */
+ u_int32_t rreq_oa; /* originator IPv4 address */
+ u_int32_t rreq_os; /* originator sequence number */
+};
+#ifdef INET6
+struct aodv_rreq6 {
+ u_int8_t rreq_type; /* AODV message type (1) */
+ u_int8_t rreq_flags; /* various flags */
+ u_int8_t rreq_zero0; /* reserved, set to zero */
+ u_int8_t rreq_hops; /* number of hops from originator */
+ u_int32_t rreq_id; /* request ID */
+ struct in6_addr rreq_da; /* destination IPv6 address */
+ u_int32_t rreq_ds; /* destination sequence number */
+ struct in6_addr rreq_oa; /* originator IPv6 address */
+ u_int32_t rreq_os; /* originator sequence number */
+};
+struct aodv_rreq6_draft_01 {
+ u_int8_t rreq_type; /* AODV message type (16) */
+ u_int8_t rreq_flags; /* various flags */
+ u_int8_t rreq_zero0; /* reserved, set to zero */
+ u_int8_t rreq_hops; /* number of hops from originator */
+ u_int32_t rreq_id; /* request ID */
+ u_int32_t rreq_ds; /* destination sequence number */
+ u_int32_t rreq_os; /* originator sequence number */
+ struct in6_addr rreq_da; /* destination IPv6 address */
+ struct in6_addr rreq_oa; /* originator IPv6 address */
+};
+#endif
+
+#define RREQ_JOIN 0x80 /* join (reserved for multicast */
+#define RREQ_REPAIR 0x40 /* repair (reserved for multicast */
+#define RREQ_GRAT 0x20 /* gratuitous RREP */
+#define RREQ_DEST 0x10 /* destination only */
+#define RREQ_UNKNOWN 0x08 /* unknown destination sequence num */
+#define RREQ_FLAGS_MASK 0xF8 /* mask for rreq_flags */
+
+struct aodv_rrep {
+ u_int8_t rrep_type; /* AODV message type (2) */
+ u_int8_t rrep_flags; /* various flags */
+ u_int8_t rrep_ps; /* prefix size */
+ u_int8_t rrep_hops; /* number of hops from o to d */
+ u_int32_t rrep_da; /* destination IPv4 address */
+ u_int32_t rrep_ds; /* destination sequence number */
+ u_int32_t rrep_oa; /* originator IPv4 address */
+ u_int32_t rrep_life; /* lifetime of this route */
+};
+#ifdef INET6
+struct aodv_rrep6 {
+ u_int8_t rrep_type; /* AODV message type (2) */
+ u_int8_t rrep_flags; /* various flags */
+ u_int8_t rrep_ps; /* prefix size */
+ u_int8_t rrep_hops; /* number of hops from o to d */
+ struct in6_addr rrep_da; /* destination IPv6 address */
+ u_int32_t rrep_ds; /* destination sequence number */
+ struct in6_addr rrep_oa; /* originator IPv6 address */
+ u_int32_t rrep_life; /* lifetime of this route */
+};
+struct aodv_rrep6_draft_01 {
+ u_int8_t rrep_type; /* AODV message type (17) */
+ u_int8_t rrep_flags; /* various flags */
+ u_int8_t rrep_ps; /* prefix size */
+ u_int8_t rrep_hops; /* number of hops from o to d */
+ u_int32_t rrep_ds; /* destination sequence number */
+ struct in6_addr rrep_da; /* destination IPv6 address */
+ struct in6_addr rrep_oa; /* originator IPv6 address */
+ u_int32_t rrep_life; /* lifetime of this route */
+};
+#endif
+
+#define RREP_REPAIR 0x80 /* repair (reserved for multicast */
+#define RREP_ACK 0x40 /* acknowledgement required */
+#define RREP_FLAGS_MASK 0xC0 /* mask for rrep_flags */
+#define RREP_PREFIX_MASK 0x1F /* mask for prefix size */
+
+struct rerr_unreach {
+ u_int32_t u_da; /* IPv4 address */
+ u_int32_t u_ds; /* sequence number */
+};
+#ifdef INET6
+struct rerr_unreach6 {
+ struct in6_addr u_da; /* IPv6 address */
+ u_int32_t u_ds; /* sequence number */
+};
+struct rerr_unreach6_draft_01 {
+ struct in6_addr u_da; /* IPv6 address */
+ u_int32_t u_ds; /* sequence number */
+};
+#endif
+
+struct aodv_rerr {
+ u_int8_t rerr_type; /* AODV message type (3 or 18) */
+ u_int8_t rerr_flags; /* various flags */
+ u_int8_t rerr_zero0; /* reserved, set to zero */
+ u_int8_t rerr_dc; /* destination count */
+ union {
+ struct rerr_unreach dest[1];
+#ifdef INET6
+ struct rerr_unreach6 dest6[1];
+ struct rerr_unreach6_draft_01 dest6_draft_01[1];
+#endif
+ } r;
+};
+
+#define RERR_NODELETE 0x80 /* don't delete the link */
+#define RERR_FLAGS_MASK 0x80 /* mask for rerr_flags */
+
+struct aodv_rrep_ack {
+ u_int8_t ra_type;
+ u_int8_t ra_zero0;
+};
+
+union aodv {
+ struct aodv_rreq rreq;
+ struct aodv_rrep rrep;
+ struct aodv_rerr rerr;
+ struct aodv_rrep_ack rrep_ack;
+#ifdef INET6
+ struct aodv_rreq6 rreq6;
+ struct aodv_rreq6_draft_01 rreq6_draft_01;
+ struct aodv_rrep6 rrep6;
+ struct aodv_rrep6_draft_01 rrep6_draft_01;
+#endif
+};
+
+#define AODV_RREQ 1 /* route request */
+#define AODV_RREP 2 /* route response */
+#define AODV_RERR 3 /* error report */
+#define AODV_RREP_ACK 4 /* route response acknowledgement */
+
+#define AODV_V6_DRAFT_01_RREQ 16 /* IPv6 route request */
+#define AODV_V6_DRAFT_01_RREP 17 /* IPv6 route response */
+#define AODV_V6_DRAFT_01_RERR 18 /* IPv6 error report */
+#define AODV_V6_DRAFT_01_RREP_ACK 19 /* IPV6 route response acknowledgment */
+
+struct aodv_ext {
+ u_int8_t type; /* extension type */
+ u_int8_t length; /* extension length */
+};
+
+struct aodv_hello {
+ struct aodv_ext eh; /* extension header */
+ u_int32_t interval; /* expect my next hello in
+ * (n) ms */
+};
+
+#define AODV_EXT_HELLO 1
+
+#endif /* _AODV_H_ */
diff --git a/freebsd/contrib/tcpdump/appletalk.h b/freebsd/contrib/tcpdump/appletalk.h
new file mode 100644
index 00000000..ff972f65
--- /dev/null
+++ b/freebsd/contrib/tcpdump/appletalk.h
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 1988, 1989, 1990, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * AppleTalk protocol formats (courtesy Bill Croft of Stanford/SUMEX).
+ *
+ * @(#) $Header: /tcpdump/master/tcpdump/appletalk.h,v 1.16 2004-05-01 09:41:50 hannes Exp $ (LBL)
+ */
+
+struct LAP {
+ u_int8_t dst;
+ u_int8_t src;
+ u_int8_t type;
+};
+#define lapShortDDP 1 /* short DDP type */
+#define lapDDP 2 /* DDP type */
+#define lapKLAP 'K' /* Kinetics KLAP type */
+
+/* Datagram Delivery Protocol */
+
+struct atDDP {
+ u_int16_t length;
+ u_int16_t checksum;
+ u_int16_t dstNet;
+ u_int16_t srcNet;
+ u_int8_t dstNode;
+ u_int8_t srcNode;
+ u_int8_t dstSkt;
+ u_int8_t srcSkt;
+ u_int8_t type;
+};
+
+struct atShortDDP {
+ u_int16_t length;
+ u_int8_t dstSkt;
+ u_int8_t srcSkt;
+ u_int8_t type;
+};
+
+#define ddpMaxWKS 0x7F
+#define ddpMaxData 586
+#define ddpLengthMask 0x3FF
+#define ddpHopShift 10
+#define ddpSize 13 /* size of DDP header (avoid struct padding) */
+#define ddpSSize 5
+#define ddpWKS 128 /* boundary of DDP well known sockets */
+#define ddpRTMP 1 /* RTMP type */
+#define ddpRTMPrequest 5 /* RTMP request type */
+#define ddpNBP 2 /* NBP type */
+#define ddpATP 3 /* ATP type */
+#define ddpECHO 4 /* ECHO type */
+#define ddpIP 22 /* IP type */
+#define ddpARP 23 /* ARP type */
+#define ddpEIGRP 88 /* EIGRP over Appletalk */
+#define ddpKLAP 0x4b /* Kinetics KLAP type */
+
+
+/* AppleTalk Transaction Protocol */
+
+struct atATP {
+ u_int8_t control;
+ u_int8_t bitmap;
+ u_int16_t transID;
+ int32_t userData;
+};
+
+#define atpReqCode 0x40
+#define atpRspCode 0x80
+#define atpRelCode 0xC0
+#define atpXO 0x20
+#define atpEOM 0x10
+#define atpSTS 0x08
+#define atpFlagMask 0x3F
+#define atpControlMask 0xF8
+#define atpMaxNum 8
+#define atpMaxData 578
+
+
+/* AppleTalk Echo Protocol */
+
+struct atEcho {
+ u_int8_t echoFunction;
+ u_int8_t *echoData;
+};
+
+#define echoSkt 4 /* the echoer socket */
+#define echoSize 1 /* size of echo header */
+#define echoRequest 1 /* echo request */
+#define echoReply 2 /* echo request */
+
+
+/* Name Binding Protocol */
+
+struct atNBP {
+ u_int8_t control;
+ u_int8_t id;
+};
+
+struct atNBPtuple {
+ u_int16_t net;
+ u_int8_t node;
+ u_int8_t skt;
+ u_int8_t enumerator;
+};
+
+#define nbpBrRq 0x10
+#define nbpLkUp 0x20
+#define nbpLkUpReply 0x30
+
+#define nbpNIS 2
+#define nbpTupleMax 15
+
+#define nbpHeaderSize 2
+#define nbpTupleSize 5
+
+#define nbpSkt 2 /* NIS */
+
+
+/* Routing Table Maint. Protocol */
+
+#define rtmpSkt 1 /* number of RTMP socket */
+#define rtmpSize 4 /* minimum size */
+#define rtmpTupleSize 3
+
+
+/* Zone Information Protocol */
+
+struct zipHeader {
+ u_int8_t command;
+ u_int8_t netcount;
+};
+
+#define zipHeaderSize 2
+#define zipQuery 1
+#define zipReply 2
+#define zipTakedown 3
+#define zipBringup 4
+#define ddpZIP 6
+#define zipSkt 6
+#define GetMyZone 7
+#define GetZoneList 8
+
+/*
+ * UDP port range used for ddp-in-udp encapsulation is 16512-16639
+ * for client sockets (128-255) and 200-327 for server sockets
+ * (0-127). We also try to recognize the pre-April 88 server
+ * socket range of 768-895.
+ */
+#define atalk_port(p) \
+ (((unsigned)((p) - 16512) < 128) || \
+ ((unsigned)((p) - 200) < 128) || \
+ ((unsigned)((p) - 768) < 128))
diff --git a/freebsd/contrib/tcpdump/arcnet.h b/freebsd/contrib/tcpdump/arcnet.h
new file mode 100644
index 00000000..3b609566
--- /dev/null
+++ b/freebsd/contrib/tcpdump/arcnet.h
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) $Id: arcnet.h,v 1.3 2003-01-23 09:05:37 guy Exp $ (LBL)
+ *
+ * from: NetBSD: if_arc.h,v 1.13 1999/11/19 20:41:19 thorpej Exp
+ */
+
+/*
+ * Structure of a 2.5MB/s Arcnet header on the BSDs,
+ * as given to interface code.
+ */
+struct arc_header {
+ u_int8_t arc_shost;
+ u_int8_t arc_dhost;
+ u_int8_t arc_type;
+ /*
+ * only present for newstyle encoding with LL fragmentation.
+ * Don't use sizeof(anything), use ARC_HDR{,NEW}LEN instead.
+ */
+ u_int8_t arc_flag;
+ u_int16_t arc_seqid;
+
+ /*
+ * only present in exception packets (arc_flag == 0xff)
+ */
+ u_int8_t arc_type2; /* same as arc_type */
+ u_int8_t arc_flag2; /* real flag value */
+ u_int16_t arc_seqid2; /* real seqid value */
+};
+
+#define ARC_HDRLEN 3
+#define ARC_HDRNEWLEN 6
+#define ARC_HDRNEWLEN_EXC 10
+
+/* RFC 1051 */
+#define ARCTYPE_IP_OLD 240 /* IP protocol */
+#define ARCTYPE_ARP_OLD 241 /* address resolution protocol */
+
+/* RFC 1201 */
+#define ARCTYPE_IP 212 /* IP protocol */
+#define ARCTYPE_ARP 213 /* address resolution protocol */
+#define ARCTYPE_REVARP 214 /* reverse addr resolution protocol */
+
+#define ARCTYPE_ATALK 221 /* Appletalk */
+#define ARCTYPE_BANIAN 247 /* Banyan Vines */
+#define ARCTYPE_IPX 250 /* Novell IPX */
+
+#define ARCTYPE_INET6 0xc4 /* IPng */
+#define ARCTYPE_DIAGNOSE 0x80 /* as per ANSI/ATA 878.1 */
+
+/*
+ * Structure of a 2.5MB/s Arcnet header on Linux. Linux has
+ * an extra "offset" field when given to interface code, and
+ * never presents packets that look like exception frames.
+ */
+struct arc_linux_header {
+ u_int8_t arc_shost;
+ u_int8_t arc_dhost;
+ u_int16_t arc_offset;
+ u_int8_t arc_type;
+ /*
+ * only present for newstyle encoding with LL fragmentation.
+ * Don't use sizeof(anything), use ARC_LINUX_HDR{,NEW}LEN
+ * instead.
+ */
+ u_int8_t arc_flag;
+ u_int16_t arc_seqid;
+};
+
+#define ARC_LINUX_HDRLEN 5
+#define ARC_LINUX_HDRNEWLEN 8
diff --git a/freebsd/contrib/tcpdump/atm.h b/freebsd/contrib/tcpdump/atm.h
new file mode 100644
index 00000000..65ac5c17
--- /dev/null
+++ b/freebsd/contrib/tcpdump/atm.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2002 Guy Harris.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * The name of Guy Harris may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /tcpdump/master/tcpdump/atm.h,v 1.3 2006-02-08 01:43:00 hannes Exp $
+ */
+
+/*
+ * Traffic types for ATM.
+ */
+#define ATM_UNKNOWN 0 /* Unknown */
+#define ATM_LANE 1 /* LANE */
+#define ATM_LLC 2 /* LLC encapsulation */
+
+/*
+ * some OAM cell captures (most notably Juniper's)
+ * do not deliver a heading HEC byte
+ */
+#define ATM_OAM_NOHEC 0
+#define ATM_OAM_HEC 1
+#define ATM_HDR_LEN_NOHEC 4
diff --git a/freebsd/contrib/tcpdump/bgp.h b/freebsd/contrib/tcpdump/bgp.h
new file mode 100644
index 00000000..50815960
--- /dev/null
+++ b/freebsd/contrib/tcpdump/bgp.h
@@ -0,0 +1,17 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/bgp.h,v 1.3 2004-06-16 08:45:15 hannes Exp $ (LBL) */
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+extern char *bgp_vpn_rd_print (const u_char *);
diff --git a/freebsd/contrib/tcpdump/bootp.h b/freebsd/contrib/tcpdump/bootp.h
new file mode 100644
index 00000000..b1b81dce
--- /dev/null
+++ b/freebsd/contrib/tcpdump/bootp.h
@@ -0,0 +1,231 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/bootp.h,v 1.19 2008-04-22 09:46:03 hannes Exp $ (LBL) */
+/*
+ * Bootstrap Protocol (BOOTP). RFC951 and RFC1048.
+ *
+ * This file specifies the "implementation-independent" BOOTP protocol
+ * information which is common to both client and server.
+ *
+ * Copyright 1988 by Carnegie Mellon.
+ *
+ * Permission to use, copy, modify, and distribute this program for any
+ * purpose and without fee is hereby granted, provided that this copyright
+ * and permission notice appear on all copies and supporting documentation,
+ * the name of Carnegie Mellon not be used in advertising or publicity
+ * pertaining to distribution of the program without specific prior
+ * permission, and notice be given in supporting documentation that copying
+ * and distribution is by permission of Carnegie Mellon and Stanford
+ * University. Carnegie Mellon makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+
+struct bootp {
+ u_int8_t bp_op; /* packet opcode type */
+ u_int8_t bp_htype; /* hardware addr type */
+ u_int8_t bp_hlen; /* hardware addr length */
+ u_int8_t bp_hops; /* gateway hops */
+ u_int32_t bp_xid; /* transaction ID */
+ u_int16_t bp_secs; /* seconds since boot began */
+ u_int16_t bp_flags; /* flags - see bootp_flag_values[]
+ in print-bootp.c */
+ struct in_addr bp_ciaddr; /* client IP address */
+ struct in_addr bp_yiaddr; /* 'your' IP address */
+ struct in_addr bp_siaddr; /* server IP address */
+ struct in_addr bp_giaddr; /* gateway IP address */
+ u_int8_t bp_chaddr[16]; /* client hardware address */
+ u_int8_t bp_sname[64]; /* server host name */
+ u_int8_t bp_file[128]; /* boot file name */
+ u_int8_t bp_vend[64]; /* vendor-specific area */
+} UNALIGNED;
+
+/*
+ * UDP port numbers, server and client.
+ */
+#define IPPORT_BOOTPS 67
+#define IPPORT_BOOTPC 68
+
+#define BOOTPREPLY 2
+#define BOOTPREQUEST 1
+
+/*
+ * Vendor magic cookie (v_magic) for CMU
+ */
+#define VM_CMU "CMU"
+
+/*
+ * Vendor magic cookie (v_magic) for RFC1048
+ */
+#define VM_RFC1048 { 99, 130, 83, 99 }
+
+
+
+/*
+ * RFC1048 tag values used to specify what information is being supplied in
+ * the vendor field of the packet.
+ */
+
+#define TAG_PAD ((u_int8_t) 0)
+#define TAG_SUBNET_MASK ((u_int8_t) 1)
+#define TAG_TIME_OFFSET ((u_int8_t) 2)
+#define TAG_GATEWAY ((u_int8_t) 3)
+#define TAG_TIME_SERVER ((u_int8_t) 4)
+#define TAG_NAME_SERVER ((u_int8_t) 5)
+#define TAG_DOMAIN_SERVER ((u_int8_t) 6)
+#define TAG_LOG_SERVER ((u_int8_t) 7)
+#define TAG_COOKIE_SERVER ((u_int8_t) 8)
+#define TAG_LPR_SERVER ((u_int8_t) 9)
+#define TAG_IMPRESS_SERVER ((u_int8_t) 10)
+#define TAG_RLP_SERVER ((u_int8_t) 11)
+#define TAG_HOSTNAME ((u_int8_t) 12)
+#define TAG_BOOTSIZE ((u_int8_t) 13)
+#define TAG_END ((u_int8_t) 255)
+/* RFC1497 tags */
+#define TAG_DUMPPATH ((u_int8_t) 14)
+#define TAG_DOMAINNAME ((u_int8_t) 15)
+#define TAG_SWAP_SERVER ((u_int8_t) 16)
+#define TAG_ROOTPATH ((u_int8_t) 17)
+#define TAG_EXTPATH ((u_int8_t) 18)
+/* RFC2132 */
+#define TAG_IP_FORWARD ((u_int8_t) 19)
+#define TAG_NL_SRCRT ((u_int8_t) 20)
+#define TAG_PFILTERS ((u_int8_t) 21)
+#define TAG_REASS_SIZE ((u_int8_t) 22)
+#define TAG_DEF_TTL ((u_int8_t) 23)
+#define TAG_MTU_TIMEOUT ((u_int8_t) 24)
+#define TAG_MTU_TABLE ((u_int8_t) 25)
+#define TAG_INT_MTU ((u_int8_t) 26)
+#define TAG_LOCAL_SUBNETS ((u_int8_t) 27)
+#define TAG_BROAD_ADDR ((u_int8_t) 28)
+#define TAG_DO_MASK_DISC ((u_int8_t) 29)
+#define TAG_SUPPLY_MASK ((u_int8_t) 30)
+#define TAG_DO_RDISC ((u_int8_t) 31)
+#define TAG_RTR_SOL_ADDR ((u_int8_t) 32)
+#define TAG_STATIC_ROUTE ((u_int8_t) 33)
+#define TAG_USE_TRAILERS ((u_int8_t) 34)
+#define TAG_ARP_TIMEOUT ((u_int8_t) 35)
+#define TAG_ETH_ENCAP ((u_int8_t) 36)
+#define TAG_TCP_TTL ((u_int8_t) 37)
+#define TAG_TCP_KEEPALIVE ((u_int8_t) 38)
+#define TAG_KEEPALIVE_GO ((u_int8_t) 39)
+#define TAG_NIS_DOMAIN ((u_int8_t) 40)
+#define TAG_NIS_SERVERS ((u_int8_t) 41)
+#define TAG_NTP_SERVERS ((u_int8_t) 42)
+#define TAG_VENDOR_OPTS ((u_int8_t) 43)
+#define TAG_NETBIOS_NS ((u_int8_t) 44)
+#define TAG_NETBIOS_DDS ((u_int8_t) 45)
+#define TAG_NETBIOS_NODE ((u_int8_t) 46)
+#define TAG_NETBIOS_SCOPE ((u_int8_t) 47)
+#define TAG_XWIN_FS ((u_int8_t) 48)
+#define TAG_XWIN_DM ((u_int8_t) 49)
+#define TAG_NIS_P_DOMAIN ((u_int8_t) 64)
+#define TAG_NIS_P_SERVERS ((u_int8_t) 65)
+#define TAG_MOBILE_HOME ((u_int8_t) 68)
+#define TAG_SMPT_SERVER ((u_int8_t) 69)
+#define TAG_POP3_SERVER ((u_int8_t) 70)
+#define TAG_NNTP_SERVER ((u_int8_t) 71)
+#define TAG_WWW_SERVER ((u_int8_t) 72)
+#define TAG_FINGER_SERVER ((u_int8_t) 73)
+#define TAG_IRC_SERVER ((u_int8_t) 74)
+#define TAG_STREETTALK_SRVR ((u_int8_t) 75)
+#define TAG_STREETTALK_STDA ((u_int8_t) 76)
+/* DHCP options */
+#define TAG_REQUESTED_IP ((u_int8_t) 50)
+#define TAG_IP_LEASE ((u_int8_t) 51)
+#define TAG_OPT_OVERLOAD ((u_int8_t) 52)
+#define TAG_TFTP_SERVER ((u_int8_t) 66)
+#define TAG_BOOTFILENAME ((u_int8_t) 67)
+#define TAG_DHCP_MESSAGE ((u_int8_t) 53)
+#define TAG_SERVER_ID ((u_int8_t) 54)
+#define TAG_PARM_REQUEST ((u_int8_t) 55)
+#define TAG_MESSAGE ((u_int8_t) 56)
+#define TAG_MAX_MSG_SIZE ((u_int8_t) 57)
+#define TAG_RENEWAL_TIME ((u_int8_t) 58)
+#define TAG_REBIND_TIME ((u_int8_t) 59)
+#define TAG_VENDOR_CLASS ((u_int8_t) 60)
+#define TAG_CLIENT_ID ((u_int8_t) 61)
+/* RFC 2241 */
+#define TAG_NDS_SERVERS ((u_int8_t) 85)
+#define TAG_NDS_TREE_NAME ((u_int8_t) 86)
+#define TAG_NDS_CONTEXT ((u_int8_t) 87)
+/* RFC 2242 */
+#define TAG_NDS_IPDOMAIN ((u_int8_t) 62)
+#define TAG_NDS_IPINFO ((u_int8_t) 63)
+/* RFC 2485 */
+#define TAG_OPEN_GROUP_UAP ((u_int8_t) 98)
+/* RFC 2563 */
+#define TAG_DISABLE_AUTOCONF ((u_int8_t) 116)
+/* RFC 2610 */
+#define TAG_SLP_DA ((u_int8_t) 78)
+#define TAG_SLP_SCOPE ((u_int8_t) 79)
+/* RFC 2937 */
+#define TAG_NS_SEARCH ((u_int8_t) 117)
+/* RFC 3011 */
+#define TAG_IP4_SUBNET_SELECT ((u_int8_t) 118)
+/* RFC 3442 */
+#define TAG_CLASSLESS_STATIC_RT ((u_int8_t) 121)
+#define TAG_CLASSLESS_STA_RT_MS ((u_int8_t) 249)
+/* ftp://ftp.isi.edu/.../assignments/bootp-dhcp-extensions */
+#define TAG_USER_CLASS ((u_int8_t) 77)
+#define TAG_SLP_NAMING_AUTH ((u_int8_t) 80)
+#define TAG_CLIENT_FQDN ((u_int8_t) 81)
+#define TAG_AGENT_CIRCUIT ((u_int8_t) 82)
+#define TAG_AGENT_REMOTE ((u_int8_t) 83)
+#define TAG_AGENT_MASK ((u_int8_t) 84)
+#define TAG_TZ_STRING ((u_int8_t) 88)
+#define TAG_FQDN_OPTION ((u_int8_t) 89)
+#define TAG_AUTH ((u_int8_t) 90)
+#define TAG_VINES_SERVERS ((u_int8_t) 91)
+#define TAG_SERVER_RANK ((u_int8_t) 92)
+#define TAG_CLIENT_ARCH ((u_int8_t) 93)
+#define TAG_CLIENT_NDI ((u_int8_t) 94)
+#define TAG_CLIENT_GUID ((u_int8_t) 97)
+#define TAG_LDAP_URL ((u_int8_t) 95)
+#define TAG_6OVER4 ((u_int8_t) 96)
+#define TAG_PRINTER_NAME ((u_int8_t) 100)
+#define TAG_MDHCP_SERVER ((u_int8_t) 101)
+#define TAG_IPX_COMPAT ((u_int8_t) 110)
+#define TAG_NETINFO_PARENT ((u_int8_t) 112)
+#define TAG_NETINFO_PARENT_TAG ((u_int8_t) 113)
+#define TAG_URL ((u_int8_t) 114)
+#define TAG_FAILOVER ((u_int8_t) 115)
+#define TAG_EXTENDED_REQUEST ((u_int8_t) 126)
+#define TAG_EXTENDED_OPTION ((u_int8_t) 127)
+
+
+/* DHCP Message types (values for TAG_DHCP_MESSAGE option) */
+#define DHCPDISCOVER 1
+#define DHCPOFFER 2
+#define DHCPREQUEST 3
+#define DHCPDECLINE 4
+#define DHCPACK 5
+#define DHCPNAK 6
+#define DHCPRELEASE 7
+#define DHCPINFORM 8
+
+
+/*
+ * "vendor" data permitted for CMU bootp clients.
+ */
+
+struct cmu_vend {
+ u_int8_t v_magic[4]; /* magic number */
+ u_int32_t v_flags; /* flags/opcodes, etc. */
+ struct in_addr v_smask; /* Subnet mask */
+ struct in_addr v_dgate; /* Default gateway */
+ struct in_addr v_dns1, v_dns2; /* Domain name servers */
+ struct in_addr v_ins1, v_ins2; /* IEN-116 name servers */
+ struct in_addr v_ts1, v_ts2; /* Time servers */
+ u_int8_t v_unused[24]; /* currently unused */
+} UNALIGNED;
+
+
+/* v_flags values */
+#define VF_SMASK 1 /* Subnet mask field contains valid data */
+
+/* RFC 4702 DHCP Client FQDN Option */
+
+#define CLIENT_FQDN_FLAGS_S 0x01
+#define CLIENT_FQDN_FLAGS_O 0x02
+#define CLIENT_FQDN_FLAGS_E 0x04
+#define CLIENT_FQDN_FLAGS_N 0x08
diff --git a/freebsd/contrib/tcpdump/bpf_dump.c b/freebsd/contrib/tcpdump/bpf_dump.c
new file mode 100644
index 00000000..841f8d77
--- /dev/null
+++ b/freebsd/contrib/tcpdump/bpf_dump.c
@@ -0,0 +1,68 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1992, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/bpf_dump.c,v 1.17 2008-02-14 20:53:49 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <pcap.h>
+#include <stdio.h>
+
+#include "interface.h"
+
+void
+bpf_dump(const struct bpf_program *p, int option)
+{
+ struct bpf_insn *insn;
+ int i;
+ int n = p->bf_len;
+
+ insn = p->bf_insns;
+ if (option > 2) {
+ printf("%d\n", n);
+ for (i = 0; i < n; ++insn, ++i) {
+ printf("%u %u %u %u\n", insn->code,
+ insn->jt, insn->jf, insn->k);
+ }
+ return ;
+ }
+ if (option > 1) {
+ for (i = 0; i < n; ++insn, ++i)
+ printf("{ 0x%x, %d, %d, 0x%08x },\n",
+ insn->code, insn->jt, insn->jf, insn->k);
+ return;
+ }
+ for (i = 0; i < n; ++insn, ++i) {
+#ifdef BDEBUG
+ extern int bids[];
+ printf(bids[i] > 0 ? "[%02d]" : " -- ", bids[i] - 1);
+#endif
+ puts(bpf_image(insn, i));
+ }
+}
diff --git a/freebsd/contrib/tcpdump/chdlc.h b/freebsd/contrib/tcpdump/chdlc.h
new file mode 100644
index 00000000..d1172633
--- /dev/null
+++ b/freebsd/contrib/tcpdump/chdlc.h
@@ -0,0 +1,27 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/chdlc.h,v 1.1 2000-09-18 05:11:43 guy Exp $ (LBL) */
+/*
+ * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#define CHDLC_HDRLEN 4
+#define CHDLC_UNICAST 0x0f
+#define CHDLC_BCAST 0x8f
+#define CHDLC_TYPE_SLARP 0x8035
+#define CHDLC_TYPE_CDP 0x2000
diff --git a/freebsd/contrib/tcpdump/checksum.c b/freebsd/contrib/tcpdump/checksum.c
new file mode 100644
index 00000000..a9077303
--- /dev/null
+++ b/freebsd/contrib/tcpdump/checksum.c
@@ -0,0 +1,196 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1998-2006 The TCPDUMP project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * miscellaneous checksumming routines
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/checksum.c,v 1.4 2006-09-25 09:23:32 hannes Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "interface.h"
+
+/*
+ * CRC-10 table generated using the following Python snippet:
+
+import sys
+
+crc_table = []
+for i in range(256):
+ accum = i << 2
+ for j in range(8):
+ accum <<= 1
+ if accum & 0x400:
+ accum ^= 0x633
+ crc_table.append(accum)
+
+for i in range(len(crc_table)/8):
+ for j in range(8):
+ sys.stdout.write("0x%04x, " % crc_table[i*8+j])
+ sys.stdout.write("\n")
+
+ */
+static const u_int16_t crc10_table[256] =
+{
+ 0x0000, 0x0233, 0x0255, 0x0066, 0x0299, 0x00aa, 0x00cc, 0x02ff,
+ 0x0301, 0x0132, 0x0154, 0x0367, 0x0198, 0x03ab, 0x03cd, 0x01fe,
+ 0x0031, 0x0202, 0x0264, 0x0057, 0x02a8, 0x009b, 0x00fd, 0x02ce,
+ 0x0330, 0x0103, 0x0165, 0x0356, 0x01a9, 0x039a, 0x03fc, 0x01cf,
+ 0x0062, 0x0251, 0x0237, 0x0004, 0x02fb, 0x00c8, 0x00ae, 0x029d,
+ 0x0363, 0x0150, 0x0136, 0x0305, 0x01fa, 0x03c9, 0x03af, 0x019c,
+ 0x0053, 0x0260, 0x0206, 0x0035, 0x02ca, 0x00f9, 0x009f, 0x02ac,
+ 0x0352, 0x0161, 0x0107, 0x0334, 0x01cb, 0x03f8, 0x039e, 0x01ad,
+ 0x00c4, 0x02f7, 0x0291, 0x00a2, 0x025d, 0x006e, 0x0008, 0x023b,
+ 0x03c5, 0x01f6, 0x0190, 0x03a3, 0x015c, 0x036f, 0x0309, 0x013a,
+ 0x00f5, 0x02c6, 0x02a0, 0x0093, 0x026c, 0x005f, 0x0039, 0x020a,
+ 0x03f4, 0x01c7, 0x01a1, 0x0392, 0x016d, 0x035e, 0x0338, 0x010b,
+ 0x00a6, 0x0295, 0x02f3, 0x00c0, 0x023f, 0x000c, 0x006a, 0x0259,
+ 0x03a7, 0x0194, 0x01f2, 0x03c1, 0x013e, 0x030d, 0x036b, 0x0158,
+ 0x0097, 0x02a4, 0x02c2, 0x00f1, 0x020e, 0x003d, 0x005b, 0x0268,
+ 0x0396, 0x01a5, 0x01c3, 0x03f0, 0x010f, 0x033c, 0x035a, 0x0169,
+ 0x0188, 0x03bb, 0x03dd, 0x01ee, 0x0311, 0x0122, 0x0144, 0x0377,
+ 0x0289, 0x00ba, 0x00dc, 0x02ef, 0x0010, 0x0223, 0x0245, 0x0076,
+ 0x01b9, 0x038a, 0x03ec, 0x01df, 0x0320, 0x0113, 0x0175, 0x0346,
+ 0x02b8, 0x008b, 0x00ed, 0x02de, 0x0021, 0x0212, 0x0274, 0x0047,
+ 0x01ea, 0x03d9, 0x03bf, 0x018c, 0x0373, 0x0140, 0x0126, 0x0315,
+ 0x02eb, 0x00d8, 0x00be, 0x028d, 0x0072, 0x0241, 0x0227, 0x0014,
+ 0x01db, 0x03e8, 0x038e, 0x01bd, 0x0342, 0x0171, 0x0117, 0x0324,
+ 0x02da, 0x00e9, 0x008f, 0x02bc, 0x0043, 0x0270, 0x0216, 0x0025,
+ 0x014c, 0x037f, 0x0319, 0x012a, 0x03d5, 0x01e6, 0x0180, 0x03b3,
+ 0x024d, 0x007e, 0x0018, 0x022b, 0x00d4, 0x02e7, 0x0281, 0x00b2,
+ 0x017d, 0x034e, 0x0328, 0x011b, 0x03e4, 0x01d7, 0x01b1, 0x0382,
+ 0x027c, 0x004f, 0x0029, 0x021a, 0x00e5, 0x02d6, 0x02b0, 0x0083,
+ 0x012e, 0x031d, 0x037b, 0x0148, 0x03b7, 0x0184, 0x01e2, 0x03d1,
+ 0x022f, 0x001c, 0x007a, 0x0249, 0x00b6, 0x0285, 0x02e3, 0x00d0,
+ 0x011f, 0x032c, 0x034a, 0x0179, 0x0386, 0x01b5, 0x01d3, 0x03e0,
+ 0x021e, 0x002d, 0x004b, 0x0278, 0x0087, 0x02b4, 0x02d2, 0x00e1
+};
+
+static void
+init_crc10_table(void)
+{
+#define CRC10_POLYNOMIAL 0x633
+ register int i, j;
+ register u_int16_t accum;
+ u_int16_t verify_crc10_table[256];
+
+ for ( i = 0; i < 256; i++ )
+ {
+ accum = ((unsigned short) i << 2);
+ for ( j = 0; j < 8; j++ )
+ {
+ if ((accum <<= 1) & 0x400) accum ^= CRC10_POLYNOMIAL;
+ }
+ verify_crc10_table[i] = accum;
+ }
+ assert(memcmp(verify_crc10_table,
+ crc10_table,
+ sizeof(verify_crc10_table)) == 0);
+#undef CRC10_POLYNOMIAL
+}
+
+u_int16_t
+verify_crc10_cksum(u_int16_t accum, const u_char *p, int length)
+{
+ register int i;
+
+ for ( i = 0; i < length; i++ )
+ {
+ accum = ((accum << 8) & 0x3ff)
+ ^ crc10_table[( accum >> 2) & 0xff]
+ ^ *p++;
+ }
+ return accum;
+}
+
+/* precompute checksum tables */
+void
+init_checksum(void) {
+
+ init_crc10_table();
+
+}
+
+/*
+ * Creates the OSI Fletcher checksum. See 8473-1, Appendix C, section C.3.
+ * The checksum field of the passed PDU does not need to be reset to zero.
+ */
+u_int16_t
+create_osi_cksum (const u_int8_t *pptr, int checksum_offset, int length)
+{
+
+ int x;
+ int y;
+ u_int32_t mul;
+ u_int32_t c0;
+ u_int32_t c1;
+ u_int16_t checksum;
+ int index;
+
+ c0 = 0;
+ c1 = 0;
+
+ for (index = 0; index < length; index++) {
+ /*
+ * Ignore the contents of the checksum field.
+ */
+ if (index == checksum_offset ||
+ index == checksum_offset+1) {
+ c1 += c0;
+ pptr++;
+ } else {
+ c0 = c0 + *(pptr++);
+ c1 += c0;
+ }
+ }
+
+ c0 = c0 % 255;
+ c1 = c1 % 255;
+
+ mul = (length - checksum_offset)*(c0);
+
+ x = mul - c0 - c1;
+ y = c1 - mul - 1;
+
+ if ( y >= 0 ) y++;
+ if ( x < 0 ) x--;
+
+ x %= 255;
+ y %= 255;
+
+
+ if (x == 0) x = 255;
+ if (y == 0) y = 255;
+
+ y &= 0x00FF;
+ checksum = ((x << 8) | y);
+
+ return checksum;
+}
diff --git a/freebsd/contrib/tcpdump/cpack.c b/freebsd/contrib/tcpdump/cpack.c
new file mode 100644
index 00000000..e34fc1dc
--- /dev/null
+++ b/freebsd/contrib/tcpdump/cpack.c
@@ -0,0 +1,146 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*-
+ * Copyright (c) 2003, 2004 David Young. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of David Young may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID
+ * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <tcpdump-stdinc.h>
+
+#include "cpack.h"
+#include "extract.h"
+
+u_int8_t *
+cpack_next_boundary(u_int8_t *buf, u_int8_t *p, size_t alignment)
+{
+ size_t misalignment = (size_t)(p - buf) % alignment;
+
+ if (misalignment == 0)
+ return p;
+
+ return p + (alignment - misalignment);
+}
+
+/* Advance to the next wordsize boundary. Return NULL if fewer than
+ * wordsize bytes remain in the buffer after the boundary. Otherwise,
+ * return a pointer to the boundary.
+ */
+u_int8_t *
+cpack_align_and_reserve(struct cpack_state *cs, size_t wordsize)
+{
+ u_int8_t *next;
+
+ /* Ensure alignment. */
+ next = cpack_next_boundary(cs->c_buf, cs->c_next, wordsize);
+
+ /* Too little space for wordsize bytes? */
+ if (next - cs->c_buf + wordsize > cs->c_len)
+ return NULL;
+
+ return next;
+}
+
+int
+cpack_init(struct cpack_state *cs, u_int8_t *buf, size_t buflen)
+{
+ memset(cs, 0, sizeof(*cs));
+
+ cs->c_buf = buf;
+ cs->c_len = buflen;
+ cs->c_next = cs->c_buf;
+
+ return 0;
+}
+
+/* Unpack a 64-bit unsigned integer. */
+int
+cpack_uint64(struct cpack_state *cs, u_int64_t *u)
+{
+ u_int8_t *next;
+
+ if ((next = cpack_align_and_reserve(cs, sizeof(*u))) == NULL)
+ return -1;
+
+ *u = EXTRACT_LE_64BITS(next);
+
+ /* Move pointer past the u_int64_t. */
+ cs->c_next = next + sizeof(*u);
+ return 0;
+}
+
+/* Unpack a 32-bit unsigned integer. */
+int
+cpack_uint32(struct cpack_state *cs, u_int32_t *u)
+{
+ u_int8_t *next;
+
+ if ((next = cpack_align_and_reserve(cs, sizeof(*u))) == NULL)
+ return -1;
+
+ *u = EXTRACT_LE_32BITS(next);
+
+ /* Move pointer past the u_int32_t. */
+ cs->c_next = next + sizeof(*u);
+ return 0;
+}
+
+/* Unpack a 16-bit unsigned integer. */
+int
+cpack_uint16(struct cpack_state *cs, u_int16_t *u)
+{
+ u_int8_t *next;
+
+ if ((next = cpack_align_and_reserve(cs, sizeof(*u))) == NULL)
+ return -1;
+
+ *u = EXTRACT_LE_16BITS(next);
+
+ /* Move pointer past the u_int16_t. */
+ cs->c_next = next + sizeof(*u);
+ return 0;
+}
+
+/* Unpack an 8-bit unsigned integer. */
+int
+cpack_uint8(struct cpack_state *cs, u_int8_t *u)
+{
+ /* No space left? */
+ if ((size_t)(cs->c_next - cs->c_buf) >= cs->c_len)
+ return -1;
+
+ *u = *cs->c_next;
+
+ /* Move pointer past the u_int8_t. */
+ cs->c_next++;
+ return 0;
+}
diff --git a/freebsd/contrib/tcpdump/cpack.h b/freebsd/contrib/tcpdump/cpack.h
new file mode 100644
index 00000000..74f97960
--- /dev/null
+++ b/freebsd/contrib/tcpdump/cpack.h
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 2003, 2004 David Young. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of David Young may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID
+ * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ */
+
+#ifndef _CPACK_H
+#define _CPACK_H
+
+struct cpack_state {
+ u_int8_t *c_buf;
+ u_int8_t *c_next;
+ size_t c_len;
+};
+
+int cpack_init(struct cpack_state *, u_int8_t *, size_t);
+
+int cpack_uint8(struct cpack_state *, u_int8_t *);
+int cpack_uint16(struct cpack_state *, u_int16_t *);
+int cpack_uint32(struct cpack_state *, u_int32_t *);
+int cpack_uint64(struct cpack_state *, u_int64_t *);
+
+u_int8_t *cpack_next_boundary(u_int8_t *buf, u_int8_t *p, size_t alignment);
+u_int8_t *cpack_align_and_reserve(struct cpack_state *cs, size_t wordsize);
+
+#define cpack_int8(__s, __p) cpack_uint8((__s), (u_int8_t*)(__p))
+#define cpack_int16(__s, __p) cpack_uint16((__s), (u_int16_t*)(__p))
+#define cpack_int32(__s, __p) cpack_uint32((__s), (u_int32_t*)(__p))
+#define cpack_int64(__s, __p) cpack_uint64((__s), (u_int64_t*)(__p))
+
+#endif /* _CPACK_H */
diff --git a/freebsd/contrib/tcpdump/dccp.h b/freebsd/contrib/tcpdump/dccp.h
new file mode 100644
index 00000000..5c66e23c
--- /dev/null
+++ b/freebsd/contrib/tcpdump/dccp.h
@@ -0,0 +1,139 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/dccp.h,v 1.5 2006-11-02 09:05:23 hannes Exp $ (LBL) */
+/*
+ * Copyright (C) Arnaldo Carvalho de Melo 2004
+ * Copyright (C) Ian McDonald 2005 <iam4@cs.waikato.ac.nz>
+ * Copyright (C) Yoshifumi Nishida 2005
+ *
+ * This software may be distributed either under the terms of the
+ * BSD-style license that accompanies tcpdump or the GNU GPL version 2
+ */
+
+#ifndef __DCCP_HDR__
+#define __DCCP_HDR__
+
+/**
+ * struct dccp_hdr - generic part of DCCP packet header
+ *
+ * @dccph_sport - Relevant port on the endpoint that sent this packet
+ * @dccph_dport - Relevant port on the other endpoint
+ * @dccph_doff - Data Offset from the start of the DCCP header, in 32-bit words
+ * @dccph_ccval - Used by the HC-Sender CCID
+ * @dccph_cscov - Parts of the packet that are covered by the Checksum field
+ * @dccph_checksum - Internet checksum, depends on dccph_cscov
+ * @dccph_x - 0 = 24 bit sequence number, 1 = 48
+ * @dccph_type - packet type, see DCCP_PKT_ prefixed macros
+ * @dccph_seq - sequence number high or low order 24 bits, depends on dccph_x
+ */
+struct dccp_hdr {
+ u_int16_t dccph_sport,
+ dccph_dport;
+ u_int8_t dccph_doff;
+ u_int8_t dccph_ccval_cscov;
+ u_int16_t dccph_checksum;
+ union {
+ u_int8_t dccph_xtr;
+ u_int32_t dccph_seq;
+ } dccph_xtrs;
+};
+
+#define DCCPH_CCVAL(dh) (((dh)->dccph_ccval_cscov >> 4) & 0xF)
+#define DCCPH_CSCOV(dh) (((dh)->dccph_ccval_cscov) & 0xF)
+
+#define DCCPH_X(dh) ((dh)->dccph_xtrs.dccph_xtr & 1)
+#define DCCPH_TYPE(dh) (((dh)->dccph_xtrs.dccph_xtr >> 1) & 0xF)
+#define DCCPH_SEQ(dh) (((dh)->dccph_xtrs.dccph_seq) >> 8)
+
+/**
+ * struct dccp_hdr_ext - the low bits of a 48 bit seq packet
+ *
+ * @dccph_seq_low - low 24 bits of a 48 bit seq packet
+ */
+struct dccp_hdr_ext {
+ u_int32_t dccph_seq_low;
+};
+
+/**
+ * struct dccp_hdr_request - Conection initiation request header
+ *
+ * @dccph_req_service - Service to which the client app wants to connect
+ */
+struct dccp_hdr_request {
+ u_int32_t dccph_req_service;
+};
+
+/**
+ * struct dccp_hdr_ack_bits - acknowledgment bits common to most packets
+ *
+ * @dccph_resp_ack_nr_high - 48 bit ack number high order bits, contains GSR
+ * @dccph_resp_ack_nr_low - 48 bit ack number low order bits, contains GSR
+ */
+struct dccp_hdr_ack_bits {
+ u_int32_t dccph_ra;
+ u_int32_t dccph_ack_nr_low;
+};
+
+#define DCCPH_ACK(dh_ack) ((dh_ack)->dccph_ra >> 8)
+
+/**
+ * struct dccp_hdr_response - Conection initiation response header
+ *
+ * @dccph_resp_ack_nr_high - 48 bit ack number high order bits, contains GSR
+ * @dccph_resp_ack_nr_low - 48 bit ack number low order bits, contains GSR
+ * @dccph_resp_service - Echoes the Service Code on a received DCCP-Request
+ */
+struct dccp_hdr_response {
+ struct dccp_hdr_ack_bits dccph_resp_ack;
+ u_int32_t dccph_resp_service;
+};
+
+#if 0
+static inline struct dccp_hdr_data *dccp_hdr_data(struct dccp_hdr *hdrg)
+{
+ const int ext = DCCPH_X(hdrg) ? sizeof(struct dccp_hdr_ext) : 0;
+
+ return (struct dccp_hdr_data *)(((u_char *)hdrg) + sizeof(hdrg) + ext);
+}
+#endif
+
+/**
+ * struct dccp_hdr_reset - Unconditionally shut down a connection
+ *
+ * @dccph_reset_service - Echoes the Service Code on a received DCCP-Request
+ */
+struct dccp_hdr_reset {
+ struct dccp_hdr_ack_bits dccph_reset_ack;
+ u_int8_t dccph_reset_code,
+ dccph_reset_data[3];
+};
+
+enum dccp_pkt_type {
+ DCCP_PKT_REQUEST = 0,
+ DCCP_PKT_RESPONSE,
+ DCCP_PKT_DATA,
+ DCCP_PKT_ACK,
+ DCCP_PKT_DATAACK,
+ DCCP_PKT_CLOSEREQ,
+ DCCP_PKT_CLOSE,
+ DCCP_PKT_RESET,
+ DCCP_PKT_SYNC,
+ DCCP_PKT_SYNCACK,
+ DCCP_PKT_INVALID
+};
+
+enum dccp_reset_codes {
+ DCCP_RESET_CODE_UNSPECIFIED = 0,
+ DCCP_RESET_CODE_CLOSED,
+ DCCP_RESET_CODE_ABORTED,
+ DCCP_RESET_CODE_NO_CONNECTION,
+ DCCP_RESET_CODE_PACKET_ERROR,
+ DCCP_RESET_CODE_OPTION_ERROR,
+ DCCP_RESET_CODE_MANDATORY_ERROR,
+ DCCP_RESET_CODE_CONNECTION_REFUSED,
+ DCCP_RESET_CODE_BAD_SERVICE_CODE,
+ DCCP_RESET_CODE_TOO_BUSY,
+ DCCP_RESET_CODE_BAD_INIT_COOKIE,
+ DCCP_RESET_CODE_AGGRESSION_PENALTY,
+ __DCCP_RESET_CODE_LAST
+};
+
+#endif /* __DCCP_HDR__ */
diff --git a/freebsd/contrib/tcpdump/decnet.h b/freebsd/contrib/tcpdump/decnet.h
new file mode 100644
index 00000000..d25d157d
--- /dev/null
+++ b/freebsd/contrib/tcpdump/decnet.h
@@ -0,0 +1,461 @@
+/*
+ * Copyright (c) 1992, 1994, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /tcpdump/master/tcpdump/decnet.h,v 1.11 2002-12-11 07:13:50 guy Exp $ (LBL)
+ */
+
+#ifndef WIN32
+typedef u_int8_t byte[1]; /* single byte field */
+#else
+/*
+ * the keyword 'byte' generates conflicts in Windows
+ */
+typedef unsigned char Byte[1]; /* single byte field */
+#define byte Byte
+#endif /* WIN32 */
+typedef u_int8_t word[2]; /* 2 byte field */
+typedef u_int8_t longword[4]; /* 4 bytes field */
+
+/*
+ * Definitions for DECNET Phase IV protocol headers
+ */
+union etheraddress {
+ u_int8_t dne_addr[6]; /* full ethernet address */
+ struct {
+ u_int8_t dne_hiord[4]; /* DECnet HIORD prefix */
+ u_int8_t dne_nodeaddr[2]; /* DECnet node address */
+ } dne_remote;
+};
+
+typedef union etheraddress etheraddr; /* Ethernet address */
+
+#define HIORD 0x000400aa /* high 32-bits of address (swapped) */
+
+#define AREAMASK 0176000 /* mask for area field */
+#define AREASHIFT 10 /* bit-offset for area field */
+#define NODEMASK 01777 /* mask for node address field */
+
+#define DN_MAXADDL 20 /* max size of DECnet address */
+struct dn_naddr {
+ u_int16_t a_len; /* length of address */
+ u_int8_t a_addr[DN_MAXADDL]; /* address as bytes */
+};
+
+/*
+ * Define long and short header formats.
+ */
+struct shorthdr
+ {
+ byte sh_flags; /* route flags */
+ word sh_dst; /* destination node address */
+ word sh_src; /* source node address */
+ byte sh_visits; /* visit count */
+ };
+
+struct longhdr
+ {
+ byte lg_flags; /* route flags */
+ byte lg_darea; /* destination area (reserved) */
+ byte lg_dsarea; /* destination subarea (reserved) */
+ etheraddr lg_dst; /* destination id */
+ byte lg_sarea; /* source area (reserved) */
+ byte lg_ssarea; /* source subarea (reserved) */
+ etheraddr lg_src; /* source id */
+ byte lg_nextl2; /* next level 2 router (reserved) */
+ byte lg_visits; /* visit count */
+ byte lg_service; /* service class (reserved) */
+ byte lg_pt; /* protocol type (reserved) */
+ };
+
+union routehdr
+ {
+ struct shorthdr rh_short; /* short route header */
+ struct longhdr rh_long; /* long route header */
+ };
+
+/*
+ * Define the values of various fields in the protocol messages.
+ *
+ * 1. Data packet formats.
+ */
+#define RMF_MASK 7 /* mask for message type */
+#define RMF_SHORT 2 /* short message format */
+#define RMF_LONG 6 /* long message format */
+#ifndef RMF_RQR
+#define RMF_RQR 010 /* request return to sender */
+#define RMF_RTS 020 /* returning to sender */
+#define RMF_IE 040 /* intra-ethernet packet */
+#endif /* RMR_RQR */
+#define RMF_FVER 0100 /* future version flag */
+#define RMF_PAD 0200 /* pad field */
+#define RMF_PADMASK 0177 /* pad field mask */
+
+#define VIS_MASK 077 /* visit field mask */
+
+/*
+ * 2. Control packet formats.
+ */
+#define RMF_CTLMASK 017 /* mask for message type */
+#define RMF_CTLMSG 01 /* control message indicator */
+#define RMF_INIT 01 /* initialization message */
+#define RMF_VER 03 /* verification message */
+#define RMF_TEST 05 /* hello and test message */
+#define RMF_L1ROUT 07 /* level 1 routing message */
+#define RMF_L2ROUT 011 /* level 2 routing message */
+#define RMF_RHELLO 013 /* router hello message */
+#define RMF_EHELLO 015 /* endnode hello message */
+
+#define TI_L2ROUT 01 /* level 2 router */
+#define TI_L1ROUT 02 /* level 1 router */
+#define TI_ENDNODE 03 /* endnode */
+#define TI_VERIF 04 /* verification required */
+#define TI_BLOCK 010 /* blocking requested */
+
+#define VE_VERS 2 /* version number (2) */
+#define VE_ECO 0 /* ECO number */
+#define VE_UECO 0 /* user ECO number (0) */
+
+#define P3_VERS 1 /* phase III version number (1) */
+#define P3_ECO 3 /* ECO number (3) */
+#define P3_UECO 0 /* user ECO number (0) */
+
+#define II_L2ROUT 01 /* level 2 router */
+#define II_L1ROUT 02 /* level 1 router */
+#define II_ENDNODE 03 /* endnode */
+#define II_VERIF 04 /* verification required */
+#define II_NOMCAST 040 /* no multicast traffic accepted */
+#define II_BLOCK 0100 /* blocking requested */
+#define II_TYPEMASK 03 /* mask for node type */
+
+#define TESTDATA 0252 /* test data bytes */
+#define TESTLEN 1 /* length of transmitted test data */
+
+/*
+ * Define control message formats.
+ */
+struct initmsgIII /* phase III initialization message */
+ {
+ byte inIII_flags; /* route flags */
+ word inIII_src; /* source node address */
+ byte inIII_info; /* routing layer information */
+ word inIII_blksize; /* maximum data link block size */
+ byte inIII_vers; /* version number */
+ byte inIII_eco; /* ECO number */
+ byte inIII_ueco; /* user ECO number */
+ byte inIII_rsvd; /* reserved image field */
+ };
+
+struct initmsg /* initialization message */
+ {
+ byte in_flags; /* route flags */
+ word in_src; /* source node address */
+ byte in_info; /* routing layer information */
+ word in_blksize; /* maximum data link block size */
+ byte in_vers; /* version number */
+ byte in_eco; /* ECO number */
+ byte in_ueco; /* user ECO number */
+ word in_hello; /* hello timer */
+ byte in_rsvd; /* reserved image field */
+ };
+
+struct verifmsg /* verification message */
+ {
+ byte ve_flags; /* route flags */
+ word ve_src; /* source node address */
+ byte ve_fcnval; /* function value image field */
+ };
+
+struct testmsg /* hello and test message */
+ {
+ byte te_flags; /* route flags */
+ word te_src; /* source node address */
+ byte te_data; /* test data image field */
+ };
+
+struct l1rout /* level 1 routing message */
+ {
+ byte r1_flags; /* route flags */
+ word r1_src; /* source node address */
+ byte r1_rsvd; /* reserved field */
+ };
+
+struct l2rout /* level 2 routing message */
+ {
+ byte r2_flags; /* route flags */
+ word r2_src; /* source node address */
+ byte r2_rsvd; /* reserved field */
+ };
+
+struct rhellomsg /* router hello message */
+ {
+ byte rh_flags; /* route flags */
+ byte rh_vers; /* version number */
+ byte rh_eco; /* ECO number */
+ byte rh_ueco; /* user ECO number */
+ etheraddr rh_src; /* source id */
+ byte rh_info; /* routing layer information */
+ word rh_blksize; /* maximum data link block size */
+ byte rh_priority; /* router's priority */
+ byte rh_area; /* reserved */
+ word rh_hello; /* hello timer */
+ byte rh_mpd; /* reserved */
+ };
+
+struct ehellomsg /* endnode hello message */
+ {
+ byte eh_flags; /* route flags */
+ byte eh_vers; /* version number */
+ byte eh_eco; /* ECO number */
+ byte eh_ueco; /* user ECO number */
+ etheraddr eh_src; /* source id */
+ byte eh_info; /* routing layer information */
+ word eh_blksize; /* maximum data link block size */
+ byte eh_area; /* area (reserved) */
+ byte eh_seed[8]; /* verification seed */
+ etheraddr eh_router; /* designated router */
+ word eh_hello; /* hello timer */
+ byte eh_mpd; /* (reserved) */
+ byte eh_data; /* test data image field */
+ };
+
+union controlmsg
+ {
+ struct initmsg cm_init; /* initialization message */
+ struct verifmsg cm_ver; /* verification message */
+ struct testmsg cm_test; /* hello and test message */
+ struct l1rout cm_l1rou; /* level 1 routing message */
+ struct l2rout cm_l2rout; /* level 2 routing message */
+ struct rhellomsg cm_rhello; /* router hello message */
+ struct ehellomsg cm_ehello; /* endnode hello message */
+ };
+
+/* Macros for decoding routing-info fields */
+#define RI_COST(x) ((x)&0777)
+#define RI_HOPS(x) (((x)>>10)&037)
+
+/*
+ * NSP protocol fields and values.
+ */
+
+#define NSP_TYPEMASK 014 /* mask to isolate type code */
+#define NSP_SUBMASK 0160 /* mask to isolate subtype code */
+#define NSP_SUBSHFT 4 /* shift to move subtype code */
+
+#define MFT_DATA 0 /* data message */
+#define MFT_ACK 04 /* acknowledgement message */
+#define MFT_CTL 010 /* control message */
+
+#define MFS_ILS 020 /* data or I/LS indicator */
+#define MFS_BOM 040 /* beginning of message (data) */
+#define MFS_MOM 0 /* middle of message (data) */
+#define MFS_EOM 0100 /* end of message (data) */
+#define MFS_INT 040 /* interrupt message */
+
+#define MFS_DACK 0 /* data acknowledgement */
+#define MFS_IACK 020 /* I/LS acknowledgement */
+#define MFS_CACK 040 /* connect acknowledgement */
+
+#define MFS_NOP 0 /* no operation */
+#define MFS_CI 020 /* connect initiate */
+#define MFS_CC 040 /* connect confirm */
+#define MFS_DI 060 /* disconnect initiate */
+#define MFS_DC 0100 /* disconnect confirm */
+#define MFS_RCI 0140 /* retransmitted connect initiate */
+
+#define SGQ_ACK 0100000 /* ack */
+#define SGQ_NAK 0110000 /* negative ack */
+#define SGQ_OACK 0120000 /* other channel ack */
+#define SGQ_ONAK 0130000 /* other channel negative ack */
+#define SGQ_MASK 07777 /* mask to isolate seq # */
+#define SGQ_OTHER 020000 /* other channel qualifier */
+#define SGQ_DELAY 010000 /* ack delay flag */
+
+#define SGQ_EOM 0100000 /* pseudo flag for end-of-message */
+
+#define LSM_MASK 03 /* mask for modifier field */
+#define LSM_NOCHANGE 0 /* no change */
+#define LSM_DONOTSEND 1 /* do not send data */
+#define LSM_SEND 2 /* send data */
+
+#define LSI_MASK 014 /* mask for interpretation field */
+#define LSI_DATA 0 /* data segment or message count */
+#define LSI_INTR 4 /* interrupt request count */
+#define LSI_INTM 0377 /* funny marker for int. message */
+
+#define COS_MASK 014 /* mask for flow control field */
+#define COS_NONE 0 /* no flow control */
+#define COS_SEGMENT 04 /* segment flow control */
+#define COS_MESSAGE 010 /* message flow control */
+#define COS_CRYPTSER 020 /* cryptographic services requested */
+#define COS_DEFAULT 1 /* default value for field */
+
+#define COI_MASK 3 /* mask for version field */
+#define COI_32 0 /* version 3.2 */
+#define COI_31 1 /* version 3.1 */
+#define COI_40 2 /* version 4.0 */
+#define COI_41 3 /* version 4.1 */
+
+#define MNU_MASK 140 /* mask for session control version */
+#define MNU_10 000 /* session V1.0 */
+#define MNU_20 040 /* session V2.0 */
+#define MNU_ACCESS 1 /* access control present */
+#define MNU_USRDATA 2 /* user data field present */
+#define MNU_INVKPROXY 4 /* invoke proxy field present */
+#define MNU_UICPROXY 8 /* use uic-based proxy */
+
+#define DC_NORESOURCES 1 /* no resource reason code */
+#define DC_NOLINK 41 /* no link terminate reason code */
+#define DC_COMPLETE 42 /* disconnect complete reason code */
+
+#define DI_NOERROR 0 /* user disconnect */
+#define DI_SHUT 3 /* node is shutting down */
+#define DI_NOUSER 4 /* destination end user does not exist */
+#define DI_INVDEST 5 /* invalid end user destination */
+#define DI_REMRESRC 6 /* insufficient remote resources */
+#define DI_TPA 8 /* third party abort */
+#define DI_PROTOCOL 7 /* protocol error discovered */
+#define DI_ABORT 9 /* user abort */
+#define DI_LOCALRESRC 32 /* insufficient local resources */
+#define DI_REMUSERRESRC 33 /* insufficient remote user resources */
+#define DI_BADACCESS 34 /* bad access control information */
+#define DI_BADACCNT 36 /* bad ACCOUNT information */
+#define DI_CONNECTABORT 38 /* connect request cancelled */
+#define DI_TIMEDOUT 38 /* remote node or user crashed */
+#define DI_UNREACHABLE 39 /* local timers expired due to ... */
+#define DI_BADIMAGE 43 /* bad image data in connect */
+#define DI_SERVMISMATCH 54 /* cryptographic service mismatch */
+
+#define UC_OBJREJECT 0 /* object rejected connect */
+#define UC_USERDISCONNECT 0 /* user disconnect */
+#define UC_RESOURCES 1 /* insufficient resources (local or remote) */
+#define UC_NOSUCHNODE 2 /* unrecognized node name */
+#define UC_REMOTESHUT 3 /* remote node shutting down */
+#define UC_NOSUCHOBJ 4 /* unrecognized object */
+#define UC_INVOBJFORMAT 5 /* invalid object name format */
+#define UC_OBJTOOBUSY 6 /* object too busy */
+#define UC_NETWORKABORT 8 /* network abort */
+#define UC_USERABORT 9 /* user abort */
+#define UC_INVNODEFORMAT 10 /* invalid node name format */
+#define UC_LOCALSHUT 11 /* local node shutting down */
+#define UC_ACCESSREJECT 34 /* invalid access control information */
+#define UC_NORESPONSE 38 /* no response from object */
+#define UC_UNREACHABLE 39 /* node unreachable */
+
+/*
+ * NSP message formats.
+ */
+struct nsphdr /* general nsp header */
+ {
+ byte nh_flags; /* message flags */
+ word nh_dst; /* destination link address */
+ word nh_src; /* source link address */
+ };
+
+struct seghdr /* data segment header */
+ {
+ byte sh_flags; /* message flags */
+ word sh_dst; /* destination link address */
+ word sh_src; /* source link address */
+ word sh_seq[3]; /* sequence numbers */
+ };
+
+struct minseghdr /* minimum data segment header */
+ {
+ byte ms_flags; /* message flags */
+ word ms_dst; /* destination link address */
+ word ms_src; /* source link address */
+ word ms_seq; /* sequence number */
+ };
+
+struct lsmsg /* link service message (after hdr) */
+ {
+ byte ls_lsflags; /* link service flags */
+ byte ls_fcval; /* flow control value */
+ };
+
+struct ackmsg /* acknowledgement message */
+ {
+ byte ak_flags; /* message flags */
+ word ak_dst; /* destination link address */
+ word ak_src; /* source link address */
+ word ak_acknum[2]; /* acknowledgement numbers */
+ };
+
+struct minackmsg /* minimum acknowledgement message */
+ {
+ byte mk_flags; /* message flags */
+ word mk_dst; /* destination link address */
+ word mk_src; /* source link address */
+ word mk_acknum; /* acknowledgement number */
+ };
+
+struct ciackmsg /* connect acknowledgement message */
+ {
+ byte ck_flags; /* message flags */
+ word ck_dst; /* destination link address */
+ };
+
+struct cimsg /* connect initiate message */
+ {
+ byte ci_flags; /* message flags */
+ word ci_dst; /* destination link address (0) */
+ word ci_src; /* source link address */
+ byte ci_services; /* requested services */
+ byte ci_info; /* information */
+ word ci_segsize; /* maximum segment size */
+ };
+
+struct ccmsg /* connect confirm message */
+ {
+ byte cc_flags; /* message flags */
+ word cc_dst; /* destination link address */
+ word cc_src; /* source link address */
+ byte cc_services; /* requested services */
+ byte cc_info; /* information */
+ word cc_segsize; /* maximum segment size */
+ byte cc_optlen; /* optional data length */
+ };
+
+struct cnmsg /* generic connect message */
+ {
+ byte cn_flags; /* message flags */
+ word cn_dst; /* destination link address */
+ word cn_src; /* source link address */
+ byte cn_services; /* requested services */
+ byte cn_info; /* information */
+ word cn_segsize; /* maximum segment size */
+ };
+
+struct dimsg /* disconnect initiate message */
+ {
+ byte di_flags; /* message flags */
+ word di_dst; /* destination link address */
+ word di_src; /* source link address */
+ word di_reason; /* reason code */
+ byte di_optlen; /* optional data length */
+ };
+
+struct dcmsg /* disconnect confirm message */
+ {
+ byte dc_flags; /* message flags */
+ word dc_dst; /* destination link address */
+ word dc_src; /* source link address */
+ word dc_reason; /* reason code */
+ };
diff --git a/freebsd/contrib/tcpdump/decode_prefix.h b/freebsd/contrib/tcpdump/decode_prefix.h
new file mode 100644
index 00000000..8bb4a767
--- /dev/null
+++ b/freebsd/contrib/tcpdump/decode_prefix.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 1999 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Extensively modified by Hannes Gredler (hannes@juniper.net) for more
+ * complete BGP support.
+ */
+
+#ifndef tcpdump_decode_prefix_h
+#define tcpdump_decode_prefix_h
+
+extern int decode_prefix4(const u_char *pptr, u_int itemlen, char *buf, u_int buflen);
+#ifdef INET6
+extern int decode_prefix6(const u_char *pd, u_int itemlen, char *buf, u_int buflen);
+#endif
+
+#endif
diff --git a/freebsd/contrib/tcpdump/enc.h b/freebsd/contrib/tcpdump/enc.h
new file mode 100644
index 00000000..2d57e2b8
--- /dev/null
+++ b/freebsd/contrib/tcpdump/enc.h
@@ -0,0 +1,47 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/enc.h,v 1.1 2003-03-08 08:55:33 guy Exp $ (LBL) */
+/* From $OpenBSD: if_enc.h,v 1.8 2001/06/25 05:14:00 angelos Exp $ */
+/*
+ * The authors of this code are John Ioannidis (ji@tla.org),
+ * Angelos D. Keromytis (kermit@csd.uch.gr) and
+ * Niels Provos (provos@physnet.uni-hamburg.de).
+ *
+ * This code was written by John Ioannidis for BSD/OS in Athens, Greece,
+ * in November 1995.
+ *
+ * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
+ * by Angelos D. Keromytis.
+ *
+ * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
+ * and Niels Provos.
+ *
+ * Copyright (C) 1995, 1996, 1997, 1998 by John Ioannidis, Angelos D. Keromytis
+ * and Niels Provos.
+ * Copyright (c) 2001, Angelos D. Keromytis.
+ *
+ * Permission to use, copy, and modify this software with or without fee
+ * is hereby granted, provided that this entire notice is included in
+ * all copies of any software which is or includes a copy or
+ * modification of this software.
+ * You may use this code under the GNU public license if you so wish. Please
+ * contribute changes back to the authors under this freer than GPL license
+ * so that we may further the use of strong encryption without limitations to
+ * all.
+ *
+ * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
+ * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
+ * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
+ * PURPOSE.
+ */
+
+#define ENC_HDRLEN 12
+
+/* From $OpenBSD: mbuf.h,v 1.56 2002/01/25 15:50:23 art Exp $ */
+#define M_CONF 0x0400 /* packet was encrypted (ESP-transport) */
+#define M_AUTH 0x0800 /* packet was authenticated (AH) */
+
+struct enchdr {
+ u_int32_t af;
+ u_int32_t spi;
+ u_int32_t flags;
+};
diff --git a/freebsd/contrib/tcpdump/esp.h b/freebsd/contrib/tcpdump/esp.h
new file mode 100644
index 00000000..56cdada0
--- /dev/null
+++ b/freebsd/contrib/tcpdump/esp.h
@@ -0,0 +1,68 @@
+/* $NetBSD: esp.h,v 1.13 2000/09/26 08:37:38 itojun Exp $ */
+/* $KAME: esp.h,v 1.15 2000/09/20 18:15:22 itojun Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * RFC1827/2406 Encapsulated Security Payload.
+ */
+
+#ifndef _NETINET6_ESP_H_
+#define _NETINET6_ESP_H_
+
+struct esp {
+ u_int32_t esp_spi; /* ESP */
+ /*variable size, 32bit bound*/ /* Initialization Vector */
+ /*variable size*/ /* Payload data */
+ /*variable size*/ /* padding */
+ /*8bit*/ /* pad size */
+ /*8bit*/ /* next header */
+ /*8bit*/ /* next header */
+ /*variable size, 32bit bound*/ /* Authentication data (new IPsec) */
+};
+
+struct newesp {
+ u_int32_t esp_spi; /* ESP */
+ u_int32_t esp_seq; /* Sequence number */
+ /*variable size*/ /* (IV and) Payload data */
+ /*variable size*/ /* padding */
+ /*8bit*/ /* pad size */
+ /*8bit*/ /* next header */
+ /*8bit*/ /* next header */
+ /*variable size, 32bit bound*/ /* Authentication data */
+};
+
+struct esptail {
+ u_int8_t esp_padlen; /* pad length */
+ u_int8_t esp_nxt; /* Next header */
+ /*variable size, 32bit bound*/ /* Authentication data (new IPsec)*/
+};
+
+#endif /*_NETINET6_ESP_H_*/
diff --git a/freebsd/contrib/tcpdump/ether.h b/freebsd/contrib/tcpdump/ether.h
new file mode 100644
index 00000000..e8b3a713
--- /dev/null
+++ b/freebsd/contrib/tcpdump/ether.h
@@ -0,0 +1,59 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/ether.h,v 1.8 2002-12-11 07:13:51 guy Exp $ (LBL) */
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)if_ether.h 8.3 (Berkeley) 5/2/95
+ */
+
+#define ETHERMTU 1500
+
+/*
+ * The number of bytes in an ethernet (MAC) address.
+ */
+#define ETHER_ADDR_LEN 6
+
+/*
+ * Structure of a DEC/Intel/Xerox or 802.3 Ethernet header.
+ */
+struct ether_header {
+ u_int8_t ether_dhost[ETHER_ADDR_LEN];
+ u_int8_t ether_shost[ETHER_ADDR_LEN];
+ u_int16_t ether_type;
+};
+
+/*
+ * Length of a DEC/Intel/Xerox or 802.3 Ethernet header; note that some
+ * compilers may pad "struct ether_header" to a multiple of 4 bytes,
+ * for example, so "sizeof (struct ether_header)" may not give the right
+ * answer.
+ */
+#define ETHER_HDRLEN 14
diff --git a/freebsd/contrib/tcpdump/ethertype.h b/freebsd/contrib/tcpdump/ethertype.h
new file mode 100644
index 00000000..2c79ba28
--- /dev/null
+++ b/freebsd/contrib/tcpdump/ethertype.h
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 1993, 1994, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /tcpdump/master/tcpdump/ethertype.h,v 1.30 2008-02-06 10:47:53 guy Exp $ (LBL)
+ * $FreeBSD$
+ */
+
+/*
+ * Ethernet types.
+ *
+ * We wrap the declarations with #ifdef, so that if a file includes
+ * <netinet/if_ether.h>, which may declare some of these, we don't
+ * get a bunch of complaints from the C compiler about redefinitions
+ * of these values.
+ *
+ * We declare all of them here so that no file has to include
+ * <netinet/if_ether.h> if all it needs are ETHERTYPE_ values.
+ */
+
+#ifndef ETHERTYPE_LEN
+#define ETHERTYPE_LEN 2
+#endif
+
+#ifndef ETHERTYPE_GRE_ISO
+#define ETHERTYPE_GRE_ISO 0x00FE /* not really an ethertype only used in GRE */
+#endif
+#ifndef ETHERTYPE_PUP
+#define ETHERTYPE_PUP 0x0200 /* PUP protocol */
+#endif
+#ifndef ETHERTYPE_IP
+#define ETHERTYPE_IP 0x0800 /* IP protocol */
+#endif
+#ifndef ETHERTYPE_ARP
+#define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */
+#endif
+#ifndef ETHERTYPE_REVARP
+#define ETHERTYPE_REVARP 0x8035 /* reverse Addr. resolution protocol */
+#endif
+#ifndef ETHERTYPE_NS
+#define ETHERTYPE_NS 0x0600
+#endif
+#ifndef ETHERTYPE_SPRITE
+#define ETHERTYPE_SPRITE 0x0500
+#endif
+#ifndef ETHERTYPE_TRAIL
+#define ETHERTYPE_TRAIL 0x1000
+#endif
+#ifndef ETHERTYPE_MOPDL
+#define ETHERTYPE_MOPDL 0x6001
+#endif
+#ifndef ETHERTYPE_MOPRC
+#define ETHERTYPE_MOPRC 0x6002
+#endif
+#ifndef ETHERTYPE_DN
+#define ETHERTYPE_DN 0x6003
+#endif
+#ifndef ETHERTYPE_LAT
+#define ETHERTYPE_LAT 0x6004
+#endif
+#ifndef ETHERTYPE_SCA
+#define ETHERTYPE_SCA 0x6007
+#endif
+#ifndef ETHERTYPE_TEB
+#define ETHERTYPE_TEB 0x6558
+#endif
+#ifndef ETHERTYPE_LANBRIDGE
+#define ETHERTYPE_LANBRIDGE 0x8038
+#endif
+#ifndef ETHERTYPE_DECDNS
+#define ETHERTYPE_DECDNS 0x803c
+#endif
+#ifndef ETHERTYPE_DECDTS
+#define ETHERTYPE_DECDTS 0x803e
+#endif
+#ifndef ETHERTYPE_VEXP
+#define ETHERTYPE_VEXP 0x805b
+#endif
+#ifndef ETHERTYPE_VPROD
+#define ETHERTYPE_VPROD 0x805c
+#endif
+#ifndef ETHERTYPE_ATALK
+#define ETHERTYPE_ATALK 0x809b
+#endif
+#ifndef ETHERTYPE_AARP
+#define ETHERTYPE_AARP 0x80f3
+#endif
+#ifndef ETHERTYPE_TIPC
+#define ETHERTYPE_TIPC 0x88ca
+#endif
+#ifndef ETHERTYPE_8021Q
+#define ETHERTYPE_8021Q 0x8100
+#endif
+
+/* see:
+ http://en.wikipedia.org/wiki/IEEE_802.1Q
+ and http://en.wikipedia.org/wiki/QinQ
+*/
+#ifndef ETHERTYPE_8021Q9100
+#define ETHERTYPE_8021Q9100 0x9100
+#endif
+#ifndef ETHERTYPE_8021Q9200
+#define ETHERTYPE_8021Q9200 0x9200
+#endif
+#ifndef ETHERTYPE_8021QinQ
+#define ETHERTYPE_8021QinQ 0x88a8
+#endif
+#ifndef ETHERTYPE_IPX
+#define ETHERTYPE_IPX 0x8137
+#endif
+#ifndef ETHERTYPE_IPV6
+#define ETHERTYPE_IPV6 0x86dd
+#endif
+#ifndef ETHERTYPE_PPP
+#define ETHERTYPE_PPP 0x880b
+#endif
+#ifndef ETHERTYPE_MPCP
+#define ETHERTYPE_MPCP 0x8808
+#endif
+#ifndef ETHERTYPE_SLOW
+#define ETHERTYPE_SLOW 0x8809
+#endif
+#ifndef ETHERTYPE_MPLS
+#define ETHERTYPE_MPLS 0x8847
+#endif
+#ifndef ETHERTYPE_MPLS_MULTI
+#define ETHERTYPE_MPLS_MULTI 0x8848
+#endif
+#ifndef ETHERTYPE_PPPOED
+#define ETHERTYPE_PPPOED 0x8863
+#endif
+#ifndef ETHERTYPE_PPPOES
+#define ETHERTYPE_PPPOES 0x8864
+#endif
+#ifndef ETHERTYPE_PPPOED2
+#define ETHERTYPE_PPPOED2 0x3c12
+#endif
+#ifndef ETHERTYPE_PPPOES2
+#define ETHERTYPE_PPPOES2 0x3c13
+#endif
+#ifndef ETHERTYPE_MS_NLB_HB
+#define ETHERTYPE_MS_NLB_HB 0x886f /* MS Network Load Balancing Heartbeat */
+#endif
+#ifndef ETHERTYPE_JUMBO
+#define ETHERTYPE_JUMBO 0x8870
+#endif
+#ifndef ETHERTYPE_LLDP
+#define ETHERTYPE_LLDP 0x88cc
+#endif
+#ifndef ETHERTYPE_EAPOL
+#define ETHERTYPE_EAPOL 0x888e
+#endif
+#ifndef ETHERTYPE_RRCP
+#define ETHERTYPE_RRCP 0x8899
+#endif
+#ifndef ETHERTYPE_LOOPBACK
+#define ETHERTYPE_LOOPBACK 0x9000
+#endif
+#ifndef ETHERTYPE_VMAN
+#define ETHERTYPE_VMAN 0x9100 /* Extreme VMAN Protocol */
+#endif
+#ifndef ETHERTYPE_CFM_OLD
+#define ETHERTYPE_CFM_OLD 0xabcd /* 802.1ag depreciated */
+#endif
+#ifndef ETHERTYPE_CFM
+#define ETHERTYPE_CFM 0x8902 /* 802.1ag */
+#endif
+#ifndef ETHERTYPE_ISO
+#define ETHERTYPE_ISO 0xfefe /* nonstandard - used in Cisco HDLC encapsulation */
+#endif
+
+extern const struct tok ethertype_values[];
diff --git a/freebsd/contrib/tcpdump/extract.h b/freebsd/contrib/tcpdump/extract.h
new file mode 100644
index 00000000..60ecd680
--- /dev/null
+++ b/freebsd/contrib/tcpdump/extract.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 1992, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /tcpdump/master/tcpdump/extract.h,v 1.25 2006-01-30 16:20:07 hannes Exp $ (LBL)
+ */
+
+/*
+ * Macros to extract possibly-unaligned big-endian integral values.
+ */
+#ifdef LBL_ALIGN
+/*
+ * The processor doesn't natively handle unaligned loads.
+ */
+#ifdef HAVE___ATTRIBUTE__
+/*
+ * We have __attribute__; we assume that means we have __attribute__((packed)).
+ * Declare packed structures containing a u_int16_t and a u_int32_t,
+ * cast the pointer to point to one of those, and fetch through it;
+ * the GCC manual doesn't appear to explicitly say that
+ * __attribute__((packed)) causes the compiler to generate unaligned-safe
+ * code, but it apppears to do so.
+ *
+ * We do this in case the compiler can generate, for this instruction set,
+ * better code to do an unaligned load and pass stuff to "ntohs()" or
+ * "ntohl()" than the code to fetch the bytes one at a time and
+ * assemble them. (That might not be the case on a little-endian platform,
+ * where "ntohs()" and "ntohl()" might not be done inline.)
+ */
+typedef struct {
+ u_int16_t val;
+} __attribute__((packed)) unaligned_u_int16_t;
+
+typedef struct {
+ u_int32_t val;
+} __attribute__((packed)) unaligned_u_int32_t;
+
+static inline u_int16_t
+EXTRACT_16BITS(const void *p)
+{
+ return ((u_int16_t)ntohs(((const unaligned_u_int16_t *)(p))->val));
+}
+
+static inline u_int32_t
+EXTRACT_32BITS(const void *p)
+{
+ return ((u_int32_t)ntohl(((const unaligned_u_int32_t *)(p))->val));
+}
+
+static inline u_int64_t
+EXTRACT_64BITS(const void *p)
+{
+ return ((u_int64_t)(((u_int64_t)ntohl(((const unaligned_u_int32_t *)(p) + 0)->val)) << 32 | \
+ ((u_int64_t)ntohl(((const unaligned_u_int32_t *)(p) + 1)->val)) << 0));
+
+}
+
+#else /* HAVE___ATTRIBUTE__ */
+/*
+ * We don't have __attribute__, so do unaligned loads of big-endian
+ * quantities the hard way - fetch the bytes one at a time and
+ * assemble them.
+ */
+#define EXTRACT_16BITS(p) \
+ ((u_int16_t)((u_int16_t)*((const u_int8_t *)(p) + 0) << 8 | \
+ (u_int16_t)*((const u_int8_t *)(p) + 1)))
+#define EXTRACT_32BITS(p) \
+ ((u_int32_t)((u_int32_t)*((const u_int8_t *)(p) + 0) << 24 | \
+ (u_int32_t)*((const u_int8_t *)(p) + 1) << 16 | \
+ (u_int32_t)*((const u_int8_t *)(p) + 2) << 8 | \
+ (u_int32_t)*((const u_int8_t *)(p) + 3)))
+#define EXTRACT_64BITS(p) \
+ ((u_int64_t)((u_int64_t)*((const u_int8_t *)(p) + 0) << 56 | \
+ (u_int64_t)*((const u_int8_t *)(p) + 1) << 48 | \
+ (u_int64_t)*((const u_int8_t *)(p) + 2) << 40 | \
+ (u_int64_t)*((const u_int8_t *)(p) + 3) << 32 | \
+ (u_int64_t)*((const u_int8_t *)(p) + 4) << 24 | \
+ (u_int64_t)*((const u_int8_t *)(p) + 5) << 16 | \
+ (u_int64_t)*((const u_int8_t *)(p) + 6) << 8 | \
+ (u_int64_t)*((const u_int8_t *)(p) + 7)))
+#endif /* HAVE___ATTRIBUTE__ */
+#else /* LBL_ALIGN */
+/*
+ * The processor natively handles unaligned loads, so we can just
+ * cast the pointer and fetch through it.
+ */
+static inline u_int16_t
+EXTRACT_16BITS(const void *p)
+{
+ return ((u_int16_t)ntohs(*(const u_int16_t *)(p)));
+}
+
+static inline u_int32_t
+EXTRACT_32BITS(const void *p)
+{
+ return ((u_int32_t)ntohl(*(const u_int32_t *)(p)));
+}
+
+static inline u_int64_t
+EXTRACT_64BITS(const void *p)
+{
+ return ((u_int64_t)(((u_int64_t)ntohl(*((const u_int32_t *)(p) + 0))) << 32 | \
+ ((u_int64_t)ntohl(*((const u_int32_t *)(p) + 1))) << 0));
+
+}
+
+#endif /* LBL_ALIGN */
+
+#define EXTRACT_24BITS(p) \
+ ((u_int32_t)((u_int32_t)*((const u_int8_t *)(p) + 0) << 16 | \
+ (u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \
+ (u_int32_t)*((const u_int8_t *)(p) + 2)))
+
+/*
+ * Macros to extract possibly-unaligned little-endian integral values.
+ * XXX - do loads on little-endian machines that support unaligned loads?
+ */
+#define EXTRACT_LE_8BITS(p) (*(p))
+#define EXTRACT_LE_16BITS(p) \
+ ((u_int16_t)((u_int16_t)*((const u_int8_t *)(p) + 1) << 8 | \
+ (u_int16_t)*((const u_int8_t *)(p) + 0)))
+#define EXTRACT_LE_32BITS(p) \
+ ((u_int32_t)((u_int32_t)*((const u_int8_t *)(p) + 3) << 24 | \
+ (u_int32_t)*((const u_int8_t *)(p) + 2) << 16 | \
+ (u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \
+ (u_int32_t)*((const u_int8_t *)(p) + 0)))
+#define EXTRACT_LE_24BITS(p) \
+ ((u_int32_t)((u_int32_t)*((const u_int8_t *)(p) + 2) << 16 | \
+ (u_int32_t)*((const u_int8_t *)(p) + 1) << 8 | \
+ (u_int32_t)*((const u_int8_t *)(p) + 0)))
+#define EXTRACT_LE_64BITS(p) \
+ ((u_int64_t)((u_int64_t)*((const u_int8_t *)(p) + 7) << 56 | \
+ (u_int64_t)*((const u_int8_t *)(p) + 6) << 48 | \
+ (u_int64_t)*((const u_int8_t *)(p) + 5) << 40 | \
+ (u_int64_t)*((const u_int8_t *)(p) + 4) << 32 | \
+ (u_int64_t)*((const u_int8_t *)(p) + 3) << 24 | \
+ (u_int64_t)*((const u_int8_t *)(p) + 2) << 16 | \
+ (u_int64_t)*((const u_int8_t *)(p) + 1) << 8 | \
+ (u_int64_t)*((const u_int8_t *)(p) + 0)))
diff --git a/freebsd/contrib/tcpdump/fddi.h b/freebsd/contrib/tcpdump/fddi.h
new file mode 100644
index 00000000..df38c8e9
--- /dev/null
+++ b/freebsd/contrib/tcpdump/fddi.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 1992, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /tcpdump/master/tcpdump/fddi.h,v 1.11 2002-12-11 07:13:51 guy Exp $ (LBL)
+ */
+
+/*
+ * Based on Ultrix if_fddi.h
+ */
+
+/*
+ * This stuff should come from a system header file, but there's no
+ * obviously portable way to do that and it's not really going
+ * to change from system to system (except for the padding business).
+ */
+
+struct fddi_header {
+ u_char fddi_fc; /* frame control */
+ u_char fddi_dhost[6];
+ u_char fddi_shost[6];
+};
+
+/*
+ * Length of an FDDI header; note that some compilers may pad
+ * "struct fddi_header" to a multiple of 4 bytes, for example, so
+ * "sizeof (struct fddi_header)" may not give the right
+ * answer.
+ */
+#define FDDI_HDRLEN 13
+
+/* Useful values for fddi_fc (frame control) field */
+
+/*
+ * FDDI Frame Control bits
+ */
+#define FDDIFC_C 0x80 /* Class bit */
+#define FDDIFC_L 0x40 /* Address length bit */
+#define FDDIFC_F 0x30 /* Frame format bits */
+#define FDDIFC_Z 0x0f /* Control bits */
+
+/*
+ * FDDI Frame Control values. (48-bit addressing only).
+ */
+#define FDDIFC_VOID 0x40 /* Void frame */
+#define FDDIFC_NRT 0x80 /* Nonrestricted token */
+#define FDDIFC_RT 0xc0 /* Restricted token */
+#define FDDIFC_SMT_INFO 0x41 /* SMT Info */
+#define FDDIFC_SMT_NSA 0x4F /* SMT Next station adrs */
+#define FDDIFC_MAC_BEACON 0xc2 /* MAC Beacon frame */
+#define FDDIFC_MAC_CLAIM 0xc3 /* MAC Claim frame */
+#define FDDIFC_LLC_ASYNC 0x50 /* Async. LLC frame */
+#define FDDIFC_LLC_SYNC 0xd0 /* Sync. LLC frame */
+#define FDDIFC_IMP_ASYNC 0x60 /* Implementor Async. */
+#define FDDIFC_IMP_SYNC 0xe0 /* Implementor Synch. */
+#define FDDIFC_SMT 0x40 /* SMT frame */
+#define FDDIFC_MAC 0xc0 /* MAC frame */
+
+#define FDDIFC_CLFF 0xF0 /* Class/Length/Format bits */
+#define FDDIFC_ZZZZ 0x0F /* Control bits */
diff --git a/freebsd/contrib/tcpdump/forces.h b/freebsd/contrib/tcpdump/forces.h
new file mode 100644
index 00000000..d41475f9
--- /dev/null
+++ b/freebsd/contrib/tcpdump/forces.h
@@ -0,0 +1,679 @@
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Copyright (c) 2009 Mojatatu Networks, Inc
+ *
+ */
+
+/*
+ * Per draft-ietf-forces-protocol-22
+*/
+#define ForCES_VERS 1
+#define ForCES_HDRL 24
+#define ForCES_ALNL 4U
+#define TLV_HDRL 4
+#define ILV_HDRL 8
+
+#define TOM_RSVD 0x0
+#define TOM_ASSNSETUP 0x1
+#define TOM_ASSNTEARD 0x2
+#define TOM_CONFIG 0x3
+#define TOM_QUERY 0x4
+#define TOM_EVENTNOT 0x5
+#define TOM_PKTREDIR 0x6
+#define TOM_HEARTBT 0x0F
+#define TOM_ASSNSETREP 0x11
+#define TOM_CONFIGREP 0x13
+#define TOM_QUERYREP 0x14
+
+/*
+ * tom_h Flags: resv1(8b):maxtlvs(4b):resv2(2b):mintlv(2b)
+*/
+#define ZERO_TTLV 0x01
+#define ZERO_MORE_TTLV 0x02
+#define ONE_MORE_TTLV 0x04
+#define ZERO_TLV 0x00
+#define ONE_TLV 0x10
+#define TWO_TLV 0x20
+#define MAX_TLV 0xF0
+
+#define TTLV_T1 (ONE_MORE_TTLV|ONE_TLV)
+#define TTLV_T2 (ONE_MORE_TTLV|MAX_TLV)
+
+struct tom_h {
+ u_int32_t v;
+ u_int16_t flags;
+ u_int16_t op_msk;
+ const char *s;
+ int (*print) (register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent);
+};
+
+enum {
+ TOM_RSV_I,
+ TOM_ASS_I,
+ TOM_AST_I,
+ TOM_CFG_I,
+ TOM_QRY_I,
+ TOM_EVN_I,
+ TOM_RED_I,
+ TOM_HBT_I,
+ TOM_ASR_I,
+ TOM_CNR_I,
+ TOM_QRR_I,
+ _TOM_RSV_MAX
+};
+#define TOM_MAX_IND (_TOM_RSV_MAX - 1)
+
+int lfbselect_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent);
+int redirect_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent);
+int asrtlv_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent);
+int asttlv_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent);
+int gentltlv_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent);
+int print_metailv(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent);
+int print_metatlv(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent);
+int print_reddata(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent);
+
+static inline int tom_valid(u_int8_t tom)
+{
+ if (tom > 0) {
+ if (tom >= 0x7 && tom <= 0xe)
+ return 0;
+ if (tom == 0x10)
+ return 0;
+ if (tom > 0x14)
+ return 0;
+ return 1;
+ } else
+ return 0;
+}
+
+static inline const char *ForCES_node(u_int32_t node)
+{
+ if (node <= 0x3FFFFFFF)
+ return "FE";
+ if (node >= 0x40000000 && node <= 0x7FFFFFFF)
+ return "CE";
+ if (node >= 0xC0000000 && node <= 0xFFFFFFEF)
+ return "AllMulticast";
+ if (node == 0xFFFFFFFD)
+ return "AllCEsBroadcast";
+ if (node == 0xFFFFFFFE)
+ return "AllFEsBroadcast";
+ if (node == 0xFFFFFFFF)
+ return "AllBroadcast";
+
+ return "ForCESreserved";
+
+}
+
+static inline const char *ForCES_ACKp(u_int32_t flg)
+{
+ if (flg == 0x0)
+ return "NoACK";
+ if (flg == 0x1)
+ return "SuccessACK";
+ if (flg == 0x2)
+ return "FailureACK";
+ if (flg == 0x3)
+ return "AlwaysACK";
+ return "ACKUnknown";
+}
+
+static inline const char *ForCES_EMp(u_int32_t flg)
+{
+ if (flg == 0x0)
+ return "EMReserved";
+ if (flg == 0x1)
+ return "execute-all-or-none";
+ if (flg == 0x2)
+ return "execute-until-failure";
+ if (flg == 0x3)
+ return "continue-execute-on-failure";
+ return "EMUnknown";
+}
+
+static inline const char *ForCES_ATp(u_int32_t flg)
+{
+ if (flg == 0x0)
+ return "Standalone";
+ if (flg == 0x1)
+ return "2PCtransaction";
+ return "ATUnknown";
+}
+
+static inline const char *ForCES_TPp(u_int32_t flg)
+{
+ if (flg == 0x0)
+ return "StartofTransaction";
+ if (flg == 0x1)
+ return "MiddleofTransaction";
+ if (flg == 0x2)
+ return "EndofTransaction";
+ if (flg == 0x3)
+ return "abort";
+ return "TPUnknown";
+}
+
+/*
+ * Structure of forces header, naked of TLVs.
+ */
+struct forcesh {
+ u_int8_t fm_vrsvd; /* version and reserved */
+#define ForCES_V(forcesh) ((forcesh)->fm_vrsvd >> 4)
+ u_int8_t fm_tom; /* type of message */
+ u_int16_t fm_len; /* total length * 4 bytes */
+#define ForCES_BLN(forcesh) ((u_int32_t)(EXTRACT_16BITS(&(forcesh)->fm_len) << 2))
+ u_int32_t fm_sid; /* Source ID */
+#define ForCES_SID(forcesh) EXTRACT_32BITS(&(forcesh)->fm_sid)
+ u_int32_t fm_did; /* Destination ID */
+#define ForCES_DID(forcesh) EXTRACT_32BITS(&(forcesh)->fm_did)
+ u_int8_t fm_cor[8]; /* correlator */
+ u_int32_t fm_flags; /* flags */
+#define ForCES_ACK(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0xC0000000) >> 30)
+#define ForCES_PRI(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x38000000) >> 27)
+#define ForCES_RS1(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x07000000) >> 24)
+#define ForCES_EM(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x00C00000) >> 22)
+#define ForCES_AT(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x00200000) >> 21)
+#define ForCES_TP(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x00180000) >> 19)
+#define ForCES_RS2(forcesh) ((EXTRACT_32BITS(&(forcesh)->fm_flags)&0x0007FFFF) >> 0)
+};
+
+#define ForCES_HLN_VALID(fhl,tlen) ((tlen) >= ForCES_HDRL && \
+ (fhl) >= ForCES_HDRL && \
+ (fhl) == (tlen))
+
+#define F_LFB_RSVD 0x0
+#define F_LFB_FEO 0x1
+#define F_LFB_FEPO 0x2
+const struct tok ForCES_LFBs[] = {
+ {F_LFB_RSVD, "Invalid TLV"},
+ {F_LFB_FEO, "FEObj LFB"},
+ {F_LFB_FEPO, "FEProtoObj LFB"},
+ {0, NULL}
+};
+
+int forces_type_print(register const u_char * pptr, const struct forcesh *fhdr,
+ register u_int mlen, const struct tom_h *tops);
+
+enum {
+ F_OP_RSV,
+ F_OP_SET,
+ F_OP_SETPROP,
+ F_OP_SETRESP,
+ F_OP_SETPRESP,
+ F_OP_DEL,
+ F_OP_DELRESP,
+ F_OP_GET,
+ F_OP_GETPROP,
+ F_OP_GETRESP,
+ F_OP_GETPRESP,
+ F_OP_REPORT,
+ F_OP_COMMIT,
+ F_OP_RCOMMIT,
+ F_OP_RTRCOMP,
+ _F_OP_MAX
+};
+
+#define F_OP_MAX (_F_OP_MAX - 1)
+enum {
+ B_OP_SET = 1 << (F_OP_SET - 1),
+ B_OP_SETPROP = 1 << (F_OP_SETPROP - 1),
+ B_OP_SETRESP = 1 << (F_OP_SETRESP - 1),
+ B_OP_SETPRESP = 1 << (F_OP_SETPRESP - 1),
+ B_OP_DEL = 1 << (F_OP_DEL - 1),
+ B_OP_DELRESP = 1 << (F_OP_DELRESP - 1),
+ B_OP_GET = 1 << (F_OP_GET - 1),
+ B_OP_GETPROP = 1 << (F_OP_GETPROP - 1),
+ B_OP_GETRESP = 1 << (F_OP_GETRESP - 1),
+ B_OP_GETPRESP = 1 << (F_OP_GETPRESP - 1),
+ B_OP_REPORT = 1 << (F_OP_REPORT - 1),
+ B_OP_COMMIT = 1 << (F_OP_COMMIT - 1),
+ B_OP_RCOMMIT = 1 << (F_OP_RCOMMIT - 1),
+ B_OP_RTRCOMP = 1 << (F_OP_RTRCOMP - 1),
+};
+
+struct optlv_h {
+ u_int16_t flags;
+ u_int16_t op_msk;
+ const char *s;
+ int (*print) (register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent);
+};
+
+int genoptlv_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent);
+int recpdoptlv_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent);
+int invoptlv_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent);
+
+#define OP_MIN_SIZ 8
+struct pathdata_h {
+ u_int16_t pflags;
+ u_int16_t pIDcnt;
+};
+
+#define B_FULLD 0x1
+#define B_SPARD 0x2
+#define B_RESTV 0x4
+#define B_KEYIN 0x8
+
+static const struct optlv_h OPTLV_msg[F_OP_MAX + 1] = {
+ /* F_OP_RSV */ {ZERO_TTLV, 0, "Invalid OPTLV", invoptlv_print},
+ /* F_OP_SET */ {TTLV_T2, B_FULLD | B_SPARD, " Set", recpdoptlv_print},
+ /* F_OP_SETPROP */
+ {TTLV_T2, B_FULLD | B_SPARD, " SetProp", recpdoptlv_print},
+ /* F_OP_SETRESP */ {TTLV_T2, B_RESTV, " SetResp", recpdoptlv_print},
+ /* F_OP_SETPRESP */ {TTLV_T2, B_RESTV, " SetPropResp", recpdoptlv_print},
+ /* F_OP_DEL */ {ZERO_TTLV, 0, " Del", recpdoptlv_print},
+ /* F_OP_DELRESP */ {TTLV_T2, B_RESTV, " DelResp", recpdoptlv_print},
+ /* F_OP_GET */ {ZERO_TTLV, 0, " Get", recpdoptlv_print},
+ /* F_OP_GETPROP */ {ZERO_TTLV, 0, " GetProp", recpdoptlv_print},
+ /* F_OP_GETRESP */
+ {TTLV_T2, B_FULLD | B_SPARD | B_RESTV, " GetResp", recpdoptlv_print},
+ /* F_OP_GETPRESP */
+ {TTLV_T2, B_FULLD | B_RESTV, " GetPropResp", recpdoptlv_print},
+ /* F_OP_REPORT */
+ {TTLV_T2, B_FULLD | B_SPARD, " Report", recpdoptlv_print},
+ /* F_OP_COMMIT */ {ZERO_TTLV, 0, " Commit", NULL},
+ /* F_OP_RCOMMIT */ {TTLV_T1, B_RESTV, " RCommit", genoptlv_print},
+ /* F_OP_RTRCOMP */ {ZERO_TTLV, 0, " RTRCOMP", NULL},
+};
+
+static inline const struct optlv_h *get_forces_optlv_h(u_int16_t opt)
+{
+ if (opt > F_OP_MAX || opt <= F_OP_RSV)
+ return &OPTLV_msg[F_OP_RSV];
+
+ return &OPTLV_msg[opt];
+}
+
+#define IND_SIZE 256
+#define IND_CHR ' '
+#define IND_PREF '\n'
+#define IND_SUF 0x0
+char ind_buf[IND_SIZE];
+
+static inline char *indent_pr(int indent, int nlpref)
+{
+ int i = 0;
+ char *r = ind_buf;
+
+ if (indent > (IND_SIZE - 1))
+ indent = IND_SIZE - 1;
+
+ if (nlpref) {
+ r[i] = IND_PREF;
+ i++;
+ indent--;
+ }
+
+ while (--indent >= 0)
+ r[i++] = IND_CHR;
+
+ r[i] = IND_SUF;
+ return r;
+}
+
+static inline int op_valid(u_int16_t op, u_int16_t mask)
+{
+ int opb = 1 << (op - 1);
+
+ if (op == 0)
+ return 0;
+ if (opb & mask)
+ return 1;
+ /* I guess we should allow vendor operations? */
+ if (op >= 0x8000)
+ return 1;
+ return 0;
+}
+
+#define F_TLV_RSVD 0x0000
+#define F_TLV_REDR 0x0001
+#define F_TLV_ASRS 0x0010
+#define F_TLV_ASRT 0x0011
+#define F_TLV_LFBS 0x1000
+#define F_TLV_PDAT 0x0110
+#define F_TLV_KEYI 0x0111
+#define F_TLV_FULD 0x0112
+#define F_TLV_SPAD 0x0113
+#define F_TLV_REST 0x0114
+#define F_TLV_METD 0x0115
+#define F_TLV_REDD 0x0116
+#define F_TLV_VNST 0x8000
+
+static const struct tok ForCES_TLV[] = {
+ {F_TLV_RSVD, "Invalid TLV"},
+ {F_TLV_REDR, "REDIRECT TLV"},
+ {F_TLV_ASRS, "ASResult TLV"},
+ {F_TLV_ASRT, "ASTreason TLV"},
+ {F_TLV_LFBS, "LFBselect TLV"},
+ {F_TLV_PDAT, "PATH-DATA TLV"},
+ {F_TLV_KEYI, "KEYINFO TLV"},
+ {F_TLV_FULD, "FULLDATA TLV"},
+ {F_TLV_SPAD, "SPARSEDATA TLV"},
+ {F_TLV_REST, "RESULT TLV"},
+ {F_TLV_METD, "METADATA TLV"},
+ {F_TLV_REDD, "REDIRECTDATA TLV"},
+ {0, NULL}
+};
+
+#define TLV_HLN 4
+static inline int ttlv_valid(u_int16_t ttlv)
+{
+ if (ttlv > 0) {
+ if (ttlv == 1 || ttlv == 0x1000)
+ return 1;
+ if (ttlv >= 0x10 && ttlv <= 0x11)
+ return 1;
+ if (ttlv >= 0x110 && ttlv <= 0x116)
+ return 1;
+ if (ttlv >= 0x8000)
+ return 0; /* XXX: */
+ }
+
+ return 0;
+}
+
+struct forces_ilv {
+ u_int32_t type;
+ u_int32_t length;
+};
+
+struct forces_tlv {
+ u_int16_t type;
+ u_int16_t length;
+};
+
+int otlv_print(const struct forces_tlv *otlv, u_int16_t op_msk, int indent);
+
+#define F_ALN_LEN(len) ( ((len)+ForCES_ALNL-1) & ~(ForCES_ALNL-1) )
+#define GET_TOP_TLV(fhdr) ((struct forces_tlv *)((fhdr) + sizeof (struct forcesh)))
+#define TLV_SET_LEN(len) (F_ALN_LEN(TLV_HDRL) + (len))
+#define TLV_ALN_LEN(len) F_ALN_LEN(TLV_SET_LEN(len))
+#define TLV_RDAT_LEN(tlv) ((int)(EXTRACT_16BITS(&(tlv)->length) - TLV_SET_LEN(0))
+#define TLV_DATA(tlvp) ((void*)(((char*)(tlvp)) + TLV_SET_LEN(0)))
+#define GO_NXT_TLV(tlv,rlen) ((rlen) -= F_ALN_LEN(EXTRACT_16BITS(&(tlv)->length)), \
+ (struct forces_tlv*)(((char*)(tlv)) \
+ + F_ALN_LEN(EXTRACT_16BITS(&(tlv)->length))))
+#define ILV_SET_LEN(len) (F_ALN_LEN(ILV_HDRL) + (len))
+#define ILV_ALN_LEN(len) F_ALN_LEN(ILV_SET_LEN(len))
+#define ILV_RDAT_LEN(ilv) ((int)(EXTRACT_32BITS(&(ilv)->length)) - ILV_SET_LEN(0))
+#define ILV_DATA(ilvp) ((void*)(((char*)(ilvp)) + ILV_SET_LEN(0)))
+#define GO_NXT_ILV(ilv,rlen) ((rlen) -= F_ALN_LEN(EXTRACT_32BITS(&(ilv)->length)), \
+ (struct forces_ilv *)(((char*)(ilv)) \
+ + F_ALN_LEN(EXTRACT_32BITS(&(ilv)->length))))
+#define INVALID_RLEN -1
+#define INVALID_STLN -2
+#define INVALID_LTLN -3
+#define INVALID_ALEN -4
+
+static const struct tok ForCES_TLV_err[] = {
+ {INVALID_RLEN, "Invalid total length"},
+ {INVALID_STLN, "xLV too short"},
+ {INVALID_LTLN, "xLV too long"},
+ {INVALID_ALEN, "data padding missing"},
+ {0, NULL}
+};
+
+static inline int tlv_valid(const struct forces_tlv *tlv, u_int rlen)
+{
+ if (rlen < TLV_HDRL)
+ return INVALID_RLEN;
+ if (EXTRACT_16BITS(&tlv->length) < TLV_HDRL)
+ return INVALID_STLN;
+ if (EXTRACT_16BITS(&tlv->length) > rlen)
+ return INVALID_LTLN;
+ if (rlen < F_ALN_LEN(EXTRACT_16BITS(&tlv->length)))
+ return INVALID_ALEN;
+
+ return 0;
+}
+
+static inline int ilv_valid(const struct forces_ilv *ilv, u_int rlen)
+{
+ if (rlen < ILV_HDRL)
+ return INVALID_RLEN;
+ if (EXTRACT_32BITS(&ilv->length) < ILV_HDRL)
+ return INVALID_STLN;
+ if (EXTRACT_32BITS(&ilv->length) > rlen)
+ return INVALID_LTLN;
+ if (rlen < F_ALN_LEN(EXTRACT_32BITS(&ilv->length)))
+ return INVALID_ALEN;
+
+ return 0;
+}
+
+struct forces_lfbsh {
+ u_int32_t class;
+ u_int32_t instance;
+};
+
+#define ASSNS_OPS (B_OP_REPORT)
+#define CFG_OPS (B_OP_SET|B_OP_SETPROP|B_OP_DEL|B_OP_COMMIT|B_OP_RTRCOMP)
+#define CFG_ROPS (B_OP_SETRESP|B_OP_SETPRESP|B_OP_DELRESP|B_OP_RCOMMIT)
+#define CFG_QY (B_OP_GET|B_OP_GETPROP)
+#define CFG_QYR (B_OP_GETRESP|B_OP_GETPRESP)
+#define CFG_EVN (B_OP_REPORT)
+
+static const struct tom_h ForCES_msg[TOM_MAX_IND + 1] = {
+ /* TOM_RSV_I */ {TOM_RSVD, ZERO_TTLV, 0, "Invalid message", NULL},
+ /* TOM_ASS_I */ {TOM_ASSNSETUP, ZERO_MORE_TTLV | TWO_TLV, ASSNS_OPS,
+ "Association Setup", lfbselect_print},
+ /* TOM_AST_I */
+ {TOM_ASSNTEARD, TTLV_T1, 0, "Association TearDown", asttlv_print},
+ /* TOM_CFG_I */ {TOM_CONFIG, TTLV_T2, CFG_OPS, "Config", lfbselect_print},
+ /* TOM_QRY_I */ {TOM_QUERY, TTLV_T2, CFG_QY, "Query", lfbselect_print},
+ /* TOM_EVN_I */ {TOM_EVENTNOT, TTLV_T1, CFG_EVN, "Event Notification",
+ lfbselect_print},
+ /* TOM_RED_I */
+ {TOM_PKTREDIR, TTLV_T2, 0, "Packet Redirect", redirect_print},
+ /* TOM_HBT_I */ {TOM_HEARTBT, ZERO_TTLV, 0, "HeartBeat", NULL},
+ /* TOM_ASR_I */
+ {TOM_ASSNSETREP, TTLV_T1, 0, "Association Response", asrtlv_print},
+ /* TOM_CNR_I */ {TOM_CONFIGREP, TTLV_T2, CFG_ROPS, "Config Response",
+ lfbselect_print},
+ /* TOM_QRR_I */
+ {TOM_QUERYREP, TTLV_T2, CFG_QYR, "Query Response", lfbselect_print},
+};
+
+static inline const struct tom_h *get_forces_tom(u_int8_t tom)
+{
+ int i;
+ for (i = TOM_RSV_I; i <= TOM_MAX_IND; i++) {
+ const struct tom_h *th = &ForCES_msg[i];
+ if (th->v == tom)
+ return th;
+ }
+ return &ForCES_msg[TOM_RSV_I];
+}
+
+struct pdata_ops {
+ u_int32_t v;
+ u_int16_t flags;
+ u_int16_t op_msk;
+ const char *s;
+ int (*print) (register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent);
+};
+
+enum {
+ PD_RSV_I,
+ PD_SEL_I,
+ PD_FDT_I,
+ PD_SDT_I,
+ PD_RES_I,
+ PD_PDT_I,
+ _PD_RSV_MAX
+};
+#define PD_MAX_IND (_TOM_RSV_MAX - 1)
+
+static inline int pd_valid(u_int16_t pd)
+{
+ if (pd >= F_TLV_PDAT && pd <= F_TLV_REST)
+ return 1;
+ return 0;
+}
+
+static inline void chk_op_type(u_int16_t type, u_int16_t msk, u_int16_t omsk)
+{
+ if (type != F_TLV_PDAT) {
+ if (msk & B_KEYIN) {
+ if (type != F_TLV_KEYI) {
+ printf
+ ("Based on flags expected KEYINFO TLV!\n");
+ }
+ } else {
+ if (!(msk & omsk)) {
+ printf
+ ("Illegal DATA encoding for type 0x%x programmed %x got %x \n",
+ type, omsk, msk);
+ }
+ }
+ }
+
+}
+
+int fdatatlv_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent);
+int sdatailv_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent);
+int sdatatlv_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent);
+int pdatatlv_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent);
+int pkeyitlv_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent);
+
+int pdatacnt_print(register const u_char * pptr, register u_int len,
+ u_int16_t IDcnt, u_int16_t op_msk, int indent);
+int pdata_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent);
+
+int prestlv_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent);
+#define F_SELKEY 1
+
+struct res_val {
+ u_int8_t result;
+ u_int8_t resv1;
+ u_int16_t resv2;
+};
+
+static const struct pdata_ops ForCES_pdata[PD_MAX_IND + 1] = {
+ /* PD_RSV_I */ {0, 0, 0, "Invalid message", NULL},
+ /* PD_SEL_I */ {F_TLV_KEYI, 0, 0, "KEYINFO TLV", pkeyitlv_print},
+ /* PD_FDT_I */ {F_TLV_FULD, 0, B_FULLD, "FULLDATA TLV", fdatatlv_print},
+ /* PD_SDT_I */ {F_TLV_SPAD, 0, B_SPARD, "SPARSEDATA TLV", sdatatlv_print},
+ /* PD_RES_I */ {F_TLV_REST, 0, B_RESTV, "RESULT TLV", prestlv_print},
+ /* PD_PDT_I */
+ {F_TLV_PDAT, 0, 0, "Inner PATH-DATA TLV", recpdoptlv_print},
+};
+
+static inline const struct pdata_ops *get_forces_pd(u_int16_t pd)
+{
+ int i;
+ for (i = PD_RSV_I + 1; i <= PD_MAX_IND; i++) {
+ const struct pdata_ops *pdo = &ForCES_pdata[i];
+ if (pdo->v == pd)
+ return pdo;
+ }
+ return &ForCES_pdata[TOM_RSV_I];
+}
+
+enum {
+ E_SUCCESS,
+ E_INVALID_HEADER,
+ E_LENGTH_MISMATCH,
+ E_VERSION_MISMATCH,
+ E_INVALID_DESTINATION_PID,
+ E_LFB_UNKNOWN,
+ E_LFB_NOT_FOUND,
+ E_LFB_INSTANCE_ID_NOT_FOUND,
+ E_INVALID_PATH,
+ E_COMPONENT_DOES_NOT_EXIST,
+ E_EXISTS,
+ E_NOT_FOUND,
+ E_READ_ONLY,
+ E_INVALID_ARRAY_CREATION,
+ E_VALUE_OUT_OF_RANGE,
+ E_CONTENTS_TOO_LONG,
+ E_INVALID_PARAMETERS,
+ E_INVALID_MESSAGE_TYPE,
+ E_INVALID_FLAGS,
+ E_INVALID_TLV,
+ E_EVENT_ERROR,
+ E_NOT_SUPPORTED,
+ E_MEMORY_ERROR,
+ E_INTERNAL_ERROR,
+ /* 0x18-0xFE are reserved .. */
+ E_UNSPECIFIED_ERROR = 0XFF
+};
+
+const struct tok ForCES_errs[] = {
+ {E_SUCCESS, "SUCCESS"},
+ {E_INVALID_HEADER, "INVALID HEADER"},
+ {E_LENGTH_MISMATCH, "LENGTH MISMATCH"},
+ {E_VERSION_MISMATCH, "VERSION MISMATCH"},
+ {E_INVALID_DESTINATION_PID, "INVALID DESTINATION PID"},
+ {E_LFB_UNKNOWN, "LFB UNKNOWN"},
+ {E_LFB_NOT_FOUND, "LFB NOT FOUND"},
+ {E_LFB_INSTANCE_ID_NOT_FOUND, "LFB INSTANCE ID NOT FOUND"},
+ {E_INVALID_PATH, "INVALID PATH"},
+ {E_COMPONENT_DOES_NOT_EXIST, "COMPONENT DOES NOT EXIST"},
+ {E_EXISTS, "EXISTS ALREADY"},
+ {E_NOT_FOUND, "NOT FOUND"},
+ {E_READ_ONLY, "READ ONLY"},
+ {E_INVALID_ARRAY_CREATION, "INVALID ARRAY CREATION"},
+ {E_VALUE_OUT_OF_RANGE, "VALUE OUT OF RANGE"},
+ {E_CONTENTS_TOO_LONG, "CONTENTS TOO LONG"},
+ {E_INVALID_PARAMETERS, "INVALID PARAMETERS"},
+ {E_INVALID_MESSAGE_TYPE, "INVALID MESSAGE TYPE"},
+ {E_INVALID_FLAGS, "INVALID FLAGS"},
+ {E_INVALID_TLV, "INVALID TLV"},
+ {E_EVENT_ERROR, "EVENT ERROR"},
+ {E_NOT_SUPPORTED, "NOT SUPPORTED"},
+ {E_MEMORY_ERROR, "MEMORY ERROR"},
+ {E_INTERNAL_ERROR, "INTERNAL ERROR"},
+ {E_UNSPECIFIED_ERROR, "UNSPECIFIED ERROR"},
+ {0, NULL}
+};
diff --git a/freebsd/contrib/tcpdump/gmpls.c b/freebsd/contrib/tcpdump/gmpls.c
new file mode 100644
index 00000000..8216d658
--- /dev/null
+++ b/freebsd/contrib/tcpdump/gmpls.c
@@ -0,0 +1,199 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/gmpls.c,v 1.7 2006-04-14 07:11:59 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include "interface.h"
+#include "gmpls.h"
+
+/* rfc3471 */
+const struct tok gmpls_link_prot_values[] = {
+ { 0x01, "Extra Traffic"},
+ { 0x02, "Unprotected"},
+ { 0x04, "Shared"},
+ { 0x08, "Dedicated 1:1"},
+ { 0x10, "Dedicated 1+1"},
+ { 0x20, "Enhanced"},
+ { 0x40, "Reserved"},
+ { 0x80, "Reserved"},
+ { 0, NULL }
+};
+
+/* rfc3471 */
+const struct tok gmpls_switch_cap_values[] = {
+ { GMPLS_PSC1, "Packet-Switch Capable-1"},
+ { GMPLS_PSC2, "Packet-Switch Capable-2"},
+ { GMPLS_PSC3, "Packet-Switch Capable-3"},
+ { GMPLS_PSC4, "Packet-Switch Capable-4"},
+ { GMPLS_L2SC, "Layer-2 Switch Capable"},
+ { GMPLS_TSC, "Time-Division-Multiplex"},
+ { GMPLS_LSC, "Lambda-Switch Capable"},
+ { GMPLS_FSC, "Fiber-Switch Capable"},
+ { 0, NULL }
+};
+
+/* rfc4205 */
+const struct tok gmpls_switch_cap_tsc_indication_values[] = {
+ { 0, "Standard SONET/SDH" },
+ { 1, "Arbitrary SONET/SDH" },
+ { 0, NULL }
+};
+
+/* rfc3471 */
+const struct tok gmpls_encoding_values[] = {
+ { 1, "Packet"},
+ { 2, "Ethernet V2/DIX"},
+ { 3, "ANSI/ETSI PDH"},
+ { 4, "Reserved"},
+ { 5, "SDH ITU-T G.707/SONET ANSI T1.105"},
+ { 6, "Reserved"},
+ { 7, "Digital Wrapper"},
+ { 8, "Lambda (photonic)"},
+ { 9, "Fiber"},
+ { 10, "Reserved"},
+ { 11, "FiberChannel"},
+ { 0, NULL }
+};
+
+/* rfc3471 */
+const struct tok gmpls_payload_values[] = {
+ { 0, "Unknown"},
+ { 1, "Reserved"},
+ { 2, "Reserved"},
+ { 3, "Reserved"},
+ { 4, "Reserved"},
+ { 5, "Asynchronous mapping of E4"},
+ { 6, "Asynchronous mapping of DS3/T3"},
+ { 7, "Asynchronous mapping of E3"},
+ { 8, "Bit synchronous mapping of E3"},
+ { 9, "Byte synchronous mapping of E3"},
+ { 10, "Asynchronous mapping of DS2/T2"},
+ { 11, "Bit synchronous mapping of DS2/T2"},
+ { 12, "Reserved"},
+ { 13, "Asynchronous mapping of E1"},
+ { 14, "Byte synchronous mapping of E1"},
+ { 15, "Byte synchronous mapping of 31 * DS0"},
+ { 16, "Asynchronous mapping of DS1/T1"},
+ { 17, "Bit synchronous mapping of DS1/T1"},
+ { 18, "Byte synchronous mapping of DS1/T1"},
+ { 19, "VC-11 in VC-12"},
+ { 20, "Reserved"},
+ { 21, "Reserved"},
+ { 22, "DS1 SF Asynchronous"},
+ { 23, "DS1 ESF Asynchronous"},
+ { 24, "DS3 M23 Asynchronous"},
+ { 25, "DS3 C-Bit Parity Asynchronous"},
+ { 26, "VT/LOVC"},
+ { 27, "STS SPE/HOVC"},
+ { 28, "POS - No Scrambling, 16 bit CRC"},
+ { 29, "POS - No Scrambling, 32 bit CRC"},
+ { 30, "POS - Scrambling, 16 bit CRC"},
+ { 31, "POS - Scrambling, 32 bit CRC"},
+ { 32, "ATM mapping"},
+ { 33, "Ethernet PHY"},
+ { 34, "SONET/SDH"},
+ { 35, "Reserved (SONET deprecated)"},
+ { 36, "Digital Wrapper"},
+ { 37, "Lambda"},
+ { 38, "ANSI/ETSI PDH"},
+ { 39, "Reserved"},
+ { 40, "Link Access Protocol SDH (X.85 and X.86)"},
+ { 41, "FDDI"},
+ { 42, "DQDB (ETSI ETS 300 216)"},
+ { 43, "FiberChannel-3 (Services)"},
+ { 44, "HDLC"},
+ { 45, "Ethernet V2/DIX (only)"},
+ { 46, "Ethernet 802.3 (only)"},
+/* draft-ietf-ccamp-gmpls-g709-04.txt */
+ { 47, "G.709 ODUj"},
+ { 48, "G.709 OTUk(v)"},
+ { 49, "CBR/CBRa"},
+ { 50, "CBRb"},
+ { 51, "BSOT"},
+ { 52, "BSNT"},
+ { 53, "IP/PPP (GFP)"},
+ { 54, "Ethernet MAC (framed GFP)"},
+ { 55, "Ethernet PHY (transparent GFP)"},
+ { 56, "ESCON"},
+ { 57, "FICON"},
+ { 58, "Fiber Channel"},
+ { 0, NULL }
+};
+
+/*
+ * Link Type values used by LMP Service Discovery (specifically, the Client
+ * Port Service Attributes Object). See UNI 1.0 section 9.4.2 for details.
+ */
+const struct tok lmp_sd_service_config_cpsa_link_type_values[] = {
+ { 5, "SDH ITU-T G.707"},
+ { 6, "SONET ANSI T1.105"},
+ { 0, NULL}
+};
+
+/*
+ * Signal Type values for SDH links used by LMP Service Discovery (specifically,
+ * the Client Port Service Attributes Object). See UNI 1.0 section 9.4.2 for
+ * details.
+ */
+const struct tok lmp_sd_service_config_cpsa_signal_type_sdh_values[] = {
+ { 5, "VC-3"},
+ { 6, "VC-4"},
+ { 7, "STM-0"},
+ { 8, "STM-1"},
+ { 9, "STM-4"},
+ { 10, "STM-16"},
+ { 11, "STM-64"},
+ { 12, "STM-256"},
+ { 0, NULL}
+};
+
+/*
+ * Signal Type values for SONET links used by LMP Service Discovery (specifically,
+ * the Client Port Service Attributes Object). See UNI 1.0 section 9.4.2 for
+ * details.
+ */
+const struct tok lmp_sd_service_config_cpsa_signal_type_sonet_values[] = {
+ { 5, "STS-1 SPE"},
+ { 6, "STS-3c SPE"},
+ { 7, "STS-1"},
+ { 8, "STM-3"},
+ { 9, "STM-12"},
+ { 10, "STM-48"},
+ { 11, "STM-192"},
+ { 12, "STM-768"},
+ { 0, NULL}
+};
+
+#define DIFFSERV_BC_MODEL_RDM 0 /* draft-ietf-tewg-diff-te-proto-07 */
+#define DIFFSERV_BC_MODEL_MAM 1 /* draft-ietf-tewg-diff-te-proto-07 */
+#define DIFFSERV_BC_MODEL_EXTD_MAM 254 /* experimental */
+
+const struct tok diffserv_te_bc_values[] = {
+ { DIFFSERV_BC_MODEL_RDM, "Russian dolls"},
+ { DIFFSERV_BC_MODEL_MAM, "Maximum allocation"},
+ { DIFFSERV_BC_MODEL_EXTD_MAM, "Maximum allocation with E-LSP support"},
+ { 0, NULL }
+};
diff --git a/freebsd/contrib/tcpdump/gmpls.h b/freebsd/contrib/tcpdump/gmpls.h
new file mode 100644
index 00000000..8db99dea
--- /dev/null
+++ b/freebsd/contrib/tcpdump/gmpls.h
@@ -0,0 +1,34 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/gmpls.h,v 1.5 2006-04-14 07:11:59 hannes Exp $ (LBL) */
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+#define GMPLS_PSC1 1
+#define GMPLS_PSC2 2
+#define GMPLS_PSC3 3
+#define GMPLS_PSC4 4
+#define GMPLS_L2SC 51
+#define GMPLS_TSC 100
+#define GMPLS_LSC 150
+#define GMPLS_FSC 200
+
+extern const struct tok gmpls_link_prot_values[];
+extern const struct tok gmpls_switch_cap_values[];
+extern const struct tok gmpls_switch_cap_tsc_indication_values[];
+extern const struct tok gmpls_encoding_values[];
+extern const struct tok gmpls_payload_values[];
+extern const struct tok diffserv_te_bc_values[];
+extern const struct tok lmp_sd_service_config_cpsa_link_type_values[];
+extern const struct tok lmp_sd_service_config_cpsa_signal_type_sdh_values[];
+extern const struct tok lmp_sd_service_config_cpsa_signal_type_sonet_values[];
diff --git a/freebsd/contrib/tcpdump/gmt2local.c b/freebsd/contrib/tcpdump/gmt2local.c
new file mode 100644
index 00000000..6e220919
--- /dev/null
+++ b/freebsd/contrib/tcpdump/gmt2local.c
@@ -0,0 +1,73 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/gmt2local.c,v 1.9 2003-11-16 09:36:09 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#include "gmt2local.h"
+
+/*
+ * Returns the difference between gmt and local time in seconds.
+ * Use gmtime() and localtime() to keep things simple.
+ */
+int32_t
+gmt2local(time_t t)
+{
+ register int dt, dir;
+ register struct tm *gmt, *loc;
+ struct tm sgmt;
+
+ if (t == 0)
+ t = time(NULL);
+ gmt = &sgmt;
+ *gmt = *gmtime(&t);
+ loc = localtime(&t);
+ dt = (loc->tm_hour - gmt->tm_hour) * 60 * 60 +
+ (loc->tm_min - gmt->tm_min) * 60;
+
+ /*
+ * If the year or julian day is different, we span 00:00 GMT
+ * and must add or subtract a day. Check the year first to
+ * avoid problems when the julian day wraps.
+ */
+ dir = loc->tm_year - gmt->tm_year;
+ if (dir == 0)
+ dir = loc->tm_yday - gmt->tm_yday;
+ dt += dir * 24 * 60 * 60;
+
+ return (dt);
+}
diff --git a/freebsd/contrib/tcpdump/gmt2local.h b/freebsd/contrib/tcpdump/gmt2local.h
new file mode 100644
index 00000000..f7b3841e
--- /dev/null
+++ b/freebsd/contrib/tcpdump/gmt2local.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /tcpdump/master/tcpdump/gmt2local.h,v 1.2 1999-10-07 23:47:10 mcr Exp $ (LBL)
+ */
+#ifndef gmt2local_h
+#define gmt2local_h
+
+int32_t gmt2local(time_t);
+#endif
diff --git a/freebsd/contrib/tcpdump/icmp6.h b/freebsd/contrib/tcpdump/icmp6.h
new file mode 100644
index 00000000..c4d292e5
--- /dev/null
+++ b/freebsd/contrib/tcpdump/icmp6.h
@@ -0,0 +1,473 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/icmp6.h,v 1.18 2007-08-29 02:31:44 mcr Exp $ (LBL) */
+/* NetBSD: icmp6.h,v 1.13 2000/08/03 16:30:37 itojun Exp */
+/* $KAME: icmp6.h,v 1.22 2000/08/03 15:25:16 jinmei Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)ip_icmp.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_ICMP6_H_
+#define _NETINET_ICMP6_H_
+
+struct icmp6_hdr {
+ u_int8_t icmp6_type; /* type field */
+ u_int8_t icmp6_code; /* code field */
+ u_int16_t icmp6_cksum; /* checksum field */
+ union {
+ u_int32_t icmp6_un_data32[1]; /* type-specific field */
+ u_int16_t icmp6_un_data16[2]; /* type-specific field */
+ u_int8_t icmp6_un_data8[4]; /* type-specific field */
+ } icmp6_dataun;
+};
+
+#define icmp6_data32 icmp6_dataun.icmp6_un_data32
+#define icmp6_data16 icmp6_dataun.icmp6_un_data16
+#define icmp6_data8 icmp6_dataun.icmp6_un_data8
+#define icmp6_pptr icmp6_data32[0] /* parameter prob */
+#define icmp6_mtu icmp6_data32[0] /* packet too big */
+#define icmp6_id icmp6_data16[0] /* echo request/reply */
+#define icmp6_seq icmp6_data16[1] /* echo request/reply */
+#define icmp6_maxdelay icmp6_data16[0] /* mcast group membership */
+
+#define ICMP6_DST_UNREACH 1 /* dest unreachable, codes: */
+#define ICMP6_PACKET_TOO_BIG 2 /* packet too big */
+#define ICMP6_TIME_EXCEEDED 3 /* time exceeded, code: */
+#define ICMP6_PARAM_PROB 4 /* ip6 header bad */
+
+#define ICMP6_ECHO_REQUEST 128 /* echo service */
+#define ICMP6_ECHO_REPLY 129 /* echo reply */
+#define ICMP6_MEMBERSHIP_QUERY 130 /* group membership query */
+#define MLD6_LISTENER_QUERY 130 /* multicast listener query */
+#define ICMP6_MEMBERSHIP_REPORT 131 /* group membership report */
+#define MLD6_LISTENER_REPORT 131 /* multicast listener report */
+#define ICMP6_MEMBERSHIP_REDUCTION 132 /* group membership termination */
+#define MLD6_LISTENER_DONE 132 /* multicast listener done */
+
+#define ND_ROUTER_SOLICIT 133 /* router solicitation */
+#define ND_ROUTER_ADVERT 134 /* router advertisement */
+#define ND_NEIGHBOR_SOLICIT 135 /* neighbor solicitation */
+#define ND_NEIGHBOR_ADVERT 136 /* neighbor advertisement */
+#define ND_REDIRECT 137 /* redirect */
+
+#define ICMP6_ROUTER_RENUMBERING 138 /* router renumbering */
+
+#define ICMP6_WRUREQUEST 139 /* who are you request */
+#define ICMP6_WRUREPLY 140 /* who are you reply */
+#define ICMP6_FQDN_QUERY 139 /* FQDN query */
+#define ICMP6_FQDN_REPLY 140 /* FQDN reply */
+#define ICMP6_NI_QUERY 139 /* node information request */
+#define ICMP6_NI_REPLY 140 /* node information reply */
+#define IND_SOLICIT 141 /* inverse neighbor solicitation */
+#define IND_ADVERT 142 /* inverse neighbor advertisement */
+
+#define ICMP6_V2_MEMBERSHIP_REPORT 143 /* v2 membership report */
+#define MLDV2_LISTENER_REPORT 143 /* v2 multicast listener report */
+#define ICMP6_HADISCOV_REQUEST 144
+#define ICMP6_HADISCOV_REPLY 145
+#define ICMP6_MOBILEPREFIX_SOLICIT 146
+#define ICMP6_MOBILEPREFIX_ADVERT 147
+
+#define MLD6_MTRACE_RESP 200 /* mtrace response(to sender) */
+#define MLD6_MTRACE 201 /* mtrace messages */
+
+#define ICMP6_MAXTYPE 201
+
+#define ICMP6_DST_UNREACH_NOROUTE 0 /* no route to destination */
+#define ICMP6_DST_UNREACH_ADMIN 1 /* administratively prohibited */
+#define ICMP6_DST_UNREACH_NOTNEIGHBOR 2 /* not a neighbor(obsolete) */
+#define ICMP6_DST_UNREACH_BEYONDSCOPE 2 /* beyond scope of source address */
+#define ICMP6_DST_UNREACH_ADDR 3 /* address unreachable */
+#define ICMP6_DST_UNREACH_NOPORT 4 /* port unreachable */
+
+#define ICMP6_TIME_EXCEED_TRANSIT 0 /* ttl==0 in transit */
+#define ICMP6_TIME_EXCEED_REASSEMBLY 1 /* ttl==0 in reass */
+
+#define ICMP6_PARAMPROB_HEADER 0 /* erroneous header field */
+#define ICMP6_PARAMPROB_NEXTHEADER 1 /* unrecognized next header */
+#define ICMP6_PARAMPROB_OPTION 2 /* unrecognized option */
+
+#define ICMP6_INFOMSG_MASK 0x80 /* all informational messages */
+
+#define ICMP6_NI_SUBJ_IPV6 0 /* Query Subject is an IPv6 address */
+#define ICMP6_NI_SUBJ_FQDN 1 /* Query Subject is a Domain name */
+#define ICMP6_NI_SUBJ_IPV4 2 /* Query Subject is an IPv4 address */
+
+#define ICMP6_NI_SUCCESS 0 /* node information successful reply */
+#define ICMP6_NI_REFUSED 1 /* node information request is refused */
+#define ICMP6_NI_UNKNOWN 2 /* unknown Qtype */
+
+#define ICMP6_ROUTER_RENUMBERING_COMMAND 0 /* rr command */
+#define ICMP6_ROUTER_RENUMBERING_RESULT 1 /* rr result */
+#define ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET 255 /* rr seq num reset */
+
+/* Used in kernel only */
+#define ND_REDIRECT_ONLINK 0 /* redirect to an on-link node */
+#define ND_REDIRECT_ROUTER 1 /* redirect to a better router */
+
+/*
+ * Multicast Listener Discovery
+ */
+struct mld6_hdr {
+ struct icmp6_hdr mld6_hdr;
+ struct in6_addr mld6_addr; /* multicast address */
+};
+
+#define mld6_type mld6_hdr.icmp6_type
+#define mld6_code mld6_hdr.icmp6_code
+#define mld6_cksum mld6_hdr.icmp6_cksum
+#define mld6_maxdelay mld6_hdr.icmp6_data16[0]
+#define mld6_reserved mld6_hdr.icmp6_data16[1]
+
+#define MLD_MINLEN 24
+#define MLDV2_MINLEN 28
+
+/*
+ * Neighbor Discovery
+ */
+
+struct nd_router_solicit { /* router solicitation */
+ struct icmp6_hdr nd_rs_hdr;
+ /* could be followed by options */
+};
+
+#define nd_rs_type nd_rs_hdr.icmp6_type
+#define nd_rs_code nd_rs_hdr.icmp6_code
+#define nd_rs_cksum nd_rs_hdr.icmp6_cksum
+#define nd_rs_reserved nd_rs_hdr.icmp6_data32[0]
+
+struct nd_router_advert { /* router advertisement */
+ struct icmp6_hdr nd_ra_hdr;
+ u_int32_t nd_ra_reachable; /* reachable time */
+ u_int32_t nd_ra_retransmit; /* retransmit timer */
+ /* could be followed by options */
+};
+
+#define nd_ra_type nd_ra_hdr.icmp6_type
+#define nd_ra_code nd_ra_hdr.icmp6_code
+#define nd_ra_cksum nd_ra_hdr.icmp6_cksum
+#define nd_ra_curhoplimit nd_ra_hdr.icmp6_data8[0]
+#define nd_ra_flags_reserved nd_ra_hdr.icmp6_data8[1]
+#define ND_RA_FLAG_MANAGED 0x80
+#define ND_RA_FLAG_OTHER 0x40
+#define ND_RA_FLAG_HOME_AGENT 0x20
+
+/*
+ * Router preference values based on draft-draves-ipngwg-router-selection-01.
+ * These are non-standard definitions.
+ */
+#define ND_RA_FLAG_RTPREF_MASK 0x18 /* 00011000 */
+
+#define ND_RA_FLAG_RTPREF_HIGH 0x08 /* 00001000 */
+#define ND_RA_FLAG_RTPREF_MEDIUM 0x00 /* 00000000 */
+#define ND_RA_FLAG_RTPREF_LOW 0x18 /* 00011000 */
+#define ND_RA_FLAG_RTPREF_RSV 0x10 /* 00010000 */
+
+#define nd_ra_router_lifetime nd_ra_hdr.icmp6_data16[1]
+
+struct nd_neighbor_solicit { /* neighbor solicitation */
+ struct icmp6_hdr nd_ns_hdr;
+ struct in6_addr nd_ns_target; /*target address */
+ /* could be followed by options */
+};
+
+#define nd_ns_type nd_ns_hdr.icmp6_type
+#define nd_ns_code nd_ns_hdr.icmp6_code
+#define nd_ns_cksum nd_ns_hdr.icmp6_cksum
+#define nd_ns_reserved nd_ns_hdr.icmp6_data32[0]
+
+struct nd_neighbor_advert { /* neighbor advertisement */
+ struct icmp6_hdr nd_na_hdr;
+ struct in6_addr nd_na_target; /* target address */
+ /* could be followed by options */
+};
+
+#define nd_na_type nd_na_hdr.icmp6_type
+#define nd_na_code nd_na_hdr.icmp6_code
+#define nd_na_cksum nd_na_hdr.icmp6_cksum
+#define nd_na_flags_reserved nd_na_hdr.icmp6_data32[0]
+
+#define ND_NA_FLAG_ROUTER 0x80000000
+#define ND_NA_FLAG_SOLICITED 0x40000000
+#define ND_NA_FLAG_OVERRIDE 0x20000000
+
+struct nd_redirect { /* redirect */
+ struct icmp6_hdr nd_rd_hdr;
+ struct in6_addr nd_rd_target; /* target address */
+ struct in6_addr nd_rd_dst; /* destination address */
+ /* could be followed by options */
+};
+
+#define nd_rd_type nd_rd_hdr.icmp6_type
+#define nd_rd_code nd_rd_hdr.icmp6_code
+#define nd_rd_cksum nd_rd_hdr.icmp6_cksum
+#define nd_rd_reserved nd_rd_hdr.icmp6_data32[0]
+
+struct nd_opt_hdr { /* Neighbor discovery option header */
+ u_int8_t nd_opt_type;
+ u_int8_t nd_opt_len;
+ /* followed by option specific data*/
+};
+
+#define ND_OPT_SOURCE_LINKADDR 1
+#define ND_OPT_TARGET_LINKADDR 2
+#define ND_OPT_PREFIX_INFORMATION 3
+#define ND_OPT_REDIRECTED_HEADER 4
+#define ND_OPT_MTU 5
+#define ND_OPT_ADVINTERVAL 7
+#define ND_OPT_HOMEAGENT_INFO 8
+#define ND_OPT_ROUTE_INFO 9 /* draft-ietf-ipngwg-router-preference, not officially assigned yet */
+#define ND_OPT_RDNSS 25
+#define ND_OPT_DNSSL 31
+
+struct nd_opt_prefix_info { /* prefix information */
+ u_int8_t nd_opt_pi_type;
+ u_int8_t nd_opt_pi_len;
+ u_int8_t nd_opt_pi_prefix_len;
+ u_int8_t nd_opt_pi_flags_reserved;
+ u_int8_t nd_opt_pi_valid_time[4];
+ u_int8_t nd_opt_pi_preferred_time[4];
+ u_int8_t nd_opt_pi_reserved2[4];
+ struct in6_addr nd_opt_pi_prefix;
+};
+
+#define ND_OPT_PI_FLAG_ONLINK 0x80
+#define ND_OPT_PI_FLAG_AUTO 0x40
+#define ND_OPT_PI_FLAG_ROUTER 0x20 /*2292bis*/
+
+struct nd_opt_rd_hdr { /* redirected header */
+ u_int8_t nd_opt_rh_type;
+ u_int8_t nd_opt_rh_len;
+ u_int16_t nd_opt_rh_reserved1;
+ u_int32_t nd_opt_rh_reserved2;
+ /* followed by IP header and data */
+};
+
+struct nd_opt_mtu { /* MTU option */
+ u_int8_t nd_opt_mtu_type;
+ u_int8_t nd_opt_mtu_len;
+ u_int16_t nd_opt_mtu_reserved;
+ u_int32_t nd_opt_mtu_mtu;
+};
+
+struct nd_opt_rdnss { /* RDNSS RFC 6106 5.1 */
+ u_int8_t nd_opt_rdnss_type;
+ u_int8_t nd_opt_rdnss_len;
+ u_int16_t nd_opt_rdnss_reserved;
+ u_int32_t nd_opt_rdnss_lifetime;
+ struct in6_addr nd_opt_rdnss_addr[1]; /* variable-length */
+};
+
+struct nd_opt_dnssl { /* DNSSL RFC 6106 5.2 */
+ u_int8_t nd_opt_dnssl_type;
+ u_int8_t nd_opt_dnssl_len;
+ u_int16_t nd_opt_dnssl_reserved;
+ u_int32_t nd_opt_dnssl_lifetime;
+ /* followed by list of DNS search domains, variable-length */
+};
+
+struct nd_opt_advinterval { /* Advertisement interval option */
+ u_int8_t nd_opt_adv_type;
+ u_int8_t nd_opt_adv_len;
+ u_int16_t nd_opt_adv_reserved;
+ u_int32_t nd_opt_adv_interval;
+};
+
+struct nd_opt_homeagent_info { /* Home Agent info */
+ u_int8_t nd_opt_hai_type;
+ u_int8_t nd_opt_hai_len;
+ u_int16_t nd_opt_hai_reserved;
+ int16_t nd_opt_hai_preference;
+ u_int16_t nd_opt_hai_lifetime;
+};
+
+struct nd_opt_route_info { /* route info */
+ u_int8_t nd_opt_rti_type;
+ u_int8_t nd_opt_rti_len;
+ u_int8_t nd_opt_rti_prefixlen;
+ u_int8_t nd_opt_rti_flags;
+ u_int32_t nd_opt_rti_lifetime;
+ /* prefix follows */
+};
+
+/*
+ * icmp6 namelookup
+ */
+
+struct icmp6_namelookup {
+ struct icmp6_hdr icmp6_nl_hdr;
+ u_int8_t icmp6_nl_nonce[8];
+ int32_t icmp6_nl_ttl;
+#if 0
+ u_int8_t icmp6_nl_len;
+ u_int8_t icmp6_nl_name[3];
+#endif
+ /* could be followed by options */
+};
+
+/*
+ * icmp6 node information
+ */
+struct icmp6_nodeinfo {
+ struct icmp6_hdr icmp6_ni_hdr;
+ u_int8_t icmp6_ni_nonce[8];
+ /* could be followed by reply data */
+};
+
+#define ni_type icmp6_ni_hdr.icmp6_type
+#define ni_code icmp6_ni_hdr.icmp6_code
+#define ni_cksum icmp6_ni_hdr.icmp6_cksum
+#define ni_qtype icmp6_ni_hdr.icmp6_data16[0]
+#define ni_flags icmp6_ni_hdr.icmp6_data16[1]
+
+#define NI_QTYPE_NOOP 0 /* NOOP */
+#define NI_QTYPE_SUPTYPES 1 /* Supported Qtypes */
+#define NI_QTYPE_FQDN 2 /* FQDN (draft 04) */
+#define NI_QTYPE_DNSNAME 2 /* DNS Name */
+#define NI_QTYPE_NODEADDR 3 /* Node Addresses */
+#define NI_QTYPE_IPV4ADDR 4 /* IPv4 Addresses */
+
+/* network endian */
+#define NI_SUPTYPE_FLAG_COMPRESS ((u_int16_t)htons(0x1))
+#define NI_FQDN_FLAG_VALIDTTL ((u_int16_t)htons(0x1))
+
+/* network endian */
+#define NI_NODEADDR_FLAG_TRUNCATE ((u_int16_t)htons(0x1))
+#define NI_NODEADDR_FLAG_ALL ((u_int16_t)htons(0x2))
+#define NI_NODEADDR_FLAG_COMPAT ((u_int16_t)htons(0x4))
+#define NI_NODEADDR_FLAG_LINKLOCAL ((u_int16_t)htons(0x8))
+#define NI_NODEADDR_FLAG_SITELOCAL ((u_int16_t)htons(0x10))
+#define NI_NODEADDR_FLAG_GLOBAL ((u_int16_t)htons(0x20))
+#define NI_NODEADDR_FLAG_ANYCAST ((u_int16_t)htons(0x40)) /* just experimental. not in spec */
+
+struct ni_reply_fqdn {
+ u_int32_t ni_fqdn_ttl; /* TTL */
+ u_int8_t ni_fqdn_namelen; /* length in octets of the FQDN */
+ u_int8_t ni_fqdn_name[3]; /* XXX: alignment */
+};
+
+/*
+ * Router Renumbering. as router-renum-08.txt
+ */
+struct icmp6_router_renum { /* router renumbering header */
+ struct icmp6_hdr rr_hdr;
+ u_int8_t rr_segnum;
+ u_int8_t rr_flags;
+ u_int16_t rr_maxdelay;
+ u_int32_t rr_reserved;
+};
+#define ICMP6_RR_FLAGS_TEST 0x80
+#define ICMP6_RR_FLAGS_REQRESULT 0x40
+#define ICMP6_RR_FLAGS_FORCEAPPLY 0x20
+#define ICMP6_RR_FLAGS_SPECSITE 0x10
+#define ICMP6_RR_FLAGS_PREVDONE 0x08
+
+#define rr_type rr_hdr.icmp6_type
+#define rr_code rr_hdr.icmp6_code
+#define rr_cksum rr_hdr.icmp6_cksum
+#define rr_seqnum rr_hdr.icmp6_data32[0]
+
+struct rr_pco_match { /* match prefix part */
+ u_int8_t rpm_code;
+ u_int8_t rpm_len;
+ u_int8_t rpm_ordinal;
+ u_int8_t rpm_matchlen;
+ u_int8_t rpm_minlen;
+ u_int8_t rpm_maxlen;
+ u_int16_t rpm_reserved;
+ struct in6_addr rpm_prefix;
+};
+
+#define RPM_PCO_ADD 1
+#define RPM_PCO_CHANGE 2
+#define RPM_PCO_SETGLOBAL 3
+#define RPM_PCO_MAX 4
+
+struct rr_pco_use { /* use prefix part */
+ u_int8_t rpu_uselen;
+ u_int8_t rpu_keeplen;
+ u_int8_t rpu_ramask;
+ u_int8_t rpu_raflags;
+ u_int32_t rpu_vltime;
+ u_int32_t rpu_pltime;
+ u_int32_t rpu_flags;
+ struct in6_addr rpu_prefix;
+};
+#define ICMP6_RR_PCOUSE_RAFLAGS_ONLINK 0x80
+#define ICMP6_RR_PCOUSE_RAFLAGS_AUTO 0x40
+
+/* network endian */
+#define ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME ((u_int32_t)htonl(0x80000000))
+#define ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME ((u_int32_t)htonl(0x40000000))
+
+struct rr_result { /* router renumbering result message */
+ u_int16_t rrr_flags;
+ u_int8_t rrr_ordinal;
+ u_int8_t rrr_matchedlen;
+ u_int32_t rrr_ifid;
+ struct in6_addr rrr_prefix;
+};
+/* network endian */
+#define ICMP6_RR_RESULT_FLAGS_OOB ((u_int16_t)htons(0x0002))
+#define ICMP6_RR_RESULT_FLAGS_FORBIDDEN ((u_int16_t)htons(0x0001))
+
+#endif /* not _NETINET_ICMP6_H_ */
diff --git a/freebsd/contrib/tcpdump/ieee802_11.h b/freebsd/contrib/tcpdump/ieee802_11.h
new file mode 100644
index 00000000..2aa13450
--- /dev/null
+++ b/freebsd/contrib/tcpdump/ieee802_11.h
@@ -0,0 +1,347 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/ieee802_11.h,v 1.12 2007-07-22 19:59:06 guy Exp $ (LBL) */
+/*
+ * Copyright (c) 2001
+ * Fortress Technologies
+ * Charlie Lenahan ( clenahan@fortresstech.com )
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/* Lengths of 802.11 header components. */
+#define IEEE802_11_FC_LEN 2
+#define IEEE802_11_DUR_LEN 2
+#define IEEE802_11_DA_LEN 6
+#define IEEE802_11_SA_LEN 6
+#define IEEE802_11_BSSID_LEN 6
+#define IEEE802_11_RA_LEN 6
+#define IEEE802_11_TA_LEN 6
+#define IEEE802_11_SEQ_LEN 2
+#define IEEE802_11_CTL_LEN 2
+#define IEEE802_11_IV_LEN 3
+#define IEEE802_11_KID_LEN 1
+
+/* Frame check sequence length. */
+#define IEEE802_11_FCS_LEN 4
+
+/* Lengths of beacon components. */
+#define IEEE802_11_TSTAMP_LEN 8
+#define IEEE802_11_BCNINT_LEN 2
+#define IEEE802_11_CAPINFO_LEN 2
+#define IEEE802_11_LISTENINT_LEN 2
+
+#define IEEE802_11_AID_LEN 2
+#define IEEE802_11_STATUS_LEN 2
+#define IEEE802_11_REASON_LEN 2
+
+/* Length of previous AP in reassocation frame */
+#define IEEE802_11_AP_LEN 6
+
+#define T_MGMT 0x0 /* management */
+#define T_CTRL 0x1 /* control */
+#define T_DATA 0x2 /* data */
+#define T_RESV 0x3 /* reserved */
+
+#define ST_ASSOC_REQUEST 0x0
+#define ST_ASSOC_RESPONSE 0x1
+#define ST_REASSOC_REQUEST 0x2
+#define ST_REASSOC_RESPONSE 0x3
+#define ST_PROBE_REQUEST 0x4
+#define ST_PROBE_RESPONSE 0x5
+/* RESERVED 0x6 */
+/* RESERVED 0x7 */
+#define ST_BEACON 0x8
+#define ST_ATIM 0x9
+#define ST_DISASSOC 0xA
+#define ST_AUTH 0xB
+#define ST_DEAUTH 0xC
+#define ST_ACTION 0xD
+/* RESERVED 0xE */
+/* RESERVED 0xF */
+
+
+#define CTRL_CONTROL_WRAPPER 0x7
+#define CTRL_BAR 0x8
+#define CTRL_BA 0x9
+#define CTRL_PS_POLL 0xA
+#define CTRL_RTS 0xB
+#define CTRL_CTS 0xC
+#define CTRL_ACK 0xD
+#define CTRL_CF_END 0xE
+#define CTRL_END_ACK 0xF
+
+#define DATA_DATA 0x0
+#define DATA_DATA_CF_ACK 0x1
+#define DATA_DATA_CF_POLL 0x2
+#define DATA_DATA_CF_ACK_POLL 0x3
+#define DATA_NODATA 0x4
+#define DATA_NODATA_CF_ACK 0x5
+#define DATA_NODATA_CF_POLL 0x6
+#define DATA_NODATA_CF_ACK_POLL 0x7
+
+#define DATA_QOS_DATA 0x8
+#define DATA_QOS_DATA_CF_ACK 0x9
+#define DATA_QOS_DATA_CF_POLL 0xA
+#define DATA_QOS_DATA_CF_ACK_POLL 0xB
+#define DATA_QOS_NODATA 0xC
+#define DATA_QOS_CF_POLL_NODATA 0xE
+#define DATA_QOS_CF_ACK_POLL_NODATA 0xF
+
+/*
+ * The subtype field of a data frame is, in effect, composed of 4 flag
+ * bits - CF-Ack, CF-Poll, Null (means the frame doesn't actually have
+ * any data), and QoS.
+ */
+#define DATA_FRAME_IS_CF_ACK(x) ((x) & 0x01)
+#define DATA_FRAME_IS_CF_POLL(x) ((x) & 0x02)
+#define DATA_FRAME_IS_NULL(x) ((x) & 0x04)
+#define DATA_FRAME_IS_QOS(x) ((x) & 0x08)
+
+/*
+ * Bits in the frame control field.
+ */
+#define FC_VERSION(fc) ((fc) & 0x3)
+#define FC_TYPE(fc) (((fc) >> 2) & 0x3)
+#define FC_SUBTYPE(fc) (((fc) >> 4) & 0xF)
+#define FC_TO_DS(fc) ((fc) & 0x0100)
+#define FC_FROM_DS(fc) ((fc) & 0x0200)
+#define FC_MORE_FLAG(fc) ((fc) & 0x0400)
+#define FC_RETRY(fc) ((fc) & 0x0800)
+#define FC_POWER_MGMT(fc) ((fc) & 0x1000)
+#define FC_MORE_DATA(fc) ((fc) & 0x2000)
+#define FC_WEP(fc) ((fc) & 0x4000)
+#define FC_ORDER(fc) ((fc) & 0x8000)
+
+struct mgmt_header_t {
+ u_int16_t fc;
+ u_int16_t duration;
+ u_int8_t da[6];
+ u_int8_t sa[6];
+ u_int8_t bssid[6];
+ u_int16_t seq_ctrl;
+};
+
+#define MGMT_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
+ IEEE802_11_DA_LEN+IEEE802_11_SA_LEN+\
+ IEEE802_11_BSSID_LEN+IEEE802_11_SEQ_LEN)
+
+#define CAPABILITY_ESS(cap) ((cap) & 0x0001)
+#define CAPABILITY_IBSS(cap) ((cap) & 0x0002)
+#define CAPABILITY_CFP(cap) ((cap) & 0x0004)
+#define CAPABILITY_CFP_REQ(cap) ((cap) & 0x0008)
+#define CAPABILITY_PRIVACY(cap) ((cap) & 0x0010)
+
+struct ssid_t {
+ u_int8_t element_id;
+ u_int8_t length;
+ u_char ssid[33]; /* 32 + 1 for null */
+};
+
+struct rates_t {
+ u_int8_t element_id;
+ u_int8_t length;
+ u_int8_t rate[16];
+};
+
+struct challenge_t {
+ u_int8_t element_id;
+ u_int8_t length;
+ u_int8_t text[254]; /* 1-253 + 1 for null */
+};
+
+struct fh_t {
+ u_int8_t element_id;
+ u_int8_t length;
+ u_int16_t dwell_time;
+ u_int8_t hop_set;
+ u_int8_t hop_pattern;
+ u_int8_t hop_index;
+};
+
+struct ds_t {
+ u_int8_t element_id;
+ u_int8_t length;
+ u_int8_t channel;
+};
+
+struct cf_t {
+ u_int8_t element_id;
+ u_int8_t length;
+ u_int8_t count;
+ u_int8_t period;
+ u_int16_t max_duration;
+ u_int16_t dur_remaing;
+};
+
+struct tim_t {
+ u_int8_t element_id;
+ u_int8_t length;
+ u_int8_t count;
+ u_int8_t period;
+ u_int8_t bitmap_control;
+ u_int8_t bitmap[251];
+};
+
+#define E_SSID 0
+#define E_RATES 1
+#define E_FH 2
+#define E_DS 3
+#define E_CF 4
+#define E_TIM 5
+#define E_IBSS 6
+/* reserved 7 */
+/* reserved 8 */
+/* reserved 9 */
+/* reserved 10 */
+/* reserved 11 */
+/* reserved 12 */
+/* reserved 13 */
+/* reserved 14 */
+/* reserved 15 */
+/* reserved 16 */
+
+#define E_CHALLENGE 16
+/* reserved 17 */
+/* reserved 18 */
+/* reserved 19 */
+/* reserved 16 */
+/* reserved 16 */
+
+
+struct mgmt_body_t {
+ u_int8_t timestamp[IEEE802_11_TSTAMP_LEN];
+ u_int16_t beacon_interval;
+ u_int16_t listen_interval;
+ u_int16_t status_code;
+ u_int16_t aid;
+ u_char ap[IEEE802_11_AP_LEN];
+ u_int16_t reason_code;
+ u_int16_t auth_alg;
+ u_int16_t auth_trans_seq_num;
+ int challenge_present;
+ struct challenge_t challenge;
+ u_int16_t capability_info;
+ int ssid_present;
+ struct ssid_t ssid;
+ int rates_present;
+ struct rates_t rates;
+ int ds_present;
+ struct ds_t ds;
+ int cf_present;
+ struct cf_t cf;
+ int fh_present;
+ struct fh_t fh;
+ int tim_present;
+ struct tim_t tim;
+};
+
+struct ctrl_rts_t {
+ u_int16_t fc;
+ u_int16_t duration;
+ u_int8_t ra[6];
+ u_int8_t ta[6];
+ u_int8_t fcs[4];
+};
+
+#define CTRL_RTS_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
+ IEEE802_11_RA_LEN+IEEE802_11_TA_LEN)
+
+struct ctrl_cts_t {
+ u_int16_t fc;
+ u_int16_t duration;
+ u_int8_t ra[6];
+ u_int8_t fcs[4];
+};
+
+#define CTRL_CTS_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN)
+
+struct ctrl_ack_t {
+ u_int16_t fc;
+ u_int16_t duration;
+ u_int8_t ra[6];
+ u_int8_t fcs[4];
+};
+
+#define CTRL_ACK_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN)
+
+struct ctrl_ps_poll_t {
+ u_int16_t fc;
+ u_int16_t aid;
+ u_int8_t bssid[6];
+ u_int8_t ta[6];
+ u_int8_t fcs[4];
+};
+
+#define CTRL_PS_POLL_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_AID_LEN+\
+ IEEE802_11_BSSID_LEN+IEEE802_11_TA_LEN)
+
+struct ctrl_end_t {
+ u_int16_t fc;
+ u_int16_t duration;
+ u_int8_t ra[6];
+ u_int8_t bssid[6];
+ u_int8_t fcs[4];
+};
+
+#define CTRL_END_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
+ IEEE802_11_RA_LEN+IEEE802_11_BSSID_LEN)
+
+struct ctrl_end_ack_t {
+ u_int16_t fc;
+ u_int16_t duration;
+ u_int8_t ra[6];
+ u_int8_t bssid[6];
+ u_int8_t fcs[4];
+};
+
+#define CTRL_END_ACK_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
+ IEEE802_11_RA_LEN+IEEE802_11_BSSID_LEN)
+
+struct ctrl_ba_t {
+ u_int16_t fc;
+ u_int16_t duration;
+ u_int8_t ra[6];
+ u_int8_t fcs[4];
+};
+
+#define CTRL_BA_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+IEEE802_11_RA_LEN)
+
+struct ctrl_bar_t {
+ u_int16_t fc;
+ u_int16_t dur;
+ u_int8_t ra[6];
+ u_int8_t ta[6];
+ u_int16_t ctl;
+ u_int16_t seq;
+ u_int8_t fcs[4];
+};
+
+#define CTRL_BAR_HDRLEN (IEEE802_11_FC_LEN+IEEE802_11_DUR_LEN+\
+ IEEE802_11_RA_LEN+IEEE802_11_TA_LEN+\
+ IEEE802_11_CTL_LEN+IEEE802_11_SEQ_LEN)
+
+struct meshcntl_t {
+ u_int8_t flags;
+ u_int8_t ttl;
+ u_int8_t seq[4];
+ u_int8_t addr4[6];
+ u_int8_t addr5[6];
+ u_int8_t addr6[6];
+};
+
+#define IV_IV(iv) ((iv) & 0xFFFFFF)
+#define IV_PAD(iv) (((iv) >> 24) & 0x3F)
+#define IV_KEYID(iv) (((iv) >> 30) & 0x03)
diff --git a/freebsd/contrib/tcpdump/ieee802_11_radio.h b/freebsd/contrib/tcpdump/ieee802_11_radio.h
new file mode 100644
index 00000000..812b5ac3
--- /dev/null
+++ b/freebsd/contrib/tcpdump/ieee802_11_radio.h
@@ -0,0 +1,291 @@
+/* $FreeBSD$ */
+/* NetBSD: ieee802_11_radio.h,v 1.2 2006/02/26 03:04:03 dyoung Exp */
+/* $Header: /tcpdump/master/tcpdump/ieee802_11_radio.h,v 1.3 2007-08-29 02:31:44 mcr Exp $ */
+
+/*-
+ * Copyright (c) 2003, 2004 David Young. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of David Young may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY DAVID YOUNG ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DAVID
+ * YOUNG BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ */
+#ifndef _NET_IF_IEEE80211RADIOTAP_H_
+#define _NET_IF_IEEE80211RADIOTAP_H_
+
+/* A generic radio capture format is desirable. It must be
+ * rigidly defined (e.g., units for fields should be given),
+ * and easily extensible.
+ *
+ * The following is an extensible radio capture format. It is
+ * based on a bitmap indicating which fields are present.
+ *
+ * I am trying to describe precisely what the application programmer
+ * should expect in the following, and for that reason I tell the
+ * units and origin of each measurement (where it applies), or else I
+ * use sufficiently weaselly language ("is a monotonically nondecreasing
+ * function of...") that I cannot set false expectations for lawyerly
+ * readers.
+ */
+
+/*
+ * The radio capture header precedes the 802.11 header.
+ *
+ * Note well: all radiotap fields are little-endian.
+ */
+struct ieee80211_radiotap_header {
+ u_int8_t it_version; /* Version 0. Only increases
+ * for drastic changes,
+ * introduction of compatible
+ * new fields does not count.
+ */
+ u_int8_t it_pad;
+ u_int16_t it_len; /* length of the whole
+ * header in bytes, including
+ * it_version, it_pad,
+ * it_len, and data fields.
+ */
+ u_int32_t it_present; /* A bitmap telling which
+ * fields are present. Set bit 31
+ * (0x80000000) to extend the
+ * bitmap by another 32 bits.
+ * Additional extensions are made
+ * by setting bit 31.
+ */
+};
+
+/* Name Data type Units
+ * ---- --------- -----
+ *
+ * IEEE80211_RADIOTAP_TSFT u_int64_t microseconds
+ *
+ * Value in microseconds of the MAC's 64-bit 802.11 Time
+ * Synchronization Function timer when the first bit of the
+ * MPDU arrived at the MAC. For received frames, only.
+ *
+ * IEEE80211_RADIOTAP_CHANNEL 2 x u_int16_t MHz, bitmap
+ *
+ * Tx/Rx frequency in MHz, followed by flags (see below).
+ * Note that IEEE80211_RADIOTAP_XCHANNEL must be used to
+ * represent an HT channel as there is not enough room in
+ * the flags word.
+ *
+ * IEEE80211_RADIOTAP_FHSS u_int16_t see below
+ *
+ * For frequency-hopping radios, the hop set (first byte)
+ * and pattern (second byte).
+ *
+ * IEEE80211_RADIOTAP_RATE u_int8_t 500kb/s or index
+ *
+ * Tx/Rx data rate. If bit 0x80 is set then it represents an
+ * an MCS index and not an IEEE rate.
+ *
+ * IEEE80211_RADIOTAP_DBM_ANTSIGNAL int8_t decibels from
+ * one milliwatt (dBm)
+ *
+ * RF signal power at the antenna, decibel difference from
+ * one milliwatt.
+ *
+ * IEEE80211_RADIOTAP_DBM_ANTNOISE int8_t decibels from
+ * one milliwatt (dBm)
+ *
+ * RF noise power at the antenna, decibel difference from one
+ * milliwatt.
+ *
+ * IEEE80211_RADIOTAP_DB_ANTSIGNAL u_int8_t decibel (dB)
+ *
+ * RF signal power at the antenna, decibel difference from an
+ * arbitrary, fixed reference.
+ *
+ * IEEE80211_RADIOTAP_DB_ANTNOISE u_int8_t decibel (dB)
+ *
+ * RF noise power at the antenna, decibel difference from an
+ * arbitrary, fixed reference point.
+ *
+ * IEEE80211_RADIOTAP_LOCK_QUALITY u_int16_t unitless
+ *
+ * Quality of Barker code lock. Unitless. Monotonically
+ * nondecreasing with "better" lock strength. Called "Signal
+ * Quality" in datasheets. (Is there a standard way to measure
+ * this?)
+ *
+ * IEEE80211_RADIOTAP_TX_ATTENUATION u_int16_t unitless
+ *
+ * Transmit power expressed as unitless distance from max
+ * power set at factory calibration. 0 is max power.
+ * Monotonically nondecreasing with lower power levels.
+ *
+ * IEEE80211_RADIOTAP_DB_TX_ATTENUATION u_int16_t decibels (dB)
+ *
+ * Transmit power expressed as decibel distance from max power
+ * set at factory calibration. 0 is max power. Monotonically
+ * nondecreasing with lower power levels.
+ *
+ * IEEE80211_RADIOTAP_DBM_TX_POWER int8_t decibels from
+ * one milliwatt (dBm)
+ *
+ * Transmit power expressed as dBm (decibels from a 1 milliwatt
+ * reference). This is the absolute power level measured at
+ * the antenna port.
+ *
+ * IEEE80211_RADIOTAP_FLAGS u_int8_t bitmap
+ *
+ * Properties of transmitted and received frames. See flags
+ * defined below.
+ *
+ * IEEE80211_RADIOTAP_ANTENNA u_int8_t antenna index
+ *
+ * Unitless indication of the Rx/Tx antenna for this packet.
+ * The first antenna is antenna 0.
+ *
+ * IEEE80211_RADIOTAP_RX_FLAGS u_int16_t bitmap
+ *
+ * Properties of received frames. See flags defined below.
+ *
+ * IEEE80211_RADIOTAP_XCHANNEL u_int32_t bitmap
+ * u_int16_t MHz
+ * u_int8_t channel number
+ * u_int8_t .5 dBm
+ *
+ * Extended channel specification: flags (see below) followed by
+ * frequency in MHz, the corresponding IEEE channel number, and
+ * finally the maximum regulatory transmit power cap in .5 dBm
+ * units. This property supersedes IEEE80211_RADIOTAP_CHANNEL
+ * and only one of the two should be present.
+ *
+ * IEEE80211_RADIOTAP_MCS u_int8_t known
+ * u_int8_t flags
+ * u_int8_t mcs
+ *
+ * Bitset indicating which fields have known values, followed
+ * by bitset of flag values, followed by the MCS rate index as
+ * in IEEE 802.11n.
+ *
+ * IEEE80211_RADIOTAP_VENDOR_NAMESPACE
+ * u_int8_t OUI[3]
+ * u_int8_t subspace
+ * u_int16_t length
+ *
+ * The Vendor Namespace Field contains three sub-fields. The first
+ * sub-field is 3 bytes long. It contains the vendor's IEEE 802
+ * Organizationally Unique Identifier (OUI). The fourth byte is a
+ * vendor-specific "namespace selector."
+ *
+ */
+enum ieee80211_radiotap_type {
+ IEEE80211_RADIOTAP_TSFT = 0,
+ IEEE80211_RADIOTAP_FLAGS = 1,
+ IEEE80211_RADIOTAP_RATE = 2,
+ IEEE80211_RADIOTAP_CHANNEL = 3,
+ IEEE80211_RADIOTAP_FHSS = 4,
+ IEEE80211_RADIOTAP_DBM_ANTSIGNAL = 5,
+ IEEE80211_RADIOTAP_DBM_ANTNOISE = 6,
+ IEEE80211_RADIOTAP_LOCK_QUALITY = 7,
+ IEEE80211_RADIOTAP_TX_ATTENUATION = 8,
+ IEEE80211_RADIOTAP_DB_TX_ATTENUATION = 9,
+ IEEE80211_RADIOTAP_DBM_TX_POWER = 10,
+ IEEE80211_RADIOTAP_ANTENNA = 11,
+ IEEE80211_RADIOTAP_DB_ANTSIGNAL = 12,
+ IEEE80211_RADIOTAP_DB_ANTNOISE = 13,
+ IEEE80211_RADIOTAP_RX_FLAGS = 14,
+ /* NB: gap for netbsd definitions */
+ IEEE80211_RADIOTAP_XCHANNEL = 18,
+ IEEE80211_RADIOTAP_MCS = 19,
+ IEEE80211_RADIOTAP_NAMESPACE = 29,
+ IEEE80211_RADIOTAP_VENDOR_NAMESPACE = 30,
+ IEEE80211_RADIOTAP_EXT = 31
+};
+
+/* channel attributes */
+#define IEEE80211_CHAN_TURBO 0x00010 /* Turbo channel */
+#define IEEE80211_CHAN_CCK 0x00020 /* CCK channel */
+#define IEEE80211_CHAN_OFDM 0x00040 /* OFDM channel */
+#define IEEE80211_CHAN_2GHZ 0x00080 /* 2 GHz spectrum channel. */
+#define IEEE80211_CHAN_5GHZ 0x00100 /* 5 GHz spectrum channel */
+#define IEEE80211_CHAN_PASSIVE 0x00200 /* Only passive scan allowed */
+#define IEEE80211_CHAN_DYN 0x00400 /* Dynamic CCK-OFDM channel */
+#define IEEE80211_CHAN_GFSK 0x00800 /* GFSK channel (FHSS PHY) */
+#define IEEE80211_CHAN_GSM 0x01000 /* 900 MHz spectrum channel */
+#define IEEE80211_CHAN_STURBO 0x02000 /* 11a static turbo channel only */
+#define IEEE80211_CHAN_HALF 0x04000 /* Half rate channel */
+#define IEEE80211_CHAN_QUARTER 0x08000 /* Quarter rate channel */
+#define IEEE80211_CHAN_HT20 0x10000 /* HT 20 channel */
+#define IEEE80211_CHAN_HT40U 0x20000 /* HT 40 channel w/ ext above */
+#define IEEE80211_CHAN_HT40D 0x40000 /* HT 40 channel w/ ext below */
+
+/* Useful combinations of channel characteristics, borrowed from Ethereal */
+#define IEEE80211_CHAN_A \
+ (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
+#define IEEE80211_CHAN_B \
+ (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
+#define IEEE80211_CHAN_G \
+ (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
+#define IEEE80211_CHAN_TA \
+ (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM | IEEE80211_CHAN_TURBO)
+#define IEEE80211_CHAN_TG \
+ (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN | IEEE80211_CHAN_TURBO)
+
+
+/* For IEEE80211_RADIOTAP_FLAGS */
+#define IEEE80211_RADIOTAP_F_CFP 0x01 /* sent/received
+ * during CFP
+ */
+#define IEEE80211_RADIOTAP_F_SHORTPRE 0x02 /* sent/received
+ * with short
+ * preamble
+ */
+#define IEEE80211_RADIOTAP_F_WEP 0x04 /* sent/received
+ * with WEP encryption
+ */
+#define IEEE80211_RADIOTAP_F_FRAG 0x08 /* sent/received
+ * with fragmentation
+ */
+#define IEEE80211_RADIOTAP_F_FCS 0x10 /* frame includes FCS */
+#define IEEE80211_RADIOTAP_F_DATAPAD 0x20 /* frame has padding between
+ * 802.11 header and payload
+ * (to 32-bit boundary)
+ */
+#define IEEE80211_RADIOTAP_F_BADFCS 0x40 /* does not pass FCS check */
+
+/* For IEEE80211_RADIOTAP_RX_FLAGS */
+#define IEEE80211_RADIOTAP_F_RX_BADFCS 0x0001 /* frame failed crc check */
+#define IEEE80211_RADIOTAP_F_RX_PLCP_CRC 0x0002 /* frame failed PLCP CRC check */
+
+/* For IEEE80211_RADIOTAP_MCS known */
+#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN 0x01
+#define IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN 0x02 /* MCS index field */
+#define IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN 0x04
+#define IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN 0x08
+#define IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN 0x10
+
+/* For IEEE80211_RADIOTAP_MCS flags */
+#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK 0x03
+#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20 0
+#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 1
+#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20L 2
+#define IEEE80211_RADIOTAP_MCS_BANDWIDTH_20U 3
+#define IEEE80211_RADIOTAP_MCS_SHORT_GI 0x04 /* short guard interval */
+#define IEEE80211_RADIOTAP_MCS_HT_GREENFIELD 0x08
+#define IEEE80211_RADIOTAP_MCS_FEC_LDPC 0x10
+
+#endif /* _NET_IF_IEEE80211RADIOTAP_H_ */
diff --git a/freebsd/contrib/tcpdump/igrp.h b/freebsd/contrib/tcpdump/igrp.h
new file mode 100644
index 00000000..b5f133bc
--- /dev/null
+++ b/freebsd/contrib/tcpdump/igrp.h
@@ -0,0 +1,33 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/igrp.h,v 1.6 2002-12-11 07:13:52 guy Exp $ (LBL) */
+/* Cisco IGRP definitions */
+
+/* IGRP Header */
+
+struct igrphdr {
+ u_int8_t ig_vop; /* protocol version number / opcode */
+#define IGRP_V(x) (((x) & 0xf0) >> 4)
+#define IGRP_OP(x) ((x) & 0x0f)
+ u_int8_t ig_ed; /* edition number */
+ u_int16_t ig_as; /* autonomous system number */
+ u_int16_t ig_ni; /* number of subnet in local net */
+ u_int16_t ig_ns; /* number of networks in AS */
+ u_int16_t ig_nx; /* number of networks ouside AS */
+ u_int16_t ig_sum; /* checksum of IGRP header & data */
+};
+
+#define IGRP_UPDATE 1
+#define IGRP_REQUEST 2
+
+/* IGRP routing entry */
+
+struct igrprte {
+ u_int8_t igr_net[3]; /* 3 significant octets of IP address */
+ u_int8_t igr_dly[3]; /* delay in tens of microseconds */
+ u_int8_t igr_bw[3]; /* bandwidth in units of 1 kb/s */
+ u_int8_t igr_mtu[2]; /* MTU in octets */
+ u_int8_t igr_rel; /* percent packets successfully tx/rx */
+ u_int8_t igr_ld; /* percent of channel occupied */
+ u_int8_t igr_hct; /* hop count */
+};
+
+#define IGRP_RTE_SIZE 14 /* don't believe sizeof ! */
diff --git a/freebsd/contrib/tcpdump/in_cksum.c b/freebsd/contrib/tcpdump/in_cksum.c
new file mode 100644
index 00000000..bfd6be98
--- /dev/null
+++ b/freebsd/contrib/tcpdump/in_cksum.c
@@ -0,0 +1,202 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/* in_cksum.c
+ * 4.4-Lite-2 Internet checksum routine, modified to take a vector of
+ * pointers/lengths giving the pieces to be checksummed. Also using
+ * Tahoe/CGI version of ADDCARRY(x) macro instead of from portable version.
+ */
+
+/*
+ * Copyright (c) 1988, 1992, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)in_cksum.c 8.1 (Berkeley) 6/10/93
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include "interface.h"
+
+/*
+ * Checksum routine for Internet Protocol family headers (Portable Version).
+ *
+ * This routine is very heavily used in the network
+ * code and should be modified for each CPU to be as fast as possible.
+ */
+
+#define ADDCARRY(x) {if ((x) > 65535) (x) -= 65535;}
+#define REDUCE {l_util.l = sum; sum = l_util.s[0] + l_util.s[1]; ADDCARRY(sum);}
+
+u_int16_t
+in_cksum(const struct cksum_vec *vec, int veclen)
+{
+ register const u_int16_t *w;
+ register int sum = 0;
+ register int mlen = 0;
+ int byte_swapped = 0;
+
+ union {
+ u_int8_t c[2];
+ u_int16_t s;
+ } s_util;
+ union {
+ u_int16_t s[2];
+ u_int32_t l;
+ } l_util;
+
+ for (; veclen != 0; vec++, veclen--) {
+ if (vec->len == 0)
+ continue;
+ w = (const u_int16_t *)(void *)vec->ptr;
+ if (mlen == -1) {
+ /*
+ * The first byte of this chunk is the continuation
+ * of a word spanning between this chunk and the
+ * last chunk.
+ *
+ * s_util.c[0] is already saved when scanning previous
+ * chunk.
+ */
+ s_util.c[1] = *(const u_int8_t *)w;
+ sum += s_util.s;
+ w = (const u_int16_t *)(void *)((const u_int8_t *)w + 1);
+ mlen = vec->len - 1;
+ } else
+ mlen = vec->len;
+ /*
+ * Force to even boundary.
+ */
+ if ((1 & (unsigned long) w) && (mlen > 0)) {
+ REDUCE;
+ sum <<= 8;
+ s_util.c[0] = *(const u_int8_t *)w;
+ w = (const u_int16_t *)(void *)((const u_int8_t *)w + 1);
+ mlen--;
+ byte_swapped = 1;
+ }
+ /*
+ * Unroll the loop to make overhead from
+ * branches &c small.
+ */
+ while ((mlen -= 32) >= 0) {
+ sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
+ sum += w[4]; sum += w[5]; sum += w[6]; sum += w[7];
+ sum += w[8]; sum += w[9]; sum += w[10]; sum += w[11];
+ sum += w[12]; sum += w[13]; sum += w[14]; sum += w[15];
+ w += 16;
+ }
+ mlen += 32;
+ while ((mlen -= 8) >= 0) {
+ sum += w[0]; sum += w[1]; sum += w[2]; sum += w[3];
+ w += 4;
+ }
+ mlen += 8;
+ if (mlen == 0 && byte_swapped == 0)
+ continue;
+ REDUCE;
+ while ((mlen -= 2) >= 0) {
+ sum += *w++;
+ }
+ if (byte_swapped) {
+ REDUCE;
+ sum <<= 8;
+ byte_swapped = 0;
+ if (mlen == -1) {
+ s_util.c[1] = *(const u_int8_t *)w;
+ sum += s_util.s;
+ mlen = 0;
+ } else
+ mlen = -1;
+ } else if (mlen == -1)
+ s_util.c[0] = *(const u_int8_t *)w;
+ }
+ if (mlen == -1) {
+ /* The last mbuf has odd # of bytes. Follow the
+ standard (the odd byte may be shifted left by 8 bits
+ or not as determined by endian-ness of the machine) */
+ s_util.c[1] = 0;
+ sum += s_util.s;
+ }
+ REDUCE;
+ return (~sum & 0xffff);
+}
+
+/*
+ * Given the host-byte-order value of the checksum field in a packet
+ * header, and the network-byte-order computed checksum of the data
+ * that the checksum covers (including the checksum itself), compute
+ * what the checksum field *should* have been.
+ */
+u_int16_t
+in_cksum_shouldbe(u_int16_t sum, u_int16_t computed_sum)
+{
+ u_int32_t shouldbe;
+
+ /*
+ * The value that should have gone into the checksum field
+ * is the negative of the value gotten by summing up everything
+ * *but* the checksum field.
+ *
+ * We can compute that by subtracting the value of the checksum
+ * field from the sum of all the data in the packet, and then
+ * computing the negative of that value.
+ *
+ * "sum" is the value of the checksum field, and "computed_sum"
+ * is the negative of the sum of all the data in the packets,
+ * so that's -(-computed_sum - sum), or (sum + computed_sum).
+ *
+ * All the arithmetic in question is one's complement, so the
+ * addition must include an end-around carry; we do this by
+ * doing the arithmetic in 32 bits (with no sign-extension),
+ * and then adding the upper 16 bits of the sum, which contain
+ * the carry, to the lower 16 bits of the sum, and then do it
+ * again in case *that* sum produced a carry.
+ *
+ * As RFC 1071 notes, the checksum can be computed without
+ * byte-swapping the 16-bit words; summing 16-bit words
+ * on a big-endian machine gives a big-endian checksum, which
+ * can be directly stuffed into the big-endian checksum fields
+ * in protocol headers, and summing words on a little-endian
+ * machine gives a little-endian checksum, which must be
+ * byte-swapped before being stuffed into a big-endian checksum
+ * field.
+ *
+ * "computed_sum" is a network-byte-order value, so we must put
+ * it in host byte order before subtracting it from the
+ * host-byte-order value from the header; the adjusted checksum
+ * will be in host byte order, which is what we'll return.
+ */
+ shouldbe = sum;
+ shouldbe += ntohs(computed_sum);
+ shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16);
+ shouldbe = (shouldbe & 0xFFFF) + (shouldbe >> 16);
+ return shouldbe;
+}
diff --git a/freebsd/contrib/tcpdump/interface.h b/freebsd/contrib/tcpdump/interface.h
new file mode 100644
index 00000000..175c33e2
--- /dev/null
+++ b/freebsd/contrib/tcpdump/interface.h
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 1988-2002
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /tcpdump/master/tcpdump/interface.h,v 1.285 2008-08-16 11:36:20 hannes Exp $ (LBL)
+ */
+
+#ifndef tcpdump_interface_h
+#define tcpdump_interface_h
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+/* snprintf et al */
+
+#include <stdarg.h>
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+
+#if !defined(HAVE_SNPRINTF)
+int snprintf(char *, size_t, const char *, ...)
+ __attribute__((format(printf, 3, 4)));
+#endif
+
+#if !defined(HAVE_VSNPRINTF)
+int vsnprintf(char *, size_t, const char *, va_list)
+ __attribute__((format(printf, 3, 0)));
+#endif
+
+#ifndef HAVE_STRLCAT
+extern size_t strlcat(char *, const char *, size_t);
+#endif
+#ifndef HAVE_STRLCPY
+extern size_t strlcpy(char *, const char *, size_t);
+#endif
+
+#ifndef HAVE_STRDUP
+extern char *strdup(const char *);
+#endif
+
+#ifndef HAVE_STRSEP
+extern char *strsep(char **, const char *);
+#endif
+
+#define PT_VAT 1 /* Visual Audio Tool */
+#define PT_WB 2 /* distributed White Board */
+#define PT_RPC 3 /* Remote Procedure Call */
+#define PT_RTP 4 /* Real-Time Applications protocol */
+#define PT_RTCP 5 /* Real-Time Applications control protocol */
+#define PT_SNMP 6 /* Simple Network Management Protocol */
+#define PT_CNFP 7 /* Cisco NetFlow protocol */
+#define PT_TFTP 8 /* trivial file transfer protocol */
+#define PT_AODV 9 /* Ad-hoc On-demand Distance Vector Protocol */
+#define PT_CARP 10 /* Common Address Redundancy Protocol */
+#define PT_RADIUS 11 /* RADIUS authentication Protocol */
+#define PT_ZMTP1 12 /* ZeroMQ Message Transport Protocol 1.0 */
+#define PT_VXLAN 13 /* Virtual eXtensible Local Area Network */
+
+#ifndef min
+#define min(a,b) ((a)>(b)?(b):(a))
+#endif
+#ifndef max
+#define max(a,b) ((b)>(a)?(b):(a))
+#endif
+
+#define ESRC(ep) ((ep)->ether_shost)
+#define EDST(ep) ((ep)->ether_dhost)
+
+#ifndef NTOHL
+#define NTOHL(x) (x) = ntohl(x)
+#define NTOHS(x) (x) = ntohs(x)
+#define HTONL(x) (x) = htonl(x)
+#define HTONS(x) (x) = htons(x)
+#endif
+#endif
+
+#ifndef MIN
+#define MIN(a,b) ((a)<(b)?(a):(b))
+#endif
+
+extern char *program_name; /* used to generate self-identifying messages */
+
+extern int32_t thiszone; /* seconds offset from gmt to local time */
+
+/*
+ * True if "l" bytes of "var" were captured.
+ *
+ * The "snapend - (l) <= snapend" checks to make sure "l" isn't so large
+ * that "snapend - (l)" underflows.
+ *
+ * The check is for <= rather than < because "l" might be 0.
+ */
+#define TTEST2(var, l) (snapend - (l) <= snapend && \
+ (const u_char *)&(var) <= snapend - (l))
+
+/* True if "var" was captured */
+#define TTEST(var) TTEST2(var, sizeof(var))
+
+/* Bail if "l" bytes of "var" were not captured */
+#define TCHECK2(var, l) if (!TTEST2(var, l)) goto trunc
+
+/* Bail if "var" was not captured */
+#define TCHECK(var) TCHECK2(var, sizeof(var))
+
+extern void ts_print(const struct timeval *);
+extern void relts_print(int);
+
+extern int fn_print(const u_char *, const u_char *);
+extern int fn_printn(const u_char *, u_int, const u_char *);
+extern int fn_printzp(const u_char *, u_int, const u_char *);
+extern int mask2plen(u_int32_t);
+extern const char *tok2strary_internal(const char **, int, const char *, int);
+#define tok2strary(a,f,i) tok2strary_internal(a, sizeof(a)/sizeof(a[0]),f,i)
+
+extern const char *dnaddr_string(u_short);
+
+extern void error(const char *, ...)
+ __attribute__((noreturn, format (printf, 1, 2)));
+extern void warning(const char *, ...) __attribute__ ((format (printf, 1, 2)));
+
+extern char *read_infile(char *);
+extern char *copy_argv(char **);
+
+extern void safeputchar(int);
+extern void safeputs(const char *, int);
+
+extern const char *isonsap_string(const u_char *, register u_int);
+extern const char *protoid_string(const u_char *);
+extern const char *ipxsap_string(u_short);
+extern const char *dnname_string(u_short);
+extern const char *dnnum_string(u_short);
+
+/* checksum routines */
+extern void init_checksum(void);
+extern u_int16_t verify_crc10_cksum(u_int16_t, const u_char *, int);
+extern u_int16_t create_osi_cksum(const u_int8_t *, int, int);
+
+/* The printer routines. */
+
+#include <pcap.h>
+
+extern int print_unknown_data(const u_char *, const char *,int);
+extern void ascii_print(const u_char *, u_int);
+extern void hex_and_ascii_print_with_offset(const char *, const u_char *,
+ u_int, u_int);
+extern void hex_and_ascii_print(const char *, const u_char *, u_int);
+extern void hex_print_with_offset(const char *, const u_char *, u_int, u_int);
+extern void hex_print(const char *, const u_char *, u_int);
+extern void telnet_print(const u_char *, u_int);
+extern int llc_print(const u_char *, u_int, u_int, const u_char *,
+ const u_char *, u_short *);
+extern int snap_print(const u_char *, u_int, u_int, u_int);
+extern void aarp_print(const u_char *, u_int);
+extern void aodv_print(const u_char *, u_int, int);
+extern void atalk_print(const u_char *, u_int);
+extern void atm_print(u_int, u_int, u_int, const u_char *, u_int, u_int);
+extern u_int atm_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int sunatm_if_print(const struct pcap_pkthdr *, const u_char *);
+extern int oam_print(const u_char *, u_int, u_int);
+extern void bootp_print(const u_char *, u_int);
+extern void bgp_print(const u_char *, int);
+extern void beep_print(const u_char *, u_int);
+extern void cnfp_print(const u_char *, const u_char *);
+extern void decnet_print(const u_char *, u_int, u_int);
+extern void default_print(const u_char *, u_int);
+extern void dvmrp_print(const u_char *, u_int);
+extern void egp_print(const u_char *, u_int);
+extern u_int enc_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int pflog_if_print(const struct pcap_pkthdr *, const u_char *);
+extern void pfsync_ip_print(const u_char *, u_int);
+extern u_int arcnet_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int arcnet_linux_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int token_print(const u_char *, u_int, u_int);
+extern u_int token_if_print(const struct pcap_pkthdr *, const u_char *);
+extern void fddi_print(const u_char *, u_int, u_int);
+extern u_int fddi_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int fr_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int mfr_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int fr_print(register const u_char *, u_int);
+extern u_int mfr_print(register const u_char *, u_int);
+extern char *q922_string(const u_char *);
+extern u_int ieee802_11_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int ieee802_11_radio_if_print(const struct pcap_pkthdr *,
+ const u_char *);
+extern u_int ap1394_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int ieee802_11_radio_avs_if_print(const struct pcap_pkthdr *,
+ const u_char *);
+extern void gre_print(const u_char *, u_int);
+extern void icmp_print(const u_char *, u_int, const u_char *, int);
+extern void igmp_print(const u_char *, u_int);
+extern void igrp_print(const u_char *, u_int, const u_char *);
+extern void ipN_print(const u_char *, u_int);
+extern u_int ipfc_if_print(const struct pcap_pkthdr *, const u_char *);
+extern void ipx_print(const u_char *, u_int);
+extern void isoclns_print(const u_char *, u_int, u_int);
+extern void krb_print(const u_char *);
+extern u_int llap_print(const u_char *, u_int);
+extern u_int ltalk_if_print(const struct pcap_pkthdr *, const u_char *);
+extern void msdp_print(const unsigned char *, u_int);
+extern void nfsreply_print(const u_char *, u_int, const u_char *);
+extern void nfsreq_print(const u_char *, u_int, const u_char *);
+extern void ns_print(const u_char *, u_int, int);
+extern const u_char * ns_nprint (register const u_char *, register const u_char *);
+extern void ntp_print(const u_char *, u_int);
+extern u_int null_if_print(const struct pcap_pkthdr *, const u_char *);
+extern void ospf_print(const u_char *, u_int, const u_char *);
+extern void olsr_print (const u_char *, u_int, int);
+extern void pimv1_print(const u_char *, u_int);
+extern void cisco_autorp_print(const u_char *, u_int);
+extern void rsvp_print(const u_char *, u_int);
+extern void ldp_print(const u_char *, u_int);
+extern void lldp_print(const u_char *, u_int);
+extern void rpki_rtr_print(const u_char *, u_int);
+extern void lmp_print(const u_char *, u_int);
+extern void lspping_print(const u_char *, u_int);
+extern void lwapp_control_print(const u_char *, u_int, int);
+extern void lwapp_data_print(const u_char *, u_int);
+extern void eigrp_print(const u_char *, u_int);
+extern void mobile_print(const u_char *, u_int);
+extern void pim_print(const u_char *, u_int, u_int);
+extern u_int pppoe_print(const u_char *, u_int);
+extern u_int ppp_print(register const u_char *, u_int);
+extern u_int ppp_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int ppp_hdlc_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int ppp_bsdos_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int pppoe_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int prism_if_print(const struct pcap_pkthdr *, const u_char *);
+extern void q933_print(const u_char *, u_int);
+extern int vjc_print(register const char *, u_short);
+extern void vqp_print(register const u_char *, register u_int);
+extern u_int raw_if_print(const struct pcap_pkthdr *, const u_char *);
+extern void rip_print(const u_char *, u_int);
+extern u_int sl_if_print(const struct pcap_pkthdr *, const u_char *);
+extern void lane_print(const u_char *, u_int, u_int);
+extern u_int lane_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int cip_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int sl_bsdos_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int chdlc_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int chdlc_print(register const u_char *, u_int);
+extern u_int juniper_atm1_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int juniper_atm2_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int juniper_mfr_print(const struct pcap_pkthdr *, register const u_char *);
+extern u_int juniper_mlfr_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int juniper_mlppp_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int juniper_pppoe_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int juniper_pppoe_atm_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int juniper_ggsn_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int juniper_es_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int juniper_monitor_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int juniper_services_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int juniper_ether_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int juniper_ppp_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int juniper_frelay_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int juniper_chdlc_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int sll_if_print(const struct pcap_pkthdr *, const u_char *);
+extern void snmp_print(const u_char *, u_int);
+extern void sunrpcrequest_print(const u_char *, u_int, const u_char *);
+extern u_int symantec_if_print(const struct pcap_pkthdr *, const u_char *);
+extern void tcp_print(const u_char *, u_int, const u_char *, int);
+extern void tftp_print(const u_char *, u_int);
+extern void timed_print(const u_char *);
+extern void udld_print(const u_char *, u_int);
+extern void udp_print(const u_char *, u_int, const u_char *, int);
+extern void vtp_print(const u_char *, u_int);
+extern void wb_print(const void *, u_int);
+extern int ah_print(register const u_char *);
+extern int ipcomp_print(register const u_char *, int *);
+extern void rx_print(register const u_char *, int, int, int, u_char *);
+extern void netbeui_print(u_short, const u_char *, int);
+extern void ipx_netbios_print(const u_char *, u_int);
+extern void nbt_tcp_print(const u_char *, int);
+extern void nbt_udp137_print(const u_char *, int);
+extern void nbt_udp138_print(const u_char *, int);
+extern void smb_tcp_print(const u_char *, int);
+extern char *smb_errstr(int, int);
+extern const char *nt_errstr(u_int32_t);
+extern void print_data(const unsigned char *, int);
+extern void l2tp_print(const u_char *, u_int);
+extern void vrrp_print(const u_char *, u_int, int);
+extern void carp_print(const u_char *, u_int, int);
+extern void slow_print(const u_char *, u_int);
+extern void sflow_print(const u_char *, u_int);
+extern void mpcp_print(const u_char *, u_int);
+extern void cfm_print(const u_char *, u_int);
+extern void pgm_print(const u_char *, u_int, const u_char *);
+extern void cdp_print(const u_char *, u_int, u_int);
+extern void dtp_print(const u_char *, u_int);
+extern void stp_print(const u_char *, u_int);
+extern void radius_print(const u_char *, u_int);
+extern void lwres_print(const u_char *, u_int);
+extern void pptp_print(const u_char *);
+extern void dccp_print(const u_char *, const u_char *, u_int);
+extern void sctp_print(const u_char *, const u_char *, u_int);
+extern void forces_print(const u_char *, u_int);
+extern void mpls_print(const u_char *, u_int);
+extern void mpls_lsp_ping_print(const u_char *, u_int);
+extern void zephyr_print(const u_char *, int);
+extern void zmtp1_print(const u_char *, u_int);
+extern void hsrp_print(const u_char *, u_int);
+extern void bfd_print(const u_char *, u_int, u_int);
+extern void sip_print(const u_char *, u_int);
+extern void syslog_print(const u_char *, u_int);
+extern u_int bt_if_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int usb_linux_48_byte_print(const struct pcap_pkthdr *, const u_char *);
+extern u_int usb_linux_64_byte_print(const struct pcap_pkthdr *, const u_char *);
+extern void vxlan_print(const u_char *, u_int);
+extern void otv_print(const u_char *, u_int);
+
+
+#ifdef INET6
+extern void ip6_opt_print(const u_char *, int);
+extern int hbhopt_print(const u_char *);
+extern int dstopt_print(const u_char *);
+extern int frag6_print(const u_char *, const u_char *);
+extern int mobility_print(const u_char *, const u_char *);
+extern void ripng_print(const u_char *, unsigned int);
+extern int rt6_print(const u_char *, const u_char *);
+extern void ospf6_print(const u_char *, u_int);
+extern void dhcp6_print(const u_char *, u_int);
+extern void babel_print(const u_char *, u_int);
+extern int mask62plen(const u_char *);
+#endif /*INET6*/
+
+struct cksum_vec {
+ const u_int8_t *ptr;
+ int len;
+};
+extern u_int16_t in_cksum(const struct cksum_vec *, int);
+extern u_int16_t in_cksum_shouldbe(u_int16_t, u_int16_t);
+
+#ifndef HAVE_BPF_DUMP
+struct bpf_program;
+
+extern void bpf_dump(const struct bpf_program *, int);
+
+#endif
+
+#include "netdissect.h"
+
+/* forward compatibility */
+
+#ifndef NETDISSECT_REWORKED
+extern netdissect_options *gndo;
+
+#define bflag gndo->ndo_bflag
+#define eflag gndo->ndo_eflag
+#define fflag gndo->ndo_fflag
+#define jflag gndo->ndo_jflag
+#define Kflag gndo->ndo_Kflag
+#define nflag gndo->ndo_nflag
+#define Nflag gndo->ndo_Nflag
+#define Oflag gndo->ndo_Oflag
+#define pflag gndo->ndo_pflag
+#define qflag gndo->ndo_qflag
+#define Rflag gndo->ndo_Rflag
+#define sflag gndo->ndo_sflag
+#define Sflag gndo->ndo_Sflag
+#define tflag gndo->ndo_tflag
+#define Uflag gndo->ndo_Uflag
+#define uflag gndo->ndo_uflag
+#define vflag gndo->ndo_vflag
+#define xflag gndo->ndo_xflag
+#define Xflag gndo->ndo_Xflag
+#define Cflag gndo->ndo_Cflag
+#define Gflag gndo->ndo_Gflag
+#define Aflag gndo->ndo_Aflag
+#define Bflag gndo->ndo_Bflag
+#define Iflag gndo->ndo_Iflag
+#define suppress_default_print gndo->ndo_suppress_default_print
+#define packettype gndo->ndo_packettype
+#define sigsecret gndo->ndo_sigsecret
+#define Wflag gndo->ndo_Wflag
+#define WflagChars gndo->ndo_WflagChars
+#define Cflag_count gndo->ndo_Cflag_count
+#define Gflag_count gndo->ndo_Gflag_count
+#define Gflag_time gndo->ndo_Gflag_time
+#define Hflag gndo->ndo_Hflag
+#define snaplen gndo->ndo_snaplen
+#define snapend gndo->ndo_snapend
+
+#endif
diff --git a/freebsd/contrib/tcpdump/ip.h b/freebsd/contrib/tcpdump/ip.h
new file mode 100644
index 00000000..8a97632e
--- /dev/null
+++ b/freebsd/contrib/tcpdump/ip.h
@@ -0,0 +1,164 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/ip.h,v 1.12 2007-09-14 01:29:28 guy Exp $ (LBL) */
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)ip.h 8.2 (Berkeley) 6/1/94
+ */
+
+/*
+ * Definitions for internet protocol version 4.
+ * Per RFC 791, September 1981.
+ */
+#define IPVERSION 4
+
+/*
+ * Structure of an internet header, naked of options.
+ *
+ * We declare ip_len and ip_off to be short, rather than u_short
+ * pragmatically since otherwise unsigned comparisons can result
+ * against negative integers quite easily, and fail in subtle ways.
+ */
+struct ip {
+ u_int8_t ip_vhl; /* header length, version */
+#define IP_V(ip) (((ip)->ip_vhl & 0xf0) >> 4)
+#define IP_HL(ip) ((ip)->ip_vhl & 0x0f)
+ u_int8_t ip_tos; /* type of service */
+ u_int16_t ip_len; /* total length */
+ u_int16_t ip_id; /* identification */
+ u_int16_t ip_off; /* fragment offset field */
+#define IP_DF 0x4000 /* dont fragment flag */
+#define IP_MF 0x2000 /* more fragments flag */
+#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
+ u_int8_t ip_ttl; /* time to live */
+ u_int8_t ip_p; /* protocol */
+ u_int16_t ip_sum; /* checksum */
+ struct in_addr ip_src,ip_dst; /* source and dest address */
+} UNALIGNED;
+
+#define IP_MAXPACKET 65535 /* maximum packet size */
+
+/*
+ * Definitions for IP type of service (ip_tos)
+ */
+#define IPTOS_LOWDELAY 0x10
+#define IPTOS_THROUGHPUT 0x08
+#define IPTOS_RELIABILITY 0x04
+
+/*
+ * Definitions for IP precedence (also in ip_tos) (hopefully unused)
+ */
+#define IPTOS_PREC_NETCONTROL 0xe0
+#define IPTOS_PREC_INTERNETCONTROL 0xc0
+#define IPTOS_PREC_CRITIC_ECP 0xa0
+#define IPTOS_PREC_FLASHOVERRIDE 0x80
+#define IPTOS_PREC_FLASH 0x60
+#define IPTOS_PREC_IMMEDIATE 0x40
+#define IPTOS_PREC_PRIORITY 0x20
+#define IPTOS_PREC_ROUTINE 0x00
+
+/*
+ * Definitions for options.
+ */
+#define IPOPT_COPIED(o) ((o)&0x80)
+#define IPOPT_CLASS(o) ((o)&0x60)
+#define IPOPT_NUMBER(o) ((o)&0x1f)
+
+#define IPOPT_CONTROL 0x00
+#define IPOPT_RESERVED1 0x20
+#define IPOPT_DEBMEAS 0x40
+#define IPOPT_RESERVED2 0x60
+
+#define IPOPT_EOL 0 /* end of option list */
+#define IPOPT_NOP 1 /* no operation */
+
+#define IPOPT_RR 7 /* record packet route */
+#define IPOPT_TS 68 /* timestamp */
+#define IPOPT_RFC1393 82 /* traceroute RFC 1393 */
+#define IPOPT_SECURITY 130 /* provide s,c,h,tcc */
+#define IPOPT_LSRR 131 /* loose source route */
+#define IPOPT_SATID 136 /* satnet id */
+#define IPOPT_SSRR 137 /* strict source route */
+#define IPOPT_RA 148 /* router-alert, rfc2113 */
+
+/*
+ * Offsets to fields in options other than EOL and NOP.
+ */
+#define IPOPT_OPTVAL 0 /* option ID */
+#define IPOPT_OLEN 1 /* option length */
+#define IPOPT_OFFSET 2 /* offset within option */
+#define IPOPT_MINOFF 4 /* min value of above */
+
+/*
+ * Time stamp option structure.
+ */
+struct ip_timestamp {
+ u_int8_t ipt_code; /* IPOPT_TS */
+ u_int8_t ipt_len; /* size of structure (variable) */
+ u_int8_t ipt_ptr; /* index of current entry */
+ u_int8_t ipt_oflwflg; /* flags, overflow counter */
+#define IPTS_OFLW(ip) (((ipt)->ipt_oflwflg & 0xf0) >> 4)
+#define IPTS_FLG(ip) ((ipt)->ipt_oflwflg & 0x0f)
+ union ipt_timestamp {
+ u_int32_t ipt_time[1];
+ struct ipt_ta {
+ struct in_addr ipt_addr;
+ u_int32_t ipt_time;
+ } ipt_ta[1];
+ } ipt_timestamp;
+} UNALIGNED;
+
+/* flag bits for ipt_flg */
+#define IPOPT_TS_TSONLY 0 /* timestamps only */
+#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */
+#define IPOPT_TS_PRESPEC 3 /* specified modules only */
+
+/* bits for security (not byte swapped) */
+#define IPOPT_SECUR_UNCLASS 0x0000
+#define IPOPT_SECUR_CONFID 0xf135
+#define IPOPT_SECUR_EFTO 0x789a
+#define IPOPT_SECUR_MMMM 0xbc4d
+#define IPOPT_SECUR_RESTR 0xaf13
+#define IPOPT_SECUR_SECRET 0xd788
+#define IPOPT_SECUR_TOPSECRET 0x6bc5
+
+/*
+ * Internet implementation parameters.
+ */
+#define MAXTTL 255 /* maximum time to live (seconds) */
+#define IPDEFTTL 64 /* default ttl, from RFC 1340 */
+#define IPFRAGTTL 60 /* time to live for frags, slowhz */
+#define IPTTLDEC 1 /* subtracted when forwarding */
+
+#define IP_MSS 576 /* default maximum segment size */
+
+/* in print-ip.c */
+extern int nextproto4_cksum(const struct ip *, const u_int8_t *, u_int, u_int);
diff --git a/freebsd/contrib/tcpdump/ip6.h b/freebsd/contrib/tcpdump/ip6.h
new file mode 100644
index 00000000..12c87ad2
--- /dev/null
+++ b/freebsd/contrib/tcpdump/ip6.h
@@ -0,0 +1,192 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/ip6.h,v 1.8 2007-08-29 02:31:44 mcr Exp $ (LBL) */
+/* NetBSD: ip6.h,v 1.9 2000/07/13 05:34:21 itojun Exp */
+/* $KAME: ip6.h,v 1.9 2000/07/02 21:01:32 itojun Exp $ */
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)ip.h 8.1 (Berkeley) 6/10/93
+ */
+
+#ifndef _NETINET_IP6_H_
+#define _NETINET_IP6_H_
+
+/*
+ * Definition for internet protocol version 6.
+ * RFC 2460
+ */
+
+struct ip6_hdr {
+ union {
+ struct ip6_hdrctl {
+ u_int32_t ip6_un1_flow; /* 20 bits of flow-ID */
+ u_int16_t ip6_un1_plen; /* payload length */
+ u_int8_t ip6_un1_nxt; /* next header */
+ u_int8_t ip6_un1_hlim; /* hop limit */
+ } ip6_un1;
+ u_int8_t ip6_un2_vfc; /* 4 bits version, top 4 bits class */
+ } ip6_ctlun;
+ struct in6_addr ip6_src; /* source address */
+ struct in6_addr ip6_dst; /* destination address */
+} UNALIGNED;
+
+#define ip6_vfc ip6_ctlun.ip6_un2_vfc
+#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
+#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
+#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
+#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
+#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim
+
+/* in network endian */
+#define IPV6_FLOWINFO_MASK ((u_int32_t)htonl(0x0fffffff)) /* flow info (28 bits) */
+#define IPV6_FLOWLABEL_MASK ((u_int32_t)htonl(0x000fffff)) /* flow label (20 bits) */
+#if 1
+/* ECN bits proposed by Sally Floyd */
+#define IP6TOS_CE 0x01 /* congestion experienced */
+#define IP6TOS_ECT 0x02 /* ECN-capable transport */
+#endif
+
+/*
+ * Extension Headers
+ */
+
+struct ip6_ext {
+ u_int8_t ip6e_nxt;
+ u_int8_t ip6e_len;
+} UNALIGNED;
+
+/* Hop-by-Hop options header */
+struct ip6_hbh {
+ u_int8_t ip6h_nxt; /* next header */
+ u_int8_t ip6h_len; /* length in units of 8 octets */
+ /* followed by options */
+} UNALIGNED;
+
+/* Destination options header */
+struct ip6_dest {
+ u_int8_t ip6d_nxt; /* next header */
+ u_int8_t ip6d_len; /* length in units of 8 octets */
+ /* followed by options */
+} UNALIGNED;
+
+/* Option types and related macros */
+#define IP6OPT_PAD1 0x00 /* 00 0 00000 */
+#define IP6OPT_PADN 0x01 /* 00 0 00001 */
+#define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */
+#define IP6OPT_JUMBO_LEN 6
+#define IP6OPT_ROUTER_ALERT 0x05 /* 00 0 00101 */
+
+#define IP6OPT_RTALERT_LEN 4
+#define IP6OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */
+#define IP6OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */
+#define IP6OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */
+#define IP6OPT_MINLEN 2
+
+#define IP6OPT_BINDING_UPDATE 0xc6 /* 11 0 00110 */
+#define IP6OPT_BINDING_ACK 0x07 /* 00 0 00111 */
+#define IP6OPT_BINDING_REQ 0x08 /* 00 0 01000 */
+#define IP6OPT_HOME_ADDRESS 0xc9 /* 11 0 01001 */
+#define IP6OPT_EID 0x8a /* 10 0 01010 */
+
+#define IP6OPT_TYPE(o) ((o) & 0xC0)
+#define IP6OPT_TYPE_SKIP 0x00
+#define IP6OPT_TYPE_DISCARD 0x40
+#define IP6OPT_TYPE_FORCEICMP 0x80
+#define IP6OPT_TYPE_ICMP 0xC0
+
+#define IP6OPT_MUTABLE 0x20
+
+/* Routing header */
+struct ip6_rthdr {
+ u_int8_t ip6r_nxt; /* next header */
+ u_int8_t ip6r_len; /* length in units of 8 octets */
+ u_int8_t ip6r_type; /* routing type */
+ u_int8_t ip6r_segleft; /* segments left */
+ /* followed by routing type specific data */
+} UNALIGNED;
+
+/* Type 0 Routing header */
+struct ip6_rthdr0 {
+ u_int8_t ip6r0_nxt; /* next header */
+ u_int8_t ip6r0_len; /* length in units of 8 octets */
+ u_int8_t ip6r0_type; /* always zero */
+ u_int8_t ip6r0_segleft; /* segments left */
+ u_int8_t ip6r0_reserved; /* reserved field */
+ u_int8_t ip6r0_slmap[3]; /* strict/loose bit map */
+ struct in6_addr ip6r0_addr[1]; /* up to 23 addresses */
+} UNALIGNED;
+
+/* Fragment header */
+struct ip6_frag {
+ u_int8_t ip6f_nxt; /* next header */
+ u_int8_t ip6f_reserved; /* reserved field */
+ u_int16_t ip6f_offlg; /* offset, reserved, and flag */
+ u_int32_t ip6f_ident; /* identification */
+} UNALIGNED;
+
+#define IP6F_OFF_MASK 0xfff8 /* mask out offset from ip6f_offlg */
+#define IP6F_RESERVED_MASK 0x0006 /* reserved bits in ip6f_offlg */
+#define IP6F_MORE_FRAG 0x0001 /* more-fragments flag */
+
+/* in print-ip6.c */
+extern int nextproto6_cksum(const struct ip6_hdr *, const u_int8_t *, u_int, u_int);
+
+#endif /* not _NETINET_IP6_H_ */
diff --git a/freebsd/contrib/tcpdump/ipfc.h b/freebsd/contrib/tcpdump/ipfc.h
new file mode 100644
index 00000000..438d1156
--- /dev/null
+++ b/freebsd/contrib/tcpdump/ipfc.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 1992, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /tcpdump/master/tcpdump/ipfc.h,v 1.4 2002-12-11 07:13:53 guy Exp $ (LBL)
+ */
+
+struct ipfc_header {
+ u_char ipfc_dhost[8];
+ u_char ipfc_shost[8];
+};
+
+#define IPFC_HDRLEN 16
diff --git a/freebsd/contrib/tcpdump/ipnet.h b/freebsd/contrib/tcpdump/ipnet.h
new file mode 100644
index 00000000..ae692842
--- /dev/null
+++ b/freebsd/contrib/tcpdump/ipnet.h
@@ -0,0 +1,13 @@
+typedef struct ipnet_hdr {
+ uint8_t iph_version;
+ uint8_t iph_family;
+ uint16_t iph_htype;
+ uint32_t iph_pktlen;
+ uint32_t iph_ifindex;
+ uint32_t iph_grifindex;
+ uint32_t iph_zsrc;
+ uint32_t iph_zdst;
+} ipnet_hdr_t;
+
+#define IPH_AF_INET 2 /* Matches Solaris's AF_INET */
+#define IPH_AF_INET6 26 /* Matches Solaris's AF_INET6 */
diff --git a/freebsd/contrib/tcpdump/ipproto.c b/freebsd/contrib/tcpdump/ipproto.c
new file mode 100644
index 00000000..a0ddf867
--- /dev/null
+++ b/freebsd/contrib/tcpdump/ipproto.c
@@ -0,0 +1,64 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/ipproto.c,v 1.6 2005-09-20 06:01:22 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include "interface.h"
+#include "ipproto.h"
+
+const struct tok ipproto_values[] = {
+ { IPPROTO_HOPOPTS, "Options" },
+ { IPPROTO_ICMP, "ICMP" },
+ { IPPROTO_IGMP, "IGMP" },
+ { IPPROTO_IPV4, "IPIP" },
+ { IPPROTO_TCP, "TCP" },
+ { IPPROTO_EGP, "EGP" },
+ { IPPROTO_PIGP, "IGRP" },
+ { IPPROTO_UDP, "UDP" },
+ { IPPROTO_DCCP, "DCCP" },
+ { IPPROTO_IPV6, "IPv6" },
+ { IPPROTO_ROUTING, "Routing" },
+ { IPPROTO_FRAGMENT, "Fragment" },
+ { IPPROTO_RSVP, "RSVP" },
+ { IPPROTO_GRE, "GRE" },
+ { IPPROTO_ESP, "ESP" },
+ { IPPROTO_AH, "AH" },
+ { IPPROTO_MOBILE, "Mobile IP" },
+ { IPPROTO_ICMPV6, "ICMPv6" },
+ { IPPROTO_MOBILITY_OLD, "Mobile IP (old)" },
+ { IPPROTO_EIGRP, "EIGRP" },
+ { IPPROTO_OSPF, "OSPF" },
+ { IPPROTO_PIM, "PIM" },
+ { IPPROTO_IPCOMP, "Compressed IP" },
+ { IPPROTO_VRRP, "VRRP" },
+ { IPPROTO_PGM, "PGM" },
+ { IPPROTO_SCTP, "SCTP" },
+ { IPPROTO_MOBILITY, "Mobility" },
+ { IPPROTO_CARP, "CARP" },
+ { IPPROTO_PFSYNC, "pfsync" },
+ { 0, NULL }
+};
+
diff --git a/freebsd/contrib/tcpdump/ipproto.h b/freebsd/contrib/tcpdump/ipproto.h
new file mode 100644
index 00000000..4b6bf51c
--- /dev/null
+++ b/freebsd/contrib/tcpdump/ipproto.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 1982, 1986, 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) $Header: /tcpdump/master/tcpdump/ipproto.h,v 1.6 2005-09-20 06:01:22 guy Exp $ (LBL)
+ *
+ * From:
+ * @(#)in.h 8.3 (Berkeley) 1/3/94
+ * $FreeBSD$
+ * FreeBSD: src/sys/netinet/in.h,v 1.38.2.3 1999/08/29 16:29:34 peter Exp
+ */
+
+extern const struct tok ipproto_values[];
+
+#ifndef IPPROTO_IP
+#define IPPROTO_IP 0 /* dummy for IP */
+#endif
+#ifndef IPPROTO_HOPOPTS
+#define IPPROTO_HOPOPTS 0 /* IPv6 hop-by-hop options */
+#endif
+#ifndef IPPROTO_ICMP
+#define IPPROTO_ICMP 1 /* control message protocol */
+#endif
+#ifndef IPPROTO_IGMP
+#define IPPROTO_IGMP 2 /* group mgmt protocol */
+#endif
+#ifndef IPPROTO_IPV4
+#define IPPROTO_IPV4 4
+#endif
+#ifndef IPPROTO_TCP
+#define IPPROTO_TCP 6 /* tcp */
+#endif
+#ifndef IPPROTO_EGP
+#define IPPROTO_EGP 8 /* exterior gateway protocol */
+#endif
+#ifndef IPPROTO_PIGP
+#define IPPROTO_PIGP 9
+#endif
+#ifndef IPPROTO_UDP
+#define IPPROTO_UDP 17 /* user datagram protocol */
+#endif
+#ifndef IPPROTO_DCCP
+#define IPPROTO_DCCP 33 /* datagram congestion control protocol */
+#endif
+#ifndef IPPROTO_IPV6
+#define IPPROTO_IPV6 41
+#endif
+#ifndef IPPROTO_ROUTING
+#define IPPROTO_ROUTING 43 /* IPv6 routing header */
+#endif
+#ifndef IPPROTO_FRAGMENT
+#define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */
+#endif
+#ifndef IPPROTO_RSVP
+#define IPPROTO_RSVP 46 /* resource reservation */
+#endif
+#ifndef IPPROTO_GRE
+#define IPPROTO_GRE 47 /* General Routing Encap. */
+#endif
+#ifndef IPPROTO_ESP
+#define IPPROTO_ESP 50 /* SIPP Encap Sec. Payload */
+#endif
+#ifndef IPPROTO_AH
+#define IPPROTO_AH 51 /* SIPP Auth Header */
+#endif
+#ifndef IPPROTO_MOBILE
+#define IPPROTO_MOBILE 55
+#endif
+#ifndef IPPROTO_ICMPV6
+#define IPPROTO_ICMPV6 58 /* ICMPv6 */
+#endif
+#ifndef IPPROTO_NONE
+#define IPPROTO_NONE 59 /* IPv6 no next header */
+#endif
+#ifndef IPPROTO_DSTOPTS
+#define IPPROTO_DSTOPTS 60 /* IPv6 destination options */
+#endif
+#ifndef IPPROTO_MOBILITY_OLD
+/*
+ * The current Protocol Numbers list says that the IP protocol number for
+ * mobility headers is 135; it cites draft-ietf-mobileip-ipv6-24, but
+ * that draft doesn't actually give a number.
+ *
+ * It appears that 62 used to be used, even though that's assigned to
+ * a protocol called CFTP; however, the only reference for CFTP is a
+ * Network Message from BBN back in 1982, so, for now, we support 62,
+ * aas well as 135, as a protocol number for mobility headers.
+ */
+#define IPPROTO_MOBILITY_OLD 62
+#endif
+#ifndef IPPROTO_ND
+#define IPPROTO_ND 77 /* Sun net disk proto (temp.) */
+#endif
+#ifndef IPPROTO_EIGRP
+#define IPPROTO_EIGRP 88 /* Cisco/GXS IGRP */
+#endif
+#ifndef IPPROTO_OSPF
+#define IPPROTO_OSPF 89
+#endif
+#ifndef IPPROTO_PIM
+#define IPPROTO_PIM 103
+#endif
+#ifndef IPPROTO_IPCOMP
+#define IPPROTO_IPCOMP 108
+#endif
+#ifndef IPPROTO_VRRP
+#define IPPROTO_VRRP 112
+#endif
+#ifndef IPPROTO_CARP
+#define IPPROTO_CARP 112
+#endif
+#ifndef IPPROTO_PGM
+#define IPPROTO_PGM 113
+#endif
+#ifndef IPPROTO_SCTP
+#define IPPROTO_SCTP 132
+#endif
+#ifndef IPPROTO_MOBILITY
+#define IPPROTO_MOBILITY 135
+#endif
diff --git a/freebsd/contrib/tcpdump/ipsec_doi.h b/freebsd/contrib/tcpdump/ipsec_doi.h
new file mode 100644
index 00000000..554a2586
--- /dev/null
+++ b/freebsd/contrib/tcpdump/ipsec_doi.h
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/* YIPS @(#)$Id: ipsec_doi.h,v 1.7 2002-12-11 07:13:53 guy Exp $ */
+
+/* refer to RFC 2407 */
+
+#if !defined(_IPSEC_DOI_H_)
+#define _IPSEC_DOI_H_
+
+#define IPSEC_DOI 1
+
+/* 4.2 IPSEC Situation Definition */
+#define IPSECDOI_SIT_IDENTITY_ONLY 0x00000001
+#define IPSECDOI_SIT_SECRECY 0x00000002
+#define IPSECDOI_SIT_INTEGRITY 0x00000004
+
+/* 4.4.1 IPSEC Security Protocol Identifiers */
+ /* 4.4.2 IPSEC ISAKMP Transform Values */
+#define IPSECDOI_PROTO_ISAKMP 1
+#define IPSECDOI_KEY_IKE 1
+
+/* 4.4.1 IPSEC Security Protocol Identifiers */
+#define IPSECDOI_PROTO_IPSEC_AH 2
+ /* 4.4.3 IPSEC AH Transform Values */
+#define IPSECDOI_AH_MD5 2
+#define IPSECDOI_AH_SHA 3
+#define IPSECDOI_AH_DES 4
+#define IPSECDOI_AH_SHA2_256 5
+#define IPSECDOI_AH_SHA2_384 6
+#define IPSECDOI_AH_SHA2_512 7
+
+/* 4.4.1 IPSEC Security Protocol Identifiers */
+#define IPSECDOI_PROTO_IPSEC_ESP 3
+ /* 4.4.4 IPSEC ESP Transform Identifiers */
+#define IPSECDOI_ESP_DES_IV64 1
+#define IPSECDOI_ESP_DES 2
+#define IPSECDOI_ESP_3DES 3
+#define IPSECDOI_ESP_RC5 4
+#define IPSECDOI_ESP_IDEA 5
+#define IPSECDOI_ESP_CAST 6
+#define IPSECDOI_ESP_BLOWFISH 7
+#define IPSECDOI_ESP_3IDEA 8
+#define IPSECDOI_ESP_DES_IV32 9
+#define IPSECDOI_ESP_RC4 10
+#define IPSECDOI_ESP_NULL 11
+#define IPSECDOI_ESP_RIJNDAEL 12
+#define IPSECDOI_ESP_AES 12
+
+/* 4.4.1 IPSEC Security Protocol Identifiers */
+#define IPSECDOI_PROTO_IPCOMP 4
+ /* 4.4.5 IPSEC IPCOMP Transform Identifiers */
+#define IPSECDOI_IPCOMP_OUI 1
+#define IPSECDOI_IPCOMP_DEFLATE 2
+#define IPSECDOI_IPCOMP_LZS 3
+
+/* 4.5 IPSEC Security Association Attributes */
+#define IPSECDOI_ATTR_SA_LTYPE 1 /* B */
+#define IPSECDOI_ATTR_SA_LTYPE_DEFAULT 1
+#define IPSECDOI_ATTR_SA_LTYPE_SEC 1
+#define IPSECDOI_ATTR_SA_LTYPE_KB 2
+#define IPSECDOI_ATTR_SA_LDUR 2 /* V */
+#define IPSECDOI_ATTR_SA_LDUR_DEFAULT 28800 /* 8 hours */
+#define IPSECDOI_ATTR_GRP_DESC 3 /* B */
+#define IPSECDOI_ATTR_ENC_MODE 4 /* B */
+ /* default value: host dependent */
+#define IPSECDOI_ATTR_ENC_MODE_TUNNEL 1
+#define IPSECDOI_ATTR_ENC_MODE_TRNS 2
+#define IPSECDOI_ATTR_AUTH 5 /* B */
+ /* 0 means not to use authentication. */
+#define IPSECDOI_ATTR_AUTH_HMAC_MD5 1
+#define IPSECDOI_ATTR_AUTH_HMAC_SHA1 2
+#define IPSECDOI_ATTR_AUTH_DES_MAC 3
+#define IPSECDOI_ATTR_AUTH_KPDK 4 /*RFC-1826(Key/Pad/Data/Key)*/
+ /*
+ * When negotiating ESP without authentication, the Auth
+ * Algorithm attribute MUST NOT be included in the proposal.
+ * When negotiating ESP without confidentiality, the Auth
+ * Algorithm attribute MUST be included in the proposal and
+ * the ESP transform ID must be ESP_NULL.
+ */
+#define IPSECDOI_ATTR_KEY_LENGTH 6 /* B */
+#define IPSECDOI_ATTR_KEY_ROUNDS 7 /* B */
+#define IPSECDOI_ATTR_COMP_DICT_SIZE 8 /* B */
+#define IPSECDOI_ATTR_COMP_PRIVALG 9 /* V */
+
+/* 4.6.1 Security Association Payload */
+struct ipsecdoi_sa {
+ struct isakmp_gen h;
+ u_int32_t doi; /* Domain of Interpretation */
+ u_int32_t sit; /* Situation */
+};
+
+struct ipsecdoi_secrecy_h {
+ u_int16_t len;
+ u_int16_t reserved;
+};
+
+/* 4.6.2.1 Identification Type Values */
+struct ipsecdoi_id {
+ struct isakmp_gen h;
+ u_int8_t type; /* ID Type */
+ u_int8_t proto_id; /* Protocol ID */
+ u_int16_t port; /* Port */
+ /* Identification Data */
+};
+
+#define IPSECDOI_ID_IPV4_ADDR 1
+#define IPSECDOI_ID_FQDN 2
+#define IPSECDOI_ID_USER_FQDN 3
+#define IPSECDOI_ID_IPV4_ADDR_SUBNET 4
+#define IPSECDOI_ID_IPV6_ADDR 5
+#define IPSECDOI_ID_IPV6_ADDR_SUBNET 6
+#define IPSECDOI_ID_IPV4_ADDR_RANGE 7
+#define IPSECDOI_ID_IPV6_ADDR_RANGE 8
+#define IPSECDOI_ID_DER_ASN1_DN 9
+#define IPSECDOI_ID_DER_ASN1_GN 10
+#define IPSECDOI_ID_KEY_ID 11
+
+/* 4.6.3 IPSEC DOI Notify Message Types */
+/* Notify Messages - Status Types */
+#define IPSECDOI_NTYPE_RESPONDER_LIFETIME 24576
+#define IPSECDOI_NTYPE_REPLAY_STATUS 24577
+#define IPSECDOI_NTYPE_INITIAL_CONTACT 24578
+
+#endif /* !defined(_IPSEC_DOI_H_) */
diff --git a/freebsd/contrib/tcpdump/ipx.h b/freebsd/contrib/tcpdump/ipx.h
new file mode 100644
index 00000000..bfc30198
--- /dev/null
+++ b/freebsd/contrib/tcpdump/ipx.h
@@ -0,0 +1,31 @@
+/*
+ * IPX protocol formats
+ *
+ * @(#) $Header: /tcpdump/master/tcpdump/ipx.h,v 1.8 2002-12-11 07:13:54 guy Exp $
+ */
+
+/* well-known sockets */
+#define IPX_SKT_NCP 0x0451
+#define IPX_SKT_SAP 0x0452
+#define IPX_SKT_RIP 0x0453
+#define IPX_SKT_NETBIOS 0x0455
+#define IPX_SKT_DIAGNOSTICS 0x0456
+#define IPX_SKT_NWLINK_DGM 0x0553 /* NWLink datagram, may contain SMB */
+#define IPX_SKT_EIGRP 0x85be /* Cisco EIGRP over IPX */
+
+/* IPX transport header */
+struct ipxHdr {
+ u_int16_t cksum; /* Checksum */
+ u_int16_t length; /* Length, in bytes, including header */
+ u_int8_t tCtl; /* Transport Control (i.e. hop count) */
+ u_int8_t pType; /* Packet Type (i.e. level 2 protocol) */
+ u_int16_t dstNet[2]; /* destination net */
+ u_int8_t dstNode[6]; /* destination node */
+ u_int16_t dstSkt; /* destination socket */
+ u_int16_t srcNet[2]; /* source net */
+ u_int8_t srcNode[6]; /* source node */
+ u_int16_t srcSkt; /* source socket */
+};
+
+#define ipxSize 30
+
diff --git a/freebsd/contrib/tcpdump/isakmp.h b/freebsd/contrib/tcpdump/isakmp.h
new file mode 100644
index 00000000..d628f7ae
--- /dev/null
+++ b/freebsd/contrib/tcpdump/isakmp.h
@@ -0,0 +1,501 @@
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/* YIPS @(#)$Id: isakmp.h,v 1.12 2007-11-24 18:13:33 mcr Exp $ */
+
+/* refer to RFC 2408 */
+
+/* must include <netinet/in.h> */
+
+#if !defined(_ISAKMP_H_)
+#define _ISAKMP_H_
+
+typedef u_char cookie_t[8];
+typedef u_char msgid_t[4];
+
+typedef struct { /* i_cookie + r_cookie */
+ cookie_t i_ck;
+ cookie_t r_ck;
+} isakmp_index;
+
+#define INITIATOR 1
+#define RESPONDER 2
+
+#define PORT_ISAKMP 500
+
+#define GENERATE 1
+#define VALIDATE 0
+
+/* Phase of oakley definition */
+/*
+ 0000 0000 0000 0000
+ | |||| ||||
+ | |||| ++++--> negosiation number in phase
+ | ++++-------> phase number
+ +---------------> expire ?
+ */
+#define ISAKMP_PH1 0x0010
+#define ISAKMP_PH2 0x0020
+#define ISAKMP_EXPIRED 0x0100
+
+#define ISAKMP_NGP_0 0x0000
+#define ISAKMP_NGP_1 0x0001
+#define ISAKMP_NGP_2 0x0002
+#define ISAKMP_NGP_3 0x0003
+#define ISAKMP_NGP_4 0x0004
+
+#define ISAKMP_PH1_N (ISAKMP_PH1 | ISAKMP_NGP_0) /* i.e. spawn */
+#define ISAKMP_PH1_1 (ISAKMP_PH1 | ISAKMP_NGP_1)
+#define ISAKMP_PH1_2 (ISAKMP_PH1 | ISAKMP_NGP_2)
+#define ISAKMP_PH1_3 (ISAKMP_PH1 | ISAKMP_NGP_3)
+#define ISAKMP_PH2_N (ISAKMP_PH2 | ISAKMP_NGP_0)
+#define ISAKMP_PH2_1 (ISAKMP_PH2 | ISAKMP_NGP_1)
+#define ISAKMP_PH2_2 (ISAKMP_PH2 | ISAKMP_NGP_2)
+#define ISAKMP_PH2_3 (ISAKMP_PH2 | ISAKMP_NGP_3)
+
+#define ISAKMP_TIMER_DEFAULT 10 /* seconds */
+#define ISAKMP_TRY_DEFAULT 3 /* times */
+
+/* 3.1 ISAKMP Header Format (IKEv1 and IKEv2)
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! Initiator !
+ ! Cookie !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! Responder !
+ ! Cookie !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! Next Payload ! MjVer ! MnVer ! Exchange Type ! Flags !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! Message ID !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! Length !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+struct isakmp {
+ cookie_t i_ck; /* Initiator Cookie */
+ cookie_t r_ck; /* Responder Cookie */
+ u_int8_t np; /* Next Payload Type */
+ u_int8_t vers;
+#define ISAKMP_VERS_MAJOR 0xf0
+#define ISAKMP_VERS_MAJOR_SHIFT 4
+#define ISAKMP_VERS_MINOR 0x0f
+#define ISAKMP_VERS_MINOR_SHIFT 0
+ u_int8_t etype; /* Exchange Type */
+ u_int8_t flags; /* Flags */
+ msgid_t msgid;
+ u_int32_t len; /* Length */
+};
+
+/* Next Payload Type */
+#define ISAKMP_NPTYPE_NONE 0 /* NONE*/
+#define ISAKMP_NPTYPE_SA 1 /* Security Association */
+#define ISAKMP_NPTYPE_P 2 /* Proposal */
+#define ISAKMP_NPTYPE_T 3 /* Transform */
+#define ISAKMP_NPTYPE_KE 4 /* Key Exchange */
+#define ISAKMP_NPTYPE_ID 5 /* Identification */
+#define ISAKMP_NPTYPE_CERT 6 /* Certificate */
+#define ISAKMP_NPTYPE_CR 7 /* Certificate Request */
+#define ISAKMP_NPTYPE_HASH 8 /* Hash */
+#define ISAKMP_NPTYPE_SIG 9 /* Signature */
+#define ISAKMP_NPTYPE_NONCE 10 /* Nonce */
+#define ISAKMP_NPTYPE_N 11 /* Notification */
+#define ISAKMP_NPTYPE_D 12 /* Delete */
+#define ISAKMP_NPTYPE_VID 13 /* Vendor ID */
+#define ISAKMP_NPTYPE_v2E 46 /* v2 Encrypted payload */
+
+#define IKEv1_MAJOR_VERSION 1
+#define IKEv1_MINOR_VERSION 0
+
+#define IKEv2_MAJOR_VERSION 2
+#define IKEv2_MINOR_VERSION 0
+
+/* Exchange Type */
+#define ISAKMP_ETYPE_NONE 0 /* NONE */
+#define ISAKMP_ETYPE_BASE 1 /* Base */
+#define ISAKMP_ETYPE_IDENT 2 /* Identity Proteciton */
+#define ISAKMP_ETYPE_AUTH 3 /* Authentication Only */
+#define ISAKMP_ETYPE_AGG 4 /* Aggressive */
+#define ISAKMP_ETYPE_INF 5 /* Informational */
+
+/* Flags */
+#define ISAKMP_FLAG_E 0x01 /* Encryption Bit */
+#define ISAKMP_FLAG_C 0x02 /* Commit Bit */
+#define ISAKMP_FLAG_extra 0x04
+
+/* IKEv2 */
+#define ISAKMP_FLAG_I (1 << 3) /* (I)nitiator */
+#define ISAKMP_FLAG_V (1 << 4) /* (V)ersion */
+#define ISAKMP_FLAG_R (1 << 5) /* (R)esponse */
+
+
+/* 3.2 Payload Generic Header
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ ! Next Payload ! RESERVED ! Payload Length !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+struct isakmp_gen {
+ u_int8_t np; /* Next Payload */
+ u_int8_t critical; /* bit 7 - critical, rest is RESERVED */
+ u_int16_t len; /* Payload Length */
+};
+
+/* 3.3 Data Attributes
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ !A! Attribute Type ! AF=0 Attribute Length !
+ !F! ! AF=1 Attribute Value !
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ . AF=0 Attribute Value .
+ . AF=1 Not Transmitted .
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+struct isakmp_data {
+ u_int16_t type; /* defined by DOI-spec, and Attribute Format */
+ u_int16_t lorv; /* if f equal 1, Attribute Length */
+ /* if f equal 0, Attribute Value */
+ /* if f equal 1, Attribute Value */
+};
+#define ISAKMP_GEN_TLV 0x0000
+#define ISAKMP_GEN_TV 0x8000
+ /* mask for type of attribute format */
+#define ISAKMP_GEN_MASK 0x8000
+
+/* 3.4 Security Association Payload */
+ /* MAY NOT be used, because of being defined in ipsec-doi. */
+ /*
+ If the current payload is the last in the message,
+ then the value of the next payload field will be 0.
+ This field MUST NOT contain the
+ values for the Proposal or Transform payloads as they are considered
+ part of the security association negotiation. For example, this
+ field would contain the value "10" (Nonce payload) in the first
+ message of a Base Exchange (see Section 4.4) and the value "0" in the
+ first message of an Identity Protect Exchange (see Section 4.5).
+ */
+struct ikev1_pl_sa {
+ struct isakmp_gen h;
+ u_int32_t doi; /* Domain of Interpretation */
+ u_int32_t sit; /* Situation */
+};
+
+/* 3.5 Proposal Payload */
+ /*
+ The value of the next payload field MUST only contain the value "2"
+ or "0". If there are additional Proposal payloads in the message,
+ then this field will be 2. If the current Proposal payload is the
+ last within the security association proposal, then this field will
+ be 0.
+ */
+struct ikev1_pl_p {
+ struct isakmp_gen h;
+ u_int8_t p_no; /* Proposal # */
+ u_int8_t prot_id; /* Protocol */
+ u_int8_t spi_size; /* SPI Size */
+ u_int8_t num_t; /* Number of Transforms */
+ /* SPI */
+};
+
+/* 3.6 Transform Payload */
+ /*
+ The value of the next payload field MUST only contain the value "3"
+ or "0". If there are additional Transform payloads in the proposal,
+ then this field will be 3. If the current Transform payload is the
+ last within the proposal, then this field will be 0.
+ */
+struct ikev1_pl_t {
+ struct isakmp_gen h;
+ u_int8_t t_no; /* Transform # */
+ u_int8_t t_id; /* Transform-Id */
+ u_int16_t reserved; /* RESERVED2 */
+ /* SA Attributes */
+};
+
+/* 3.7 Key Exchange Payload */
+struct ikev1_pl_ke {
+ struct isakmp_gen h;
+ /* Key Exchange Data */
+};
+
+/* 3.8 Identification Payload */
+ /* MUST NOT to be used, because of being defined in ipsec-doi. */
+struct ikev1_pl_id {
+ struct isakmp_gen h;
+ union {
+ u_int8_t id_type; /* ID Type */
+ u_int32_t doi_data; /* DOI Specific ID Data */
+ } d;
+ /* Identification Data */
+};
+
+/* 3.9 Certificate Payload */
+struct ikev1_pl_cert {
+ struct isakmp_gen h;
+ u_int8_t encode; /* Cert Encoding */
+ char cert; /* Certificate Data */
+ /*
+ This field indicates the type of
+ certificate or certificate-related information contained in the
+ Certificate Data field.
+ */
+};
+
+/* Certificate Type */
+#define ISAKMP_CERT_NONE 0
+#define ISAKMP_CERT_PKCS 1
+#define ISAKMP_CERT_PGP 2
+#define ISAKMP_CERT_DNS 3
+#define ISAKMP_CERT_SIGN 4
+#define ISAKMP_CERT_KE 5
+#define ISAKMP_CERT_KT 6
+#define ISAKMP_CERT_CRL 7
+#define ISAKMP_CERT_ARL 8
+#define ISAKMP_CERT_SPKI 9
+
+/* 3.10 Certificate Request Payload */
+struct ikev1_pl_cr {
+ struct isakmp_gen h;
+ u_int8_t num_cert; /* # Cert. Types */
+ /*
+ Certificate Types (variable length)
+ -- Contains a list of the types of certificates requested,
+ sorted in order of preference. Each individual certificate
+ type is 1 octet. This field is NOT requiredo
+ */
+ /* # Certificate Authorities (1 octet) */
+ /* Certificate Authorities (variable length) */
+};
+
+/* 3.11 Hash Payload */
+ /* may not be used, because of having only data. */
+struct ikev1_pl_hash {
+ struct isakmp_gen h;
+ /* Hash Data */
+};
+
+/* 3.12 Signature Payload */
+ /* may not be used, because of having only data. */
+struct ikev1_pl_sig {
+ struct isakmp_gen h;
+ /* Signature Data */
+};
+
+/* 3.13 Nonce Payload */
+ /* may not be used, because of having only data. */
+struct ikev1_pl_nonce {
+ struct isakmp_gen h;
+ /* Nonce Data */
+};
+
+/* 3.14 Notification Payload */
+struct ikev1_pl_n {
+ struct isakmp_gen h;
+ u_int32_t doi; /* Domain of Interpretation */
+ u_int8_t prot_id; /* Protocol-ID */
+ u_int8_t spi_size; /* SPI Size */
+ u_int16_t type; /* Notify Message Type */
+ /* SPI */
+ /* Notification Data */
+};
+
+/* 3.14.1 Notify Message Types */
+/* NOTIFY MESSAGES - ERROR TYPES */
+#define ISAKMP_NTYPE_INVALID_PAYLOAD_TYPE 1
+#define ISAKMP_NTYPE_DOI_NOT_SUPPORTED 2
+#define ISAKMP_NTYPE_SITUATION_NOT_SUPPORTED 3
+#define ISAKMP_NTYPE_INVALID_COOKIE 4
+#define ISAKMP_NTYPE_INVALID_MAJOR_VERSION 5
+#define ISAKMP_NTYPE_INVALID_MINOR_VERSION 6
+#define ISAKMP_NTYPE_INVALID_EXCHANGE_TYPE 7
+#define ISAKMP_NTYPE_INVALID_FLAGS 8
+#define ISAKMP_NTYPE_INVALID_MESSAGE_ID 9
+#define ISAKMP_NTYPE_INVALID_PROTOCOL_ID 10
+#define ISAKMP_NTYPE_INVALID_SPI 11
+#define ISAKMP_NTYPE_INVALID_TRANSFORM_ID 12
+#define ISAKMP_NTYPE_ATTRIBUTES_NOT_SUPPORTED 13
+#define ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN 14
+#define ISAKMP_NTYPE_BAD_PROPOSAL_SYNTAX 15
+#define ISAKMP_NTYPE_PAYLOAD_MALFORMED 16
+#define ISAKMP_NTYPE_INVALID_KEY_INFORMATION 17
+#define ISAKMP_NTYPE_INVALID_ID_INFORMATION 18
+#define ISAKMP_NTYPE_INVALID_CERT_ENCODING 19
+#define ISAKMP_NTYPE_INVALID_CERTIFICATE 20
+#define ISAKMP_NTYPE_BAD_CERT_REQUEST_SYNTAX 21
+#define ISAKMP_NTYPE_INVALID_CERT_AUTHORITY 22
+#define ISAKMP_NTYPE_INVALID_HASH_INFORMATION 23
+#define ISAKMP_NTYPE_AUTHENTICATION_FAILED 24
+#define ISAKMP_NTYPE_INVALID_SIGNATURE 25
+#define ISAKMP_NTYPE_ADDRESS_NOTIFICATION 26
+/* NOTIFY MESSAGES - STATUS TYPES */
+#define ISAKMP_NTYPE_CONNECTED 16384
+/* using only to log */
+#define ISAKMP_LOG_RETRY_LIMIT_REACHED 65530
+
+/* 3.15 Delete Payload */
+struct ikev1_pl_d {
+ struct isakmp_gen h;
+ u_int32_t doi; /* Domain of Interpretation */
+ u_int8_t prot_id; /* Protocol-Id */
+ u_int8_t spi_size; /* SPI Size */
+ u_int16_t num_spi; /* # of SPIs */
+ /* SPI(es) */
+};
+
+
+struct ikev1_ph1tab {
+ struct ikev1_ph1 *head;
+ struct ikev1_ph1 *tail;
+ int len;
+};
+
+struct isakmp_ph2tab {
+ struct ikev1_ph2 *head;
+ struct ikev1_ph2 *tail;
+ int len;
+};
+
+#define EXCHANGE_PROXY 1
+#define EXCHANGE_MYSELF 0
+
+#define PFS_NEED 1
+#define PFS_NONEED 0
+
+/* IKEv2 (RFC4306) */
+
+/* 3.3 Security Association Payload -- generic header */
+/* 3.3.1. Proposal Substructure */
+struct ikev2_p {
+ struct isakmp_gen h;
+ u_int8_t p_no; /* Proposal # */
+ u_int8_t prot_id; /* Protocol */
+ u_int8_t spi_size; /* SPI Size */
+ u_int8_t num_t; /* Number of Transforms */
+};
+
+/* 3.3.2. Transform Substructure */
+struct ikev2_t {
+ struct isakmp_gen h;
+ u_int8_t t_type; /* Transform Type (ENCR,PRF,INTEG,etc.*/
+ u_int8_t res2; /* reserved byte */
+ u_int16_t t_id; /* Transform ID */
+};
+
+enum ikev2_t_type {
+ IV2_T_ENCR = 1,
+ IV2_T_PRF = 2,
+ IV2_T_INTEG= 3,
+ IV2_T_DH = 4,
+ IV2_T_ESN = 5,
+};
+
+/* 3.4. Key Exchange Payload */
+struct ikev2_ke {
+ struct isakmp_gen h;
+ u_int16_t ke_group;
+ u_int16_t ke_res1;
+ /* KE data */
+};
+
+
+/* 3.5. Identification Payloads */
+enum ikev2_id_type {
+ ID_IPV4_ADDR=1,
+ ID_FQDN=2,
+ ID_RFC822_ADDR=3,
+ ID_IPV6_ADDR=5,
+ ID_DER_ASN1_DN=9,
+ ID_DER_ASN1_GN=10,
+ ID_KEY_ID=11,
+};
+struct ikev2_id {
+ struct isakmp_gen h;
+ u_int8_t type; /* ID type */
+ u_int8_t res1;
+ u_int16_t res2;
+ /* SPI */
+ /* Notification Data */
+};
+
+/* 3.10 Notification Payload */
+struct ikev2_n {
+ struct isakmp_gen h;
+ u_int8_t prot_id; /* Protocol-ID */
+ u_int8_t spi_size; /* SPI Size */
+ u_int16_t type; /* Notify Message Type */
+};
+
+enum ikev2_n_type {
+ IV2_NOTIFY_UNSUPPORTED_CRITICAL_PAYLOAD = 1,
+ IV2_NOTIFY_INVALID_IKE_SPI = 4,
+ IV2_NOTIFY_INVALID_MAJOR_VERSION = 5,
+ IV2_NOTIFY_INVALID_SYNTAX = 7,
+ IV2_NOTIFY_INVALID_MESSAGE_ID = 9,
+ IV2_NOTIFY_INVALID_SPI =11,
+ IV2_NOTIFY_NO_PROPOSAL_CHOSEN =14,
+ IV2_NOTIFY_INVALID_KE_PAYLOAD =17,
+ IV2_NOTIFY_AUTHENTICATION_FAILED =24,
+ IV2_NOTIFY_SINGLE_PAIR_REQUIRED =34,
+ IV2_NOTIFY_NO_ADDITIONAL_SAS =35,
+ IV2_NOTIFY_INTERNAL_ADDRESS_FAILURE =36,
+ IV2_NOTIFY_FAILED_CP_REQUIRED =37,
+ IV2_NOTIFY_INVALID_SELECTORS =39,
+ IV2_NOTIFY_INITIAL_CONTACT =16384,
+ IV2_NOTIFY_SET_WINDOW_SIZE =16385,
+ IV2_NOTIFY_ADDITIONAL_TS_POSSIBLE =16386,
+ IV2_NOTIFY_IPCOMP_SUPPORTED =16387,
+ IV2_NOTIFY_NAT_DETECTION_SOURCE_IP =16388,
+ IV2_NOTIFY_NAT_DETECTION_DESTINATION_IP =16389,
+ IV2_NOTIFY_COOKIE =16390,
+ IV2_NOTIFY_USE_TRANSPORT_MODE =16391,
+ IV2_NOTIFY_HTTP_CERT_LOOKUP_SUPPORTED =16392,
+ IV2_NOTIFY_REKEY_SA =16393,
+ IV2_NOTIFY_ESP_TFC_PADDING_NOT_SUPPORTED =16394,
+ IV2_NOTIFY_NON_FIRST_FRAGMENTS_ALSO =16395
+};
+
+struct notify_messages {
+ u_int16_t type;
+ char *msg;
+};
+
+/* 3.8 Notification Payload */
+struct ikev2_auth {
+ struct isakmp_gen h;
+ u_int8_t auth_method; /* Protocol-ID */
+ u_int8_t reserved[3];
+ /* authentication data */
+};
+
+enum ikev2_auth_type {
+ IV2_RSA_SIG = 1,
+ IV2_SHARED = 2,
+ IV2_DSS_SIG = 3,
+};
+
+#endif /* !defined(_ISAKMP_H_) */
diff --git a/freebsd/contrib/tcpdump/l2tp.h b/freebsd/contrib/tcpdump/l2tp.h
new file mode 100644
index 00000000..5be24b9f
--- /dev/null
+++ b/freebsd/contrib/tcpdump/l2tp.h
@@ -0,0 +1,62 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/l2tp.h,v 1.5 2001-11-05 10:03:27 guy Exp $ (LBL) */
+/*
+ * Copyright (c) 1991, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * L2TP support contributed by Motonori Shindo (mshindo@mshindo.net)
+ */
+
+
+#define L2TP_FLAG_TYPE 0x8000 /* Type (0=Data, 1=Control) */
+#define L2TP_FLAG_LENGTH 0x4000 /* Length */
+#define L2TP_FLAG_SEQUENCE 0x0800 /* Sequence */
+#define L2TP_FLAG_OFFSET 0x0200 /* Offset */
+#define L2TP_FLAG_PRIORITY 0x0100 /* Priority */
+
+#define L2TP_VERSION_MASK 0x000f /* Version Mask */
+#define L2TP_VERSION_L2F 0x0001 /* L2F */
+#define L2TP_VERSION_L2TP 0x0002 /* L2TP */
+
+#define L2TP_AVP_HDR_FLAG_MANDATORY 0x8000 /* Mandatory Flag */
+#define L2TP_AVP_HDR_FLAG_HIDDEN 0x4000 /* Hidden Flag */
+#define L2TP_AVP_HDR_LEN_MASK 0x03ff /* Length Mask */
+
+#define L2TP_FRAMING_CAP_SYNC_MASK 0x00000001 /* Synchronous */
+#define L2TP_FRAMING_CAP_ASYNC_MASK 0x00000002 /* Asynchronous */
+
+#define L2TP_FRAMING_TYPE_SYNC_MASK 0x00000001 /* Synchronous */
+#define L2TP_FRAMING_TYPE_ASYNC_MASK 0x00000002 /* Asynchronous */
+
+#define L2TP_BEARER_CAP_DIGITAL_MASK 0x00000001 /* Digital */
+#define L2TP_BEARER_CAP_ANALOG_MASK 0x00000002 /* Analog */
+
+#define L2TP_BEARER_TYPE_DIGITAL_MASK 0x00000001 /* Digital */
+#define L2TP_BEARER_TYPE_ANALOG_MASK 0x00000002 /* Analog */
+
+/* Authen Type */
+#define L2TP_AUTHEN_TYPE_RESERVED 0x0000 /* Reserved */
+#define L2TP_AUTHEN_TYPE_TEXTUAL 0x0001 /* Textual username/password exchange */
+#define L2TP_AUTHEN_TYPE_CHAP 0x0002 /* PPP CHAP */
+#define L2TP_AUTHEN_TYPE_PAP 0x0003 /* PPP PAP */
+#define L2TP_AUTHEN_TYPE_NO_AUTH 0x0004 /* No Authentication */
+#define L2TP_AUTHEN_TYPE_MSCHAPv1 0x0005 /* MSCHAPv1 */
+
+#define L2TP_PROXY_AUTH_ID_MASK 0x00ff
+
+
diff --git a/freebsd/contrib/tcpdump/l2vpn.c b/freebsd/contrib/tcpdump/l2vpn.c
new file mode 100644
index 00000000..f869242b
--- /dev/null
+++ b/freebsd/contrib/tcpdump/l2vpn.c
@@ -0,0 +1,60 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/l2vpn.c,v 1.1 2004-06-15 09:42:40 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+#include "interface.h"
+#include "l2vpn.h"
+
+/* draft-ietf-pwe3-iana-allocation-04 */
+const struct tok l2vpn_encaps_values[] = {
+ { 0x00, "Reserved"},
+ { 0x01, "Frame Relay"},
+ { 0x02, "ATM AAL5 VCC transport"},
+ { 0x03, "ATM transparent cell transport"},
+ { 0x04, "Ethernet VLAN"},
+ { 0x05, "Ethernet"},
+ { 0x06, "Cisco-HDLC"},
+ { 0x07, "PPP"},
+ { 0x08, "SONET/SDH Circuit Emulation Service over MPLS"},
+ { 0x09, "ATM n-to-one VCC cell transport"},
+ { 0x0a, "ATM n-to-one VPC cell transport"},
+ { 0x0b, "IP Layer2 Transport"},
+ { 0x0c, "ATM one-to-one VCC Cell Mode"},
+ { 0x0d, "ATM one-to-one VPC Cell Mode"},
+ { 0x0e, "ATM AAL5 PDU VCC transport"},
+ { 0x0f, "Frame-Relay Port mode"},
+ { 0x10, "SONET/SDH Circuit Emulation over Packet"},
+ { 0x11, "Structure-agnostic E1 over Packet"},
+ { 0x12, "Structure-agnostic T1 (DS1) over Packet"},
+ { 0x13, "Structure-agnostic E3 over Packet"},
+ { 0x14, "Structure-agnostic T3 (DS3) over Packet"},
+ { 0x15, "CESoPSN basic mode"},
+ { 0x16, "TDMoIP basic mode"},
+ { 0x17, "CESoPSN TDM with CAS"},
+ { 0x18, "TDMoIP TDM with CAS"},
+ { 0x40, "IP-interworking"},
+ { 0, NULL}
+};
diff --git a/freebsd/contrib/tcpdump/l2vpn.h b/freebsd/contrib/tcpdump/l2vpn.h
new file mode 100644
index 00000000..871eca0e
--- /dev/null
+++ b/freebsd/contrib/tcpdump/l2vpn.h
@@ -0,0 +1,17 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/l2vpn.h,v 1.1 2004-06-15 09:42:41 hannes Exp $ (LBL) */
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+extern const struct tok l2vpn_encaps_values[];
diff --git a/freebsd/contrib/tcpdump/lane.h b/freebsd/contrib/tcpdump/lane.h
new file mode 100644
index 00000000..76cc020e
--- /dev/null
+++ b/freebsd/contrib/tcpdump/lane.h
@@ -0,0 +1,41 @@
+/*
+ * Marko Kiiskila carnil@cs.tut.fi
+ *
+ * Tampere University of Technology - Telecommunications Laboratory
+ *
+ * Permission to use, copy, modify and distribute this
+ * software and its documentation is hereby granted,
+ * provided that both the copyright notice and this
+ * permission notice appear in all copies of the software,
+ * derivative works or modified versions, and any portions
+ * thereof, that both notices appear in supporting
+ * documentation, and that the use of this software is
+ * acknowledged in any publications resulting from using
+ * the software.
+ *
+ * TUT ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION AND DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS
+ * SOFTWARE.
+ *
+ */
+
+/* $Id: lane.h,v 1.7 2002-12-11 07:13:54 guy Exp $ */
+
+#ifndef ETHER_ADDR_LEN
+#define ETHER_ADDR_LEN 6
+#endif
+
+struct lecdatahdr_8023 {
+ u_int16_t le_header;
+ u_int8_t h_dest[ETHER_ADDR_LEN];
+ u_int8_t h_source[ETHER_ADDR_LEN];
+ u_int16_t h_type;
+};
+
+struct lane_controlhdr {
+ u_int16_t lec_header;
+ u_int8_t lec_proto;
+ u_int8_t lec_vers;
+ u_int16_t lec_opcode;
+};
diff --git a/freebsd/contrib/tcpdump/llc.h b/freebsd/contrib/tcpdump/llc.h
new file mode 100644
index 00000000..faa72561
--- /dev/null
+++ b/freebsd/contrib/tcpdump/llc.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 1993, 1994, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /tcpdump/master/tcpdump/llc.h,v 1.23 2007-04-13 09:43:11 hannes Exp $ (LBL)
+ */
+
+/*
+ * Definitions for information in the LLC header.
+ */
+
+#define LLC_U_FMT 3
+#define LLC_GSAP 1
+#define LLC_IG 1 /* Individual / Group */
+#define LLC_S_FMT 1
+
+#define LLC_U_POLL 0x10
+#define LLC_IS_POLL 0x0100
+#define LLC_XID_FI 0x81
+
+#define LLC_U_CMD(u) ((u) & 0xef)
+#define LLC_UI 0x03
+#define LLC_UA 0x63
+#define LLC_DISC 0x43
+#define LLC_DM 0x0f
+#define LLC_SABME 0x6f
+#define LLC_TEST 0xe3
+#define LLC_XID 0xaf
+#define LLC_FRMR 0x87
+
+#define LLC_S_CMD(is) (((is) >> 2) & 0x03)
+#define LLC_RR 0x0001
+#define LLC_RNR 0x0005
+#define LLC_REJ 0x0009
+
+#define LLC_IS_NR(is) (((is) >> 9) & 0x7f)
+#define LLC_I_NS(is) (((is) >> 1) & 0x7f)
+
+#ifndef LLCSAP_NULL
+#define LLCSAP_NULL 0x00
+#endif
+#ifndef LLCSAP_GLOBAL
+#define LLCSAP_GLOBAL 0xff
+#endif
+#ifndef LLCSAP_8021B_I
+#define LLCSAP_8021B_I 0x02
+#endif
+#ifndef LLCSAP_8021B_G
+#define LLCSAP_8021B_G 0x03
+#endif
+#ifndef LLCSAP_SNA
+#define LLCSAP_SNA 0x04
+#endif
+#ifndef LLCSAP_IP
+#define LLCSAP_IP 0x06
+#endif
+#ifndef LLCSAP_PROWAYNM
+#define LLCSAP_PROWAYNM 0x0e
+#endif
+#ifndef LLCSAP_8021D
+#define LLCSAP_8021D 0x42
+#endif
+#ifndef LLCSAP_RS511
+#define LLCSAP_RS511 0x4e
+#endif
+#ifndef LLCSAP_ISO8208
+#define LLCSAP_ISO8208 0x7e
+#endif
+#ifndef LLCSAP_PROWAY
+#define LLCSAP_PROWAY 0x8e
+#endif
+#ifndef LLCSAP_SNAP
+#define LLCSAP_SNAP 0xaa
+#endif
+#ifndef LLCSAP_IPX
+#define LLCSAP_IPX 0xe0
+#endif
+#ifndef LLCSAP_NETBEUI
+#define LLCSAP_NETBEUI 0xf0
+#endif
+#ifndef LLCSAP_ISONS
+#define LLCSAP_ISONS 0xfe
+#endif
+
+/*
+ * PIDs for use with OUI_CISCO.
+ */
+#define PID_CISCO_CDP 0x2000 /* Cisco Discovery Protocol */
+#define PID_CISCO_VTP 0x2003 /* Cisco VLAN Trunk Protocol */
+#define PID_CISCO_DTP 0x2004 /* Cisco Dynamic Trunk Protocol */
+#define PID_CISCO_UDLD 0x0111 /* Unidirectional Link Detection */
+#define PID_CISCO_PVST 0x010b /* Per VLAN Spanning Tree+ and RPVST+ */
+
+/*
+ * PIDs for use with OUI_RFC2684.
+ */
+#define PID_RFC2684_ETH_FCS 0x0001 /* Ethernet, with FCS */
+#define PID_RFC2684_ETH_NOFCS 0x0007 /* Ethernet, without FCS */
+#define PID_RFC2684_802_4_FCS 0x0002 /* 802.4, with FCS */
+#define PID_RFC2684_802_4_NOFCS 0x0008 /* 802.4, without FCS */
+#define PID_RFC2684_802_5_FCS 0x0003 /* 802.5, with FCS */
+#define PID_RFC2684_802_5_NOFCS 0x0009 /* 802.5, without FCS */
+#define PID_RFC2684_FDDI_FCS 0x0004 /* FDDI, with FCS */
+#define PID_RFC2684_FDDI_NOFCS 0x000a /* FDDI, without FCS */
+#define PID_RFC2684_802_6_FCS 0x0005 /* 802.6, with FCS */
+#define PID_RFC2684_802_6_NOFCS 0x000b /* 802.6, without FCS */
+#define PID_RFC2684_BPDU 0x000e /* BPDUs */
diff --git a/freebsd/contrib/tcpdump/machdep.c b/freebsd/contrib/tcpdump/machdep.c
new file mode 100644
index 00000000..4d5e6b06
--- /dev/null
+++ b/freebsd/contrib/tcpdump/machdep.c
@@ -0,0 +1,69 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/machdep.c,v 1.13 2003-12-15 03:53:21 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/*
+ * XXX - all we need, on platforms other than DEC OSF/1 (a/k/a Digital UNIX,
+ * a/k/a Tru64 UNIX), is "size_t", which is a standard C type; what do we
+ * need to do to get it defined? This is clearly wrong, as we shouldn't
+ * have to include UNIX or Windows system header files to get it.
+ */
+#include <tcpdump-stdinc.h>
+
+#ifndef HAVE___ATTRIBUTE__
+#define __attribute__(x)
+#endif /* HAVE___ATTRIBUTE__ */
+
+#ifdef __osf__
+#include <sys/sysinfo.h>
+#include <sys/proc.h>
+
+#if !defined(HAVE_SNPRINTF)
+int snprintf(char *, size_t, const char *, ...)
+ __attribute__((format(printf, 3, 4)));
+#endif /* !defined(HAVE_SNPRINTF) */
+#endif /* __osf__ */
+
+#include "machdep.h"
+
+int
+abort_on_misalignment(char *ebuf _U_, size_t ebufsiz _U_)
+{
+#ifdef __osf__
+ static int buf[2] = { SSIN_UACPROC, UAC_SIGBUS };
+
+ if (setsysinfo(SSI_NVPAIRS, (caddr_t)buf, 1, 0, 0) < 0) {
+ (void)snprintf(ebuf, ebufsiz, "setsysinfo: errno %d", errno);
+ return (-1);
+ }
+#endif
+ return (0);
+}
diff --git a/freebsd/contrib/tcpdump/machdep.h b/freebsd/contrib/tcpdump/machdep.h
new file mode 100644
index 00000000..6328c826
--- /dev/null
+++ b/freebsd/contrib/tcpdump/machdep.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /tcpdump/master/tcpdump/machdep.h,v 1.2 2000-01-17 06:24:24 itojun Exp $ (LBL)
+ */
+#ifndef tcpdump_machdep_h
+#define tcpdump_machdep_h
+
+int abort_on_misalignment(char *, size_t);
+#endif
diff --git a/freebsd/contrib/tcpdump/mib.h b/freebsd/contrib/tcpdump/mib.h
new file mode 100644
index 00000000..92c6c2c5
--- /dev/null
+++ b/freebsd/contrib/tcpdump/mib.h
@@ -0,0 +1,1460 @@
+/*
+ * This file was generated by tcpdump/makemib on Wed Sep 26 12:12:31 EDT 1990
+ * You probably don't want to edit this by hand!
+ *
+ * struct mib somename = { desc, oid-octet, type, child-pointer, next-pointer
+};
+ */
+
+/* parse problem: new name "mib" for mgmt.mib(1) ignored */
+/* parse problem: no parent for 0.nullSpecific(0) */
+struct obj
+_proteon_obj = {
+ "proteon", 1, 0,
+ NULL, NULL
+},
+_ibm_obj = {
+ "ibm", 2, 0,
+ NULL, &_proteon_obj
+},
+_cmu_obj = {
+ "cmu", 3, 0,
+ NULL, &_ibm_obj
+},
+_unix_obj = {
+ "unix", 4, 0,
+ NULL, &_cmu_obj
+},
+_acc_obj = {
+ "acc", 5, 0,
+ NULL, &_unix_obj
+},
+_twg_obj = {
+ "twg", 6, 0,
+ NULL, &_acc_obj
+},
+_cayman_obj = {
+ "cayman", 7, 0,
+ NULL, &_twg_obj
+},
+_nysernet_obj = {
+ "nysernet", 8, 0,
+ NULL, &_cayman_obj
+},
+_cisco_obj = {
+ "cisco", 9, 0,
+ NULL, &_nysernet_obj
+},
+_nsc_obj = {
+ "nsc", 10, 0,
+ NULL, &_cisco_obj
+},
+_hp_obj = {
+ "hp", 11, 0,
+ NULL, &_nsc_obj
+},
+_epilogue_obj = {
+ "epilogue", 12, 0,
+ NULL, &_hp_obj
+},
+_utennessee_obj = {
+ "utennessee", 13, 0,
+ NULL, &_epilogue_obj
+},
+_bbn_obj = {
+ "bbn", 14, 0,
+ NULL, &_utennessee_obj
+},
+_xylogics_obj = {
+ "xylogics", 15, 0,
+ NULL, &_bbn_obj
+},
+_unisys_obj = {
+ "unisys", 16, 0,
+ NULL, &_xylogics_obj
+},
+_canstar_obj = {
+ "canstar", 17, 0,
+ NULL, &_unisys_obj
+},
+_wellfleet_obj = {
+ "wellfleet", 18, 0,
+ NULL, &_canstar_obj
+},
+_trw_obj = {
+ "trw", 19, 0,
+ NULL, &_wellfleet_obj
+},
+_mit_obj = {
+ "mit", 20, 0,
+ NULL, &_trw_obj
+},
+_eon_obj = {
+ "eon", 21, 0,
+ NULL, &_mit_obj
+},
+_spartacus_obj = {
+ "spartacus", 22, 0,
+ NULL, &_eon_obj
+},
+_excelan_obj = {
+ "excelan", 23, 0,
+ NULL, &_spartacus_obj
+},
+_spider_obj = {
+ "spider", 24, 0,
+ NULL, &_excelan_obj
+},
+_nsfnet_obj = {
+ "nsfnet", 25, 0,
+ NULL, &_spider_obj
+},
+_sytek_obj = {
+ "sytek", 26, 0,
+ NULL, &_nsfnet_obj
+},
+_intergraph_obj = {
+ "intergraph", 27, 0,
+ NULL, &_sytek_obj
+},
+_interlan_obj = {
+ "interlan", 28, 0,
+ NULL, &_intergraph_obj
+},
+_vitalink_obj = {
+ "vitalink", 29, 0,
+ NULL, &_interlan_obj
+},
+_ulana_obj = {
+ "ulana", 30, 0,
+ NULL, &_vitalink_obj
+},
+_nswc_obj = {
+ "nswc", 31, 0,
+ NULL, &_ulana_obj
+},
+_santacruzoperation_obj = {
+ "santacruzoperation", 32, 0,
+ NULL, &_nswc_obj
+},
+_xyplex_obj = {
+ "xyplex", 33, 0,
+ NULL, &_santacruzoperation_obj
+},
+_cray_obj = {
+ "cray", 34, 0,
+ NULL, &_xyplex_obj
+},
+_bellnorthernresearch_obj = {
+ "bellnorthernresearch", 35, 0,
+ NULL, &_cray_obj
+},
+_dec_obj = {
+ "dec", 36, 0,
+ NULL, &_bellnorthernresearch_obj
+},
+_touch_obj = {
+ "touch", 37, 0,
+ NULL, &_dec_obj
+},
+_networkresearchcorp_obj = {
+ "networkresearchcorp", 38, 0,
+ NULL, &_touch_obj
+},
+_baylor_obj = {
+ "baylor", 39, 0,
+ NULL, &_networkresearchcorp_obj
+},
+_nmfeccllnl_obj = {
+ "nmfeccllnl", 40, 0,
+ NULL, &_baylor_obj
+},
+_sri_obj = {
+ "sri", 41, 0,
+ NULL, &_nmfeccllnl_obj
+},
+_sun_obj = {
+ "sun", 42, 0,
+ NULL, &_sri_obj
+},
+_3com_obj = {
+ "3com", 43, 0,
+ NULL, &_sun_obj
+},
+_cmc_obj = {
+ "cmc", 44, 0,
+ NULL, &_3com_obj
+},
+_synoptics_obj = {
+ "synoptics", 45, 0,
+ NULL, &_cmc_obj
+},
+_cheyenne_obj = {
+ "cheyenne", 46, 0,
+ NULL, &_synoptics_obj
+},
+_prime_obj = {
+ "prime", 47, 0,
+ NULL, &_cheyenne_obj
+},
+_mcnc_obj = {
+ "mcnc", 48, 0,
+ NULL, &_prime_obj
+},
+_chipcom_obj = {
+ "chipcom", 49, 0,
+ NULL, &_mcnc_obj
+},
+_opticaldatasystems_obj = {
+ "opticaldatasystems", 50, 0,
+ NULL, &_chipcom_obj
+},
+_gated_obj = {
+ "gated", 51, 0,
+ NULL, &_opticaldatasystems_obj
+},
+_cabletron_obj = {
+ "cabletron", 52, 0,
+ NULL, &_gated_obj
+},
+_apollo_obj = {
+ "apollo", 53, 0,
+ NULL, &_cabletron_obj
+},
+_desktalksystems_obj = {
+ "desktalksystems", 54, 0,
+ NULL, &_apollo_obj
+},
+_ssds_obj = {
+ "ssds", 55, 0,
+ NULL, &_desktalksystems_obj
+},
+_castlerock_obj = {
+ "castlerock", 56, 0,
+ NULL, &_ssds_obj
+},
+_mips_obj = {
+ "mips", 57, 0,
+ NULL, &_castlerock_obj
+},
+_tgv_obj = {
+ "tgv", 58, 0,
+ NULL, &_mips_obj
+},
+_silicongraphics_obj = {
+ "silicongraphics", 59, 0,
+ NULL, &_tgv_obj
+},
+_ubc_obj = {
+ "ubc", 60, 0,
+ NULL, &_silicongraphics_obj
+},
+_merit_obj = {
+ "merit", 61, 0,
+ NULL, &_ubc_obj
+},
+_fibercom_obj = {
+ "fibercom", 62, 0,
+ NULL, &_merit_obj
+},
+_apple_obj = {
+ "apple", 63, 0,
+ NULL, &_fibercom_obj
+},
+_gandalf_obj = {
+ "gandalf", 64, 0,
+ NULL, &_apple_obj
+},
+_dartmouth_obj = {
+ "dartmouth", 65, 0,
+ NULL, &_gandalf_obj
+},
+_davidsystems_obj = {
+ "davidsystems", 66, 0,
+ NULL, &_dartmouth_obj
+},
+_reuter_obj = {
+ "reuter", 67, 0,
+ NULL, &_davidsystems_obj
+},
+_cornell_obj = {
+ "cornell", 68, 0,
+ NULL, &_reuter_obj
+},
+_tmac_obj = {
+ "tmac", 69, 0,
+ NULL, &_cornell_obj
+},
+_locus_obj = {
+ "locus", 70, 0,
+ NULL, &_tmac_obj
+},
+_nasa_obj = {
+ "nasa", 71, 0,
+ NULL, &_locus_obj
+},
+_retix_obj = {
+ "retix", 72, 0,
+ NULL, &_nasa_obj
+},
+_boeing_obj = {
+ "boeing", 73, 0,
+ NULL, &_retix_obj
+},
+_att_obj = {
+ "att", 74, 0,
+ NULL, &_boeing_obj
+},
+_ungermannbass_obj = {
+ "ungermannbass", 75, 0,
+ NULL, &_att_obj
+},
+_digitalanalysis_obj = {
+ "digitalanalysis", 76, 0,
+ NULL, &_ungermannbass_obj
+},
+_hplanman_obj = {
+ "hplanman", 77, 0,
+ NULL, &_digitalanalysis_obj
+},
+_netlabs_obj = {
+ "netlabs", 78, 0,
+ NULL, &_hplanman_obj
+},
+_icl_obj = {
+ "icl", 79, 0,
+ NULL, &_netlabs_obj
+},
+_auspex_obj = {
+ "auspex", 80, 0,
+ NULL, &_icl_obj
+},
+_lannet_obj = {
+ "lannet", 81, 0,
+ NULL, &_auspex_obj
+},
+_ncd_obj = {
+ "ncd", 82, 0,
+ NULL, &_lannet_obj
+},
+_raycom_obj = {
+ "raycom", 83, 0,
+ NULL, &_ncd_obj
+},
+_pirellifocom_obj = {
+ "pirellifocom", 84, 0,
+ NULL, &_raycom_obj
+},
+_datability_obj = {
+ "datability", 85, 0,
+ NULL, &_pirellifocom_obj
+},
+_networkappltech_obj = {
+ "networkappltech", 86, 0,
+ NULL, &_datability_obj
+},
+_link_obj = {
+ "link", 87, 0,
+ NULL, &_networkappltech_obj
+},
+_nyu_obj = {
+ "nyu", 88, 0,
+ NULL, &_link_obj
+},
+_rnd_obj = {
+ "rnd", 89, 0,
+ NULL, &_nyu_obj
+},
+_intercon_obj = {
+ "intercon", 90, 0,
+ NULL, &_rnd_obj
+},
+_learningtree_obj = {
+ "learningtree", 91, 0,
+ NULL, &_intercon_obj
+},
+_webstercomputer_obj = {
+ "webstercomputer", 92, 0,
+ NULL, &_learningtree_obj
+},
+_frontier_obj = {
+ "frontier", 93, 0,
+ NULL, &_webstercomputer_obj
+},
+_nokia_obj = {
+ "nokia", 94, 0,
+ NULL, &_frontier_obj
+},
+_allenbradley_obj = {
+ "allenbradley", 95, 0,
+ NULL, &_nokia_obj
+},
+_cern_obj = {
+ "cern", 96, 0,
+ NULL, &_allenbradley_obj
+},
+_sigma_obj = {
+ "sigma", 97, 0,
+ NULL, &_cern_obj
+},
+_emergingtech_obj = {
+ "emergingtech", 98, 0,
+ NULL, &_sigma_obj
+},
+_snmpresearch_obj = {
+ "snmpresearch", 99, 0,
+ NULL, &_emergingtech_obj
+},
+_ohiostate_obj = {
+ "ohiostate", 100, 0,
+ NULL, &_snmpresearch_obj
+},
+_ultra_obj = {
+ "ultra", 101, 0,
+ NULL, &_ohiostate_obj
+},
+_ccur_obj = {
+ "ccur", 136, 0,
+ NULL, &_ultra_obj
+},
+_enterprises_obj = {
+ "enterprises", 1, 0,
+ &_ccur_obj, NULL
+},
+_snmpInPkts_obj = {
+ "snmpInPkts", 1, 0,
+ NULL, NULL
+},
+_snmpOutPkts_obj = {
+ "snmpOutPkts", 2, 0,
+ NULL, &_snmpInPkts_obj
+},
+_snmpInBadVersions_obj = {
+ "snmpInBadVersions", 3, 0,
+ NULL, &_snmpOutPkts_obj
+},
+_snmpInBadCommunityNames_obj = {
+ "snmpInBadCommunityNames", 4, 0,
+ NULL, &_snmpInBadVersions_obj
+},
+_snmpInBadCommunityUses_obj = {
+ "snmpInBadCommunityUses", 5, 0,
+ NULL, &_snmpInBadCommunityNames_obj
+},
+_snmpInASNParseErrs_obj = {
+ "snmpInASNParseErrs", 6, 0,
+ NULL, &_snmpInBadCommunityUses_obj
+},
+_snmpInBadTypes_obj = {
+ "snmpInBadTypes", 7, 0,
+ NULL, &_snmpInASNParseErrs_obj
+},
+_snmpInTooBigs_obj = {
+ "snmpInTooBigs", 8, 0,
+ NULL, &_snmpInBadTypes_obj
+},
+_snmpInNoSuchNames_obj = {
+ "snmpInNoSuchNames", 9, 0,
+ NULL, &_snmpInTooBigs_obj
+},
+_snmpInBadValues_obj = {
+ "snmpInBadValues", 10, 0,
+ NULL, &_snmpInNoSuchNames_obj
+},
+_snmpInReadOnlys_obj = {
+ "snmpInReadOnlys", 11, 0,
+ NULL, &_snmpInBadValues_obj
+},
+_snmpInGenErrs_obj = {
+ "snmpInGenErrs", 12, 0,
+ NULL, &_snmpInReadOnlys_obj
+},
+_snmpInTotalReqVars_obj = {
+ "snmpInTotalReqVars", 13, 0,
+ NULL, &_snmpInGenErrs_obj
+},
+_snmpInTotalSetVars_obj = {
+ "snmpInTotalSetVars", 14, 0,
+ NULL, &_snmpInTotalReqVars_obj
+},
+_snmpInGetRequests_obj = {
+ "snmpInGetRequests", 15, 0,
+ NULL, &_snmpInTotalSetVars_obj
+},
+_snmpInGetNexts_obj = {
+ "snmpInGetNexts", 16, 0,
+ NULL, &_snmpInGetRequests_obj
+},
+_snmpInSetRequests_obj = {
+ "snmpInSetRequests", 17, 0,
+ NULL, &_snmpInGetNexts_obj
+},
+_snmpInGetResponses_obj = {
+ "snmpInGetResponses", 18, 0,
+ NULL, &_snmpInSetRequests_obj
+},
+_snmpInTraps_obj = {
+ "snmpInTraps", 19, 0,
+ NULL, &_snmpInGetResponses_obj
+},
+_snmpOutTooBigs_obj = {
+ "snmpOutTooBigs", 20, 0,
+ NULL, &_snmpInTraps_obj
+},
+_snmpOutNoSuchNames_obj = {
+ "snmpOutNoSuchNames", 21, 0,
+ NULL, &_snmpOutTooBigs_obj
+},
+_snmpOutBadValues_obj = {
+ "snmpOutBadValues", 22, 0,
+ NULL, &_snmpOutNoSuchNames_obj
+},
+_snmpOutReadOnlys_obj = {
+ "snmpOutReadOnlys", 23, 0,
+ NULL, &_snmpOutBadValues_obj
+},
+_snmpOutGenErrs_obj = {
+ "snmpOutGenErrs", 24, 0,
+ NULL, &_snmpOutReadOnlys_obj
+},
+_snmpOutGetRequests_obj = {
+ "snmpOutGetRequests", 25, 0,
+ NULL, &_snmpOutGenErrs_obj
+},
+_snmpOutGetNexts_obj = {
+ "snmpOutGetNexts", 26, 0,
+ NULL, &_snmpOutGetRequests_obj
+},
+_snmpOutSetRequests_obj = {
+ "snmpOutSetRequests", 27, 0,
+ NULL, &_snmpOutGetNexts_obj
+},
+_snmpOutGetResponses_obj = {
+ "snmpOutGetResponses", 28, 0,
+ NULL, &_snmpOutSetRequests_obj
+},
+_snmpOutTraps_obj = {
+ "snmpOutTraps", 29, 0,
+ NULL, &_snmpOutGetResponses_obj
+},
+_snmpEnableAuthTraps_obj = {
+ "snmpEnableAuthTraps", 30, 0,
+ NULL, &_snmpOutTraps_obj
+},
+_egpNeighState_obj = {
+ "egpNeighState", 1, 0,
+ NULL, NULL
+},
+_egpNeighAddr_obj = {
+ "egpNeighAddr", 2, 0,
+ NULL, &_egpNeighState_obj
+},
+_egpNeighAs_obj = {
+ "egpNeighAs", 3, 0,
+ NULL, &_egpNeighAddr_obj
+},
+_egpNeighInMsgs_obj = {
+ "egpNeighInMsgs", 4, 0,
+ NULL, &_egpNeighAs_obj
+},
+_egpNeighInErrs_obj = {
+ "egpNeighInErrs", 5, 0,
+ NULL, &_egpNeighInMsgs_obj
+},
+_egpNeighOutMsgs_obj = {
+ "egpNeighOutMsgs", 6, 0,
+ NULL, &_egpNeighInErrs_obj
+},
+_egpNeighOutErrs_obj = {
+ "egpNeighOutErrs", 7, 0,
+ NULL, &_egpNeighOutMsgs_obj
+},
+_egpNeighInErrMsgs_obj = {
+ "egpNeighInErrMsgs", 8, 0,
+ NULL, &_egpNeighOutErrs_obj
+},
+_egpNeighOutErrMsgs_obj = {
+ "egpNeighOutErrMsgs", 9, 0,
+ NULL, &_egpNeighInErrMsgs_obj
+},
+_egpNeighStateUps_obj = {
+ "egpNeighStateUps", 10, 0,
+ NULL, &_egpNeighOutErrMsgs_obj
+},
+_egpNeighStateDowns_obj = {
+ "egpNeighStateDowns", 11, 0,
+ NULL, &_egpNeighStateUps_obj
+},
+_egpNeighIntervalHello_obj = {
+ "egpNeighIntervalHello", 12, 0,
+ NULL, &_egpNeighStateDowns_obj
+},
+_egpNeighIntervalPoll_obj = {
+ "egpNeighIntervalPoll", 13, 0,
+ NULL, &_egpNeighIntervalHello_obj
+},
+_egpNeighMode_obj = {
+ "egpNeighMode", 14, 0,
+ NULL, &_egpNeighIntervalPoll_obj
+},
+_egpNeighEventTrigger_obj = {
+ "egpNeighEventTrigger", 15, 0,
+ NULL, &_egpNeighMode_obj
+},
+_egpNeighEntry_obj = {
+ "egpNeighEntry", 1, 0,
+ &_egpNeighEventTrigger_obj, NULL
+},
+_egpInMsgs_obj = {
+ "egpInMsgs", 1, 0,
+ NULL, NULL
+},
+_egpInErrors_obj = {
+ "egpInErrors", 2, 0,
+ NULL, &_egpInMsgs_obj
+},
+_egpOutMsgs_obj = {
+ "egpOutMsgs", 3, 0,
+ NULL, &_egpInErrors_obj
+},
+_egpOutErrors_obj = {
+ "egpOutErrors", 4, 0,
+ NULL, &_egpOutMsgs_obj
+},
+_egpNeighTable_obj = {
+ "egpNeighTable", 5, 0,
+ &_egpNeighEntry_obj, &_egpOutErrors_obj
+},
+_egpAs_obj = {
+ "egpAs", 6, 0,
+ NULL, &_egpNeighTable_obj
+},
+_udpLocalAddress_obj = {
+ "udpLocalAddress", 1, 0,
+ NULL, NULL
+},
+_udpLocalPort_obj = {
+ "udpLocalPort", 2, 0,
+ NULL, &_udpLocalAddress_obj
+},
+_udpEntry_obj = {
+ "udpEntry", 1, 0,
+ &_udpLocalPort_obj, NULL
+},
+_udpInDatagrams_obj = {
+ "udpInDatagrams", 1, 0,
+ NULL, NULL
+},
+_udpNoPorts_obj = {
+ "udpNoPorts", 2, 0,
+ NULL, &_udpInDatagrams_obj
+},
+_udpInErrors_obj = {
+ "udpInErrors", 3, 0,
+ NULL, &_udpNoPorts_obj
+},
+_udpOutDatagrams_obj = {
+ "udpOutDatagrams", 4, 0,
+ NULL, &_udpInErrors_obj
+},
+_udpTable_obj = {
+ "udpTable", 5, 0,
+ &_udpEntry_obj, &_udpOutDatagrams_obj
+},
+_tcpConnState_obj = {
+ "tcpConnState", 1, 0,
+ NULL, NULL
+},
+_tcpConnLocalAddress_obj = {
+ "tcpConnLocalAddress", 2, 0,
+ NULL, &_tcpConnState_obj
+},
+_tcpConnLocalPort_obj = {
+ "tcpConnLocalPort", 3, 0,
+ NULL, &_tcpConnLocalAddress_obj
+},
+_tcpConnRemAddress_obj = {
+ "tcpConnRemAddress", 4, 0,
+ NULL, &_tcpConnLocalPort_obj
+},
+_tcpConnRemPort_obj = {
+ "tcpConnRemPort", 5, 0,
+ NULL, &_tcpConnRemAddress_obj
+},
+_tcpConnEntry_obj = {
+ "tcpConnEntry", 1, 0,
+ &_tcpConnRemPort_obj, NULL
+},
+_tcpRtoAlgorithm_obj = {
+ "tcpRtoAlgorithm", 1, 0,
+ NULL, NULL
+},
+_tcpRtoMin_obj = {
+ "tcpRtoMin", 2, 0,
+ NULL, &_tcpRtoAlgorithm_obj
+},
+_tcpRtoMax_obj = {
+ "tcpRtoMax", 3, 0,
+ NULL, &_tcpRtoMin_obj
+},
+_tcpMaxConn_obj = {
+ "tcpMaxConn", 4, 0,
+ NULL, &_tcpRtoMax_obj
+},
+_tcpActiveOpens_obj = {
+ "tcpActiveOpens", 5, 0,
+ NULL, &_tcpMaxConn_obj
+},
+_tcpPassiveOpens_obj = {
+ "tcpPassiveOpens", 6, 0,
+ NULL, &_tcpActiveOpens_obj
+},
+_tcpAttemptFails_obj = {
+ "tcpAttemptFails", 7, 0,
+ NULL, &_tcpPassiveOpens_obj
+},
+_tcpEstabResets_obj = {
+ "tcpEstabResets", 8, 0,
+ NULL, &_tcpAttemptFails_obj
+},
+_tcpCurrEstab_obj = {
+ "tcpCurrEstab", 9, 0,
+ NULL, &_tcpEstabResets_obj
+},
+_tcpInSegs_obj = {
+ "tcpInSegs", 10, 0,
+ NULL, &_tcpCurrEstab_obj
+},
+_tcpOutSegs_obj = {
+ "tcpOutSegs", 11, 0,
+ NULL, &_tcpInSegs_obj
+},
+_tcpRetransSegs_obj = {
+ "tcpRetransSegs", 12, 0,
+ NULL, &_tcpOutSegs_obj
+},
+_tcpConnTable_obj = {
+ "tcpConnTable", 13, 0,
+ &_tcpConnEntry_obj, &_tcpRetransSegs_obj
+},
+_tcpInErrs_obj = {
+ "tcpInErrs", 14, 0,
+ NULL, &_tcpConnTable_obj
+},
+_tcpOutRsts_obj = {
+ "tcpOutRsts", 15, 0,
+ NULL, &_tcpInErrs_obj
+},
+_icmpInMsgs_obj = {
+ "icmpInMsgs", 1, 0,
+ NULL, NULL
+},
+_icmpInErrors_obj = {
+ "icmpInErrors", 2, 0,
+ NULL, &_icmpInMsgs_obj
+},
+_icmpInDestUnreachs_obj = {
+ "icmpInDestUnreachs", 3, 0,
+ NULL, &_icmpInErrors_obj
+},
+_icmpInTimeExcds_obj = {
+ "icmpInTimeExcds", 4, 0,
+ NULL, &_icmpInDestUnreachs_obj
+},
+_icmpInParmProbs_obj = {
+ "icmpInParmProbs", 5, 0,
+ NULL, &_icmpInTimeExcds_obj
+},
+_icmpInSrcQuenchs_obj = {
+ "icmpInSrcQuenchs", 6, 0,
+ NULL, &_icmpInParmProbs_obj
+},
+_icmpInRedirects_obj = {
+ "icmpInRedirects", 7, 0,
+ NULL, &_icmpInSrcQuenchs_obj
+},
+_icmpInEchos_obj = {
+ "icmpInEchos", 8, 0,
+ NULL, &_icmpInRedirects_obj
+},
+_icmpInEchoReps_obj = {
+ "icmpInEchoReps", 9, 0,
+ NULL, &_icmpInEchos_obj
+},
+_icmpInTimestamps_obj = {
+ "icmpInTimestamps", 10, 0,
+ NULL, &_icmpInEchoReps_obj
+},
+_icmpInTimestampReps_obj = {
+ "icmpInTimestampReps", 11, 0,
+ NULL, &_icmpInTimestamps_obj
+},
+_icmpInAddrMasks_obj = {
+ "icmpInAddrMasks", 12, 0,
+ NULL, &_icmpInTimestampReps_obj
+},
+_icmpInAddrMaskReps_obj = {
+ "icmpInAddrMaskReps", 13, 0,
+ NULL, &_icmpInAddrMasks_obj
+},
+_icmpOutMsgs_obj = {
+ "icmpOutMsgs", 14, 0,
+ NULL, &_icmpInAddrMaskReps_obj
+},
+_icmpOutErrors_obj = {
+ "icmpOutErrors", 15, 0,
+ NULL, &_icmpOutMsgs_obj
+},
+_icmpOutDestUnreachs_obj = {
+ "icmpOutDestUnreachs", 16, 0,
+ NULL, &_icmpOutErrors_obj
+},
+_icmpOutTimeExcds_obj = {
+ "icmpOutTimeExcds", 17, 0,
+ NULL, &_icmpOutDestUnreachs_obj
+},
+_icmpOutParmProbs_obj = {
+ "icmpOutParmProbs", 18, 0,
+ NULL, &_icmpOutTimeExcds_obj
+},
+_icmpOutSrcQuenchs_obj = {
+ "icmpOutSrcQuenchs", 19, 0,
+ NULL, &_icmpOutParmProbs_obj
+},
+_icmpOutRedirects_obj = {
+ "icmpOutRedirects", 20, 0,
+ NULL, &_icmpOutSrcQuenchs_obj
+},
+_icmpOutEchos_obj = {
+ "icmpOutEchos", 21, 0,
+ NULL, &_icmpOutRedirects_obj
+},
+_icmpOutEchoReps_obj = {
+ "icmpOutEchoReps", 22, 0,
+ NULL, &_icmpOutEchos_obj
+},
+_icmpOutTimestamps_obj = {
+ "icmpOutTimestamps", 23, 0,
+ NULL, &_icmpOutEchoReps_obj
+},
+_icmpOutTimestampReps_obj = {
+ "icmpOutTimestampReps", 24, 0,
+ NULL, &_icmpOutTimestamps_obj
+},
+_icmpOutAddrMasks_obj = {
+ "icmpOutAddrMasks", 25, 0,
+ NULL, &_icmpOutTimestampReps_obj
+},
+_icmpOutAddrMaskReps_obj = {
+ "icmpOutAddrMaskReps", 26, 0,
+ NULL, &_icmpOutAddrMasks_obj
+},
+_ipNetToMediaIfIndex_obj = {
+ "ipNetToMediaIfIndex", 1, 0,
+ NULL, NULL
+},
+_ipNetToMediaPhysAddress_obj = {
+ "ipNetToMediaPhysAddress", 2, 0,
+ NULL, &_ipNetToMediaIfIndex_obj
+},
+_ipNetToMediaNetAddress_obj = {
+ "ipNetToMediaNetAddress", 3, 0,
+ NULL, &_ipNetToMediaPhysAddress_obj
+},
+_ipNetToMediaType_obj = {
+ "ipNetToMediaType", 4, 0,
+ NULL, &_ipNetToMediaNetAddress_obj
+},
+_ipNetToMediaEntry_obj = {
+ "ipNetToMediaEntry", 1, 0,
+ &_ipNetToMediaType_obj, NULL
+},
+_ipRouteDest_obj = {
+ "ipRouteDest", 1, 0,
+ NULL, NULL
+},
+_ipRouteIfIndex_obj = {
+ "ipRouteIfIndex", 2, 0,
+ NULL, &_ipRouteDest_obj
+},
+_ipRouteMetric1_obj = {
+ "ipRouteMetric1", 3, 0,
+ NULL, &_ipRouteIfIndex_obj
+},
+_ipRouteMetric2_obj = {
+ "ipRouteMetric2", 4, 0,
+ NULL, &_ipRouteMetric1_obj
+},
+_ipRouteMetric3_obj = {
+ "ipRouteMetric3", 5, 0,
+ NULL, &_ipRouteMetric2_obj
+},
+_ipRouteMetric4_obj = {
+ "ipRouteMetric4", 6, 0,
+ NULL, &_ipRouteMetric3_obj
+},
+_ipRouteNextHop_obj = {
+ "ipRouteNextHop", 7, 0,
+ NULL, &_ipRouteMetric4_obj
+},
+_ipRouteType_obj = {
+ "ipRouteType", 8, 0,
+ NULL, &_ipRouteNextHop_obj
+},
+_ipRouteProto_obj = {
+ "ipRouteProto", 9, 0,
+ NULL, &_ipRouteType_obj
+},
+_ipRouteAge_obj = {
+ "ipRouteAge", 10, 0,
+ NULL, &_ipRouteProto_obj
+},
+_ipRouteMask_obj = {
+ "ipRouteMask", 11, 0,
+ NULL, &_ipRouteAge_obj
+},
+_ipRouteEntry_obj = {
+ "ipRouteEntry", 1, 0,
+ &_ipRouteMask_obj, NULL
+},
+_ipAdEntAddr_obj = {
+ "ipAdEntAddr", 1, 0,
+ NULL, NULL
+},
+_ipAdEntIfIndex_obj = {
+ "ipAdEntIfIndex", 2, 0,
+ NULL, &_ipAdEntAddr_obj
+},
+_ipAdEntNetMask_obj = {
+ "ipAdEntNetMask", 3, 0,
+ NULL, &_ipAdEntIfIndex_obj
+},
+_ipAdEntBcastAddr_obj = {
+ "ipAdEntBcastAddr", 4, 0,
+ NULL, &_ipAdEntNetMask_obj
+},
+_ipAdEntReasmMaxSize_obj = {
+ "ipAdEntReasmMaxSize", 5, 0,
+ NULL, &_ipAdEntBcastAddr_obj
+},
+_ipAddrEntry_obj = {
+ "ipAddrEntry", 1, 0,
+ &_ipAdEntReasmMaxSize_obj, NULL
+},
+_ipForwarding_obj = {
+ "ipForwarding", 1, 0,
+ NULL, NULL
+},
+_ipDefaultTTL_obj = {
+ "ipDefaultTTL", 2, 0,
+ NULL, &_ipForwarding_obj
+},
+_ipInReceives_obj = {
+ "ipInReceives", 3, 0,
+ NULL, &_ipDefaultTTL_obj
+},
+_ipInHdrErrors_obj = {
+ "ipInHdrErrors", 4, 0,
+ NULL, &_ipInReceives_obj
+},
+_ipInAddrErrors_obj = {
+ "ipInAddrErrors", 5, 0,
+ NULL, &_ipInHdrErrors_obj
+},
+_ipForwDatagrams_obj = {
+ "ipForwDatagrams", 6, 0,
+ NULL, &_ipInAddrErrors_obj
+},
+_ipInUnknownProtos_obj = {
+ "ipInUnknownProtos", 7, 0,
+ NULL, &_ipForwDatagrams_obj
+},
+_ipInDiscards_obj = {
+ "ipInDiscards", 8, 0,
+ NULL, &_ipInUnknownProtos_obj
+},
+_ipInDelivers_obj = {
+ "ipInDelivers", 9, 0,
+ NULL, &_ipInDiscards_obj
+},
+_ipOutRequests_obj = {
+ "ipOutRequests", 10, 0,
+ NULL, &_ipInDelivers_obj
+},
+_ipOutDiscards_obj = {
+ "ipOutDiscards", 11, 0,
+ NULL, &_ipOutRequests_obj
+},
+_ipOutNoRoutes_obj = {
+ "ipOutNoRoutes", 12, 0,
+ NULL, &_ipOutDiscards_obj
+},
+_ipReasmTimeout_obj = {
+ "ipReasmTimeout", 13, 0,
+ NULL, &_ipOutNoRoutes_obj
+},
+_ipReasmReqds_obj = {
+ "ipReasmReqds", 14, 0,
+ NULL, &_ipReasmTimeout_obj
+},
+_ipReasmOKs_obj = {
+ "ipReasmOKs", 15, 0,
+ NULL, &_ipReasmReqds_obj
+},
+_ipReasmFails_obj = {
+ "ipReasmFails", 16, 0,
+ NULL, &_ipReasmOKs_obj
+},
+_ipFragOKs_obj = {
+ "ipFragOKs", 17, 0,
+ NULL, &_ipReasmFails_obj
+},
+_ipFragFails_obj = {
+ "ipFragFails", 18, 0,
+ NULL, &_ipFragOKs_obj
+},
+_ipFragCreates_obj = {
+ "ipFragCreates", 19, 0,
+ NULL, &_ipFragFails_obj
+},
+_ipAddrTable_obj = {
+ "ipAddrTable", 20, 0,
+ &_ipAddrEntry_obj, &_ipFragCreates_obj
+},
+_ipRoutingTable_obj = {
+ "ipRoutingTable", 21, 0,
+ &_ipRouteEntry_obj, &_ipAddrTable_obj
+},
+_ipNetToMediaTable_obj = {
+ "ipNetToMediaTable", 22, 0,
+ &_ipNetToMediaEntry_obj, &_ipRoutingTable_obj
+},
+_atIfIndex_obj = {
+ "atIfIndex", 1, 0,
+ NULL, NULL
+},
+_atPhysAddress_obj = {
+ "atPhysAddress", 2, 0,
+ NULL, &_atIfIndex_obj
+},
+_atNetAddress_obj = {
+ "atNetAddress", 3, 0,
+ NULL, &_atPhysAddress_obj
+},
+_atEntry_obj = {
+ "atEntry", 1, 0,
+ &_atNetAddress_obj, NULL
+},
+_atTable_obj = {
+ "atTable", 1, 0,
+ &_atEntry_obj, NULL
+},
+_ifIndex_obj = {
+ "ifIndex", 1, 0,
+ NULL, NULL
+},
+_ifDescr_obj = {
+ "ifDescr", 2, 0,
+ NULL, &_ifIndex_obj
+},
+_ifType_obj = {
+ "ifType", 3, 0,
+ NULL, &_ifDescr_obj
+},
+_ifMtu_obj = {
+ "ifMtu", 4, 0,
+ NULL, &_ifType_obj
+},
+_ifSpeed_obj = {
+ "ifSpeed", 5, 0,
+ NULL, &_ifMtu_obj
+},
+_ifPhysAddress_obj = {
+ "ifPhysAddress", 6, 0,
+ NULL, &_ifSpeed_obj
+},
+_ifAdminStatus_obj = {
+ "ifAdminStatus", 7, 0,
+ NULL, &_ifPhysAddress_obj
+},
+_ifOperStatus_obj = {
+ "ifOperStatus", 8, 0,
+ NULL, &_ifAdminStatus_obj
+},
+_ifLastChange_obj = {
+ "ifLastChange", 9, 0,
+ NULL, &_ifOperStatus_obj
+},
+_ifInOctets_obj = {
+ "ifInOctets", 10, 0,
+ NULL, &_ifLastChange_obj
+},
+_ifInUcastPkts_obj = {
+ "ifInUcastPkts", 11, 0,
+ NULL, &_ifInOctets_obj
+},
+_ifInNUcastPkts_obj = {
+ "ifInNUcastPkts", 12, 0,
+ NULL, &_ifInUcastPkts_obj
+},
+_ifInDiscards_obj = {
+ "ifInDiscards", 13, 0,
+ NULL, &_ifInNUcastPkts_obj
+},
+_ifInErrors_obj = {
+ "ifInErrors", 14, 0,
+ NULL, &_ifInDiscards_obj
+},
+_ifInUnknownProtos_obj = {
+ "ifInUnknownProtos", 15, 0,
+ NULL, &_ifInErrors_obj
+},
+_ifOutOctets_obj = {
+ "ifOutOctets", 16, 0,
+ NULL, &_ifInUnknownProtos_obj
+},
+_ifOutUcastPkts_obj = {
+ "ifOutUcastPkts", 17, 0,
+ NULL, &_ifOutOctets_obj
+},
+_ifOutNUcastPkts_obj = {
+ "ifOutNUcastPkts", 18, 0,
+ NULL, &_ifOutUcastPkts_obj
+},
+_ifOutDiscards_obj = {
+ "ifOutDiscards", 19, 0,
+ NULL, &_ifOutNUcastPkts_obj
+},
+_ifOutErrors_obj = {
+ "ifOutErrors", 20, 0,
+ NULL, &_ifOutDiscards_obj
+},
+_ifOutQLen_obj = {
+ "ifOutQLen", 21, 0,
+ NULL, &_ifOutErrors_obj
+},
+_ifSpecific_obj = {
+ "ifSpecific", 22, 0,
+ NULL, &_ifOutQLen_obj
+},
+_ifEntry_obj = {
+ "ifEntry", 1, 0,
+ &_ifSpecific_obj, NULL
+},
+_ifNumber_obj = {
+ "ifNumber", 1, 0,
+ NULL, NULL
+},
+_ifTable_obj = {
+ "ifTable", 2, 0,
+ &_ifEntry_obj, &_ifNumber_obj
+},
+_sysDescr_obj = {
+ "sysDescr", 1, 0,
+ NULL, NULL
+},
+_sysObjectID_obj = {
+ "sysObjectID", 2, 0,
+ NULL, &_sysDescr_obj
+},
+_sysUpTime_obj = {
+ "sysUpTime", 3, 0,
+ NULL, &_sysObjectID_obj
+},
+_sysContact_obj = {
+ "sysContact", 4, 0,
+ NULL, &_sysUpTime_obj
+},
+_sysName_obj = {
+ "sysName", 5, 0,
+ NULL, &_sysContact_obj
+},
+_sysLocation_obj = {
+ "sysLocation", 6, 0,
+ NULL, &_sysName_obj
+},
+_sysServices_obj = {
+ "sysServices", 7, 0,
+ NULL, &_sysLocation_obj
+},
+_system_obj = {
+ "system", 1, 0,
+ &_sysServices_obj, NULL
+},
+_interfaces_obj = {
+ "interfaces", 2, 0,
+ &_ifTable_obj, &_system_obj
+},
+_at_obj = {
+ "at", 3, 0,
+ &_atTable_obj, &_interfaces_obj
+},
+_ip_obj = {
+ "ip", 4, 0,
+ &_ipNetToMediaTable_obj, &_at_obj
+},
+_icmp_obj = {
+ "icmp", 5, 0,
+ &_icmpOutAddrMaskReps_obj, &_ip_obj
+},
+_tcp_obj = {
+ "tcp", 6, 0,
+ &_tcpOutRsts_obj, &_icmp_obj
+},
+_udp_obj = {
+ "udp", 7, 0,
+ &_udpTable_obj, &_tcp_obj
+},
+_egp_obj = {
+ "egp", 8, 0,
+ &_egpAs_obj, &_udp_obj
+},
+_transmission_obj = {
+ "transmission", 10, 0,
+ NULL, &_egp_obj
+},
+_snmp_obj = {
+ "snmp", 11, 0,
+ &_snmpEnableAuthTraps_obj, &_transmission_obj
+},
+_usmMIBCompliances_obj = {
+ "usmMIBCompliances", 1, 0,
+ NULL, NULL
+},
+_usmMIBGroups_obj = {
+ "usmMIBGroups", 2, 0,
+ NULL, &_usmMIBCompliances_obj
+},
+_usmUserEngineID_obj = {
+ "usmUserEngineID", 1, 0,
+ NULL, NULL
+},
+_usmUserName_obj = {
+ "usmUserName", 2, 0,
+ NULL, &_usmUserEngineID_obj
+},
+_usmUserSecurityName_obj = {
+ "usmUserSecurityName", 3, 0,
+ NULL, &_usmUserName_obj
+},
+_usmUserCloneFrom_obj = {
+ "usmUserCloneFrom", 4, 0,
+ NULL, &_usmUserSecurityName_obj
+},
+_usmUserAuthProtocol_obj = {
+ "usmUserAuthProtocol", 5, 0,
+ NULL, &_usmUserCloneFrom_obj
+},
+_usmUserAuthKeyChange_obj = {
+ "usmUserAuthKeyChange", 6, 0,
+ NULL, &_usmUserAuthProtocol_obj
+},
+_usmUserOwnAuthKeyChange_obj = {
+ "usmUserOwnAuthKeyChange", 7, 0,
+ NULL, &_usmUserAuthKeyChange_obj
+},
+_usmUserPrivProtocol_obj = {
+ "usmUserPrivProtocol", 8, 0,
+ NULL, &_usmUserOwnAuthKeyChange_obj
+},
+_usmUserPrivKeyChange_obj = {
+ "usmUserPrivKeyChange", 9, 0,
+ NULL, &_usmUserPrivProtocol_obj
+},
+_usmUserOwnPrivKeyChange_obj = {
+ "usmUserOwnPrivKeyChange", 10, 0,
+ NULL, &_usmUserPrivKeyChange_obj
+},
+_usmUserPublic_obj = {
+ "usmUserPublic", 11, 0,
+ NULL, &_usmUserOwnPrivKeyChange_obj
+},
+_usmUserStorageType_obj = {
+ "usmUserStorageType", 12, 0,
+ NULL, &_usmUserPublic_obj
+},
+_usmUserStatus_obj = {
+ "usmUserStatus", 13, 0,
+ NULL, &_usmUserStorageType_obj
+},
+_usmUserEntry_obj = {
+ "usmUserEntry", 1, 0,
+ &_usmUserStatus_obj, NULL
+},
+_usmUserSpinLock_obj = {
+ "usmUserSpinLock", 1, 0,
+ NULL, NULL
+},
+_usmUserTable_obj = {
+ "usmUserTable", 2, 0,
+ &_usmUserEntry_obj, &_usmUserSpinLock_obj
+},
+_usmStatsUnsupportedSecLevels_obj = {
+ "usmStatsUnsupportedSecLevels", 1, 0,
+ NULL, NULL
+},
+_usmStatsNotInTimeWindows_obj = {
+ "usmStatsNotInTimeWindows", 2, 0,
+ NULL, &_usmStatsUnsupportedSecLevels_obj
+},
+_usmStatsUnknownUserNames_obj = {
+ "usmStatsUnknownUserNames", 3, 0,
+ NULL, &_usmStatsNotInTimeWindows_obj
+},
+_usmStatsUnknownEngineIDs_obj = {
+ "usmStatsUnknownEngineIDs", 4, 0,
+ NULL, &_usmStatsUnknownUserNames_obj
+},
+_usmStatsWrongDigests_obj = {
+ "usmStatsWrongDigests", 5, 0,
+ NULL, &_usmStatsUnknownEngineIDs_obj
+},
+_usmStatsDecryptionErrors_obj = {
+ "usmStatsDecryptionErrors", 6, 0,
+ NULL, &_usmStatsWrongDigests_obj
+},
+_usmStats_obj = {
+ "usmStats", 1, 0,
+ &_usmStatsDecryptionErrors_obj, NULL
+},
+_usmUser_obj = {
+ "usmUser", 2, 0,
+ &_usmUserTable_obj, &_usmStats_obj
+},
+_usmMIBObjects_obj = {
+ "usmMIBObjects", 1, 0,
+ &_usmUser_obj, NULL
+},
+_usmMIBConformance_obj = {
+ "usmMIBConformance", 2, 0,
+ &_usmMIBGroups_obj, &_usmMIBObjects_obj
+},
+_snmpMPDMIBCompliances_obj = {
+ "snmpMPDMIBCompliances", 1, 0,
+ NULL, NULL
+},
+_snmpMPDMIBGroups_obj = {
+ "snmpMPDMIBGroups", 2, 0,
+ NULL, &_snmpMPDMIBCompliances_obj
+},
+_snmpUnknownSecurityModels_obj = {
+ "snmpUnknownSecurityModels", 1, 0,
+ NULL, NULL
+},
+_snmpInvalidMsgs_obj = {
+ "snmpInvalidMsgs", 2, 0,
+ NULL, &_snmpUnknownSecurityModels_obj
+},
+_snmpUnknownPDUHandlers_obj = {
+ "snmpUnknownPDUHandlers", 3, 0,
+ NULL, &_snmpInvalidMsgs_obj
+},
+_snmpMPDStats_obj = {
+ "snmpMPDStats", 1, 0,
+ &_snmpUnknownPDUHandlers_obj, NULL
+},
+_snmpMPDAdmin_obj = {
+ "snmpMPDAdmin", 1, 0,
+ NULL, NULL
+},
+_snmpMPDMIBObjects_obj = {
+ "snmpMPDMIBObjects", 2, 0,
+ &_snmpMPDStats_obj, &_snmpMPDAdmin_obj
+},
+_snmpMPDMIBConformance_obj = {
+ "snmpMPDMIBConformance", 3, 0,
+ &_snmpMPDMIBGroups_obj, &_snmpMPDMIBObjects_obj
+},
+_snmpEngineID_obj = {
+ "snmpEngineID", 1, 0,
+ NULL, NULL
+},
+_snmpEngineBoots_obj = {
+ "snmpEngineBoots", 2, 0,
+ NULL, &_snmpEngineID_obj
+},
+_snmpEngineTime_obj = {
+ "snmpEngineTime", 3, 0,
+ NULL, &_snmpEngineBoots_obj
+},
+_snmpEngineMaxMessageSize_obj = {
+ "snmpEngineMaxMessageSize", 4, 0,
+ NULL, &_snmpEngineTime_obj
+},
+_snmpEngine_obj = {
+ "snmpEngine", 1, 0,
+ &_snmpEngineMaxMessageSize_obj, NULL
+},
+_snmpFrameworkAdmin_obj = {
+ "snmpFrameworkAdmin", 1, 0,
+ NULL, NULL
+},
+_snmpFrameworkMIBObjects_obj = {
+ "snmpFrameworkMIBObjects", 2, 0,
+ &_snmpEngine_obj, &_snmpFrameworkAdmin_obj
+},
+_snmpFrameworkMIBConformance_obj = {
+ "snmpFrameworkMIBConformance", 3, 0,
+ NULL, &_snmpFrameworkMIBObjects_obj
+},
+_snmpFrameworkMIB_obj = {
+ "snmpFrameworkMIB", 10, 0,
+ &_snmpFrameworkMIBConformance_obj, NULL
+},
+_snmpMPDMIB_obj = {
+ "snmpMPDMIB", 11, 0,
+ &_snmpMPDMIBConformance_obj, &_snmpFrameworkMIB_obj
+},
+_snmpUsmMIB_obj = {
+ "snmpUsmMIB", 15, 0,
+ &_usmMIBConformance_obj, &_snmpMPDMIB_obj
+},
+_snmpModules_obj = {
+ "snmpModules", 3, 0,
+ &_snmpUsmMIB_obj, NULL
+},
+_mib_obj = {
+ "mib", 1, 0,
+ &_snmp_obj, NULL
+},
+_directory_obj = {
+ "directory", 1, 0,
+ NULL, NULL
+},
+_mgmt_obj = {
+ "mgmt", 2, 0,
+ &_mib_obj, &_directory_obj
+},
+_experimental_obj = {
+ "experimental", 3, 0,
+ NULL, &_mgmt_obj
+},
+_private_obj = {
+ "private", 4, 0,
+ &_enterprises_obj, &_experimental_obj
+},
+_security_obj = {
+ "security", 5, 0,
+ NULL, &_private_obj
+},
+_snmpV2_obj = {
+ "snmpV2", 6, 0,
+ &_snmpModules_obj, &_security_obj
+},
+_internet_obj = {
+ "internet", 1, 0,
+ &_snmpV2_obj, NULL
+},
+_dod_obj = {
+ "dod", 6, 0,
+ &_internet_obj, NULL
+},
+_org_obj = {
+ "org", 3, 0,
+ &_dod_obj, NULL
+},
+_iso_obj = {
+ "iso", 1, 0,
+ &_org_obj, NULL
+},
+*mibroot = &_iso_obj;
diff --git a/freebsd/contrib/tcpdump/mpls.h b/freebsd/contrib/tcpdump/mpls.h
new file mode 100644
index 00000000..ae1c97e6
--- /dev/null
+++ b/freebsd/contrib/tcpdump/mpls.h
@@ -0,0 +1,41 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/mpls.h,v 1.1 2004-06-14 14:47:58 hannes Exp $ (LBL)
+ * Copyright (C) 2001 WIDE Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#define LABEL_MASK 0xfffff000
+#define LABEL_SHIFT 12
+#define EXP_MASK 0x00000e00
+#define EXP_SHIFT 9
+#define STACK_MASK 0x00000100
+#define STACK_SHIFT 8
+#define TTL_MASK 0x000000ff
+#define TTL_SHIFT 0
+
+#define MPLS_LABEL(x) (((x) & LABEL_MASK) >> LABEL_SHIFT)
+#define MPLS_EXP(x) (((x) & EXP_MASK) >> EXP_SHIFT)
+#define MPLS_STACK(x) (((x) & STACK_MASK) >> STACK_SHIFT)
+#define MPLS_TTL(x) (((x) & TTL_MASK) >> TTL_SHIFT)
diff --git a/freebsd/contrib/tcpdump/nameser.h b/freebsd/contrib/tcpdump/nameser.h
new file mode 100644
index 00000000..655afb42
--- /dev/null
+++ b/freebsd/contrib/tcpdump/nameser.h
@@ -0,0 +1,315 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/nameser.h,v 1.16 2006-11-10 03:18:21 guy Exp $ (LBL) */
+/*
+ * Copyright (c) 1983, 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)nameser.h 8.2 (Berkeley) 2/16/94
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#ifndef _NAMESER_H_
+#define _NAMESER_H_
+
+#include <rtems/bsd/sys/types.h>
+
+/*
+ * Define constants based on rfc883
+ */
+#define PACKETSZ 512 /* maximum packet size */
+#define MAXDNAME 256 /* maximum domain name */
+#define MAXCDNAME 255 /* maximum compressed domain name */
+#define MAXLABEL 63 /* maximum length of domain label */
+ /* Number of bytes of fixed size data in query structure */
+#define QFIXEDSZ 4
+ /* number of bytes of fixed size data in resource record */
+#define RRFIXEDSZ 10
+
+/*
+ * Internet nameserver port number
+ */
+#define NAMESERVER_PORT 53
+
+/*
+ * Port for multicast DNS; see
+ *
+ * http://files.multicastdns.org/draft-cheshire-dnsext-multicastdns.txt
+ *
+ * for the current mDNS spec.
+ */
+#define MULTICASTDNS_PORT 5353
+
+/*
+ * Currently defined opcodes
+ */
+#define QUERY 0x0 /* standard query */
+#define IQUERY 0x1 /* inverse query */
+#define STATUS 0x2 /* nameserver status query */
+#if 0
+#define xxx 0x3 /* 0x3 reserved */
+#endif
+ /* non standard - supports ALLOW_UPDATES stuff from Mike Schwartz */
+#define UPDATEA 0x9 /* add resource record */
+#define UPDATED 0xa /* delete a specific resource record */
+#define UPDATEDA 0xb /* delete all named resource record */
+#define UPDATEM 0xc /* modify a specific resource record */
+#define UPDATEMA 0xd /* modify all named resource record */
+
+#define ZONEINIT 0xe /* initial zone transfer */
+#define ZONEREF 0xf /* incremental zone referesh */
+
+/*
+ * Undefine various #defines from various System V-flavored OSes (Solaris,
+ * SINIX, HP-UX) so the compiler doesn't whine that we redefine them.
+ */
+#ifdef T_NULL
+#undef T_NULL
+#endif
+#ifdef T_OPT
+#undef T_OPT
+#endif
+#ifdef T_UNSPEC
+#undef T_UNSPEC
+#endif
+#ifdef NOERROR
+#undef NOERROR
+#endif
+
+/*
+ * Currently defined response codes
+ */
+#define NOERROR 0 /* no error */
+#define FORMERR 1 /* format error */
+#define SERVFAIL 2 /* server failure */
+#define NXDOMAIN 3 /* non existent domain */
+#define NOTIMP 4 /* not implemented */
+#define REFUSED 5 /* query refused */
+ /* non standard */
+#define NOCHANGE 0xf /* update failed to change db */
+
+/*
+ * Type values for resources and queries
+ */
+#define T_A 1 /* host address */
+#define T_NS 2 /* authoritative server */
+#define T_MD 3 /* mail destination */
+#define T_MF 4 /* mail forwarder */
+#define T_CNAME 5 /* connonical name */
+#define T_SOA 6 /* start of authority zone */
+#define T_MB 7 /* mailbox domain name */
+#define T_MG 8 /* mail group member */
+#define T_MR 9 /* mail rename name */
+#define T_NULL 10 /* null resource record */
+#define T_WKS 11 /* well known service */
+#define T_PTR 12 /* domain name pointer */
+#define T_HINFO 13 /* host information */
+#define T_MINFO 14 /* mailbox information */
+#define T_MX 15 /* mail routing information */
+#define T_TXT 16 /* text strings */
+#define T_RP 17 /* responsible person */
+#define T_AFSDB 18 /* AFS cell database */
+#define T_X25 19 /* X_25 calling address */
+#define T_ISDN 20 /* ISDN calling address */
+#define T_RT 21 /* router */
+#define T_NSAP 22 /* NSAP address */
+#define T_NSAP_PTR 23 /* reverse lookup for NSAP */
+#define T_SIG 24 /* security signature */
+#define T_KEY 25 /* security key */
+#define T_PX 26 /* X.400 mail mapping */
+#define T_GPOS 27 /* geographical position (withdrawn) */
+#define T_AAAA 28 /* IP6 Address */
+#define T_LOC 29 /* Location Information */
+#define T_NXT 30 /* Next Valid Name in Zone */
+#define T_EID 31 /* Endpoint identifier */
+#define T_NIMLOC 32 /* Nimrod locator */
+#define T_SRV 33 /* Server selection */
+#define T_ATMA 34 /* ATM Address */
+#define T_NAPTR 35 /* Naming Authority PoinTeR */
+#define T_KX 36 /* Key Exchanger */
+#define T_CERT 37 /* Certificates in the DNS */
+#define T_A6 38 /* IP6 address */
+#define T_DNAME 39 /* non-terminal redirection */
+#define T_SINK 40 /* unknown */
+#define T_OPT 41 /* EDNS0 option (meta-RR) */
+#define T_APL 42 /* lists of address prefixes */
+#define T_DS 43 /* Delegation Signer */
+#define T_SSHFP 44 /* SSH Fingerprint */
+#define T_IPSECKEY 45 /* IPsec keying material */
+#define T_RRSIG 46 /* new security signature */
+#define T_NSEC 47 /* provable insecure information */
+#define T_DNSKEY 48 /* new security key */
+ /* non standard */
+#define T_SPF 99 /* sender policy framework */
+#define T_UINFO 100 /* user (finger) information */
+#define T_UID 101 /* user ID */
+#define T_GID 102 /* group ID */
+#define T_UNSPEC 103 /* Unspecified format (binary data) */
+#define T_UNSPECA 104 /* "unspecified ascii". Ugly MIT hack */
+ /* Query type values which do not appear in resource records */
+#define T_TKEY 249 /* Transaction Key [RFC2930] */
+#define T_TSIG 250 /* Transaction Signature [RFC2845] */
+#define T_IXFR 251 /* incremental transfer [RFC1995] */
+#define T_AXFR 252 /* transfer zone of authority */
+#define T_MAILB 253 /* transfer mailbox records */
+#define T_MAILA 254 /* transfer mail agent records */
+#define T_ANY 255 /* wildcard match */
+
+/*
+ * Values for class field
+ */
+
+#define C_IN 1 /* the arpa internet */
+#define C_CHAOS 3 /* for chaos net (MIT) */
+#define C_HS 4 /* for Hesiod name server (MIT) (XXX) */
+ /* Query class values which do not appear in resource records */
+#define C_ANY 255 /* wildcard match */
+#define C_QU 0x8000 /* mDNS QU flag in queries */
+#define C_CACHE_FLUSH 0x8000 /* mDNS cache flush flag in replies */
+
+/*
+ * Status return codes for T_UNSPEC conversion routines
+ */
+#define CONV_SUCCESS 0
+#define CONV_OVERFLOW -1
+#define CONV_BADFMT -2
+#define CONV_BADCKSUM -3
+#define CONV_BADBUFLEN -4
+
+/*
+ * Structure for query header.
+ */
+typedef struct {
+ u_int16_t id; /* query identification number */
+ u_int8_t flags1; /* first byte of flags */
+ u_int8_t flags2; /* second byte of flags */
+ u_int16_t qdcount; /* number of question entries */
+ u_int16_t ancount; /* number of answer entries */
+ u_int16_t nscount; /* number of authority entries */
+ u_int16_t arcount; /* number of resource entries */
+} HEADER;
+
+/*
+ * Macros for subfields of flag fields.
+ */
+#define DNS_QR(np) ((np)->flags1 & 0x80) /* response flag */
+#define DNS_OPCODE(np) ((((np)->flags1) >> 3) & 0xF) /* purpose of message */
+#define DNS_AA(np) ((np)->flags1 & 0x04) /* authoritative answer */
+#define DNS_TC(np) ((np)->flags1 & 0x02) /* truncated message */
+#define DNS_RD(np) ((np)->flags1 & 0x01) /* recursion desired */
+
+#define DNS_RA(np) ((np)->flags2 & 0x80) /* recursion available */
+#define DNS_AD(np) ((np)->flags2 & 0x20) /* authentic data from named */
+#define DNS_CD(np) ((np)->flags2 & 0x10) /* checking disabled by resolver */
+#define DNS_RCODE(np) ((np)->flags2 & 0xF) /* response code */
+
+/*
+ * Defines for handling compressed domain names, EDNS0 labels, etc.
+ */
+#define INDIR_MASK 0xc0 /* 11.... */
+#define EDNS0_MASK 0x40 /* 01.... */
+# define EDNS0_ELT_BITLABEL 0x01
+
+/*
+ * Structure for passing resource records around.
+ */
+struct rrec {
+ int16_t r_zone; /* zone number */
+ int16_t r_class; /* class number */
+ int16_t r_type; /* type number */
+ u_int32_t r_ttl; /* time to live */
+ int r_size; /* size of data area */
+ char *r_data; /* pointer to data */
+};
+
+/*
+ * Inline versions of get/put short/long. Pointer is advanced.
+ * We also assume that a "u_int16_t" holds 2 "chars"
+ * and that a "u_int32_t" holds 4 "chars".
+ *
+ * These macros demonstrate the property of C whereby it can be
+ * portable or it can be elegant but never both.
+ */
+#define GETSHORT(s, cp) { \
+ register u_char *t_cp = (u_char *)(cp); \
+ (s) = ((u_int16_t)t_cp[0] << 8) | (u_int16_t)t_cp[1]; \
+ (cp) += 2; \
+}
+
+#define GETLONG(l, cp) { \
+ register u_char *t_cp = (u_char *)(cp); \
+ (l) = (((u_int32_t)t_cp[0]) << 24) \
+ | (((u_int32_t)t_cp[1]) << 16) \
+ | (((u_int32_t)t_cp[2]) << 8) \
+ | (((u_int32_t)t_cp[3])); \
+ (cp) += 4; \
+}
+
+#define PUTSHORT(s, cp) { \
+ register u_int16_t t_s = (u_int16_t)(s); \
+ register u_char *t_cp = (u_char *)(cp); \
+ *t_cp++ = t_s >> 8; \
+ *t_cp = t_s; \
+ (cp) += 2; \
+}
+
+/*
+ * Warning: PUTLONG --no-longer-- destroys its first argument. if you
+ * were depending on this "feature", you will lose.
+ */
+#define PUTLONG(l, cp) { \
+ register u_int32_t t_l = (u_int32_t)(l); \
+ register u_char *t_cp = (u_char *)(cp); \
+ *t_cp++ = t_l >> 24; \
+ *t_cp++ = t_l >> 16; \
+ *t_cp++ = t_l >> 8; \
+ *t_cp = t_l; \
+ (cp) += 4; \
+}
+
+#endif /* !_NAMESER_H_ */
diff --git a/freebsd/contrib/tcpdump/netbios.h b/freebsd/contrib/tcpdump/netbios.h
new file mode 100644
index 00000000..d3e2725f
--- /dev/null
+++ b/freebsd/contrib/tcpdump/netbios.h
@@ -0,0 +1,16 @@
+/*
+ * NETBIOS protocol formats
+ *
+ * @(#) $Header: /tcpdump/master/tcpdump/netbios.h,v 1.3 2002-12-11 07:13:55 guy Exp $
+ */
+
+struct p8022Hdr {
+ u_char dsap;
+ u_char ssap;
+ u_char flags;
+};
+
+#define p8022Size 3 /* min 802.2 header size */
+
+#define UI 0x03 /* 802.2 flags */
+
diff --git a/freebsd/contrib/tcpdump/netdissect.h b/freebsd/contrib/tcpdump/netdissect.h
new file mode 100644
index 00000000..d201d8c3
--- /dev/null
+++ b/freebsd/contrib/tcpdump/netdissect.h
@@ -0,0 +1,515 @@
+/*
+ * Copyright (c) 1988-1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Copyright (c) 1998-2012 Michael Richardson <mcr@tcpdump.org>
+ * The TCPDUMP project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /tcpdump/master/tcpdump/netdissect.h,v 1.27 2008-08-16 11:36:20 hannes Exp $ (LBL)
+ */
+
+#ifndef netdissect_h
+#define netdissect_h
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+#include <rtems/bsd/sys/types.h>
+
+#ifndef HAVE___ATTRIBUTE__
+#define __attribute__(x)
+#endif
+
+/* snprintf et al */
+
+#include <stdarg.h>
+
+#if !defined(HAVE_SNPRINTF)
+int snprintf (char *str, size_t sz, const char *format, ...)
+ __attribute__ ((format (printf, 3, 4)));
+#endif
+
+#if !defined(HAVE_VSNPRINTF)
+int vsnprintf (char *str, size_t sz, const char *format, va_list ap)
+ __attribute__((format (printf, 3, 0)));
+#endif
+
+#ifndef HAVE_STRLCAT
+extern size_t strlcat (char *, const char *, size_t);
+#endif
+#ifndef HAVE_STRLCPY
+extern size_t strlcpy (char *, const char *, size_t);
+#endif
+
+#ifndef HAVE_STRDUP
+extern char *strdup (const char *str);
+#endif
+
+#ifndef HAVE_STRSEP
+extern char *strsep(char **, const char *);
+#endif
+
+struct tok {
+ int v; /* value */
+ const char *s; /* string */
+};
+
+#define TOKBUFSIZE 128
+extern const char *tok2strbuf(const struct tok *, const char *, int,
+ char *buf, size_t bufsize);
+
+/* tok2str is deprecated */
+extern const char *tok2str(const struct tok *, const char *, int);
+extern char *bittok2str(const struct tok *, const char *, int);
+extern char *bittok2str_nosep(const struct tok *, const char *, int);
+
+
+typedef struct netdissect_options netdissect_options;
+
+struct netdissect_options {
+ int ndo_aflag; /* translate network and broadcast addresses */
+ int ndo_bflag; /* print 4 byte ASes in ASDOT notation */
+ int ndo_eflag; /* print ethernet header */
+ int ndo_fflag; /* don't translate "foreign" IP address */
+ int ndo_Kflag; /* don't check TCP checksums */
+ int ndo_nflag; /* leave addresses as numbers */
+ int ndo_Nflag; /* remove domains from printed host names */
+ int ndo_qflag; /* quick (shorter) output */
+ int ndo_Rflag; /* print sequence # field in AH/ESP*/
+ int ndo_sflag; /* use the libsmi to translate OIDs */
+ int ndo_Sflag; /* print raw TCP sequence numbers */
+ int ndo_tflag; /* print packet arrival time */
+ int ndo_Uflag; /* "unbuffered" output of dump files */
+ int ndo_uflag; /* Print undecoded NFS handles */
+ int ndo_vflag; /* verbose */
+ int ndo_xflag; /* print packet in hex */
+ int ndo_Xflag; /* print packet in hex/ascii */
+ int ndo_Aflag; /* print packet only in ascii observing TAB,
+ * LF, CR and SPACE as graphical chars
+ */
+ int ndo_Bflag; /* buffer size */
+ int ndo_Iflag; /* rfmon (monitor) mode */
+ int ndo_Oflag; /* run filter code optimizer */
+ int ndo_dlt; /* if != -1, ask libpcap for the DLT it names*/
+ int ndo_jflag; /* packet time stamp source */
+ int ndo_pflag; /* don't go promiscuous */
+
+ int ndo_Cflag; /* rotate dump files after this many bytes */
+ int ndo_Cflag_count; /* Keep track of which file number we're writing */
+ int ndo_Gflag; /* rotate dump files after this many seconds */
+ int ndo_Gflag_count; /* number of files created with Gflag rotation */
+ time_t ndo_Gflag_time; /* The last time_t the dump file was rotated. */
+ int ndo_Wflag; /* recycle output files after this number of files */
+ int ndo_WflagChars;
+ int ndo_Hflag; /* dissect 802.11s draft mesh standard */
+ int ndo_suppress_default_print; /* don't use default_print() for unknown packet types */
+ const char *ndo_dltname;
+
+ char *ndo_espsecret;
+ struct sa_list *ndo_sa_list_head; /* used by print-esp.c */
+ struct sa_list *ndo_sa_default;
+
+ char *ndo_sigsecret; /* Signature verification secret key */
+
+ struct esp_algorithm *ndo_espsecret_xform; /* cache of decoded */
+ char *ndo_espsecret_key;
+
+ int ndo_packettype; /* as specified by -T */
+
+ char *ndo_program_name; /*used to generate self-identifying messages */
+
+ int32_t ndo_thiszone; /* seconds offset from gmt to local time */
+
+ int ndo_snaplen;
+
+ /*global pointers to beginning and end of current packet (during printing) */
+ const u_char *ndo_packetp;
+ const u_char *ndo_snapend;
+
+ /* bookkeeping for ^T output */
+ int ndo_infodelay;
+
+ /* pointer to void function to output stuff */
+ void (*ndo_default_print)(netdissect_options *,
+ register const u_char *bp, register u_int length);
+ void (*ndo_info)(netdissect_options *, int verbose);
+
+ int (*ndo_printf)(netdissect_options *,
+ const char *fmt, ...)
+#ifdef __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS
+ __attribute__ ((format (printf, 2, 3)))
+#endif
+ ;
+ void (*ndo_error)(netdissect_options *,
+ const char *fmt, ...)
+#ifdef __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS
+ __attribute__ ((noreturn, format (printf, 2, 3)))
+#endif
+ ;
+ void (*ndo_warning)(netdissect_options *,
+ const char *fmt, ...)
+#ifdef __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS
+ __attribute__ ((format (printf, 2, 3)))
+#endif
+ ;
+};
+
+#define PT_VAT 1 /* Visual Audio Tool */
+#define PT_WB 2 /* distributed White Board */
+#define PT_RPC 3 /* Remote Procedure Call */
+#define PT_RTP 4 /* Real-Time Applications protocol */
+#define PT_RTCP 5 /* Real-Time Applications control protocol */
+#define PT_SNMP 6 /* Simple Network Management Protocol */
+#define PT_CNFP 7 /* Cisco NetFlow protocol */
+#define PT_TFTP 8 /* trivial file transfer protocol */
+#define PT_AODV 9 /* Ad-hoc On-demand Distance Vector Protocol */
+#define PT_CARP 10 /* Common Address Redundancy Protocol */
+#define PT_RADIUS 11 /* RADIUS authentication Protocol */
+#define PT_ZMTP1 12 /* ZeroMQ Message Transport Protocol 1.0 */
+#define PT_VXLAN 13 /* Virtual eXtensible Local Area Network */
+
+#ifndef min
+#define min(a,b) ((a)>(b)?(b):(a))
+#endif
+#ifndef max
+#define max(a,b) ((b)>(a)?(b):(a))
+#endif
+
+/*
+ * Maximum snapshot length. This should be enough to capture the full
+ * packet on most network interfaces.
+ *
+ * XXX - could it be larger? If so, should it? Some applications might
+ * use the snapshot length in a savefile header to control the size of
+ * the buffer they allocate, so a size of, say, 2^31-1 might not work
+ * well.
+ */
+#define MAXIMUM_SNAPLEN 65535
+
+/*
+ * The default snapshot length is the maximum.
+ */
+#define DEFAULT_SNAPLEN MAXIMUM_SNAPLEN
+
+#define ESRC(ep) ((ep)->ether_shost)
+#define EDST(ep) ((ep)->ether_dhost)
+
+#ifndef NTOHL
+#define NTOHL(x) (x) = ntohl(x)
+#define NTOHS(x) (x) = ntohs(x)
+#define HTONL(x) (x) = htonl(x)
+#define HTONS(x) (x) = htons(x)
+#endif
+
+/*
+ * True if "l" bytes of "var" were captured.
+ *
+ * The "ndo->ndo_snapend - (l) <= ndo->ndo_snapend" checks to make sure
+ * "l" isn't so large that "ndo->ndo_snapend - (l)" underflows.
+ *
+ * The check is for <= rather than < because "l" might be 0.
+ */
+#define ND_TTEST2(var, l) (ndo->ndo_snapend - (l) <= ndo->ndo_snapend && \
+ (const u_char *)&(var) <= ndo->ndo_snapend - (l))
+
+/* True if "var" was captured */
+#define ND_TTEST(var) ND_TTEST2(var, sizeof(var))
+
+/* Bail if "l" bytes of "var" were not captured */
+#define ND_TCHECK2(var, l) if (!ND_TTEST2(var, l)) goto trunc
+
+/* Bail if "var" was not captured */
+#define ND_TCHECK(var) ND_TCHECK2(var, sizeof(var))
+
+#define ND_PRINT(STUFF) (*ndo->ndo_printf)STUFF
+#define ND_DEFAULTPRINT(ap, length) (*ndo->ndo_default_print)(ndo, ap, length)
+
+#if 0
+extern void ts_print(netdissect_options *ipdo,
+ const struct timeval *);
+extern void relts_print(int);
+#endif
+
+extern int fn_print(const u_char *, const u_char *);
+extern int fn_printn(const u_char *, u_int, const u_char *);
+extern const char *tok2str(const struct tok *, const char *, int);
+
+extern void wrapup(int);
+
+#if 0
+extern char *read_infile(netdissect_options *, char *);
+extern char *copy_argv(netdissect_options *, char **);
+#endif
+
+extern void safeputchar(int);
+extern void safeputs(const char *, int);
+
+#define PLURAL_SUFFIX(n) \
+ (((n) != 1) ? "s" : "")
+
+#if 0
+extern const char *isonsap_string(netdissect_options *, const u_char *);
+extern const char *protoid_string(netdissect_options *, const u_char *);
+extern const char *dnname_string(netdissect_options *, u_short);
+extern const char *dnnum_string(netdissect_options *, u_short);
+#endif
+
+/* The printer routines. */
+
+#include <pcap.h>
+
+typedef u_int (*if_ndo_printer)(struct netdissect_options *ndo,
+ const struct pcap_pkthdr *, const u_char *);
+typedef u_int (*if_printer)(const struct pcap_pkthdr *, const u_char *);
+
+extern if_ndo_printer lookup_ndo_printer(int);
+extern if_printer lookup_printer(int);
+
+extern void eap_print(netdissect_options *,const u_char *, u_int);
+extern int esp_print(netdissect_options *,
+ register const u_char *bp, int len, register const u_char *bp2,
+ int *nhdr, int *padlen);
+extern void arp_print(netdissect_options *,const u_char *, u_int, u_int);
+extern void tipc_print(netdissect_options *, const u_char *, u_int, u_int);
+extern void msnlb_print(netdissect_options *, const u_char *, u_int);
+extern void icmp6_print(netdissect_options *ndo, const u_char *,
+ u_int, const u_char *, int);
+extern void isakmp_print(netdissect_options *,const u_char *,
+ u_int, const u_char *);
+extern void isakmp_rfc3948_print(netdissect_options *,const u_char *,
+ u_int, const u_char *);
+extern void ip_print(netdissect_options *,const u_char *, u_int);
+extern void ip_print_inner(netdissect_options *ndo,
+ const u_char *bp, u_int length, u_int nh,
+ const u_char *bp2);
+extern void rrcp_print(netdissect_options *,const u_char *, u_int);
+
+extern void ether_print(netdissect_options *,
+ const u_char *, u_int, u_int,
+ void (*)(netdissect_options *, const u_char *),
+ const u_char *);
+
+extern u_int ether_if_print(netdissect_options *,
+ const struct pcap_pkthdr *,const u_char *);
+extern u_int netanalyzer_if_print(netdissect_options *,
+ const struct pcap_pkthdr *,const u_char *);
+extern u_int netanalyzer_transparent_if_print(netdissect_options *,
+ const struct pcap_pkthdr *,
+ const u_char *);
+
+extern int ethertype_print(netdissect_options *,u_short, const u_char *,
+ u_int, u_int);
+
+/* stuff that has not yet been rototiled */
+#if 0
+extern void ascii_print(netdissect_options *,u_int);
+extern void hex_and_ascii_print_with_offset(netdissect_options *,const char *,
+ u_int, u_int);
+extern void hex_and_ascii_print(netdissect_options *,const char *, u_int);
+extern void hex_print_with_offset(netdissect_options *,const char *,
+ u_int, u_int);
+extern void hex_print(netdissect_options *,const char *, u_int);
+extern void telnet_print(netdissect_options *,const u_char *, u_int);
+extern int llc_print(netdissect_options *,
+ const u_char *, u_int, u_int, const u_char *,
+ const u_char *, u_short *);
+extern void aarp_print(netdissect_options *,const u_char *, u_int);
+extern void atalk_print(netdissect_options *,const u_char *, u_int);
+extern void atm_if_print(u_char *,const struct pcap_pkthdr *, const u_char *);
+extern void bootp_print(netdissect_options *,const u_char *,
+ u_int, u_short, u_short);
+extern void bgp_print(netdissect_options *,const u_char *, int);
+extern void bxxp_print(netdissect_options *,const u_char *, u_int);
+extern void chdlc_if_print(u_char *user, const struct pcap_pkthdr *h,
+ register const u_char *p);
+extern void chdlc_print(netdissect_options *ndo,
+ register const u_char *p, u_int length, u_int caplen);
+extern void cisco_autorp_print(netdissect_options *,
+ const u_char *, u_int);
+extern void cnfp_print(netdissect_options *,const u_char *cp,
+ u_int len, const u_char *bp);
+extern void decnet_print(netdissect_options *,const u_char *,
+ u_int, u_int);
+extern void default_print(netdissect_options *,const u_char *, u_int);
+extern void dvmrp_print(netdissect_options *,const u_char *, u_int);
+extern void egp_print(netdissect_options *,const u_char *, u_int,
+ const u_char *);
+
+extern void arcnet_if_print(u_char*,const struct pcap_pkthdr *,const u_char *);
+extern void token_if_print(u_char *,const struct pcap_pkthdr *,const u_char *);
+extern void fddi_if_print(u_char *,const struct pcap_pkthdr *, const u_char *);
+
+extern void gre_print(netdissect_options *,const u_char *, u_int);
+extern void icmp_print(netdissect_options *,const u_char *, u_int,
+ const u_char *);
+extern void hsrp_print(netdissect_options *ndo,
+ register const u_char *bp, register u_int len);
+extern void ieee802_11_if_print(u_char *,const struct pcap_pkthdr *, const u_char *);
+extern void igmp_print(netdissect_options *,
+ register const u_char *, u_int);
+extern void igrp_print(netdissect_options *,const u_char *, u_int,
+ const u_char *);
+extern int nextproto4_cksum(const struct ip *, const u_int8_t *, u_int, u_int);
+extern void ipN_print(netdissect_options *,const u_char *, u_int);
+extern void ipx_print(netdissect_options *,const u_char *, u_int);
+extern void isoclns_print(netdissect_options *,const u_char *,
+ u_int, u_int, const u_char *, const u_char *);
+extern void krb_print(netdissect_options *,const u_char *, u_int);
+extern void llap_print(netdissect_options *,const u_char *, u_int);
+extern const char *linkaddr_string(netdissect_options *ndo,
+ const u_char *ep, const unsigned int len);
+extern void ltalk_if_print(netdissect_options *ndo,
+ u_char *user, const struct pcap_pkthdr *h,
+ const u_char *p);
+extern void mpls_print(netdissect_options *ndo,
+ const u_char *bp, u_int length);
+extern void msdp_print(netdissect_options *ndo,
+ const unsigned char *sp, u_int length);
+extern void nfsreply_print(netdissect_options *,const u_char *,
+ u_int, const u_char *);
+extern void nfsreq_print(netdissect_options *,const u_char *,
+ u_int, const u_char *);
+extern void ns_print(netdissect_options *,const u_char *, u_int);
+extern void ntp_print(netdissect_options *,const u_char *, u_int);
+extern void null_if_print(u_char *,const struct pcap_pkthdr *, const u_char *);
+extern void ospf_print(netdissect_options *,const u_char *,
+ u_int, const u_char *);
+extern void pimv1_print(netdissect_options *,const u_char *, u_int);
+extern void mobile_print(netdissect_options *,const u_char *, u_int);
+extern void pim_print(netdissect_options *,const u_char *, u_int, u_int);
+extern void pppoe_if_print(u_char *,const struct pcap_pkthdr *, const u_char *);
+extern void pppoe_print(netdissect_options *,const u_char *, u_int);
+extern void ppp_print(netdissect_options *,
+ register const u_char *, u_int);
+
+extern void ppp_if_print(u_char *,const struct pcap_pkthdr *, const u_char *);
+extern void ppp_hdlc_if_print(u_char *,
+ const struct pcap_pkthdr *, const u_char *);
+extern void ppp_bsdos_if_print(u_char *,
+ const struct pcap_pkthdr *, const u_char *);
+
+extern int vjc_print(netdissect_options *,register const char *,
+ register u_int, u_short);
+
+extern void raw_if_print(u_char *,
+ const struct pcap_pkthdr *, const u_char *);
+
+extern void rip_print(netdissect_options *,const u_char *, u_int);
+extern void rpki_rtr_print(netdissect_options *,const u_char *, u_int);
+
+extern void sctp_print(netdissect_options *ndo,
+ const u_char *bp, const u_char *bp2,
+ u_int sctpPacketLength);
+
+extern void sl_if_print(u_char *,const struct pcap_pkthdr *, const u_char *);
+
+extern void lane_if_print(u_char *,const struct pcap_pkthdr *,const u_char *);
+extern void cip_if_print(u_char *,const struct pcap_pkthdr *,const u_char *);
+extern void sl_bsdos_if_print(u_char *,
+ const struct pcap_pkthdr *, const u_char *);
+extern void sll_if_print(u_char *,
+ const struct pcap_pkthdr *, const u_char *);
+
+extern void snmp_print(netdissect_options *,const u_char *, u_int);
+extern void sunrpcrequest_print(netdissect_options *,const u_char *,
+ u_int, const u_char *);
+extern void tcp_print(netdissect_options *,const u_char *, u_int,
+ const u_char *, int);
+extern void tftp_print(netdissect_options *,const u_char *, u_int);
+extern void timed_print(netdissect_options *,const u_char *, u_int);
+extern void udp_print(netdissect_options *,const u_char *, u_int,
+ const u_char *, int);
+extern void wb_print(netdissect_options *,const void *, u_int);
+extern int ah_print(netdissect_options *,register const u_char *,
+ register const u_char *);
+extern void esp_print_decodesecret(netdissect_options *ndo);
+extern int ipcomp_print(netdissect_options *,register const u_char *,
+ register const u_char *, int *);
+extern void rx_print(netdissect_options *,register const u_char *,
+ int, int, int, u_char *);
+extern void netbeui_print(netdissect_options *,u_short,
+ const u_char *, int);
+extern void ipx_netbios_print(netdissect_options *,const u_char *, u_int);
+extern void nbt_tcp_print(netdissect_options *,const u_char *, int);
+extern void nbt_udp137_print(netdissect_options *,
+ const u_char *data, int);
+extern void nbt_udp138_print(netdissect_options *,
+ const u_char *data, int);
+extern char *smb_errstr(netdissect_options *,int, int);
+extern const char *nt_errstr(netdissect_options *, u_int32_t);
+extern void print_data(netdissect_options *,const unsigned char *, int);
+extern void l2tp_print(netdissect_options *,const u_char *, u_int);
+extern void lcp_print(netdissect_options *,const u_char *, u_int);
+extern void vrrp_print(netdissect_options *,const u_char *bp,
+ u_int len, int ttl);
+extern void carp_print(netdissect_options *,const u_char *bp,
+ u_int len, int ttl);
+extern void cdp_print(netdissect_options *,const u_char *,
+ u_int, u_int, const u_char *, const u_char *);
+extern void stp_print(netdissect_options *,const u_char *p, u_int length);
+extern void radius_print(netdissect_options *,const u_char *, u_int);
+extern void lwres_print(netdissect_options *,const u_char *, u_int);
+extern void pptp_print(netdissect_options *,const u_char *, u_int);
+#endif
+
+extern u_int ipnet_if_print(netdissect_options *,const struct pcap_pkthdr *, const u_char *);
+extern u_int ppi_if_print(netdissect_options *,const struct pcap_pkthdr *, const u_char *);
+
+extern u_int ieee802_15_4_if_print(netdissect_options *,const struct pcap_pkthdr *, const u_char *);
+
+#ifdef INET6
+extern void ip6_print(netdissect_options *,const u_char *, u_int);
+#if 0
+extern void ip6_opt_print(netdissect_options *,const u_char *, int);
+extern int nextproto6_cksum(const struct ip6_hdr *, const u_int8_t *, u_int, u_int);
+extern int hbhopt_print(netdissect_options *,const u_char *);
+extern int dstopt_print(netdissect_options *,const u_char *);
+extern int frag6_print(netdissect_options *,const u_char *,
+ const u_char *);
+extern void icmp6_print(netdissect_options *,const u_char *,
+ const u_char *);
+extern void ripng_print(netdissect_options *,const u_char *, int);
+extern int rt6_print(netdissect_options *,const u_char *, const u_char *);
+extern void ospf6_print(netdissect_options *,const u_char *, u_int);
+extern void dhcp6_print(netdissect_options *,const u_char *,
+ u_int, u_int16_t, u_int16_t);
+
+extern void zephyr_print(netdissect_options * ndo,
+ const u_char *cp, int length);
+#endif /* 0 */
+
+#endif /*INET6*/
+
+#if 0
+struct cksum_vec {
+ const u_int8_t *ptr;
+ int len;
+};
+extern u_int16_t in_cksum(const struct cksum_vec *, int);
+extern u_int16_t in_cksum_shouldbe(u_int16_t, u_int16_t);
+#endif
+
+extern void esp_print_decodesecret(netdissect_options *ndo);
+extern int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
+ int initiator,
+ u_char spii[8], u_char spir[8],
+ u_char *buf, u_char *end);
+
+
+#endif /* netdissect_h */
diff --git a/freebsd/contrib/tcpdump/nfs.h b/freebsd/contrib/tcpdump/nfs.h
new file mode 100644
index 00000000..b35e2cd5
--- /dev/null
+++ b/freebsd/contrib/tcpdump/nfs.h
@@ -0,0 +1,440 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/nfs.h,v 1.9 2007-11-18 03:24:38 guy Exp $ (LBL) */
+/* NetBSD: nfs.h,v 1.1 1996/05/23 22:49:53 fvdl Exp */
+
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Rick Macklem at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ * @(#)nfsproto.h 8.2 (Berkeley) 3/30/95
+ */
+
+/*
+ * nfs definitions as per the Version 2 and 3 specs
+ */
+
+/*
+ * Constants as defined in the Sun NFS Version 2 and 3 specs.
+ * "NFS: Network File System Protocol Specification" RFC1094
+ * and in the "NFS: Network File System Version 3 Protocol
+ * Specification"
+ */
+
+#define NFS_PORT 2049
+#define NFS_PROG 100003
+#define NFS_VER2 2
+#define NFS_VER3 3
+#define NFS_V2MAXDATA 8192
+#define NFS_MAXDGRAMDATA 16384
+#define NFS_MAXDATA 32768
+#define NFS_MAXPATHLEN 1024
+#define NFS_MAXNAMLEN 255
+#define NFS_MAXPKTHDR 404
+#define NFS_MAXPACKET (NFS_MAXPKTHDR + NFS_MAXDATA)
+#define NFS_MINPACKET 20
+#define NFS_FABLKSIZE 512 /* Size in bytes of a block wrt fa_blocks */
+
+/* Stat numbers for rpc returns (version 2 and 3) */
+#define NFS_OK 0
+#define NFSERR_PERM 1
+#define NFSERR_NOENT 2
+#define NFSERR_IO 5
+#define NFSERR_NXIO 6
+#define NFSERR_ACCES 13
+#define NFSERR_EXIST 17
+#define NFSERR_XDEV 18 /* Version 3 only */
+#define NFSERR_NODEV 19
+#define NFSERR_NOTDIR 20
+#define NFSERR_ISDIR 21
+#define NFSERR_INVAL 22 /* Version 3 only */
+#define NFSERR_FBIG 27
+#define NFSERR_NOSPC 28
+#define NFSERR_ROFS 30
+#define NFSERR_MLINK 31 /* Version 3 only */
+#define NFSERR_NAMETOL 63
+#define NFSERR_NOTEMPTY 66
+#define NFSERR_DQUOT 69
+#define NFSERR_STALE 70
+#define NFSERR_REMOTE 71 /* Version 3 only */
+#define NFSERR_WFLUSH 99 /* Version 2 only */
+#define NFSERR_BADHANDLE 10001 /* The rest Version 3 only */
+#define NFSERR_NOT_SYNC 10002
+#define NFSERR_BAD_COOKIE 10003
+#define NFSERR_NOTSUPP 10004
+#define NFSERR_TOOSMALL 10005
+#define NFSERR_SERVERFAULT 10006
+#define NFSERR_BADTYPE 10007
+#define NFSERR_JUKEBOX 10008
+#define NFSERR_TRYLATER NFSERR_JUKEBOX
+#define NFSERR_STALEWRITEVERF 30001 /* Fake return for nfs_commit() */
+
+#define NFSERR_RETVOID 0x20000000 /* Return void, not error */
+#define NFSERR_AUTHERR 0x40000000 /* Mark an authentication error */
+#define NFSERR_RETERR 0x80000000 /* Mark an error return for V3 */
+
+/* Sizes in bytes of various nfs rpc components */
+#define NFSX_UNSIGNED 4
+
+/* specific to NFS Version 2 */
+#define NFSX_V2FH 32
+#define NFSX_V2FATTR 68
+#define NFSX_V2SATTR 32
+#define NFSX_V2COOKIE 4
+#define NFSX_V2STATFS 20
+
+/* specific to NFS Version 3 */
+#if 0
+#define NFSX_V3FH (sizeof (fhandle_t)) /* size this server uses */
+#endif
+#define NFSX_V3FHMAX 64 /* max. allowed by protocol */
+#define NFSX_V3FATTR 84
+#define NFSX_V3SATTR 60 /* max. all fields filled in */
+#define NFSX_V3SRVSATTR (sizeof (struct nfsv3_sattr))
+#define NFSX_V3POSTOPATTR (NFSX_V3FATTR + NFSX_UNSIGNED)
+#define NFSX_V3WCCDATA (NFSX_V3POSTOPATTR + 8 * NFSX_UNSIGNED)
+#define NFSX_V3COOKIEVERF 8
+#define NFSX_V3WRITEVERF 8
+#define NFSX_V3CREATEVERF 8
+#define NFSX_V3STATFS 52
+#define NFSX_V3FSINFO 48
+#define NFSX_V3PATHCONF 24
+
+/* variants for both versions */
+#define NFSX_FH(v3) ((v3) ? (NFSX_V3FHMAX + NFSX_UNSIGNED) : \
+ NFSX_V2FH)
+#define NFSX_SRVFH(v3) ((v3) ? NFSX_V3FH : NFSX_V2FH)
+#define NFSX_FATTR(v3) ((v3) ? NFSX_V3FATTR : NFSX_V2FATTR)
+#define NFSX_PREOPATTR(v3) ((v3) ? (7 * NFSX_UNSIGNED) : 0)
+#define NFSX_POSTOPATTR(v3) ((v3) ? (NFSX_V3FATTR + NFSX_UNSIGNED) : 0)
+#define NFSX_POSTOPORFATTR(v3) ((v3) ? (NFSX_V3FATTR + NFSX_UNSIGNED) : \
+ NFSX_V2FATTR)
+#define NFSX_WCCDATA(v3) ((v3) ? NFSX_V3WCCDATA : 0)
+#define NFSX_WCCORFATTR(v3) ((v3) ? NFSX_V3WCCDATA : NFSX_V2FATTR)
+#define NFSX_SATTR(v3) ((v3) ? NFSX_V3SATTR : NFSX_V2SATTR)
+#define NFSX_COOKIEVERF(v3) ((v3) ? NFSX_V3COOKIEVERF : 0)
+#define NFSX_WRITEVERF(v3) ((v3) ? NFSX_V3WRITEVERF : 0)
+#define NFSX_READDIR(v3) ((v3) ? (5 * NFSX_UNSIGNED) : \
+ (2 * NFSX_UNSIGNED))
+#define NFSX_STATFS(v3) ((v3) ? NFSX_V3STATFS : NFSX_V2STATFS)
+
+/* nfs rpc procedure numbers (before version mapping) */
+#define NFSPROC_NULL 0
+#define NFSPROC_GETATTR 1
+#define NFSPROC_SETATTR 2
+#define NFSPROC_LOOKUP 3
+#define NFSPROC_ACCESS 4
+#define NFSPROC_READLINK 5
+#define NFSPROC_READ 6
+#define NFSPROC_WRITE 7
+#define NFSPROC_CREATE 8
+#define NFSPROC_MKDIR 9
+#define NFSPROC_SYMLINK 10
+#define NFSPROC_MKNOD 11
+#define NFSPROC_REMOVE 12
+#define NFSPROC_RMDIR 13
+#define NFSPROC_RENAME 14
+#define NFSPROC_LINK 15
+#define NFSPROC_READDIR 16
+#define NFSPROC_READDIRPLUS 17
+#define NFSPROC_FSSTAT 18
+#define NFSPROC_FSINFO 19
+#define NFSPROC_PATHCONF 20
+#define NFSPROC_COMMIT 21
+
+/* And leasing (nqnfs) procedure numbers (must be last) */
+#define NQNFSPROC_GETLEASE 22
+#define NQNFSPROC_VACATED 23
+#define NQNFSPROC_EVICTED 24
+
+#define NFSPROC_NOOP 25
+#define NFS_NPROCS 26
+
+/* Actual Version 2 procedure numbers */
+#define NFSV2PROC_NULL 0
+#define NFSV2PROC_GETATTR 1
+#define NFSV2PROC_SETATTR 2
+#define NFSV2PROC_NOOP 3
+#define NFSV2PROC_ROOT NFSV2PROC_NOOP /* Obsolete */
+#define NFSV2PROC_LOOKUP 4
+#define NFSV2PROC_READLINK 5
+#define NFSV2PROC_READ 6
+#define NFSV2PROC_WRITECACHE NFSV2PROC_NOOP /* Obsolete */
+#define NFSV2PROC_WRITE 8
+#define NFSV2PROC_CREATE 9
+#define NFSV2PROC_REMOVE 10
+#define NFSV2PROC_RENAME 11
+#define NFSV2PROC_LINK 12
+#define NFSV2PROC_SYMLINK 13
+#define NFSV2PROC_MKDIR 14
+#define NFSV2PROC_RMDIR 15
+#define NFSV2PROC_READDIR 16
+#define NFSV2PROC_STATFS 17
+
+/*
+ * Constants used by the Version 3 protocol for various RPCs
+ */
+#define NFSV3SATTRTIME_DONTCHANGE 0
+#define NFSV3SATTRTIME_TOSERVER 1
+#define NFSV3SATTRTIME_TOCLIENT 2
+
+#define NFSV3ATTRTIME_NMODES 3
+
+#define NFSV3ACCESS_READ 0x01
+#define NFSV3ACCESS_LOOKUP 0x02
+#define NFSV3ACCESS_MODIFY 0x04
+#define NFSV3ACCESS_EXTEND 0x08
+#define NFSV3ACCESS_DELETE 0x10
+#define NFSV3ACCESS_EXECUTE 0x20
+#define NFSV3ACCESS_FULL 0x3f
+
+#define NFSV3WRITE_UNSTABLE 0
+#define NFSV3WRITE_DATASYNC 1
+#define NFSV3WRITE_FILESYNC 2
+
+#define NFSV3WRITE_NMODES 3
+
+#define NFSV3CREATE_UNCHECKED 0
+#define NFSV3CREATE_GUARDED 1
+#define NFSV3CREATE_EXCLUSIVE 2
+
+#define NFSV3CREATE_NMODES 3
+
+#define NFSV3FSINFO_LINK 0x01
+#define NFSV3FSINFO_SYMLINK 0x02
+#define NFSV3FSINFO_HOMOGENEOUS 0x08
+#define NFSV3FSINFO_CANSETTIME 0x10
+
+/* Conversion macros */
+#define vtonfsv2_mode(t,m) \
+ txdr_unsigned(((t) == VFIFO) ? MAKEIMODE(VCHR, (m)) : \
+ MAKEIMODE((t), (m)))
+#define vtonfsv3_mode(m) txdr_unsigned((m) & 07777)
+#define nfstov_mode(a) (fxdr_unsigned(u_int16_t, (a))&07777)
+#define vtonfsv2_type(a) txdr_unsigned(nfsv2_type[((int32_t)(a))])
+#define vtonfsv3_type(a) txdr_unsigned(nfsv3_type[((int32_t)(a))])
+#define nfsv2tov_type(a) nv2tov_type[fxdr_unsigned(u_int32_t,(a))&0x7]
+#define nfsv3tov_type(a) nv3tov_type[fxdr_unsigned(u_int32_t,(a))&0x7]
+
+/* File types */
+typedef enum { NFNON=0, NFREG=1, NFDIR=2, NFBLK=3, NFCHR=4, NFLNK=5,
+ NFSOCK=6, NFFIFO=7 } nfs_type;
+
+/* Structs for common parts of the rpc's */
+/*
+ * File Handle (32 bytes for version 2), variable up to 64 for version 3.
+ * File Handles of up to NFS_SMALLFH in size are stored directly in the
+ * nfs node, whereas larger ones are malloc'd. (This never happens when
+ * NFS_SMALLFH is set to 64.)
+ * NFS_SMALLFH should be in the range of 32 to 64 and be divisible by 4.
+ */
+#ifndef NFS_SMALLFH
+#define NFS_SMALLFH 64
+#endif
+union nfsfh {
+/* fhandle_t fh_generic; */
+ u_char fh_bytes[NFS_SMALLFH];
+};
+typedef union nfsfh nfsfh_t;
+
+struct nfsv2_time {
+ u_int32_t nfsv2_sec;
+ u_int32_t nfsv2_usec;
+};
+typedef struct nfsv2_time nfstime2;
+
+struct nfsv3_time {
+ u_int32_t nfsv3_sec;
+ u_int32_t nfsv3_nsec;
+};
+typedef struct nfsv3_time nfstime3;
+
+/*
+ * Quads are defined as arrays of 2 longs to ensure dense packing for the
+ * protocol and to facilitate xdr conversion.
+ */
+struct nfs_uquad {
+ u_int32_t nfsuquad[2];
+};
+typedef struct nfs_uquad nfsuint64;
+
+/*
+ * NFS Version 3 special file number.
+ */
+struct nfsv3_spec {
+ u_int32_t specdata1;
+ u_int32_t specdata2;
+};
+typedef struct nfsv3_spec nfsv3spec;
+
+/*
+ * File attributes and setable attributes. These structures cover both
+ * NFS version 2 and the version 3 protocol. Note that the union is only
+ * used so that one pointer can refer to both variants. These structures
+ * go out on the wire and must be densely packed, so no quad data types
+ * are used. (all fields are longs or u_longs or structures of same)
+ * NB: You can't do sizeof(struct nfs_fattr), you must use the
+ * NFSX_FATTR(v3) macro.
+ */
+struct nfs_fattr {
+ u_int32_t fa_type;
+ u_int32_t fa_mode;
+ u_int32_t fa_nlink;
+ u_int32_t fa_uid;
+ u_int32_t fa_gid;
+ union {
+ struct {
+ u_int32_t nfsv2fa_size;
+ u_int32_t nfsv2fa_blocksize;
+ u_int32_t nfsv2fa_rdev;
+ u_int32_t nfsv2fa_blocks;
+ u_int32_t nfsv2fa_fsid;
+ u_int32_t nfsv2fa_fileid;
+ nfstime2 nfsv2fa_atime;
+ nfstime2 nfsv2fa_mtime;
+ nfstime2 nfsv2fa_ctime;
+ } fa_nfsv2;
+ struct {
+ nfsuint64 nfsv3fa_size;
+ nfsuint64 nfsv3fa_used;
+ nfsv3spec nfsv3fa_rdev;
+ nfsuint64 nfsv3fa_fsid;
+ nfsuint64 nfsv3fa_fileid;
+ nfstime3 nfsv3fa_atime;
+ nfstime3 nfsv3fa_mtime;
+ nfstime3 nfsv3fa_ctime;
+ } fa_nfsv3;
+ } fa_un;
+};
+
+/* and some ugly defines for accessing union components */
+#define fa2_size fa_un.fa_nfsv2.nfsv2fa_size
+#define fa2_blocksize fa_un.fa_nfsv2.nfsv2fa_blocksize
+#define fa2_rdev fa_un.fa_nfsv2.nfsv2fa_rdev
+#define fa2_blocks fa_un.fa_nfsv2.nfsv2fa_blocks
+#define fa2_fsid fa_un.fa_nfsv2.nfsv2fa_fsid
+#define fa2_fileid fa_un.fa_nfsv2.nfsv2fa_fileid
+#define fa2_atime fa_un.fa_nfsv2.nfsv2fa_atime
+#define fa2_mtime fa_un.fa_nfsv2.nfsv2fa_mtime
+#define fa2_ctime fa_un.fa_nfsv2.nfsv2fa_ctime
+#define fa3_size fa_un.fa_nfsv3.nfsv3fa_size
+#define fa3_used fa_un.fa_nfsv3.nfsv3fa_used
+#define fa3_rdev fa_un.fa_nfsv3.nfsv3fa_rdev
+#define fa3_fsid fa_un.fa_nfsv3.nfsv3fa_fsid
+#define fa3_fileid fa_un.fa_nfsv3.nfsv3fa_fileid
+#define fa3_atime fa_un.fa_nfsv3.nfsv3fa_atime
+#define fa3_mtime fa_un.fa_nfsv3.nfsv3fa_mtime
+#define fa3_ctime fa_un.fa_nfsv3.nfsv3fa_ctime
+
+struct nfsv2_sattr {
+ u_int32_t sa_mode;
+ u_int32_t sa_uid;
+ u_int32_t sa_gid;
+ u_int32_t sa_size;
+ nfstime2 sa_atime;
+ nfstime2 sa_mtime;
+};
+
+/*
+ * NFS Version 3 sattr structure for the new node creation case.
+ */
+struct nfsv3_sattr {
+ u_int32_t sa_modeset;
+ u_int32_t sa_mode;
+ u_int32_t sa_uidset;
+ u_int32_t sa_uid;
+ u_int32_t sa_gidset;
+ u_int32_t sa_gid;
+ u_int32_t sa_sizeset;
+ u_int32_t sa_size;
+ u_int32_t sa_atimetype;
+ nfstime3 sa_atime;
+ u_int32_t sa_mtimetype;
+ nfstime3 sa_mtime;
+};
+
+struct nfs_statfs {
+ union {
+ struct {
+ u_int32_t nfsv2sf_tsize;
+ u_int32_t nfsv2sf_bsize;
+ u_int32_t nfsv2sf_blocks;
+ u_int32_t nfsv2sf_bfree;
+ u_int32_t nfsv2sf_bavail;
+ } sf_nfsv2;
+ struct {
+ nfsuint64 nfsv3sf_tbytes;
+ nfsuint64 nfsv3sf_fbytes;
+ nfsuint64 nfsv3sf_abytes;
+ nfsuint64 nfsv3sf_tfiles;
+ nfsuint64 nfsv3sf_ffiles;
+ nfsuint64 nfsv3sf_afiles;
+ u_int32_t nfsv3sf_invarsec;
+ } sf_nfsv3;
+ } sf_un;
+};
+
+#define sf_tsize sf_un.sf_nfsv2.nfsv2sf_tsize
+#define sf_bsize sf_un.sf_nfsv2.nfsv2sf_bsize
+#define sf_blocks sf_un.sf_nfsv2.nfsv2sf_blocks
+#define sf_bfree sf_un.sf_nfsv2.nfsv2sf_bfree
+#define sf_bavail sf_un.sf_nfsv2.nfsv2sf_bavail
+#define sf_tbytes sf_un.sf_nfsv3.nfsv3sf_tbytes
+#define sf_fbytes sf_un.sf_nfsv3.nfsv3sf_fbytes
+#define sf_abytes sf_un.sf_nfsv3.nfsv3sf_abytes
+#define sf_tfiles sf_un.sf_nfsv3.nfsv3sf_tfiles
+#define sf_ffiles sf_un.sf_nfsv3.nfsv3sf_ffiles
+#define sf_afiles sf_un.sf_nfsv3.nfsv3sf_afiles
+#define sf_invarsec sf_un.sf_nfsv3.nfsv3sf_invarsec
+
+struct nfsv3_fsinfo {
+ u_int32_t fs_rtmax;
+ u_int32_t fs_rtpref;
+ u_int32_t fs_rtmult;
+ u_int32_t fs_wtmax;
+ u_int32_t fs_wtpref;
+ u_int32_t fs_wtmult;
+ u_int32_t fs_dtpref;
+ nfsuint64 fs_maxfilesize;
+ nfstime3 fs_timedelta;
+ u_int32_t fs_properties;
+};
+
+struct nfsv3_pathconf {
+ u_int32_t pc_linkmax;
+ u_int32_t pc_namemax;
+ u_int32_t pc_notrunc;
+ u_int32_t pc_chownrestricted;
+ u_int32_t pc_caseinsensitive;
+ u_int32_t pc_casepreserving;
+};
diff --git a/freebsd/contrib/tcpdump/nfsfh.h b/freebsd/contrib/tcpdump/nfsfh.h
new file mode 100644
index 00000000..82367132
--- /dev/null
+++ b/freebsd/contrib/tcpdump/nfsfh.h
@@ -0,0 +1,70 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/nfsfh.h,v 1.13 2002-04-24 06:27:05 guy Exp $ (LBL) */
+
+/*
+ * Copyright (c) 1993, 1994 Jeffrey C. Mogul, Digital Equipment Corporation,
+ * Western Research Laboratory. All rights reserved.
+ * Copyright (c) 2001 Compaq Computer Corporation. All rights reserved.
+ *
+ * Permission to use, copy, and modify this software and its
+ * documentation is hereby granted only under the following terms and
+ * conditions. Both the above copyright notice and this permission
+ * notice must appear in all copies of the software, derivative works
+ * or modified versions, and any portions thereof, and both notices
+ * must appear in supporting documentation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND COMPAQ COMPUTER CORPORATION
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL COMPAQ COMPUTER CORPORATION BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * nfsfh.h - NFS file handle definitions (for portable use)
+ *
+ * Jeffrey C. Mogul
+ * Digital Equipment Corporation
+ * Western Research Laboratory
+ * $FreeBSD$
+ * $NetBSD: nfsfh.h,v 1.1.1.2 1997/10/03 17:25:13 christos Exp $
+ */
+
+/*
+ * Internal representation of dev_t, because different NFS servers
+ * that we might be spying upon use different external representations.
+ */
+typedef struct {
+ u_int32_t Minor; /* upper case to avoid clashing with macro names */
+ u_int32_t Major;
+} my_devt;
+
+#define dev_eq(a,b) ((a.Minor == b.Minor) && (a.Major == b.Major))
+
+/*
+ * Many file servers now use a large file system ID. This is
+ * our internal representation of that.
+ */
+typedef struct {
+ my_devt Fsid_dev; /* XXX avoid name conflict with AIX */
+ char Opaque_Handle[2 * 32 + 1];
+ u_int32_t fsid_code;
+} my_fsid;
+
+#define fsid_eq(a,b) ((a.fsid_code == b.fsid_code) &&\
+ dev_eq(a.Fsid_dev, b.Fsid_dev))
+
+extern void Parse_fh(const unsigned char *, int, my_fsid *, ino_t *, const char **, const char **, int);
diff --git a/freebsd/contrib/tcpdump/nlpid.c b/freebsd/contrib/tcpdump/nlpid.c
new file mode 100644
index 00000000..83bfedf0
--- /dev/null
+++ b/freebsd/contrib/tcpdump/nlpid.c
@@ -0,0 +1,48 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/nlpid.c,v 1.4 2004-10-19 15:27:55 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+#include "interface.h"
+#include "nlpid.h"
+
+const struct tok nlpid_values[] = {
+ { NLPID_NULLNS, "NULL" },
+ { NLPID_Q933, "Q.933" },
+ { NLPID_LMI, "LMI" },
+ { NLPID_SNAP, "SNAP" },
+ { NLPID_CLNP, "CLNP" },
+ { NLPID_ESIS, "ES-IS" },
+ { NLPID_ISIS, "IS-IS" },
+ { NLPID_CONS, "CONS" },
+ { NLPID_IDRP, "IDRP" },
+ { NLPID_SPB, "ISIS_SPB" },
+ { NLPID_MFR, "FRF.15" },
+ { NLPID_IP, "IPv4" },
+ { NLPID_PPP, "PPP" },
+ { NLPID_X25_ESIS, "X25 ES-IS" },
+ { NLPID_IP6, "IPv6" },
+ { 0, NULL }
+};
diff --git a/freebsd/contrib/tcpdump/nlpid.h b/freebsd/contrib/tcpdump/nlpid.h
new file mode 100644
index 00000000..1546fc6e
--- /dev/null
+++ b/freebsd/contrib/tcpdump/nlpid.h
@@ -0,0 +1,33 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/nlpid.h,v 1.4 2004-10-19 15:27:55 hannes Exp $ (LBL) */
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+extern const struct tok nlpid_values[];
+
+#define NLPID_NULLNS 0x00
+#define NLPID_Q933 0x08 /* ANSI T1.617 Annex D or ITU-T Q.933 Annex A */
+#define NLPID_LMI 0x09 /* The original, aka Cisco, aka Gang of Four */
+#define NLPID_SNAP 0x80
+#define NLPID_CLNP 0x81 /* iso9577 */
+#define NLPID_ESIS 0x82 /* iso9577 */
+#define NLPID_ISIS 0x83 /* iso9577 */
+#define NLPID_CONS 0x84
+#define NLPID_IDRP 0x85
+#define NLPID_MFR 0xb1 /* FRF.15 */
+#define NLPID_SPB 0xc1 /* IEEE 802.1aq/D4.5 */
+#define NLPID_IP 0xcc
+#define NLPID_PPP 0xcf
+#define NLPID_X25_ESIS 0x8a
+#define NLPID_IP6 0x8e
diff --git a/freebsd/contrib/tcpdump/ntp.h b/freebsd/contrib/tcpdump/ntp.h
new file mode 100644
index 00000000..0614f73b
--- /dev/null
+++ b/freebsd/contrib/tcpdump/ntp.h
@@ -0,0 +1,127 @@
+/* $Header: /tcpdump/master/tcpdump/ntp.h,v 1.8 2004-01-28 14:34:50 hannes Exp $ */
+
+/*
+ * Based on ntp.h from the U of MD implementation
+ * This file is based on Version 2 of the NTP spec (RFC1119).
+ */
+
+/*
+ * Definitions for the masses
+ */
+#define JAN_1970 2208988800U /* 1970 - 1900 in seconds */
+
+/*
+ * Structure definitions for NTP fixed point values
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Integer Part |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Fraction Part |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Integer Part | Fraction Part |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+*/
+struct l_fixedpt {
+ u_int32_t int_part;
+ u_int32_t fraction;
+};
+
+struct s_fixedpt {
+ u_int16_t int_part;
+ u_int16_t fraction;
+};
+
+/* rfc2030
+ * 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |LI | VN |Mode | Stratum | Poll | Precision |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Root Delay |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Root Dispersion |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reference Identifier |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * | Reference Timestamp (64) |
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * | Originate Timestamp (64) |
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * | Receive Timestamp (64) |
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * | Transmit Timestamp (64) |
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Key Identifier (optional) (32) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * | |
+ * | Message Digest (optional) (128) |
+ * | |
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+struct ntpdata {
+ u_char status; /* status of local clock and leap info */
+ u_char stratum; /* Stratum level */
+ u_char ppoll; /* poll value */
+ int precision:8;
+ struct s_fixedpt root_delay;
+ struct s_fixedpt root_dispersion;
+ u_int32_t refid;
+ struct l_fixedpt ref_timestamp;
+ struct l_fixedpt org_timestamp;
+ struct l_fixedpt rec_timestamp;
+ struct l_fixedpt xmt_timestamp;
+ u_int32_t key_id;
+ u_int8_t message_digest[16];
+};
+/*
+ * Leap Second Codes (high order two bits)
+ */
+#define NO_WARNING 0x00 /* no warning */
+#define PLUS_SEC 0x40 /* add a second (61 seconds) */
+#define MINUS_SEC 0x80 /* minus a second (59 seconds) */
+#define ALARM 0xc0 /* alarm condition (clock unsynchronized) */
+
+/*
+ * Clock Status Bits that Encode Version
+ */
+#define NTPVERSION_1 0x08
+#define VERSIONMASK 0x38
+#define LEAPMASK 0xc0
+#define MODEMASK 0x07
+
+/*
+ * Code values
+ */
+#define MODE_UNSPEC 0 /* unspecified */
+#define MODE_SYM_ACT 1 /* symmetric active */
+#define MODE_SYM_PAS 2 /* symmetric passive */
+#define MODE_CLIENT 3 /* client */
+#define MODE_SERVER 4 /* server */
+#define MODE_BROADCAST 5 /* broadcast */
+#define MODE_RES1 6 /* reserved */
+#define MODE_RES2 7 /* reserved */
+
+/*
+ * Stratum Definitions
+ */
+#define UNSPECIFIED 0
+#define PRIM_REF 1 /* radio clock */
+#define INFO_QUERY 62 /* **** THIS implementation dependent **** */
+#define INFO_REPLY 63 /* **** THIS implementation dependent **** */
diff --git a/freebsd/contrib/tcpdump/oakley.h b/freebsd/contrib/tcpdump/oakley.h
new file mode 100644
index 00000000..ad328171
--- /dev/null
+++ b/freebsd/contrib/tcpdump/oakley.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/* YIPS @(#)$Id: oakley.h,v 1.4 2002-12-11 07:13:56 guy Exp $ */
+
+/* refer to RFC 2409 */
+
+#if !defined(_ISAKMP_OAKLEY_H_)
+#define _ISAKMP_OAKLEY_H_
+
+/* Attribute Classes */
+#define OAKLEY_ATTR_ENC_ALG 1 /* B */
+#define OAKLEY_ATTR_ENC_ALG_DES 1
+#define OAKLEY_ATTR_ENC_ALG_IDEA 2
+#define OAKLEY_ATTR_ENC_ALG_BL 3
+#define OAKLEY_ATTR_ENC_ALG_RC5 4
+#define OAKLEY_ATTR_ENC_ALG_3DES 5
+#define OAKLEY_ATTR_ENC_ALG_CAST 6
+#define OAKLEY_ATTR_HASH_ALG 2 /* B */
+#define OAKLEY_ATTR_HASH_ALG_MD5 1
+#define OAKLEY_ATTR_HASH_ALG_SHA 2
+#define OAKLEY_ATTR_HASH_ALG_TIGER 3
+#define OAKLEY_ATTR_AUTH_METHOD 3 /* B */
+#define OAKLEY_ATTR_AUTH_METHOD_PSKEY 1
+#define OAKLEY_ATTR_AUTH_METHOD_DSS 2
+#define OAKLEY_ATTR_AUTH_METHOD_RSA 3
+#define OAKLEY_ATTR_AUTH_METHOD_RSAENC 4
+#define OAKLEY_ATTR_AUTH_METHOD_RSAREV 5
+#define OAKLEY_ATTR_GRP_DESC 4 /* B */
+#define OAKLEY_ATTR_GRP_DESC_MODP768 1
+#define OAKLEY_ATTR_GRP_DESC_MODP1024 2
+#define OAKLEY_ATTR_GRP_DESC_EC2N155 3
+#define OAKLEY_ATTR_GRP_DESC_EC2N185 4
+#define OAKLEY_ATTR_GRP_TYPE 5 /* B */
+#define OAKLEY_ATTR_GRP_TYPE_MODP 1
+#define OAKLEY_ATTR_GRP_TYPE_ECP 2
+#define OAKLEY_ATTR_GRP_TYPE_EC2N 3
+#define OAKLEY_ATTR_GRP_PI 6 /* V */
+#define OAKLEY_ATTR_GRP_GEN_ONE 7 /* V */
+#define OAKLEY_ATTR_GRP_GEN_TWO 8 /* V */
+#define OAKLEY_ATTR_GRP_CURVE_A 9 /* V */
+#define OAKLEY_ATTR_GRP_CURVE_B 10 /* V */
+#define OAKLEY_ATTR_SA_LTYPE 11 /* B */
+#define OAKLEY_ATTR_SA_LTYPE_DEFAULT 1
+#define OAKLEY_ATTR_SA_LTYPE_SEC 1
+#define OAKLEY_ATTR_SA_LTYPE_KB 2
+#define OAKLEY_ATTR_SA_LDUR 12 /* V */
+#define OAKLEY_ATTR_SA_LDUR_DEFAULT 28800 /* 8 hours */
+#define OAKLEY_ATTR_PRF 13 /* B */
+#define OAKLEY_ATTR_KEY_LEN 14 /* B */
+#define OAKLEY_ATTR_FIELD_SIZE 15 /* B */
+#define OAKLEY_ATTR_GRP_ORDER 16 /* V */
+
+#define OAKLEY_ID_IPV4_ADDR 0
+#define OAKLEY_ID_IPV4_ADDR_SUBNET 1
+#define OAKLEY_ID_IPV6_ADDR 2
+#define OAKLEY_ID_IPV6_ADDR_SUBNET 3
+
+/* Additional Exchange Type */
+#define ISAKMP_ETYPE_QUICK 32
+#define ISAKMP_ETYPE_NEWGRP 33
+
+/* The use for checking proposal payload. This is not exchange type. */
+#define OAKLEY_MAIN_MODE 0
+#define OAKLEY_QUICK_MODE 1
+
+#define OAKLEY_PRIME_MODP768 "\
+ FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 \
+ 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD \
+ EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 \
+ E485B576 625E7EC6 F44C42E9 A63A3620 FFFFFFFF FFFFFFFF"
+
+#define OAKLEY_PRIME_MODP1024 "\
+ FFFFFFFF FFFFFFFF C90FDAA2 2168C234 C4C6628B 80DC1CD1 \
+ 29024E08 8A67CC74 020BBEA6 3B139B22 514A0879 8E3404DD \
+ EF9519B3 CD3A431B 302B0A6D F25F1437 4FE1356D 6D51C245 \
+ E485B576 625E7EC6 F44C42E9 A637ED6B 0BFF5CB6 F406B7ED \
+ EE386BFB 5A899FA5 AE9F2411 7C4B1FE6 49286651 ECE65381 \
+ FFFFFFFF FFFFFFFF"
+
+#define DEFAULTSECRETSIZE ( 128 / 8 ) /* 128 bits */
+#define DEFAULTNONCESIZE ( 128 / 8 ) /* 128 bits */
+
+#define MAXPADLWORD 20
+
+#if 0
+/* isakmp sa structure */
+struct oakley_sa {
+ u_int8_t proto_id; /* OAKLEY */
+ vchar_t *spi; /* spi */
+ u_int8_t dhgrp; /* DH; group */
+ u_int8_t auth_t; /* method of authentication */
+ u_int8_t prf_t; /* type of prf */
+ u_int8_t hash_t; /* type of hash */
+ u_int8_t enc_t; /* type of cipher */
+ u_int8_t life_t; /* type of duration of lifetime */
+ u_int32_t ldur; /* life duration */
+};
+#endif
+
+#endif /* !defined(_ISAKMP_OAKLEY_H_) */
diff --git a/freebsd/contrib/tcpdump/ospf.h b/freebsd/contrib/tcpdump/ospf.h
new file mode 100644
index 00000000..b86458ba
--- /dev/null
+++ b/freebsd/contrib/tcpdump/ospf.h
@@ -0,0 +1,328 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/ospf.h,v 1.23 2007-10-08 07:53:21 hannes Exp $ (LBL) */
+/*
+ * Copyright (c) 1991, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu)
+ */
+#define OSPF_TYPE_UMD 0 /* UMd's special monitoring packets */
+#define OSPF_TYPE_HELLO 1 /* Hello */
+#define OSPF_TYPE_DD 2 /* Database Description */
+#define OSPF_TYPE_LS_REQ 3 /* Link State Request */
+#define OSPF_TYPE_LS_UPDATE 4 /* Link State Update */
+#define OSPF_TYPE_LS_ACK 5 /* Link State Ack */
+
+/* Options field
+ *
+ * +------------------------------------+
+ * | DN | O | DC | L | N/P | MC | E | T |
+ * +------------------------------------+
+ *
+ */
+
+#define OSPF_OPTION_T 0x01 /* T bit: TOS support */
+#define OSPF_OPTION_E 0x02 /* E bit: External routes advertised */
+#define OSPF_OPTION_MC 0x04 /* MC bit: Multicast capable */
+#define OSPF_OPTION_NP 0x08 /* N/P bit: NSSA capable */
+#define OSPF_OPTION_EA 0x10 /* EA bit: External Attribute capable */
+#define OSPF_OPTION_L 0x10 /* L bit: Packet contains LLS data block */
+#define OSPF_OPTION_DC 0x20 /* DC bit: Demand circuit capable */
+#define OSPF_OPTION_O 0x40 /* O bit: Opaque LSA capable */
+#define OSPF_OPTION_DN 0x80 /* DN bit: Up/Down Bit capable - draft-ietf-ospf-2547-dnbit-04 */
+
+/* ospf_authtype */
+#define OSPF_AUTH_NONE 0 /* No auth-data */
+#define OSPF_AUTH_SIMPLE 1 /* Simple password */
+#define OSPF_AUTH_SIMPLE_LEN 8 /* max length of simple authentication */
+#define OSPF_AUTH_MD5 2 /* MD5 authentication */
+#define OSPF_AUTH_MD5_LEN 16 /* length of MD5 authentication */
+
+/* db_flags */
+#define OSPF_DB_INIT 0x04
+#define OSPF_DB_MORE 0x02
+#define OSPF_DB_MASTER 0x01
+#define OSPF_DB_RESYNC 0x08 /* RFC4811 */
+
+/* ls_type */
+#define LS_TYPE_ROUTER 1 /* router link */
+#define LS_TYPE_NETWORK 2 /* network link */
+#define LS_TYPE_SUM_IP 3 /* summary link */
+#define LS_TYPE_SUM_ABR 4 /* summary area link */
+#define LS_TYPE_ASE 5 /* ASE */
+#define LS_TYPE_GROUP 6 /* Group membership (multicast */
+ /* extensions 23 July 1991) */
+#define LS_TYPE_NSSA 7 /* rfc3101 - Not so Stubby Areas */
+#define LS_TYPE_OPAQUE_LL 9 /* rfc2370 - Opaque Link Local */
+#define LS_TYPE_OPAQUE_AL 10 /* rfc2370 - Opaque Link Local */
+#define LS_TYPE_OPAQUE_DW 11 /* rfc2370 - Opaque Domain Wide */
+
+#define LS_OPAQUE_TYPE_TE 1 /* rfc3630 */
+#define LS_OPAQUE_TYPE_GRACE 3 /* rfc3623 */
+#define LS_OPAQUE_TYPE_RI 4 /* draft-ietf-ospf-cap-03 */
+
+#define LS_OPAQUE_TE_TLV_ROUTER 1 /* rfc3630 */
+#define LS_OPAQUE_TE_TLV_LINK 2 /* rfc3630 */
+
+#define LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE 1 /* rfc3630 */
+#define LS_OPAQUE_TE_LINK_SUBTLV_LINK_ID 2 /* rfc3630 */
+#define LS_OPAQUE_TE_LINK_SUBTLV_LOCAL_IP 3 /* rfc3630 */
+#define LS_OPAQUE_TE_LINK_SUBTLV_REMOTE_IP 4 /* rfc3630 */
+#define LS_OPAQUE_TE_LINK_SUBTLV_TE_METRIC 5 /* rfc3630 */
+#define LS_OPAQUE_TE_LINK_SUBTLV_MAX_BW 6 /* rfc3630 */
+#define LS_OPAQUE_TE_LINK_SUBTLV_MAX_RES_BW 7 /* rfc3630 */
+#define LS_OPAQUE_TE_LINK_SUBTLV_UNRES_BW 8 /* rfc3630 */
+#define LS_OPAQUE_TE_LINK_SUBTLV_ADMIN_GROUP 9 /* rfc3630 */
+#define LS_OPAQUE_TE_LINK_SUBTLV_LINK_LOCAL_REMOTE_ID 11 /* rfc4203 */
+#define LS_OPAQUE_TE_LINK_SUBTLV_LINK_PROTECTION_TYPE 14 /* rfc4203 */
+#define LS_OPAQUE_TE_LINK_SUBTLV_INTF_SW_CAP_DESCR 15 /* rfc4203 */
+#define LS_OPAQUE_TE_LINK_SUBTLV_SHARED_RISK_GROUP 16 /* rfc4203 */
+#define LS_OPAQUE_TE_LINK_SUBTLV_BW_CONSTRAINTS 17 /* rfc4124 */
+
+#define LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_PTP 1 /* rfc3630 */
+#define LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_MA 2 /* rfc3630 */
+
+#define LS_OPAQUE_GRACE_TLV_PERIOD 1 /* rfc3623 */
+#define LS_OPAQUE_GRACE_TLV_REASON 2 /* rfc3623 */
+#define LS_OPAQUE_GRACE_TLV_INT_ADDRESS 3 /* rfc3623 */
+
+#define LS_OPAQUE_GRACE_TLV_REASON_UNKNOWN 0 /* rfc3623 */
+#define LS_OPAQUE_GRACE_TLV_REASON_SW_RESTART 1 /* rfc3623 */
+#define LS_OPAQUE_GRACE_TLV_REASON_SW_UPGRADE 2 /* rfc3623 */
+#define LS_OPAQUE_GRACE_TLV_REASON_CP_SWITCH 3 /* rfc3623 */
+
+#define LS_OPAQUE_RI_TLV_CAP 1 /* draft-ietf-ospf-cap-03 */
+
+
+/* rla_link.link_type */
+#define RLA_TYPE_ROUTER 1 /* point-to-point to another router */
+#define RLA_TYPE_TRANSIT 2 /* connection to transit network */
+#define RLA_TYPE_STUB 3 /* connection to stub network */
+#define RLA_TYPE_VIRTUAL 4 /* virtual link */
+
+/* rla_flags */
+#define RLA_FLAG_B 0x01
+#define RLA_FLAG_E 0x02
+#define RLA_FLAG_W1 0x04
+#define RLA_FLAG_W2 0x08
+
+/* sla_tosmetric breakdown */
+#define SLA_MASK_TOS 0x7f000000
+#define SLA_MASK_METRIC 0x00ffffff
+#define SLA_SHIFT_TOS 24
+
+/* asla_tosmetric breakdown */
+#define ASLA_FLAG_EXTERNAL 0x80000000
+#define ASLA_MASK_TOS 0x7f000000
+#define ASLA_SHIFT_TOS 24
+#define ASLA_MASK_METRIC 0x00ffffff
+
+/* multicast vertex type */
+#define MCLA_VERTEX_ROUTER 1
+#define MCLA_VERTEX_NETWORK 2
+
+/* Link-Local-Signaling */
+#define OSPF_LLS_EO 1 /* RFC4811, RFC4812 */
+#define OSPF_LLS_MD5 2 /* RFC4813 */
+
+#define OSPF_LLS_EO_LR 0x00000001 /* RFC4811 */
+#define OSPF_LLS_EO_RS 0x00000002 /* RFC4812 */
+
+/*
+ * TOS metric struct (will be 0 or more in router links update)
+ */
+struct tos_metric {
+ u_int8_t tos_type;
+ u_int8_t reserved;
+ u_int8_t tos_metric[2];
+};
+struct tos_link {
+ u_int8_t link_type;
+ u_int8_t link_tos_count;
+ u_int8_t tos_metric[2];
+};
+union un_tos {
+ struct tos_link link;
+ struct tos_metric metrics;
+};
+
+/* link state advertisement header */
+struct lsa_hdr {
+ u_int16_t ls_age;
+ u_int8_t ls_options;
+ u_int8_t ls_type;
+ union {
+ struct in_addr lsa_id;
+ struct { /* opaque LSAs change the LSA-ID field */
+ u_int8_t opaque_type;
+ u_int8_t opaque_id[3];
+ } opaque_field;
+ } un_lsa_id;
+ struct in_addr ls_router;
+ u_int32_t ls_seq;
+ u_int16_t ls_chksum;
+ u_int16_t ls_length;
+};
+
+/* link state advertisement */
+struct lsa {
+ struct lsa_hdr ls_hdr;
+
+ /* Link state types */
+ union {
+ /* Router links advertisements */
+ struct {
+ u_int8_t rla_flags;
+ u_int8_t rla_zero[1];
+ u_int16_t rla_count;
+ struct rlalink {
+ struct in_addr link_id;
+ struct in_addr link_data;
+ union un_tos un_tos;
+ } rla_link[1]; /* may repeat */
+ } un_rla;
+
+ /* Network links advertisements */
+ struct {
+ struct in_addr nla_mask;
+ struct in_addr nla_router[1]; /* may repeat */
+ } un_nla;
+
+ /* Summary links advertisements */
+ struct {
+ struct in_addr sla_mask;
+ u_int32_t sla_tosmetric[1]; /* may repeat */
+ } un_sla;
+
+ /* AS external links advertisements */
+ struct {
+ struct in_addr asla_mask;
+ struct aslametric {
+ u_int32_t asla_tosmetric;
+ struct in_addr asla_forward;
+ struct in_addr asla_tag;
+ } asla_metric[1]; /* may repeat */
+ } un_asla;
+
+ /* Multicast group membership */
+ struct mcla {
+ u_int32_t mcla_vtype;
+ struct in_addr mcla_vid;
+ } un_mcla[1];
+
+ /* Opaque TE LSA */
+ struct {
+ u_int16_t type;
+ u_int16_t length;
+ u_int8_t data[1]; /* may repeat */
+ } un_te_lsa_tlv;
+
+ /* Opaque Grace LSA */
+ struct {
+ u_int16_t type;
+ u_int16_t length;
+ u_int8_t data[1]; /* may repeat */
+ } un_grace_tlv;
+
+ /* Opaque Router information LSA */
+ struct {
+ u_int16_t type;
+ u_int16_t length;
+ u_int8_t data[1]; /* may repeat */
+ } un_ri_tlv;
+
+ /* Unknown LSA */
+ struct unknown {
+ u_int8_t data[1]; /* may repeat */
+ } un_unknown[1];
+
+ } lsa_un;
+};
+
+#define OSPF_AUTH_SIZE 8
+
+/*
+ * the main header
+ */
+struct ospfhdr {
+ u_int8_t ospf_version;
+ u_int8_t ospf_type;
+ u_int16_t ospf_len;
+ struct in_addr ospf_routerid;
+ struct in_addr ospf_areaid;
+ u_int16_t ospf_chksum;
+ u_int16_t ospf_authtype;
+ u_int8_t ospf_authdata[OSPF_AUTH_SIZE];
+ union {
+
+ /* Hello packet */
+ struct {
+ struct in_addr hello_mask;
+ u_int16_t hello_helloint;
+ u_int8_t hello_options;
+ u_int8_t hello_priority;
+ u_int32_t hello_deadint;
+ struct in_addr hello_dr;
+ struct in_addr hello_bdr;
+ struct in_addr hello_neighbor[1]; /* may repeat */
+ } un_hello;
+
+ /* Database Description packet */
+ struct {
+ u_int16_t db_ifmtu;
+ u_int8_t db_options;
+ u_int8_t db_flags;
+ u_int32_t db_seq;
+ struct lsa_hdr db_lshdr[1]; /* may repeat */
+ } un_db;
+
+ /* Link State Request */
+ struct lsr {
+ u_int8_t ls_type[4];
+ union {
+ struct in_addr ls_stateid;
+ struct { /* opaque LSAs change the LSA-ID field */
+ u_int8_t opaque_type;
+ u_int8_t opaque_id[3];
+ } opaque_field;
+ } un_ls_stateid;
+ struct in_addr ls_router;
+ } un_lsr[1]; /* may repeat */
+
+ /* Link State Update */
+ struct {
+ u_int32_t lsu_count;
+ struct lsa lsu_lsa[1]; /* may repeat */
+ } un_lsu;
+
+ /* Link State Acknowledgement */
+ struct {
+ struct lsa_hdr lsa_lshdr[1]; /* may repeat */
+ } un_lsa ;
+ } ospf_un ;
+};
+
+#define ospf_hello ospf_un.un_hello
+#define ospf_db ospf_un.un_db
+#define ospf_lsr ospf_un.un_lsr
+#define ospf_lsu ospf_un.un_lsu
+#define ospf_lsa ospf_un.un_lsa
+
+/* Functions shared by ospf and ospf6 */
+extern int ospf_print_te_lsa(const u_int8_t *, u_int);
+extern int ospf_print_grace_lsa(const u_int8_t *, u_int);
diff --git a/freebsd/contrib/tcpdump/ospf6.h b/freebsd/contrib/tcpdump/ospf6.h
new file mode 100644
index 00000000..e2eabee1
--- /dev/null
+++ b/freebsd/contrib/tcpdump/ospf6.h
@@ -0,0 +1,265 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/ospf6.h,v 1.7 2006-09-05 15:50:26 hannes Exp $ (LBL) */
+/*
+ * Copyright (c) 1991, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu)
+ */
+#define OSPF_TYPE_HELLO 1 /* Hello */
+#define OSPF_TYPE_DD 2 /* Database Description */
+#define OSPF_TYPE_LS_REQ 3 /* Link State Request */
+#define OSPF_TYPE_LS_UPDATE 4 /* Link State Update */
+#define OSPF_TYPE_LS_ACK 5 /* Link State Ack */
+
+/* Options *_options */
+#define OSPF6_OPTION_V6 0x01 /* V6 bit: A bit for peeping tom */
+#define OSPF6_OPTION_E 0x02 /* E bit: External routes advertised */
+#define OSPF6_OPTION_MC 0x04 /* MC bit: Multicast capable */
+#define OSPF6_OPTION_N 0x08 /* N bit: For type-7 LSA */
+#define OSPF6_OPTION_R 0x10 /* R bit: Router bit */
+#define OSPF6_OPTION_DC 0x20 /* DC bit: Demand circuits */
+
+
+/* db_flags */
+#define OSPF6_DB_INIT 0x04 /* */
+#define OSPF6_DB_MORE 0x02
+#define OSPF6_DB_MASTER 0x01
+
+/* ls_type */
+#define LS_TYPE_ROUTER 1 /* router link */
+#define LS_TYPE_NETWORK 2 /* network link */
+#define LS_TYPE_INTER_AP 3 /* Inter-Area-Prefix */
+#define LS_TYPE_INTER_AR 4 /* Inter-Area-Router */
+#define LS_TYPE_ASE 5 /* ASE */
+#define LS_TYPE_GROUP 6 /* Group membership */
+#define LS_TYPE_NSSA 7 /* NSSA */
+#define LS_TYPE_LINK 8 /* Link LSA */
+#define LS_TYPE_INTRA_AP 9 /* Intra-Area-Prefix */
+#define LS_TYPE_INTRA_ATE 10 /* Intra-Area-TE */
+#define LS_TYPE_GRACE 11 /* Grace LSA */
+#define LS_TYPE_MASK 0x1fff
+
+#define LS_SCOPE_LINKLOCAL 0x0000
+#define LS_SCOPE_AREA 0x2000
+#define LS_SCOPE_AS 0x4000
+#define LS_SCOPE_MASK 0x6000
+#define LS_SCOPE_U 0x8000
+
+/* rla_link.link_type */
+#define RLA_TYPE_ROUTER 1 /* point-to-point to another router */
+#define RLA_TYPE_TRANSIT 2 /* connection to transit network */
+#define RLA_TYPE_VIRTUAL 4 /* virtual link */
+
+/* rla_flags */
+#define RLA_FLAG_B 0x01
+#define RLA_FLAG_E 0x02
+#define RLA_FLAG_V 0x04
+#define RLA_FLAG_W 0x08
+#define RLA_FLAG_N 0x10
+
+/* lsa_prefix options */
+#define LSA_PREFIX_OPT_NU 0x01
+#define LSA_PREFIX_OPT_LA 0x02
+#define LSA_PREFIX_OPT_MC 0x04
+#define LSA_PREFIX_OPT_P 0x08
+#define LSA_PREFIX_OPT_DN 0x10
+
+/* sla_tosmetric breakdown */
+#define SLA_MASK_TOS 0x7f000000
+#define SLA_MASK_METRIC 0x00ffffff
+#define SLA_SHIFT_TOS 24
+
+/* asla_metric */
+#define ASLA_FLAG_FWDADDR 0x02000000
+#define ASLA_FLAG_ROUTETAG 0x01000000
+#define ASLA_MASK_METRIC 0x00ffffff
+
+typedef u_int32_t rtrid_t;
+
+/* link state advertisement header */
+struct lsa6_hdr {
+ u_int16_t ls_age;
+ u_int16_t ls_type;
+ rtrid_t ls_stateid;
+ rtrid_t ls_router;
+ u_int32_t ls_seq;
+ u_int16_t ls_chksum;
+ u_int16_t ls_length;
+};
+
+struct lsa6_prefix {
+ u_int8_t lsa_p_len;
+ u_int8_t lsa_p_opt;
+ u_int16_t lsa_p_metric;
+ u_int8_t lsa_p_prefix[4];
+};
+
+/* link state advertisement */
+struct lsa6 {
+ struct lsa6_hdr ls_hdr;
+
+ /* Link state types */
+ union {
+ /* Router links advertisements */
+ struct {
+ union {
+ u_int8_t flg;
+ u_int32_t opt;
+ } rla_flgandopt;
+#define rla_flags rla_flgandopt.flg
+#define rla_options rla_flgandopt.opt
+ struct rlalink6 {
+ u_int8_t link_type;
+ u_int8_t link_zero[1];
+ u_int16_t link_metric;
+ u_int32_t link_ifid;
+ u_int32_t link_nifid;
+ rtrid_t link_nrtid;
+ } rla_link[1]; /* may repeat */
+ } un_rla;
+
+ /* Network links advertisements */
+ struct {
+ u_int32_t nla_options;
+ rtrid_t nla_router[1]; /* may repeat */
+ } un_nla;
+
+ /* Inter Area Prefix LSA */
+ struct {
+ u_int32_t inter_ap_metric;
+ struct lsa6_prefix inter_ap_prefix[1];
+ } un_inter_ap;
+
+ /* AS external links advertisements */
+ struct {
+ u_int32_t asla_metric;
+ struct lsa6_prefix asla_prefix[1];
+ /* some optional fields follow */
+ } un_asla;
+
+#if 0
+ /* Summary links advertisements */
+ struct {
+ struct in_addr sla_mask;
+ u_int32_t sla_tosmetric[1]; /* may repeat */
+ } un_sla;
+
+ /* Multicast group membership */
+ struct mcla {
+ u_int32_t mcla_vtype;
+ struct in_addr mcla_vid;
+ } un_mcla[1];
+#endif
+
+ /* Type 7 LSA */
+
+ /* Link LSA */
+ struct llsa {
+ union {
+ u_int8_t pri;
+ u_int32_t opt;
+ } llsa_priandopt;
+#define llsa_priority llsa_priandopt.pri
+#define llsa_options llsa_priandopt.opt
+ struct in6_addr llsa_lladdr;
+ u_int32_t llsa_nprefix;
+ struct lsa6_prefix llsa_prefix[1];
+ } un_llsa;
+
+ /* Intra-Area-Prefix */
+ struct {
+ u_int16_t intra_ap_nprefix;
+ u_int16_t intra_ap_lstype;
+ rtrid_t intra_ap_lsid;
+ rtrid_t intra_ap_rtid;
+ struct lsa6_prefix intra_ap_prefix[1];
+ } un_intra_ap;
+ } lsa_un;
+};
+
+
+#define OSPF_AUTH_SIZE 8
+
+/*
+ * the main header
+ */
+struct ospf6hdr {
+ u_int8_t ospf6_version;
+ u_int8_t ospf6_type;
+ u_int16_t ospf6_len;
+ rtrid_t ospf6_routerid;
+ rtrid_t ospf6_areaid;
+ u_int16_t ospf6_chksum;
+ u_int8_t ospf6_instanceid;
+ u_int8_t ospf6_rsvd;
+ union {
+
+ /* Hello packet */
+ struct {
+ u_int32_t hello_ifid;
+ union {
+ u_int8_t pri;
+ u_int32_t opt;
+ } hello_priandopt;
+#define hello_priority hello_priandopt.pri
+#define hello_options hello_priandopt.opt
+ u_int16_t hello_helloint;
+ u_int16_t hello_deadint;
+ rtrid_t hello_dr;
+ rtrid_t hello_bdr;
+ rtrid_t hello_neighbor[1]; /* may repeat */
+ } un_hello;
+
+ /* Database Description packet */
+ struct {
+ u_int32_t db_options;
+ u_int16_t db_mtu;
+ u_int8_t db_mbz;
+ u_int8_t db_flags;
+ u_int32_t db_seq;
+ struct lsa6_hdr db_lshdr[1]; /* may repeat */
+ } un_db;
+
+ /* Link State Request */
+ struct lsr6 {
+ u_int16_t ls_mbz;
+ u_int16_t ls_type;
+ rtrid_t ls_stateid;
+ rtrid_t ls_router;
+ } un_lsr[1]; /* may repeat */
+
+ /* Link State Update */
+ struct {
+ u_int32_t lsu_count;
+ struct lsa6 lsu_lsa[1]; /* may repeat */
+ } un_lsu;
+
+ /* Link State Acknowledgement */
+ struct {
+ struct lsa6_hdr lsa_lshdr[1]; /* may repeat */
+ } un_lsa ;
+ } ospf6_un ;
+};
+
+#define ospf6_hello ospf6_un.un_hello
+#define ospf6_db ospf6_un.un_db
+#define ospf6_lsr ospf6_un.un_lsr
+#define ospf6_lsu ospf6_un.un_lsu
+#define ospf6_lsa ospf6_un.un_lsa
+
diff --git a/freebsd/contrib/tcpdump/oui.c b/freebsd/contrib/tcpdump/oui.c
new file mode 100644
index 00000000..07ba0943
--- /dev/null
+++ b/freebsd/contrib/tcpdump/oui.c
@@ -0,0 +1,101 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/oui.c,v 1.9 2008-01-09 09:40:47 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+#include "interface.h"
+#include "oui.h"
+
+/* FIXME complete OUI list using a script */
+
+const struct tok oui_values[] = {
+ { OUI_ENCAP_ETHER, "Ethernet" },
+ { OUI_CISCO, "Cisco" },
+ { OUI_NORTEL, "Nortel Networks SONMP" },
+ { OUI_CISCO_90, "Cisco bridged" },
+ { OUI_RFC2684, "Ethernet bridged" },
+ { OUI_ATM_FORUM, "ATM Forum" },
+ { OUI_CABLE_BPDU, "DOCSIS Spanning Tree" },
+ { OUI_APPLETALK, "Appletalk" },
+ { OUI_JUNIPER, "Juniper" },
+ { OUI_HP, "Hewlett-Packard" },
+ { OUI_IEEE_8021_PRIVATE, "IEEE 802.1 Private"},
+ { OUI_IEEE_8023_PRIVATE, "IEEE 802.3 Private"},
+ { OUI_TIA, "ANSI/TIA"},
+ { OUI_DCBX, "DCBX"},
+ { 0, NULL }
+};
+
+/*
+ * SMI Network Management Private Enterprise Codes for organizations.
+ *
+ * XXX - these also appear in FreeRadius dictionary files, with items such
+ * as
+ *
+ * VENDOR Cisco 9
+ *
+ * List taken from Ethereal's epan/sminmpec.c.
+ */
+const struct tok smi_values[] = {
+ { SMI_IETF, "IETF (reserved)"},
+ { SMI_ACC, "ACC"},
+ { SMI_CISCO, "Cisco"},
+ { SMI_HEWLETT_PACKARD, "Hewlett Packard"},
+ { SMI_SUN_MICROSYSTEMS, "Sun Microsystems"},
+ { SMI_MERIT, "Merit"},
+ { SMI_SHIVA, "Shiva"},
+ { SMI_ERICSSON, "Ericsson AB"},
+ { SMI_CISCO_VPN5000, "Cisco VPN 5000"},
+ { SMI_LIVINGSTON, "Livingston"},
+ { SMI_MICROSOFT, "Microsoft"},
+ { SMI_3COM, "3Com"},
+ { SMI_ASCEND, "Ascend"},
+ { SMI_BAY, "Bay Networks"},
+ { SMI_FOUNDRY, "Foundry"},
+ { SMI_VERSANET, "Versanet"},
+ { SMI_REDBACK, "Redback"},
+ { SMI_JUNIPER, "Juniper Networks"},
+ { SMI_APTIS, "Aptis"},
+ { SMI_CISCO_VPN3000, "Cisco VPN 3000"},
+ { SMI_COSINE, "CoSine Communications"},
+ { SMI_NETSCREEN, "Netscreen"},
+ { SMI_SHASTA, "Shasta"},
+ { SMI_NOMADIX, "Nomadix"},
+ { SMI_SIEMENS, "Siemens"},
+ { SMI_CABLELABS, "CableLabs"},
+ { SMI_UNISPHERE, "Unisphere Networks"},
+ { SMI_CISCO_BBSM, "Cisco BBSM"},
+ { SMI_THE3GPP2, "3rd Generation Partnership Project 2 (3GPP2)"},
+ { SMI_IP_UNPLUGGED, "ipUnplugged"},
+ { SMI_ISSANNI, "Issanni Communications"},
+ { SMI_QUINTUM, "Quintum"},
+ { SMI_INTERLINK, "Interlink"},
+ { SMI_COLUBRIS, "Colubris"},
+ { SMI_COLUMBIA_UNIVERSITY, "Columbia University"},
+ { SMI_THE3GPP, "3GPP"},
+ { SMI_GEMTEK_SYSTEMS, "Gemtek-Systems"},
+ { SMI_WIFI_ALLIANCE, "Wi-Fi Alliance"},
+ { 0, NULL}
+};
diff --git a/freebsd/contrib/tcpdump/oui.h b/freebsd/contrib/tcpdump/oui.h
new file mode 100644
index 00000000..d39cb6ca
--- /dev/null
+++ b/freebsd/contrib/tcpdump/oui.h
@@ -0,0 +1,82 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/oui.h,v 1.8 2008-01-09 09:40:47 hannes Exp $ (LBL) */
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+extern const struct tok oui_values[];
+extern const struct tok smi_values[];
+
+#define OUI_ENCAP_ETHER 0x000000 /* encapsulated Ethernet */
+#define OUI_CISCO 0x00000c /* Cisco protocols */
+#define OUI_NORTEL 0x000081 /* Nortel SONMP */
+#define OUI_CISCO_90 0x0000f8 /* Cisco bridging */
+#define OUI_RFC2684 0x0080c2 /* RFC 2427/2684 bridged Ethernet */
+#define OUI_ATM_FORUM 0x00A03E /* ATM Forum */
+#define OUI_CABLE_BPDU 0x00E02F /* DOCSIS spanning tree BPDU */
+#define OUI_APPLETALK 0x080007 /* Appletalk */
+#define OUI_JUNIPER 0x009069 /* Juniper */
+#define OUI_HP 0x080009 /* Hewlett-Packard */
+#define OUI_IEEE_8021_PRIVATE 0x0080c2 /* IEEE 802.1 Organisation Specific - Annex F */
+#define OUI_IEEE_8023_PRIVATE 0x00120f /* IEEE 802.3 Organisation Specific - Annex G */
+#define OUI_TIA 0x0012bb /* TIA - Telecommunications Industry Association - ANSI/TIA-1057- 2006 */
+#define OUI_DCBX 0x001B21 /* DCBX */
+
+/*
+ * These are SMI Network Management Private Enterprise Codes for
+ * organizations; see
+ *
+ * http://www.iana.org/assignments/enterprise-numbers
+ *
+ * for a list.
+ *
+ * List taken from Ethereal's epan/sminmpec.h.
+ */
+#define SMI_IETF 0 /* reserved - used by the IETF in L2TP? */
+#define SMI_ACC 5
+#define SMI_CISCO 9
+#define SMI_HEWLETT_PACKARD 11
+#define SMI_SUN_MICROSYSTEMS 42
+#define SMI_MERIT 61
+#define SMI_SHIVA 166
+#define SMI_ERICSSON 193
+#define SMI_CISCO_VPN5000 255
+#define SMI_LIVINGSTON 307
+#define SMI_MICROSOFT 311
+#define SMI_3COM 429
+#define SMI_ASCEND 529
+#define SMI_BAY 1584
+#define SMI_FOUNDRY 1991
+#define SMI_VERSANET 2180
+#define SMI_REDBACK 2352
+#define SMI_JUNIPER 2636
+#define SMI_APTIS 2637
+#define SMI_CISCO_VPN3000 3076
+#define SMI_COSINE 3085
+#define SMI_SHASTA 3199
+#define SMI_NETSCREEN 3224
+#define SMI_NOMADIX 3309
+#define SMI_SIEMENS 4329
+#define SMI_CABLELABS 4491
+#define SMI_UNISPHERE 4874
+#define SMI_CISCO_BBSM 5263
+#define SMI_THE3GPP2 5535
+#define SMI_IP_UNPLUGGED 5925
+#define SMI_ISSANNI 5948
+#define SMI_QUINTUM 6618
+#define SMI_INTERLINK 6728
+#define SMI_COLUBRIS 8744
+#define SMI_COLUMBIA_UNIVERSITY 11862
+#define SMI_THE3GPP 10415
+#define SMI_GEMTEK_SYSTEMS 10529
+#define SMI_WIFI_ALLIANCE 14122
diff --git a/freebsd/contrib/tcpdump/parsenfsfh.c b/freebsd/contrib/tcpdump/parsenfsfh.c
new file mode 100644
index 00000000..a6025e6b
--- /dev/null
+++ b/freebsd/contrib/tcpdump/parsenfsfh.c
@@ -0,0 +1,488 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1993, 1994 Jeffrey C. Mogul, Digital Equipment Corporation,
+ * Western Research Laboratory. All rights reserved.
+ * Copyright (c) 2001 Compaq Computer Corporation. All rights reserved.
+ *
+ * Permission to use, copy, and modify this software and its
+ * documentation is hereby granted only under the following terms and
+ * conditions. Both the above copyright notice and this permission
+ * notice must appear in all copies of the software, derivative works
+ * or modified versions, and any portions thereof, and both notices
+ * must appear in supporting documentation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND COMPAQ COMPUTER CORPORATION
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+ * EVENT SHALL COMPAQ COMPUTER CORPORATION BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
+ * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
+ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ */
+
+/*
+ * parsenfsfh.c - portable parser for NFS file handles
+ * uses all sorts of heuristics
+ *
+ * Jeffrey C. Mogul
+ * Digital Equipment Corporation
+ * Western Research Laboratory
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/parsenfsfh.c,v 1.29 2006-06-13 22:21:38 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "nfsfh.h"
+
+/*
+ * This routine attempts to parse a file handle (in network byte order),
+ * using heuristics to guess what kind of format it is in. See the
+ * file "fhandle_layouts" for a detailed description of the various
+ * patterns we know about.
+ *
+ * The file handle is parsed into our internal representation of a
+ * file-system id, and an internal representation of an inode-number.
+ */
+
+#define FHT_UNKNOWN 0
+#define FHT_AUSPEX 1
+#define FHT_DECOSF 2
+#define FHT_IRIX4 3
+#define FHT_IRIX5 4
+#define FHT_SUNOS3 5
+#define FHT_SUNOS4 6
+#define FHT_ULTRIX 7
+#define FHT_VMSUCX 8
+#define FHT_SUNOS5 9
+#define FHT_AIX32 10
+#define FHT_HPUX9 11
+#define FHT_BSD44 12
+
+#ifdef ultrix
+/* Nasty hack to keep the Ultrix C compiler from emitting bogus warnings */
+#define XFF(x) ((u_int32_t)(x))
+#else
+#define XFF(x) (x)
+#endif
+
+#define make_uint32(msb,b,c,lsb)\
+ (XFF(lsb) + (XFF(c)<<8) + (XFF(b)<<16) + (XFF(msb)<<24))
+
+#define make_uint24(msb,b, lsb)\
+ (XFF(lsb) + (XFF(b)<<8) + (XFF(msb)<<16))
+
+#define make_uint16(msb,lsb)\
+ (XFF(lsb) + (XFF(msb)<<8))
+
+#ifdef __alpha
+ /* or other 64-bit systems */
+#define make_uint48(msb,b,c,d,e,lsb)\
+ ((lsb) + ((e)<<8) + ((d)<<16) + ((c)<<24) + ((b)<<32) + ((msb)<<40))
+#else
+ /* on 32-bit systems ignore high-order bits */
+#define make_uint48(msb,b,c,d,e,lsb)\
+ ((lsb) + ((e)<<8) + ((d)<<16) + ((c)<<24))
+#endif
+
+static int is_UCX(const unsigned char *);
+
+void
+Parse_fh(fh, len, fsidp, inop, osnamep, fsnamep, ourself)
+register const unsigned char *fh;
+int len _U_;
+my_fsid *fsidp;
+ino_t *inop;
+const char **osnamep; /* if non-NULL, return OS name here */
+const char **fsnamep; /* if non-NULL, return server fs name here (for VMS) */
+int ourself; /* true if file handle was generated on this host */
+{
+ register const unsigned char *fhp = fh;
+ u_int32_t temp;
+ int fhtype = FHT_UNKNOWN;
+ int i;
+
+ if (ourself) {
+ /* File handle generated on this host, no need for guessing */
+#if defined(IRIX40)
+ fhtype = FHT_IRIX4;
+#endif
+#if defined(IRIX50)
+ fhtype = FHT_IRIX5;
+#endif
+#if defined(IRIX51)
+ fhtype = FHT_IRIX5;
+#endif
+#if defined(SUNOS4)
+ fhtype = FHT_SUNOS4;
+#endif
+#if defined(SUNOS5)
+ fhtype = FHT_SUNOS5;
+#endif
+#if defined(ultrix)
+ fhtype = FHT_ULTRIX;
+#endif
+#if defined(__osf__)
+ fhtype = FHT_DECOSF;
+#endif
+#if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) \
+ || defined(__OpenBSD__)
+ fhtype = FHT_BSD44;
+#endif
+ }
+ /*
+ * This is basically a big decision tree
+ */
+ else if ((fhp[0] == 0) && (fhp[1] == 0)) {
+ /* bytes[0,1] == (0,0); rules out Ultrix, IRIX5, SUNOS5 */
+ /* probably rules out HP-UX, AIX unless they allow major=0 */
+ if ((fhp[2] == 0) && (fhp[3] == 0)) {
+ /* bytes[2,3] == (0,0); must be Auspex */
+ /* XXX or could be Ultrix+MASSBUS "hp" disk? */
+ fhtype = FHT_AUSPEX;
+ }
+ else {
+ /*
+ * bytes[2,3] != (0,0); rules out Auspex, could be
+ * DECOSF, SUNOS4, or IRIX4
+ */
+ if ((fhp[4] != 0) && (fhp[5] == 0) &&
+ (fhp[8] == 12) && (fhp[9] == 0)) {
+ /* seems to be DECOSF, with minor == 0 */
+ fhtype = FHT_DECOSF;
+ }
+ else {
+ /* could be SUNOS4 or IRIX4 */
+ /* XXX the test of fhp[5] == 8 could be wrong */
+ if ((fhp[4] == 0) && (fhp[5] == 8) && (fhp[6] == 0) &&
+ (fhp[7] == 0)) {
+ /* looks like a length, not a file system typecode */
+ fhtype = FHT_IRIX4;
+ }
+ else {
+ /* by elimination */
+ fhtype = FHT_SUNOS4;
+ }
+ }
+ }
+ }
+ else {
+ /*
+ * bytes[0,1] != (0,0); rules out Auspex, IRIX4, SUNOS4
+ * could be IRIX5, DECOSF, UCX, Ultrix, SUNOS5
+ * could be AIX, HP-UX
+ */
+ if ((fhp[2] == 0) && (fhp[3] == 0)) {
+ /*
+ * bytes[2,3] == (0,0); rules out OSF, probably not UCX
+ * (unless the exported device name is just one letter!),
+ * could be Ultrix, IRIX5, AIX, or SUNOS5
+ * might be HP-UX (depends on their values for minor devs)
+ */
+ if ((fhp[6] == 0) && (fhp[7] == 0)) {
+ fhtype = FHT_BSD44;
+ }
+ /*XXX we probably only need to test of these two bytes */
+ else if ((fhp[21] == 0) && (fhp[23] == 0)) {
+ fhtype = FHT_ULTRIX;
+ }
+ else {
+ /* Could be SUNOS5/IRIX5, maybe AIX */
+ /* XXX no obvious difference between SUNOS5 and IRIX5 */
+ if (fhp[9] == 10)
+ fhtype = FHT_SUNOS5;
+ /* XXX what about AIX? */
+ }
+ }
+ else {
+ /*
+ * bytes[2,3] != (0,0); rules out Ultrix, could be
+ * DECOSF, SUNOS5, IRIX5, AIX, HP-UX, or UCX
+ */
+ if ((fhp[8] == 12) && (fhp[9] == 0)) {
+ fhtype = FHT_DECOSF;
+ }
+ else if ((fhp[8] == 0) && (fhp[9] == 10)) {
+ /* could be SUNOS5/IRIX5, AIX, HP-UX */
+ if ((fhp[7] == 0) && (fhp[6] == 0) &&
+ (fhp[5] == 0) && (fhp[4] == 0)) {
+ /* XXX is this always true of HP-UX? */
+ fhtype = FHT_HPUX9;
+ }
+ else if (fhp[7] == 2) {
+ /* This would be MNT_NFS on AIX, which is impossible */
+ fhtype = FHT_SUNOS5; /* or maybe IRIX5 */
+ }
+ else {
+ /*
+ * XXX Could be SUNOS5/IRIX5 or AIX. I don't
+ * XXX see any way to disambiguate these, so
+ * XXX I'm going with the more likely guess.
+ * XXX Sorry, Big Blue.
+ */
+ fhtype = FHT_SUNOS5; /* or maybe IRIX5 */
+ }
+ }
+ else {
+ if (is_UCX(fhp)) {
+ fhtype = FHT_VMSUCX;
+ }
+ else {
+ fhtype = FHT_UNKNOWN;
+ }
+ }
+ }
+ }
+
+ /* XXX still needs to handle SUNOS3 */
+
+ switch (fhtype) {
+ case FHT_AUSPEX:
+ fsidp->Fsid_dev.Minor = fhp[7];
+ fsidp->Fsid_dev.Major = fhp[6];
+ fsidp->fsid_code = 0;
+
+ temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
+ *inop = temp;
+
+ if (osnamep)
+ *osnamep = "Auspex";
+ break;
+
+ case FHT_BSD44:
+ fsidp->Fsid_dev.Minor = fhp[0];
+ fsidp->Fsid_dev.Major = fhp[1];
+ fsidp->fsid_code = 0;
+
+ temp = make_uint32(fhp[15], fhp[14], fhp[13], fhp[12]);
+ *inop = temp;
+
+ if (osnamep)
+ *osnamep = "BSD 4.4";
+ break;
+
+ case FHT_DECOSF:
+ fsidp->fsid_code = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]);
+ /* XXX could ignore 3 high-order bytes */
+
+ temp = make_uint32(fhp[3], fhp[2], fhp[1], fhp[0]);
+ fsidp->Fsid_dev.Minor = temp & 0xFFFFF;
+ fsidp->Fsid_dev.Major = (temp>>20) & 0xFFF;
+
+ temp = make_uint32(fhp[15], fhp[14], fhp[13], fhp[12]);
+ *inop = temp;
+ if (osnamep)
+ *osnamep = "OSF";
+ break;
+
+ case FHT_IRIX4:
+ fsidp->Fsid_dev.Minor = fhp[3];
+ fsidp->Fsid_dev.Major = fhp[2];
+ fsidp->fsid_code = 0;
+
+ temp = make_uint32(fhp[8], fhp[9], fhp[10], fhp[11]);
+ *inop = temp;
+
+ if (osnamep)
+ *osnamep = "IRIX4";
+ break;
+
+ case FHT_IRIX5:
+ fsidp->Fsid_dev.Minor = make_uint16(fhp[2], fhp[3]);
+ fsidp->Fsid_dev.Major = make_uint16(fhp[0], fhp[1]);
+ fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]);
+
+ temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
+ *inop = temp;
+
+ if (osnamep)
+ *osnamep = "IRIX5";
+ break;
+
+#ifdef notdef
+ case FHT_SUNOS3:
+ /*
+ * XXX - none of the heuristics above return this.
+ * Are there any SunOS 3.x systems around to care about?
+ */
+ if (osnamep)
+ *osnamep = "SUNOS3";
+ break;
+#endif
+
+ case FHT_SUNOS4:
+ fsidp->Fsid_dev.Minor = fhp[3];
+ fsidp->Fsid_dev.Major = fhp[2];
+ fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]);
+
+ temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
+ *inop = temp;
+
+ if (osnamep)
+ *osnamep = "SUNOS4";
+ break;
+
+ case FHT_SUNOS5:
+ temp = make_uint16(fhp[0], fhp[1]);
+ fsidp->Fsid_dev.Major = (temp>>2) & 0x3FFF;
+ temp = make_uint24(fhp[1], fhp[2], fhp[3]);
+ fsidp->Fsid_dev.Minor = temp & 0x3FFFF;
+ fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]);
+
+ temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
+ *inop = temp;
+
+ if (osnamep)
+ *osnamep = "SUNOS5";
+ break;
+
+ case FHT_ULTRIX:
+ fsidp->fsid_code = 0;
+ fsidp->Fsid_dev.Minor = fhp[0];
+ fsidp->Fsid_dev.Major = fhp[1];
+
+ temp = make_uint32(fhp[7], fhp[6], fhp[5], fhp[4]);
+ *inop = temp;
+ if (osnamep)
+ *osnamep = "Ultrix";
+ break;
+
+ case FHT_VMSUCX:
+ /* No numeric file system ID, so hash on the device-name */
+ if (sizeof(*fsidp) >= 14) {
+ if (sizeof(*fsidp) > 14)
+ memset((char *)fsidp, 0, sizeof(*fsidp));
+ /* just use the whole thing */
+ memcpy((char *)fsidp, (char *)fh, 14);
+ }
+ else {
+ u_int32_t tempa[4]; /* at least 16 bytes, maybe more */
+
+ memset((char *)tempa, 0, sizeof(tempa));
+ memcpy((char *)tempa, (char *)fh, 14); /* ensure alignment */
+ fsidp->Fsid_dev.Minor = tempa[0] + (tempa[1]<<1);
+ fsidp->Fsid_dev.Major = tempa[2] + (tempa[3]<<1);
+ fsidp->fsid_code = 0;
+ }
+
+ /* VMS file ID is: (RVN, FidHi, FidLo) */
+ *inop = make_uint32(fhp[26], fhp[27], fhp[23], fhp[22]);
+
+ /* Caller must save (and null-terminate?) this value */
+ if (fsnamep)
+ *fsnamep = (char *)&(fhp[1]);
+
+ if (osnamep)
+ *osnamep = "VMS";
+ break;
+
+ case FHT_AIX32:
+ fsidp->Fsid_dev.Minor = make_uint16(fhp[2], fhp[3]);
+ fsidp->Fsid_dev.Major = make_uint16(fhp[0], fhp[1]);
+ fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]);
+
+ temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
+ *inop = temp;
+
+ if (osnamep)
+ *osnamep = "AIX32";
+ break;
+
+ case FHT_HPUX9:
+ fsidp->Fsid_dev.Major = fhp[0];
+ temp = make_uint24(fhp[1], fhp[2], fhp[3]);
+ fsidp->Fsid_dev.Minor = temp;
+ fsidp->fsid_code = make_uint32(fhp[4], fhp[5], fhp[6], fhp[7]);
+
+ temp = make_uint32(fhp[12], fhp[13], fhp[14], fhp[15]);
+ *inop = temp;
+
+ if (osnamep)
+ *osnamep = "HPUX9";
+ break;
+
+ case FHT_UNKNOWN:
+#ifdef DEBUG
+ /* XXX debugging */
+ for (i = 0; i < 32; i++)
+ (void)fprintf(stderr, "%x.", fhp[i]);
+ (void)fprintf(stderr, "\n");
+#endif
+ /* Save the actual handle, so it can be display with -u */
+ for (i = 0; i < 32; i++)
+ (void)snprintf(&(fsidp->Opaque_Handle[i*2]), 3, "%.2X", fhp[i]);
+
+ /* XXX for now, give "bogus" values to aid debugging */
+ fsidp->fsid_code = 0;
+ fsidp->Fsid_dev.Minor = 257;
+ fsidp->Fsid_dev.Major = 257;
+ *inop = 1;
+
+ /* display will show this string instead of (257,257) */
+ if (fsnamep)
+ *fsnamep = "Unknown";
+
+ if (osnamep)
+ *osnamep = "Unknown";
+ break;
+
+ }
+}
+
+/*
+ * Is this a VMS UCX file handle?
+ * Check for:
+ * (1) leading code byte [XXX not yet]
+ * (2) followed by string of printing chars & spaces
+ * (3) followed by string of nulls
+ */
+static int
+is_UCX(fhp)
+const unsigned char *fhp;
+{
+ register int i;
+ int seen_null = 0;
+
+ for (i = 1; i < 14; i++) {
+ if (isprint(fhp[i])) {
+ if (seen_null)
+ return(0);
+ else
+ continue;
+ }
+ else if (fhp[i] == 0) {
+ seen_null = 1;
+ continue;
+ }
+ else
+ return(0);
+ }
+
+ return(1);
+}
diff --git a/freebsd/contrib/tcpdump/pcap-missing.h b/freebsd/contrib/tcpdump/pcap-missing.h
new file mode 100644
index 00000000..5c0ece25
--- /dev/null
+++ b/freebsd/contrib/tcpdump/pcap-missing.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 1988-2002
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /tcpdump/master/tcpdump/pcap-missing.h,v 1.3 2005-06-03 22:08:52 guy Exp $ (LBL)
+ */
+
+#ifndef tcpdump_pcap_missing_h
+#define tcpdump_pcap_missing_h
+
+/*
+ * Declarations of functions that might be missing from libpcap.
+ */
+
+#ifndef HAVE_PCAP_LIST_DATALINKS
+extern int pcap_list_datalinks(pcap_t *, int **);
+#endif
+
+#ifndef HAVE_PCAP_DATALINK_NAME_TO_VAL
+/*
+ * We assume no platform has one but not the other.
+ */
+extern int pcap_datalink_name_to_val(const char *);
+extern const char *pcap_datalink_val_to_name(int);
+#endif
+
+#ifndef HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION
+extern const char *pcap_datalink_val_to_description(int);
+#endif
+
+#ifndef HAVE_PCAP_DUMP_FTELL
+extern long pcap_dump_ftell(pcap_dumper_t *);
+#endif
+
+#endif
+
+
+
+
+
+
+
+
+
diff --git a/freebsd/contrib/tcpdump/pmap_prot.h b/freebsd/contrib/tcpdump/pmap_prot.h
new file mode 100644
index 00000000..949c3994
--- /dev/null
+++ b/freebsd/contrib/tcpdump/pmap_prot.h
@@ -0,0 +1,90 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/pmap_prot.h,v 1.3 2005-04-27 21:43:48 guy Exp $ (LBL) */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ *
+ * from: @(#)pmap_prot.h 1.14 88/02/08 SMI
+ * from: @(#)pmap_prot.h 2.1 88/07/29 4.0 RPCSRC
+ * $FreeBSD$
+ * FreeBSD: src/include/rpc/pmap_prot.h,v 1.9.2.1 1999/08/29 14:39:05 peter Exp
+ */
+
+/*
+ * pmap_prot.h
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * The following procedures are supported by the protocol:
+ *
+ * PMAPPROC_NULL() returns ()
+ * takes nothing, returns nothing
+ *
+ * PMAPPROC_SET(struct pmap) returns (bool_t)
+ * TRUE is success, FALSE is failure. Registers the tuple
+ * [prog, vers, prot, port].
+ *
+ * PMAPPROC_UNSET(struct pmap) returns (bool_t)
+ * TRUE is success, FALSE is failure. Un-registers pair
+ * [prog, vers]. prot and port are ignored.
+ *
+ * PMAPPROC_GETPORT(struct pmap) returns (long unsigned).
+ * 0 is failure. Otherwise returns the port number where the pair
+ * [prog, vers] is registered. It may lie!
+ *
+ * PMAPPROC_DUMP() RETURNS (struct pmaplist *)
+ *
+ * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>)
+ * RETURNS (port, string<>);
+ * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs);
+ * Calls the procedure on the local machine. If it is not registered,
+ * this procedure is quite; ie it does not return error information!!!
+ * This procedure only is supported on rpc/udp and calls via
+ * rpc/udp. This routine only passes null authentication parameters.
+ * This file has no interface to xdr routines for PMAPPROC_CALLIT.
+ *
+ * The service supports remote procedure calls on udp/ip or tcp/ip socket 111.
+ */
+
+#define SUNRPC_PMAPPORT ((u_int16_t)111)
+#define SUNRPC_PMAPPROG ((u_int32_t)100000)
+#define SUNRPC_PMAPVERS ((u_int32_t)2)
+#define SUNRPC_PMAPVERS_PROTO ((u_int32_t)2)
+#define SUNRPC_PMAPVERS_ORIG ((u_int32_t)1)
+#define SUNRPC_PMAPPROC_NULL ((u_int32_t)0)
+#define SUNRPC_PMAPPROC_SET ((u_int32_t)1)
+#define SUNRPC_PMAPPROC_UNSET ((u_int32_t)2)
+#define SUNRPC_PMAPPROC_GETPORT ((u_int32_t)3)
+#define SUNRPC_PMAPPROC_DUMP ((u_int32_t)4)
+#define SUNRPC_PMAPPROC_CALLIT ((u_int32_t)5)
+
+struct sunrpc_pmap {
+ u_int32_t pm_prog;
+ u_int32_t pm_vers;
+ u_int32_t pm_prot;
+ u_int32_t pm_port;
+};
diff --git a/freebsd/contrib/tcpdump/ppi.h b/freebsd/contrib/tcpdump/ppi.h
new file mode 100644
index 00000000..733eb950
--- /dev/null
+++ b/freebsd/contrib/tcpdump/ppi.h
@@ -0,0 +1,9 @@
+typedef struct ppi_header {
+ uint8_t ppi_ver;
+ uint8_t ppi_flags;
+ uint16_t ppi_len;
+ uint32_t ppi_dlt;
+} ppi_header_t;
+
+#define PPI_HDRLEN 8
+
diff --git a/freebsd/contrib/tcpdump/ppp.h b/freebsd/contrib/tcpdump/ppp.h
new file mode 100644
index 00000000..3ae519b6
--- /dev/null
+++ b/freebsd/contrib/tcpdump/ppp.h
@@ -0,0 +1,73 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/ppp.h,v 1.16 2004-10-20 16:14:16 hannes Exp $ (LBL) */
+/*
+ * Point to Point Protocol (PPP) RFC1331
+ *
+ * Copyright 1989 by Carnegie Mellon.
+ *
+ * Permission to use, copy, modify, and distribute this program for any
+ * purpose and without fee is hereby granted, provided that this copyright
+ * and permission notice appear on all copies and supporting documentation,
+ * the name of Carnegie Mellon not be used in advertising or publicity
+ * pertaining to distribution of the program without specific prior
+ * permission, and notice be given in supporting documentation that copying
+ * and distribution is by permission of Carnegie Mellon and Stanford
+ * University. Carnegie Mellon makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ *
+ * $FreeBSD$
+ */
+#define PPP_HDRLEN 4 /* length of PPP header */
+
+#define PPP_ADDRESS 0xff /* The address byte value */
+#define PPP_CONTROL 0x03 /* The control byte value */
+
+#define PPP_WITHDIRECTION_IN 0x00 /* non-standard for DLT_PPP_WITHDIRECTION */
+#define PPP_WITHDIRECTION_OUT 0x01 /* non-standard for DLT_PPP_WITHDIRECTION */
+
+/* Protocol numbers */
+#define PPP_IP 0x0021 /* Raw IP */
+#define PPP_OSI 0x0023 /* OSI Network Layer */
+#define PPP_NS 0x0025 /* Xerox NS IDP */
+#define PPP_DECNET 0x0027 /* DECnet Phase IV */
+#define PPP_APPLE 0x0029 /* Appletalk */
+#define PPP_IPX 0x002b /* Novell IPX */
+#define PPP_VJC 0x002d /* Van Jacobson Compressed TCP/IP */
+#define PPP_VJNC 0x002f /* Van Jacobson Uncompressed TCP/IP */
+#define PPP_BRPDU 0x0031 /* Bridging PDU */
+#define PPP_STII 0x0033 /* Stream Protocol (ST-II) */
+#define PPP_VINES 0x0035 /* Banyan Vines */
+#define PPP_ML 0x003d /* Multi-Link PPP */
+#define PPP_IPV6 0x0057 /* IPv6 */
+#define PPP_COMP 0x00fd /* Compressed Datagram */
+
+#define PPP_HELLO 0x0201 /* 802.1d Hello Packets */
+#define PPP_LUXCOM 0x0231 /* Luxcom */
+#define PPP_SNS 0x0233 /* Sigma Network Systems */
+#define PPP_MPLS_UCAST 0x0281 /* rfc 3032 */
+#define PPP_MPLS_MCAST 0x0283 /* rfc 3022 */
+
+#define PPP_IPCP 0x8021 /* IP Control Protocol */
+#define PPP_OSICP 0x8023 /* OSI Network Layer Control Protocol */
+#define PPP_NSCP 0x8025 /* Xerox NS IDP Control Protocol */
+#define PPP_DECNETCP 0x8027 /* DECnet Control Protocol */
+#define PPP_APPLECP 0x8029 /* Appletalk Control Protocol */
+#define PPP_IPXCP 0x802b /* Novell IPX Control Protocol */
+#define PPP_STIICP 0x8033 /* Strean Protocol Control Protocol */
+#define PPP_VINESCP 0x8035 /* Banyan Vines Control Protocol */
+#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */
+#define PPP_CCP 0x80fd /* Compress Control Protocol */
+#define PPP_MPLSCP 0x8281 /* rfc 3022 */
+
+#define PPP_LCP 0xc021 /* Link Control Protocol */
+#define PPP_PAP 0xc023 /* Password Authentication Protocol */
+#define PPP_LQM 0xc025 /* Link Quality Monitoring */
+#define PPP_SPAP 0xc027
+#define PPP_CHAP 0xc223 /* Challenge Handshake Authentication Protocol */
+#define PPP_BACP 0xc02b /* Bandwidth Allocation Control Protocol */
+#define PPP_BAP 0xc02d /* BAP */
+#define PPP_MPCP 0xc03d /* Multi-Link */
+#define PPP_SPAP_OLD 0xc123
+#define PPP_EAP 0xc227
+
+extern struct tok ppptype2str[];
diff --git a/freebsd/contrib/tcpdump/print-802_11.c b/freebsd/contrib/tcpdump/print-802_11.c
new file mode 100644
index 00000000..d0dee658
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-802_11.c
@@ -0,0 +1,2389 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 2001
+ * Fortress Technologies, Inc. All rights reserved.
+ * Charlie Lenahan (clenahan@fortresstech.com)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-802_11.c,v 1.49 2007-12-29 23:25:02 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <pcap.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+
+#include "extract.h"
+
+#include "cpack.h"
+
+#include "ieee802_11.h"
+#include "ieee802_11_radio.h"
+
+/* Radiotap state */
+/* This is used to save state when parsing/processing parameters */
+struct radiotap_state
+{
+ u_int32_t present;
+
+ u_int8_t rate;
+};
+
+#define PRINT_SSID(p) \
+ if (p.ssid_present) { \
+ printf(" ("); \
+ fn_print(p.ssid.ssid, NULL); \
+ printf(")"); \
+ }
+
+#define PRINT_RATE(_sep, _r, _suf) \
+ printf("%s%2.1f%s", _sep, (.5 * ((_r) & 0x7f)), _suf)
+#define PRINT_RATES(p) \
+ if (p.rates_present) { \
+ int z; \
+ const char *sep = " ["; \
+ for (z = 0; z < p.rates.length ; z++) { \
+ PRINT_RATE(sep, p.rates.rate[z], \
+ (p.rates.rate[z] & 0x80 ? "*" : "")); \
+ sep = " "; \
+ } \
+ if (p.rates.length != 0) \
+ printf(" Mbit]"); \
+ }
+
+#define PRINT_DS_CHANNEL(p) \
+ if (p.ds_present) \
+ printf(" CH: %u", p.ds.channel); \
+ printf("%s", \
+ CAPABILITY_PRIVACY(p.capability_info) ? ", PRIVACY" : "" );
+
+#define MAX_MCS_INDEX 76
+
+/*
+ * Indices are:
+ *
+ * the MCS index (0-76);
+ *
+ * 0 for 20 MHz, 1 for 40 MHz;
+ *
+ * 0 for a long guard interval, 1 for a short guard interval.
+ */
+static const float ieee80211_float_htrates[MAX_MCS_INDEX+1][2][2] = {
+ /* MCS 0 */
+ { /* 20 Mhz */ { 6.5, /* SGI */ 7.2, },
+ /* 40 Mhz */ { 13.5, /* SGI */ 15.0, },
+ },
+
+ /* MCS 1 */
+ { /* 20 Mhz */ { 13.0, /* SGI */ 14.4, },
+ /* 40 Mhz */ { 27.0, /* SGI */ 30.0, },
+ },
+
+ /* MCS 2 */
+ { /* 20 Mhz */ { 19.5, /* SGI */ 21.7, },
+ /* 40 Mhz */ { 40.5, /* SGI */ 45.0, },
+ },
+
+ /* MCS 3 */
+ { /* 20 Mhz */ { 26.0, /* SGI */ 28.9, },
+ /* 40 Mhz */ { 54.0, /* SGI */ 60.0, },
+ },
+
+ /* MCS 4 */
+ { /* 20 Mhz */ { 39.0, /* SGI */ 43.3, },
+ /* 40 Mhz */ { 81.0, /* SGI */ 90.0, },
+ },
+
+ /* MCS 5 */
+ { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, },
+ /* 40 Mhz */ { 108.0, /* SGI */ 120.0, },
+ },
+
+ /* MCS 6 */
+ { /* 20 Mhz */ { 58.5, /* SGI */ 65.0, },
+ /* 40 Mhz */ { 121.5, /* SGI */ 135.0, },
+ },
+
+ /* MCS 7 */
+ { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, },
+ /* 40 Mhz */ { 135.0, /* SGI */ 150.0, },
+ },
+
+ /* MCS 8 */
+ { /* 20 Mhz */ { 13.0, /* SGI */ 14.4, },
+ /* 40 Mhz */ { 27.0, /* SGI */ 30.0, },
+ },
+
+ /* MCS 9 */
+ { /* 20 Mhz */ { 26.0, /* SGI */ 28.9, },
+ /* 40 Mhz */ { 54.0, /* SGI */ 60.0, },
+ },
+
+ /* MCS 10 */
+ { /* 20 Mhz */ { 39.0, /* SGI */ 43.3, },
+ /* 40 Mhz */ { 81.0, /* SGI */ 90.0, },
+ },
+
+ /* MCS 11 */
+ { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, },
+ /* 40 Mhz */ { 108.0, /* SGI */ 120.0, },
+ },
+
+ /* MCS 12 */
+ { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, },
+ /* 40 Mhz */ { 162.0, /* SGI */ 180.0, },
+ },
+
+ /* MCS 13 */
+ { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, },
+ /* 40 Mhz */ { 216.0, /* SGI */ 240.0, },
+ },
+
+ /* MCS 14 */
+ { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, },
+ /* 40 Mhz */ { 243.0, /* SGI */ 270.0, },
+ },
+
+ /* MCS 15 */
+ { /* 20 Mhz */ { 130.0, /* SGI */ 144.4, },
+ /* 40 Mhz */ { 270.0, /* SGI */ 300.0, },
+ },
+
+ /* MCS 16 */
+ { /* 20 Mhz */ { 19.5, /* SGI */ 21.7, },
+ /* 40 Mhz */ { 40.5, /* SGI */ 45.0, },
+ },
+
+ /* MCS 17 */
+ { /* 20 Mhz */ { 39.0, /* SGI */ 43.3, },
+ /* 40 Mhz */ { 81.0, /* SGI */ 90.0, },
+ },
+
+ /* MCS 18 */
+ { /* 20 Mhz */ { 58.5, /* SGI */ 65.0, },
+ /* 40 Mhz */ { 121.5, /* SGI */ 135.0, },
+ },
+
+ /* MCS 19 */
+ { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, },
+ /* 40 Mhz */ { 162.0, /* SGI */ 180.0, },
+ },
+
+ /* MCS 20 */
+ { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, },
+ /* 40 Mhz */ { 243.0, /* SGI */ 270.0, },
+ },
+
+ /* MCS 21 */
+ { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, },
+ /* 40 Mhz */ { 324.0, /* SGI */ 360.0, },
+ },
+
+ /* MCS 22 */
+ { /* 20 Mhz */ { 175.5, /* SGI */ 195.0, },
+ /* 40 Mhz */ { 364.5, /* SGI */ 405.0, },
+ },
+
+ /* MCS 23 */
+ { /* 20 Mhz */ { 195.0, /* SGI */ 216.7, },
+ /* 40 Mhz */ { 405.0, /* SGI */ 450.0, },
+ },
+
+ /* MCS 24 */
+ { /* 20 Mhz */ { 26.0, /* SGI */ 28.9, },
+ /* 40 Mhz */ { 54.0, /* SGI */ 60.0, },
+ },
+
+ /* MCS 25 */
+ { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, },
+ /* 40 Mhz */ { 108.0, /* SGI */ 120.0, },
+ },
+
+ /* MCS 26 */
+ { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, },
+ /* 40 Mhz */ { 162.0, /* SGI */ 180.0, },
+ },
+
+ /* MCS 27 */
+ { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, },
+ /* 40 Mhz */ { 216.0, /* SGI */ 240.0, },
+ },
+
+ /* MCS 28 */
+ { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, },
+ /* 40 Mhz */ { 324.0, /* SGI */ 360.0, },
+ },
+
+ /* MCS 29 */
+ { /* 20 Mhz */ { 208.0, /* SGI */ 231.1, },
+ /* 40 Mhz */ { 432.0, /* SGI */ 480.0, },
+ },
+
+ /* MCS 30 */
+ { /* 20 Mhz */ { 234.0, /* SGI */ 260.0, },
+ /* 40 Mhz */ { 486.0, /* SGI */ 540.0, },
+ },
+
+ /* MCS 31 */
+ { /* 20 Mhz */ { 260.0, /* SGI */ 288.9, },
+ /* 40 Mhz */ { 540.0, /* SGI */ 600.0, },
+ },
+
+ /* MCS 32 */
+ { /* 20 Mhz */ { 0.0, /* SGI */ 0.0, }, /* not valid */
+ /* 40 Mhz */ { 6.0, /* SGI */ 6.7, },
+ },
+
+ /* MCS 33 */
+ { /* 20 Mhz */ { 39.0, /* SGI */ 43.3, },
+ /* 40 Mhz */ { 81.0, /* SGI */ 90.0, },
+ },
+
+ /* MCS 34 */
+ { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, },
+ /* 40 Mhz */ { 108.0, /* SGI */ 120.0, },
+ },
+
+ /* MCS 35 */
+ { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, },
+ /* 40 Mhz */ { 135.0, /* SGI */ 150.0, },
+ },
+
+ /* MCS 36 */
+ { /* 20 Mhz */ { 58.5, /* SGI */ 65.0, },
+ /* 40 Mhz */ { 121.5, /* SGI */ 135.0, },
+ },
+
+ /* MCS 37 */
+ { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, },
+ /* 40 Mhz */ { 162.0, /* SGI */ 180.0, },
+ },
+
+ /* MCS 38 */
+ { /* 20 Mhz */ { 97.5, /* SGI */ 108.3, },
+ /* 40 Mhz */ { 202.5, /* SGI */ 225.0, },
+ },
+
+ /* MCS 39 */
+ { /* 20 Mhz */ { 52.0, /* SGI */ 57.8, },
+ /* 40 Mhz */ { 108.0, /* SGI */ 120.0, },
+ },
+
+ /* MCS 40 */
+ { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, },
+ /* 40 Mhz */ { 135.0, /* SGI */ 150.0, },
+ },
+
+ /* MCS 41 */
+ { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, },
+ /* 40 Mhz */ { 135.0, /* SGI */ 150.0, },
+ },
+
+ /* MCS 42 */
+ { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, },
+ /* 40 Mhz */ { 162.0, /* SGI */ 180.0, },
+ },
+
+ /* MCS 43 */
+ { /* 20 Mhz */ { 91.0, /* SGI */ 101.1, },
+ /* 40 Mhz */ { 189.0, /* SGI */ 210.0, },
+ },
+
+ /* MCS 44 */
+ { /* 20 Mhz */ { 91.0, /* SGI */ 101.1, },
+ /* 40 Mhz */ { 189.0, /* SGI */ 210.0, },
+ },
+
+ /* MCS 45 */
+ { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, },
+ /* 40 Mhz */ { 216.0, /* SGI */ 240.0, },
+ },
+
+ /* MCS 46 */
+ { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, },
+ /* 40 Mhz */ { 162.0, /* SGI */ 180.0, },
+ },
+
+ /* MCS 47 */
+ { /* 20 Mhz */ { 97.5, /* SGI */ 108.3, },
+ /* 40 Mhz */ { 202.5, /* SGI */ 225.0, },
+ },
+
+ /* MCS 48 */
+ { /* 20 Mhz */ { 97.5, /* SGI */ 108.3, },
+ /* 40 Mhz */ { 202.5, /* SGI */ 225.0, },
+ },
+
+ /* MCS 49 */
+ { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, },
+ /* 40 Mhz */ { 243.0, /* SGI */ 270.0, },
+ },
+
+ /* MCS 50 */
+ { /* 20 Mhz */ { 136.5, /* SGI */ 151.7, },
+ /* 40 Mhz */ { 283.5, /* SGI */ 315.0, },
+ },
+
+ /* MCS 51 */
+ { /* 20 Mhz */ { 136.5, /* SGI */ 151.7, },
+ /* 40 Mhz */ { 283.5, /* SGI */ 315.0, },
+ },
+
+ /* MCS 52 */
+ { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, },
+ /* 40 Mhz */ { 324.0, /* SGI */ 360.0, },
+ },
+
+ /* MCS 53 */
+ { /* 20 Mhz */ { 65.0, /* SGI */ 72.2, },
+ /* 40 Mhz */ { 135.0, /* SGI */ 150.0, },
+ },
+
+ /* MCS 54 */
+ { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, },
+ /* 40 Mhz */ { 162.0, /* SGI */ 180.0, },
+ },
+
+ /* MCS 55 */
+ { /* 20 Mhz */ { 91.0, /* SGI */ 101.1, },
+ /* 40 Mhz */ { 189.0, /* SGI */ 210.0, },
+ },
+
+ /* MCS 56 */
+ { /* 20 Mhz */ { 78.0, /* SGI */ 86.7, },
+ /* 40 Mhz */ { 162.0, /* SGI */ 180.0, },
+ },
+
+ /* MCS 57 */
+ { /* 20 Mhz */ { 91.0, /* SGI */ 101.1, },
+ /* 40 Mhz */ { 189.0, /* SGI */ 210.0, },
+ },
+
+ /* MCS 58 */
+ { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, },
+ /* 40 Mhz */ { 216.0, /* SGI */ 240.0, },
+ },
+
+ /* MCS 59 */
+ { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, },
+ /* 40 Mhz */ { 243.0, /* SGI */ 270.0, },
+ },
+
+ /* MCS 60 */
+ { /* 20 Mhz */ { 104.0, /* SGI */ 115.6, },
+ /* 40 Mhz */ { 216.0, /* SGI */ 240.0, },
+ },
+
+ /* MCS 61 */
+ { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, },
+ /* 40 Mhz */ { 243.0, /* SGI */ 270.0, },
+ },
+
+ /* MCS 62 */
+ { /* 20 Mhz */ { 130.0, /* SGI */ 144.4, },
+ /* 40 Mhz */ { 270.0, /* SGI */ 300.0, },
+ },
+
+ /* MCS 63 */
+ { /* 20 Mhz */ { 130.0, /* SGI */ 144.4, },
+ /* 40 Mhz */ { 270.0, /* SGI */ 300.0, },
+ },
+
+ /* MCS 64 */
+ { /* 20 Mhz */ { 143.0, /* SGI */ 158.9, },
+ /* 40 Mhz */ { 297.0, /* SGI */ 330.0, },
+ },
+
+ /* MCS 65 */
+ { /* 20 Mhz */ { 97.5, /* SGI */ 108.3, },
+ /* 40 Mhz */ { 202.5, /* SGI */ 225.0, },
+ },
+
+ /* MCS 66 */
+ { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, },
+ /* 40 Mhz */ { 243.0, /* SGI */ 270.0, },
+ },
+
+ /* MCS 67 */
+ { /* 20 Mhz */ { 136.5, /* SGI */ 151.7, },
+ /* 40 Mhz */ { 283.5, /* SGI */ 315.0, },
+ },
+
+ /* MCS 68 */
+ { /* 20 Mhz */ { 117.0, /* SGI */ 130.0, },
+ /* 40 Mhz */ { 243.0, /* SGI */ 270.0, },
+ },
+
+ /* MCS 69 */
+ { /* 20 Mhz */ { 136.5, /* SGI */ 151.7, },
+ /* 40 Mhz */ { 283.5, /* SGI */ 315.0, },
+ },
+
+ /* MCS 70 */
+ { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, },
+ /* 40 Mhz */ { 324.0, /* SGI */ 360.0, },
+ },
+
+ /* MCS 71 */
+ { /* 20 Mhz */ { 175.5, /* SGI */ 195.0, },
+ /* 40 Mhz */ { 364.5, /* SGI */ 405.0, },
+ },
+
+ /* MCS 72 */
+ { /* 20 Mhz */ { 156.0, /* SGI */ 173.3, },
+ /* 40 Mhz */ { 324.0, /* SGI */ 360.0, },
+ },
+
+ /* MCS 73 */
+ { /* 20 Mhz */ { 175.5, /* SGI */ 195.0, },
+ /* 40 Mhz */ { 364.5, /* SGI */ 405.0, },
+ },
+
+ /* MCS 74 */
+ { /* 20 Mhz */ { 195.0, /* SGI */ 216.7, },
+ /* 40 Mhz */ { 405.0, /* SGI */ 450.0, },
+ },
+
+ /* MCS 75 */
+ { /* 20 Mhz */ { 195.0, /* SGI */ 216.7, },
+ /* 40 Mhz */ { 405.0, /* SGI */ 450.0, },
+ },
+
+ /* MCS 76 */
+ { /* 20 Mhz */ { 214.5, /* SGI */ 238.3, },
+ /* 40 Mhz */ { 445.5, /* SGI */ 495.0, },
+ },
+};
+
+static const char *auth_alg_text[]={"Open System","Shared Key","EAP"};
+#define NUM_AUTH_ALGS (sizeof auth_alg_text / sizeof auth_alg_text[0])
+
+static const char *status_text[] = {
+ "Successful", /* 0 */
+ "Unspecified failure", /* 1 */
+ "Reserved", /* 2 */
+ "Reserved", /* 3 */
+ "Reserved", /* 4 */
+ "Reserved", /* 5 */
+ "Reserved", /* 6 */
+ "Reserved", /* 7 */
+ "Reserved", /* 8 */
+ "Reserved", /* 9 */
+ "Cannot Support all requested capabilities in the Capability "
+ "Information field", /* 10 */
+ "Reassociation denied due to inability to confirm that association "
+ "exists", /* 11 */
+ "Association denied due to reason outside the scope of the "
+ "standard", /* 12 */
+ "Responding station does not support the specified authentication "
+ "algorithm ", /* 13 */
+ "Received an Authentication frame with authentication transaction "
+ "sequence number out of expected sequence", /* 14 */
+ "Authentication rejected because of challenge failure", /* 15 */
+ "Authentication rejected due to timeout waiting for next frame in "
+ "sequence", /* 16 */
+ "Association denied because AP is unable to handle additional"
+ "associated stations", /* 17 */
+ "Association denied due to requesting station not supporting all of "
+ "the data rates in BSSBasicRateSet parameter", /* 18 */
+ "Association denied due to requesting station not supporting "
+ "short preamble operation", /* 19 */
+ "Association denied due to requesting station not supporting "
+ "PBCC encoding", /* 20 */
+ "Association denied due to requesting station not supporting "
+ "channel agility", /* 21 */
+ "Association request rejected because Spectrum Management "
+ "capability is required", /* 22 */
+ "Association request rejected because the information in the "
+ "Power Capability element is unacceptable", /* 23 */
+ "Association request rejected because the information in the "
+ "Supported Channels element is unacceptable", /* 24 */
+ "Association denied due to requesting station not supporting "
+ "short slot operation", /* 25 */
+ "Association denied due to requesting station not supporting "
+ "DSSS-OFDM operation", /* 26 */
+ "Association denied because the requested STA does not support HT "
+ "features", /* 27 */
+ "Reserved", /* 28 */
+ "Association denied because the requested STA does not support "
+ "the PCO transition time required by the AP", /* 29 */
+ "Reserved", /* 30 */
+ "Reserved", /* 31 */
+ "Unspecified, QoS-related failure", /* 32 */
+ "Association denied due to QAP having insufficient bandwidth "
+ "to handle another QSTA", /* 33 */
+ "Association denied due to excessive frame loss rates and/or "
+ "poor conditions on current operating channel", /* 34 */
+ "Association (with QBSS) denied due to requesting station not "
+ "supporting the QoS facility", /* 35 */
+ "Association denied due to requesting station not supporting "
+ "Block Ack", /* 36 */
+ "The request has been declined", /* 37 */
+ "The request has not been successful as one or more parameters "
+ "have invalid values", /* 38 */
+ "The TS has not been created because the request cannot be honored. "
+ "However, a suggested TSPEC is provided so that the initiating QSTA"
+ "may attempt to set another TS with the suggested changes to the "
+ "TSPEC", /* 39 */
+ "Invalid Information Element", /* 40 */
+ "Group Cipher is not valid", /* 41 */
+ "Pairwise Cipher is not valid", /* 42 */
+ "AKMP is not valid", /* 43 */
+ "Unsupported RSN IE version", /* 44 */
+ "Invalid RSN IE Capabilities", /* 45 */
+ "Cipher suite is rejected per security policy", /* 46 */
+ "The TS has not been created. However, the HC may be capable of "
+ "creating a TS, in response to a request, after the time indicated "
+ "in the TS Delay element", /* 47 */
+ "Direct Link is not allowed in the BSS by policy", /* 48 */
+ "Destination STA is not present within this QBSS.", /* 49 */
+ "The Destination STA is not a QSTA.", /* 50 */
+
+};
+#define NUM_STATUSES (sizeof status_text / sizeof status_text[0])
+
+static const char *reason_text[] = {
+ "Reserved", /* 0 */
+ "Unspecified reason", /* 1 */
+ "Previous authentication no longer valid", /* 2 */
+ "Deauthenticated because sending station is leaving (or has left) "
+ "IBSS or ESS", /* 3 */
+ "Disassociated due to inactivity", /* 4 */
+ "Disassociated because AP is unable to handle all currently "
+ " associated stations", /* 5 */
+ "Class 2 frame received from nonauthenticated station", /* 6 */
+ "Class 3 frame received from nonassociated station", /* 7 */
+ "Disassociated because sending station is leaving "
+ "(or has left) BSS", /* 8 */
+ "Station requesting (re)association is not authenticated with "
+ "responding station", /* 9 */
+ "Disassociated because the information in the Power Capability "
+ "element is unacceptable", /* 10 */
+ "Disassociated because the information in the SupportedChannels "
+ "element is unacceptable", /* 11 */
+ "Invalid Information Element", /* 12 */
+ "Reserved", /* 13 */
+ "Michael MIC failure", /* 14 */
+ "4-Way Handshake timeout", /* 15 */
+ "Group key update timeout", /* 16 */
+ "Information element in 4-Way Handshake different from (Re)Association"
+ "Request/Probe Response/Beacon", /* 17 */
+ "Group Cipher is not valid", /* 18 */
+ "AKMP is not valid", /* 20 */
+ "Unsupported RSN IE version", /* 21 */
+ "Invalid RSN IE Capabilities", /* 22 */
+ "IEEE 802.1X Authentication failed", /* 23 */
+ "Cipher suite is rejected per security policy", /* 24 */
+ "Reserved", /* 25 */
+ "Reserved", /* 26 */
+ "Reserved", /* 27 */
+ "Reserved", /* 28 */
+ "Reserved", /* 29 */
+ "Reserved", /* 30 */
+ "TS deleted because QoS AP lacks sufficient bandwidth for this "
+ "QoS STA due to a change in BSS service characteristics or "
+ "operational mode (e.g. an HT BSS change from 40 MHz channel "
+ "to 20 MHz channel)", /* 31 */
+ "Disassociated for unspecified, QoS-related reason", /* 32 */
+ "Disassociated because QoS AP lacks sufficient bandwidth for this "
+ "QoS STA", /* 33 */
+ "Disassociated because of excessive number of frames that need to be "
+ "acknowledged, but are not acknowledged for AP transmissions "
+ "and/or poor channel conditions", /* 34 */
+ "Disassociated because STA is transmitting outside the limits "
+ "of its TXOPs", /* 35 */
+ "Requested from peer STA as the STA is leaving the BSS "
+ "(or resetting)", /* 36 */
+ "Requested from peer STA as it does not want to use the "
+ "mechanism", /* 37 */
+ "Requested from peer STA as the STA received frames using the "
+ "mechanism for which a set up is required", /* 38 */
+ "Requested from peer STA due to time out", /* 39 */
+ "Reserved", /* 40 */
+ "Reserved", /* 41 */
+ "Reserved", /* 42 */
+ "Reserved", /* 43 */
+ "Reserved", /* 44 */
+ "Peer STA does not support the requested cipher suite", /* 45 */
+ "Association denied due to requesting STA not supporting HT "
+ "features", /* 46 */
+};
+#define NUM_REASONS (sizeof reason_text / sizeof reason_text[0])
+
+static int
+wep_print(const u_char *p)
+{
+ u_int32_t iv;
+
+ if (!TTEST2(*p, IEEE802_11_IV_LEN + IEEE802_11_KID_LEN))
+ return 0;
+ iv = EXTRACT_LE_32BITS(p);
+
+ printf("Data IV:%3x Pad %x KeyID %x", IV_IV(iv), IV_PAD(iv),
+ IV_KEYID(iv));
+
+ return 1;
+}
+
+static int
+parse_elements(struct mgmt_body_t *pbody, const u_char *p, int offset,
+ u_int length)
+{
+ u_int elementlen;
+ struct ssid_t ssid;
+ struct challenge_t challenge;
+ struct rates_t rates;
+ struct ds_t ds;
+ struct cf_t cf;
+ struct tim_t tim;
+
+ /*
+ * We haven't seen any elements yet.
+ */
+ pbody->challenge_present = 0;
+ pbody->ssid_present = 0;
+ pbody->rates_present = 0;
+ pbody->ds_present = 0;
+ pbody->cf_present = 0;
+ pbody->tim_present = 0;
+
+ while (length != 0) {
+ if (!TTEST2(*(p + offset), 1))
+ return 0;
+ if (length < 1)
+ return 0;
+ switch (*(p + offset)) {
+ case E_SSID:
+ if (!TTEST2(*(p + offset), 2))
+ return 0;
+ if (length < 2)
+ return 0;
+ memcpy(&ssid, p + offset, 2);
+ offset += 2;
+ length -= 2;
+ if (ssid.length != 0) {
+ if (ssid.length > sizeof(ssid.ssid) - 1)
+ return 0;
+ if (!TTEST2(*(p + offset), ssid.length))
+ return 0;
+ if (length < ssid.length)
+ return 0;
+ memcpy(&ssid.ssid, p + offset, ssid.length);
+ offset += ssid.length;
+ length -= ssid.length;
+ }
+ ssid.ssid[ssid.length] = '\0';
+ /*
+ * Present and not truncated.
+ *
+ * If we haven't already seen an SSID IE,
+ * copy this one, otherwise ignore this one,
+ * so we later report the first one we saw.
+ */
+ if (!pbody->ssid_present) {
+ pbody->ssid = ssid;
+ pbody->ssid_present = 1;
+ }
+ break;
+ case E_CHALLENGE:
+ if (!TTEST2(*(p + offset), 2))
+ return 0;
+ if (length < 2)
+ return 0;
+ memcpy(&challenge, p + offset, 2);
+ offset += 2;
+ length -= 2;
+ if (challenge.length != 0) {
+ if (challenge.length >
+ sizeof(challenge.text) - 1)
+ return 0;
+ if (!TTEST2(*(p + offset), challenge.length))
+ return 0;
+ if (length < challenge.length)
+ return 0;
+ memcpy(&challenge.text, p + offset,
+ challenge.length);
+ offset += challenge.length;
+ length -= challenge.length;
+ }
+ challenge.text[challenge.length] = '\0';
+ /*
+ * Present and not truncated.
+ *
+ * If we haven't already seen a challenge IE,
+ * copy this one, otherwise ignore this one,
+ * so we later report the first one we saw.
+ */
+ if (!pbody->challenge_present) {
+ pbody->challenge = challenge;
+ pbody->challenge_present = 1;
+ }
+ break;
+ case E_RATES:
+ if (!TTEST2(*(p + offset), 2))
+ return 0;
+ if (length < 2)
+ return 0;
+ memcpy(&rates, p + offset, 2);
+ offset += 2;
+ length -= 2;
+ if (rates.length != 0) {
+ if (rates.length > sizeof rates.rate)
+ return 0;
+ if (!TTEST2(*(p + offset), rates.length))
+ return 0;
+ if (length < rates.length)
+ return 0;
+ memcpy(&rates.rate, p + offset, rates.length);
+ offset += rates.length;
+ length -= rates.length;
+ }
+ /*
+ * Present and not truncated.
+ *
+ * If we haven't already seen a rates IE,
+ * copy this one if it's not zero-length,
+ * otherwise ignore this one, so we later
+ * report the first one we saw.
+ *
+ * We ignore zero-length rates IEs as some
+ * devices seem to put a zero-length rates
+ * IE, followed by an SSID IE, followed by
+ * a non-zero-length rates IE into frames,
+ * even though IEEE Std 802.11-2007 doesn't
+ * seem to indicate that a zero-length rates
+ * IE is valid.
+ */
+ if (!pbody->rates_present && rates.length != 0) {
+ pbody->rates = rates;
+ pbody->rates_present = 1;
+ }
+ break;
+ case E_DS:
+ if (!TTEST2(*(p + offset), 3))
+ return 0;
+ if (length < 3)
+ return 0;
+ memcpy(&ds, p + offset, 3);
+ offset += 3;
+ length -= 3;
+ /*
+ * Present and not truncated.
+ *
+ * If we haven't already seen a DS IE,
+ * copy this one, otherwise ignore this one,
+ * so we later report the first one we saw.
+ */
+ if (!pbody->ds_present) {
+ pbody->ds = ds;
+ pbody->ds_present = 1;
+ }
+ break;
+ case E_CF:
+ if (!TTEST2(*(p + offset), 8))
+ return 0;
+ if (length < 8)
+ return 0;
+ memcpy(&cf, p + offset, 8);
+ offset += 8;
+ length -= 8;
+ /*
+ * Present and not truncated.
+ *
+ * If we haven't already seen a CF IE,
+ * copy this one, otherwise ignore this one,
+ * so we later report the first one we saw.
+ */
+ if (!pbody->cf_present) {
+ pbody->cf = cf;
+ pbody->cf_present = 1;
+ }
+ break;
+ case E_TIM:
+ if (!TTEST2(*(p + offset), 2))
+ return 0;
+ if (length < 2)
+ return 0;
+ memcpy(&tim, p + offset, 2);
+ offset += 2;
+ length -= 2;
+ if (!TTEST2(*(p + offset), 3))
+ return 0;
+ if (length < 3)
+ return 0;
+ memcpy(&tim.count, p + offset, 3);
+ offset += 3;
+ length -= 3;
+
+ if (tim.length <= 3)
+ break;
+ if (tim.length - 3 > (int)sizeof tim.bitmap)
+ return 0;
+ if (!TTEST2(*(p + offset), tim.length - 3))
+ return 0;
+ if (length < (u_int)(tim.length - 3))
+ return 0;
+ memcpy(tim.bitmap, p + (tim.length - 3),
+ (tim.length - 3));
+ offset += tim.length - 3;
+ length -= tim.length - 3;
+ /*
+ * Present and not truncated.
+ *
+ * If we haven't already seen a TIM IE,
+ * copy this one, otherwise ignore this one,
+ * so we later report the first one we saw.
+ */
+ if (!pbody->tim_present) {
+ pbody->tim = tim;
+ pbody->tim_present = 1;
+ }
+ break;
+ default:
+#if 0
+ printf("(1) unhandled element_id (%d) ",
+ *(p + offset));
+#endif
+ if (!TTEST2(*(p + offset), 2))
+ return 0;
+ if (length < 2)
+ return 0;
+ elementlen = *(p + offset + 1);
+ if (!TTEST2(*(p + offset + 2), elementlen))
+ return 0;
+ if (length < elementlen + 2)
+ return 0;
+ offset += elementlen + 2;
+ length -= elementlen + 2;
+ break;
+ }
+ }
+
+ /* No problems found. */
+ return 1;
+}
+
+/*********************************************************************************
+ * Print Handle functions for the management frame types
+ *********************************************************************************/
+
+static int
+handle_beacon(const u_char *p, u_int length)
+{
+ struct mgmt_body_t pbody;
+ int offset = 0;
+ int ret;
+
+ memset(&pbody, 0, sizeof(pbody));
+
+ if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
+ IEEE802_11_CAPINFO_LEN))
+ return 0;
+ if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
+ IEEE802_11_CAPINFO_LEN)
+ return 0;
+ memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
+ offset += IEEE802_11_TSTAMP_LEN;
+ length -= IEEE802_11_TSTAMP_LEN;
+ pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
+ offset += IEEE802_11_BCNINT_LEN;
+ length -= IEEE802_11_BCNINT_LEN;
+ pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
+ offset += IEEE802_11_CAPINFO_LEN;
+ length -= IEEE802_11_CAPINFO_LEN;
+
+ ret = parse_elements(&pbody, p, offset, length);
+
+ PRINT_SSID(pbody);
+ PRINT_RATES(pbody);
+ printf(" %s",
+ CAPABILITY_ESS(pbody.capability_info) ? "ESS" : "IBSS");
+ PRINT_DS_CHANNEL(pbody);
+
+ return ret;
+}
+
+static int
+handle_assoc_request(const u_char *p, u_int length)
+{
+ struct mgmt_body_t pbody;
+ int offset = 0;
+ int ret;
+
+ memset(&pbody, 0, sizeof(pbody));
+
+ if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN))
+ return 0;
+ if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN)
+ return 0;
+ pbody.capability_info = EXTRACT_LE_16BITS(p);
+ offset += IEEE802_11_CAPINFO_LEN;
+ length -= IEEE802_11_CAPINFO_LEN;
+ pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
+ offset += IEEE802_11_LISTENINT_LEN;
+ length -= IEEE802_11_LISTENINT_LEN;
+
+ ret = parse_elements(&pbody, p, offset, length);
+
+ PRINT_SSID(pbody);
+ PRINT_RATES(pbody);
+ return ret;
+}
+
+static int
+handle_assoc_response(const u_char *p, u_int length)
+{
+ struct mgmt_body_t pbody;
+ int offset = 0;
+ int ret;
+
+ memset(&pbody, 0, sizeof(pbody));
+
+ if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
+ IEEE802_11_AID_LEN))
+ return 0;
+ if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_STATUS_LEN +
+ IEEE802_11_AID_LEN)
+ return 0;
+ pbody.capability_info = EXTRACT_LE_16BITS(p);
+ offset += IEEE802_11_CAPINFO_LEN;
+ length -= IEEE802_11_CAPINFO_LEN;
+ pbody.status_code = EXTRACT_LE_16BITS(p+offset);
+ offset += IEEE802_11_STATUS_LEN;
+ length -= IEEE802_11_STATUS_LEN;
+ pbody.aid = EXTRACT_LE_16BITS(p+offset);
+ offset += IEEE802_11_AID_LEN;
+ length -= IEEE802_11_AID_LEN;
+
+ ret = parse_elements(&pbody, p, offset, length);
+
+ printf(" AID(%x) :%s: %s", ((u_int16_t)(pbody.aid << 2 )) >> 2 ,
+ CAPABILITY_PRIVACY(pbody.capability_info) ? " PRIVACY " : "",
+ (pbody.status_code < NUM_STATUSES
+ ? status_text[pbody.status_code]
+ : "n/a"));
+
+ return ret;
+}
+
+static int
+handle_reassoc_request(const u_char *p, u_int length)
+{
+ struct mgmt_body_t pbody;
+ int offset = 0;
+ int ret;
+
+ memset(&pbody, 0, sizeof(pbody));
+
+ if (!TTEST2(*p, IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
+ IEEE802_11_AP_LEN))
+ return 0;
+ if (length < IEEE802_11_CAPINFO_LEN + IEEE802_11_LISTENINT_LEN +
+ IEEE802_11_AP_LEN)
+ return 0;
+ pbody.capability_info = EXTRACT_LE_16BITS(p);
+ offset += IEEE802_11_CAPINFO_LEN;
+ length -= IEEE802_11_CAPINFO_LEN;
+ pbody.listen_interval = EXTRACT_LE_16BITS(p+offset);
+ offset += IEEE802_11_LISTENINT_LEN;
+ length -= IEEE802_11_LISTENINT_LEN;
+ memcpy(&pbody.ap, p+offset, IEEE802_11_AP_LEN);
+ offset += IEEE802_11_AP_LEN;
+ length -= IEEE802_11_AP_LEN;
+
+ ret = parse_elements(&pbody, p, offset, length);
+
+ PRINT_SSID(pbody);
+ printf(" AP : %s", etheraddr_string( pbody.ap ));
+
+ return ret;
+}
+
+static int
+handle_reassoc_response(const u_char *p, u_int length)
+{
+ /* Same as a Association Reponse */
+ return handle_assoc_response(p, length);
+}
+
+static int
+handle_probe_request(const u_char *p, u_int length)
+{
+ struct mgmt_body_t pbody;
+ int offset = 0;
+ int ret;
+
+ memset(&pbody, 0, sizeof(pbody));
+
+ ret = parse_elements(&pbody, p, offset, length);
+
+ PRINT_SSID(pbody);
+ PRINT_RATES(pbody);
+
+ return ret;
+}
+
+static int
+handle_probe_response(const u_char *p, u_int length)
+{
+ struct mgmt_body_t pbody;
+ int offset = 0;
+ int ret;
+
+ memset(&pbody, 0, sizeof(pbody));
+
+ if (!TTEST2(*p, IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
+ IEEE802_11_CAPINFO_LEN))
+ return 0;
+ if (length < IEEE802_11_TSTAMP_LEN + IEEE802_11_BCNINT_LEN +
+ IEEE802_11_CAPINFO_LEN)
+ return 0;
+ memcpy(&pbody.timestamp, p, IEEE802_11_TSTAMP_LEN);
+ offset += IEEE802_11_TSTAMP_LEN;
+ length -= IEEE802_11_TSTAMP_LEN;
+ pbody.beacon_interval = EXTRACT_LE_16BITS(p+offset);
+ offset += IEEE802_11_BCNINT_LEN;
+ length -= IEEE802_11_BCNINT_LEN;
+ pbody.capability_info = EXTRACT_LE_16BITS(p+offset);
+ offset += IEEE802_11_CAPINFO_LEN;
+ length -= IEEE802_11_CAPINFO_LEN;
+
+ ret = parse_elements(&pbody, p, offset, length);
+
+ PRINT_SSID(pbody);
+ PRINT_RATES(pbody);
+ PRINT_DS_CHANNEL(pbody);
+
+ return ret;
+}
+
+static int
+handle_atim(void)
+{
+ /* the frame body for ATIM is null. */
+ return 1;
+}
+
+static int
+handle_disassoc(const u_char *p, u_int length)
+{
+ struct mgmt_body_t pbody;
+
+ memset(&pbody, 0, sizeof(pbody));
+
+ if (!TTEST2(*p, IEEE802_11_REASON_LEN))
+ return 0;
+ if (length < IEEE802_11_REASON_LEN)
+ return 0;
+ pbody.reason_code = EXTRACT_LE_16BITS(p);
+
+ printf(": %s",
+ (pbody.reason_code < NUM_REASONS)
+ ? reason_text[pbody.reason_code]
+ : "Reserved" );
+
+ return 1;
+}
+
+static int
+handle_auth(const u_char *p, u_int length)
+{
+ struct mgmt_body_t pbody;
+ int offset = 0;
+ int ret;
+
+ memset(&pbody, 0, sizeof(pbody));
+
+ if (!TTEST2(*p, 6))
+ return 0;
+ if (length < 6)
+ return 0;
+ pbody.auth_alg = EXTRACT_LE_16BITS(p);
+ offset += 2;
+ length -= 2;
+ pbody.auth_trans_seq_num = EXTRACT_LE_16BITS(p + offset);
+ offset += 2;
+ length -= 2;
+ pbody.status_code = EXTRACT_LE_16BITS(p + offset);
+ offset += 2;
+ length -= 2;
+
+ ret = parse_elements(&pbody, p, offset, length);
+
+ if ((pbody.auth_alg == 1) &&
+ ((pbody.auth_trans_seq_num == 2) ||
+ (pbody.auth_trans_seq_num == 3))) {
+ printf(" (%s)-%x [Challenge Text] %s",
+ (pbody.auth_alg < NUM_AUTH_ALGS)
+ ? auth_alg_text[pbody.auth_alg]
+ : "Reserved",
+ pbody.auth_trans_seq_num,
+ ((pbody.auth_trans_seq_num % 2)
+ ? ((pbody.status_code < NUM_STATUSES)
+ ? status_text[pbody.status_code]
+ : "n/a") : ""));
+ return ret;
+ }
+ printf(" (%s)-%x: %s",
+ (pbody.auth_alg < NUM_AUTH_ALGS)
+ ? auth_alg_text[pbody.auth_alg]
+ : "Reserved",
+ pbody.auth_trans_seq_num,
+ (pbody.auth_trans_seq_num % 2)
+ ? ((pbody.status_code < NUM_STATUSES)
+ ? status_text[pbody.status_code]
+ : "n/a")
+ : "");
+
+ return ret;
+}
+
+static int
+handle_deauth(const struct mgmt_header_t *pmh, const u_char *p, u_int length)
+{
+ struct mgmt_body_t pbody;
+ int offset = 0;
+ const char *reason = NULL;
+
+ memset(&pbody, 0, sizeof(pbody));
+
+ if (!TTEST2(*p, IEEE802_11_REASON_LEN))
+ return 0;
+ if (length < IEEE802_11_REASON_LEN)
+ return 0;
+ pbody.reason_code = EXTRACT_LE_16BITS(p);
+ offset += IEEE802_11_REASON_LEN;
+ length -= IEEE802_11_REASON_LEN;
+
+ reason = (pbody.reason_code < NUM_REASONS)
+ ? reason_text[pbody.reason_code]
+ : "Reserved";
+
+ if (eflag) {
+ printf(": %s", reason);
+ } else {
+ printf(" (%s): %s", etheraddr_string(pmh->sa), reason);
+ }
+ return 1;
+}
+
+#define PRINT_HT_ACTION(v) (\
+ (v) == 0 ? printf("TxChWidth") : \
+ (v) == 1 ? printf("MIMOPwrSave") : \
+ printf("Act#%d", (v)) \
+)
+#define PRINT_BA_ACTION(v) (\
+ (v) == 0 ? printf("ADDBA Request") : \
+ (v) == 1 ? printf("ADDBA Response") : \
+ (v) == 2 ? printf("DELBA") : \
+ printf("Act#%d", (v)) \
+)
+#define PRINT_MESHLINK_ACTION(v) (\
+ (v) == 0 ? printf("Request") : \
+ (v) == 1 ? printf("Report") : \
+ printf("Act#%d", (v)) \
+)
+#define PRINT_MESHPEERING_ACTION(v) (\
+ (v) == 0 ? printf("Open") : \
+ (v) == 1 ? printf("Confirm") : \
+ (v) == 2 ? printf("Close") : \
+ printf("Act#%d", (v)) \
+)
+#define PRINT_MESHPATH_ACTION(v) (\
+ (v) == 0 ? printf("Request") : \
+ (v) == 1 ? printf("Report") : \
+ (v) == 2 ? printf("Error") : \
+ (v) == 3 ? printf("RootAnnouncement") : \
+ printf("Act#%d", (v)) \
+)
+
+#define PRINT_MESH_ACTION(v) (\
+ (v) == 0 ? printf("MeshLink") : \
+ (v) == 1 ? printf("HWMP") : \
+ (v) == 2 ? printf("Gate Announcement") : \
+ (v) == 3 ? printf("Congestion Control") : \
+ (v) == 4 ? printf("MCCA Setup Request") : \
+ (v) == 5 ? printf("MCCA Setup Reply") : \
+ (v) == 6 ? printf("MCCA Advertisement Request") : \
+ (v) == 7 ? printf("MCCA Advertisement") : \
+ (v) == 8 ? printf("MCCA Teardown") : \
+ (v) == 9 ? printf("TBTT Adjustment Request") : \
+ (v) == 10 ? printf("TBTT Adjustment Response") : \
+ printf("Act#%d", (v)) \
+)
+#define PRINT_MULTIHOP_ACTION(v) (\
+ (v) == 0 ? printf("Proxy Update") : \
+ (v) == 1 ? printf("Proxy Update Confirmation") : \
+ printf("Act#%d", (v)) \
+)
+#define PRINT_SELFPROT_ACTION(v) (\
+ (v) == 1 ? printf("Peering Open") : \
+ (v) == 2 ? printf("Peering Confirm") : \
+ (v) == 3 ? printf("Peering Close") : \
+ (v) == 4 ? printf("Group Key Inform") : \
+ (v) == 5 ? printf("Group Key Acknowledge") : \
+ printf("Act#%d", (v)) \
+)
+
+static int
+handle_action(const struct mgmt_header_t *pmh, const u_char *p, u_int length)
+{
+ if (!TTEST2(*p, 2))
+ return 0;
+ if (length < 2)
+ return 0;
+ if (eflag) {
+ printf(": ");
+ } else {
+ printf(" (%s): ", etheraddr_string(pmh->sa));
+ }
+ switch (p[0]) {
+ case 0: printf("Spectrum Management Act#%d", p[1]); break;
+ case 1: printf("QoS Act#%d", p[1]); break;
+ case 2: printf("DLS Act#%d", p[1]); break;
+ case 3: printf("BA "); PRINT_BA_ACTION(p[1]); break;
+ case 7: printf("HT "); PRINT_HT_ACTION(p[1]); break;
+ case 13: printf("MeshAction "); PRINT_MESH_ACTION(p[1]); break;
+ case 14:
+ printf("MultiohopAction ");
+ PRINT_MULTIHOP_ACTION(p[1]); break;
+ case 15:
+ printf("SelfprotectAction ");
+ PRINT_SELFPROT_ACTION(p[1]); break;
+ case 127: printf("Vendor Act#%d", p[1]); break;
+ default:
+ printf("Reserved(%d) Act#%d", p[0], p[1]);
+ break;
+ }
+ return 1;
+}
+
+
+/*********************************************************************************
+ * Print Body funcs
+ *********************************************************************************/
+
+
+static int
+mgmt_body_print(u_int16_t fc, const struct mgmt_header_t *pmh,
+ const u_char *p, u_int length)
+{
+ switch (FC_SUBTYPE(fc)) {
+ case ST_ASSOC_REQUEST:
+ printf("Assoc Request");
+ return handle_assoc_request(p, length);
+ case ST_ASSOC_RESPONSE:
+ printf("Assoc Response");
+ return handle_assoc_response(p, length);
+ case ST_REASSOC_REQUEST:
+ printf("ReAssoc Request");
+ return handle_reassoc_request(p, length);
+ case ST_REASSOC_RESPONSE:
+ printf("ReAssoc Response");
+ return handle_reassoc_response(p, length);
+ case ST_PROBE_REQUEST:
+ printf("Probe Request");
+ return handle_probe_request(p, length);
+ case ST_PROBE_RESPONSE:
+ printf("Probe Response");
+ return handle_probe_response(p, length);
+ case ST_BEACON:
+ printf("Beacon");
+ return handle_beacon(p, length);
+ case ST_ATIM:
+ printf("ATIM");
+ return handle_atim();
+ case ST_DISASSOC:
+ printf("Disassociation");
+ return handle_disassoc(p, length);
+ case ST_AUTH:
+ printf("Authentication");
+ if (!TTEST2(*p, 3))
+ return 0;
+ if ((p[0] == 0 ) && (p[1] == 0) && (p[2] == 0)) {
+ printf("Authentication (Shared-Key)-3 ");
+ return wep_print(p);
+ }
+ return handle_auth(p, length);
+ case ST_DEAUTH:
+ printf("DeAuthentication");
+ return handle_deauth(pmh, p, length);
+ break;
+ case ST_ACTION:
+ printf("Action");
+ return handle_action(pmh, p, length);
+ break;
+ default:
+ printf("Unhandled Management subtype(%x)",
+ FC_SUBTYPE(fc));
+ return 1;
+ }
+}
+
+
+/*********************************************************************************
+ * Handles printing all the control frame types
+ *********************************************************************************/
+
+static int
+ctrl_body_print(u_int16_t fc, const u_char *p)
+{
+ switch (FC_SUBTYPE(fc)) {
+ case CTRL_CONTROL_WRAPPER:
+ printf("Control Wrapper");
+ /* XXX - requires special handling */
+ break;
+ case CTRL_BAR:
+ printf("BAR");
+ if (!TTEST2(*p, CTRL_BAR_HDRLEN))
+ return 0;
+ if (!eflag)
+ printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
+ etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
+ etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
+ EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
+ EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
+ break;
+ case CTRL_BA:
+ printf("BA");
+ if (!TTEST2(*p, CTRL_BA_HDRLEN))
+ return 0;
+ if (!eflag)
+ printf(" RA:%s ",
+ etheraddr_string(((const struct ctrl_ba_t *)p)->ra));
+ break;
+ case CTRL_PS_POLL:
+ printf("Power Save-Poll");
+ if (!TTEST2(*p, CTRL_PS_POLL_HDRLEN))
+ return 0;
+ printf(" AID(%x)",
+ EXTRACT_LE_16BITS(&(((const struct ctrl_ps_poll_t *)p)->aid)));
+ break;
+ case CTRL_RTS:
+ printf("Request-To-Send");
+ if (!TTEST2(*p, CTRL_RTS_HDRLEN))
+ return 0;
+ if (!eflag)
+ printf(" TA:%s ",
+ etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
+ break;
+ case CTRL_CTS:
+ printf("Clear-To-Send");
+ if (!TTEST2(*p, CTRL_CTS_HDRLEN))
+ return 0;
+ if (!eflag)
+ printf(" RA:%s ",
+ etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
+ break;
+ case CTRL_ACK:
+ printf("Acknowledgment");
+ if (!TTEST2(*p, CTRL_ACK_HDRLEN))
+ return 0;
+ if (!eflag)
+ printf(" RA:%s ",
+ etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
+ break;
+ case CTRL_CF_END:
+ printf("CF-End");
+ if (!TTEST2(*p, CTRL_END_HDRLEN))
+ return 0;
+ if (!eflag)
+ printf(" RA:%s ",
+ etheraddr_string(((const struct ctrl_end_t *)p)->ra));
+ break;
+ case CTRL_END_ACK:
+ printf("CF-End+CF-Ack");
+ if (!TTEST2(*p, CTRL_END_ACK_HDRLEN))
+ return 0;
+ if (!eflag)
+ printf(" RA:%s ",
+ etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra));
+ break;
+ default:
+ printf("Unknown Ctrl Subtype");
+ }
+ return 1;
+}
+
+/*
+ * Print Header funcs
+ */
+
+/*
+ * Data Frame - Address field contents
+ *
+ * To Ds | From DS | Addr 1 | Addr 2 | Addr 3 | Addr 4
+ * 0 | 0 | DA | SA | BSSID | n/a
+ * 0 | 1 | DA | BSSID | SA | n/a
+ * 1 | 0 | BSSID | SA | DA | n/a
+ * 1 | 1 | RA | TA | DA | SA
+ */
+
+static void
+data_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
+ const u_int8_t **dstp)
+{
+ u_int subtype = FC_SUBTYPE(fc);
+
+ if (DATA_FRAME_IS_CF_ACK(subtype) || DATA_FRAME_IS_CF_POLL(subtype) ||
+ DATA_FRAME_IS_QOS(subtype)) {
+ printf("CF ");
+ if (DATA_FRAME_IS_CF_ACK(subtype)) {
+ if (DATA_FRAME_IS_CF_POLL(subtype))
+ printf("Ack/Poll");
+ else
+ printf("Ack");
+ } else {
+ if (DATA_FRAME_IS_CF_POLL(subtype))
+ printf("Poll");
+ }
+ if (DATA_FRAME_IS_QOS(subtype))
+ printf("+QoS");
+ printf(" ");
+ }
+
+#define ADDR1 (p + 4)
+#define ADDR2 (p + 10)
+#define ADDR3 (p + 16)
+#define ADDR4 (p + 24)
+
+ if (!FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
+ if (srcp != NULL)
+ *srcp = ADDR2;
+ if (dstp != NULL)
+ *dstp = ADDR1;
+ if (!eflag)
+ return;
+ printf("DA:%s SA:%s BSSID:%s ",
+ etheraddr_string(ADDR1), etheraddr_string(ADDR2),
+ etheraddr_string(ADDR3));
+ } else if (!FC_TO_DS(fc) && FC_FROM_DS(fc)) {
+ if (srcp != NULL)
+ *srcp = ADDR3;
+ if (dstp != NULL)
+ *dstp = ADDR1;
+ if (!eflag)
+ return;
+ printf("DA:%s BSSID:%s SA:%s ",
+ etheraddr_string(ADDR1), etheraddr_string(ADDR2),
+ etheraddr_string(ADDR3));
+ } else if (FC_TO_DS(fc) && !FC_FROM_DS(fc)) {
+ if (srcp != NULL)
+ *srcp = ADDR2;
+ if (dstp != NULL)
+ *dstp = ADDR3;
+ if (!eflag)
+ return;
+ printf("BSSID:%s SA:%s DA:%s ",
+ etheraddr_string(ADDR1), etheraddr_string(ADDR2),
+ etheraddr_string(ADDR3));
+ } else if (FC_TO_DS(fc) && FC_FROM_DS(fc)) {
+ if (srcp != NULL)
+ *srcp = ADDR4;
+ if (dstp != NULL)
+ *dstp = ADDR3;
+ if (!eflag)
+ return;
+ printf("RA:%s TA:%s DA:%s SA:%s ",
+ etheraddr_string(ADDR1), etheraddr_string(ADDR2),
+ etheraddr_string(ADDR3), etheraddr_string(ADDR4));
+ }
+
+#undef ADDR1
+#undef ADDR2
+#undef ADDR3
+#undef ADDR4
+}
+
+static void
+mgmt_header_print(const u_char *p, const u_int8_t **srcp,
+ const u_int8_t **dstp)
+{
+ const struct mgmt_header_t *hp = (const struct mgmt_header_t *) p;
+
+ if (srcp != NULL)
+ *srcp = hp->sa;
+ if (dstp != NULL)
+ *dstp = hp->da;
+ if (!eflag)
+ return;
+
+ printf("BSSID:%s DA:%s SA:%s ",
+ etheraddr_string((hp)->bssid), etheraddr_string((hp)->da),
+ etheraddr_string((hp)->sa));
+}
+
+static void
+ctrl_header_print(u_int16_t fc, const u_char *p, const u_int8_t **srcp,
+ const u_int8_t **dstp)
+{
+ if (srcp != NULL)
+ *srcp = NULL;
+ if (dstp != NULL)
+ *dstp = NULL;
+ if (!eflag)
+ return;
+
+ switch (FC_SUBTYPE(fc)) {
+ case CTRL_BAR:
+ printf(" RA:%s TA:%s CTL(%x) SEQ(%u) ",
+ etheraddr_string(((const struct ctrl_bar_t *)p)->ra),
+ etheraddr_string(((const struct ctrl_bar_t *)p)->ta),
+ EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->ctl)),
+ EXTRACT_LE_16BITS(&(((const struct ctrl_bar_t *)p)->seq)));
+ break;
+ case CTRL_BA:
+ printf("RA:%s ",
+ etheraddr_string(((const struct ctrl_ba_t *)p)->ra));
+ break;
+ case CTRL_PS_POLL:
+ printf("BSSID:%s TA:%s ",
+ etheraddr_string(((const struct ctrl_ps_poll_t *)p)->bssid),
+ etheraddr_string(((const struct ctrl_ps_poll_t *)p)->ta));
+ break;
+ case CTRL_RTS:
+ printf("RA:%s TA:%s ",
+ etheraddr_string(((const struct ctrl_rts_t *)p)->ra),
+ etheraddr_string(((const struct ctrl_rts_t *)p)->ta));
+ break;
+ case CTRL_CTS:
+ printf("RA:%s ",
+ etheraddr_string(((const struct ctrl_cts_t *)p)->ra));
+ break;
+ case CTRL_ACK:
+ printf("RA:%s ",
+ etheraddr_string(((const struct ctrl_ack_t *)p)->ra));
+ break;
+ case CTRL_CF_END:
+ printf("RA:%s BSSID:%s ",
+ etheraddr_string(((const struct ctrl_end_t *)p)->ra),
+ etheraddr_string(((const struct ctrl_end_t *)p)->bssid));
+ break;
+ case CTRL_END_ACK:
+ printf("RA:%s BSSID:%s ",
+ etheraddr_string(((const struct ctrl_end_ack_t *)p)->ra),
+ etheraddr_string(((const struct ctrl_end_ack_t *)p)->bssid));
+ break;
+ default:
+ printf("(H) Unknown Ctrl Subtype");
+ break;
+ }
+}
+
+static int
+extract_header_length(u_int16_t fc)
+{
+ int len;
+
+ switch (FC_TYPE(fc)) {
+ case T_MGMT:
+ return MGMT_HDRLEN;
+ case T_CTRL:
+ switch (FC_SUBTYPE(fc)) {
+ case CTRL_BAR:
+ return CTRL_BAR_HDRLEN;
+ case CTRL_PS_POLL:
+ return CTRL_PS_POLL_HDRLEN;
+ case CTRL_RTS:
+ return CTRL_RTS_HDRLEN;
+ case CTRL_CTS:
+ return CTRL_CTS_HDRLEN;
+ case CTRL_ACK:
+ return CTRL_ACK_HDRLEN;
+ case CTRL_CF_END:
+ return CTRL_END_HDRLEN;
+ case CTRL_END_ACK:
+ return CTRL_END_ACK_HDRLEN;
+ default:
+ return 0;
+ }
+ case T_DATA:
+ len = (FC_TO_DS(fc) && FC_FROM_DS(fc)) ? 30 : 24;
+ if (DATA_FRAME_IS_QOS(FC_SUBTYPE(fc)))
+ len += 2;
+ return len;
+ default:
+ printf("unknown IEEE802.11 frame type (%d)", FC_TYPE(fc));
+ return 0;
+ }
+}
+
+static int
+extract_mesh_header_length(const u_char *p)
+{
+ return (p[0] &~ 3) ? 0 : 6*(1 + (p[0] & 3));
+}
+
+/*
+ * Print the 802.11 MAC header if eflag is set, and set "*srcp" and "*dstp"
+ * to point to the source and destination MAC addresses in any case if
+ * "srcp" and "dstp" aren't null.
+ */
+static void
+ieee_802_11_hdr_print(u_int16_t fc, const u_char *p, u_int hdrlen,
+ u_int meshdrlen, const u_int8_t **srcp, const u_int8_t **dstp)
+{
+ if (vflag) {
+ if (FC_MORE_DATA(fc))
+ printf("More Data ");
+ if (FC_MORE_FLAG(fc))
+ printf("More Fragments ");
+ if (FC_POWER_MGMT(fc))
+ printf("Pwr Mgmt ");
+ if (FC_RETRY(fc))
+ printf("Retry ");
+ if (FC_ORDER(fc))
+ printf("Strictly Ordered ");
+ if (FC_WEP(fc))
+ printf("WEP Encrypted ");
+ if (FC_TYPE(fc) != T_CTRL || FC_SUBTYPE(fc) != CTRL_PS_POLL)
+ printf("%dus ",
+ EXTRACT_LE_16BITS(
+ &((const struct mgmt_header_t *)p)->duration));
+ }
+ if (meshdrlen != 0) {
+ const struct meshcntl_t *mc =
+ (const struct meshcntl_t *)&p[hdrlen - meshdrlen];
+ int ae = mc->flags & 3;
+
+ printf("MeshData (AE %d TTL %u seq %u", ae, mc->ttl,
+ EXTRACT_LE_32BITS(mc->seq));
+ if (ae > 0)
+ printf(" A4:%s", etheraddr_string(mc->addr4));
+ if (ae > 1)
+ printf(" A5:%s", etheraddr_string(mc->addr5));
+ if (ae > 2)
+ printf(" A6:%s", etheraddr_string(mc->addr6));
+ printf(") ");
+ }
+
+ switch (FC_TYPE(fc)) {
+ case T_MGMT:
+ mgmt_header_print(p, srcp, dstp);
+ break;
+ case T_CTRL:
+ ctrl_header_print(fc, p, srcp, dstp);
+ break;
+ case T_DATA:
+ data_header_print(fc, p, srcp, dstp);
+ break;
+ default:
+ printf("(header) unknown IEEE802.11 frame type (%d)",
+ FC_TYPE(fc));
+ *srcp = NULL;
+ *dstp = NULL;
+ break;
+ }
+}
+
+#ifndef roundup2
+#define roundup2(x, y) (((x)+((y)-1))&(~((y)-1))) /* if y is powers of two */
+#endif
+
+static u_int
+ieee802_11_print(const u_char *p, u_int length, u_int orig_caplen, int pad,
+ u_int fcslen)
+{
+ u_int16_t fc;
+ u_int caplen, hdrlen, meshdrlen;
+ const u_int8_t *src, *dst;
+ u_short extracted_ethertype;
+
+ caplen = orig_caplen;
+ /* Remove FCS, if present */
+ if (length < fcslen) {
+ printf("[|802.11]");
+ return caplen;
+ }
+ length -= fcslen;
+ if (caplen > length) {
+ /* Amount of FCS in actual packet data, if any */
+ fcslen = caplen - length;
+ caplen -= fcslen;
+ snapend -= fcslen;
+ }
+
+ if (caplen < IEEE802_11_FC_LEN) {
+ printf("[|802.11]");
+ return orig_caplen;
+ }
+
+ fc = EXTRACT_LE_16BITS(p);
+ hdrlen = extract_header_length(fc);
+ if (pad)
+ hdrlen = roundup2(hdrlen, 4);
+ if (Hflag && FC_TYPE(fc) == T_DATA &&
+ DATA_FRAME_IS_QOS(FC_SUBTYPE(fc))) {
+ meshdrlen = extract_mesh_header_length(p+hdrlen);
+ hdrlen += meshdrlen;
+ } else
+ meshdrlen = 0;
+
+
+ if (caplen < hdrlen) {
+ printf("[|802.11]");
+ return hdrlen;
+ }
+
+ ieee_802_11_hdr_print(fc, p, hdrlen, meshdrlen, &src, &dst);
+
+ /*
+ * Go past the 802.11 header.
+ */
+ length -= hdrlen;
+ caplen -= hdrlen;
+ p += hdrlen;
+
+ switch (FC_TYPE(fc)) {
+ case T_MGMT:
+ if (!mgmt_body_print(fc,
+ (const struct mgmt_header_t *)(p - hdrlen), p, length)) {
+ printf("[|802.11]");
+ return hdrlen;
+ }
+ break;
+ case T_CTRL:
+ if (!ctrl_body_print(fc, p - hdrlen)) {
+ printf("[|802.11]");
+ return hdrlen;
+ }
+ break;
+ case T_DATA:
+ if (DATA_FRAME_IS_NULL(FC_SUBTYPE(fc)))
+ return hdrlen; /* no-data frame */
+ /* There may be a problem w/ AP not having this bit set */
+ if (FC_WEP(fc)) {
+ if (!wep_print(p)) {
+ printf("[|802.11]");
+ return hdrlen;
+ }
+ } else if (llc_print(p, length, caplen, dst, src,
+ &extracted_ethertype) == 0) {
+ /*
+ * Some kinds of LLC packet we cannot
+ * handle intelligently
+ */
+ if (!eflag)
+ ieee_802_11_hdr_print(fc, p - hdrlen, hdrlen,
+ meshdrlen, NULL, NULL);
+ if (extracted_ethertype)
+ printf("(LLC %s) ",
+ etherproto_string(
+ htons(extracted_ethertype)));
+ if (!suppress_default_print)
+ default_print(p, caplen);
+ }
+ break;
+ default:
+ printf("unknown 802.11 frame type (%d)", FC_TYPE(fc));
+ break;
+ }
+
+ return hdrlen;
+}
+
+/*
+ * This is the top level routine of the printer. 'p' points
+ * to the 802.11 header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ */
+u_int
+ieee802_11_if_print(const struct pcap_pkthdr *h, const u_char *p)
+{
+ return ieee802_11_print(p, h->len, h->caplen, 0, 0);
+}
+
+#define IEEE80211_CHAN_FHSS \
+ (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_GFSK)
+#define IEEE80211_CHAN_A \
+ (IEEE80211_CHAN_5GHZ | IEEE80211_CHAN_OFDM)
+#define IEEE80211_CHAN_B \
+ (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_CCK)
+#define IEEE80211_CHAN_PUREG \
+ (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_OFDM)
+#define IEEE80211_CHAN_G \
+ (IEEE80211_CHAN_2GHZ | IEEE80211_CHAN_DYN)
+
+#define IS_CHAN_FHSS(flags) \
+ ((flags & IEEE80211_CHAN_FHSS) == IEEE80211_CHAN_FHSS)
+#define IS_CHAN_A(flags) \
+ ((flags & IEEE80211_CHAN_A) == IEEE80211_CHAN_A)
+#define IS_CHAN_B(flags) \
+ ((flags & IEEE80211_CHAN_B) == IEEE80211_CHAN_B)
+#define IS_CHAN_PUREG(flags) \
+ ((flags & IEEE80211_CHAN_PUREG) == IEEE80211_CHAN_PUREG)
+#define IS_CHAN_G(flags) \
+ ((flags & IEEE80211_CHAN_G) == IEEE80211_CHAN_G)
+#define IS_CHAN_ANYG(flags) \
+ (IS_CHAN_PUREG(flags) || IS_CHAN_G(flags))
+
+static void
+print_chaninfo(int freq, int flags)
+{
+ printf("%u MHz", freq);
+ if (IS_CHAN_FHSS(flags))
+ printf(" FHSS");
+ if (IS_CHAN_A(flags)) {
+ if (flags & IEEE80211_CHAN_HALF)
+ printf(" 11a/10Mhz");
+ else if (flags & IEEE80211_CHAN_QUARTER)
+ printf(" 11a/5Mhz");
+ else
+ printf(" 11a");
+ }
+ if (IS_CHAN_ANYG(flags)) {
+ if (flags & IEEE80211_CHAN_HALF)
+ printf(" 11g/10Mhz");
+ else if (flags & IEEE80211_CHAN_QUARTER)
+ printf(" 11g/5Mhz");
+ else
+ printf(" 11g");
+ } else if (IS_CHAN_B(flags))
+ printf(" 11b");
+ if (flags & IEEE80211_CHAN_TURBO)
+ printf(" Turbo");
+ if (flags & IEEE80211_CHAN_HT20)
+ printf(" ht/20");
+ else if (flags & IEEE80211_CHAN_HT40D)
+ printf(" ht/40-");
+ else if (flags & IEEE80211_CHAN_HT40U)
+ printf(" ht/40+");
+ printf(" ");
+}
+
+static int
+print_radiotap_field(struct cpack_state *s, u_int32_t bit, u_int8_t *flags,
+ struct radiotap_state *state, u_int32_t presentflags)
+{
+ union {
+ int8_t i8;
+ u_int8_t u8;
+ int16_t i16;
+ u_int16_t u16;
+ u_int32_t u32;
+ u_int64_t u64;
+ } u, u2, u3, u4;
+ int rc;
+
+ switch (bit) {
+ case IEEE80211_RADIOTAP_FLAGS:
+ rc = cpack_uint8(s, &u.u8);
+ if (rc != 0)
+ break;
+ *flags = u.u8;
+ break;
+ case IEEE80211_RADIOTAP_RATE:
+ rc = cpack_uint8(s, &u.u8);
+ if (rc != 0)
+ break;
+
+ /* Save state rate */
+ state->rate = u.u8;
+ break;
+ case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
+ case IEEE80211_RADIOTAP_DB_ANTNOISE:
+ case IEEE80211_RADIOTAP_ANTENNA:
+ rc = cpack_uint8(s, &u.u8);
+ break;
+ case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
+ case IEEE80211_RADIOTAP_DBM_ANTNOISE:
+ rc = cpack_int8(s, &u.i8);
+ break;
+ case IEEE80211_RADIOTAP_CHANNEL:
+ rc = cpack_uint16(s, &u.u16);
+ if (rc != 0)
+ break;
+ rc = cpack_uint16(s, &u2.u16);
+ break;
+ case IEEE80211_RADIOTAP_FHSS:
+ case IEEE80211_RADIOTAP_LOCK_QUALITY:
+ case IEEE80211_RADIOTAP_TX_ATTENUATION:
+ case IEEE80211_RADIOTAP_RX_FLAGS:
+ rc = cpack_uint16(s, &u.u16);
+ break;
+ case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
+ rc = cpack_uint8(s, &u.u8);
+ break;
+ case IEEE80211_RADIOTAP_DBM_TX_POWER:
+ rc = cpack_int8(s, &u.i8);
+ break;
+ case IEEE80211_RADIOTAP_TSFT:
+ rc = cpack_uint64(s, &u.u64);
+ break;
+ case IEEE80211_RADIOTAP_XCHANNEL:
+ rc = cpack_uint32(s, &u.u32);
+ if (rc != 0)
+ break;
+ rc = cpack_uint16(s, &u2.u16);
+ if (rc != 0)
+ break;
+ rc = cpack_uint8(s, &u3.u8);
+ if (rc != 0)
+ break;
+ rc = cpack_uint8(s, &u4.u8);
+ break;
+ case IEEE80211_RADIOTAP_MCS:
+ rc = cpack_uint8(s, &u.u8);
+ if (rc != 0)
+ break;
+ rc = cpack_uint8(s, &u2.u8);
+ if (rc != 0)
+ break;
+ rc = cpack_uint8(s, &u3.u8);
+ break;
+ case IEEE80211_RADIOTAP_VENDOR_NAMESPACE: {
+ u_int8_t vns[3];
+ u_int16_t length;
+ u_int8_t subspace;
+
+ if ((cpack_align_and_reserve(s, 2)) == NULL) {
+ rc = -1;
+ break;
+ }
+
+ rc = cpack_uint8(s, &vns[0]);
+ if (rc != 0)
+ break;
+ rc = cpack_uint8(s, &vns[1]);
+ if (rc != 0)
+ break;
+ rc = cpack_uint8(s, &vns[2]);
+ if (rc != 0)
+ break;
+ rc = cpack_uint8(s, &subspace);
+ if (rc != 0)
+ break;
+ rc = cpack_uint16(s, &length);
+ if (rc != 0)
+ break;
+
+ /* Skip up to length */
+ s->c_next += length;
+ break;
+ }
+ default:
+ /* this bit indicates a field whose
+ * size we do not know, so we cannot
+ * proceed. Just print the bit number.
+ */
+ printf("[bit %u] ", bit);
+ return -1;
+ }
+
+ if (rc != 0) {
+ printf("[|802.11]");
+ return rc;
+ }
+
+ /* Preserve the state present flags */
+ state->present = presentflags;
+
+ switch (bit) {
+ case IEEE80211_RADIOTAP_CHANNEL:
+ /*
+ * If CHANNEL and XCHANNEL are both present, skip
+ * CHANNEL.
+ */
+ if (presentflags & (1 << IEEE80211_RADIOTAP_XCHANNEL))
+ break;
+ print_chaninfo(u.u16, u2.u16);
+ break;
+ case IEEE80211_RADIOTAP_FHSS:
+ printf("fhset %d fhpat %d ", u.u16 & 0xff, (u.u16 >> 8) & 0xff);
+ break;
+ case IEEE80211_RADIOTAP_RATE:
+ /*
+ * XXX On FreeBSD rate & 0x80 means we have an MCS. On
+ * Linux and AirPcap it does not. (What about
+ * Mac OS X, NetBSD, OpenBSD, and DragonFly BSD?)
+ *
+ * This is an issue either for proprietary extensions
+ * to 11a or 11g, which do exist, or for 11n
+ * implementations that stuff a rate value into
+ * this field, which also appear to exist.
+ *
+ * We currently handle that by assuming that
+ * if the 0x80 bit is set *and* the remaining
+ * bits have a value between 0 and 15 it's
+ * an MCS value, otherwise it's a rate. If
+ * there are cases where systems that use
+ * "0x80 + MCS index" for MCS indices > 15,
+ * or stuff a rate value here between 64 and
+ * 71.5 Mb/s in here, we'll need a preference
+ * setting. Such rates do exist, e.g. 11n
+ * MCS 7 at 20 MHz with a long guard interval.
+ */
+ if (u.u8 >= 0x80 && u.u8 <= 0x8f) {
+ /*
+ * XXX - we don't know the channel width
+ * or guard interval length, so we can't
+ * convert this to a data rate.
+ *
+ * If you want us to show a data rate,
+ * use the MCS field, not the Rate field;
+ * the MCS field includes not only the
+ * MCS index, it also includes bandwidth
+ * and guard interval information.
+ *
+ * XXX - can we get the channel width
+ * from XChannel and the guard interval
+ * information from Flags, at least on
+ * FreeBSD?
+ */
+ printf("MCS %u ", u.u8 & 0x7f);
+ } else
+ printf("%2.1f Mb/s ", .5*u.u8);
+ break;
+ case IEEE80211_RADIOTAP_DBM_ANTSIGNAL:
+ printf("%ddB signal ", u.i8);
+ break;
+ case IEEE80211_RADIOTAP_DBM_ANTNOISE:
+ printf("%ddB noise ", u.i8);
+ break;
+ case IEEE80211_RADIOTAP_DB_ANTSIGNAL:
+ printf("%ddB signal ", u.u8);
+ break;
+ case IEEE80211_RADIOTAP_DB_ANTNOISE:
+ printf("%ddB noise ", u.u8);
+ break;
+ case IEEE80211_RADIOTAP_LOCK_QUALITY:
+ printf("%u sq ", u.u16);
+ break;
+ case IEEE80211_RADIOTAP_TX_ATTENUATION:
+ printf("%d tx power ", -(int)u.u16);
+ break;
+ case IEEE80211_RADIOTAP_DB_TX_ATTENUATION:
+ printf("%ddB tx power ", -(int)u.u8);
+ break;
+ case IEEE80211_RADIOTAP_DBM_TX_POWER:
+ printf("%ddBm tx power ", u.i8);
+ break;
+ case IEEE80211_RADIOTAP_FLAGS:
+ if (u.u8 & IEEE80211_RADIOTAP_F_CFP)
+ printf("cfp ");
+ if (u.u8 & IEEE80211_RADIOTAP_F_SHORTPRE)
+ printf("short preamble ");
+ if (u.u8 & IEEE80211_RADIOTAP_F_WEP)
+ printf("wep ");
+ if (u.u8 & IEEE80211_RADIOTAP_F_FRAG)
+ printf("fragmented ");
+ if (u.u8 & IEEE80211_RADIOTAP_F_BADFCS)
+ printf("bad-fcs ");
+ break;
+ case IEEE80211_RADIOTAP_ANTENNA:
+ printf("antenna %d ", u.u8);
+ break;
+ case IEEE80211_RADIOTAP_TSFT:
+ printf("%" PRIu64 "us tsft ", u.u64);
+ break;
+ case IEEE80211_RADIOTAP_RX_FLAGS:
+ /* Do nothing for now */
+ break;
+ case IEEE80211_RADIOTAP_XCHANNEL:
+ print_chaninfo(u2.u16, u.u32);
+ break;
+ case IEEE80211_RADIOTAP_MCS: {
+ static const char *bandwidth[4] = {
+ "20 MHz",
+ "40 MHz",
+ "20 MHz (L)",
+ "20 MHz (U)"
+ };
+ float htrate;
+
+ if (u.u8 & IEEE80211_RADIOTAP_MCS_MCS_INDEX_KNOWN) {
+ /*
+ * We know the MCS index.
+ */
+ if (u3.u8 <= MAX_MCS_INDEX) {
+ /*
+ * And it's in-range.
+ */
+ if (u.u8 & (IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN|IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN)) {
+ /*
+ * And we know both the bandwidth and
+ * the guard interval, so we can look
+ * up the rate.
+ */
+ htrate =
+ ieee80211_float_htrates \
+ [u3.u8] \
+ [((u2.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK) == IEEE80211_RADIOTAP_MCS_BANDWIDTH_40 ? 1 : 0)] \
+ [((u2.u8 & IEEE80211_RADIOTAP_MCS_SHORT_GI) ? 1 : 0)];
+ } else {
+ /*
+ * We don't know both the bandwidth
+ * and the guard interval, so we can
+ * only report the MCS index.
+ */
+ htrate = 0.0;
+ }
+ } else {
+ /*
+ * The MCS value is out of range.
+ */
+ htrate = 0.0;
+ }
+ if (htrate != 0.0) {
+ /*
+ * We have the rate.
+ * Print it.
+ */
+ printf("%.1f Mb/s MCS %u ", htrate, u3.u8);
+ } else {
+ /*
+ * We at least have the MCS index.
+ * Print it.
+ */
+ printf("MCS %u ", u3.u8);
+ }
+ }
+ if (u.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_KNOWN) {
+ printf("%s ",
+ bandwidth[u2.u8 & IEEE80211_RADIOTAP_MCS_BANDWIDTH_MASK]);
+ }
+ if (u.u8 & IEEE80211_RADIOTAP_MCS_GUARD_INTERVAL_KNOWN) {
+ printf("%s GI ",
+ (u2.u8 & IEEE80211_RADIOTAP_MCS_SHORT_GI) ?
+ "short" : "lon");
+ }
+ if (u.u8 & IEEE80211_RADIOTAP_MCS_HT_FORMAT_KNOWN) {
+ printf("%s ",
+ (u2.u8 & IEEE80211_RADIOTAP_MCS_HT_GREENFIELD) ?
+ "greenfield" : "mixed");
+ }
+ if (u.u8 & IEEE80211_RADIOTAP_MCS_FEC_TYPE_KNOWN) {
+ printf("%s FEC ",
+ (u2.u8 & IEEE80211_RADIOTAP_MCS_FEC_LDPC) ?
+ "LDPC" : "BCC");
+ }
+ break;
+ }
+ }
+ return 0;
+}
+
+static u_int
+ieee802_11_radio_print(const u_char *p, u_int length, u_int caplen)
+{
+#define BITNO_32(x) (((x) >> 16) ? 16 + BITNO_16((x) >> 16) : BITNO_16((x)))
+#define BITNO_16(x) (((x) >> 8) ? 8 + BITNO_8((x) >> 8) : BITNO_8((x)))
+#define BITNO_8(x) (((x) >> 4) ? 4 + BITNO_4((x) >> 4) : BITNO_4((x)))
+#define BITNO_4(x) (((x) >> 2) ? 2 + BITNO_2((x) >> 2) : BITNO_2((x)))
+#define BITNO_2(x) (((x) & 2) ? 1 : 0)
+#define BIT(n) (1U << n)
+#define IS_EXTENDED(__p) \
+ (EXTRACT_LE_32BITS(__p) & BIT(IEEE80211_RADIOTAP_EXT)) != 0
+
+ struct cpack_state cpacker;
+ struct ieee80211_radiotap_header *hdr;
+ u_int32_t present, next_present;
+ u_int32_t presentflags = 0;
+ u_int32_t *presentp, *last_presentp;
+ enum ieee80211_radiotap_type bit;
+ int bit0;
+ const u_char *iter;
+ u_int len;
+ u_int8_t flags;
+ int pad;
+ u_int fcslen;
+ struct radiotap_state state;
+
+ if (caplen < sizeof(*hdr)) {
+ printf("[|802.11]");
+ return caplen;
+ }
+
+ hdr = (struct ieee80211_radiotap_header *)p;
+
+ len = EXTRACT_LE_16BITS(&hdr->it_len);
+
+ if (caplen < len) {
+ printf("[|802.11]");
+ return caplen;
+ }
+ for (last_presentp = &hdr->it_present;
+ IS_EXTENDED(last_presentp) &&
+ (u_char*)(last_presentp + 1) <= p + len;
+ last_presentp++);
+
+ /* are there more bitmap extensions than bytes in header? */
+ if (IS_EXTENDED(last_presentp)) {
+ printf("[|802.11]");
+ return caplen;
+ }
+
+ iter = (u_char*)(last_presentp + 1);
+
+ if (cpack_init(&cpacker, (u_int8_t*)iter, len - (iter - p)) != 0) {
+ /* XXX */
+ printf("[|802.11]");
+ return caplen;
+ }
+
+ /* Assume no flags */
+ flags = 0;
+ /* Assume no Atheros padding between 802.11 header and body */
+ pad = 0;
+ /* Assume no FCS at end of frame */
+ fcslen = 0;
+ for (bit0 = 0, presentp = &hdr->it_present; presentp <= last_presentp;
+ presentp++, bit0 += 32) {
+ presentflags = EXTRACT_LE_32BITS(presentp);
+
+ /* Clear state. */
+ memset(&state, 0, sizeof(state));
+
+ for (present = EXTRACT_LE_32BITS(presentp); present;
+ present = next_present) {
+ /* clear the least significant bit that is set */
+ next_present = present & (present - 1);
+
+ /* extract the least significant bit that is set */
+ bit = (enum ieee80211_radiotap_type)
+ (bit0 + BITNO_32(present ^ next_present));
+
+ if (print_radiotap_field(&cpacker, bit, &flags, &state, presentflags) != 0)
+ goto out;
+ }
+ }
+
+out:
+ if (flags & IEEE80211_RADIOTAP_F_DATAPAD)
+ pad = 1; /* Atheros padding */
+ if (flags & IEEE80211_RADIOTAP_F_FCS)
+ fcslen = 4; /* FCS at end of packet */
+ return len + ieee802_11_print(p + len, length - len, caplen - len, pad,
+ fcslen);
+#undef BITNO_32
+#undef BITNO_16
+#undef BITNO_8
+#undef BITNO_4
+#undef BITNO_2
+#undef BIT
+}
+
+static u_int
+ieee802_11_avs_radio_print(const u_char *p, u_int length, u_int caplen)
+{
+ u_int32_t caphdr_len;
+
+ if (caplen < 8) {
+ printf("[|802.11]");
+ return caplen;
+ }
+
+ caphdr_len = EXTRACT_32BITS(p + 4);
+ if (caphdr_len < 8) {
+ /*
+ * Yow! The capture header length is claimed not
+ * to be large enough to include even the version
+ * cookie or capture header length!
+ */
+ printf("[|802.11]");
+ return caplen;
+ }
+
+ if (caplen < caphdr_len) {
+ printf("[|802.11]");
+ return caplen;
+ }
+
+ return caphdr_len + ieee802_11_print(p + caphdr_len,
+ length - caphdr_len, caplen - caphdr_len, 0, 0);
+}
+
+#define PRISM_HDR_LEN 144
+
+#define WLANCAP_MAGIC_COOKIE_BASE 0x80211000
+#define WLANCAP_MAGIC_COOKIE_V1 0x80211001
+#define WLANCAP_MAGIC_COOKIE_V2 0x80211002
+
+/*
+ * For DLT_PRISM_HEADER; like DLT_IEEE802_11, but with an extra header,
+ * containing information such as radio information, which we
+ * currently ignore.
+ *
+ * If, however, the packet begins with WLANCAP_MAGIC_COOKIE_V1 or
+ * WLANCAP_MAGIC_COOKIE_V2, it's really DLT_IEEE802_11_RADIO_AVS
+ * (currently, on Linux, there's no ARPHRD_ type for
+ * DLT_IEEE802_11_RADIO_AVS, as there is a ARPHRD_IEEE80211_PRISM
+ * for DLT_PRISM_HEADER, so ARPHRD_IEEE80211_PRISM is used for
+ * the AVS header, and the first 4 bytes of the header are used to
+ * indicate whether it's a Prism header or an AVS header).
+ */
+u_int
+prism_if_print(const struct pcap_pkthdr *h, const u_char *p)
+{
+ u_int caplen = h->caplen;
+ u_int length = h->len;
+ u_int32_t msgcode;
+
+ if (caplen < 4) {
+ printf("[|802.11]");
+ return caplen;
+ }
+
+ msgcode = EXTRACT_32BITS(p);
+ if (msgcode == WLANCAP_MAGIC_COOKIE_V1 ||
+ msgcode == WLANCAP_MAGIC_COOKIE_V2)
+ return ieee802_11_avs_radio_print(p, length, caplen);
+
+ if (caplen < PRISM_HDR_LEN) {
+ printf("[|802.11]");
+ return caplen;
+ }
+
+ return PRISM_HDR_LEN + ieee802_11_print(p + PRISM_HDR_LEN,
+ length - PRISM_HDR_LEN, caplen - PRISM_HDR_LEN, 0, 0);
+}
+
+/*
+ * For DLT_IEEE802_11_RADIO; like DLT_IEEE802_11, but with an extra
+ * header, containing information such as radio information.
+ */
+u_int
+ieee802_11_radio_if_print(const struct pcap_pkthdr *h, const u_char *p)
+{
+ return ieee802_11_radio_print(p, h->len, h->caplen);
+}
+
+/*
+ * For DLT_IEEE802_11_RADIO_AVS; like DLT_IEEE802_11, but with an
+ * extra header, containing information such as radio information,
+ * which we currently ignore.
+ */
+u_int
+ieee802_11_radio_avs_if_print(const struct pcap_pkthdr *h, const u_char *p)
+{
+ return ieee802_11_avs_radio_print(p, h->len, h->caplen);
+}
diff --git a/freebsd/contrib/tcpdump/print-802_15_4.c b/freebsd/contrib/tcpdump/print-802_15_4.c
new file mode 100644
index 00000000..cd8ff8e6
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-802_15_4.c
@@ -0,0 +1,185 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 2009
+ * Siemens AG, All rights reserved.
+ * Dmitry Eremin-Solenikov (dbaryshkov@gmail.com)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <pcap.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+#include "extract.h"
+
+static const char *ftypes[] = {
+ "Beacon", /* 0 */
+ "Data", /* 1 */
+ "ACK", /* 2 */
+ "Command", /* 3 */
+ "Reserved", /* 4 */
+ "Reserved", /* 5 */
+ "Reserved", /* 6 */
+ "Reserved", /* 7 */
+};
+
+static int
+extract_header_length(u_int16_t fc)
+{
+ int len = 0;
+
+ switch ((fc >> 10) & 0x3) {
+ case 0x00:
+ if (fc & (1 << 6)) /* intra-PAN with none dest addr */
+ return -1;
+ break;
+ case 0x01:
+ return -1;
+ case 0x02:
+ len += 4;
+ break;
+ case 0x03:
+ len += 10;
+ break;
+ }
+
+ switch ((fc >> 14) & 0x3) {
+ case 0x00:
+ break;
+ case 0x01:
+ return -1;
+ case 0x02:
+ len += 4;
+ break;
+ case 0x03:
+ len += 10;
+ break;
+ }
+
+ if (fc & (1 << 6)) {
+ if (len < 2)
+ return -1;
+ len -= 2;
+ }
+
+ return len;
+}
+
+
+u_int
+ieee802_15_4_if_print(struct netdissect_options *ndo,
+ const struct pcap_pkthdr *h, const u_char *p)
+{
+ u_int caplen = h->caplen;
+ int hdrlen;
+ u_int16_t fc;
+ u_int8_t seq;
+
+ if (caplen < 3) {
+ ND_PRINT((ndo, "[|802.15.4] %x", caplen));
+ return caplen;
+ }
+
+ fc = EXTRACT_LE_16BITS(p);
+ hdrlen = extract_header_length(fc);
+
+ seq = EXTRACT_LE_8BITS(p + 2);
+
+ p += 3;
+ caplen -= 3;
+
+ ND_PRINT((ndo,"IEEE 802.15.4 %s packet ", ftypes[fc & 0x7]));
+ if (vflag)
+ ND_PRINT((ndo,"seq %02x ", seq));
+ if (hdrlen == -1) {
+ ND_PRINT((ndo,"malformed! "));
+ return caplen;
+ }
+
+
+ if (!vflag) {
+ p+= hdrlen;
+ caplen -= hdrlen;
+ } else {
+ u_int16_t panid = 0;
+
+ switch ((fc >> 10) & 0x3) {
+ case 0x00:
+ ND_PRINT((ndo,"none "));
+ break;
+ case 0x01:
+ ND_PRINT((ndo,"reserved destination addressing mode"));
+ return 0;
+ case 0x02:
+ panid = EXTRACT_LE_16BITS(p);
+ p += 2;
+ ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p)));
+ p += 2;
+ break;
+ case 0x03:
+ panid = EXTRACT_LE_16BITS(p);
+ p += 2;
+ ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(p)));
+ p += 8;
+ break;
+ }
+ ND_PRINT((ndo,"< ");
+
+ switch ((fc >> 14) & 0x3) {
+ case 0x00:
+ ND_PRINT((ndo,"none "));
+ break;
+ case 0x01:
+ ND_PRINT((ndo,"reserved source addressing mode"));
+ return 0;
+ case 0x02:
+ if (!(fc & (1 << 6))) {
+ panid = EXTRACT_LE_16BITS(p);
+ p += 2;
+ }
+ ND_PRINT((ndo,"%04x:%04x ", panid, EXTRACT_LE_16BITS(p)));
+ p += 2;
+ break;
+ case 0x03:
+ if (!(fc & (1 << 6))) {
+ panid = EXTRACT_LE_16BITS(p);
+ p += 2;
+ }
+ ND_PRINT((ndo,"%04x:%s ", panid, le64addr_string(p))));
+ p += 8;
+ break;
+ }
+
+ caplen -= hdrlen;
+ }
+
+ if (!suppress_default_print)
+ (ndo->ndo_default_print)(ndo, p, caplen);
+
+ return 0;
+}
diff --git a/freebsd/contrib/tcpdump/print-ah.c b/freebsd/contrib/tcpdump/print-ah.c
new file mode 100644
index 00000000..0bc6b389
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-ah.c
@@ -0,0 +1,73 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/* $NetBSD: print-ah.c,v 1.4 1996/05/20 00:41:16 fvdl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ah.c,v 1.22 2003-11-19 00:36:06 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+
+#include "ah.h"
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+int
+ah_print(register const u_char *bp)
+{
+ register const struct ah *ah;
+ register const u_char *ep;
+ int sumlen;
+ u_int32_t spi;
+
+ ah = (const struct ah *)bp;
+ ep = snapend; /* 'ep' points to the end of available data. */
+
+ TCHECK(*ah);
+
+ sumlen = ah->ah_len << 2;
+ spi = EXTRACT_32BITS(&ah->ah_spi);
+
+ printf("AH(spi=0x%08x", spi);
+ if (vflag)
+ printf(",sumlen=%d", sumlen);
+ printf(",seq=0x%x", EXTRACT_32BITS(ah + 1));
+ if (bp + sizeof(struct ah) + sumlen > ep)
+ fputs("[truncated]", stdout);
+ fputs("): ", stdout);
+
+ return sizeof(struct ah) + sumlen;
+ trunc:
+ fputs("[|AH]", stdout);
+ return -1;
+}
diff --git a/freebsd/contrib/tcpdump/print-aodv.c b/freebsd/contrib/tcpdump/print-aodv.c
new file mode 100644
index 00000000..a585a95a
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-aodv.c
@@ -0,0 +1,457 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 2003 Bruce M. Simpson <bms@spc.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Bruce M. Simpson.
+ * 4. Neither the name of Bruce M. Simpson nor the names of co-
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Bruce M. Simpson AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Bruce M. Simpson OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-aodv.c,v 1.11 2004-03-24 00:30:19 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stddef.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h" /* must come after interface.h */
+
+#include "aodv.h"
+
+static void
+aodv_extension(const struct aodv_ext *ep, u_int length)
+{
+ u_int i;
+ const struct aodv_hello *ah;
+
+ switch (ep->type) {
+ case AODV_EXT_HELLO:
+ if (snapend < (u_char *) ep) {
+ printf(" [|hello]");
+ return;
+ }
+ i = min(length, (u_int)(snapend - (u_char *)ep));
+ if (i < sizeof(struct aodv_hello)) {
+ printf(" [|hello]");
+ return;
+ }
+ i -= sizeof(struct aodv_hello);
+ ah = (void *)ep;
+ printf("\n\text HELLO %ld ms",
+ (unsigned long)EXTRACT_32BITS(&ah->interval));
+ break;
+
+ default:
+ printf("\n\text %u %u", ep->type, ep->length);
+ break;
+ }
+}
+
+static void
+aodv_rreq(const union aodv *ap, const u_char *dat, u_int length)
+{
+ u_int i;
+
+ if (snapend < dat) {
+ printf(" [|aodv]");
+ return;
+ }
+ i = min(length, (u_int)(snapend - dat));
+ if (i < sizeof(ap->rreq)) {
+ printf(" [|rreq]");
+ return;
+ }
+ i -= sizeof(ap->rreq);
+ printf(" rreq %u %s%s%s%s%shops %u id 0x%08lx\n"
+ "\tdst %s seq %lu src %s seq %lu", length,
+ ap->rreq.rreq_type & RREQ_JOIN ? "[J]" : "",
+ ap->rreq.rreq_type & RREQ_REPAIR ? "[R]" : "",
+ ap->rreq.rreq_type & RREQ_GRAT ? "[G]" : "",
+ ap->rreq.rreq_type & RREQ_DEST ? "[D]" : "",
+ ap->rreq.rreq_type & RREQ_UNKNOWN ? "[U] " : " ",
+ ap->rreq.rreq_hops,
+ (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_id),
+ ipaddr_string(&ap->rreq.rreq_da),
+ (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_ds),
+ ipaddr_string(&ap->rreq.rreq_oa),
+ (unsigned long)EXTRACT_32BITS(&ap->rreq.rreq_os));
+ if (i >= sizeof(struct aodv_ext))
+ aodv_extension((void *)(&ap->rreq + 1), i);
+}
+
+static void
+aodv_rrep(const union aodv *ap, const u_char *dat, u_int length)
+{
+ u_int i;
+
+ if (snapend < dat) {
+ printf(" [|aodv]");
+ return;
+ }
+ i = min(length, (u_int)(snapend - dat));
+ if (i < sizeof(ap->rrep)) {
+ printf(" [|rrep]");
+ return;
+ }
+ i -= sizeof(ap->rrep);
+ printf(" rrep %u %s%sprefix %u hops %u\n"
+ "\tdst %s dseq %lu src %s %lu ms", length,
+ ap->rrep.rrep_type & RREP_REPAIR ? "[R]" : "",
+ ap->rrep.rrep_type & RREP_ACK ? "[A] " : " ",
+ ap->rrep.rrep_ps & RREP_PREFIX_MASK,
+ ap->rrep.rrep_hops,
+ ipaddr_string(&ap->rrep.rrep_da),
+ (unsigned long)EXTRACT_32BITS(&ap->rrep.rrep_ds),
+ ipaddr_string(&ap->rrep.rrep_oa),
+ (unsigned long)EXTRACT_32BITS(&ap->rrep.rrep_life));
+ if (i >= sizeof(struct aodv_ext))
+ aodv_extension((void *)(&ap->rrep + 1), i);
+}
+
+static void
+aodv_rerr(const union aodv *ap, const u_char *dat, u_int length)
+{
+ u_int i;
+ const struct rerr_unreach *dp = NULL;
+ int n, trunc;
+
+ if (snapend < dat) {
+ printf(" [|aodv]");
+ return;
+ }
+ i = min(length, (u_int)(snapend - dat));
+ if (i < offsetof(struct aodv_rerr, r)) {
+ printf(" [|rerr]");
+ return;
+ }
+ i -= offsetof(struct aodv_rerr, r);
+ dp = &ap->rerr.r.dest[0];
+ n = ap->rerr.rerr_dc * sizeof(ap->rerr.r.dest[0]);
+ printf(" rerr %s [items %u] [%u]:",
+ ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "",
+ ap->rerr.rerr_dc, length);
+ trunc = n - (i/sizeof(ap->rerr.r.dest[0]));
+ for (; i >= sizeof(ap->rerr.r.dest[0]);
+ ++dp, i -= sizeof(ap->rerr.r.dest[0])) {
+ printf(" {%s}(%ld)", ipaddr_string(&dp->u_da),
+ (unsigned long)EXTRACT_32BITS(&dp->u_ds));
+ }
+ if (trunc)
+ printf("[|rerr]");
+}
+
+static void
+#ifdef INET6
+aodv_v6_rreq(const union aodv *ap, const u_char *dat, u_int length)
+#else
+aodv_v6_rreq(const union aodv *ap _U_, const u_char *dat _U_, u_int length)
+#endif
+{
+#ifdef INET6
+ u_int i;
+
+ if (snapend < dat) {
+ printf(" [|aodv]");
+ return;
+ }
+ i = min(length, (u_int)(snapend - dat));
+ if (i < sizeof(ap->rreq6)) {
+ printf(" [|rreq6]");
+ return;
+ }
+ i -= sizeof(ap->rreq6);
+ printf(" v6 rreq %u %s%s%s%s%shops %u id 0x%08lx\n"
+ "\tdst %s seq %lu src %s seq %lu", length,
+ ap->rreq6.rreq_type & RREQ_JOIN ? "[J]" : "",
+ ap->rreq6.rreq_type & RREQ_REPAIR ? "[R]" : "",
+ ap->rreq6.rreq_type & RREQ_GRAT ? "[G]" : "",
+ ap->rreq6.rreq_type & RREQ_DEST ? "[D]" : "",
+ ap->rreq6.rreq_type & RREQ_UNKNOWN ? "[U] " : " ",
+ ap->rreq6.rreq_hops,
+ (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_id),
+ ip6addr_string(&ap->rreq6.rreq_da),
+ (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_ds),
+ ip6addr_string(&ap->rreq6.rreq_oa),
+ (unsigned long)EXTRACT_32BITS(&ap->rreq6.rreq_os));
+ if (i >= sizeof(struct aodv_ext))
+ aodv_extension((void *)(&ap->rreq6 + 1), i);
+#else
+ printf(" v6 rreq %u", length);
+#endif
+}
+
+static void
+#ifdef INET6
+aodv_v6_rrep(const union aodv *ap, const u_char *dat, u_int length)
+#else
+aodv_v6_rrep(const union aodv *ap _U_, const u_char *dat _U_, u_int length)
+#endif
+{
+#ifdef INET6
+ u_int i;
+
+ if (snapend < dat) {
+ printf(" [|aodv]");
+ return;
+ }
+ i = min(length, (u_int)(snapend - dat));
+ if (i < sizeof(ap->rrep6)) {
+ printf(" [|rrep6]");
+ return;
+ }
+ i -= sizeof(ap->rrep6);
+ printf(" rrep %u %s%sprefix %u hops %u\n"
+ "\tdst %s dseq %lu src %s %lu ms", length,
+ ap->rrep6.rrep_type & RREP_REPAIR ? "[R]" : "",
+ ap->rrep6.rrep_type & RREP_ACK ? "[A] " : " ",
+ ap->rrep6.rrep_ps & RREP_PREFIX_MASK,
+ ap->rrep6.rrep_hops,
+ ip6addr_string(&ap->rrep6.rrep_da),
+ (unsigned long)EXTRACT_32BITS(&ap->rrep6.rrep_ds),
+ ip6addr_string(&ap->rrep6.rrep_oa),
+ (unsigned long)EXTRACT_32BITS(&ap->rrep6.rrep_life));
+ if (i >= sizeof(struct aodv_ext))
+ aodv_extension((void *)(&ap->rrep6 + 1), i);
+#else
+ printf(" rrep %u", length);
+#endif
+}
+
+static void
+#ifdef INET6
+aodv_v6_rerr(const union aodv *ap, u_int length)
+#else
+aodv_v6_rerr(const union aodv *ap _U_, u_int length)
+#endif
+{
+#ifdef INET6
+ const struct rerr_unreach6 *dp6 = NULL;
+ int i, j, n, trunc;
+
+ i = length - offsetof(struct aodv_rerr, r);
+ j = sizeof(ap->rerr.r.dest6[0]);
+ dp6 = &ap->rerr.r.dest6[0];
+ n = ap->rerr.rerr_dc * j;
+ printf(" rerr %s [items %u] [%u]:",
+ ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "",
+ ap->rerr.rerr_dc, length);
+ trunc = n - (i/j);
+ for (; i -= j >= 0; ++dp6) {
+ printf(" {%s}(%ld)", ip6addr_string(&dp6->u_da),
+ (unsigned long)EXTRACT_32BITS(&dp6->u_ds));
+ }
+ if (trunc)
+ printf("[|rerr]");
+#else
+ printf(" rerr %u", length);
+#endif
+}
+
+static void
+#ifdef INET6
+aodv_v6_draft_01_rreq(const union aodv *ap, const u_char *dat, u_int length)
+#else
+aodv_v6_draft_01_rreq(const union aodv *ap _U_, const u_char *dat _U_,
+ u_int length)
+#endif
+{
+#ifdef INET6
+ u_int i;
+
+ if (snapend < dat) {
+ printf(" [|aodv]");
+ return;
+ }
+ i = min(length, (u_int)(snapend - dat));
+ if (i < sizeof(ap->rreq6_draft_01)) {
+ printf(" [|rreq6]");
+ return;
+ }
+ i -= sizeof(ap->rreq6_draft_01);
+ printf(" rreq %u %s%s%s%s%shops %u id 0x%08lx\n"
+ "\tdst %s seq %lu src %s seq %lu", length,
+ ap->rreq6_draft_01.rreq_type & RREQ_JOIN ? "[J]" : "",
+ ap->rreq6_draft_01.rreq_type & RREQ_REPAIR ? "[R]" : "",
+ ap->rreq6_draft_01.rreq_type & RREQ_GRAT ? "[G]" : "",
+ ap->rreq6_draft_01.rreq_type & RREQ_DEST ? "[D]" : "",
+ ap->rreq6_draft_01.rreq_type & RREQ_UNKNOWN ? "[U] " : " ",
+ ap->rreq6_draft_01.rreq_hops,
+ (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_id),
+ ip6addr_string(&ap->rreq6_draft_01.rreq_da),
+ (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_ds),
+ ip6addr_string(&ap->rreq6_draft_01.rreq_oa),
+ (unsigned long)EXTRACT_32BITS(&ap->rreq6_draft_01.rreq_os));
+ if (i >= sizeof(struct aodv_ext))
+ aodv_extension((void *)(&ap->rreq6_draft_01 + 1), i);
+#else
+ printf(" rreq %u", length);
+#endif
+}
+
+static void
+#ifdef INET6
+aodv_v6_draft_01_rrep(const union aodv *ap, const u_char *dat, u_int length)
+#else
+aodv_v6_draft_01_rrep(const union aodv *ap _U_, const u_char *dat _U_,
+ u_int length)
+#endif
+{
+#ifdef INET6
+ u_int i;
+
+ if (snapend < dat) {
+ printf(" [|aodv]");
+ return;
+ }
+ i = min(length, (u_int)(snapend - dat));
+ if (i < sizeof(ap->rrep6_draft_01)) {
+ printf(" [|rrep6]");
+ return;
+ }
+ i -= sizeof(ap->rrep6_draft_01);
+ printf(" rrep %u %s%sprefix %u hops %u\n"
+ "\tdst %s dseq %lu src %s %lu ms", length,
+ ap->rrep6_draft_01.rrep_type & RREP_REPAIR ? "[R]" : "",
+ ap->rrep6_draft_01.rrep_type & RREP_ACK ? "[A] " : " ",
+ ap->rrep6_draft_01.rrep_ps & RREP_PREFIX_MASK,
+ ap->rrep6_draft_01.rrep_hops,
+ ip6addr_string(&ap->rrep6_draft_01.rrep_da),
+ (unsigned long)EXTRACT_32BITS(&ap->rrep6_draft_01.rrep_ds),
+ ip6addr_string(&ap->rrep6_draft_01.rrep_oa),
+ (unsigned long)EXTRACT_32BITS(&ap->rrep6_draft_01.rrep_life));
+ if (i >= sizeof(struct aodv_ext))
+ aodv_extension((void *)(&ap->rrep6_draft_01 + 1), i);
+#else
+ printf(" rrep %u", length);
+#endif
+}
+
+static void
+#ifdef INET6
+aodv_v6_draft_01_rerr(const union aodv *ap, u_int length)
+#else
+aodv_v6_draft_01_rerr(const union aodv *ap _U_, u_int length)
+#endif
+{
+#ifdef INET6
+ const struct rerr_unreach6_draft_01 *dp6 = NULL;
+ int i, j, n, trunc;
+
+ i = length - offsetof(struct aodv_rerr, r);
+ j = sizeof(ap->rerr.r.dest6_draft_01[0]);
+ dp6 = &ap->rerr.r.dest6_draft_01[0];
+ n = ap->rerr.rerr_dc * j;
+ printf(" rerr %s [items %u] [%u]:",
+ ap->rerr.rerr_flags & RERR_NODELETE ? "[D]" : "",
+ ap->rerr.rerr_dc, length);
+ trunc = n - (i/j);
+ for (; i -= j >= 0; ++dp6) {
+ printf(" {%s}(%ld)", ip6addr_string(&dp6->u_da),
+ (unsigned long)EXTRACT_32BITS(&dp6->u_ds));
+ }
+ if (trunc)
+ printf("[|rerr]");
+#else
+ printf(" rerr %u", length);
+#endif
+}
+
+void
+aodv_print(const u_char *dat, u_int length, int is_ip6)
+{
+ const union aodv *ap;
+
+ ap = (union aodv *)dat;
+ if (snapend < dat) {
+ printf(" [|aodv]");
+ return;
+ }
+ if (min(length, (u_int)(snapend - dat)) < sizeof(ap->rrep_ack)) {
+ printf(" [|aodv]");
+ return;
+ }
+ printf(" aodv");
+
+ switch (ap->rerr.rerr_type) {
+
+ case AODV_RREQ:
+ if (is_ip6)
+ aodv_v6_rreq(ap, dat, length);
+ else
+ aodv_rreq(ap, dat, length);
+ break;
+
+ case AODV_RREP:
+ if (is_ip6)
+ aodv_v6_rrep(ap, dat, length);
+ else
+ aodv_rrep(ap, dat, length);
+ break;
+
+ case AODV_RERR:
+ if (is_ip6)
+ aodv_v6_rerr(ap, length);
+ else
+ aodv_rerr(ap, dat, length);
+ break;
+
+ case AODV_RREP_ACK:
+ printf(" rrep-ack %u", length);
+ break;
+
+ case AODV_V6_DRAFT_01_RREQ:
+ aodv_v6_draft_01_rreq(ap, dat, length);
+ break;
+
+ case AODV_V6_DRAFT_01_RREP:
+ aodv_v6_draft_01_rrep(ap, dat, length);
+ break;
+
+ case AODV_V6_DRAFT_01_RERR:
+ aodv_v6_draft_01_rerr(ap, length);
+ break;
+
+ case AODV_V6_DRAFT_01_RREP_ACK:
+ printf(" rrep-ack %u", length);
+ break;
+
+ default:
+ printf(" %u %u", ap->rreq.rreq_type, length);
+ }
+}
diff --git a/freebsd/contrib/tcpdump/print-ap1394.c b/freebsd/contrib/tcpdump/print-ap1394.c
new file mode 100644
index 00000000..698b2123
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-ap1394.c
@@ -0,0 +1,121 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ap1394.c,v 1.5 2006-02-11 22:12:06 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <pcap.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+
+/*
+ * Structure of a header for Apple's IP-over-IEEE 1384 BPF header.
+ */
+#define FIREWIRE_EUI64_LEN 8
+struct firewire_header {
+ u_char firewire_dhost[FIREWIRE_EUI64_LEN];
+ u_char firewire_shost[FIREWIRE_EUI64_LEN];
+ u_short firewire_type;
+};
+
+/*
+ * Length of that header; note that some compilers may pad
+ * "struct firewire_header" to a multiple of 4 bytes, for example, so
+ * "sizeof (struct firewire_header)" may not give the right answer.
+ */
+#define FIREWIRE_HDRLEN 18
+
+static inline void
+ap1394_hdr_print(register const u_char *bp, u_int length)
+{
+ register const struct firewire_header *fp;
+ u_int16_t firewire_type;
+
+ fp = (const struct firewire_header *)bp;
+
+ (void)printf("%s > %s",
+ linkaddr_string(fp->firewire_dhost, LINKADDR_IEEE1394, FIREWIRE_EUI64_LEN),
+ linkaddr_string(fp->firewire_shost, LINKADDR_IEEE1394, FIREWIRE_EUI64_LEN));
+
+ firewire_type = EXTRACT_16BITS(&fp->firewire_type);
+ if (!qflag) {
+ (void)printf(", ethertype %s (0x%04x)",
+ tok2str(ethertype_values,"Unknown", firewire_type),
+ firewire_type);
+ } else {
+ (void)printf(", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", firewire_type));
+ }
+
+ (void)printf(", length %u: ", length);
+}
+
+/*
+ * This is the top level routine of the printer. 'p' points
+ * to the ether header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ */
+u_int
+ap1394_if_print(const struct pcap_pkthdr *h, const u_char *p)
+{
+ u_int length = h->len;
+ u_int caplen = h->caplen;
+ struct firewire_header *fp;
+ u_short ether_type;
+
+ if (caplen < FIREWIRE_HDRLEN) {
+ printf("[|ap1394]");
+ return FIREWIRE_HDRLEN;
+ }
+
+ if (eflag)
+ ap1394_hdr_print(p, length);
+
+ length -= FIREWIRE_HDRLEN;
+ caplen -= FIREWIRE_HDRLEN;
+ fp = (struct firewire_header *)p;
+ p += FIREWIRE_HDRLEN;
+
+ ether_type = EXTRACT_16BITS(&fp->firewire_type);
+ if (ethertype_print(gndo, ether_type, p, length, caplen) == 0) {
+ /* ether_type not known, print raw packet */
+ if (!eflag)
+ ap1394_hdr_print((u_char *)fp, length + FIREWIRE_HDRLEN);
+
+ if (!suppress_default_print)
+ default_print(p, caplen);
+ }
+
+ return FIREWIRE_HDRLEN;
+}
diff --git a/freebsd/contrib/tcpdump/print-arcnet.c b/freebsd/contrib/tcpdump/print-arcnet.c
new file mode 100644
index 00000000..83bb8fb6
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-arcnet.c
@@ -0,0 +1,300 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * From: NetBSD: print-arcnet.c,v 1.2 2000/04/24 13:02:28 itojun Exp
+ */
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-arcnet.c,v 1.20 2005-04-06 21:32:38 mcr Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <pcap.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "arcnet.h"
+
+static int arcnet_encap_print(u_char arctype, const u_char *p,
+ u_int length, u_int caplen);
+
+struct tok arctypemap[] = {
+ { ARCTYPE_IP_OLD, "oldip" },
+ { ARCTYPE_ARP_OLD, "oldarp" },
+ { ARCTYPE_IP, "ip" },
+ { ARCTYPE_ARP, "arp" },
+ { ARCTYPE_REVARP, "rarp" },
+ { ARCTYPE_ATALK, "atalk" },
+ { ARCTYPE_BANIAN, "banyan" },
+ { ARCTYPE_IPX, "ipx" },
+ { ARCTYPE_INET6, "ipv6" },
+ { ARCTYPE_DIAGNOSE, "diag" },
+ { 0, 0 }
+};
+
+static inline void
+arcnet_print(const u_char *bp, u_int length, int phds, int flag, u_int seqid)
+{
+ const struct arc_header *ap;
+ const char *arctypename;
+
+
+ ap = (const struct arc_header *)bp;
+
+
+ if (qflag) {
+ (void)printf("%02x %02x %d: ",
+ ap->arc_shost,
+ ap->arc_dhost,
+ length);
+ return;
+ }
+
+ arctypename = tok2str(arctypemap, "%02x", ap->arc_type);
+
+ if (!phds) {
+ (void)printf("%02x %02x %s %d: ",
+ ap->arc_shost, ap->arc_dhost, arctypename,
+ length);
+ return;
+ }
+
+ if (flag == 0) {
+ (void)printf("%02x %02x %s seqid %04x %d: ",
+ ap->arc_shost, ap->arc_dhost, arctypename, seqid,
+ length);
+ return;
+ }
+
+ if (flag & 1)
+ (void)printf("%02x %02x %s seqid %04x "
+ "(first of %d fragments) %d: ",
+ ap->arc_shost, ap->arc_dhost, arctypename, seqid,
+ (flag + 3) / 2, length);
+ else
+ (void)printf("%02x %02x %s seqid %04x "
+ "(fragment %d) %d: ",
+ ap->arc_shost, ap->arc_dhost, arctypename, seqid,
+ flag/2 + 1, length);
+}
+
+/*
+ * This is the top level routine of the printer. 'p' points
+ * to the ARCNET header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ */
+u_int
+arcnet_if_print(const struct pcap_pkthdr *h, const u_char *p)
+{
+ u_int caplen = h->caplen;
+ u_int length = h->len;
+ const struct arc_header *ap;
+
+ int phds, flag = 0, archdrlen = 0;
+ u_int seqid = 0;
+ u_char arc_type;
+
+ if (caplen < ARC_HDRLEN) {
+ printf("[|arcnet]");
+ return (caplen);
+ }
+
+ ap = (const struct arc_header *)p;
+ arc_type = ap->arc_type;
+
+ switch (arc_type) {
+ default:
+ phds = 1;
+ break;
+ case ARCTYPE_IP_OLD:
+ case ARCTYPE_ARP_OLD:
+ case ARCTYPE_DIAGNOSE:
+ phds = 0;
+ archdrlen = ARC_HDRLEN;
+ break;
+ }
+
+ if (phds) {
+ if (caplen < ARC_HDRNEWLEN) {
+ arcnet_print(p, length, 0, 0, 0);
+ printf("[|phds]");
+ return (caplen);
+ }
+
+ if (ap->arc_flag == 0xff) {
+ if (caplen < ARC_HDRNEWLEN_EXC) {
+ arcnet_print(p, length, 0, 0, 0);
+ printf("[|phds extended]");
+ return (caplen);
+ }
+ flag = ap->arc_flag2;
+ seqid = EXTRACT_16BITS(&ap->arc_seqid2);
+ archdrlen = ARC_HDRNEWLEN_EXC;
+ } else {
+ flag = ap->arc_flag;
+ seqid = EXTRACT_16BITS(&ap->arc_seqid);
+ archdrlen = ARC_HDRNEWLEN;
+ }
+ }
+
+
+ if (eflag)
+ arcnet_print(p, length, phds, flag, seqid);
+
+ /*
+ * Go past the ARCNET header.
+ */
+ length -= archdrlen;
+ caplen -= archdrlen;
+ p += archdrlen;
+
+ if (phds && flag && (flag & 1) == 0) {
+ /*
+ * This is a middle fragment.
+ */
+ return (archdrlen);
+ }
+
+ if (!arcnet_encap_print(arc_type, p, length, caplen))
+ default_print(p, caplen);
+
+ return (archdrlen);
+}
+
+/*
+ * This is the top level routine of the printer. 'p' points
+ * to the ARCNET header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured. It is quite similar
+ * to the non-Linux style printer except that Linux doesn't ever
+ * supply packets that look like exception frames, it always supplies
+ * reassembled packets rather than raw frames, and headers have an
+ * extra "offset" field between the src/dest and packet type.
+ */
+u_int
+arcnet_linux_if_print(const struct pcap_pkthdr *h, const u_char *p)
+{
+ u_int caplen = h->caplen;
+ u_int length = h->len;
+ const struct arc_linux_header *ap;
+
+ int archdrlen = 0;
+ u_char arc_type;
+
+ if (caplen < ARC_LINUX_HDRLEN) {
+ printf("[|arcnet]");
+ return (caplen);
+ }
+
+ ap = (const struct arc_linux_header *)p;
+ arc_type = ap->arc_type;
+
+ switch (arc_type) {
+ default:
+ archdrlen = ARC_LINUX_HDRNEWLEN;
+ if (caplen < ARC_LINUX_HDRNEWLEN) {
+ printf("[|arcnet]");
+ return (caplen);
+ }
+ break;
+ case ARCTYPE_IP_OLD:
+ case ARCTYPE_ARP_OLD:
+ case ARCTYPE_DIAGNOSE:
+ archdrlen = ARC_LINUX_HDRLEN;
+ break;
+ }
+
+ if (eflag)
+ arcnet_print(p, length, 0, 0, 0);
+
+ /*
+ * Go past the ARCNET header.
+ */
+ length -= archdrlen;
+ caplen -= archdrlen;
+ p += archdrlen;
+
+ if (!arcnet_encap_print(arc_type, p, length, caplen))
+ default_print(p, caplen);
+
+ return (archdrlen);
+}
+
+/*
+ * Prints the packet encapsulated in an ARCnet data field,
+ * given the ARCnet system code.
+ *
+ * Returns non-zero if it can do so, zero if the system code is unknown.
+ */
+
+
+static int
+arcnet_encap_print(u_char arctype, const u_char *p,
+ u_int length, u_int caplen)
+{
+ switch (arctype) {
+
+ case ARCTYPE_IP_OLD:
+ case ARCTYPE_IP:
+ ip_print(gndo, p, length);
+ return (1);
+
+#ifdef INET6
+ case ARCTYPE_INET6:
+ ip6_print(gndo, p, length);
+ return (1);
+#endif /*INET6*/
+
+ case ARCTYPE_ARP_OLD:
+ case ARCTYPE_ARP:
+ case ARCTYPE_REVARP:
+ arp_print(gndo, p, length, caplen);
+ return (1);
+
+ case ARCTYPE_ATALK: /* XXX was this ever used? */
+ if (vflag)
+ fputs("et1 ", stdout);
+ atalk_print(p, length);
+ return (1);
+
+ case ARCTYPE_IPX:
+ ipx_print(p, length);
+ return (1);
+
+ default:
+ return (0);
+ }
+}
+
+/*
+ * Local Variables:
+ * c-style: bsd
+ * End:
+ */
+
diff --git a/freebsd/contrib/tcpdump/print-arp.c b/freebsd/contrib/tcpdump/print-arp.c
new file mode 100644
index 00000000..ac85cf96
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-arp.c
@@ -0,0 +1,421 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-arp.c,v 1.66 2006-03-03 22:53:21 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "netdissect.h"
+#include "addrtoname.h"
+#include "ether.h"
+#include "ethertype.h"
+#include "extract.h" /* must come after interface.h */
+
+/*
+ * Address Resolution Protocol.
+ *
+ * See RFC 826 for protocol description. ARP packets are variable
+ * in size; the arphdr structure defines the fixed-length portion.
+ * Protocol type values are the same as those for 10 Mb/s Ethernet.
+ * It is followed by the variable-sized fields ar_sha, arp_spa,
+ * arp_tha and arp_tpa in that order, according to the lengths
+ * specified. Field names used correspond to RFC 826.
+ */
+struct arp_pkthdr {
+ u_short ar_hrd; /* format of hardware address */
+#define ARPHRD_ETHER 1 /* ethernet hardware format */
+#define ARPHRD_IEEE802 6 /* token-ring hardware format */
+#define ARPHRD_ARCNET 7 /* arcnet hardware format */
+#define ARPHRD_FRELAY 15 /* frame relay hardware format */
+#define ARPHRD_ATM2225 19 /* ATM (RFC 2225) */
+#define ARPHRD_STRIP 23 /* Ricochet Starmode Radio hardware format */
+#define ARPHRD_IEEE1394 24 /* IEEE 1394 (FireWire) hardware format */
+ u_short ar_pro; /* format of protocol address */
+ u_char ar_hln; /* length of hardware address */
+ u_char ar_pln; /* length of protocol address */
+ u_short ar_op; /* one of: */
+#define ARPOP_REQUEST 1 /* request to resolve address */
+#define ARPOP_REPLY 2 /* response to previous request */
+#define ARPOP_REVREQUEST 3 /* request protocol address given hardware */
+#define ARPOP_REVREPLY 4 /* response giving protocol address */
+#define ARPOP_INVREQUEST 8 /* request to identify peer */
+#define ARPOP_INVREPLY 9 /* response identifying peer */
+#define ARPOP_NAK 10 /* NAK - only valif for ATM ARP */
+
+/*
+ * The remaining fields are variable in size,
+ * according to the sizes above.
+ */
+#ifdef COMMENT_ONLY
+ u_char ar_sha[]; /* sender hardware address */
+ u_char ar_spa[]; /* sender protocol address */
+ u_char ar_tha[]; /* target hardware address */
+ u_char ar_tpa[]; /* target protocol address */
+#endif
+#define ar_sha(ap) (((const u_char *)((ap)+1))+0)
+#define ar_spa(ap) (((const u_char *)((ap)+1))+ (ap)->ar_hln)
+#define ar_tha(ap) (((const u_char *)((ap)+1))+ (ap)->ar_hln+(ap)->ar_pln)
+#define ar_tpa(ap) (((const u_char *)((ap)+1))+2*(ap)->ar_hln+(ap)->ar_pln)
+};
+
+#define ARP_HDRLEN 8
+
+#define HRD(ap) EXTRACT_16BITS(&(ap)->ar_hrd)
+#define HRD_LEN(ap) ((ap)->ar_hln)
+#define PROTO_LEN(ap) ((ap)->ar_pln)
+#define OP(ap) EXTRACT_16BITS(&(ap)->ar_op)
+#define PRO(ap) EXTRACT_16BITS(&(ap)->ar_pro)
+#define SHA(ap) (ar_sha(ap))
+#define SPA(ap) (ar_spa(ap))
+#define THA(ap) (ar_tha(ap))
+#define TPA(ap) (ar_tpa(ap))
+
+
+struct tok arpop_values[] = {
+ { ARPOP_REQUEST, "Request" },
+ { ARPOP_REPLY, "Reply" },
+ { ARPOP_REVREQUEST, "Reverse Request" },
+ { ARPOP_REVREPLY, "Reverse Reply" },
+ { ARPOP_INVREQUEST, "Inverse Request" },
+ { ARPOP_INVREPLY, "Inverse Reply" },
+ { ARPOP_NAK, "NACK Reply" },
+ { 0, NULL }
+};
+
+struct tok arphrd_values[] = {
+ { ARPHRD_ETHER, "Ethernet" },
+ { ARPHRD_IEEE802, "TokenRing" },
+ { ARPHRD_ARCNET, "ArcNet" },
+ { ARPHRD_FRELAY, "FrameRelay" },
+ { ARPHRD_STRIP, "Strip" },
+ { ARPHRD_IEEE1394, "IEEE 1394" },
+ { ARPHRD_ATM2225, "ATM" },
+ { 0, NULL }
+};
+
+/*
+ * ATM Address Resolution Protocol.
+ *
+ * See RFC 2225 for protocol description. ATMARP packets are similar
+ * to ARP packets, except that there are no length fields for the
+ * protocol address - instead, there are type/length fields for
+ * the ATM number and subaddress - and the hardware addresses consist
+ * of an ATM number and an ATM subaddress.
+ */
+struct atmarp_pkthdr {
+ u_short aar_hrd; /* format of hardware address */
+ u_short aar_pro; /* format of protocol address */
+ u_char aar_shtl; /* length of source ATM number */
+ u_char aar_sstl; /* length of source ATM subaddress */
+#define ATMARP_IS_E164 0x40 /* bit in type/length for E.164 format */
+#define ATMARP_LEN_MASK 0x3F /* length of {sub}address in type/length */
+ u_short aar_op; /* same as regular ARP */
+ u_char aar_spln; /* length of source protocol address */
+ u_char aar_thtl; /* length of target ATM number */
+ u_char aar_tstl; /* length of target ATM subaddress */
+ u_char aar_tpln; /* length of target protocol address */
+/*
+ * The remaining fields are variable in size,
+ * according to the sizes above.
+ */
+#ifdef COMMENT_ONLY
+ u_char aar_sha[]; /* source ATM number */
+ u_char aar_ssa[]; /* source ATM subaddress */
+ u_char aar_spa[]; /* sender protocol address */
+ u_char aar_tha[]; /* target ATM number */
+ u_char aar_tsa[]; /* target ATM subaddress */
+ u_char aar_tpa[]; /* target protocol address */
+#endif
+
+#define ATMHRD(ap) EXTRACT_16BITS(&(ap)->aar_hrd)
+#define ATMSHRD_LEN(ap) ((ap)->aar_shtl & ATMARP_LEN_MASK)
+#define ATMSSLN(ap) ((ap)->aar_sstl & ATMARP_LEN_MASK)
+#define ATMSPROTO_LEN(ap) ((ap)->aar_spln)
+#define ATMOP(ap) EXTRACT_16BITS(&(ap)->aar_op)
+#define ATMPRO(ap) EXTRACT_16BITS(&(ap)->aar_pro)
+#define ATMTHRD_LEN(ap) ((ap)->aar_thtl & ATMARP_LEN_MASK)
+#define ATMTSLN(ap) ((ap)->aar_tstl & ATMARP_LEN_MASK)
+#define ATMTPROTO_LEN(ap) ((ap)->aar_tpln)
+#define aar_sha(ap) ((const u_char *)((ap)+1))
+#define aar_ssa(ap) (aar_sha(ap) + ATMSHRD_LEN(ap))
+#define aar_spa(ap) (aar_ssa(ap) + ATMSSLN(ap))
+#define aar_tha(ap) (aar_spa(ap) + ATMSPROTO_LEN(ap))
+#define aar_tsa(ap) (aar_tha(ap) + ATMTHRD_LEN(ap))
+#define aar_tpa(ap) (aar_tsa(ap) + ATMTSLN(ap))
+};
+
+#define ATMSHA(ap) (aar_sha(ap))
+#define ATMSSA(ap) (aar_ssa(ap))
+#define ATMSPA(ap) (aar_spa(ap))
+#define ATMTHA(ap) (aar_tha(ap))
+#define ATMTSA(ap) (aar_tsa(ap))
+#define ATMTPA(ap) (aar_tpa(ap))
+
+static u_char ezero[6];
+
+static void
+atmarp_addr_print(netdissect_options *ndo,
+ const u_char *ha, u_int ha_len, const u_char *srca,
+ u_int srca_len)
+{
+ if (ha_len == 0)
+ ND_PRINT((ndo, "<No address>"));
+ else {
+ ND_PRINT((ndo, "%s", linkaddr_string(ha, LINKADDR_ATM, ha_len)));
+ if (srca_len != 0)
+ ND_PRINT((ndo, ",%s",
+ linkaddr_string(srca, LINKADDR_ATM, srca_len)));
+ }
+}
+
+static void
+atmarp_print(netdissect_options *ndo,
+ const u_char *bp, u_int length, u_int caplen)
+{
+ const struct atmarp_pkthdr *ap;
+ u_short pro, hrd, op;
+
+ ap = (const struct atmarp_pkthdr *)bp;
+ ND_TCHECK(*ap);
+
+ hrd = ATMHRD(ap);
+ pro = ATMPRO(ap);
+ op = ATMOP(ap);
+
+ if (!ND_TTEST2(*aar_tpa(ap), ATMTPROTO_LEN(ap))) {
+ ND_PRINT((ndo, "[|ARP]"));
+ ND_DEFAULTPRINT((const u_char *)ap, length);
+ return;
+ }
+
+ if (!ndo->ndo_eflag) {
+ ND_PRINT((ndo, "ARP, "));
+ }
+
+ if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) ||
+ ATMSPROTO_LEN(ap) != 4 ||
+ ATMTPROTO_LEN(ap) != 4 ||
+ ndo->ndo_vflag) {
+ ND_PRINT((ndo, "%s, %s (len %u/%u)",
+ tok2str(arphrd_values, "Unknown Hardware (%u)", hrd),
+ tok2str(ethertype_values, "Unknown Protocol (0x%04x)", pro),
+ ATMSPROTO_LEN(ap),
+ ATMTPROTO_LEN(ap)));
+
+ /* don't know know about the address formats */
+ if (!ndo->ndo_vflag) {
+ goto out;
+ }
+ }
+
+ /* print operation */
+ printf("%s%s ",
+ ndo->ndo_vflag ? ", " : "",
+ tok2str(arpop_values, "Unknown (%u)", op));
+
+ switch (op) {
+
+ case ARPOP_REQUEST:
+ ND_PRINT((ndo, "who-has %s", ipaddr_string(ATMTPA(ap))));
+ if (ATMTHRD_LEN(ap) != 0) {
+ ND_PRINT((ndo, " ("));
+ atmarp_addr_print(ndo, ATMTHA(ap), ATMTHRD_LEN(ap),
+ ATMTSA(ap), ATMTSLN(ap));
+ ND_PRINT((ndo, ")"));
+ }
+ ND_PRINT((ndo, "tell %s", ipaddr_string(ATMSPA(ap))));
+ break;
+
+ case ARPOP_REPLY:
+ ND_PRINT((ndo, "%s is-at ", ipaddr_string(ATMSPA(ap))));
+ atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap),
+ ATMSSLN(ap));
+ break;
+
+ case ARPOP_INVREQUEST:
+ ND_PRINT((ndo, "who-is "));
+ atmarp_addr_print(ndo, ATMTHA(ap), ATMTHRD_LEN(ap), ATMTSA(ap),
+ ATMTSLN(ap));
+ ND_PRINT((ndo, " tell "));
+ atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap),
+ ATMSSLN(ap));
+ break;
+
+ case ARPOP_INVREPLY:
+ atmarp_addr_print(ndo, ATMSHA(ap), ATMSHRD_LEN(ap), ATMSSA(ap),
+ ATMSSLN(ap));
+ ND_PRINT((ndo, "at %s", ipaddr_string(ATMSPA(ap))));
+ break;
+
+ case ARPOP_NAK:
+ ND_PRINT((ndo, "for %s", ipaddr_string(ATMSPA(ap))));
+ break;
+
+ default:
+ ND_DEFAULTPRINT((const u_char *)ap, caplen);
+ return;
+ }
+
+ out:
+ ND_PRINT((ndo, ", length %u", length));
+ return;
+
+trunc:
+ ND_PRINT((ndo, "[|ARP]"));
+}
+
+void
+arp_print(netdissect_options *ndo,
+ const u_char *bp, u_int length, u_int caplen)
+{
+ const struct arp_pkthdr *ap;
+ u_short pro, hrd, op, linkaddr;
+
+ ap = (const struct arp_pkthdr *)bp;
+ ND_TCHECK(*ap);
+
+ hrd = HRD(ap);
+ pro = PRO(ap);
+ op = OP(ap);
+
+
+ /* if its ATM then call the ATM ARP printer
+ for Frame-relay ARP most of the fields
+ are similar to Ethernet so overload the Ethernet Printer
+ and set the linkaddr type for linkaddr_string() accordingly */
+
+ switch(hrd) {
+ case ARPHRD_ATM2225:
+ atmarp_print(ndo, bp, length, caplen);
+ return;
+ case ARPHRD_FRELAY:
+ linkaddr = LINKADDR_FRELAY;
+ break;
+ default:
+ linkaddr = LINKADDR_ETHER;
+ break;
+ }
+
+ if (!ND_TTEST2(*ar_tpa(ap), PROTO_LEN(ap))) {
+ ND_PRINT((ndo, "[|ARP]"));
+ ND_DEFAULTPRINT((const u_char *)ap, length);
+ return;
+ }
+
+ if (!ndo->ndo_eflag) {
+ ND_PRINT((ndo, "ARP, "));
+ }
+
+ /* print hardware type/len and proto type/len */
+ if ((pro != ETHERTYPE_IP && pro != ETHERTYPE_TRAIL) ||
+ PROTO_LEN(ap) != 4 ||
+ HRD_LEN(ap) == 0 ||
+ ndo->ndo_vflag) {
+ ND_PRINT((ndo, "%s (len %u), %s (len %u)",
+ tok2str(arphrd_values, "Unknown Hardware (%u)", hrd),
+ HRD_LEN(ap),
+ tok2str(ethertype_values, "Unknown Protocol (0x%04x)", pro),
+ PROTO_LEN(ap)));
+
+ /* don't know know about the address formats */
+ if (!ndo->ndo_vflag) {
+ goto out;
+ }
+ }
+
+ /* print operation */
+ printf("%s%s ",
+ ndo->ndo_vflag ? ", " : "",
+ tok2str(arpop_values, "Unknown (%u)", op));
+
+ switch (op) {
+
+ case ARPOP_REQUEST:
+ ND_PRINT((ndo, "who-has %s", ipaddr_string(TPA(ap))));
+ if (memcmp((const char *)ezero, (const char *)THA(ap), HRD_LEN(ap)) != 0)
+ ND_PRINT((ndo, " (%s)",
+ linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap))));
+ ND_PRINT((ndo, " tell %s", ipaddr_string(SPA(ap))));
+ break;
+
+ case ARPOP_REPLY:
+ ND_PRINT((ndo, "%s is-at %s",
+ ipaddr_string(SPA(ap)),
+ linkaddr_string(SHA(ap), linkaddr, HRD_LEN(ap))));
+ break;
+
+ case ARPOP_REVREQUEST:
+ ND_PRINT((ndo, "who-is %s tell %s",
+ linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)),
+ linkaddr_string(SHA(ap), linkaddr, HRD_LEN(ap))));
+ break;
+
+ case ARPOP_REVREPLY:
+ ND_PRINT((ndo, "%s at %s",
+ linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)),
+ ipaddr_string(TPA(ap))));
+ break;
+
+ case ARPOP_INVREQUEST:
+ ND_PRINT((ndo, "who-is %s tell %s",
+ linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)),
+ linkaddr_string(SHA(ap), linkaddr, HRD_LEN(ap))));
+ break;
+
+ case ARPOP_INVREPLY:
+ ND_PRINT((ndo,"%s at %s",
+ linkaddr_string(THA(ap), linkaddr, HRD_LEN(ap)),
+ ipaddr_string(TPA(ap))));
+ break;
+
+ default:
+ ND_DEFAULTPRINT((const u_char *)ap, caplen);
+ return;
+ }
+
+ out:
+ ND_PRINT((ndo, ", length %u", length));
+
+ return;
+trunc:
+ ND_PRINT((ndo, "[|ARP]"));
+}
+
+/*
+ * Local Variables:
+ * c-style: bsd
+ * End:
+ */
+
diff --git a/freebsd/contrib/tcpdump/print-ascii.c b/freebsd/contrib/tcpdump/print-ascii.c
new file mode 100644
index 00000000..70199afd
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-ascii.c
@@ -0,0 +1,185 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/* $NetBSD: print-ascii.c,v 1.1 1999/09/30 14:49:12 sjg Exp $ */
+
+/*-
+ * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Alan Barrett and Simon J. Gerraty.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ascii.c,v 1.17 2005-07-06 20:53:32 guy Exp $";
+#endif
+#include <tcpdump-stdinc.h>
+#include <stdio.h>
+
+#include "interface.h"
+
+#define ASCII_LINELENGTH 300
+#define HEXDUMP_BYTES_PER_LINE 16
+#define HEXDUMP_SHORTS_PER_LINE (HEXDUMP_BYTES_PER_LINE / 2)
+#define HEXDUMP_HEXSTUFF_PER_SHORT 5 /* 4 hex digits and a space */
+#define HEXDUMP_HEXSTUFF_PER_LINE \
+ (HEXDUMP_HEXSTUFF_PER_SHORT * HEXDUMP_SHORTS_PER_LINE)
+
+void
+ascii_print(register const u_char *cp, register u_int length)
+{
+ register int s;
+
+ putchar('\n');
+ while (length > 0) {
+ s = *cp++;
+ length--;
+ if (!isgraph(s) &&
+ (s != '\t' && s != ' ' && s != '\n' && s != '\r'))
+ putchar('.');
+ else
+ putchar(s);
+ }
+}
+
+void
+hex_and_ascii_print_with_offset(register const char *ident,
+ register const u_char *cp, register u_int length, register u_int oset)
+{
+ register u_int i;
+ register int s1, s2;
+ register int nshorts;
+ char hexstuff[HEXDUMP_SHORTS_PER_LINE*HEXDUMP_HEXSTUFF_PER_SHORT+1], *hsp;
+ char asciistuff[ASCII_LINELENGTH+1], *asp;
+
+ nshorts = length / sizeof(u_short);
+ i = 0;
+ hsp = hexstuff; asp = asciistuff;
+ while (--nshorts >= 0) {
+ s1 = *cp++;
+ s2 = *cp++;
+ (void)snprintf(hsp, sizeof(hexstuff) - (hsp - hexstuff),
+ " %02x%02x", s1, s2);
+ hsp += HEXDUMP_HEXSTUFF_PER_SHORT;
+ *(asp++) = (isgraph(s1) ? s1 : '.');
+ *(asp++) = (isgraph(s2) ? s2 : '.');
+ i++;
+ if (i >= HEXDUMP_SHORTS_PER_LINE) {
+ *hsp = *asp = '\0';
+ (void)printf("%s0x%04x: %-*s %s",
+ ident, oset, HEXDUMP_HEXSTUFF_PER_LINE,
+ hexstuff, asciistuff);
+ i = 0; hsp = hexstuff; asp = asciistuff;
+ oset += HEXDUMP_BYTES_PER_LINE;
+ }
+ }
+ if (length & 1) {
+ s1 = *cp++;
+ (void)snprintf(hsp, sizeof(hexstuff) - (hsp - hexstuff),
+ " %02x", s1);
+ hsp += 3;
+ *(asp++) = (isgraph(s1) ? s1 : '.');
+ ++i;
+ }
+ if (i > 0) {
+ *hsp = *asp = '\0';
+ (void)printf("%s0x%04x: %-*s %s",
+ ident, oset, HEXDUMP_HEXSTUFF_PER_LINE,
+ hexstuff, asciistuff);
+ }
+}
+
+void
+hex_and_ascii_print(register const char *ident, register const u_char *cp,
+ register u_int length)
+{
+ hex_and_ascii_print_with_offset(ident, cp, length, 0);
+}
+
+/*
+ * telnet_print() wants this. It is essentially default_print_unaligned()
+ */
+void
+hex_print_with_offset(register const char *ident, register const u_char *cp, register u_int length,
+ register u_int oset)
+{
+ register u_int i, s;
+ register int nshorts;
+
+ nshorts = (u_int) length / sizeof(u_short);
+ i = 0;
+ while (--nshorts >= 0) {
+ if ((i++ % 8) == 0) {
+ (void)printf("%s0x%04x: ", ident, oset);
+ oset += HEXDUMP_BYTES_PER_LINE;
+ }
+ s = *cp++;
+ (void)printf(" %02x%02x", s, *cp++);
+ }
+ if (length & 1) {
+ if ((i % 8) == 0)
+ (void)printf("%s0x%04x: ", ident, oset);
+ (void)printf(" %02x", *cp);
+ }
+}
+
+/*
+ * just for completeness
+ */
+void
+hex_print(register const char *ident, register const u_char *cp, register u_int length)
+{
+ hex_print_with_offset(ident, cp, length, 0);
+}
+
+#ifdef MAIN
+int
+main(int argc, char *argv[])
+{
+ hex_print("\n\t", "Hello, World!\n", 14);
+ printf("\n");
+ hex_and_ascii_print("\n\t", "Hello, World!\n", 14);
+ printf("\n");
+ ascii_print("Hello, World!\n", 14);
+ printf("\n");
+#define TMSG "Now is the winter of our discontent...\n"
+ hex_print_with_offset("\n\t", TMSG, sizeof(TMSG) - 1, 0x100);
+ printf("\n");
+ hex_and_ascii_print_with_offset("\n\t", TMSG, sizeof(TMSG) - 1, 0x100);
+ printf("\n");
+ exit(0);
+}
+#endif /* MAIN */
diff --git a/freebsd/contrib/tcpdump/print-atalk.c b/freebsd/contrib/tcpdump/print-atalk.c
new file mode 100644
index 00000000..f6a0dcc0
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-atalk.c
@@ -0,0 +1,627 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Format and print AppleTalk packets.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-atalk.c,v 1.81 2004-05-01 09:41:50 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pcap.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+#include "extract.h" /* must come after interface.h */
+#include "appletalk.h"
+
+static struct tok type2str[] = {
+ { ddpRTMP, "rtmp" },
+ { ddpRTMPrequest, "rtmpReq" },
+ { ddpECHO, "echo" },
+ { ddpIP, "IP" },
+ { ddpARP, "ARP" },
+ { ddpKLAP, "KLAP" },
+ { 0, NULL }
+};
+
+struct aarp {
+ u_int16_t htype, ptype;
+ u_int8_t halen, palen;
+ u_int16_t op;
+ u_int8_t hsaddr[6];
+ u_int8_t psaddr[4];
+ u_int8_t hdaddr[6];
+ u_int8_t pdaddr[4];
+};
+
+static char tstr[] = "[|atalk]";
+
+static void atp_print(const struct atATP *, u_int);
+static void atp_bitmap_print(u_char);
+static void nbp_print(const struct atNBP *, u_int, u_short, u_char, u_char);
+static const char *print_cstring(const char *, const u_char *);
+static const struct atNBPtuple *nbp_tuple_print(const struct atNBPtuple *,
+ const u_char *,
+ u_short, u_char, u_char);
+static const struct atNBPtuple *nbp_name_print(const struct atNBPtuple *,
+ const u_char *);
+static const char *ataddr_string(u_short, u_char);
+static void ddp_print(const u_char *, u_int, int, u_short, u_char, u_char);
+static const char *ddpskt_string(int);
+
+/*
+ * Print LLAP packets received on a physical LocalTalk interface.
+ */
+u_int
+ltalk_if_print(const struct pcap_pkthdr *h, const u_char *p)
+{
+ return (llap_print(p, h->caplen));
+}
+
+/*
+ * Print AppleTalk LLAP packets.
+ */
+u_int
+llap_print(register const u_char *bp, u_int length)
+{
+ register const struct LAP *lp;
+ register const struct atDDP *dp;
+ register const struct atShortDDP *sdp;
+ u_short snet;
+ u_int hdrlen;
+
+ if (length < sizeof(*lp)) {
+ (void)printf(" [|llap %u]", length);
+ return (length);
+ }
+ lp = (const struct LAP *)bp;
+ bp += sizeof(*lp);
+ length -= sizeof(*lp);
+ hdrlen = sizeof(*lp);
+ switch (lp->type) {
+
+ case lapShortDDP:
+ if (length < ddpSSize) {
+ (void)printf(" [|sddp %u]", length);
+ return (length);
+ }
+ sdp = (const struct atShortDDP *)bp;
+ printf("%s.%s",
+ ataddr_string(0, lp->src), ddpskt_string(sdp->srcSkt));
+ printf(" > %s.%s:",
+ ataddr_string(0, lp->dst), ddpskt_string(sdp->dstSkt));
+ bp += ddpSSize;
+ length -= ddpSSize;
+ hdrlen += ddpSSize;
+ ddp_print(bp, length, sdp->type, 0, lp->src, sdp->srcSkt);
+ break;
+
+ case lapDDP:
+ if (length < ddpSize) {
+ (void)printf(" [|ddp %u]", length);
+ return (length);
+ }
+ dp = (const struct atDDP *)bp;
+ snet = EXTRACT_16BITS(&dp->srcNet);
+ printf("%s.%s", ataddr_string(snet, dp->srcNode),
+ ddpskt_string(dp->srcSkt));
+ printf(" > %s.%s:",
+ ataddr_string(EXTRACT_16BITS(&dp->dstNet), dp->dstNode),
+ ddpskt_string(dp->dstSkt));
+ bp += ddpSize;
+ length -= ddpSize;
+ hdrlen += ddpSize;
+ ddp_print(bp, length, dp->type, snet, dp->srcNode, dp->srcSkt);
+ break;
+
+#ifdef notdef
+ case lapKLAP:
+ klap_print(bp, length);
+ break;
+#endif
+
+ default:
+ printf("%d > %d at-lap#%d %u",
+ lp->src, lp->dst, lp->type, length);
+ break;
+ }
+ return (hdrlen);
+}
+
+/*
+ * Print EtherTalk/TokenTalk packets (or FDDITalk, or whatever it's called
+ * when it runs over FDDI; yes, I've seen FDDI captures with AppleTalk
+ * packets in them).
+ */
+void
+atalk_print(register const u_char *bp, u_int length)
+{
+ register const struct atDDP *dp;
+ u_short snet;
+
+ if(!eflag)
+ printf("AT ");
+
+ if (length < ddpSize) {
+ (void)printf(" [|ddp %u]", length);
+ return;
+ }
+ dp = (const struct atDDP *)bp;
+ snet = EXTRACT_16BITS(&dp->srcNet);
+ printf("%s.%s", ataddr_string(snet, dp->srcNode),
+ ddpskt_string(dp->srcSkt));
+ printf(" > %s.%s: ",
+ ataddr_string(EXTRACT_16BITS(&dp->dstNet), dp->dstNode),
+ ddpskt_string(dp->dstSkt));
+ bp += ddpSize;
+ length -= ddpSize;
+ ddp_print(bp, length, dp->type, snet, dp->srcNode, dp->srcSkt);
+}
+
+/* XXX should probably pass in the snap header and do checks like arp_print() */
+void
+aarp_print(register const u_char *bp, u_int length)
+{
+ register const struct aarp *ap;
+
+#define AT(member) ataddr_string((ap->member[1]<<8)|ap->member[2],ap->member[3])
+
+ printf("aarp ");
+ ap = (const struct aarp *)bp;
+ if (EXTRACT_16BITS(&ap->htype) == 1 &&
+ EXTRACT_16BITS(&ap->ptype) == ETHERTYPE_ATALK &&
+ ap->halen == 6 && ap->palen == 4 )
+ switch (EXTRACT_16BITS(&ap->op)) {
+
+ case 1: /* request */
+ (void)printf("who-has %s tell %s",
+ AT(pdaddr), AT(psaddr));
+ return;
+
+ case 2: /* response */
+ (void)printf("reply %s is-at %s",
+ AT(psaddr), etheraddr_string(ap->hsaddr));
+ return;
+
+ case 3: /* probe (oy!) */
+ (void)printf("probe %s tell %s",
+ AT(pdaddr), AT(psaddr));
+ return;
+ }
+ (void)printf("len %u op %u htype %u ptype %#x halen %u palen %u",
+ length, EXTRACT_16BITS(&ap->op), EXTRACT_16BITS(&ap->htype),
+ EXTRACT_16BITS(&ap->ptype), ap->halen, ap->palen);
+}
+
+/*
+ * Print AppleTalk Datagram Delivery Protocol packets.
+ */
+static void
+ddp_print(register const u_char *bp, register u_int length, register int t,
+ register u_short snet, register u_char snode, u_char skt)
+{
+
+ switch (t) {
+
+ case ddpNBP:
+ nbp_print((const struct atNBP *)bp, length, snet, snode, skt);
+ break;
+
+ case ddpATP:
+ atp_print((const struct atATP *)bp, length);
+ break;
+
+ case ddpEIGRP:
+ eigrp_print(bp, length);
+ break;
+
+ default:
+ (void)printf(" at-%s %d", tok2str(type2str, NULL, t), length);
+ break;
+ }
+}
+
+static void
+atp_print(register const struct atATP *ap, u_int length)
+{
+ char c;
+ u_int32_t data;
+
+ if ((const u_char *)(ap + 1) > snapend) {
+ /* Just bail if we don't have the whole chunk. */
+ fputs(tstr, stdout);
+ return;
+ }
+ if (length < sizeof(*ap)) {
+ (void)printf(" [|atp %u]", length);
+ return;
+ }
+ length -= sizeof(*ap);
+ switch (ap->control & 0xc0) {
+
+ case atpReqCode:
+ (void)printf(" atp-req%s %d",
+ ap->control & atpXO? " " : "*",
+ EXTRACT_16BITS(&ap->transID));
+
+ atp_bitmap_print(ap->bitmap);
+
+ if (length != 0)
+ (void)printf(" [len=%u]", length);
+
+ switch (ap->control & (atpEOM|atpSTS)) {
+ case atpEOM:
+ (void)printf(" [EOM]");
+ break;
+ case atpSTS:
+ (void)printf(" [STS]");
+ break;
+ case atpEOM|atpSTS:
+ (void)printf(" [EOM,STS]");
+ break;
+ }
+ break;
+
+ case atpRspCode:
+ (void)printf(" atp-resp%s%d:%d (%u)",
+ ap->control & atpEOM? "*" : " ",
+ EXTRACT_16BITS(&ap->transID), ap->bitmap, length);
+ switch (ap->control & (atpXO|atpSTS)) {
+ case atpXO:
+ (void)printf(" [XO]");
+ break;
+ case atpSTS:
+ (void)printf(" [STS]");
+ break;
+ case atpXO|atpSTS:
+ (void)printf(" [XO,STS]");
+ break;
+ }
+ break;
+
+ case atpRelCode:
+ (void)printf(" atp-rel %d", EXTRACT_16BITS(&ap->transID));
+
+ atp_bitmap_print(ap->bitmap);
+
+ /* length should be zero */
+ if (length)
+ (void)printf(" [len=%u]", length);
+
+ /* there shouldn't be any control flags */
+ if (ap->control & (atpXO|atpEOM|atpSTS)) {
+ c = '[';
+ if (ap->control & atpXO) {
+ (void)printf("%cXO", c);
+ c = ',';
+ }
+ if (ap->control & atpEOM) {
+ (void)printf("%cEOM", c);
+ c = ',';
+ }
+ if (ap->control & atpSTS) {
+ (void)printf("%cSTS", c);
+ c = ',';
+ }
+ (void)printf("]");
+ }
+ break;
+
+ default:
+ (void)printf(" atp-0x%x %d (%u)", ap->control,
+ EXTRACT_16BITS(&ap->transID), length);
+ break;
+ }
+ data = EXTRACT_32BITS(&ap->userData);
+ if (data != 0)
+ (void)printf(" 0x%x", data);
+}
+
+static void
+atp_bitmap_print(register u_char bm)
+{
+ register char c;
+ register int i;
+
+ /*
+ * The '& 0xff' below is needed for compilers that want to sign
+ * extend a u_char, which is the case with the Ultrix compiler.
+ * (gcc is smart enough to eliminate it, at least on the Sparc).
+ */
+ if ((bm + 1) & (bm & 0xff)) {
+ c = '<';
+ for (i = 0; bm; ++i) {
+ if (bm & 1) {
+ (void)printf("%c%d", c, i);
+ c = ',';
+ }
+ bm >>= 1;
+ }
+ (void)printf(">");
+ } else {
+ for (i = 0; bm; ++i)
+ bm >>= 1;
+ if (i > 1)
+ (void)printf("<0-%d>", i - 1);
+ else
+ (void)printf("<0>");
+ }
+}
+
+static void
+nbp_print(register const struct atNBP *np, u_int length, register u_short snet,
+ register u_char snode, register u_char skt)
+{
+ register const struct atNBPtuple *tp =
+ (const struct atNBPtuple *)((u_char *)np + nbpHeaderSize);
+ int i;
+ const u_char *ep;
+
+ if (length < nbpHeaderSize) {
+ (void)printf(" truncated-nbp %u", length);
+ return;
+ }
+
+ length -= nbpHeaderSize;
+ if (length < 8) {
+ /* must be room for at least one tuple */
+ (void)printf(" truncated-nbp %u", length + nbpHeaderSize);
+ return;
+ }
+ /* ep points to end of available data */
+ ep = snapend;
+ if ((const u_char *)tp > ep) {
+ fputs(tstr, stdout);
+ return;
+ }
+ switch (i = np->control & 0xf0) {
+
+ case nbpBrRq:
+ case nbpLkUp:
+ (void)printf(i == nbpLkUp? " nbp-lkup %d:":" nbp-brRq %d:",
+ np->id);
+ if ((const u_char *)(tp + 1) > ep) {
+ fputs(tstr, stdout);
+ return;
+ }
+ (void)nbp_name_print(tp, ep);
+ /*
+ * look for anomalies: the spec says there can only
+ * be one tuple, the address must match the source
+ * address and the enumerator should be zero.
+ */
+ if ((np->control & 0xf) != 1)
+ (void)printf(" [ntup=%d]", np->control & 0xf);
+ if (tp->enumerator)
+ (void)printf(" [enum=%d]", tp->enumerator);
+ if (EXTRACT_16BITS(&tp->net) != snet ||
+ tp->node != snode || tp->skt != skt)
+ (void)printf(" [addr=%s.%d]",
+ ataddr_string(EXTRACT_16BITS(&tp->net),
+ tp->node), tp->skt);
+ break;
+
+ case nbpLkUpReply:
+ (void)printf(" nbp-reply %d:", np->id);
+
+ /* print each of the tuples in the reply */
+ for (i = np->control & 0xf; --i >= 0 && tp; )
+ tp = nbp_tuple_print(tp, ep, snet, snode, skt);
+ break;
+
+ default:
+ (void)printf(" nbp-0x%x %d (%u)", np->control, np->id,
+ length);
+ break;
+ }
+}
+
+/* print a counted string */
+static const char *
+print_cstring(register const char *cp, register const u_char *ep)
+{
+ register u_int length;
+
+ if (cp >= (const char *)ep) {
+ fputs(tstr, stdout);
+ return (0);
+ }
+ length = *cp++;
+
+ /* Spec says string can be at most 32 bytes long */
+ if (length > 32) {
+ (void)printf("[len=%u]", length);
+ return (0);
+ }
+ while ((int)--length >= 0) {
+ if (cp >= (const char *)ep) {
+ fputs(tstr, stdout);
+ return (0);
+ }
+ putchar(*cp++);
+ }
+ return (cp);
+}
+
+static const struct atNBPtuple *
+nbp_tuple_print(register const struct atNBPtuple *tp,
+ register const u_char *ep,
+ register u_short snet, register u_char snode,
+ register u_char skt)
+{
+ register const struct atNBPtuple *tpn;
+
+ if ((const u_char *)(tp + 1) > ep) {
+ fputs(tstr, stdout);
+ return 0;
+ }
+ tpn = nbp_name_print(tp, ep);
+
+ /* if the enumerator isn't 1, print it */
+ if (tp->enumerator != 1)
+ (void)printf("(%d)", tp->enumerator);
+
+ /* if the socket doesn't match the src socket, print it */
+ if (tp->skt != skt)
+ (void)printf(" %d", tp->skt);
+
+ /* if the address doesn't match the src address, it's an anomaly */
+ if (EXTRACT_16BITS(&tp->net) != snet || tp->node != snode)
+ (void)printf(" [addr=%s]",
+ ataddr_string(EXTRACT_16BITS(&tp->net), tp->node));
+
+ return (tpn);
+}
+
+static const struct atNBPtuple *
+nbp_name_print(const struct atNBPtuple *tp, register const u_char *ep)
+{
+ register const char *cp = (const char *)tp + nbpTupleSize;
+
+ putchar(' ');
+
+ /* Object */
+ putchar('"');
+ if ((cp = print_cstring(cp, ep)) != NULL) {
+ /* Type */
+ putchar(':');
+ if ((cp = print_cstring(cp, ep)) != NULL) {
+ /* Zone */
+ putchar('@');
+ if ((cp = print_cstring(cp, ep)) != NULL)
+ putchar('"');
+ }
+ }
+ return ((const struct atNBPtuple *)cp);
+}
+
+
+#define HASHNAMESIZE 4096
+
+struct hnamemem {
+ int addr;
+ char *name;
+ struct hnamemem *nxt;
+};
+
+static struct hnamemem hnametable[HASHNAMESIZE];
+
+static const char *
+ataddr_string(u_short atnet, u_char athost)
+{
+ register struct hnamemem *tp, *tp2;
+ register int i = (atnet << 8) | athost;
+ char nambuf[MAXHOSTNAMELEN + 20];
+ static int first = 1;
+ FILE *fp;
+
+ /*
+ * if this is the first call, see if there's an AppleTalk
+ * number to name map file.
+ */
+ if (first && (first = 0, !nflag)
+ && (fp = fopen("/etc/atalk.names", "r"))) {
+ char line[256];
+ int i1, i2;
+
+ while (fgets(line, sizeof(line), fp)) {
+ if (line[0] == '\n' || line[0] == 0 || line[0] == '#')
+ continue;
+ if (sscanf(line, "%d.%d %256s", &i1, &i2, nambuf) == 3)
+ /* got a hostname. */
+ i2 |= (i1 << 8);
+ else if (sscanf(line, "%d %256s", &i1, nambuf) == 2)
+ /* got a net name */
+ i2 = (i1 << 8) | 255;
+ else
+ continue;
+
+ for (tp = &hnametable[i2 & (HASHNAMESIZE-1)];
+ tp->nxt; tp = tp->nxt)
+ ;
+ tp->addr = i2;
+ tp->nxt = newhnamemem();
+ tp->name = strdup(nambuf);
+ }
+ fclose(fp);
+ }
+
+ for (tp = &hnametable[i & (HASHNAMESIZE-1)]; tp->nxt; tp = tp->nxt)
+ if (tp->addr == i)
+ return (tp->name);
+
+ /* didn't have the node name -- see if we've got the net name */
+ i |= 255;
+ for (tp2 = &hnametable[i & (HASHNAMESIZE-1)]; tp2->nxt; tp2 = tp2->nxt)
+ if (tp2->addr == i) {
+ tp->addr = (atnet << 8) | athost;
+ tp->nxt = newhnamemem();
+ (void)snprintf(nambuf, sizeof(nambuf), "%s.%d",
+ tp2->name, athost);
+ tp->name = strdup(nambuf);
+ return (tp->name);
+ }
+
+ tp->addr = (atnet << 8) | athost;
+ tp->nxt = newhnamemem();
+ if (athost != 255)
+ (void)snprintf(nambuf, sizeof(nambuf), "%d.%d", atnet, athost);
+ else
+ (void)snprintf(nambuf, sizeof(nambuf), "%d", atnet);
+ tp->name = strdup(nambuf);
+
+ return (tp->name);
+}
+
+static struct tok skt2str[] = {
+ { rtmpSkt, "rtmp" }, /* routing table maintenance */
+ { nbpSkt, "nis" }, /* name info socket */
+ { echoSkt, "echo" }, /* AppleTalk echo protocol */
+ { zipSkt, "zip" }, /* zone info protocol */
+ { 0, NULL }
+};
+
+static const char *
+ddpskt_string(register int skt)
+{
+ static char buf[8];
+
+ if (nflag) {
+ (void)snprintf(buf, sizeof(buf), "%d", skt);
+ return (buf);
+ }
+ return (tok2str(skt2str, "%d", skt));
+}
diff --git a/freebsd/contrib/tcpdump/print-atm.c b/freebsd/contrib/tcpdump/print-atm.c
new file mode 100644
index 00000000..ecf03a86
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-atm.c
@@ -0,0 +1,455 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-atm.c,v 1.49 2007-10-22 19:37:51 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <pcap.h>
+#include <string.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+#include "atm.h"
+#include "atmuni31.h"
+#include "llc.h"
+
+#include "ether.h"
+
+#define OAM_CRC10_MASK 0x3ff
+#define OAM_PAYLOAD_LEN 48
+#define OAM_FUNCTION_SPECIFIC_LEN 45 /* this excludes crc10 and cell-type/function-type */
+#define OAM_CELLTYPE_FUNCTYPE_LEN 1
+
+struct tok oam_f_values[] = {
+ { VCI_OAMF4SC, "OAM F4 (segment)" },
+ { VCI_OAMF4EC, "OAM F4 (end)" },
+ { 0, NULL }
+};
+
+struct tok atm_pty_values[] = {
+ { 0x0, "user data, uncongested, SDU 0" },
+ { 0x1, "user data, uncongested, SDU 1" },
+ { 0x2, "user data, congested, SDU 0" },
+ { 0x3, "user data, congested, SDU 1" },
+ { 0x4, "VCC OAM F5 flow segment" },
+ { 0x5, "VCC OAM F5 flow end-to-end" },
+ { 0x6, "Traffic Control and resource Mgmt" },
+ { 0, NULL }
+};
+
+#define OAM_CELLTYPE_FM 0x1
+#define OAM_CELLTYPE_PM 0x2
+#define OAM_CELLTYPE_AD 0x8
+#define OAM_CELLTYPE_SM 0xf
+
+struct tok oam_celltype_values[] = {
+ { OAM_CELLTYPE_FM, "Fault Management" },
+ { OAM_CELLTYPE_PM, "Performance Management" },
+ { OAM_CELLTYPE_AD, "activate/deactivate" },
+ { OAM_CELLTYPE_SM, "System Management" },
+ { 0, NULL }
+};
+
+#define OAM_FM_FUNCTYPE_AIS 0x0
+#define OAM_FM_FUNCTYPE_RDI 0x1
+#define OAM_FM_FUNCTYPE_CONTCHECK 0x4
+#define OAM_FM_FUNCTYPE_LOOPBACK 0x8
+
+struct tok oam_fm_functype_values[] = {
+ { OAM_FM_FUNCTYPE_AIS, "AIS" },
+ { OAM_FM_FUNCTYPE_RDI, "RDI" },
+ { OAM_FM_FUNCTYPE_CONTCHECK, "Continuity Check" },
+ { OAM_FM_FUNCTYPE_LOOPBACK, "Loopback" },
+ { 0, NULL }
+};
+
+struct tok oam_pm_functype_values[] = {
+ { 0x0, "Forward Monitoring" },
+ { 0x1, "Backward Reporting" },
+ { 0x2, "Monitoring and Reporting" },
+ { 0, NULL }
+};
+
+struct tok oam_ad_functype_values[] = {
+ { 0x0, "Performance Monitoring" },
+ { 0x1, "Continuity Check" },
+ { 0, NULL }
+};
+
+#define OAM_FM_LOOPBACK_INDICATOR_MASK 0x1
+
+struct tok oam_fm_loopback_indicator_values[] = {
+ { 0x0, "Reply" },
+ { 0x1, "Request" },
+ { 0, NULL }
+};
+
+static const struct tok *oam_functype_values[16] = {
+ NULL,
+ oam_fm_functype_values, /* 1 */
+ oam_pm_functype_values, /* 2 */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ oam_ad_functype_values, /* 8 */
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+/*
+ * Print an RFC 1483 LLC-encapsulated ATM frame.
+ */
+static void
+atm_llc_print(const u_char *p, int length, int caplen)
+{
+ u_short extracted_ethertype;
+
+ if (!llc_print(p, length, caplen, NULL, NULL,
+ &extracted_ethertype)) {
+ /* ether_type not known, print raw packet */
+ if (extracted_ethertype) {
+ printf("(LLC %s) ",
+ etherproto_string(htons(extracted_ethertype)));
+ }
+ if (!suppress_default_print)
+ default_print(p, caplen);
+ }
+}
+
+/*
+ * Given a SAP value, generate the LLC header value for a UI packet
+ * with that SAP as the source and destination SAP.
+ */
+#define LLC_UI_HDR(sap) ((sap)<<16 | (sap<<8) | 0x03)
+
+/*
+ * This is the top level routine of the printer. 'p' points
+ * to the LLC/SNAP header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ */
+u_int
+atm_if_print(const struct pcap_pkthdr *h, const u_char *p)
+{
+ u_int caplen = h->caplen;
+ u_int length = h->len;
+ u_int32_t llchdr;
+ u_int hdrlen = 0;
+
+ if (caplen < 8) {
+ printf("[|atm]");
+ return (caplen);
+ }
+
+ /* Cisco Style NLPID ? */
+ if (*p == LLC_UI) {
+ if (eflag)
+ printf("CNLPID ");
+ isoclns_print(p+1, length-1, caplen-1);
+ return hdrlen;
+ }
+
+ /*
+ * Extract the presumed LLC header into a variable, for quick
+ * testing.
+ * Then check for a header that's neither a header for a SNAP
+ * packet nor an RFC 2684 routed NLPID-formatted PDU nor
+ * an 802.2-but-no-SNAP IP packet.
+ */
+ llchdr = EXTRACT_24BITS(p);
+ if (llchdr != LLC_UI_HDR(LLCSAP_SNAP) &&
+ llchdr != LLC_UI_HDR(LLCSAP_ISONS) &&
+ llchdr != LLC_UI_HDR(LLCSAP_IP)) {
+ /*
+ * XXX - assume 802.6 MAC header from Fore driver.
+ *
+ * Unfortunately, the above list doesn't check for
+ * all known SAPs, doesn't check for headers where
+ * the source and destination SAP aren't the same,
+ * and doesn't check for non-UI frames. It also
+ * runs the risk of an 802.6 MAC header that happens
+ * to begin with one of those values being
+ * incorrectly treated as an 802.2 header.
+ *
+ * So is that Fore driver still around? And, if so,
+ * is it still putting 802.6 MAC headers on ATM
+ * packets? If so, could it be changed to use a
+ * new DLT_IEEE802_6 value if we added it?
+ */
+ if (eflag)
+ printf("%08x%08x %08x%08x ",
+ EXTRACT_32BITS(p),
+ EXTRACT_32BITS(p+4),
+ EXTRACT_32BITS(p+8),
+ EXTRACT_32BITS(p+12));
+ p += 20;
+ length -= 20;
+ caplen -= 20;
+ hdrlen += 20;
+ }
+ atm_llc_print(p, length, caplen);
+ return (hdrlen);
+}
+
+/*
+ * ATM signalling.
+ */
+static struct tok msgtype2str[] = {
+ { CALL_PROCEED, "Call_proceeding" },
+ { CONNECT, "Connect" },
+ { CONNECT_ACK, "Connect_ack" },
+ { SETUP, "Setup" },
+ { RELEASE, "Release" },
+ { RELEASE_DONE, "Release_complete" },
+ { RESTART, "Restart" },
+ { RESTART_ACK, "Restart_ack" },
+ { STATUS, "Status" },
+ { STATUS_ENQ, "Status_enquiry" },
+ { ADD_PARTY, "Add_party" },
+ { ADD_PARTY_ACK, "Add_party_ack" },
+ { ADD_PARTY_REJ, "Add_party_reject" },
+ { DROP_PARTY, "Drop_party" },
+ { DROP_PARTY_ACK, "Drop_party_ack" },
+ { 0, NULL }
+};
+
+static void
+sig_print(const u_char *p, int caplen)
+{
+ bpf_u_int32 call_ref;
+
+ if (caplen < PROTO_POS) {
+ printf("[|atm]");
+ return;
+ }
+ if (p[PROTO_POS] == Q2931) {
+ /*
+ * protocol:Q.2931 for User to Network Interface
+ * (UNI 3.1) signalling
+ */
+ printf("Q.2931");
+ if (caplen < MSG_TYPE_POS) {
+ printf(" [|atm]");
+ return;
+ }
+ printf(":%s ",
+ tok2str(msgtype2str, "msgtype#%d", p[MSG_TYPE_POS]));
+
+ /*
+ * The call reference comes before the message type,
+ * so if we know we have the message type, which we
+ * do from the caplen test above, we also know we have
+ * the call reference.
+ */
+ call_ref = EXTRACT_24BITS(&p[CALL_REF_POS]);
+ printf("CALL_REF:0x%06x", call_ref);
+ } else {
+ /* SCCOP with some unknown protocol atop it */
+ printf("SSCOP, proto %d ", p[PROTO_POS]);
+ }
+}
+
+/*
+ * Print an ATM PDU (such as an AAL5 PDU).
+ */
+void
+atm_print(u_int vpi, u_int vci, u_int traftype, const u_char *p, u_int length,
+ u_int caplen)
+{
+ if (eflag)
+ printf("VPI:%u VCI:%u ", vpi, vci);
+
+ if (vpi == 0) {
+ switch (vci) {
+
+ case VCI_PPC:
+ sig_print(p, caplen);
+ return;
+
+ case VCI_BCC:
+ printf("broadcast sig: ");
+ return;
+
+ case VCI_OAMF4SC: /* fall through */
+ case VCI_OAMF4EC:
+ oam_print(p, length, ATM_OAM_HEC);
+ return;
+
+ case VCI_METAC:
+ printf("meta: ");
+ return;
+
+ case VCI_ILMIC:
+ printf("ilmi: ");
+ snmp_print(p, length);
+ return;
+ }
+ }
+
+ switch (traftype) {
+
+ case ATM_LLC:
+ default:
+ /*
+ * Assumes traffic is LLC if unknown.
+ */
+ atm_llc_print(p, length, caplen);
+ break;
+
+ case ATM_LANE:
+ lane_print(p, length, caplen);
+ break;
+ }
+}
+
+struct oam_fm_loopback_t {
+ u_int8_t loopback_indicator;
+ u_int8_t correlation_tag[4];
+ u_int8_t loopback_id[12];
+ u_int8_t source_id[12];
+ u_int8_t unused[16];
+};
+
+struct oam_fm_ais_rdi_t {
+ u_int8_t failure_type;
+ u_int8_t failure_location[16];
+ u_int8_t unused[28];
+};
+
+int
+oam_print (const u_char *p, u_int length, u_int hec) {
+
+ u_int32_t cell_header;
+ u_int16_t vpi, vci, cksum, cksum_shouldbe, idx;
+ u_int8_t cell_type, func_type, payload, clp;
+
+ union {
+ const struct oam_fm_loopback_t *oam_fm_loopback;
+ const struct oam_fm_ais_rdi_t *oam_fm_ais_rdi;
+ } oam_ptr;
+
+
+ cell_header = EXTRACT_32BITS(p+hec);
+ cell_type = ((*(p+ATM_HDR_LEN_NOHEC+hec))>>4) & 0x0f;
+ func_type = (*(p+ATM_HDR_LEN_NOHEC+hec)) & 0x0f;
+
+ vpi = (cell_header>>20)&0xff;
+ vci = (cell_header>>4)&0xffff;
+ payload = (cell_header>>1)&0x7;
+ clp = cell_header&0x1;
+
+ printf("%s, vpi %u, vci %u, payload [ %s ], clp %u, length %u",
+ tok2str(oam_f_values, "OAM F5", vci),
+ vpi, vci,
+ tok2str(atm_pty_values, "Unknown", payload),
+ clp, length);
+
+ if (!vflag) {
+ return 1;
+ }
+
+ printf("\n\tcell-type %s (%u)",
+ tok2str(oam_celltype_values, "unknown", cell_type),
+ cell_type);
+
+ if (oam_functype_values[cell_type] == NULL)
+ printf(", func-type unknown (%u)", func_type);
+ else
+ printf(", func-type %s (%u)",
+ tok2str(oam_functype_values[cell_type],"none",func_type),
+ func_type);
+
+ p += ATM_HDR_LEN_NOHEC + hec;
+
+ switch (cell_type << 4 | func_type) {
+ case (OAM_CELLTYPE_FM << 4 | OAM_FM_FUNCTYPE_LOOPBACK):
+ oam_ptr.oam_fm_loopback = (const struct oam_fm_loopback_t *)(p + OAM_CELLTYPE_FUNCTYPE_LEN);
+ printf("\n\tLoopback-Indicator %s, Correlation-Tag 0x%08x",
+ tok2str(oam_fm_loopback_indicator_values,
+ "Unknown",
+ oam_ptr.oam_fm_loopback->loopback_indicator & OAM_FM_LOOPBACK_INDICATOR_MASK),
+ EXTRACT_32BITS(&oam_ptr.oam_fm_loopback->correlation_tag));
+ printf("\n\tLocation-ID ");
+ for (idx = 0; idx < sizeof(oam_ptr.oam_fm_loopback->loopback_id); idx++) {
+ if (idx % 2) {
+ printf("%04x ", EXTRACT_16BITS(&oam_ptr.oam_fm_loopback->loopback_id[idx]));
+ }
+ }
+ printf("\n\tSource-ID ");
+ for (idx = 0; idx < sizeof(oam_ptr.oam_fm_loopback->source_id); idx++) {
+ if (idx % 2) {
+ printf("%04x ", EXTRACT_16BITS(&oam_ptr.oam_fm_loopback->source_id[idx]));
+ }
+ }
+ break;
+
+ case (OAM_CELLTYPE_FM << 4 | OAM_FM_FUNCTYPE_AIS):
+ case (OAM_CELLTYPE_FM << 4 | OAM_FM_FUNCTYPE_RDI):
+ oam_ptr.oam_fm_ais_rdi = (const struct oam_fm_ais_rdi_t *)(p + OAM_CELLTYPE_FUNCTYPE_LEN);
+ printf("\n\tFailure-type 0x%02x", oam_ptr.oam_fm_ais_rdi->failure_type);
+ printf("\n\tLocation-ID ");
+ for (idx = 0; idx < sizeof(oam_ptr.oam_fm_ais_rdi->failure_location); idx++) {
+ if (idx % 2) {
+ printf("%04x ", EXTRACT_16BITS(&oam_ptr.oam_fm_ais_rdi->failure_location[idx]));
+ }
+ }
+ break;
+
+ case (OAM_CELLTYPE_FM << 4 | OAM_FM_FUNCTYPE_CONTCHECK):
+ /* FIXME */
+ break;
+
+ default:
+ break;
+ }
+
+ /* crc10 checksum verification */
+ cksum = EXTRACT_16BITS(p + OAM_CELLTYPE_FUNCTYPE_LEN + OAM_FUNCTION_SPECIFIC_LEN)
+ & OAM_CRC10_MASK;
+ cksum_shouldbe = verify_crc10_cksum(0, p, OAM_PAYLOAD_LEN);
+
+ printf("\n\tcksum 0x%03x (%scorrect)",
+ cksum,
+ cksum_shouldbe == 0 ? "" : "in");
+
+ return 1;
+}
diff --git a/freebsd/contrib/tcpdump/print-babel.c b/freebsd/contrib/tcpdump/print-babel.c
new file mode 100644
index 00000000..629c57e9
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-babel.c
@@ -0,0 +1,449 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 2007-2011 Grégoire Henry, Juliusz Chroboczek
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "addrtoname.h"
+#include "interface.h"
+#include "extract.h"
+
+static void babel_print_v2(const u_char *cp, u_int length);
+
+void
+babel_print(const u_char *cp, u_int length) {
+ printf("babel");
+
+ TCHECK2(*cp, 4);
+
+ if(cp[0] != 42) {
+ printf(" malformed header");
+ return;
+ } else {
+ printf(" %d", cp[1]);
+ }
+
+ switch(cp[1]) {
+ case 2:
+ babel_print_v2(cp,length);
+ break;
+ default:
+ printf(" unknown version");
+ break;
+ }
+
+ return;
+
+ trunc:
+ printf(" [|babel]");
+ return;
+}
+
+#define MESSAGE_PAD1 0
+#define MESSAGE_PADN 1
+#define MESSAGE_ACK_REQ 2
+#define MESSAGE_ACK 3
+#define MESSAGE_HELLO 4
+#define MESSAGE_IHU 5
+#define MESSAGE_ROUTER_ID 6
+#define MESSAGE_NH 7
+#define MESSAGE_UPDATE 8
+#define MESSAGE_REQUEST 9
+#define MESSAGE_MH_REQUEST 10
+#define MESSAGE_TSPC 11
+#define MESSAGE_HMAC 12
+
+static const char *
+format_id(const u_char *id)
+{
+ static char buf[25];
+ snprintf(buf, 25, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
+ id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7]);
+ buf[24] = '\0';
+ return buf;
+}
+
+static const unsigned char v4prefix[16] =
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 };
+
+static const char *
+format_prefix(const u_char *prefix, unsigned char plen)
+{
+ static char buf[50];
+ if(plen >= 96 && memcmp(prefix, v4prefix, 12) == 0)
+ snprintf(buf, 50, "%s/%u", ipaddr_string(prefix + 12), plen - 96);
+ else
+#ifdef INET6
+ snprintf(buf, 50, "%s/%u", ip6addr_string(prefix), plen);
+#else
+ snprintf(buf, 50, "IPv6 addresses not supported");
+#endif
+ buf[49] = '\0';
+ return buf;
+}
+
+static const char *
+format_address(const u_char *prefix)
+{
+ if(memcmp(prefix, v4prefix, 12) == 0)
+ return ipaddr_string(prefix + 12);
+ else
+#ifdef INET6
+ return ip6addr_string(prefix);
+#else
+ return "IPv6 addresses not supported";
+#endif
+}
+
+static int
+network_prefix(int ae, int plen, unsigned int omitted,
+ const unsigned char *p, const unsigned char *dp,
+ unsigned int len, unsigned char *p_r)
+{
+ unsigned pb;
+ unsigned char prefix[16];
+
+ if(plen >= 0)
+ pb = (plen + 7) / 8;
+ else if(ae == 1)
+ pb = 4;
+ else
+ pb = 16;
+
+ if(pb > 16)
+ return -1;
+
+ memset(prefix, 0, 16);
+
+ switch(ae) {
+ case 0: break;
+ case 1:
+ if(omitted > 4 || pb > 4 || (pb > omitted && len < pb - omitted))
+ return -1;
+ memcpy(prefix, v4prefix, 12);
+ if(omitted) {
+ if (dp == NULL) return -1;
+ memcpy(prefix, dp, 12 + omitted);
+ }
+ if(pb > omitted) memcpy(prefix + 12 + omitted, p, pb - omitted);
+ break;
+ case 2:
+ if(omitted > 16 || (pb > omitted && len < pb - omitted))
+ return -1;
+ if(omitted) {
+ if (dp == NULL) return -1;
+ memcpy(prefix, dp, omitted);
+ }
+ if(pb > omitted) memcpy(prefix + omitted, p, pb - omitted);
+ break;
+ case 3:
+ if(pb > 8 && len < pb - 8) return -1;
+ prefix[0] = 0xfe;
+ prefix[1] = 0x80;
+ if(pb > 8) memcpy(prefix + 8, p, pb - 8);
+ break;
+ default:
+ return -1;
+ }
+
+ memcpy(p_r, prefix, 16);
+ return 1;
+}
+
+static int
+network_address(int ae, const unsigned char *a, unsigned int len,
+ unsigned char *a_r)
+{
+ return network_prefix(ae, -1, 0, a, NULL, len, a_r);
+}
+
+#define ICHECK(i, l) \
+ if ((i) + (l) > bodylen || (i) + (l) > length) goto corrupt;
+
+static void
+babel_print_v2(const u_char *cp, u_int length) {
+ u_int i;
+ u_short bodylen;
+ u_char v4_prefix[16] =
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 };
+ u_char v6_prefix[16] = {0};
+
+ TCHECK2(*cp, 4);
+ if (length < 4)
+ goto corrupt;
+ bodylen = EXTRACT_16BITS(cp + 2);
+ printf(" (%u)", bodylen);
+
+ /* Process the TLVs in the body */
+ i = 0;
+ while(i < bodylen) {
+ const u_char *message;
+ u_int type, len;
+
+ message = cp + 4 + i;
+ TCHECK2(*message, 2);
+ ICHECK(i, 2);
+ type = message[0];
+ len = message[1];
+
+ TCHECK2(*message, 2 + len);
+ ICHECK(i, 2 + len);
+
+ switch(type) {
+ case MESSAGE_PAD1: {
+ if(!vflag)
+ printf(" pad1");
+ else
+ printf("\n\tPad 1");
+ }
+ break;
+
+ case MESSAGE_PADN: {
+ if(!vflag)
+ printf(" padN");
+ else
+ printf("\n\tPad %d", len + 2);
+ }
+ break;
+
+ case MESSAGE_ACK_REQ: {
+ u_short nonce, interval;
+ if(!vflag)
+ printf(" ack-req");
+ else {
+ printf("\n\tAcknowledgment Request ");
+ if(len < 6) goto corrupt;
+ nonce = EXTRACT_16BITS(message + 4);
+ interval = EXTRACT_16BITS(message + 6);
+ printf("%04x %d", nonce, interval);
+ }
+ }
+ break;
+
+ case MESSAGE_ACK: {
+ u_short nonce;
+ if(!vflag)
+ printf(" ack");
+ else {
+ printf("\n\tAcknowledgment ");
+ if(len < 2) goto corrupt;
+ nonce = EXTRACT_16BITS(message + 2);
+ printf("%04x", nonce);
+ }
+ }
+ break;
+
+ case MESSAGE_HELLO: {
+ u_short seqno, interval;
+ if(!vflag)
+ printf(" hello");
+ else {
+ printf("\n\tHello ");
+ if(len < 6) goto corrupt;
+ seqno = EXTRACT_16BITS(message + 4);
+ interval = EXTRACT_16BITS(message + 6);
+ printf("seqno %u interval %u", seqno, interval);
+ }
+ }
+ break;
+
+ case MESSAGE_IHU: {
+ unsigned short txcost, interval;
+ if(!vflag)
+ printf(" ihu");
+ else {
+ u_char address[16];
+ int rc;
+ printf("\n\tIHU ");
+ if(len < 6) goto corrupt;
+ txcost = EXTRACT_16BITS(message + 4);
+ interval = EXTRACT_16BITS(message + 6);
+ rc = network_address(message[2], message + 8, len - 6, address);
+ if(rc < 0) { printf("[|babel]"); break; }
+ printf("%s txcost %u interval %d",
+ format_address(address), txcost, interval);
+ }
+ }
+ break;
+
+ case MESSAGE_ROUTER_ID: {
+ if(!vflag)
+ printf(" router-id");
+ else {
+ printf("\n\tRouter Id");
+ if(len < 10) goto corrupt;
+ printf(" %s", format_id(message + 4));
+ }
+ }
+ break;
+
+ case MESSAGE_NH: {
+ if(!vflag)
+ printf(" nh");
+ else {
+ int rc;
+ u_char nh[16];
+ printf("\n\tNext Hop");
+ if(len < 2) goto corrupt;
+ rc = network_address(message[2], message + 4, len - 2, nh);
+ if(rc < 0) goto corrupt;
+ printf(" %s", format_address(nh));
+ }
+ }
+ break;
+
+ case MESSAGE_UPDATE: {
+ if(!vflag) {
+ printf(" update");
+ if(len < 1)
+ printf("/truncated");
+ else
+ printf("%s%s%s",
+ (message[3] & 0x80) ? "/prefix": "",
+ (message[3] & 0x40) ? "/id" : "",
+ (message[3] & 0x3f) ? "/unknown" : "");
+ } else {
+ u_short interval, seqno, metric;
+ u_char plen;
+ int rc;
+ u_char prefix[16];
+ printf("\n\tUpdate");
+ if(len < 10) goto corrupt;
+ plen = message[4] + (message[2] == 1 ? 96 : 0);
+ rc = network_prefix(message[2], message[4], message[5],
+ message + 12,
+ message[2] == 1 ? v4_prefix : v6_prefix,
+ len - 10, prefix);
+ if(rc < 0) goto corrupt;
+ interval = EXTRACT_16BITS(message + 6);
+ seqno = EXTRACT_16BITS(message + 8);
+ metric = EXTRACT_16BITS(message + 10);
+ printf("%s%s%s %s metric %u seqno %u interval %u",
+ (message[3] & 0x80) ? "/prefix": "",
+ (message[3] & 0x40) ? "/id" : "",
+ (message[3] & 0x3f) ? "/unknown" : "",
+ format_prefix(prefix, plen),
+ metric, seqno, interval);
+ if(message[3] & 0x80) {
+ if(message[2] == 1)
+ memcpy(v4_prefix, prefix, 16);
+ else
+ memcpy(v6_prefix, prefix, 16);
+ }
+ }
+ }
+ break;
+
+ case MESSAGE_REQUEST: {
+ if(!vflag)
+ printf(" request");
+ else {
+ int rc;
+ u_char prefix[16], plen;
+ printf("\n\tRequest ");
+ if(len < 2) goto corrupt;
+ plen = message[3] + (message[2] == 1 ? 96 : 0);
+ rc = network_prefix(message[2], message[3], 0,
+ message + 4, NULL, len - 2, prefix);
+ if(rc < 0) goto corrupt;
+ plen = message[3] + (message[2] == 1 ? 96 : 0);
+ printf("for %s",
+ message[2] == 0 ? "any" : format_prefix(prefix, plen));
+ }
+ }
+ break;
+
+ case MESSAGE_MH_REQUEST : {
+ if(!vflag)
+ printf(" mh-request");
+ else {
+ int rc;
+ u_short seqno;
+ u_char prefix[16], plen;
+ printf("\n\tMH-Request ");
+ if(len < 14) goto corrupt;
+ seqno = EXTRACT_16BITS(message + 4);
+ rc = network_prefix(message[2], message[3], 0,
+ message + 16, NULL, len - 14, prefix);
+ if(rc < 0) goto corrupt;
+ plen = message[3] + (message[2] == 1 ? 96 : 0);
+ printf("(%u hops) for %s seqno %u id %s",
+ message[6], format_prefix(prefix, plen),
+ seqno, format_id(message + 8));
+ }
+ }
+ break;
+ case MESSAGE_TSPC :
+ if(!vflag)
+ printf(" tspc");
+ else {
+ printf("\n\tTS/PC ");
+ if(len < 6) goto corrupt;
+ printf("timestamp %u packetcounter %u", EXTRACT_32BITS (message + 4),
+ EXTRACT_16BITS(message + 2));
+ }
+ break;
+ case MESSAGE_HMAC : {
+ if(!vflag)
+ printf(" hmac");
+ else {
+ unsigned j;
+ printf("\n\tHMAC ");
+ if(len < 18) goto corrupt;
+ printf("key-id %u digest-%u ", EXTRACT_16BITS(message + 2), len - 2);
+ for (j = 0; j < len - 2; j++)
+ printf ("%02X", message[4 + j]);
+ }
+ }
+ break;
+ default:
+ if(!vflag)
+ printf(" unknown");
+ else
+ printf("\n\tUnknown message type %d", type);
+ }
+ i += len + 2;
+ }
+ return;
+
+ trunc:
+ printf(" [|babel]");
+ return;
+
+ corrupt:
+ printf(" (corrupt)");
+ return;
+}
diff --git a/freebsd/contrib/tcpdump/print-beep.c b/freebsd/contrib/tcpdump/print-beep.c
new file mode 100644
index 00000000..30b5cb0c
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-beep.c
@@ -0,0 +1,73 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2000, Richard Sharpe
+ *
+ * This software may be distributed either under the terms of the
+ * BSD-style licence that accompanies tcpdump or under the GNU GPL
+ * version 2 or later.
+ *
+ * print-beep.c
+ *
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-beep.c,v 1.6 2003-11-16 09:36:13 guy Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "interface.h"
+#include "extract.h"
+
+/* Check for a string but not go beyond length
+ * Return TRUE on match, FALSE otherwise
+ *
+ * Looks at the first few chars up to tl1 ...
+ */
+
+static int l_strnstart(const char *, u_int, const char *, u_int);
+
+static int
+l_strnstart(const char *tstr1, u_int tl1, const char *str2, u_int l2)
+{
+
+ if (tl1 > l2)
+ return 0;
+
+ return (strncmp(tstr1, str2, tl1) == 0 ? 1 : 0);
+}
+
+void
+beep_print(const u_char *bp, u_int length)
+{
+
+ if (l_strnstart("MSG", 4, (const char *)bp, length)) /* A REQuest */
+ printf(" BEEP MSG");
+ else if (l_strnstart("RPY ", 4, (const char *)bp, length))
+ printf(" BEEP RPY");
+ else if (l_strnstart("ERR ", 4, (const char *)bp, length))
+ printf(" BEEP ERR");
+ else if (l_strnstart("ANS ", 4, (const char *)bp, length))
+ printf(" BEEP ANS");
+ else if (l_strnstart("NUL ", 4, (const char *)bp, length))
+ printf(" BEEP NUL");
+ else if (l_strnstart("SEQ ", 4, (const char *)bp, length))
+ printf(" BEEP SEQ");
+ else if (l_strnstart("END", 4, (const char *)bp, length))
+ printf(" BEEP END");
+ else
+ printf(" BEEP (payload or undecoded)");
+}
diff --git a/freebsd/contrib/tcpdump/print-bfd.c b/freebsd/contrib/tcpdump/print-bfd.c
new file mode 100644
index 00000000..e6f79e60
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-bfd.c
@@ -0,0 +1,285 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-bfd.c,v 1.10 2006-02-02 06:35:52 hannes Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+
+#include "udp.h"
+
+/*
+ * Control packet, BFDv0, draft-katz-ward-bfd-01.txt
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |Vers | Diag |H|D|P|F| Rsvd | Detect Mult | Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | My Discriminator |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Your Discriminator |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Desired Min TX Interval |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Required Min RX Interval |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Required Min Echo RX Interval |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+/*
+ * Control packet, BFDv1, draft-ietf-bfd-base-02.txt
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |Vers | Diag |Sta|P|F|C|A|D|R| Detect Mult | Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | My Discriminator |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Your Discriminator |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Desired Min TX Interval |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Required Min RX Interval |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Required Min Echo RX Interval |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+struct bfd_header_t {
+ u_int8_t version_diag;
+ u_int8_t flags;
+ u_int8_t detect_time_multiplier;
+ u_int8_t length;
+ u_int8_t my_discriminator[4];
+ u_int8_t your_discriminator[4];
+ u_int8_t desired_min_tx_interval[4];
+ u_int8_t required_min_rx_interval[4];
+ u_int8_t required_min_echo_interval[4];
+};
+
+/*
+ * An optional Authentication Header may be present
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Auth Type | Auth Len | Authentication Data... |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+struct bfd_auth_header_t {
+ u_int8_t auth_type;
+ u_int8_t auth_len;
+ u_int8_t auth_data;
+};
+
+static const struct tok bfd_v1_authentication_values[] = {
+ { 0, "Reserved" },
+ { 1, "Simple Password" },
+ { 2, "Keyed MD5" },
+ { 3, "Meticulous Keyed MD5" },
+ { 4, "Keyed SHA1" },
+ { 5, "Meticulous Keyed SHA1" },
+ { 0, NULL }
+};
+
+#define BFD_EXTRACT_VERSION(x) (((x)&0xe0)>>5)
+#define BFD_EXTRACT_DIAG(x) ((x)&0x1f)
+
+static const struct tok bfd_port_values[] = {
+ { BFD_CONTROL_PORT, "Control" },
+ { BFD_ECHO_PORT, "Echo" },
+ { 0, NULL }
+};
+
+
+static const struct tok bfd_diag_values[] = {
+ { 0, "No Diagnostic" },
+ { 1, "Control Detection Time Expired" },
+ { 2, "Echo Function Failed" },
+ { 3, "Neighbor Signaled Session Down" },
+ { 4, "Forwarding Plane Reset" },
+ { 5, "Path Down" },
+ { 6, "Concatenated Path Down" },
+ { 7, "Administratively Down" },
+ { 8, "Reverse Concatenated Path Down" },
+ { 0, NULL }
+};
+
+static const struct tok bfd_v0_flag_values[] = {
+ { 0x80, "I Hear You" },
+ { 0x40, "Demand" },
+ { 0x20, "Poll" },
+ { 0x10, "Final" },
+ { 0x08, "Reserved" },
+ { 0x04, "Reserved" },
+ { 0x02, "Reserved" },
+ { 0x01, "Reserved" },
+ { 0, NULL }
+};
+
+#define BFD_FLAG_AUTH 0x04
+
+static const struct tok bfd_v1_flag_values[] = {
+ { 0x20, "Poll" },
+ { 0x10, "Final" },
+ { 0x08, "Control Plane Independent" },
+ { BFD_FLAG_AUTH, "Authentication Present" },
+ { 0x02, "Demand" },
+ { 0x01, "Reserved" },
+ { 0, NULL }
+};
+
+static const struct tok bfd_v1_state_values[] = {
+ { 0, "AdminDown" },
+ { 1, "Down" },
+ { 2, "Init" },
+ { 3, "Up" },
+ { 0, NULL }
+};
+
+void
+bfd_print(register const u_char *pptr, register u_int len, register u_int port)
+{
+ const struct bfd_header_t *bfd_header;
+ const struct bfd_auth_header_t *bfd_auth_header;
+ u_int8_t version = 0;
+
+ bfd_header = (const struct bfd_header_t *)pptr;
+ if (port == BFD_CONTROL_PORT) {
+ TCHECK(*bfd_header);
+ version = BFD_EXTRACT_VERSION(bfd_header->version_diag);
+ } else if (port == BFD_ECHO_PORT) {
+ /* Echo is BFD v1 only */
+ version = 1;
+ }
+ switch ((port << 8) | version) {
+
+ /* BFDv0 */
+ case (BFD_CONTROL_PORT << 8):
+ if (vflag < 1 )
+ {
+ printf("BFDv%u, %s, Flags: [%s], length: %u",
+ version,
+ tok2str(bfd_port_values, "unknown (%u)", port),
+ bittok2str(bfd_v0_flag_values, "none", bfd_header->flags),
+ len);
+ return;
+ }
+
+ printf("BFDv%u, length: %u\n\t%s, Flags: [%s], Diagnostic: %s (0x%02x)",
+ version,
+ len,
+ tok2str(bfd_port_values, "unknown (%u)", port),
+ bittok2str(bfd_v0_flag_values, "none", bfd_header->flags),
+ tok2str(bfd_diag_values,"unknown",BFD_EXTRACT_DIAG(bfd_header->version_diag)),
+ BFD_EXTRACT_DIAG(bfd_header->version_diag));
+
+ printf("\n\tDetection Timer Multiplier: %u (%u ms Detection time), BFD Length: %u",
+ bfd_header->detect_time_multiplier,
+ bfd_header->detect_time_multiplier * EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000,
+ bfd_header->length);
+
+
+ printf("\n\tMy Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->my_discriminator));
+ printf(", Your Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->your_discriminator));
+ printf("\n\t Desired min Tx Interval: %4u ms", EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000);
+ printf("\n\t Required min Rx Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_rx_interval)/1000);
+ printf("\n\t Required min Echo Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_echo_interval)/1000);
+ break;
+
+ /* BFDv1 */
+ case (BFD_CONTROL_PORT << 8 | 1):
+ if (vflag < 1 )
+ {
+ printf("BFDv%u, %s, State %s, Flags: [%s], length: %u",
+ version,
+ tok2str(bfd_port_values, "unknown (%u)", port),
+ tok2str(bfd_v1_state_values, "unknown (%u)", (bfd_header->flags & 0xc0) >> 6),
+ bittok2str(bfd_v1_flag_values, "none", bfd_header->flags & 0x3f),
+ len);
+ return;
+ }
+
+ printf("BFDv%u, length: %u\n\t%s, State %s, Flags: [%s], Diagnostic: %s (0x%02x)",
+ version,
+ len,
+ tok2str(bfd_port_values, "unknown (%u)", port),
+ tok2str(bfd_v1_state_values, "unknown (%u)", (bfd_header->flags & 0xc0) >> 6),
+ bittok2str(bfd_v1_flag_values, "none", bfd_header->flags & 0x3f),
+ tok2str(bfd_diag_values,"unknown",BFD_EXTRACT_DIAG(bfd_header->version_diag)),
+ BFD_EXTRACT_DIAG(bfd_header->version_diag));
+
+ printf("\n\tDetection Timer Multiplier: %u (%u ms Detection time), BFD Length: %u",
+ bfd_header->detect_time_multiplier,
+ bfd_header->detect_time_multiplier * EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000,
+ bfd_header->length);
+
+
+ printf("\n\tMy Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->my_discriminator));
+ printf(", Your Discriminator: 0x%08x", EXTRACT_32BITS(bfd_header->your_discriminator));
+ printf("\n\t Desired min Tx Interval: %4u ms", EXTRACT_32BITS(bfd_header->desired_min_tx_interval)/1000);
+ printf("\n\t Required min Rx Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_rx_interval)/1000);
+ printf("\n\t Required min Echo Interval: %4u ms", EXTRACT_32BITS(bfd_header->required_min_echo_interval)/1000);
+
+ if (bfd_header->flags & BFD_FLAG_AUTH) {
+ pptr += sizeof (const struct bfd_header_t);
+ bfd_auth_header = (const struct bfd_auth_header_t *)pptr;
+ TCHECK2(*bfd_auth_header, sizeof(const struct bfd_auth_header_t));
+ printf("\n\t%s (%u) Authentication, length %u present",
+ tok2str(bfd_v1_authentication_values,"Unknown",bfd_auth_header->auth_type),
+ bfd_auth_header->auth_type,
+ bfd_auth_header->auth_len);
+ }
+ break;
+
+ /* BFDv0 */
+ case (BFD_ECHO_PORT << 8): /* not yet supported - fall through */
+ /* BFDv1 */
+ case (BFD_ECHO_PORT << 8 | 1):
+
+ default:
+ printf("BFD, %s, length: %u",
+ tok2str(bfd_port_values, "unknown (%u)", port),
+ len);
+ if (vflag >= 1) {
+ if(!print_unknown_data(pptr,"\n\t",len))
+ return;
+ }
+ break;
+ }
+ return;
+
+trunc:
+ printf("[|BFD]");
+}
diff --git a/freebsd/contrib/tcpdump/print-bgp.c b/freebsd/contrib/tcpdump/print-bgp.c
new file mode 100644
index 00000000..f58bc316
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-bgp.c
@@ -0,0 +1,2763 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 1999 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Extensively modified by Hannes Gredler (hannes@juniper.net) for more
+ * complete BGP support.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-bgp.c,v 1.118 2007-12-07 15:54:52 hannes Exp $";
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "decode_prefix.h"
+#include "addrtoname.h"
+#include "extract.h"
+#include "bgp.h"
+#include "af.h"
+#include "l2vpn.h"
+
+struct bgp {
+ u_int8_t bgp_marker[16];
+ u_int16_t bgp_len;
+ u_int8_t bgp_type;
+};
+#define BGP_SIZE 19 /* unaligned */
+
+#define BGP_OPEN 1
+#define BGP_UPDATE 2
+#define BGP_NOTIFICATION 3
+#define BGP_KEEPALIVE 4
+#define BGP_ROUTE_REFRESH 5
+
+static struct tok bgp_msg_values[] = {
+ { BGP_OPEN, "Open"},
+ { BGP_UPDATE, "Update"},
+ { BGP_NOTIFICATION, "Notification"},
+ { BGP_KEEPALIVE, "Keepalive"},
+ { BGP_ROUTE_REFRESH, "Route Refresh"},
+ { 0, NULL}
+};
+
+struct bgp_open {
+ u_int8_t bgpo_marker[16];
+ u_int16_t bgpo_len;
+ u_int8_t bgpo_type;
+ u_int8_t bgpo_version;
+ u_int16_t bgpo_myas;
+ u_int16_t bgpo_holdtime;
+ u_int32_t bgpo_id;
+ u_int8_t bgpo_optlen;
+ /* options should follow */
+};
+#define BGP_OPEN_SIZE 29 /* unaligned */
+
+struct bgp_opt {
+ u_int8_t bgpopt_type;
+ u_int8_t bgpopt_len;
+ /* variable length */
+};
+#define BGP_OPT_SIZE 2 /* some compilers may pad to 4 bytes */
+#define BGP_CAP_HEADER_SIZE 2 /* some compilers may pad to 4 bytes */
+
+struct bgp_notification {
+ u_int8_t bgpn_marker[16];
+ u_int16_t bgpn_len;
+ u_int8_t bgpn_type;
+ u_int8_t bgpn_major;
+ u_int8_t bgpn_minor;
+};
+#define BGP_NOTIFICATION_SIZE 21 /* unaligned */
+
+struct bgp_route_refresh {
+ u_int8_t bgp_marker[16];
+ u_int16_t len;
+ u_int8_t type;
+ u_int8_t afi[2]; /* the compiler messes this structure up */
+ u_int8_t res; /* when doing misaligned sequences of int8 and int16 */
+ u_int8_t safi; /* afi should be int16 - so we have to access it using */
+}; /* EXTRACT_16BITS(&bgp_route_refresh->afi) (sigh) */
+#define BGP_ROUTE_REFRESH_SIZE 23
+
+#define bgp_attr_lenlen(flags, p) \
+ (((flags) & 0x10) ? 2 : 1)
+#define bgp_attr_len(flags, p) \
+ (((flags) & 0x10) ? EXTRACT_16BITS(p) : *(p))
+
+#define BGPTYPE_ORIGIN 1
+#define BGPTYPE_AS_PATH 2
+#define BGPTYPE_NEXT_HOP 3
+#define BGPTYPE_MULTI_EXIT_DISC 4
+#define BGPTYPE_LOCAL_PREF 5
+#define BGPTYPE_ATOMIC_AGGREGATE 6
+#define BGPTYPE_AGGREGATOR 7
+#define BGPTYPE_COMMUNITIES 8 /* RFC1997 */
+#define BGPTYPE_ORIGINATOR_ID 9 /* RFC1998 */
+#define BGPTYPE_CLUSTER_LIST 10 /* RFC1998 */
+#define BGPTYPE_DPA 11 /* draft-ietf-idr-bgp-dpa */
+#define BGPTYPE_ADVERTISERS 12 /* RFC1863 */
+#define BGPTYPE_RCID_PATH 13 /* RFC1863 */
+#define BGPTYPE_MP_REACH_NLRI 14 /* RFC2283 */
+#define BGPTYPE_MP_UNREACH_NLRI 15 /* RFC2283 */
+#define BGPTYPE_EXTD_COMMUNITIES 16 /* draft-ietf-idr-bgp-ext-communities */
+#define BGPTYPE_AS4_PATH 17 /* RFC4893 */
+#define BGPTYPE_AGGREGATOR4 18 /* RFC4893 */
+#define BGPTYPE_PMSI_TUNNEL 22 /* draft-ietf-l3vpn-2547bis-mcast-bgp-02.txt */
+#define BGPTYPE_ATTR_SET 128 /* draft-marques-ppvpn-ibgp */
+
+#define BGP_MP_NLRI_MINSIZE 3 /* End of RIB Marker detection */
+
+static struct tok bgp_attr_values[] = {
+ { BGPTYPE_ORIGIN, "Origin"},
+ { BGPTYPE_AS_PATH, "AS Path"},
+ { BGPTYPE_AS4_PATH, "AS4 Path"},
+ { BGPTYPE_NEXT_HOP, "Next Hop"},
+ { BGPTYPE_MULTI_EXIT_DISC, "Multi Exit Discriminator"},
+ { BGPTYPE_LOCAL_PREF, "Local Preference"},
+ { BGPTYPE_ATOMIC_AGGREGATE, "Atomic Aggregate"},
+ { BGPTYPE_AGGREGATOR, "Aggregator"},
+ { BGPTYPE_AGGREGATOR4, "Aggregator4"},
+ { BGPTYPE_COMMUNITIES, "Community"},
+ { BGPTYPE_ORIGINATOR_ID, "Originator ID"},
+ { BGPTYPE_CLUSTER_LIST, "Cluster List"},
+ { BGPTYPE_DPA, "DPA"},
+ { BGPTYPE_ADVERTISERS, "Advertisers"},
+ { BGPTYPE_RCID_PATH, "RCID Path / Cluster ID"},
+ { BGPTYPE_MP_REACH_NLRI, "Multi-Protocol Reach NLRI"},
+ { BGPTYPE_MP_UNREACH_NLRI, "Multi-Protocol Unreach NLRI"},
+ { BGPTYPE_EXTD_COMMUNITIES, "Extended Community"},
+ { BGPTYPE_PMSI_TUNNEL, "PMSI Tunnel"},
+ { BGPTYPE_ATTR_SET, "Attribute Set"},
+ { 255, "Reserved for development"},
+ { 0, NULL}
+};
+
+#define BGP_AS_SET 1
+#define BGP_AS_SEQUENCE 2
+#define BGP_CONFED_AS_SEQUENCE 3 /* draft-ietf-idr-rfc3065bis-01 */
+#define BGP_CONFED_AS_SET 4 /* draft-ietf-idr-rfc3065bis-01 */
+
+#define BGP_AS_SEG_TYPE_MIN BGP_AS_SET
+#define BGP_AS_SEG_TYPE_MAX BGP_CONFED_AS_SET
+
+static struct tok bgp_as_path_segment_open_values[] = {
+ { BGP_AS_SEQUENCE, ""},
+ { BGP_AS_SET, "{ "},
+ { BGP_CONFED_AS_SEQUENCE, "( "},
+ { BGP_CONFED_AS_SET, "({ "},
+ { 0, NULL}
+};
+
+static struct tok bgp_as_path_segment_close_values[] = {
+ { BGP_AS_SEQUENCE, ""},
+ { BGP_AS_SET, "}"},
+ { BGP_CONFED_AS_SEQUENCE, ")"},
+ { BGP_CONFED_AS_SET, "})"},
+ { 0, NULL}
+};
+
+#define BGP_OPT_AUTH 1
+#define BGP_OPT_CAP 2
+
+
+static struct tok bgp_opt_values[] = {
+ { BGP_OPT_AUTH, "Authentication Information"},
+ { BGP_OPT_CAP, "Capabilities Advertisement"},
+ { 0, NULL}
+};
+
+#define BGP_CAPCODE_MP 1
+#define BGP_CAPCODE_RR 2
+#define BGP_CAPCODE_ORF 3 /* XXX */
+#define BGP_CAPCODE_RESTART 64 /* draft-ietf-idr-restart-05 */
+#define BGP_CAPCODE_AS_NEW 65 /* XXX */
+#define BGP_CAPCODE_DYN_CAP 67 /* XXX */
+#define BGP_CAPCODE_RR_CISCO 128
+
+static struct tok bgp_capcode_values[] = {
+ { BGP_CAPCODE_MP, "Multiprotocol Extensions"},
+ { BGP_CAPCODE_RR, "Route Refresh"},
+ { BGP_CAPCODE_ORF, "Cooperative Route Filtering"},
+ { BGP_CAPCODE_RESTART, "Graceful Restart"},
+ { BGP_CAPCODE_AS_NEW, "32-Bit AS Number"},
+ { BGP_CAPCODE_DYN_CAP, "Dynamic Capability"},
+ { BGP_CAPCODE_RR_CISCO, "Route Refresh (Cisco)"},
+ { 0, NULL}
+};
+
+#define BGP_NOTIFY_MAJOR_MSG 1
+#define BGP_NOTIFY_MAJOR_OPEN 2
+#define BGP_NOTIFY_MAJOR_UPDATE 3
+#define BGP_NOTIFY_MAJOR_HOLDTIME 4
+#define BGP_NOTIFY_MAJOR_FSM 5
+#define BGP_NOTIFY_MAJOR_CEASE 6
+#define BGP_NOTIFY_MAJOR_CAP 7
+
+static struct tok bgp_notify_major_values[] = {
+ { BGP_NOTIFY_MAJOR_MSG, "Message Header Error"},
+ { BGP_NOTIFY_MAJOR_OPEN, "OPEN Message Error"},
+ { BGP_NOTIFY_MAJOR_UPDATE, "UPDATE Message Error"},
+ { BGP_NOTIFY_MAJOR_HOLDTIME,"Hold Timer Expired"},
+ { BGP_NOTIFY_MAJOR_FSM, "Finite State Machine Error"},
+ { BGP_NOTIFY_MAJOR_CEASE, "Cease"},
+ { BGP_NOTIFY_MAJOR_CAP, "Capability Message Error"},
+ { 0, NULL}
+};
+
+/* draft-ietf-idr-cease-subcode-02 */
+#define BGP_NOTIFY_MINOR_CEASE_MAXPRFX 1
+static struct tok bgp_notify_minor_cease_values[] = {
+ { BGP_NOTIFY_MINOR_CEASE_MAXPRFX, "Maximum Number of Prefixes Reached"},
+ { 2, "Administratively Shutdown"},
+ { 3, "Peer Unconfigured"},
+ { 4, "Administratively Reset"},
+ { 5, "Connection Rejected"},
+ { 6, "Other Configuration Change"},
+ { 7, "Connection Collision Resolution"},
+ { 0, NULL}
+};
+
+static struct tok bgp_notify_minor_msg_values[] = {
+ { 1, "Connection Not Synchronized"},
+ { 2, "Bad Message Length"},
+ { 3, "Bad Message Type"},
+ { 0, NULL}
+};
+
+static struct tok bgp_notify_minor_open_values[] = {
+ { 1, "Unsupported Version Number"},
+ { 2, "Bad Peer AS"},
+ { 3, "Bad BGP Identifier"},
+ { 4, "Unsupported Optional Parameter"},
+ { 5, "Authentication Failure"},
+ { 6, "Unacceptable Hold Time"},
+ { 7, "Capability Message Error"},
+ { 0, NULL}
+};
+
+static struct tok bgp_notify_minor_update_values[] = {
+ { 1, "Malformed Attribute List"},
+ { 2, "Unrecognized Well-known Attribute"},
+ { 3, "Missing Well-known Attribute"},
+ { 4, "Attribute Flags Error"},
+ { 5, "Attribute Length Error"},
+ { 6, "Invalid ORIGIN Attribute"},
+ { 7, "AS Routing Loop"},
+ { 8, "Invalid NEXT_HOP Attribute"},
+ { 9, "Optional Attribute Error"},
+ { 10, "Invalid Network Field"},
+ { 11, "Malformed AS_PATH"},
+ { 0, NULL}
+};
+
+static struct tok bgp_notify_minor_cap_values[] = {
+ { 1, "Invalid Action Value" },
+ { 2, "Invalid Capability Length" },
+ { 3, "Malformed Capability Value" },
+ { 4, "Unsupported Capability Code" },
+ { 0, NULL }
+};
+
+static struct tok bgp_origin_values[] = {
+ { 0, "IGP"},
+ { 1, "EGP"},
+ { 2, "Incomplete"},
+ { 0, NULL}
+};
+
+#define BGP_PMSI_TUNNEL_RSVP_P2MP 1
+#define BGP_PMSI_TUNNEL_LDP_P2MP 2
+#define BGP_PMSI_TUNNEL_PIM_SSM 3
+#define BGP_PMSI_TUNNEL_PIM_SM 4
+#define BGP_PMSI_TUNNEL_PIM_BIDIR 5
+#define BGP_PMSI_TUNNEL_INGRESS 6
+#define BGP_PMSI_TUNNEL_LDP_MP2MP 7
+
+static struct tok bgp_pmsi_tunnel_values[] = {
+ { BGP_PMSI_TUNNEL_RSVP_P2MP, "RSVP-TE P2MP LSP"},
+ { BGP_PMSI_TUNNEL_LDP_P2MP, "LDP P2MP LSP"},
+ { BGP_PMSI_TUNNEL_PIM_SSM, "PIM-SSM Tree"},
+ { BGP_PMSI_TUNNEL_PIM_SM, "PIM-SM Tree"},
+ { BGP_PMSI_TUNNEL_PIM_BIDIR, "PIM-Bidir Tree"},
+ { BGP_PMSI_TUNNEL_INGRESS, "Ingress Replication"},
+ { BGP_PMSI_TUNNEL_LDP_MP2MP, "LDP MP2MP LSP"},
+ { 0, NULL}
+};
+
+static struct tok bgp_pmsi_flag_values[] = {
+ { 0x01, "Leaf Information required"},
+ { 0, NULL}
+};
+
+
+/* Subsequent address family identifier, RFC2283 section 7 */
+#define SAFNUM_RES 0
+#define SAFNUM_UNICAST 1
+#define SAFNUM_MULTICAST 2
+#define SAFNUM_UNIMULTICAST 3
+/* labeled BGP RFC3107 */
+#define SAFNUM_LABUNICAST 4
+/* draft-ietf-l3vpn-2547bis-mcast-bgp-02.txt */
+#define SAFNUM_MULTICAST_VPN 5
+#define SAFNUM_TUNNEL 64 /* XXX */
+#define SAFNUM_VPLS 65 /* XXX */
+/* draft-nalawade-idr-mdt-safi-03 */
+#define SAFNUM_MDT 66
+/* Section 4.3.4 of draft-rosen-rfc2547bis-03.txt */
+#define SAFNUM_VPNUNICAST 128
+#define SAFNUM_VPNMULTICAST 129
+#define SAFNUM_VPNUNIMULTICAST 130
+/* draft-marques-ppvpn-rt-constrain-01.txt */
+#define SAFNUM_RT_ROUTING_INFO 132
+
+#define BGP_VPN_RD_LEN 8
+
+static struct tok bgp_safi_values[] = {
+ { SAFNUM_RES, "Reserved"},
+ { SAFNUM_UNICAST, "Unicast"},
+ { SAFNUM_MULTICAST, "Multicast"},
+ { SAFNUM_UNIMULTICAST, "Unicast+Multicast"},
+ { SAFNUM_LABUNICAST, "labeled Unicast"},
+ { SAFNUM_TUNNEL, "Tunnel"},
+ { SAFNUM_VPLS, "VPLS"},
+ { SAFNUM_MDT, "MDT"},
+ { SAFNUM_VPNUNICAST, "labeled VPN Unicast"},
+ { SAFNUM_VPNMULTICAST, "labeled VPN Multicast"},
+ { SAFNUM_VPNUNIMULTICAST, "labeled VPN Unicast+Multicast"},
+ { SAFNUM_RT_ROUTING_INFO, "Route Target Routing Information"},
+ { SAFNUM_MULTICAST_VPN, "Multicast VPN"},
+ { 0, NULL }
+};
+
+/* well-known community */
+#define BGP_COMMUNITY_NO_EXPORT 0xffffff01
+#define BGP_COMMUNITY_NO_ADVERT 0xffffff02
+#define BGP_COMMUNITY_NO_EXPORT_SUBCONFED 0xffffff03
+
+/* Extended community type - draft-ietf-idr-bgp-ext-communities-05 */
+#define BGP_EXT_COM_RT_0 0x0002 /* Route Target,Format AS(2bytes):AN(4bytes) */
+#define BGP_EXT_COM_RT_1 0x0102 /* Route Target,Format IP address:AN(2bytes) */
+#define BGP_EXT_COM_RT_2 0x0202 /* Route Target,Format AN(4bytes):local(2bytes) */
+#define BGP_EXT_COM_RO_0 0x0003 /* Route Origin,Format AS(2bytes):AN(4bytes) */
+#define BGP_EXT_COM_RO_1 0x0103 /* Route Origin,Format IP address:AN(2bytes) */
+#define BGP_EXT_COM_RO_2 0x0203 /* Route Origin,Format AN(4bytes):local(2bytes) */
+#define BGP_EXT_COM_LINKBAND 0x4004 /* Link Bandwidth,Format AS(2B):Bandwidth(4B) */
+ /* rfc2547 bgp-mpls-vpns */
+#define BGP_EXT_COM_VPN_ORIGIN 0x0005 /* OSPF Domain ID / VPN of Origin - draft-rosen-vpns-ospf-bgp-mpls */
+#define BGP_EXT_COM_VPN_ORIGIN2 0x0105 /* duplicate - keep for backwards compatability */
+#define BGP_EXT_COM_VPN_ORIGIN3 0x0205 /* duplicate - keep for backwards compatability */
+#define BGP_EXT_COM_VPN_ORIGIN4 0x8005 /* duplicate - keep for backwards compatability */
+
+#define BGP_EXT_COM_OSPF_RTYPE 0x0306 /* OSPF Route Type,Format Area(4B):RouteType(1B):Options(1B) */
+#define BGP_EXT_COM_OSPF_RTYPE2 0x8000 /* duplicate - keep for backwards compatability */
+
+#define BGP_EXT_COM_OSPF_RID 0x0107 /* OSPF Router ID,Format RouterID(4B):Unused(2B) */
+#define BGP_EXT_COM_OSPF_RID2 0x8001 /* duplicate - keep for backwards compatability */
+
+#define BGP_EXT_COM_L2INFO 0x800a /* draft-kompella-ppvpn-l2vpn */
+
+#define BGP_EXT_COM_SOURCE_AS 0x0009 /* RFC-ietf-l3vpn-2547bis-mcast-bgp-08.txt */
+#define BGP_EXT_COM_VRF_RT_IMP 0x010b /* RFC-ietf-l3vpn-2547bis-mcast-bgp-08.txt */
+#define BGP_EXT_COM_L2VPN_RT_0 0x000a /* L2VPN Identifier,Format AS(2bytes):AN(4bytes) */
+#define BGP_EXT_COM_L2VPN_RT_1 0xF10a /* L2VPN Identifier,Format IP address:AN(2bytes) */
+
+
+/* http://www.cisco.com/en/US/tech/tk436/tk428/technologies_tech_note09186a00801eb09a.shtml */
+#define BGP_EXT_COM_EIGRP_GEN 0x8800
+#define BGP_EXT_COM_EIGRP_METRIC_AS_DELAY 0x8801
+#define BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW 0x8802
+#define BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU 0x8803
+#define BGP_EXT_COM_EIGRP_EXT_REMAS_REMID 0x8804
+#define BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC 0x8805
+
+static struct tok bgp_extd_comm_flag_values[] = {
+ { 0x8000, "vendor-specific"},
+ { 0x4000, "non-transitive"},
+ { 0, NULL},
+};
+
+static struct tok bgp_extd_comm_subtype_values[] = {
+ { BGP_EXT_COM_RT_0, "target"},
+ { BGP_EXT_COM_RT_1, "target"},
+ { BGP_EXT_COM_RT_2, "target"},
+ { BGP_EXT_COM_RO_0, "origin"},
+ { BGP_EXT_COM_RO_1, "origin"},
+ { BGP_EXT_COM_RO_2, "origin"},
+ { BGP_EXT_COM_LINKBAND, "link-BW"},
+ { BGP_EXT_COM_VPN_ORIGIN, "ospf-domain"},
+ { BGP_EXT_COM_VPN_ORIGIN2, "ospf-domain"},
+ { BGP_EXT_COM_VPN_ORIGIN3, "ospf-domain"},
+ { BGP_EXT_COM_VPN_ORIGIN4, "ospf-domain"},
+ { BGP_EXT_COM_OSPF_RTYPE, "ospf-route-type"},
+ { BGP_EXT_COM_OSPF_RTYPE2, "ospf-route-type"},
+ { BGP_EXT_COM_OSPF_RID, "ospf-router-id"},
+ { BGP_EXT_COM_OSPF_RID2, "ospf-router-id"},
+ { BGP_EXT_COM_L2INFO, "layer2-info"},
+ { BGP_EXT_COM_EIGRP_GEN , "eigrp-general-route (flag, tag)" },
+ { BGP_EXT_COM_EIGRP_METRIC_AS_DELAY , "eigrp-route-metric (AS, delay)" },
+ { BGP_EXT_COM_EIGRP_METRIC_REL_NH_BW , "eigrp-route-metric (reliability, nexthop, bandwidth)" },
+ { BGP_EXT_COM_EIGRP_METRIC_LOAD_MTU , "eigrp-route-metric (load, MTU)" },
+ { BGP_EXT_COM_EIGRP_EXT_REMAS_REMID , "eigrp-external-route (remote-AS, remote-ID)" },
+ { BGP_EXT_COM_EIGRP_EXT_REMPROTO_REMMETRIC , "eigrp-external-route (remote-proto, remote-metric)" },
+ { BGP_EXT_COM_SOURCE_AS, "source-AS" },
+ { BGP_EXT_COM_VRF_RT_IMP, "vrf-route-import"},
+ { BGP_EXT_COM_L2VPN_RT_0, "l2vpn-id"},
+ { BGP_EXT_COM_L2VPN_RT_1, "l2vpn-id"},
+ { 0, NULL},
+};
+
+/* OSPF codes for BGP_EXT_COM_OSPF_RTYPE draft-rosen-vpns-ospf-bgp-mpls */
+#define BGP_OSPF_RTYPE_RTR 1 /* OSPF Router LSA */
+#define BGP_OSPF_RTYPE_NET 2 /* OSPF Network LSA */
+#define BGP_OSPF_RTYPE_SUM 3 /* OSPF Summary LSA */
+#define BGP_OSPF_RTYPE_EXT 5 /* OSPF External LSA, note that ASBR doesn't apply to MPLS-VPN */
+#define BGP_OSPF_RTYPE_NSSA 7 /* OSPF NSSA External*/
+#define BGP_OSPF_RTYPE_SHAM 129 /* OSPF-MPLS-VPN Sham link */
+#define BGP_OSPF_RTYPE_METRIC_TYPE 0x1 /* LSB of RTYPE Options Field */
+
+static struct tok bgp_extd_comm_ospf_rtype_values[] = {
+ { BGP_OSPF_RTYPE_RTR, "Router" },
+ { BGP_OSPF_RTYPE_NET, "Network" },
+ { BGP_OSPF_RTYPE_SUM, "Summary" },
+ { BGP_OSPF_RTYPE_EXT, "External" },
+ { BGP_OSPF_RTYPE_NSSA,"NSSA External" },
+ { BGP_OSPF_RTYPE_SHAM,"MPLS-VPN Sham" },
+ { 0, NULL },
+};
+
+#define TOKBUFSIZE 128
+static char astostr[20];
+
+/*
+ * as_printf
+ *
+ * Convert an AS number into a string and return string pointer.
+ *
+ * Bepending on bflag is set or not, AS number is converted into ASDOT notation
+ * or plain number notation.
+ *
+ */
+static char *
+as_printf (char *str, int size, u_int asnum)
+{
+ if (!bflag || asnum <= 0xFFFF) {
+ snprintf(str, size, "%u", asnum);
+ } else {
+ snprintf(str, size, "%u.%u", asnum >> 16, asnum & 0xFFFF);
+ }
+ return str;
+}
+
+#define ITEMCHECK(minlen) if (itemlen < minlen) goto badtlv;
+
+int
+decode_prefix4(const u_char *pptr, u_int itemlen, char *buf, u_int buflen)
+{
+ struct in_addr addr;
+ u_int plen, plenbytes;
+
+ TCHECK(pptr[0]);
+ ITEMCHECK(1);
+ plen = pptr[0];
+ if (32 < plen)
+ return -1;
+ itemlen -= 1;
+
+ memset(&addr, 0, sizeof(addr));
+ plenbytes = (plen + 7) / 8;
+ TCHECK2(pptr[1], plenbytes);
+ ITEMCHECK(plenbytes);
+ memcpy(&addr, &pptr[1], plenbytes);
+ if (plen % 8) {
+ ((u_char *)&addr)[plenbytes - 1] &=
+ ((0xff00 >> (plen % 8)) & 0xff);
+ }
+ snprintf(buf, buflen, "%s/%d", getname((u_char *)&addr), plen);
+ return 1 + plenbytes;
+
+trunc:
+ return -2;
+
+badtlv:
+ return -3;
+}
+
+static int
+decode_labeled_prefix4(const u_char *pptr, u_int itemlen, char *buf, u_int buflen)
+{
+ struct in_addr addr;
+ u_int plen, plenbytes;
+
+ /* prefix length and label = 4 bytes */
+ TCHECK2(pptr[0], 4);
+ ITEMCHECK(4);
+ plen = pptr[0]; /* get prefix length */
+
+ /* this is one of the weirdnesses of rfc3107
+ the label length (actually the label + COS bits)
+ is added to the prefix length;
+ we also do only read out just one label -
+ there is no real application for advertisement of
+ stacked labels in a a single BGP message
+ */
+
+ if (24 > plen)
+ return -1;
+
+ plen-=24; /* adjust prefixlen - labellength */
+
+ if (32 < plen)
+ return -1;
+ itemlen -= 4;
+
+ memset(&addr, 0, sizeof(addr));
+ plenbytes = (plen + 7) / 8;
+ TCHECK2(pptr[4], plenbytes);
+ ITEMCHECK(plenbytes);
+ memcpy(&addr, &pptr[4], plenbytes);
+ if (plen % 8) {
+ ((u_char *)&addr)[plenbytes - 1] &=
+ ((0xff00 >> (plen % 8)) & 0xff);
+ }
+ /* the label may get offsetted by 4 bits so lets shift it right */
+ snprintf(buf, buflen, "%s/%d, label:%u %s",
+ getname((u_char *)&addr),
+ plen,
+ EXTRACT_24BITS(pptr+1)>>4,
+ ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
+
+ return 4 + plenbytes;
+
+trunc:
+ return -2;
+
+badtlv:
+ return -3;
+}
+
+/*
+ * bgp_vpn_ip_print
+ *
+ * print an ipv4 or ipv6 address into a buffer dependend on address length.
+ */
+static char *
+bgp_vpn_ip_print (const u_char *pptr, u_int addr_length) {
+
+ /* worst case string is s fully formatted v6 address */
+ static char addr[sizeof("1234:5678:89ab:cdef:1234:5678:89ab:cdef")];
+ char *pos = addr;
+
+ switch(addr_length) {
+ case (sizeof(struct in_addr) << 3): /* 32 */
+ TCHECK2(pptr[0], sizeof(struct in_addr));
+ snprintf(pos, sizeof(addr), "%s", ipaddr_string(pptr));
+ break;
+#ifdef INET6
+ case (sizeof(struct in6_addr) << 3): /* 128 */
+ TCHECK2(pptr[0], sizeof(struct in6_addr));
+ snprintf(pos, sizeof(addr), "%s", ip6addr_string(pptr));
+ break;
+#endif
+ default:
+ snprintf(pos, sizeof(addr), "bogus address length %u", addr_length);
+ break;
+ }
+ pos += strlen(pos);
+
+trunc:
+ *(pos) = '\0';
+ return (addr);
+}
+
+/*
+ * bgp_vpn_sg_print
+ *
+ * print an multicast s,g entry into a buffer.
+ * the s,g entry is encoded like this.
+ *
+ * +-----------------------------------+
+ * | Multicast Source Length (1 octet) |
+ * +-----------------------------------+
+ * | Multicast Source (Variable) |
+ * +-----------------------------------+
+ * | Multicast Group Length (1 octet) |
+ * +-----------------------------------+
+ * | Multicast Group (Variable) |
+ * +-----------------------------------+
+ *
+ * return the number of bytes read from the wire.
+ */
+static int
+bgp_vpn_sg_print (const u_char *pptr, char *buf, u_int buflen) {
+
+ u_int8_t addr_length;
+ u_int total_length, offset;
+
+ total_length = 0;
+
+ /* Source address length, encoded in bits */
+ TCHECK2(pptr[0], 1);
+ addr_length = *pptr++;
+
+ /* Source address */
+ TCHECK2(pptr[0], (addr_length >> 3));
+ total_length += (addr_length >> 3) + 1;
+ offset = strlen(buf);
+ if (addr_length) {
+ snprintf(buf + offset, buflen - offset, ", Source %s",
+ bgp_vpn_ip_print(pptr, addr_length));
+ pptr += (addr_length >> 3);
+ }
+
+ /* Group address length, encoded in bits */
+ TCHECK2(pptr[0], 1);
+ addr_length = *pptr++;
+
+ /* Group address */
+ TCHECK2(pptr[0], (addr_length >> 3));
+ total_length += (addr_length >> 3) + 1;
+ offset = strlen(buf);
+ if (addr_length) {
+ snprintf(buf + offset, buflen - offset, ", Group %s",
+ bgp_vpn_ip_print(pptr, addr_length));
+ pptr += (addr_length >> 3);
+ }
+
+trunc:
+ return (total_length);
+}
+
+
+/* RDs and RTs share the same semantics
+ * we use bgp_vpn_rd_print for
+ * printing route targets inside a NLRI */
+char *
+bgp_vpn_rd_print (const u_char *pptr) {
+
+ /* allocate space for the largest possible string */
+ static char rd[sizeof("xxxxxxxxxx:xxxxx (xxx.xxx.xxx.xxx:xxxxx)")];
+ char *pos = rd;
+
+ /* ok lets load the RD format */
+ switch (EXTRACT_16BITS(pptr)) {
+
+ /* 2-byte-AS:number fmt*/
+ case 0:
+ snprintf(pos, sizeof(rd) - (pos - rd), "%u:%u (= %u.%u.%u.%u)",
+ EXTRACT_16BITS(pptr+2),
+ EXTRACT_32BITS(pptr+4),
+ *(pptr+4), *(pptr+5), *(pptr+6), *(pptr+7));
+ break;
+ /* IP-address:AS fmt*/
+
+ case 1:
+ snprintf(pos, sizeof(rd) - (pos - rd), "%u.%u.%u.%u:%u",
+ *(pptr+2), *(pptr+3), *(pptr+4), *(pptr+5), EXTRACT_16BITS(pptr+6));
+ break;
+
+ /* 4-byte-AS:number fmt*/
+ case 2:
+ snprintf(pos, sizeof(rd) - (pos - rd), "%s:%u (%u.%u.%u.%u:%u)",
+ as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(pptr+2)),
+ EXTRACT_16BITS(pptr+6), *(pptr+2), *(pptr+3), *(pptr+4),
+ *(pptr+5), EXTRACT_16BITS(pptr+6));
+ break;
+ default:
+ snprintf(pos, sizeof(rd) - (pos - rd), "unknown RD format");
+ break;
+ }
+ pos += strlen(pos);
+ *(pos) = '\0';
+ return (rd);
+}
+
+static int
+decode_rt_routing_info(const u_char *pptr, char *buf, u_int buflen)
+{
+ u_int8_t route_target[8];
+ u_int plen;
+
+ TCHECK(pptr[0]);
+ plen = pptr[0]; /* get prefix length */
+
+ if (0 == plen)
+ return 1; /* default route target */
+
+ if (32 > plen)
+ return -1;
+
+ plen-=32; /* adjust prefix length */
+
+ if (64 < plen)
+ return -1;
+
+ memset(&route_target, 0, sizeof(route_target));
+ TCHECK2(pptr[1], (plen + 7) / 8);
+ memcpy(&route_target, &pptr[1], (plen + 7) / 8);
+ if (plen % 8) {
+ ((u_char *)&route_target)[(plen + 7) / 8 - 1] &=
+ ((0xff00 >> (plen % 8)) & 0xff);
+ }
+ snprintf(buf, buflen, "origin AS: %s, route target %s",
+ as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(pptr+1)),
+ bgp_vpn_rd_print((u_char *)&route_target));
+
+ return 5 + (plen + 7) / 8;
+
+trunc:
+ return -2;
+}
+
+static int
+decode_labeled_vpn_prefix4(const u_char *pptr, char *buf, u_int buflen)
+{
+ struct in_addr addr;
+ u_int plen;
+
+ TCHECK(pptr[0]);
+ plen = pptr[0]; /* get prefix length */
+
+ if ((24+64) > plen)
+ return -1;
+
+ plen-=(24+64); /* adjust prefixlen - labellength - RD len*/
+
+ if (32 < plen)
+ return -1;
+
+ memset(&addr, 0, sizeof(addr));
+ TCHECK2(pptr[12], (plen + 7) / 8);
+ memcpy(&addr, &pptr[12], (plen + 7) / 8);
+ if (plen % 8) {
+ ((u_char *)&addr)[(plen + 7) / 8 - 1] &=
+ ((0xff00 >> (plen % 8)) & 0xff);
+ }
+ /* the label may get offsetted by 4 bits so lets shift it right */
+ snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s",
+ bgp_vpn_rd_print(pptr+4),
+ getname((u_char *)&addr),
+ plen,
+ EXTRACT_24BITS(pptr+1)>>4,
+ ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
+
+ return 12 + (plen + 7) / 8;
+
+trunc:
+ return -2;
+}
+
+/*
+ * +-------------------------------+
+ * | |
+ * | RD:IPv4-address (12 octets) |
+ * | |
+ * +-------------------------------+
+ * | MDT Group-address (4 octets) |
+ * +-------------------------------+
+ */
+
+#define MDT_VPN_NLRI_LEN 16
+
+static int
+decode_mdt_vpn_nlri(const u_char *pptr, char *buf, u_int buflen)
+{
+
+ const u_char *rd;
+ const u_char *vpn_ip;
+
+ TCHECK(pptr[0]);
+
+ /* if the NLRI is not predefined length, quit.*/
+ if (*pptr != MDT_VPN_NLRI_LEN * NBBY)
+ return -1;
+ pptr++;
+
+ /* RD */
+ TCHECK2(pptr[0], 8);
+ rd = pptr;
+ pptr+=8;
+
+ /* IPv4 address */
+ TCHECK2(pptr[0], sizeof(struct in_addr));
+ vpn_ip = pptr;
+ pptr+=sizeof(struct in_addr);
+
+ /* MDT Group Address */
+ TCHECK2(pptr[0], sizeof(struct in_addr));
+
+ snprintf(buf, buflen, "RD: %s, VPN IP Address: %s, MC Group Address: %s",
+ bgp_vpn_rd_print(rd), ipaddr_string(vpn_ip), ipaddr_string(pptr));
+
+ return MDT_VPN_NLRI_LEN + 1;
+
+ trunc:
+
+return -2;
+}
+
+#define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI 1
+#define BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI 2
+#define BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI 3
+#define BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF 4
+#define BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE 5
+#define BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN 6
+#define BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN 7
+
+static struct tok bgp_multicast_vpn_route_type_values[] = {
+ { BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI, "Intra-AS I-PMSI"},
+ { BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI, "Inter-AS I-PMSI"},
+ { BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI, "S-PMSI"},
+ { BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF, "Intra-AS Segment-Leaf"},
+ { BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE, "Source-Active"},
+ { BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN, "Shared Tree Join"},
+ { BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN, "Source Tree Join"},
+};
+
+static int
+decode_multicast_vpn(const u_char *pptr, char *buf, u_int buflen)
+{
+ u_int8_t route_type, route_length, addr_length, sg_length;
+ u_int offset;
+
+ TCHECK2(pptr[0], 2);
+ route_type = *pptr++;
+ route_length = *pptr++;
+
+ snprintf(buf, buflen, "Route-Type: %s (%u), length: %u",
+ tok2str(bgp_multicast_vpn_route_type_values,
+ "Unknown", route_type),
+ route_type, route_length);
+
+ switch(route_type) {
+ case BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_I_PMSI:
+ TCHECK2(pptr[0], BGP_VPN_RD_LEN);
+ offset = strlen(buf);
+ snprintf(buf + offset, buflen - offset, ", RD: %s, Originator %s",
+ bgp_vpn_rd_print(pptr),
+ bgp_vpn_ip_print(pptr + BGP_VPN_RD_LEN,
+ (route_length - BGP_VPN_RD_LEN) << 3));
+ break;
+ case BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI:
+ TCHECK2(pptr[0], BGP_VPN_RD_LEN + 4);
+ offset = strlen(buf);
+ snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s",
+ bgp_vpn_rd_print(pptr),
+ as_printf(astostr, sizeof(astostr),
+ EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN)));
+ break;
+
+ case BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI:
+ TCHECK2(pptr[0], BGP_VPN_RD_LEN);
+ offset = strlen(buf);
+ snprintf(buf + offset, buflen - offset, ", RD: %s",
+ bgp_vpn_rd_print(pptr));
+ pptr += BGP_VPN_RD_LEN;
+
+ sg_length = bgp_vpn_sg_print(pptr, buf, buflen);
+ addr_length = route_length - sg_length;
+
+ TCHECK2(pptr[0], addr_length);
+ offset = strlen(buf);
+ snprintf(buf + offset, buflen - offset, ", Originator %s",
+ bgp_vpn_ip_print(pptr, addr_length << 3));
+ break;
+
+ case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_ACTIVE:
+ TCHECK2(pptr[0], BGP_VPN_RD_LEN);
+ offset = strlen(buf);
+ snprintf(buf + offset, buflen - offset, ", RD: %s",
+ bgp_vpn_rd_print(pptr));
+ pptr += BGP_VPN_RD_LEN;
+
+ bgp_vpn_sg_print(pptr, buf, buflen);
+ break;
+
+ case BGP_MULTICAST_VPN_ROUTE_TYPE_SHARED_TREE_JOIN: /* fall through */
+ case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN:
+ TCHECK2(pptr[0], BGP_VPN_RD_LEN);
+ offset = strlen(buf);
+ snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s",
+ bgp_vpn_rd_print(pptr),
+ as_printf(astostr, sizeof(astostr),
+ EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN)));
+ pptr += BGP_VPN_RD_LEN;
+
+ bgp_vpn_sg_print(pptr, buf, buflen);
+ break;
+
+ /*
+ * no per route-type printing yet.
+ */
+ case BGP_MULTICAST_VPN_ROUTE_TYPE_INTRA_AS_SEG_LEAF:
+ default:
+ break;
+ }
+
+ return route_length + 2;
+
+trunc:
+ return -2;
+}
+
+/*
+ * As I remember, some versions of systems have an snprintf() that
+ * returns -1 if the buffer would have overflowed. If the return
+ * value is negative, set buflen to 0, to indicate that we've filled
+ * the buffer up.
+ *
+ * If the return value is greater than buflen, that means that
+ * the buffer would have overflowed; again, set buflen to 0 in
+ * that case.
+ */
+#define UPDATE_BUF_BUFLEN(buf, buflen, strlen) \
+ if (strlen<0) \
+ buflen=0; \
+ else if ((u_int)strlen>buflen) \
+ buflen=0; \
+ else { \
+ buflen-=strlen; \
+ buf+=strlen; \
+ }
+
+static int
+decode_labeled_vpn_l2(const u_char *pptr, char *buf, u_int buflen)
+{
+ int plen,tlen,strlen,tlv_type,tlv_len,ttlv_len;
+
+ TCHECK2(pptr[0], 2);
+ plen=EXTRACT_16BITS(pptr);
+ tlen=plen;
+ pptr+=2;
+ /* Old and new L2VPN NLRI share AFI/SAFI
+ * -> Assume a 12 Byte-length NLRI is auto-discovery-only
+ * and > 17 as old format. Complain for the middle case
+ */
+ if (plen==12) {
+ /* assume AD-only with RD, BGPNH */
+ TCHECK2(pptr[0],12);
+ buf[0]='\0';
+ strlen=snprintf(buf, buflen, "RD: %s, BGPNH: %s",
+ bgp_vpn_rd_print(pptr),
+ /* need something like getname() here */
+ getname(pptr+8)
+ );
+ UPDATE_BUF_BUFLEN(buf, buflen, strlen);
+ pptr+=12;
+ tlen-=12;
+ return plen;
+ } else if (plen>17) {
+ /* assume old format */
+ /* RD, ID, LBLKOFF, LBLBASE */
+
+ TCHECK2(pptr[0],15);
+ buf[0]='\0';
+ strlen=snprintf(buf, buflen, "RD: %s, CE-ID: %u, Label-Block Offset: %u, Label Base %u",
+ bgp_vpn_rd_print(pptr),
+ EXTRACT_16BITS(pptr+8),
+ EXTRACT_16BITS(pptr+10),
+ EXTRACT_24BITS(pptr+12)>>4); /* the label is offsetted by 4 bits so lets shift it right */
+ UPDATE_BUF_BUFLEN(buf, buflen, strlen);
+ pptr+=15;
+ tlen-=15;
+
+ /* ok now the variable part - lets read out TLVs*/
+ while (tlen>0) {
+ if (tlen < 3)
+ return -1;
+ TCHECK2(pptr[0], 3);
+ tlv_type=*pptr++;
+ tlv_len=EXTRACT_16BITS(pptr);
+ ttlv_len=tlv_len;
+ pptr+=2;
+
+ switch(tlv_type) {
+ case 1:
+ if (buflen!=0) {
+ strlen=snprintf(buf,buflen, "\n\t\tcircuit status vector (%u) length: %u: 0x",
+ tlv_type,
+ tlv_len);
+ UPDATE_BUF_BUFLEN(buf, buflen, strlen);
+ }
+ ttlv_len=ttlv_len/8+1; /* how many bytes do we need to read ? */
+ while (ttlv_len>0) {
+ TCHECK(pptr[0]);
+ if (buflen!=0) {
+ strlen=snprintf(buf,buflen, "%02x",*pptr++);
+ UPDATE_BUF_BUFLEN(buf, buflen, strlen);
+ }
+ ttlv_len--;
+ }
+ break;
+ default:
+ if (buflen!=0) {
+ strlen=snprintf(buf,buflen, "\n\t\tunknown TLV #%u, length: %u",
+ tlv_type,
+ tlv_len);
+ UPDATE_BUF_BUFLEN(buf, buflen, strlen);
+ }
+ break;
+ }
+ tlen-=(tlv_len<<3); /* the tlv-length is expressed in bits so lets shift it right */
+ }
+ return plen+2;
+
+ } else {
+ /* complain bitterly ? */
+ /* fall through */
+ goto trunc;
+ }
+
+trunc:
+ return -2;
+}
+
+#ifdef INET6
+int
+decode_prefix6(const u_char *pd, u_int itemlen, char *buf, u_int buflen)
+{
+ struct in6_addr addr;
+ u_int plen, plenbytes;
+
+ TCHECK(pd[0]);
+ ITEMCHECK(1);
+ plen = pd[0];
+ if (128 < plen)
+ return -1;
+ itemlen -= 1;
+
+ memset(&addr, 0, sizeof(addr));
+ plenbytes = (plen + 7) / 8;
+ TCHECK2(pd[1], plenbytes);
+ ITEMCHECK(plenbytes);
+ memcpy(&addr, &pd[1], plenbytes);
+ if (plen % 8) {
+ addr.s6_addr[plenbytes - 1] &=
+ ((0xff00 >> (plen % 8)) & 0xff);
+ }
+ snprintf(buf, buflen, "%s/%d", getname6((u_char *)&addr), plen);
+ return 1 + plenbytes;
+
+trunc:
+ return -2;
+
+badtlv:
+ return -3;
+}
+
+static int
+decode_labeled_prefix6(const u_char *pptr, u_int itemlen, char *buf, u_int buflen)
+{
+ struct in6_addr addr;
+ u_int plen, plenbytes;
+
+ /* prefix length and label = 4 bytes */
+ TCHECK2(pptr[0], 4);
+ ITEMCHECK(4);
+ plen = pptr[0]; /* get prefix length */
+
+ if (24 > plen)
+ return -1;
+
+ plen-=24; /* adjust prefixlen - labellength */
+
+ if (128 < plen)
+ return -1;
+ itemlen -= 4;
+
+ memset(&addr, 0, sizeof(addr));
+ plenbytes = (plen + 7) / 8;
+ TCHECK2(pptr[4], plenbytes);
+ memcpy(&addr, &pptr[4], plenbytes);
+ if (plen % 8) {
+ addr.s6_addr[plenbytes - 1] &=
+ ((0xff00 >> (plen % 8)) & 0xff);
+ }
+ /* the label may get offsetted by 4 bits so lets shift it right */
+ snprintf(buf, buflen, "%s/%d, label:%u %s",
+ getname6((u_char *)&addr),
+ plen,
+ EXTRACT_24BITS(pptr+1)>>4,
+ ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
+
+ return 4 + plenbytes;
+
+trunc:
+ return -2;
+
+badtlv:
+ return -3;
+}
+
+static int
+decode_labeled_vpn_prefix6(const u_char *pptr, char *buf, u_int buflen)
+{
+ struct in6_addr addr;
+ u_int plen;
+
+ TCHECK(pptr[0]);
+ plen = pptr[0]; /* get prefix length */
+
+ if ((24+64) > plen)
+ return -1;
+
+ plen-=(24+64); /* adjust prefixlen - labellength - RD len*/
+
+ if (128 < plen)
+ return -1;
+
+ memset(&addr, 0, sizeof(addr));
+ TCHECK2(pptr[12], (plen + 7) / 8);
+ memcpy(&addr, &pptr[12], (plen + 7) / 8);
+ if (plen % 8) {
+ addr.s6_addr[(plen + 7) / 8 - 1] &=
+ ((0xff00 >> (plen % 8)) & 0xff);
+ }
+ /* the label may get offsetted by 4 bits so lets shift it right */
+ snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s",
+ bgp_vpn_rd_print(pptr+4),
+ getname6((u_char *)&addr),
+ plen,
+ EXTRACT_24BITS(pptr+1)>>4,
+ ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
+
+ return 12 + (plen + 7) / 8;
+
+trunc:
+ return -2;
+}
+#endif
+
+static int
+decode_clnp_prefix(const u_char *pptr, char *buf, u_int buflen)
+{
+ u_int8_t addr[19];
+ u_int plen;
+
+ TCHECK(pptr[0]);
+ plen = pptr[0]; /* get prefix length */
+
+ if (152 < plen)
+ return -1;
+
+ memset(&addr, 0, sizeof(addr));
+ TCHECK2(pptr[4], (plen + 7) / 8);
+ memcpy(&addr, &pptr[4], (plen + 7) / 8);
+ if (plen % 8) {
+ addr[(plen + 7) / 8 - 1] &=
+ ((0xff00 >> (plen % 8)) & 0xff);
+ }
+ snprintf(buf, buflen, "%s/%d",
+ isonsap_string(addr,(plen + 7) / 8),
+ plen);
+
+ return 1 + (plen + 7) / 8;
+
+trunc:
+ return -2;
+}
+
+static int
+decode_labeled_vpn_clnp_prefix(const u_char *pptr, char *buf, u_int buflen)
+{
+ u_int8_t addr[19];
+ u_int plen;
+
+ TCHECK(pptr[0]);
+ plen = pptr[0]; /* get prefix length */
+
+ if ((24+64) > plen)
+ return -1;
+
+ plen-=(24+64); /* adjust prefixlen - labellength - RD len*/
+
+ if (152 < plen)
+ return -1;
+
+ memset(&addr, 0, sizeof(addr));
+ TCHECK2(pptr[12], (plen + 7) / 8);
+ memcpy(&addr, &pptr[12], (plen + 7) / 8);
+ if (plen % 8) {
+ addr[(plen + 7) / 8 - 1] &=
+ ((0xff00 >> (plen % 8)) & 0xff);
+ }
+ /* the label may get offsetted by 4 bits so lets shift it right */
+ snprintf(buf, buflen, "RD: %s, %s/%d, label:%u %s",
+ bgp_vpn_rd_print(pptr+4),
+ isonsap_string(addr,(plen + 7) / 8),
+ plen,
+ EXTRACT_24BITS(pptr+1)>>4,
+ ((pptr[3]&1)==0) ? "(BOGUS: Bottom of Stack NOT set!)" : "(bottom)" );
+
+ return 12 + (plen + 7) / 8;
+
+trunc:
+ return -2;
+}
+
+/*
+ * bgp_attr_get_as_size
+ *
+ * Try to find the size of the ASs encoded in an as-path. It is not obvious, as
+ * both Old speakers that do not support 4 byte AS, and the new speakers that do
+ * support, exchange AS-Path with the same path-attribute type value 0x02.
+ */
+static int
+bgp_attr_get_as_size (u_int8_t bgpa_type, const u_char *pptr, int len)
+{
+ const u_char *tptr = pptr;
+
+ /*
+ * If the path attribute is the optional AS4 path type, then we already
+ * know, that ASs must be encoded in 4 byte format.
+ */
+ if (bgpa_type == BGPTYPE_AS4_PATH) {
+ return 4;
+ }
+
+ /*
+ * Let us assume that ASs are of 2 bytes in size, and check if the AS-Path
+ * TLV is good. If not, ask the caller to try with AS encoded as 4 bytes
+ * each.
+ */
+ while (tptr < pptr + len) {
+ TCHECK(tptr[0]);
+
+ /*
+ * If we do not find a valid segment type, our guess might be wrong.
+ */
+ if (tptr[0] < BGP_AS_SEG_TYPE_MIN || tptr[0] > BGP_AS_SEG_TYPE_MAX) {
+ goto trunc;
+ }
+ TCHECK(tptr[1]);
+ tptr += 2 + tptr[1] * 2;
+ }
+
+ /*
+ * If we correctly reached end of the AS path attribute data content,
+ * then most likely ASs were indeed encoded as 2 bytes.
+ */
+ if (tptr == pptr + len) {
+ return 2;
+ }
+
+trunc:
+
+ /*
+ * We can come here, either we did not have enough data, or if we
+ * try to decode 4 byte ASs in 2 byte format. Either way, return 4,
+ * so that calller can try to decode each AS as of 4 bytes. If indeed
+ * there was not enough data, it will crib and end the parse anyways.
+ */
+ return 4;
+}
+
+static int
+bgp_attr_print(u_int atype, const u_char *pptr, u_int len)
+{
+ int i;
+ u_int16_t af;
+ u_int8_t safi, snpa, nhlen;
+ union { /* copy buffer for bandwidth values */
+ float f;
+ u_int32_t i;
+ } bw;
+ int advance;
+ u_int tlen;
+ const u_char *tptr;
+ char buf[MAXHOSTNAMELEN + 100];
+ char tokbuf[TOKBUFSIZE];
+ int as_size;
+
+ tptr = pptr;
+ tlen=len;
+
+ switch (atype) {
+ case BGPTYPE_ORIGIN:
+ if (len != 1)
+ printf("invalid len");
+ else {
+ TCHECK(*tptr);
+ printf("%s", tok2strbuf(bgp_origin_values,
+ "Unknown Origin Typecode",
+ tptr[0],
+ tokbuf, sizeof(tokbuf)));
+ }
+ break;
+
+
+ /*
+ * Process AS4 byte path and AS2 byte path attributes here.
+ */
+ case BGPTYPE_AS4_PATH:
+ case BGPTYPE_AS_PATH:
+ if (len % 2) {
+ printf("invalid len");
+ break;
+ }
+ if (!len) {
+ printf("empty");
+ break;
+ }
+
+ /*
+ * BGP updates exchanged between New speakers that support 4
+ * byte AS, ASs are always encoded in 4 bytes. There is no
+ * definitive way to find this, just by the packet's
+ * contents. So, check for packet's TLV's sanity assuming
+ * 2 bytes first, and it does not pass, assume that ASs are
+ * encoded in 4 bytes format and move on.
+ */
+ as_size = bgp_attr_get_as_size(atype, pptr, len);
+
+ while (tptr < pptr + len) {
+ TCHECK(tptr[0]);
+ printf("%s", tok2strbuf(bgp_as_path_segment_open_values,
+ "?", tptr[0],
+ tokbuf, sizeof(tokbuf)));
+ for (i = 0; i < tptr[1] * as_size; i += as_size) {
+ TCHECK2(tptr[2 + i], as_size);
+ printf("%s ",
+ as_printf(astostr, sizeof(astostr),
+ as_size == 2 ?
+ EXTRACT_16BITS(&tptr[2 + i]) :
+ EXTRACT_32BITS(&tptr[2 + i])));
+ }
+ TCHECK(tptr[0]);
+ printf("%s", tok2strbuf(bgp_as_path_segment_close_values,
+ "?", tptr[0],
+ tokbuf, sizeof(tokbuf)));
+ TCHECK(tptr[1]);
+ tptr += 2 + tptr[1] * as_size;
+ }
+ break;
+ case BGPTYPE_NEXT_HOP:
+ if (len != 4)
+ printf("invalid len");
+ else {
+ TCHECK2(tptr[0], 4);
+ printf("%s", getname(tptr));
+ }
+ break;
+ case BGPTYPE_MULTI_EXIT_DISC:
+ case BGPTYPE_LOCAL_PREF:
+ if (len != 4)
+ printf("invalid len");
+ else {
+ TCHECK2(tptr[0], 4);
+ printf("%u", EXTRACT_32BITS(tptr));
+ }
+ break;
+ case BGPTYPE_ATOMIC_AGGREGATE:
+ if (len != 0)
+ printf("invalid len");
+ break;
+ case BGPTYPE_AGGREGATOR:
+
+ /*
+ * Depending on the AS encoded is of 2 bytes or of 4 bytes,
+ * the length of this PA can be either 6 bytes or 8 bytes.
+ */
+ if (len != 6 && len != 8) {
+ printf("invalid len");
+ break;
+ }
+ TCHECK2(tptr[0], len);
+ if (len == 6) {
+ printf(" AS #%s, origin %s",
+ as_printf(astostr, sizeof(astostr), EXTRACT_16BITS(tptr)),
+ getname(tptr + 2));
+ } else {
+ printf(" AS #%s, origin %s",
+ as_printf(astostr, sizeof(astostr),
+ EXTRACT_32BITS(tptr)), getname(tptr + 4));
+ }
+ break;
+ case BGPTYPE_AGGREGATOR4:
+ if (len != 8) {
+ printf("invalid len");
+ break;
+ }
+ TCHECK2(tptr[0], 8);
+ printf(" AS #%s, origin %s",
+ as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(tptr)),
+ getname(tptr + 4));
+ break;
+ case BGPTYPE_COMMUNITIES:
+ if (len % 4) {
+ printf("invalid len");
+ break;
+ }
+ while (tlen>0) {
+ u_int32_t comm;
+ TCHECK2(tptr[0], 4);
+ comm = EXTRACT_32BITS(tptr);
+ switch (comm) {
+ case BGP_COMMUNITY_NO_EXPORT:
+ printf(" NO_EXPORT");
+ break;
+ case BGP_COMMUNITY_NO_ADVERT:
+ printf(" NO_ADVERTISE");
+ break;
+ case BGP_COMMUNITY_NO_EXPORT_SUBCONFED:
+ printf(" NO_EXPORT_SUBCONFED");
+ break;
+ default:
+ printf("%u:%u%s",
+ (comm >> 16) & 0xffff,
+ comm & 0xffff,
+ (tlen>4) ? ", " : "");
+ break;
+ }
+ tlen -=4;
+ tptr +=4;
+ }
+ break;
+ case BGPTYPE_ORIGINATOR_ID:
+ if (len != 4) {
+ printf("invalid len");
+ break;
+ }
+ TCHECK2(tptr[0], 4);
+ printf("%s",getname(tptr));
+ break;
+ case BGPTYPE_CLUSTER_LIST:
+ if (len % 4) {
+ printf("invalid len");
+ break;
+ }
+ while (tlen>0) {
+ TCHECK2(tptr[0], 4);
+ printf("%s%s",
+ getname(tptr),
+ (tlen>4) ? ", " : "");
+ tlen -=4;
+ tptr +=4;
+ }
+ break;
+ case BGPTYPE_MP_REACH_NLRI:
+ TCHECK2(tptr[0], 3);
+ af = EXTRACT_16BITS(tptr);
+ safi = tptr[2];
+
+ printf("\n\t AFI: %s (%u), %sSAFI: %s (%u)",
+ tok2strbuf(af_values, "Unknown AFI", af,
+ tokbuf, sizeof(tokbuf)),
+ af,
+ (safi>128) ? "vendor specific " : "", /* 128 is meanwhile wellknown */
+ tok2strbuf(bgp_safi_values, "Unknown SAFI", safi,
+ tokbuf, sizeof(tokbuf)),
+ safi);
+
+ switch(af<<8 | safi) {
+ case (AFNUM_INET<<8 | SAFNUM_UNICAST):
+ case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
+ case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
+ case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
+ case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO):
+ case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST):
+ case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST):
+ case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST):
+ case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN):
+ case (AFNUM_INET<<8 | SAFNUM_MDT):
+#ifdef INET6
+ case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
+ case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
+ case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
+ case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
+ case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST):
+ case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST):
+ case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST):
+#endif
+ case (AFNUM_NSAP<<8 | SAFNUM_UNICAST):
+ case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST):
+ case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST):
+ case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST):
+ case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST):
+ case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST):
+ case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST):
+ case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST):
+ case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST):
+ case (AFNUM_VPLS<<8 | SAFNUM_VPLS):
+ break;
+ default:
+ TCHECK2(tptr[0], tlen);
+ printf("\n\t no AFI %u / SAFI %u decoder",af,safi);
+ if (vflag <= 1)
+ print_unknown_data(tptr,"\n\t ",tlen);
+ goto done;
+ break;
+ }
+
+ tptr +=3;
+
+ TCHECK(tptr[0]);
+ nhlen = tptr[0];
+ tlen = nhlen;
+ tptr++;
+
+ if (tlen) {
+ int nnh = 0;
+ printf("\n\t nexthop: ");
+ while (tlen > 0) {
+ if ( nnh++ > 0 ) {
+ printf( ", " );
+ }
+ switch(af<<8 | safi) {
+ case (AFNUM_INET<<8 | SAFNUM_UNICAST):
+ case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
+ case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
+ case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
+ case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO):
+ case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN):
+ case (AFNUM_INET<<8 | SAFNUM_MDT):
+ if (tlen < (int)sizeof(struct in_addr)) {
+ printf("invalid len");
+ tlen = 0;
+ } else {
+ TCHECK2(tptr[0], sizeof(struct in_addr));
+ printf("%s",getname(tptr));
+ tlen -= sizeof(struct in_addr);
+ tptr += sizeof(struct in_addr);
+ }
+ break;
+ case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST):
+ case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST):
+ case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST):
+ if (tlen < (int)(sizeof(struct in_addr)+BGP_VPN_RD_LEN)) {
+ printf("invalid len");
+ tlen = 0;
+ } else {
+ TCHECK2(tptr[0], sizeof(struct in_addr)+BGP_VPN_RD_LEN);
+ printf("RD: %s, %s",
+ bgp_vpn_rd_print(tptr),
+ getname(tptr+BGP_VPN_RD_LEN));
+ tlen -= (sizeof(struct in_addr)+BGP_VPN_RD_LEN);
+ tptr += (sizeof(struct in_addr)+BGP_VPN_RD_LEN);
+ }
+ break;
+#ifdef INET6
+ case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
+ case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
+ case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
+ case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
+ if (tlen < (int)sizeof(struct in6_addr)) {
+ printf("invalid len");
+ tlen = 0;
+ } else {
+ TCHECK2(tptr[0], sizeof(struct in6_addr));
+ printf("%s", getname6(tptr));
+ tlen -= sizeof(struct in6_addr);
+ tptr += sizeof(struct in6_addr);
+ }
+ break;
+ case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST):
+ case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST):
+ case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST):
+ if (tlen < (int)(sizeof(struct in6_addr)+BGP_VPN_RD_LEN)) {
+ printf("invalid len");
+ tlen = 0;
+ } else {
+ TCHECK2(tptr[0], sizeof(struct in6_addr)+BGP_VPN_RD_LEN);
+ printf("RD: %s, %s",
+ bgp_vpn_rd_print(tptr),
+ getname6(tptr+BGP_VPN_RD_LEN));
+ tlen -= (sizeof(struct in6_addr)+BGP_VPN_RD_LEN);
+ tptr += (sizeof(struct in6_addr)+BGP_VPN_RD_LEN);
+ }
+ break;
+#endif
+ case (AFNUM_VPLS<<8 | SAFNUM_VPLS):
+ case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST):
+ case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST):
+ case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST):
+ if (tlen < (int)sizeof(struct in_addr)) {
+ printf("invalid len");
+ tlen = 0;
+ } else {
+ TCHECK2(tptr[0], sizeof(struct in_addr));
+ printf("%s", getname(tptr));
+ tlen -= (sizeof(struct in_addr));
+ tptr += (sizeof(struct in_addr));
+ }
+ break;
+ case (AFNUM_NSAP<<8 | SAFNUM_UNICAST):
+ case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST):
+ case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST):
+ TCHECK2(tptr[0], tlen);
+ printf("%s",isonsap_string(tptr,tlen));
+ tptr += tlen;
+ tlen = 0;
+ break;
+
+ case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST):
+ case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST):
+ case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST):
+ if (tlen < BGP_VPN_RD_LEN+1) {
+ printf("invalid len");
+ tlen = 0;
+ } else {
+ TCHECK2(tptr[0], tlen);
+ printf("RD: %s, %s",
+ bgp_vpn_rd_print(tptr),
+ isonsap_string(tptr+BGP_VPN_RD_LEN,tlen-BGP_VPN_RD_LEN));
+ /* rfc986 mapped IPv4 address ? */
+ if (EXTRACT_32BITS(tptr+BGP_VPN_RD_LEN) == 0x47000601)
+ printf(" = %s", getname(tptr+BGP_VPN_RD_LEN+4));
+#ifdef INET6
+ /* rfc1888 mapped IPv6 address ? */
+ else if (EXTRACT_24BITS(tptr+BGP_VPN_RD_LEN) == 0x350000)
+ printf(" = %s", getname6(tptr+BGP_VPN_RD_LEN+3));
+#endif
+ tptr += tlen;
+ tlen = 0;
+ }
+ break;
+ default:
+ TCHECK2(tptr[0], tlen);
+ printf("no AFI %u/SAFI %u decoder",af,safi);
+ if (vflag <= 1)
+ print_unknown_data(tptr,"\n\t ",tlen);
+ tptr += tlen;
+ tlen = 0;
+ goto done;
+ break;
+ }
+ }
+ }
+ printf(", nh-length: %u", nhlen);
+ tptr += tlen;
+
+ TCHECK(tptr[0]);
+ snpa = tptr[0];
+ tptr++;
+
+ if (snpa) {
+ printf("\n\t %u SNPA", snpa);
+ for (/*nothing*/; snpa > 0; snpa--) {
+ TCHECK(tptr[0]);
+ printf("\n\t %d bytes", tptr[0]);
+ tptr += tptr[0] + 1;
+ }
+ } else {
+ printf(", no SNPA");
+ }
+
+ while (len - (tptr - pptr) > 0) {
+ switch (af<<8 | safi) {
+ case (AFNUM_INET<<8 | SAFNUM_UNICAST):
+ case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
+ case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
+ advance = decode_prefix4(tptr, len, buf, sizeof(buf));
+ if (advance == -1)
+ printf("\n\t (illegal prefix length)");
+ else if (advance == -2)
+ goto trunc;
+ else if (advance == -3)
+ break; /* bytes left, but not enough */
+ else
+ printf("\n\t %s", buf);
+ break;
+ case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
+ advance = decode_labeled_prefix4(tptr, len, buf, sizeof(buf));
+ if (advance == -1)
+ printf("\n\t (illegal prefix length)");
+ else if (advance == -2)
+ goto trunc;
+ else if (advance == -3)
+ break; /* bytes left, but not enough */
+ else
+ printf("\n\t %s", buf);
+ break;
+ case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST):
+ case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST):
+ case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST):
+ advance = decode_labeled_vpn_prefix4(tptr, buf, sizeof(buf));
+ if (advance == -1)
+ printf("\n\t (illegal prefix length)");
+ else if (advance == -2)
+ goto trunc;
+ else
+ printf("\n\t %s", buf);
+ break;
+ case (AFNUM_INET<<8 | SAFNUM_RT_ROUTING_INFO):
+ advance = decode_rt_routing_info(tptr, buf, sizeof(buf));
+ if (advance == -1)
+ printf("\n\t (illegal prefix length)");
+ else if (advance == -2)
+ goto trunc;
+ else
+ printf("\n\t %s", buf);
+ break;
+ case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): /* fall through */
+ case (AFNUM_INET6<<8 | SAFNUM_MULTICAST_VPN):
+ advance = decode_multicast_vpn(tptr, buf, sizeof(buf));
+ if (advance == -1)
+ printf("\n\t (illegal prefix length)");
+ else if (advance == -2)
+ goto trunc;
+ else
+ printf("\n\t %s", buf);
+ break;
+
+ case (AFNUM_INET<<8 | SAFNUM_MDT):
+ advance = decode_mdt_vpn_nlri(tptr, buf, sizeof(buf));
+ if (advance == -1)
+ printf("\n\t (illegal prefix length)");
+ else if (advance == -2)
+ goto trunc;
+ else
+ printf("\n\t %s", buf);
+ break;
+#ifdef INET6
+ case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
+ case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
+ case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
+ advance = decode_prefix6(tptr, len, buf, sizeof(buf));
+ if (advance == -1)
+ printf("\n\t (illegal prefix length)");
+ else if (advance == -2)
+ goto trunc;
+ else if (advance == -3)
+ break; /* bytes left, but not enough */
+ else
+ printf("\n\t %s", buf);
+ break;
+ case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
+ advance = decode_labeled_prefix6(tptr, len, buf, sizeof(buf));
+ if (advance == -1)
+ printf("\n\t (illegal prefix length)");
+ else if (advance == -2)
+ goto trunc;
+ else if (advance == -3)
+ break; /* bytes left, but not enough */
+ else
+ printf("\n\t %s", buf);
+ break;
+ case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST):
+ case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST):
+ case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST):
+ advance = decode_labeled_vpn_prefix6(tptr, buf, sizeof(buf));
+ if (advance == -1)
+ printf("\n\t (illegal prefix length)");
+ else if (advance == -2)
+ goto trunc;
+ else
+ printf("\n\t %s", buf);
+ break;
+#endif
+ case (AFNUM_VPLS<<8 | SAFNUM_VPLS):
+ case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST):
+ case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST):
+ case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST):
+ advance = decode_labeled_vpn_l2(tptr, buf, sizeof(buf));
+ if (advance == -1)
+ printf("\n\t (illegal length)");
+ else if (advance == -2)
+ goto trunc;
+ else
+ printf("\n\t %s", buf);
+ break;
+ case (AFNUM_NSAP<<8 | SAFNUM_UNICAST):
+ case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST):
+ case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST):
+ advance = decode_clnp_prefix(tptr, buf, sizeof(buf));
+ if (advance == -1)
+ printf("\n\t (illegal prefix length)");
+ else if (advance == -2)
+ goto trunc;
+ else
+ printf("\n\t %s", buf);
+ break;
+ case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST):
+ case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST):
+ case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST):
+ advance = decode_labeled_vpn_clnp_prefix(tptr, buf, sizeof(buf));
+ if (advance == -1)
+ printf("\n\t (illegal prefix length)");
+ else if (advance == -2)
+ goto trunc;
+ else
+ printf("\n\t %s", buf);
+ break;
+ default:
+ TCHECK2(*tptr,tlen);
+ printf("\n\t no AFI %u / SAFI %u decoder",af,safi);
+ if (vflag <= 1)
+ print_unknown_data(tptr,"\n\t ",tlen);
+ advance = 0;
+ tptr = pptr + len;
+ break;
+ }
+ if (advance < 0)
+ break;
+ tptr += advance;
+ }
+ done:
+ break;
+
+ case BGPTYPE_MP_UNREACH_NLRI:
+ TCHECK2(tptr[0], BGP_MP_NLRI_MINSIZE);
+ af = EXTRACT_16BITS(tptr);
+ safi = tptr[2];
+
+ printf("\n\t AFI: %s (%u), %sSAFI: %s (%u)",
+ tok2strbuf(af_values, "Unknown AFI", af,
+ tokbuf, sizeof(tokbuf)),
+ af,
+ (safi>128) ? "vendor specific " : "", /* 128 is meanwhile wellknown */
+ tok2strbuf(bgp_safi_values, "Unknown SAFI", safi,
+ tokbuf, sizeof(tokbuf)),
+ safi);
+
+ if (len == BGP_MP_NLRI_MINSIZE)
+ printf("\n\t End-of-Rib Marker (empty NLRI)");
+
+ tptr += 3;
+
+ while (len - (tptr - pptr) > 0) {
+ switch (af<<8 | safi) {
+ case (AFNUM_INET<<8 | SAFNUM_UNICAST):
+ case (AFNUM_INET<<8 | SAFNUM_MULTICAST):
+ case (AFNUM_INET<<8 | SAFNUM_UNIMULTICAST):
+ advance = decode_prefix4(tptr, len, buf, sizeof(buf));
+ if (advance == -1)
+ printf("\n\t (illegal prefix length)");
+ else if (advance == -2)
+ goto trunc;
+ else if (advance == -3)
+ break; /* bytes left, but not enough */
+ else
+ printf("\n\t %s", buf);
+ break;
+ case (AFNUM_INET<<8 | SAFNUM_LABUNICAST):
+ advance = decode_labeled_prefix4(tptr, len, buf, sizeof(buf));
+ if (advance == -1)
+ printf("\n\t (illegal prefix length)");
+ else if (advance == -2)
+ goto trunc;
+ else if (advance == -3)
+ break; /* bytes left, but not enough */
+ else
+ printf("\n\t %s", buf);
+ break;
+ case (AFNUM_INET<<8 | SAFNUM_VPNUNICAST):
+ case (AFNUM_INET<<8 | SAFNUM_VPNMULTICAST):
+ case (AFNUM_INET<<8 | SAFNUM_VPNUNIMULTICAST):
+ advance = decode_labeled_vpn_prefix4(tptr, buf, sizeof(buf));
+ if (advance == -1)
+ printf("\n\t (illegal prefix length)");
+ else if (advance == -2)
+ goto trunc;
+ else
+ printf("\n\t %s", buf);
+ break;
+#ifdef INET6
+ case (AFNUM_INET6<<8 | SAFNUM_UNICAST):
+ case (AFNUM_INET6<<8 | SAFNUM_MULTICAST):
+ case (AFNUM_INET6<<8 | SAFNUM_UNIMULTICAST):
+ advance = decode_prefix6(tptr, len, buf, sizeof(buf));
+ if (advance == -1)
+ printf("\n\t (illegal prefix length)");
+ else if (advance == -2)
+ goto trunc;
+ else if (advance == -3)
+ break; /* bytes left, but not enough */
+ else
+ printf("\n\t %s", buf);
+ break;
+ case (AFNUM_INET6<<8 | SAFNUM_LABUNICAST):
+ advance = decode_labeled_prefix6(tptr, len, buf, sizeof(buf));
+ if (advance == -1)
+ printf("\n\t (illegal prefix length)");
+ else if (advance == -2)
+ goto trunc;
+ else if (advance == -3)
+ break; /* bytes left, but not enough */
+ else
+ printf("\n\t %s", buf);
+ break;
+ case (AFNUM_INET6<<8 | SAFNUM_VPNUNICAST):
+ case (AFNUM_INET6<<8 | SAFNUM_VPNMULTICAST):
+ case (AFNUM_INET6<<8 | SAFNUM_VPNUNIMULTICAST):
+ advance = decode_labeled_vpn_prefix6(tptr, buf, sizeof(buf));
+ if (advance == -1)
+ printf("\n\t (illegal prefix length)");
+ else if (advance == -2)
+ goto trunc;
+ else
+ printf("\n\t %s", buf);
+ break;
+#endif
+ case (AFNUM_VPLS<<8 | SAFNUM_VPLS):
+ case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNICAST):
+ case (AFNUM_L2VPN<<8 | SAFNUM_VPNMULTICAST):
+ case (AFNUM_L2VPN<<8 | SAFNUM_VPNUNIMULTICAST):
+ advance = decode_labeled_vpn_l2(tptr, buf, sizeof(buf));
+ if (advance == -1)
+ printf("\n\t (illegal length)");
+ else if (advance == -2)
+ goto trunc;
+ else
+ printf("\n\t %s", buf);
+ break;
+ case (AFNUM_NSAP<<8 | SAFNUM_UNICAST):
+ case (AFNUM_NSAP<<8 | SAFNUM_MULTICAST):
+ case (AFNUM_NSAP<<8 | SAFNUM_UNIMULTICAST):
+ advance = decode_clnp_prefix(tptr, buf, sizeof(buf));
+ if (advance == -1)
+ printf("\n\t (illegal prefix length)");
+ else if (advance == -2)
+ goto trunc;
+ else
+ printf("\n\t %s", buf);
+ break;
+ case (AFNUM_NSAP<<8 | SAFNUM_VPNUNICAST):
+ case (AFNUM_NSAP<<8 | SAFNUM_VPNMULTICAST):
+ case (AFNUM_NSAP<<8 | SAFNUM_VPNUNIMULTICAST):
+ advance = decode_labeled_vpn_clnp_prefix(tptr, buf, sizeof(buf));
+ if (advance == -1)
+ printf("\n\t (illegal prefix length)");
+ else if (advance == -2)
+ goto trunc;
+ else
+ printf("\n\t %s", buf);
+ break;
+ case (AFNUM_INET<<8 | SAFNUM_MDT):
+ advance = decode_mdt_vpn_nlri(tptr, buf, sizeof(buf));
+ if (advance == -1)
+ printf("\n\t (illegal prefix length)");
+ else if (advance == -2)
+ goto trunc;
+ else
+ printf("\n\t %s", buf);
+ break;
+ case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): /* fall through */
+ case (AFNUM_INET6<<8 | SAFNUM_MULTICAST_VPN):
+ advance = decode_multicast_vpn(tptr, buf, sizeof(buf));
+ if (advance == -1)
+ printf("\n\t (illegal prefix length)");
+ else if (advance == -2)
+ goto trunc;
+ else
+ printf("\n\t %s", buf);
+ break;
+ default:
+ TCHECK2(*(tptr-3),tlen);
+ printf("no AFI %u / SAFI %u decoder",af,safi);
+ if (vflag <= 1)
+ print_unknown_data(tptr-3,"\n\t ",tlen);
+ advance = 0;
+ tptr = pptr + len;
+ break;
+ }
+ if (advance < 0)
+ break;
+ tptr += advance;
+ }
+ break;
+ case BGPTYPE_EXTD_COMMUNITIES:
+ if (len % 8) {
+ printf("invalid len");
+ break;
+ }
+ while (tlen>0) {
+ u_int16_t extd_comm;
+
+ TCHECK2(tptr[0], 2);
+ extd_comm=EXTRACT_16BITS(tptr);
+
+ printf("\n\t %s (0x%04x), Flags [%s]",
+ tok2strbuf(bgp_extd_comm_subtype_values,
+ "unknown extd community typecode",
+ extd_comm, tokbuf, sizeof(tokbuf)),
+ extd_comm,
+ bittok2str(bgp_extd_comm_flag_values, "none", extd_comm));
+
+ TCHECK2(*(tptr+2), 6);
+ switch(extd_comm) {
+ case BGP_EXT_COM_RT_0:
+ case BGP_EXT_COM_RO_0:
+ case BGP_EXT_COM_L2VPN_RT_0:
+ printf(": %u:%u (= %s)",
+ EXTRACT_16BITS(tptr+2),
+ EXTRACT_32BITS(tptr+4),
+ getname(tptr+4));
+ break;
+ case BGP_EXT_COM_RT_1:
+ case BGP_EXT_COM_RO_1:
+ case BGP_EXT_COM_L2VPN_RT_1:
+ case BGP_EXT_COM_VRF_RT_IMP:
+ printf(": %s:%u",
+ getname(tptr+2),
+ EXTRACT_16BITS(tptr+6));
+ break;
+ case BGP_EXT_COM_RT_2:
+ case BGP_EXT_COM_RO_2:
+ printf(": %s:%u",
+ as_printf(astostr, sizeof(astostr),
+ EXTRACT_32BITS(tptr+2)), EXTRACT_16BITS(tptr+6));
+ break;
+ case BGP_EXT_COM_LINKBAND:
+ bw.i = EXTRACT_32BITS(tptr+2);
+ printf(": bandwidth: %.3f Mbps",
+ bw.f*8/1000000);
+ break;
+ case BGP_EXT_COM_VPN_ORIGIN:
+ case BGP_EXT_COM_VPN_ORIGIN2:
+ case BGP_EXT_COM_VPN_ORIGIN3:
+ case BGP_EXT_COM_VPN_ORIGIN4:
+ case BGP_EXT_COM_OSPF_RID:
+ case BGP_EXT_COM_OSPF_RID2:
+ printf("%s", getname(tptr+2));
+ break;
+ case BGP_EXT_COM_OSPF_RTYPE:
+ case BGP_EXT_COM_OSPF_RTYPE2:
+ printf(": area:%s, router-type:%s, metric-type:%s%s",
+ getname(tptr+2),
+ tok2strbuf(bgp_extd_comm_ospf_rtype_values,
+ "unknown (0x%02x)",
+ *(tptr+6),
+ tokbuf, sizeof(tokbuf)),
+ (*(tptr+7) & BGP_OSPF_RTYPE_METRIC_TYPE) ? "E2" : "",
+ ((*(tptr+6) == BGP_OSPF_RTYPE_EXT) || (*(tptr+6) == BGP_OSPF_RTYPE_NSSA)) ? "E1" : "");
+ break;
+ case BGP_EXT_COM_L2INFO:
+ printf(": %s Control Flags [0x%02x]:MTU %u",
+ tok2strbuf(l2vpn_encaps_values,
+ "unknown encaps",
+ *(tptr+2),
+ tokbuf, sizeof(tokbuf)),
+ *(tptr+3),
+ EXTRACT_16BITS(tptr+4));
+ break;
+ case BGP_EXT_COM_SOURCE_AS:
+ printf(": AS %u", EXTRACT_16BITS(tptr+2));
+ break;
+ default:
+ TCHECK2(*tptr,8);
+ print_unknown_data(tptr,"\n\t ",8);
+ break;
+ }
+ tlen -=8;
+ tptr +=8;
+ }
+ break;
+
+ case BGPTYPE_PMSI_TUNNEL:
+ {
+ u_int8_t tunnel_type, flags;
+
+ tunnel_type = *(tptr+1);
+ flags = *tptr;
+ tlen = len;
+
+ TCHECK2(tptr[0], 5);
+ printf("\n\t Tunnel-type %s (%u), Flags [%s], MPLS Label %u",
+ tok2str(bgp_pmsi_tunnel_values, "Unknown", tunnel_type),
+ tunnel_type,
+ bittok2str(bgp_pmsi_flag_values, "none", flags),
+ EXTRACT_24BITS(tptr+2)>>4);
+
+ tptr +=5;
+ tlen -= 5;
+
+ switch (tunnel_type) {
+ case BGP_PMSI_TUNNEL_PIM_SM: /* fall through */
+ case BGP_PMSI_TUNNEL_PIM_BIDIR:
+ TCHECK2(tptr[0], 8);
+ printf("\n\t Sender %s, P-Group %s",
+ ipaddr_string(tptr),
+ ipaddr_string(tptr+4));
+ break;
+
+ case BGP_PMSI_TUNNEL_PIM_SSM:
+ TCHECK2(tptr[0], 8);
+ printf("\n\t Root-Node %s, P-Group %s",
+ ipaddr_string(tptr),
+ ipaddr_string(tptr+4));
+ break;
+ case BGP_PMSI_TUNNEL_INGRESS:
+ TCHECK2(tptr[0], 4);
+ printf("\n\t Tunnel-Endpoint %s",
+ ipaddr_string(tptr));
+ break;
+ case BGP_PMSI_TUNNEL_LDP_P2MP: /* fall through */
+ case BGP_PMSI_TUNNEL_LDP_MP2MP:
+ TCHECK2(tptr[0], 8);
+ printf("\n\t Root-Node %s, LSP-ID 0x%08x",
+ ipaddr_string(tptr),
+ EXTRACT_32BITS(tptr+4));
+ break;
+ case BGP_PMSI_TUNNEL_RSVP_P2MP:
+ TCHECK2(tptr[0], 8);
+ printf("\n\t Extended-Tunnel-ID %s, P2MP-ID 0x%08x",
+ ipaddr_string(tptr),
+ EXTRACT_32BITS(tptr+4));
+ break;
+ default:
+ if (vflag <= 1) {
+ print_unknown_data(tptr,"\n\t ",tlen);
+ }
+ }
+ break;
+ }
+ case BGPTYPE_ATTR_SET:
+ TCHECK2(tptr[0], 4);
+ if (len < 4)
+ goto trunc;
+ printf("\n\t Origin AS: %s",
+ as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(tptr)));
+ tptr+=4;
+ len -=4;
+
+ while (len) {
+ u_int aflags, atype, alenlen, alen;
+
+ TCHECK2(tptr[0], 2);
+ if (len < 2)
+ goto trunc;
+ aflags = *tptr;
+ atype = *(tptr + 1);
+ tptr += 2;
+ len -= 2;
+ alenlen = bgp_attr_lenlen(aflags, tptr);
+ TCHECK2(tptr[0], alenlen);
+ if (len < alenlen)
+ goto trunc;
+ alen = bgp_attr_len(aflags, tptr);
+ tptr += alenlen;
+ len -= alenlen;
+
+ printf("\n\t %s (%u), length: %u",
+ tok2strbuf(bgp_attr_values,
+ "Unknown Attribute", atype,
+ tokbuf, sizeof(tokbuf)),
+ atype,
+ alen);
+
+ if (aflags) {
+ printf(", Flags [%s%s%s%s",
+ aflags & 0x80 ? "O" : "",
+ aflags & 0x40 ? "T" : "",
+ aflags & 0x20 ? "P" : "",
+ aflags & 0x10 ? "E" : "");
+ if (aflags & 0xf)
+ printf("+%x", aflags & 0xf);
+ printf("]: ");
+ }
+ /* FIXME check for recursion */
+ if (!bgp_attr_print(atype, tptr, alen))
+ return 0;
+ tptr += alen;
+ len -= alen;
+ }
+ break;
+
+
+ default:
+ TCHECK2(*pptr,len);
+ printf("\n\t no Attribute %u decoder",atype); /* we have no decoder for the attribute */
+ if (vflag <= 1)
+ print_unknown_data(pptr,"\n\t ",len);
+ break;
+ }
+ if (vflag > 1 && len) { /* omit zero length attributes*/
+ TCHECK2(*pptr,len);
+ print_unknown_data(pptr,"\n\t ",len);
+ }
+ return 1;
+
+trunc:
+ return 0;
+}
+
+static void
+bgp_capabilities_print(const u_char *opt, int caps_len)
+{
+ char tokbuf[TOKBUFSIZE];
+ char tokbuf2[TOKBUFSIZE];
+ int cap_type, cap_len, tcap_len, cap_offset;
+ int i = 0;
+
+ while (i < caps_len) {
+ TCHECK2(opt[i], BGP_CAP_HEADER_SIZE);
+ cap_type=opt[i];
+ cap_len=opt[i+1];
+ tcap_len=cap_len;
+ printf("\n\t %s (%u), length: %u",
+ tok2strbuf(bgp_capcode_values, "Unknown",
+ cap_type, tokbuf, sizeof(tokbuf)),
+ cap_type,
+ cap_len);
+ TCHECK2(opt[i+2], cap_len);
+ switch (cap_type) {
+ case BGP_CAPCODE_MP:
+ printf("\n\t\tAFI %s (%u), SAFI %s (%u)",
+ tok2strbuf(af_values, "Unknown",
+ EXTRACT_16BITS(opt+i+2),
+ tokbuf, sizeof(tokbuf)),
+ EXTRACT_16BITS(opt+i+2),
+ tok2strbuf(bgp_safi_values, "Unknown",
+ opt[i+5],
+ tokbuf, sizeof(tokbuf)),
+ opt[i+5]);
+ break;
+ case BGP_CAPCODE_RESTART:
+ printf("\n\t\tRestart Flags: [%s], Restart Time %us",
+ ((opt[i+2])&0x80) ? "R" : "none",
+ EXTRACT_16BITS(opt+i+2)&0xfff);
+ tcap_len-=2;
+ cap_offset=4;
+ while(tcap_len>=4) {
+ printf("\n\t\t AFI %s (%u), SAFI %s (%u), Forwarding state preserved: %s",
+ tok2strbuf(af_values,"Unknown",
+ EXTRACT_16BITS(opt+i+cap_offset),
+ tokbuf, sizeof(tokbuf)),
+ EXTRACT_16BITS(opt+i+cap_offset),
+ tok2strbuf(bgp_safi_values,"Unknown",
+ opt[i+cap_offset+2],
+ tokbuf2, sizeof(tokbuf2)),
+ opt[i+cap_offset+2],
+ ((opt[i+cap_offset+3])&0x80) ? "yes" : "no" );
+ tcap_len-=4;
+ cap_offset+=4;
+ }
+ break;
+ case BGP_CAPCODE_RR:
+ case BGP_CAPCODE_RR_CISCO:
+ break;
+ case BGP_CAPCODE_AS_NEW:
+
+ /*
+ * Extract the 4 byte AS number encoded.
+ */
+ if (cap_len == 4) {
+ printf("\n\t\t 4 Byte AS %s",
+ as_printf(astostr, sizeof(astostr),
+ EXTRACT_32BITS(opt + i + 2)));
+ }
+ break;
+ default:
+ printf("\n\t\tno decoder for Capability %u",
+ cap_type);
+ if (vflag <= 1)
+ print_unknown_data(&opt[i+2],"\n\t\t",cap_len);
+ break;
+ }
+ if (vflag > 1 && cap_len > 0) {
+ print_unknown_data(&opt[i+2],"\n\t\t",cap_len);
+ }
+ i += BGP_CAP_HEADER_SIZE + cap_len;
+ }
+ return;
+
+trunc:
+ printf("[|BGP]");
+}
+
+static void
+bgp_open_print(const u_char *dat, int length)
+{
+ struct bgp_open bgpo;
+ struct bgp_opt bgpopt;
+ const u_char *opt;
+ int i;
+ char tokbuf[TOKBUFSIZE];
+
+ TCHECK2(dat[0], BGP_OPEN_SIZE);
+ memcpy(&bgpo, dat, BGP_OPEN_SIZE);
+
+ printf("\n\t Version %d, ", bgpo.bgpo_version);
+ printf("my AS %s, ",
+ as_printf(astostr, sizeof(astostr), ntohs(bgpo.bgpo_myas)));
+ printf("Holdtime %us, ", ntohs(bgpo.bgpo_holdtime));
+ printf("ID %s", getname((u_char *)&bgpo.bgpo_id));
+ printf("\n\t Optional parameters, length: %u", bgpo.bgpo_optlen);
+
+ /* some little sanity checking */
+ if (length < bgpo.bgpo_optlen+BGP_OPEN_SIZE)
+ return;
+
+ /* ugly! */
+ opt = &((const struct bgp_open *)dat)->bgpo_optlen;
+ opt++;
+
+ i = 0;
+ while (i < bgpo.bgpo_optlen) {
+ TCHECK2(opt[i], BGP_OPT_SIZE);
+ memcpy(&bgpopt, &opt[i], BGP_OPT_SIZE);
+ if (i + 2 + bgpopt.bgpopt_len > bgpo.bgpo_optlen) {
+ printf("\n\t Option %d, length: %u", bgpopt.bgpopt_type, bgpopt.bgpopt_len);
+ break;
+ }
+
+ printf("\n\t Option %s (%u), length: %u",
+ tok2strbuf(bgp_opt_values,"Unknown",
+ bgpopt.bgpopt_type,
+ tokbuf, sizeof(tokbuf)),
+ bgpopt.bgpopt_type,
+ bgpopt.bgpopt_len);
+
+ /* now let's decode the options we know*/
+ switch(bgpopt.bgpopt_type) {
+
+ case BGP_OPT_CAP:
+ bgp_capabilities_print(&opt[i+BGP_OPT_SIZE],
+ bgpopt.bgpopt_len);
+ break;
+
+ case BGP_OPT_AUTH:
+ default:
+ printf("\n\t no decoder for option %u",
+ bgpopt.bgpopt_type);
+ break;
+ }
+ i += BGP_OPT_SIZE + bgpopt.bgpopt_len;
+ }
+ return;
+trunc:
+ printf("[|BGP]");
+}
+
+static void
+bgp_update_print(const u_char *dat, int length)
+{
+ struct bgp bgp;
+ const u_char *p;
+ int withdrawn_routes_len;
+ int len;
+ int i;
+ char tokbuf[TOKBUFSIZE];
+#ifndef INET6
+ char buf[MAXHOSTNAMELEN + 100];
+ int wpfx;
+#endif
+
+ TCHECK2(dat[0], BGP_SIZE);
+ if (length < BGP_SIZE)
+ goto trunc;
+ memcpy(&bgp, dat, BGP_SIZE);
+ p = dat + BGP_SIZE; /*XXX*/
+ length -= BGP_SIZE;
+
+ /* Unfeasible routes */
+ TCHECK2(p[0], 2);
+ if (length < 2)
+ goto trunc;
+ withdrawn_routes_len = EXTRACT_16BITS(p);
+ p += 2;
+ length -= 2;
+ if (withdrawn_routes_len) {
+ /*
+ * Without keeping state from the original NLRI message,
+ * it's not possible to tell if this a v4 or v6 route,
+ * so only try to decode it if we're not v6 enabled.
+ */
+ TCHECK2(p[0], withdrawn_routes_len);
+ if (length < withdrawn_routes_len)
+ goto trunc;
+#ifdef INET6
+ printf("\n\t Withdrawn routes: %d bytes", withdrawn_routes_len);
+ p += withdrawn_routes_len;
+ length -= withdrawn_routes_len;
+#else
+ if (withdrawn_routes_len < 2)
+ goto trunc;
+ length -= 2;
+ withdrawn_routes_len -= 2;
+
+
+ printf("\n\t Withdrawn routes:");
+
+ while(withdrawn_routes_len > 0) {
+ wpfx = decode_prefix4(p, withdrawn_routes_len, buf, sizeof(buf));
+ if (wpfx == -1) {
+ printf("\n\t (illegal prefix length)");
+ break;
+ } else if (wpfx == -2)
+ goto trunc;
+ else if (wpfx == -3)
+ goto trunc; /* bytes left, but not enough */
+ else {
+ printf("\n\t %s", buf);
+ p += wpfx;
+ length -= wpfx;
+ withdrawn_routes_len -= wpfx;
+ }
+ }
+#endif
+ }
+
+ TCHECK2(p[0], 2);
+ if (length < 2)
+ goto trunc;
+ len = EXTRACT_16BITS(p);
+ p += 2;
+ length -= 2;
+
+ if (withdrawn_routes_len == 0 && len == 0 && length == 0) {
+ /* No withdrawn routes, no path attributes, no NLRI */
+ printf("\n\t End-of-Rib Marker (empty NLRI)");
+ return;
+ }
+
+ if (len) {
+ /* do something more useful!*/
+ while (len) {
+ int aflags, atype, alenlen, alen;
+
+ TCHECK2(p[0], 2);
+ if (len < 2)
+ goto trunc;
+ if (length < 2)
+ goto trunc;
+ aflags = *p;
+ atype = *(p + 1);
+ p += 2;
+ len -= 2;
+ length -= 2;
+ alenlen = bgp_attr_lenlen(aflags, p);
+ TCHECK2(p[0], alenlen);
+ if (len < alenlen)
+ goto trunc;
+ if (length < alenlen)
+ goto trunc;
+ alen = bgp_attr_len(aflags, p);
+ p += alenlen;
+ len -= alenlen;
+ length -= alenlen;
+
+ printf("\n\t %s (%u), length: %u",
+ tok2strbuf(bgp_attr_values, "Unknown Attribute",
+ atype,
+ tokbuf, sizeof(tokbuf)),
+ atype,
+ alen);
+
+ if (aflags) {
+ printf(", Flags [%s%s%s%s",
+ aflags & 0x80 ? "O" : "",
+ aflags & 0x40 ? "T" : "",
+ aflags & 0x20 ? "P" : "",
+ aflags & 0x10 ? "E" : "");
+ if (aflags & 0xf)
+ printf("+%x", aflags & 0xf);
+ printf("]: ");
+ }
+ if (len < alen)
+ goto trunc;
+ if (length < alen)
+ goto trunc;
+ if (!bgp_attr_print(atype, p, alen))
+ goto trunc;
+ p += alen;
+ len -= alen;
+ length -= alen;
+ }
+ }
+
+ if (length) {
+ /*
+ * XXX - what if they're using the "Advertisement of
+ * Multiple Paths in BGP" feature:
+ *
+ * https://datatracker.ietf.org/doc/draft-ietf-idr-add-paths/
+ *
+ * http://tools.ietf.org/html/draft-ietf-idr-add-paths-06
+ */
+ printf("\n\t Updated routes:");
+ while (length) {
+ char buf[MAXHOSTNAMELEN + 100];
+ i = decode_prefix4(p, length, buf, sizeof(buf));
+ if (i == -1) {
+ printf("\n\t (illegal prefix length)");
+ break;
+ } else if (i == -2)
+ goto trunc;
+ else if (i == -3)
+ goto trunc; /* bytes left, but not enough */
+ else {
+ printf("\n\t %s", buf);
+ p += i;
+ length -= i;
+ }
+ }
+ }
+ return;
+trunc:
+ printf("[|BGP]");
+}
+
+static void
+bgp_notification_print(const u_char *dat, int length)
+{
+ struct bgp_notification bgpn;
+ const u_char *tptr;
+ char tokbuf[TOKBUFSIZE];
+ char tokbuf2[TOKBUFSIZE];
+
+ TCHECK2(dat[0], BGP_NOTIFICATION_SIZE);
+ memcpy(&bgpn, dat, BGP_NOTIFICATION_SIZE);
+
+ /* some little sanity checking */
+ if (length<BGP_NOTIFICATION_SIZE)
+ return;
+
+ printf(", %s (%u)",
+ tok2strbuf(bgp_notify_major_values, "Unknown Error",
+ bgpn.bgpn_major, tokbuf, sizeof(tokbuf)),
+ bgpn.bgpn_major);
+
+ switch (bgpn.bgpn_major) {
+
+ case BGP_NOTIFY_MAJOR_MSG:
+ printf(", subcode %s (%u)",
+ tok2strbuf(bgp_notify_minor_msg_values, "Unknown",
+ bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)),
+ bgpn.bgpn_minor);
+ break;
+ case BGP_NOTIFY_MAJOR_OPEN:
+ printf(", subcode %s (%u)",
+ tok2strbuf(bgp_notify_minor_open_values, "Unknown",
+ bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)),
+ bgpn.bgpn_minor);
+ break;
+ case BGP_NOTIFY_MAJOR_UPDATE:
+ printf(", subcode %s (%u)",
+ tok2strbuf(bgp_notify_minor_update_values, "Unknown",
+ bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)),
+ bgpn.bgpn_minor);
+ break;
+ case BGP_NOTIFY_MAJOR_CAP:
+ printf(" subcode %s (%u)",
+ tok2strbuf(bgp_notify_minor_cap_values, "Unknown",
+ bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)),
+ bgpn.bgpn_minor);
+ case BGP_NOTIFY_MAJOR_CEASE:
+ printf(", subcode %s (%u)",
+ tok2strbuf(bgp_notify_minor_cease_values, "Unknown",
+ bgpn.bgpn_minor, tokbuf, sizeof(tokbuf)),
+ bgpn.bgpn_minor);
+
+ /* draft-ietf-idr-cease-subcode-02 mentions optionally 7 bytes
+ * for the maxprefix subtype, which may contain AFI, SAFI and MAXPREFIXES
+ */
+ if(bgpn.bgpn_minor == BGP_NOTIFY_MINOR_CEASE_MAXPRFX && length >= BGP_NOTIFICATION_SIZE + 7) {
+ tptr = dat + BGP_NOTIFICATION_SIZE;
+ TCHECK2(*tptr, 7);
+ printf(", AFI %s (%u), SAFI %s (%u), Max Prefixes: %u",
+ tok2strbuf(af_values, "Unknown",
+ EXTRACT_16BITS(tptr), tokbuf, sizeof(tokbuf)),
+ EXTRACT_16BITS(tptr),
+ tok2strbuf(bgp_safi_values, "Unknown", *(tptr+2),
+ tokbuf2, sizeof(tokbuf)),
+ *(tptr+2),
+ EXTRACT_32BITS(tptr+3));
+ }
+ break;
+ default:
+ break;
+ }
+
+ return;
+trunc:
+ printf("[|BGP]");
+}
+
+static void
+bgp_route_refresh_print(const u_char *pptr, int len) {
+
+ const struct bgp_route_refresh *bgp_route_refresh_header;
+ char tokbuf[TOKBUFSIZE];
+ char tokbuf2[TOKBUFSIZE];
+
+ TCHECK2(pptr[0], BGP_ROUTE_REFRESH_SIZE);
+
+ /* some little sanity checking */
+ if (len<BGP_ROUTE_REFRESH_SIZE)
+ return;
+
+ bgp_route_refresh_header = (const struct bgp_route_refresh *)pptr;
+
+ printf("\n\t AFI %s (%u), SAFI %s (%u)",
+ tok2strbuf(af_values,"Unknown",
+ /* this stinks but the compiler pads the structure
+ * weird */
+ EXTRACT_16BITS(&bgp_route_refresh_header->afi),
+ tokbuf, sizeof(tokbuf)),
+ EXTRACT_16BITS(&bgp_route_refresh_header->afi),
+ tok2strbuf(bgp_safi_values,"Unknown",
+ bgp_route_refresh_header->safi,
+ tokbuf2, sizeof(tokbuf2)),
+ bgp_route_refresh_header->safi);
+
+ if (vflag > 1) {
+ TCHECK2(*pptr, len);
+ print_unknown_data(pptr,"\n\t ", len);
+ }
+
+ return;
+trunc:
+ printf("[|BGP]");
+}
+
+static int
+bgp_header_print(const u_char *dat, int length)
+{
+ struct bgp bgp;
+ char tokbuf[TOKBUFSIZE];
+
+ TCHECK2(dat[0], BGP_SIZE);
+ memcpy(&bgp, dat, BGP_SIZE);
+ printf("\n\t%s Message (%u), length: %u",
+ tok2strbuf(bgp_msg_values, "Unknown", bgp.bgp_type,
+ tokbuf, sizeof(tokbuf)),
+ bgp.bgp_type,
+ length);
+
+ switch (bgp.bgp_type) {
+ case BGP_OPEN:
+ bgp_open_print(dat, length);
+ break;
+ case BGP_UPDATE:
+ bgp_update_print(dat, length);
+ break;
+ case BGP_NOTIFICATION:
+ bgp_notification_print(dat, length);
+ break;
+ case BGP_KEEPALIVE:
+ break;
+ case BGP_ROUTE_REFRESH:
+ bgp_route_refresh_print(dat, length);
+ break;
+ default:
+ /* we have no decoder for the BGP message */
+ TCHECK2(*dat, length);
+ printf("\n\t no Message %u decoder",bgp.bgp_type);
+ print_unknown_data(dat,"\n\t ",length);
+ break;
+ }
+ return 1;
+trunc:
+ printf("[|BGP]");
+ return 0;
+}
+
+void
+bgp_print(const u_char *dat, int length)
+{
+ const u_char *p;
+ const u_char *ep;
+ const u_char *start;
+ const u_char marker[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ };
+ struct bgp bgp;
+ u_int16_t hlen;
+ char tokbuf[TOKBUFSIZE];
+
+ ep = dat + length;
+ if (snapend < dat + length)
+ ep = snapend;
+
+ printf(": BGP, length: %u",length);
+
+ if (vflag < 1) /* lets be less chatty */
+ return;
+
+ p = dat;
+ start = p;
+ while (p < ep) {
+ if (!TTEST2(p[0], 1))
+ break;
+ if (p[0] != 0xff) {
+ p++;
+ continue;
+ }
+
+ if (!TTEST2(p[0], sizeof(marker)))
+ break;
+ if (memcmp(p, marker, sizeof(marker)) != 0) {
+ p++;
+ continue;
+ }
+
+ /* found BGP header */
+ TCHECK2(p[0], BGP_SIZE); /*XXX*/
+ memcpy(&bgp, p, BGP_SIZE);
+
+ if (start != p)
+ printf(" [|BGP]");
+
+ hlen = ntohs(bgp.bgp_len);
+ if (hlen < BGP_SIZE) {
+ printf("\n[|BGP Bogus header length %u < %u]", hlen,
+ BGP_SIZE);
+ break;
+ }
+
+ if (TTEST2(p[0], hlen)) {
+ if (!bgp_header_print(p, hlen))
+ return;
+ p += hlen;
+ start = p;
+ } else {
+ printf("\n[|BGP %s]",
+ tok2strbuf(bgp_msg_values,
+ "Unknown Message Type",
+ bgp.bgp_type,
+ tokbuf, sizeof(tokbuf)));
+ break;
+ }
+ }
+
+ return;
+
+trunc:
+ printf(" [|BGP]");
+}
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-bootp.c b/freebsd/contrib/tcpdump/print-bootp.c
new file mode 100644
index 00000000..abf8efc0
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-bootp.c
@@ -0,0 +1,829 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Format and print bootp packets.
+ *
+ * $FreeBSD$
+ */
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-bootp.c,v 1.89 2008-04-22 09:45:08 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+#include "ether.h"
+#include "bootp.h"
+
+static void rfc1048_print(const u_char *);
+static void cmu_print(const u_char *);
+static char *client_fqdn_flags(u_int flags);
+
+static char tstr[] = " [|bootp]";
+
+static const struct tok bootp_flag_values[] = {
+ { 0x8000, "Broadcast" },
+ { 0, NULL}
+};
+
+static const struct tok bootp_op_values[] = {
+ { BOOTPREQUEST, "Request" },
+ { BOOTPREPLY, "Reply" },
+ { 0, NULL}
+};
+
+/*
+ * Print bootp requests
+ */
+void
+bootp_print(register const u_char *cp, u_int length)
+{
+ register const struct bootp *bp;
+ static const u_char vm_cmu[4] = VM_CMU;
+ static const u_char vm_rfc1048[4] = VM_RFC1048;
+
+ bp = (const struct bootp *)cp;
+ TCHECK(bp->bp_op);
+
+ printf("BOOTP/DHCP, %s",
+ tok2str(bootp_op_values, "unknown (0x%02x)", bp->bp_op));
+
+ if (bp->bp_htype == 1 && bp->bp_hlen == 6 && bp->bp_op == BOOTPREQUEST) {
+ TCHECK2(bp->bp_chaddr[0], 6);
+ printf(" from %s", etheraddr_string(bp->bp_chaddr));
+ }
+
+ printf(", length %u", length);
+
+ if (!vflag)
+ return;
+
+ TCHECK(bp->bp_secs);
+
+ /* The usual hardware address type is 1 (10Mb Ethernet) */
+ if (bp->bp_htype != 1)
+ printf(", htype %d", bp->bp_htype);
+
+ /* The usual length for 10Mb Ethernet address is 6 bytes */
+ if (bp->bp_htype != 1 || bp->bp_hlen != 6)
+ printf(", hlen %d", bp->bp_hlen);
+
+ /* Only print interesting fields */
+ if (bp->bp_hops)
+ printf(", hops %d", bp->bp_hops);
+ if (bp->bp_xid)
+ printf(", xid 0x%x", EXTRACT_32BITS(&bp->bp_xid));
+ if (bp->bp_secs)
+ printf(", secs %d", EXTRACT_16BITS(&bp->bp_secs));
+
+ printf(", Flags [%s]",
+ bittok2str(bootp_flag_values, "none", EXTRACT_16BITS(&bp->bp_flags)));
+ if (vflag > 1)
+ printf(" (0x%04x)", EXTRACT_16BITS(&bp->bp_flags));
+
+ /* Client's ip address */
+ TCHECK(bp->bp_ciaddr);
+ if (bp->bp_ciaddr.s_addr)
+ printf("\n\t Client-IP %s", ipaddr_string(&bp->bp_ciaddr));
+
+ /* 'your' ip address (bootp client) */
+ TCHECK(bp->bp_yiaddr);
+ if (bp->bp_yiaddr.s_addr)
+ printf("\n\t Your-IP %s", ipaddr_string(&bp->bp_yiaddr));
+
+ /* Server's ip address */
+ TCHECK(bp->bp_siaddr);
+ if (bp->bp_siaddr.s_addr)
+ printf("\n\t Server-IP %s", ipaddr_string(&bp->bp_siaddr));
+
+ /* Gateway's ip address */
+ TCHECK(bp->bp_giaddr);
+ if (bp->bp_giaddr.s_addr)
+ printf("\n\t Gateway-IP %s", ipaddr_string(&bp->bp_giaddr));
+
+ /* Client's Ethernet address */
+ if (bp->bp_htype == 1 && bp->bp_hlen == 6) {
+ TCHECK2(bp->bp_chaddr[0], 6);
+ printf("\n\t Client-Ethernet-Address %s", etheraddr_string(bp->bp_chaddr));
+ }
+
+ TCHECK2(bp->bp_sname[0], 1); /* check first char only */
+ if (*bp->bp_sname) {
+ printf("\n\t sname \"");
+ if (fn_print(bp->bp_sname, snapend)) {
+ putchar('"');
+ fputs(tstr + 1, stdout);
+ return;
+ }
+ putchar('"');
+ }
+ TCHECK2(bp->bp_file[0], 1); /* check first char only */
+ if (*bp->bp_file) {
+ printf("\n\t file \"");
+ if (fn_print(bp->bp_file, snapend)) {
+ putchar('"');
+ fputs(tstr + 1, stdout);
+ return;
+ }
+ putchar('"');
+ }
+
+ /* Decode the vendor buffer */
+ TCHECK(bp->bp_vend[0]);
+ if (memcmp((const char *)bp->bp_vend, vm_rfc1048,
+ sizeof(u_int32_t)) == 0)
+ rfc1048_print(bp->bp_vend);
+ else if (memcmp((const char *)bp->bp_vend, vm_cmu,
+ sizeof(u_int32_t)) == 0)
+ cmu_print(bp->bp_vend);
+ else {
+ u_int32_t ul;
+
+ ul = EXTRACT_32BITS(&bp->bp_vend);
+ if (ul != 0)
+ printf("\n\t Vendor-#0x%x", ul);
+ }
+
+ return;
+trunc:
+ fputs(tstr, stdout);
+}
+
+/*
+ * The first character specifies the format to print:
+ * i - ip address (32 bits)
+ * p - ip address pairs (32 bits + 32 bits)
+ * l - long (32 bits)
+ * L - unsigned long (32 bits)
+ * s - short (16 bits)
+ * b - period-seperated decimal bytes (variable length)
+ * x - colon-seperated hex bytes (variable length)
+ * a - ascii string (variable length)
+ * B - on/off (8 bits)
+ * $ - special (explicit code to handle)
+ */
+static struct tok tag2str[] = {
+/* RFC1048 tags */
+ { TAG_PAD, " PAD" },
+ { TAG_SUBNET_MASK, "iSubnet-Mask" }, /* subnet mask (RFC950) */
+ { TAG_TIME_OFFSET, "LTime-Zone" }, /* seconds from UTC */
+ { TAG_GATEWAY, "iDefault-Gateway" }, /* default gateway */
+ { TAG_TIME_SERVER, "iTime-Server" }, /* time servers (RFC868) */
+ { TAG_NAME_SERVER, "iIEN-Name-Server" }, /* IEN name servers (IEN116) */
+ { TAG_DOMAIN_SERVER, "iDomain-Name-Server" }, /* domain name (RFC1035) */
+ { TAG_LOG_SERVER, "iLOG" }, /* MIT log servers */
+ { TAG_COOKIE_SERVER, "iCS" }, /* cookie servers (RFC865) */
+ { TAG_LPR_SERVER, "iLPR-Server" }, /* lpr server (RFC1179) */
+ { TAG_IMPRESS_SERVER, "iIM" }, /* impress servers (Imagen) */
+ { TAG_RLP_SERVER, "iRL" }, /* resource location (RFC887) */
+ { TAG_HOSTNAME, "aHostname" }, /* ascii hostname */
+ { TAG_BOOTSIZE, "sBS" }, /* 512 byte blocks */
+ { TAG_END, " END" },
+/* RFC1497 tags */
+ { TAG_DUMPPATH, "aDP" },
+ { TAG_DOMAINNAME, "aDomain-Name" },
+ { TAG_SWAP_SERVER, "iSS" },
+ { TAG_ROOTPATH, "aRP" },
+ { TAG_EXTPATH, "aEP" },
+/* RFC2132 tags */
+ { TAG_IP_FORWARD, "BIPF" },
+ { TAG_NL_SRCRT, "BSRT" },
+ { TAG_PFILTERS, "pPF" },
+ { TAG_REASS_SIZE, "sRSZ" },
+ { TAG_DEF_TTL, "bTTL" },
+ { TAG_MTU_TIMEOUT, "lMTU-Timeout" },
+ { TAG_MTU_TABLE, "sMTU-Table" },
+ { TAG_INT_MTU, "sMTU" },
+ { TAG_LOCAL_SUBNETS, "BLSN" },
+ { TAG_BROAD_ADDR, "iBR" },
+ { TAG_DO_MASK_DISC, "BMD" },
+ { TAG_SUPPLY_MASK, "BMS" },
+ { TAG_DO_RDISC, "BRouter-Discovery" },
+ { TAG_RTR_SOL_ADDR, "iRSA" },
+ { TAG_STATIC_ROUTE, "pStatic-Route" },
+ { TAG_USE_TRAILERS, "BUT" },
+ { TAG_ARP_TIMEOUT, "lAT" },
+ { TAG_ETH_ENCAP, "BIE" },
+ { TAG_TCP_TTL, "bTT" },
+ { TAG_TCP_KEEPALIVE, "lKI" },
+ { TAG_KEEPALIVE_GO, "BKG" },
+ { TAG_NIS_DOMAIN, "aYD" },
+ { TAG_NIS_SERVERS, "iYS" },
+ { TAG_NTP_SERVERS, "iNTP" },
+ { TAG_VENDOR_OPTS, "bVendor-Option" },
+ { TAG_NETBIOS_NS, "iNetbios-Name-Server" },
+ { TAG_NETBIOS_DDS, "iWDD" },
+ { TAG_NETBIOS_NODE, "$Netbios-Node" },
+ { TAG_NETBIOS_SCOPE, "aNetbios-Scope" },
+ { TAG_XWIN_FS, "iXFS" },
+ { TAG_XWIN_DM, "iXDM" },
+ { TAG_NIS_P_DOMAIN, "sN+D" },
+ { TAG_NIS_P_SERVERS, "iN+S" },
+ { TAG_MOBILE_HOME, "iMH" },
+ { TAG_SMPT_SERVER, "iSMTP" },
+ { TAG_POP3_SERVER, "iPOP3" },
+ { TAG_NNTP_SERVER, "iNNTP" },
+ { TAG_WWW_SERVER, "iWWW" },
+ { TAG_FINGER_SERVER, "iFG" },
+ { TAG_IRC_SERVER, "iIRC" },
+ { TAG_STREETTALK_SRVR, "iSTS" },
+ { TAG_STREETTALK_STDA, "iSTDA" },
+ { TAG_REQUESTED_IP, "iRequested-IP" },
+ { TAG_IP_LEASE, "lLease-Time" },
+ { TAG_OPT_OVERLOAD, "$OO" },
+ { TAG_TFTP_SERVER, "aTFTP" },
+ { TAG_BOOTFILENAME, "aBF" },
+ { TAG_DHCP_MESSAGE, " DHCP-Message" },
+ { TAG_SERVER_ID, "iServer-ID" },
+ { TAG_PARM_REQUEST, "bParameter-Request" },
+ { TAG_MESSAGE, "aMSG" },
+ { TAG_MAX_MSG_SIZE, "sMSZ" },
+ { TAG_RENEWAL_TIME, "lRN" },
+ { TAG_REBIND_TIME, "lRB" },
+ { TAG_VENDOR_CLASS, "aVendor-Class" },
+ { TAG_CLIENT_ID, "$Client-ID" },
+/* RFC 2485 */
+ { TAG_OPEN_GROUP_UAP, "aUAP" },
+/* RFC 2563 */
+ { TAG_DISABLE_AUTOCONF, "BNOAUTO" },
+/* RFC 2610 */
+ { TAG_SLP_DA, "bSLP-DA" }, /*"b" is a little wrong */
+ { TAG_SLP_SCOPE, "bSLP-SCOPE" }, /*"b" is a little wrong */
+/* RFC 2937 */
+ { TAG_NS_SEARCH, "sNSSEARCH" }, /* XXX 's' */
+/* RFC 3011 */
+ { TAG_IP4_SUBNET_SELECT, "iSUBNET" },
+/* RFC 3442 */
+ { TAG_CLASSLESS_STATIC_RT, "$Classless-Static-Route" },
+ { TAG_CLASSLESS_STA_RT_MS, "$Classless-Static-Route-Microsoft" },
+/* http://www.iana.org/assignments/bootp-dhcp-extensions/index.htm */
+ { TAG_USER_CLASS, "aCLASS" },
+ { TAG_SLP_NAMING_AUTH, "aSLP-NA" },
+ { TAG_CLIENT_FQDN, "$FQDN" },
+ { TAG_AGENT_CIRCUIT, "$Agent-Information" },
+ { TAG_AGENT_REMOTE, "bARMT" },
+ { TAG_AGENT_MASK, "bAMSK" },
+ { TAG_TZ_STRING, "aTZSTR" },
+ { TAG_FQDN_OPTION, "bFQDNS" }, /* XXX 'b' */
+ { TAG_AUTH, "bAUTH" }, /* XXX 'b' */
+ { TAG_VINES_SERVERS, "iVINES" },
+ { TAG_SERVER_RANK, "sRANK" },
+ { TAG_CLIENT_ARCH, "sARCH" },
+ { TAG_CLIENT_NDI, "bNDI" }, /* XXX 'b' */
+ { TAG_CLIENT_GUID, "bGUID" }, /* XXX 'b' */
+ { TAG_LDAP_URL, "aLDAP" },
+ { TAG_6OVER4, "i6o4" },
+ { TAG_PRINTER_NAME, "aPRTR" },
+ { TAG_MDHCP_SERVER, "bMDHCP" }, /* XXX 'b' */
+ { TAG_IPX_COMPAT, "bIPX" }, /* XXX 'b' */
+ { TAG_NETINFO_PARENT, "iNI" },
+ { TAG_NETINFO_PARENT_TAG, "aNITAG" },
+ { TAG_URL, "aURL" },
+ { TAG_FAILOVER, "bFAIL" }, /* XXX 'b' */
+ { 0, NULL }
+};
+/* 2-byte extended tags */
+static struct tok xtag2str[] = {
+ { 0, NULL }
+};
+
+/* DHCP "options overload" types */
+static struct tok oo2str[] = {
+ { 1, "file" },
+ { 2, "sname" },
+ { 3, "file+sname" },
+ { 0, NULL }
+};
+
+/* NETBIOS over TCP/IP node type options */
+static struct tok nbo2str[] = {
+ { 0x1, "b-node" },
+ { 0x2, "p-node" },
+ { 0x4, "m-node" },
+ { 0x8, "h-node" },
+ { 0, NULL }
+};
+
+/* ARP Hardware types, for Client-ID option */
+static struct tok arp2str[] = {
+ { 0x1, "ether" },
+ { 0x6, "ieee802" },
+ { 0x7, "arcnet" },
+ { 0xf, "frelay" },
+ { 0x17, "strip" },
+ { 0x18, "ieee1394" },
+ { 0, NULL }
+};
+
+static struct tok dhcp_msg_values[] = {
+ { DHCPDISCOVER, "Discover" },
+ { DHCPOFFER, "Offer" },
+ { DHCPREQUEST, "Request" },
+ { DHCPDECLINE, "Decline" },
+ { DHCPACK, "ACK" },
+ { DHCPNAK, "NACK" },
+ { DHCPRELEASE, "Release" },
+ { DHCPINFORM, "Inform" },
+ { 0, NULL }
+};
+
+#define AGENT_SUBOPTION_CIRCUIT_ID 1 /* RFC 3046 */
+#define AGENT_SUBOPTION_REMOTE_ID 2 /* RFC 3046 */
+#define AGENT_SUBOPTION_SUBSCRIBER_ID 6 /* RFC 3993 */
+static struct tok agent_suboption_values[] = {
+ { AGENT_SUBOPTION_CIRCUIT_ID, "Circuit-ID" },
+ { AGENT_SUBOPTION_REMOTE_ID, "Remote-ID" },
+ { AGENT_SUBOPTION_SUBSCRIBER_ID, "Subscriber-ID" },
+ { 0, NULL }
+};
+
+
+static void
+rfc1048_print(register const u_char *bp)
+{
+ register u_int16_t tag;
+ register u_int len;
+ register const char *cp;
+ register char c;
+ int first, idx;
+ u_int32_t ul;
+ u_int16_t us;
+ u_int8_t uc, subopt, suboptlen;
+
+ printf("\n\t Vendor-rfc1048 Extensions");
+
+ /* Step over magic cookie */
+ printf("\n\t Magic Cookie 0x%08x", EXTRACT_32BITS(bp));
+ bp += sizeof(int32_t);
+
+ /* Loop while we there is a tag left in the buffer */
+ while (TTEST2(*bp, 1)) {
+ tag = *bp++;
+ if (tag == TAG_PAD && vflag < 3)
+ continue;
+ if (tag == TAG_END && vflag < 3)
+ return;
+ if (tag == TAG_EXTENDED_OPTION) {
+ TCHECK2(*(bp + 1), 2);
+ tag = EXTRACT_16BITS(bp + 1);
+ /* XXX we don't know yet if the IANA will
+ * preclude overlap of 1-byte and 2-byte spaces.
+ * If not, we need to offset tag after this step.
+ */
+ cp = tok2str(xtag2str, "?xT%u", tag);
+ } else
+ cp = tok2str(tag2str, "?T%u", tag);
+ c = *cp++;
+
+ if (tag == TAG_PAD || tag == TAG_END)
+ len = 0;
+ else {
+ /* Get the length; check for truncation */
+ TCHECK2(*bp, 1);
+ len = *bp++;
+ }
+
+ printf("\n\t %s Option %u, length %u%s", cp, tag, len,
+ len > 0 ? ": " : "");
+
+ if (tag == TAG_PAD && vflag > 2) {
+ u_int ntag = 1;
+ while (TTEST2(*bp, 1) && *bp == TAG_PAD) {
+ bp++;
+ ntag++;
+ }
+ if (ntag > 1)
+ printf(", occurs %u", ntag);
+ }
+
+ if (!TTEST2(*bp, len)) {
+ printf("[|rfc1048 %u]", len);
+ return;
+ }
+
+ if (tag == TAG_DHCP_MESSAGE && len == 1) {
+ uc = *bp++;
+ printf("%s", tok2str(dhcp_msg_values, "Unknown (%u)", uc));
+ continue;
+ }
+
+ if (tag == TAG_PARM_REQUEST) {
+ idx = 0;
+ while (len-- > 0) {
+ uc = *bp++;
+ cp = tok2str(tag2str, "?Option %u", uc);
+ if (idx % 4 == 0)
+ printf("\n\t ");
+ else
+ printf(", ");
+ printf("%s", cp + 1);
+ idx++;
+ }
+ continue;
+ }
+
+ if (tag == TAG_EXTENDED_REQUEST) {
+ first = 1;
+ while (len > 1) {
+ len -= 2;
+ us = EXTRACT_16BITS(bp);
+ bp += 2;
+ cp = tok2str(xtag2str, "?xT%u", us);
+ if (!first)
+ putchar('+');
+ printf("%s", cp + 1);
+ first = 0;
+ }
+ continue;
+ }
+
+ /* Print data */
+ if (c == '?') {
+ /* Base default formats for unknown tags on data size */
+ if (len & 1)
+ c = 'b';
+ else if (len & 2)
+ c = 's';
+ else
+ c = 'l';
+ }
+ first = 1;
+ switch (c) {
+
+ case 'a':
+ /* ascii strings */
+ putchar('"');
+ if (fn_printn(bp, len, snapend)) {
+ putchar('"');
+ goto trunc;
+ }
+ putchar('"');
+ bp += len;
+ len = 0;
+ break;
+
+ case 'i':
+ case 'l':
+ case 'L':
+ /* ip addresses/32-bit words */
+ while (len >= sizeof(ul)) {
+ if (!first)
+ putchar(',');
+ ul = EXTRACT_32BITS(bp);
+ if (c == 'i') {
+ ul = htonl(ul);
+ printf("%s", ipaddr_string(&ul));
+ } else if (c == 'L')
+ printf("%d", ul);
+ else
+ printf("%u", ul);
+ bp += sizeof(ul);
+ len -= sizeof(ul);
+ first = 0;
+ }
+ break;
+
+ case 'p':
+ /* IP address pairs */
+ while (len >= 2*sizeof(ul)) {
+ if (!first)
+ putchar(',');
+ memcpy((char *)&ul, (const char *)bp, sizeof(ul));
+ printf("(%s:", ipaddr_string(&ul));
+ bp += sizeof(ul);
+ memcpy((char *)&ul, (const char *)bp, sizeof(ul));
+ printf("%s)", ipaddr_string(&ul));
+ bp += sizeof(ul);
+ len -= 2*sizeof(ul);
+ first = 0;
+ }
+ break;
+
+ case 's':
+ /* shorts */
+ while (len >= sizeof(us)) {
+ if (!first)
+ putchar(',');
+ us = EXTRACT_16BITS(bp);
+ printf("%u", us);
+ bp += sizeof(us);
+ len -= sizeof(us);
+ first = 0;
+ }
+ break;
+
+ case 'B':
+ /* boolean */
+ while (len > 0) {
+ if (!first)
+ putchar(',');
+ switch (*bp) {
+ case 0:
+ putchar('N');
+ break;
+ case 1:
+ putchar('Y');
+ break;
+ default:
+ printf("%u?", *bp);
+ break;
+ }
+ ++bp;
+ --len;
+ first = 0;
+ }
+ break;
+
+ case 'b':
+ case 'x':
+ default:
+ /* Bytes */
+ while (len > 0) {
+ if (!first)
+ putchar(c == 'x' ? ':' : '.');
+ if (c == 'x')
+ printf("%02x", *bp);
+ else
+ printf("%u", *bp);
+ ++bp;
+ --len;
+ first = 0;
+ }
+ break;
+
+ case '$':
+ /* Guys we can't handle with one of the usual cases */
+ switch (tag) {
+
+ case TAG_NETBIOS_NODE:
+ /* this option should be at least 1 byte long */
+ if (len < 1) {
+ printf("ERROR: option %u len %u < 1 bytes",
+ TAG_NETBIOS_NODE, len);
+ break;
+ }
+ tag = *bp++;
+ --len;
+ fputs(tok2str(nbo2str, NULL, tag), stdout);
+ break;
+
+ case TAG_OPT_OVERLOAD:
+ /* this option should be at least 1 byte long */
+ if (len < 1) {
+ printf("ERROR: option %u len %u < 1 bytes",
+ TAG_OPT_OVERLOAD, len);
+ break;
+ }
+ tag = *bp++;
+ --len;
+ fputs(tok2str(oo2str, NULL, tag), stdout);
+ break;
+
+ case TAG_CLIENT_FQDN:
+ /* this option should be at least 3 bytes long */
+ if (len < 3) {
+ printf("ERROR: option %u len %u < 3 bytes",
+ TAG_CLIENT_FQDN, len);
+ bp += len;
+ len = 0;
+ break;
+ }
+ if (*bp)
+ printf("[%s] ", client_fqdn_flags(*bp));
+ bp++;
+ if (*bp || *(bp+1))
+ printf("%u/%u ", *bp, *(bp+1));
+ bp += 2;
+ putchar('"');
+ if (fn_printn(bp, len - 3, snapend)) {
+ putchar('"');
+ goto trunc;
+ }
+ putchar('"');
+ bp += len - 3;
+ len = 0;
+ break;
+
+ case TAG_CLIENT_ID:
+ { int type;
+
+ /* this option should be at least 1 byte long */
+ if (len < 1) {
+ printf("ERROR: option %u len %u < 1 bytes",
+ TAG_CLIENT_ID, len);
+ break;
+ }
+ type = *bp++;
+ len--;
+ if (type == 0) {
+ putchar('"');
+ if (fn_printn(bp, len, snapend)) {
+ putchar('"');
+ goto trunc;
+ }
+ putchar('"');
+ bp += len;
+ len = 0;
+ break;
+ } else {
+ printf("%s ", tok2str(arp2str, "hardware-type %u,", type));
+ while (len > 0) {
+ if (!first)
+ putchar(':');
+ printf("%02x", *bp);
+ ++bp;
+ --len;
+ first = 0;
+ }
+ }
+ break;
+ }
+
+ case TAG_AGENT_CIRCUIT:
+ while (len >= 2) {
+ subopt = *bp++;
+ suboptlen = *bp++;
+ len -= 2;
+ if (suboptlen > len) {
+ printf("\n\t %s SubOption %u, length %u: length goes past end of option",
+ tok2str(agent_suboption_values, "Unknown", subopt),
+ subopt,
+ suboptlen);
+ bp += len;
+ len = 0;
+ break;
+ }
+ printf("\n\t %s SubOption %u, length %u: ",
+ tok2str(agent_suboption_values, "Unknown", subopt),
+ subopt,
+ suboptlen);
+ switch (subopt) {
+
+ case AGENT_SUBOPTION_CIRCUIT_ID: /* fall through */
+ case AGENT_SUBOPTION_REMOTE_ID:
+ case AGENT_SUBOPTION_SUBSCRIBER_ID:
+ fn_printn(bp, suboptlen, NULL);
+ break;
+
+ default:
+ print_unknown_data(bp, "\n\t\t", suboptlen);
+ }
+
+ len -= suboptlen;
+ bp += suboptlen;
+ }
+ break;
+
+ case TAG_CLASSLESS_STATIC_RT:
+ case TAG_CLASSLESS_STA_RT_MS:
+ {
+ u_int mask_width, significant_octets, i;
+
+ /* this option should be at least 5 bytes long */
+ if (len < 5) {
+ printf("ERROR: option %u len %u < 5 bytes",
+ TAG_CLASSLESS_STATIC_RT, len);
+ bp += len;
+ len = 0;
+ break;
+ }
+ while (len > 0) {
+ if (!first)
+ putchar(',');
+ mask_width = *bp++;
+ len--;
+ /* mask_width <= 32 */
+ if (mask_width > 32) {
+ printf("[ERROR: Mask width (%d) > 32]", mask_width);
+ bp += len;
+ len = 0;
+ break;
+ }
+ significant_octets = (mask_width + 7) / 8;
+ /* significant octets + router(4) */
+ if (len < significant_octets + 4) {
+ printf("[ERROR: Remaining length (%u) < %u bytes]", len, significant_octets + 4);
+ bp += len;
+ len = 0;
+ break;
+ }
+ putchar('(');
+ if (mask_width == 0)
+ printf("default");
+ else {
+ for (i = 0; i < significant_octets ; i++) {
+ if (i > 0)
+ putchar('.');
+ printf("%d", *bp++);
+ }
+ for (i = significant_octets ; i < 4 ; i++)
+ printf(".0");
+ printf("/%d", mask_width);
+ }
+ memcpy((char *)&ul, (const char *)bp, sizeof(ul));
+ printf(":%s)", ipaddr_string(&ul));
+ bp += sizeof(ul);
+ len -= (significant_octets + 4);
+ first = 0;
+ }
+ }
+ break;
+
+ default:
+ printf("[unknown special tag %u, size %u]",
+ tag, len);
+ bp += len;
+ len = 0;
+ break;
+ }
+ break;
+ }
+ /* Data left over? */
+ if (len) {
+ printf("\n\t trailing data length %u", len);
+ bp += len;
+ }
+ }
+ return;
+trunc:
+ printf("|[rfc1048]");
+}
+
+static void
+cmu_print(register const u_char *bp)
+{
+ register const struct cmu_vend *cmu;
+
+#define PRINTCMUADDR(m, s) { TCHECK(cmu->m); \
+ if (cmu->m.s_addr != 0) \
+ printf(" %s:%s", s, ipaddr_string(&cmu->m.s_addr)); }
+
+ printf(" vend-cmu");
+ cmu = (const struct cmu_vend *)bp;
+
+ /* Only print if there are unknown bits */
+ TCHECK(cmu->v_flags);
+ if ((cmu->v_flags & ~(VF_SMASK)) != 0)
+ printf(" F:0x%x", cmu->v_flags);
+ PRINTCMUADDR(v_dgate, "DG");
+ PRINTCMUADDR(v_smask, cmu->v_flags & VF_SMASK ? "SM" : "SM*");
+ PRINTCMUADDR(v_dns1, "NS1");
+ PRINTCMUADDR(v_dns2, "NS2");
+ PRINTCMUADDR(v_ins1, "IEN1");
+ PRINTCMUADDR(v_ins2, "IEN2");
+ PRINTCMUADDR(v_ts1, "TS1");
+ PRINTCMUADDR(v_ts2, "TS2");
+ return;
+
+trunc:
+ fputs(tstr, stdout);
+#undef PRINTCMUADDR
+}
+
+static char *
+client_fqdn_flags(u_int flags)
+{
+ static char buf[8+1];
+ int i = 0;
+
+ if (flags & CLIENT_FQDN_FLAGS_S)
+ buf[i++] = 'S';
+ if (flags & CLIENT_FQDN_FLAGS_O)
+ buf[i++] = 'O';
+ if (flags & CLIENT_FQDN_FLAGS_E)
+ buf[i++] = 'E';
+ if (flags & CLIENT_FQDN_FLAGS_N)
+ buf[i++] = 'N';
+ buf[i] = '\0';
+
+ return buf;
+}
diff --git a/freebsd/contrib/tcpdump/print-bt.c b/freebsd/contrib/tcpdump/print-bt.c
new file mode 100644
index 00000000..3fdee7aa
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-bt.c
@@ -0,0 +1,81 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 2007
+ * paolo.abeni@email.it All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by Paolo Abeni.''
+ * The name of author may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-bt.c,v 1.2 2008-09-25 21:45:50 guy Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <pcap.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+
+#if defined(DLT_BLUETOOTH_HCI_H4_WITH_PHDR) && defined(HAVE_PCAP_BLUETOOTH_H)
+#include <pcap/bluetooth.h>
+
+#define BT_HDRLEN sizeof(pcap_bluetooth_h4_header)
+/*
+ * This is the top level routine of the printer. 'p' points
+ * to the bluetooth header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ */
+u_int
+bt_if_print(const struct pcap_pkthdr *h, const u_char *p)
+{
+ u_int length = h->len;
+ u_int caplen = h->caplen;
+ const pcap_bluetooth_h4_header* hdr = (const pcap_bluetooth_h4_header*)p;
+
+ if (caplen < BT_HDRLEN) {
+ printf("[|bt]");
+ return (BT_HDRLEN);
+ }
+ caplen -= BT_HDRLEN;
+ length -= BT_HDRLEN;
+ p += BT_HDRLEN;
+ if (eflag)
+ (void)printf("hci length %d, direction %s, ", length, (EXTRACT_32BITS(&hdr->direction)&0x1)?"in":"out");
+
+ if (!suppress_default_print)
+ default_print(p, caplen);
+
+ return (BT_HDRLEN);
+}
+#endif
+
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-carp.c b/freebsd/contrib/tcpdump/print-carp.c
new file mode 100644
index 00000000..e58c4c85
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-carp.c
@@ -0,0 +1,90 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/* $OpenBSD: print-carp.c,v 1.6 2009/10/27 23:59:55 deraadt Exp $ */
+
+/*
+ * Copyright (c) 2000 William C. Fenner.
+ * All rights reserved.
+ *
+ * Kevin Steves <ks@hp.se> July 2000
+ * Modified to:
+ * - print version, type string and packet length
+ * - print IP address count if > 1 (-v)
+ * - verify checksum (-v)
+ * - print authentication string (-v)
+ *
+ * Copyright (c) 2011 Advanced Computing Technologies
+ * George V. Neille-Neil
+ *
+ * Modified to:
+ * - work correctly with CARP
+ * - compile into the latest tcpdump
+ * - print out the counter
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * The name of William C. Fenner may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include <netinet/in.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+
+void
+carp_print(register const u_char *bp, register u_int len, int ttl)
+{
+ int version, type;
+ const char *type_s;
+
+ TCHECK(bp[0]);
+ version = (bp[0] & 0xf0) >> 4;
+ type = bp[0] & 0x0f;
+ if (type == 1)
+ type_s = "advertise";
+ else
+ type_s = "unknown";
+ printf("CARPv%d-%s %d: ", version, type_s, len);
+ if (ttl != 255)
+ printf("[ttl=%d!] ", ttl);
+ if (version != 2 || type != 1)
+ return;
+ TCHECK(bp[2]);
+ TCHECK(bp[5]);
+ printf("vhid=%d advbase=%d advskew=%d authlen=%d ",
+ bp[1], bp[5], bp[2], bp[3]);
+ if (vflag) {
+ struct cksum_vec vec[1];
+ vec[0].ptr = (const u_int8_t *)bp;
+ vec[0].len = len;
+ if (TTEST2(bp[0], len) && in_cksum(vec, 1))
+ printf(" (bad carp cksum %x!)",
+ EXTRACT_16BITS(&bp[6]));
+ }
+ printf("counter=%" PRIu64, EXTRACT_64BITS(&bp[8]));
+
+ return;
+trunc:
+ printf("[|carp]");
+}
diff --git a/freebsd/contrib/tcpdump/print-cdp.c b/freebsd/contrib/tcpdump/print-cdp.c
new file mode 100644
index 00000000..3370cdb5
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-cdp.c
@@ -0,0 +1,381 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Code by Gert Doering, SpaceNet GmbH, gert@space.net
+ *
+ * Reference documentation:
+ * http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-cdp.c,v 1.25 2004-10-07 14:53:11 hannes Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h" /* must come after interface.h */
+#include "nlpid.h"
+
+#define CDP_HEADER_LEN 4
+
+static struct tok cdp_tlv_values[] = {
+ { 0x01, "Device-ID"},
+ { 0x02, "Address"},
+ { 0x03, "Port-ID"},
+ { 0x04, "Capability"},
+ { 0x05, "Version String"},
+ { 0x06, "Platform"},
+ { 0x07, "Prefixes"},
+ { 0x08, "Protocol-Hello option"},
+ { 0x09, "VTP Management Domain"},
+ { 0x0a, "Native VLAN ID"},
+ { 0x0b, "Duplex"},
+ { 0x0e, "ATA-186 VoIP VLAN request"},
+ { 0x0f, "ATA-186 VoIP VLAN assignment"},
+ { 0x10, "power consumption"},
+ { 0x11, "MTU"},
+ { 0x12, "AVVID trust bitmap"},
+ { 0x13, "AVVID untrusted ports CoS"},
+ { 0x14, "System Name"},
+ { 0x15, "System Object ID (not decoded)"},
+ { 0x16, "Management Addresses"},
+ { 0x17, "Physical Location"},
+ { 0, NULL}
+};
+
+static struct tok cdp_capability_values[] = {
+ { 0x01, "Router" },
+ { 0x02, "Transparent Bridge" },
+ { 0x04, "Source Route Bridge" },
+ { 0x08, "L2 Switch" },
+ { 0x10, "L3 capable" },
+ { 0x20, "IGMP snooping" },
+ { 0x40, "L1 capable" },
+ { 0, NULL }
+};
+
+static int cdp_print_addr(const u_char *, int);
+static int cdp_print_prefixes(const u_char *, int);
+static unsigned long cdp_get_number(const u_char *, int);
+
+void
+cdp_print(const u_char *pptr, u_int length, u_int caplen)
+{
+ int type, len, i, j;
+ const u_char *tptr;
+
+ if (caplen < CDP_HEADER_LEN) {
+ (void)printf("[|cdp]");
+ return;
+ }
+
+ tptr = pptr; /* temporary pointer */
+
+ if (!TTEST2(*tptr, CDP_HEADER_LEN))
+ goto trunc;
+ printf("CDPv%u, ttl: %us", *tptr, *(tptr+1));
+ if (vflag)
+ printf(", checksum: %u (unverified), length %u", EXTRACT_16BITS(tptr), length);
+ tptr += CDP_HEADER_LEN;
+
+ while (tptr < (pptr+length)) {
+
+ if (!TTEST2(*tptr, 4)) /* read out Type and Length */
+ goto trunc;
+ type = EXTRACT_16BITS(tptr);
+ len = EXTRACT_16BITS(tptr+2); /* object length includes the 4 bytes header length */
+ tptr += 4;
+ len -= 4;
+
+ if (!TTEST2(*tptr, len))
+ goto trunc;
+
+ if (vflag || type == 1) { /* in non-verbose mode just print Device-ID */
+
+ if (vflag)
+ printf("\n\t%s (0x%02x), length: %u byte%s: ",
+ tok2str(cdp_tlv_values,"unknown field type", type),
+ type,
+ len,
+ PLURAL_SUFFIX(len)); /* plural */
+
+ switch (type) {
+
+ case 0x01: /* Device-ID */
+ if (!vflag)
+ printf(", Device-ID ");
+ printf("'");
+ fn_printn(tptr, len, NULL);
+ printf("'");
+ break;
+ case 0x02: /* Address */
+ if (cdp_print_addr(tptr, len) < 0)
+ goto trunc;
+ break;
+ case 0x03: /* Port-ID */
+ printf("'");
+ fn_printn(tptr, len, NULL);
+ printf("'");
+ break;
+ case 0x04: /* Capabilities */
+ printf("(0x%08x): %s",
+ EXTRACT_32BITS(tptr),
+ bittok2str(cdp_capability_values, "none",EXTRACT_32BITS(tptr)));
+ break;
+ case 0x05: /* Version */
+ printf("\n\t ");
+ for (i=0;i<len;i++) {
+ j = *(tptr+i);
+ putchar(j);
+ if (j == 0x0a) /* lets rework the version string to get a nice identation */
+ printf("\t ");
+ }
+ break;
+ case 0x06: /* Platform */
+ printf("'");
+ fn_printn(tptr, len, NULL);
+ printf("'");
+ break;
+ case 0x07: /* Prefixes */
+ if (cdp_print_prefixes(tptr, len) < 0)
+ goto trunc;
+ break;
+ case 0x08: /* Protocol Hello Option - not documented */
+ break;
+ case 0x09: /* VTP Mgmt Domain - not documented */
+ printf("'");
+ fn_printn(tptr, len, NULL);
+ printf("'");
+ break;
+ case 0x0a: /* Native VLAN ID - not documented */
+ printf("%d",EXTRACT_16BITS(tptr));
+ break;
+ case 0x0b: /* Duplex - not documented */
+ printf("%s", *(tptr) ? "full": "half");
+ break;
+
+ /* http://www.cisco.com/univercd/cc/td/doc/product/voice/ata/atarn/186rn21m.htm
+ * plus more details from other sources
+ */
+ case 0x0e: /* ATA-186 VoIP VLAN request - incomplete doc. */
+ printf("app %d, vlan %d",
+ *(tptr), EXTRACT_16BITS(tptr+1));
+ break;
+ case 0x10: /* ATA-186 VoIP VLAN assignment - incomplete doc. */
+ printf("%1.2fW",
+ cdp_get_number(tptr, len)/1000.0 );
+ break;
+ case 0x11: /* MTU - not documented */
+ printf("%u bytes", EXTRACT_32BITS(tptr));
+ break;
+ case 0x12: /* AVVID trust bitmap - not documented */
+ printf("0x%02x", *(tptr) );
+ break;
+ case 0x13: /* AVVID untrusted port CoS - not documented */
+ printf("0x%02x", *(tptr));
+ break;
+ case 0x14: /* System Name - not documented */
+ printf("'");
+ fn_printn(tptr, len, NULL);
+ printf("'");
+ break;
+ case 0x16: /* System Object ID - not documented */
+ if (cdp_print_addr(tptr, len) < 0)
+ goto trunc;
+ break;
+ case 0x17: /* Physical Location - not documented */
+ printf("0x%02x", *(tptr));
+ if (len > 1) {
+ printf("/");
+ fn_printn(tptr + 1, len - 1, NULL);
+ }
+ break;
+ default:
+ print_unknown_data(tptr,"\n\t ",len);
+ break;
+ }
+ }
+ /* avoid infinite loop */
+ if (len == 0)
+ break;
+ tptr = tptr+len;
+ }
+ if (vflag < 1)
+ printf(", length %u",caplen);
+
+ return;
+trunc:
+ printf("[|cdp]");
+}
+
+/*
+ * Protocol type values.
+ *
+ * PT_NLPID means that the protocol type field contains an OSI NLPID.
+ *
+ * PT_IEEE_802_2 means that the protocol type field contains an IEEE 802.2
+ * LLC header that specifies that the payload is for that protocol.
+ */
+#define PT_NLPID 1 /* OSI NLPID */
+#define PT_IEEE_802_2 2 /* IEEE 802.2 LLC header */
+
+static int
+cdp_print_addr(const u_char * p, int l)
+{
+ int pt, pl, al, num;
+ const u_char *endp = p + l;
+#ifdef INET6
+ static u_char prot_ipv6[] = {
+ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00, 0x86, 0xdd
+ };
+#endif
+
+ TCHECK2(*p, 2);
+ num = EXTRACT_32BITS(p);
+ p += 4;
+
+ while (p < endp && num >= 0) {
+ TCHECK2(*p, 2);
+ if (p + 2 > endp)
+ goto trunc;
+ pt = p[0]; /* type of "protocol" field */
+ pl = p[1]; /* length of "protocol" field */
+ p += 2;
+
+ TCHECK2(p[pl], 2);
+ if (p + pl + 2 > endp)
+ goto trunc;
+ al = EXTRACT_16BITS(&p[pl]); /* address length */
+
+ if (pt == PT_NLPID && pl == 1 && *p == NLPID_IP && al == 4) {
+ /*
+ * IPv4: protocol type = NLPID, protocol length = 1
+ * (1-byte NLPID), protocol = 0xcc (NLPID for IPv4),
+ * address length = 4
+ */
+ p += 3;
+
+ TCHECK2(*p, 4);
+ if (p + 4 > endp)
+ goto trunc;
+ printf("IPv4 (%u) %s",
+ num,
+ ipaddr_string(p));
+ p += 4;
+ }
+#ifdef INET6
+ else if (pt == PT_IEEE_802_2 && pl == 8 &&
+ memcmp(p, prot_ipv6, 8) == 0 && al == 16) {
+ /*
+ * IPv6: protocol type = IEEE 802.2 header,
+ * protocol length = 8 (size of LLC+SNAP header),
+ * protocol = LLC+SNAP header with the IPv6
+ * Ethertype, address length = 16
+ */
+ p += 10;
+ TCHECK2(*p, al);
+ if (p + al > endp)
+ goto trunc;
+
+ printf("IPv6 (%u) %s",
+ num,
+ ip6addr_string(p));
+ p += al;
+ }
+#endif
+ else {
+ /*
+ * Generic case: just print raw data
+ */
+ TCHECK2(*p, pl);
+ if (p + pl > endp)
+ goto trunc;
+ printf("pt=0x%02x, pl=%d, pb=", *(p - 2), pl);
+ while (pl-- > 0)
+ printf(" %02x", *p++);
+ TCHECK2(*p, 2);
+ if (p + 2 > endp)
+ goto trunc;
+ al = (*p << 8) + *(p + 1);
+ printf(", al=%d, a=", al);
+ p += 2;
+ TCHECK2(*p, al);
+ if (p + al > endp)
+ goto trunc;
+ while (al-- > 0)
+ printf(" %02x", *p++);
+ }
+ num--;
+ if (num)
+ printf(" ");
+ }
+
+ return 0;
+
+trunc:
+ return -1;
+}
+
+
+static int
+cdp_print_prefixes(const u_char * p, int l)
+{
+ if (l % 5)
+ goto trunc;
+
+ printf(" IPv4 Prefixes (%d):", l / 5);
+
+ while (l > 0) {
+ printf(" %u.%u.%u.%u/%u", p[0], p[1], p[2], p[3], p[4]);
+ l -= 5;
+ p += 5;
+ }
+
+ return 0;
+
+trunc:
+ return -1;
+}
+
+/* read in a <n>-byte number, MSB first
+ * (of course this can handle max sizeof(long))
+ */
+static unsigned long cdp_get_number(const u_char * p, int l)
+{
+ unsigned long res=0;
+ while( l>0 )
+ {
+ res = (res<<8) + *p;
+ p++; l--;
+ }
+ return res;
+}
diff --git a/freebsd/contrib/tcpdump/print-cfm.c b/freebsd/contrib/tcpdump/print-cfm.c
new file mode 100644
index 00000000..4db453a4
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-cfm.c
@@ -0,0 +1,647 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1998-2006 The TCPDUMP project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Support for the IEEE Connectivity Fault Management Protocols as per 802.1ag.
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-cfm.c,v 1.5 2007-07-24 16:01:42 hannes Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "ether.h"
+#include "addrtoname.h"
+#include "oui.h"
+#include "af.h"
+
+/*
+ * Prototypes
+ */
+const char * cfm_egress_id_string(register const u_char *);
+int cfm_mgmt_addr_print(register const u_char *);
+
+struct cfm_common_header_t {
+ u_int8_t mdlevel_version;
+ u_int8_t opcode;
+ u_int8_t flags;
+ u_int8_t first_tlv_offset;
+};
+
+#define CFM_VERSION 0
+#define CFM_EXTRACT_VERSION(x) (((x)&0x1f))
+#define CFM_EXTRACT_MD_LEVEL(x) (((x)&0xe0)>>5)
+
+#define CFM_OPCODE_CCM 1
+#define CFM_OPCODE_LBR 2
+#define CFM_OPCODE_LBM 3
+#define CFM_OPCODE_LTR 4
+#define CFM_OPCODE_LTM 5
+
+static const struct tok cfm_opcode_values[] = {
+ { CFM_OPCODE_CCM, "Continouity Check Message"},
+ { CFM_OPCODE_LBR, "Loopback Reply"},
+ { CFM_OPCODE_LBM, "Loopback Message"},
+ { CFM_OPCODE_LTR, "Linktrace Reply"},
+ { CFM_OPCODE_LTM, "Linktrace Message"},
+ { 0, NULL}
+};
+
+/*
+ * Message Formats.
+ */
+struct cfm_ccm_t {
+ u_int8_t sequence[4];
+ u_int8_t ma_epi[2];
+ u_int8_t md_nameformat;
+ u_int8_t md_namelength;
+ u_int8_t md_name[46]; /* md name and short ma name */
+ u_int8_t reserved_itu[16];
+ u_int8_t reserved[6];
+};
+
+/*
+ * Timer Bases for the CCM Interval field.
+ * Expressed in units of seconds.
+ */
+const float ccm_interval_base[8] = {0, 0.003333, 0.01, 0.1, 1, 10, 60, 600};
+#define CCM_INTERVAL_MIN_MULTIPLIER 3.25
+#define CCM_INTERVAL_MAX_MULTIPLIER 3.5
+
+#define CFM_CCM_RDI_FLAG 0x80
+#define CFM_EXTRACT_CCM_INTERVAL(x) (((x)&0x07))
+
+#define CFM_CCM_MD_FORMAT_8021 0
+#define CFM_CCM_MD_FORMAT_NONE 1
+#define CFM_CCM_MD_FORMAT_DNS 2
+#define CFM_CCM_MD_FORMAT_MAC 3
+#define CFM_CCM_MD_FORMAT_CHAR 4
+
+static const struct tok cfm_md_nameformat_values[] = {
+ { CFM_CCM_MD_FORMAT_8021, "IEEE 802.1"},
+ { CFM_CCM_MD_FORMAT_NONE, "No MD Name present"},
+ { CFM_CCM_MD_FORMAT_DNS, "DNS string"},
+ { CFM_CCM_MD_FORMAT_MAC, "MAC + 16Bit Integer"},
+ { CFM_CCM_MD_FORMAT_CHAR, "Character string"},
+ { 0, NULL}
+};
+
+#define CFM_CCM_MA_FORMAT_8021 0
+#define CFM_CCM_MA_FORMAT_VID 1
+#define CFM_CCM_MA_FORMAT_CHAR 2
+#define CFM_CCM_MA_FORMAT_INT 3
+#define CFM_CCM_MA_FORMAT_VPN 4
+
+static const struct tok cfm_ma_nameformat_values[] = {
+ { CFM_CCM_MA_FORMAT_8021, "IEEE 802.1"},
+ { CFM_CCM_MA_FORMAT_VID, "Primary VID"},
+ { CFM_CCM_MA_FORMAT_CHAR, "Character string"},
+ { CFM_CCM_MA_FORMAT_INT, "16Bit Integer"},
+ { CFM_CCM_MA_FORMAT_VPN, "RFC2685 VPN-ID"},
+ { 0, NULL}
+};
+
+struct cfm_lbm_t {
+ u_int8_t transaction_id[4];
+ u_int8_t reserved[4];
+};
+
+struct cfm_ltm_t {
+ u_int8_t transaction_id[4];
+ u_int8_t egress_id[8];
+ u_int8_t ttl;
+ u_int8_t original_mac[ETHER_ADDR_LEN];
+ u_int8_t target_mac[ETHER_ADDR_LEN];
+ u_int8_t reserved[3];
+};
+
+static const struct tok cfm_ltm_flag_values[] = {
+ { 0x80, "Use Forwarding-DB only"},
+ { 0, NULL}
+};
+
+struct cfm_ltr_t {
+ u_int8_t transaction_id[4];
+ u_int8_t last_egress_id[8];
+ u_int8_t next_egress_id[8];
+ u_int8_t ttl;
+ u_int8_t replay_action;
+ u_int8_t reserved[6];
+};
+
+static const struct tok cfm_ltr_flag_values[] = {
+ { 0x80, "Forwarded"},
+ { 0x40, "Terminal MEP"},
+ { 0, NULL}
+};
+
+static const struct tok cfm_ltr_replay_action_values[] = {
+ { 1, "Exact Match"},
+ { 2, "Filtering DB"},
+ { 3, "MIP CCM DB"},
+ { 0, NULL}
+};
+
+
+#define CFM_TLV_END 0
+#define CFM_TLV_SENDER_ID 1
+#define CFM_TLV_PORT_STATUS 2
+#define CFM_TLV_INTERFACE_STATUS 3
+#define CFM_TLV_DATA 4
+#define CFM_TLV_REPLY_INGRESS 5
+#define CFM_TLV_REPLY_EGRESS 6
+#define CFM_TLV_PRIVATE 31
+
+static const struct tok cfm_tlv_values[] = {
+ { CFM_TLV_END, "End"},
+ { CFM_TLV_SENDER_ID, "Sender ID"},
+ { CFM_TLV_PORT_STATUS, "Port status"},
+ { CFM_TLV_INTERFACE_STATUS, "Interface status"},
+ { CFM_TLV_DATA, "Data"},
+ { CFM_TLV_REPLY_INGRESS, "Reply Ingress"},
+ { CFM_TLV_REPLY_EGRESS, "Reply Egress"},
+ { CFM_TLV_PRIVATE, "Organization Specific"},
+ { 0, NULL}
+};
+
+/*
+ * TLVs
+ */
+
+struct cfm_tlv_header_t {
+ u_int8_t type;
+ u_int8_t length[2];
+};
+
+/* FIXME define TLV formats */
+
+static const struct tok cfm_tlv_port_status_values[] = {
+ { 1, "Blocked"},
+ { 2, "Up"},
+ { 0, NULL}
+};
+
+static const struct tok cfm_tlv_interface_status_values[] = {
+ { 1, "Up"},
+ { 2, "Down"},
+ { 3, "Testing"},
+ { 5, "Dormant"},
+ { 6, "not present"},
+ { 7, "lower Layer down"},
+ { 0, NULL}
+};
+
+#define CFM_CHASSIS_ID_CHASSIS_COMPONENT 1
+#define CFM_CHASSIS_ID_INTERFACE_ALIAS 2
+#define CFM_CHASSIS_ID_PORT_COMPONENT 3
+#define CFM_CHASSIS_ID_MAC_ADDRESS 4
+#define CFM_CHASSIS_ID_NETWORK_ADDRESS 5
+#define CFM_CHASSIS_ID_INTERFACE_NAME 6
+#define CFM_CHASSIS_ID_LOCAL 7
+
+static const struct tok cfm_tlv_senderid_chassisid_values[] = {
+ { 0, "Reserved"},
+ { CFM_CHASSIS_ID_CHASSIS_COMPONENT, "Chassis component"},
+ { CFM_CHASSIS_ID_INTERFACE_ALIAS, "Interface alias"},
+ { CFM_CHASSIS_ID_PORT_COMPONENT, "Port component"},
+ { CFM_CHASSIS_ID_MAC_ADDRESS, "MAC address"},
+ { CFM_CHASSIS_ID_NETWORK_ADDRESS, "Network address"},
+ { CFM_CHASSIS_ID_INTERFACE_NAME, "Interface name"},
+ { CFM_CHASSIS_ID_LOCAL, "Locally assigned"},
+ { 0, NULL}
+};
+
+
+int
+cfm_mgmt_addr_print(register const u_char *tptr) {
+
+ u_int mgmt_addr_type;
+ u_int hexdump = FALSE;
+
+ /*
+ * Altough AFIs are tpically 2 octects wide,
+ * 802.1ab specifies that this field width
+ * is only once octet
+ */
+ mgmt_addr_type = *tptr;
+ printf("\n\t Management Address Type %s (%u)",
+ tok2str(af_values, "Unknown", mgmt_addr_type),
+ mgmt_addr_type);
+
+ /*
+ * Resolve the passed in Address.
+ */
+ switch(mgmt_addr_type) {
+ case AFNUM_INET:
+ printf(", %s", ipaddr_string(tptr + 1));
+ break;
+
+#ifdef INET6
+ case AFNUM_INET6:
+ printf(", %s", ip6addr_string(tptr + 1));
+ break;
+#endif
+
+ default:
+ hexdump = TRUE;
+ break;
+ }
+
+ return hexdump;
+}
+
+/*
+ * The egress-ID string is a 16-Bit string plus a MAC address.
+ */
+const char *
+cfm_egress_id_string(register const u_char *tptr) {
+ static char egress_id_buffer[80];
+
+ snprintf(egress_id_buffer, sizeof(egress_id_buffer),
+ "MAC %0x4x-%s",
+ EXTRACT_16BITS(tptr),
+ etheraddr_string(tptr+2));
+
+ return egress_id_buffer;
+}
+
+void
+cfm_print(register const u_char *pptr, register u_int length) {
+
+ const struct cfm_common_header_t *cfm_common_header;
+ const struct cfm_tlv_header_t *cfm_tlv_header;
+ const u_int8_t *tptr, *tlv_ptr, *ma_name, *ma_nameformat, *ma_namelength;
+ u_int hexdump, tlen, cfm_tlv_len, cfm_tlv_type, ccm_interval;
+
+
+ union {
+ const struct cfm_ccm_t *cfm_ccm;
+ const struct cfm_lbm_t *cfm_lbm;
+ const struct cfm_ltm_t *cfm_ltm;
+ const struct cfm_ltr_t *cfm_ltr;
+ } msg_ptr;
+
+ tptr=pptr;
+ cfm_common_header = (const struct cfm_common_header_t *)pptr;
+ TCHECK(*cfm_common_header);
+
+ /*
+ * Sanity checking of the header.
+ */
+ if (CFM_EXTRACT_VERSION(cfm_common_header->mdlevel_version) != CFM_VERSION) {
+ printf("CFMv%u not supported, length %u",
+ CFM_EXTRACT_VERSION(cfm_common_header->mdlevel_version), length);
+ return;
+ }
+
+ printf("CFMv%u %s, MD Level %u, length %u",
+ CFM_EXTRACT_VERSION(cfm_common_header->mdlevel_version),
+ tok2str(cfm_opcode_values, "unknown (%u)", cfm_common_header->opcode),
+ CFM_EXTRACT_MD_LEVEL(cfm_common_header->mdlevel_version),
+ length);
+
+ /*
+ * In non-verbose mode just print the opcode and md-level.
+ */
+ if (vflag < 1) {
+ return;
+ }
+
+ printf("\n\tFirst TLV offset %u", cfm_common_header->first_tlv_offset);
+
+ tptr += sizeof(const struct cfm_common_header_t);
+ tlen = length - sizeof(struct cfm_common_header_t);
+
+ switch (cfm_common_header->opcode) {
+ case CFM_OPCODE_CCM:
+ msg_ptr.cfm_ccm = (const struct cfm_ccm_t *)tptr;
+
+ ccm_interval = CFM_EXTRACT_CCM_INTERVAL(cfm_common_header->flags);
+ printf(", Flags [CCM Interval %u%s]",
+ ccm_interval,
+ cfm_common_header->flags & CFM_CCM_RDI_FLAG ?
+ ", RDI" : "");
+
+ /*
+ * Resolve the CCM interval field.
+ */
+ if (ccm_interval) {
+ printf("\n\t CCM Interval %.3fs"
+ ", min CCM Lifetime %.3fs, max CCM Lifetime %.3fs",
+ ccm_interval_base[ccm_interval],
+ ccm_interval_base[ccm_interval] * CCM_INTERVAL_MIN_MULTIPLIER,
+ ccm_interval_base[ccm_interval] * CCM_INTERVAL_MAX_MULTIPLIER);
+ }
+
+ printf("\n\t Sequence Number 0x%08x, MA-End-Point-ID 0x%04x",
+ EXTRACT_32BITS(msg_ptr.cfm_ccm->sequence),
+ EXTRACT_16BITS(msg_ptr.cfm_ccm->ma_epi));
+
+
+ /*
+ * Resolve the MD fields.
+ */
+ printf("\n\t MD Name Format %s (%u), MD Name length %u",
+ tok2str(cfm_md_nameformat_values, "Unknown",
+ msg_ptr.cfm_ccm->md_nameformat),
+ msg_ptr.cfm_ccm->md_nameformat,
+ msg_ptr.cfm_ccm->md_namelength);
+
+ if (msg_ptr.cfm_ccm->md_nameformat != CFM_CCM_MD_FORMAT_NONE) {
+ printf("\n\t MD Name: ");
+ switch (msg_ptr.cfm_ccm->md_nameformat) {
+ case CFM_CCM_MD_FORMAT_DNS:
+ case CFM_CCM_MD_FORMAT_CHAR:
+ safeputs((const char *)msg_ptr.cfm_ccm->md_name, msg_ptr.cfm_ccm->md_namelength);
+ break;
+
+ case CFM_CCM_MD_FORMAT_MAC:
+ printf("\n\t MAC %s", etheraddr_string(
+ msg_ptr.cfm_ccm->md_name));
+ break;
+
+ /* FIXME add printers for those MD formats - hexdump for now */
+ case CFM_CCM_MA_FORMAT_8021:
+ default:
+ print_unknown_data(msg_ptr.cfm_ccm->md_name, "\n\t ",
+ msg_ptr.cfm_ccm->md_namelength);
+ }
+ }
+
+
+ /*
+ * Resolve the MA fields.
+ */
+ ma_nameformat = msg_ptr.cfm_ccm->md_name + msg_ptr.cfm_ccm->md_namelength;
+ ma_namelength = msg_ptr.cfm_ccm->md_name + msg_ptr.cfm_ccm->md_namelength + 1;
+ ma_name = msg_ptr.cfm_ccm->md_name + msg_ptr.cfm_ccm->md_namelength + 2;
+
+ printf("\n\t MA Name-Format %s (%u), MA name length %u",
+ tok2str(cfm_ma_nameformat_values, "Unknown",
+ *ma_nameformat),
+ *ma_nameformat,
+ *ma_namelength);
+
+ printf("\n\t MA Name: ");
+ switch (*ma_nameformat) {
+ case CFM_CCM_MA_FORMAT_CHAR:
+ safeputs((const char *)ma_name, *ma_namelength);
+ break;
+
+ /* FIXME add printers for those MA formats - hexdump for now */
+ case CFM_CCM_MA_FORMAT_8021:
+ case CFM_CCM_MA_FORMAT_VID:
+ case CFM_CCM_MA_FORMAT_INT:
+ case CFM_CCM_MA_FORMAT_VPN:
+ default:
+ print_unknown_data(ma_name, "\n\t ", *ma_namelength);
+ }
+ break;
+
+ case CFM_OPCODE_LTM:
+ msg_ptr.cfm_ltm = (const struct cfm_ltm_t *)tptr;
+
+ printf(", Flags [%s]",
+ bittok2str(cfm_ltm_flag_values, "none", cfm_common_header->flags));
+
+ printf("\n\t Transaction-ID 0x%08x, Egress-ID %s, ttl %u",
+ EXTRACT_32BITS(msg_ptr.cfm_ltm->transaction_id),
+ cfm_egress_id_string(msg_ptr.cfm_ltm->egress_id),
+ msg_ptr.cfm_ltm->ttl);
+
+ printf("\n\t Original-MAC %s, Target-MAC %s",
+ etheraddr_string(msg_ptr.cfm_ltm->original_mac),
+ etheraddr_string(msg_ptr.cfm_ltm->target_mac));
+ break;
+
+ case CFM_OPCODE_LTR:
+ msg_ptr.cfm_ltr = (const struct cfm_ltr_t *)tptr;
+
+ printf(", Flags [%s]",
+ bittok2str(cfm_ltr_flag_values, "none", cfm_common_header->flags));
+
+ printf("\n\t Transaction-ID 0x%08x, Last-Egress-ID %s",
+ EXTRACT_32BITS(msg_ptr.cfm_ltr->transaction_id),
+ cfm_egress_id_string(msg_ptr.cfm_ltr->last_egress_id));
+
+ printf("\n\t Next-Egress-ID %s, ttl %u",
+ cfm_egress_id_string(msg_ptr.cfm_ltr->next_egress_id),
+ msg_ptr.cfm_ltr->ttl);
+
+ printf("\n\t Replay-Action %s (%u)",
+ tok2str(cfm_ltr_replay_action_values,
+ "Unknown",
+ msg_ptr.cfm_ltr->replay_action),
+ msg_ptr.cfm_ltr->replay_action);
+ break;
+
+ /*
+ * No message decoder yet.
+ * Hexdump everything up until the start of the TLVs
+ */
+ case CFM_OPCODE_LBR:
+ case CFM_OPCODE_LBM:
+ default:
+ if (tlen > cfm_common_header->first_tlv_offset) {
+ print_unknown_data(tptr, "\n\t ",
+ tlen - cfm_common_header->first_tlv_offset);
+ }
+ break;
+ }
+
+ /*
+ * Sanity check for not walking off.
+ */
+ if (tlen <= cfm_common_header->first_tlv_offset) {
+ return;
+ }
+
+ tptr += cfm_common_header->first_tlv_offset;
+ tlen -= cfm_common_header->first_tlv_offset;
+
+ while (tlen > 0) {
+ cfm_tlv_header = (const struct cfm_tlv_header_t *)tptr;
+
+ /* Enough to read the tlv type ? */
+ TCHECK2(*tptr, 1);
+ cfm_tlv_type=cfm_tlv_header->type;
+
+ if (cfm_tlv_type != CFM_TLV_END) {
+ /* did we capture enough for fully decoding the object header ? */
+ TCHECK2(*tptr, sizeof(struct cfm_tlv_header_t));
+ cfm_tlv_len=EXTRACT_16BITS(&cfm_tlv_header->length);
+ } else {
+ cfm_tlv_len = 0;
+ }
+
+ printf("\n\t%s TLV (0x%02x), length %u",
+ tok2str(cfm_tlv_values, "Unknown", cfm_tlv_type),
+ cfm_tlv_type,
+ cfm_tlv_len);
+
+ /* sanity check for not walking off and infinite loop check. */
+ if ((cfm_tlv_type != CFM_TLV_END) &&
+ ((cfm_tlv_len + sizeof(struct cfm_tlv_header_t) > tlen) ||
+ (!cfm_tlv_len))) {
+ print_unknown_data(tptr,"\n\t ",tlen);
+ return;
+ }
+
+ tptr += sizeof(struct cfm_tlv_header_t);
+ tlen -= sizeof(struct cfm_tlv_header_t);
+ tlv_ptr = tptr;
+
+ /* did we capture enough for fully decoding the object ? */
+ if (cfm_tlv_type != CFM_TLV_END) {
+ TCHECK2(*tptr, cfm_tlv_len);
+ }
+ hexdump = FALSE;
+
+ switch(cfm_tlv_type) {
+ case CFM_TLV_END:
+ /* we are done - bail out */
+ return;
+
+ case CFM_TLV_PORT_STATUS:
+ printf(", Status: %s (%u)",
+ tok2str(cfm_tlv_port_status_values, "Unknown", *tptr),
+ *tptr);
+ break;
+
+ case CFM_TLV_INTERFACE_STATUS:
+ printf(", Status: %s (%u)",
+ tok2str(cfm_tlv_interface_status_values, "Unknown", *tptr),
+ *tptr);
+ break;
+
+ case CFM_TLV_PRIVATE:
+ printf(", Vendor: %s (%u), Sub-Type %u",
+ tok2str(oui_values,"Unknown", EXTRACT_24BITS(tptr)),
+ EXTRACT_24BITS(tptr),
+ *(tptr+3));
+ hexdump = TRUE;
+ break;
+
+ case CFM_TLV_SENDER_ID:
+ {
+ u_int chassis_id_type, chassis_id_length;
+ u_int mgmt_addr_length;
+
+ /*
+ * Check if there is a Chassis-ID.
+ */
+ chassis_id_length = *tptr;
+ if (chassis_id_length > tlen) {
+ hexdump = TRUE;
+ break;
+ }
+
+ tptr++;
+ tlen--;
+
+ if (chassis_id_length) {
+ chassis_id_type = *tptr;
+ printf("\n\t Chassis-ID Type %s (%u), Chassis-ID length %u",
+ tok2str(cfm_tlv_senderid_chassisid_values,
+ "Unknown",
+ chassis_id_type),
+ chassis_id_type,
+ chassis_id_length);
+
+ switch (chassis_id_type) {
+ case CFM_CHASSIS_ID_MAC_ADDRESS:
+ printf("\n\t MAC %s", etheraddr_string(tptr+1));
+ break;
+
+ case CFM_CHASSIS_ID_NETWORK_ADDRESS:
+ hexdump |= cfm_mgmt_addr_print(tptr);
+ break;
+
+ case CFM_CHASSIS_ID_INTERFACE_NAME: /* fall through */
+ case CFM_CHASSIS_ID_INTERFACE_ALIAS:
+ case CFM_CHASSIS_ID_LOCAL:
+ case CFM_CHASSIS_ID_CHASSIS_COMPONENT:
+ case CFM_CHASSIS_ID_PORT_COMPONENT:
+ safeputs((const char *)tptr+1, chassis_id_length);
+ break;
+
+ default:
+ hexdump = TRUE;
+ break;
+ }
+ }
+
+ tptr += chassis_id_length;
+ tlen -= chassis_id_length;
+
+ /*
+ * Check if there is a Management Address.
+ */
+ mgmt_addr_length = *tptr;
+ if (mgmt_addr_length > tlen) {
+ hexdump = TRUE;
+ break;
+ }
+
+ tptr++;
+ tlen--;
+
+ if (mgmt_addr_length) {
+ hexdump |= cfm_mgmt_addr_print(tptr);
+ }
+
+ tptr += mgmt_addr_length;
+ tlen -= mgmt_addr_length;
+
+ }
+ break;
+
+ /*
+ * FIXME those are the defined TLVs that lack a decoder
+ * you are welcome to contribute code ;-)
+ */
+
+ case CFM_TLV_DATA:
+ case CFM_TLV_REPLY_INGRESS:
+ case CFM_TLV_REPLY_EGRESS:
+ default:
+ hexdump = TRUE;
+ break;
+ }
+ /* do we want to see an additional hexdump ? */
+ if (hexdump || vflag > 1)
+ print_unknown_data(tlv_ptr, "\n\t ", cfm_tlv_len);
+
+ tptr+=cfm_tlv_len;
+ tlen-=cfm_tlv_len;
+ }
+ return;
+trunc:
+ printf("\n\t\t packet exceeded snapshot");
+}
diff --git a/freebsd/contrib/tcpdump/print-chdlc.c b/freebsd/contrib/tcpdump/print-chdlc.c
new file mode 100644
index 00000000..37414cb3
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-chdlc.c
@@ -0,0 +1,217 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-chdlc.c,v 1.43 2005-11-29 08:56:19 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <pcap.h>
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+#include "extract.h"
+#include "ppp.h"
+#include "chdlc.h"
+
+static void chdlc_slarp_print(const u_char *, u_int);
+
+const struct tok chdlc_cast_values[] = {
+ { CHDLC_UNICAST, "unicast" },
+ { CHDLC_BCAST, "bcast" },
+ { 0, NULL}
+};
+
+
+/* Standard CHDLC printer */
+u_int
+chdlc_if_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ register u_int length = h->len;
+ register u_int caplen = h->caplen;
+
+ if (caplen < CHDLC_HDRLEN) {
+ printf("[|chdlc]");
+ return (caplen);
+ }
+ return (chdlc_print(p,length));
+}
+
+u_int
+chdlc_print(register const u_char *p, u_int length) {
+ u_int proto;
+
+ proto = EXTRACT_16BITS(&p[2]);
+ if (eflag) {
+ printf("%s, ethertype %s (0x%04x), length %u: ",
+ tok2str(chdlc_cast_values, "0x%02x", p[0]),
+ tok2str(ethertype_values, "Unknown", proto),
+ proto,
+ length);
+ }
+
+ length -= CHDLC_HDRLEN;
+ p += CHDLC_HDRLEN;
+
+ switch (proto) {
+ case ETHERTYPE_IP:
+ ip_print(gndo, p, length);
+ break;
+#ifdef INET6
+ case ETHERTYPE_IPV6:
+ ip6_print(gndo, p, length);
+ break;
+#endif
+ case CHDLC_TYPE_SLARP:
+ chdlc_slarp_print(p, length);
+ break;
+#if 0
+ case CHDLC_TYPE_CDP:
+ chdlc_cdp_print(p, length);
+ break;
+#endif
+ case ETHERTYPE_MPLS:
+ case ETHERTYPE_MPLS_MULTI:
+ mpls_print(p, length);
+ break;
+ case ETHERTYPE_ISO:
+ /* is the fudge byte set ? lets verify by spotting ISO headers */
+ if (*(p+1) == 0x81 ||
+ *(p+1) == 0x82 ||
+ *(p+1) == 0x83)
+ isoclns_print(p+1, length-1, length-1);
+ else
+ isoclns_print(p, length, length);
+ break;
+ default:
+ if (!eflag)
+ printf("unknown CHDLC protocol (0x%04x)", proto);
+ break;
+ }
+
+ return (CHDLC_HDRLEN);
+}
+
+/*
+ * The fixed-length portion of a SLARP packet.
+ */
+struct cisco_slarp {
+ u_int8_t code[4];
+#define SLARP_REQUEST 0
+#define SLARP_REPLY 1
+#define SLARP_KEEPALIVE 2
+ union {
+ struct {
+ u_int8_t addr[4];
+ u_int8_t mask[4];
+ } addr;
+ struct {
+ u_int8_t myseq[4];
+ u_int8_t yourseq[4];
+ u_int8_t rel[2];
+ } keep;
+ } un;
+};
+
+#define SLARP_MIN_LEN 14
+#define SLARP_MAX_LEN 18
+
+static void
+chdlc_slarp_print(const u_char *cp, u_int length)
+{
+ const struct cisco_slarp *slarp;
+ u_int sec,min,hrs,days;
+
+ printf("SLARP (length: %u), ",length);
+ if (length < SLARP_MIN_LEN)
+ goto trunc;
+
+ slarp = (const struct cisco_slarp *)cp;
+ TCHECK2(*slarp, SLARP_MIN_LEN);
+ switch (EXTRACT_32BITS(&slarp->code)) {
+ case SLARP_REQUEST:
+ printf("request");
+ /*
+ * At least according to William "Chops" Westfield's
+ * message in
+ *
+ * http://www.nethelp.no/net/cisco-hdlc.txt
+ *
+ * the address and mask aren't used in requests -
+ * they're just zero.
+ */
+ break;
+ case SLARP_REPLY:
+ printf("reply %s/%s",
+ ipaddr_string(&slarp->un.addr.addr),
+ ipaddr_string(&slarp->un.addr.mask));
+ break;
+ case SLARP_KEEPALIVE:
+ printf("keepalive: mineseen=0x%08x, yourseen=0x%08x, reliability=0x%04x",
+ EXTRACT_32BITS(&slarp->un.keep.myseq),
+ EXTRACT_32BITS(&slarp->un.keep.yourseq),
+ EXTRACT_16BITS(&slarp->un.keep.rel));
+
+ if (length >= SLARP_MAX_LEN) { /* uptime-stamp is optional */
+ cp += SLARP_MIN_LEN;
+ if (!TTEST2(*cp, 4))
+ goto trunc;
+ sec = EXTRACT_32BITS(cp) / 1000;
+ min = sec / 60; sec -= min * 60;
+ hrs = min / 60; min -= hrs * 60;
+ days = hrs / 24; hrs -= days * 24;
+ printf(", link uptime=%ud%uh%um%us",days,hrs,min,sec);
+ }
+ break;
+ default:
+ printf("0x%02x unknown", EXTRACT_32BITS(&slarp->code));
+ if (vflag <= 1)
+ print_unknown_data(cp+4,"\n\t",length-4);
+ break;
+ }
+
+ if (SLARP_MAX_LEN < length && vflag)
+ printf(", (trailing junk: %d bytes)", length - SLARP_MAX_LEN);
+ if (vflag > 1)
+ print_unknown_data(cp+4,"\n\t",length-4);
+ return;
+
+trunc:
+ printf("[|slarp]");
+}
+
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-cip.c b/freebsd/contrib/tcpdump/print-cip.c
new file mode 100644
index 00000000..3b9075af
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-cip.c
@@ -0,0 +1,118 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Marko Kiiskila carnil@cs.tut.fi
+ *
+ * Tampere University of Technology - Telecommunications Laboratory
+ *
+ * Permission to use, copy, modify and distribute this
+ * software and its documentation is hereby granted,
+ * provided that both the copyright notice and this
+ * permission notice appear in all copies of the software,
+ * derivative works or modified versions, and any portions
+ * thereof, that both notices appear in supporting
+ * documentation, and that the use of this software is
+ * acknowledged in any publications resulting from using
+ * the software.
+ *
+ * TUT ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION AND DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS
+ * SOFTWARE.
+ *
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-cip.c,v 1.26 2005-07-07 01:22:17 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <pcap.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+#include "ether.h"
+
+#define RFC1483LLC_LEN 8
+
+static unsigned char rfcllc[] = {
+ 0xaa, /* DSAP: non-ISO */
+ 0xaa, /* SSAP: non-ISO */
+ 0x03, /* Ctrl: Unnumbered Information Command PDU */
+ 0x00, /* OUI: EtherType */
+ 0x00,
+ 0x00 };
+
+static inline void
+cip_print(int length)
+{
+ /*
+ * There is no MAC-layer header, so just print the length.
+ */
+ printf("%d: ", length);
+}
+
+/*
+ * This is the top level routine of the printer. 'p' points
+ * to the LLC/SNAP or raw header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ */
+u_int
+cip_if_print(const struct pcap_pkthdr *h, const u_char *p)
+{
+ u_int caplen = h->caplen;
+ u_int length = h->len;
+ u_short extracted_ethertype;
+
+ if (memcmp(rfcllc, p, sizeof(rfcllc))==0 && caplen < RFC1483LLC_LEN) {
+ printf("[|cip]");
+ return (0);
+ }
+
+ if (eflag)
+ cip_print(length);
+
+ if (memcmp(rfcllc, p, sizeof(rfcllc)) == 0) {
+ /*
+ * LLC header is present. Try to print it & higher layers.
+ */
+ if (llc_print(p, length, caplen, NULL, NULL,
+ &extracted_ethertype) == 0) {
+ /* ether_type not known, print raw packet */
+ if (!eflag)
+ cip_print(length);
+ if (extracted_ethertype) {
+ printf("(LLC %s) ",
+ etherproto_string(htons(extracted_ethertype)));
+ }
+ if (!suppress_default_print)
+ default_print(p, caplen);
+ }
+ } else {
+ /*
+ * LLC header is absent; treat it as just IP.
+ */
+ ip_print(gndo, p, length);
+ }
+
+ return (0);
+}
+
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-cnfp.c b/freebsd/contrib/tcpdump/print-cnfp.c
new file mode 100644
index 00000000..ae4a3426
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-cnfp.c
@@ -0,0 +1,192 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/* $OpenBSD: print-cnfp.c,v 1.2 1998/06/25 20:26:59 mickey Exp $ */
+
+/*
+ * Copyright (c) 1998 Michael Shalayeff
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Michael Shalayeff.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Cisco NetFlow protocol */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-cnfp.c,v 1.17 2005-04-20 20:53:18 guy Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+#include "tcp.h"
+#include "ipproto.h"
+
+struct nfhdr {
+ u_int32_t ver_cnt; /* version [15], and # of records */
+ u_int32_t msys_uptime;
+ u_int32_t utc_sec;
+ u_int32_t utc_nsec;
+ u_int32_t sequence; /* v5 flow sequence number */
+ u_int32_t reserved; /* v5 only */
+};
+
+struct nfrec {
+ struct in_addr src_ina;
+ struct in_addr dst_ina;
+ struct in_addr nhop_ina;
+ u_int32_t ifaces; /* src,dst ifaces */
+ u_int32_t packets;
+ u_int32_t octets;
+ u_int32_t start_time; /* sys_uptime value */
+ u_int32_t last_time; /* sys_uptime value */
+ u_int32_t ports; /* src,dst ports */
+ u_int32_t proto_tos; /* proto, tos, pad, flags(v5) */
+ u_int32_t asses; /* v1: flags; v5: src,dst AS */
+ u_int32_t masks; /* src,dst addr prefix; v6: encaps */
+ struct in_addr peer_nexthop; /* v6: IP address of the nexthop within the peer (FIB)*/
+};
+
+void
+cnfp_print(const u_char *cp, const u_char *bp _U_)
+{
+ register const struct nfhdr *nh;
+ register const struct nfrec *nr;
+ struct protoent *pent;
+ int nrecs, ver;
+#if 0
+ time_t t;
+#endif
+
+ nh = (const struct nfhdr *)cp;
+
+ if ((const u_char *)(nh + 1) > snapend)
+ return;
+
+ nrecs = EXTRACT_32BITS(&nh->ver_cnt) & 0xffff;
+ ver = (EXTRACT_32BITS(&nh->ver_cnt) & 0xffff0000) >> 16;
+#if 0
+ /*
+ * This is seconds since the UN*X epoch, and is followed by
+ * nanoseconds. XXX - format it, rather than just dumping the
+ * raw seconds-since-the-Epoch.
+ */
+ t = EXTRACT_32BITS(&nh->utc_sec);
+#endif
+
+ printf("NetFlow v%x, %u.%03u uptime, %u.%09u, ", ver,
+ EXTRACT_32BITS(&nh->msys_uptime)/1000,
+ EXTRACT_32BITS(&nh->msys_uptime)%1000,
+ EXTRACT_32BITS(&nh->utc_sec), EXTRACT_32BITS(&nh->utc_nsec));
+
+ if (ver == 5 || ver == 6) {
+ printf("#%u, ", EXTRACT_32BITS(&nh->sequence));
+ nr = (const struct nfrec *)&nh[1];
+ snaplen -= 24;
+ } else {
+ nr = (const struct nfrec *)&nh->sequence;
+ snaplen -= 16;
+ }
+
+ printf("%2u recs", nrecs);
+
+ for (; nrecs-- && (const u_char *)(nr + 1) <= snapend; nr++) {
+ char buf[20];
+ char asbuf[20];
+
+ printf("\n started %u.%03u, last %u.%03u",
+ EXTRACT_32BITS(&nr->start_time)/1000,
+ EXTRACT_32BITS(&nr->start_time)%1000,
+ EXTRACT_32BITS(&nr->last_time)/1000,
+ EXTRACT_32BITS(&nr->last_time)%1000);
+
+ asbuf[0] = buf[0] = '\0';
+ if (ver == 5 || ver == 6) {
+ snprintf(buf, sizeof(buf), "/%u",
+ (EXTRACT_32BITS(&nr->masks) >> 24) & 0xff);
+ snprintf(asbuf, sizeof(asbuf), ":%u",
+ (EXTRACT_32BITS(&nr->asses) >> 16) & 0xffff);
+ }
+ printf("\n %s%s%s:%u ", intoa(nr->src_ina.s_addr), buf, asbuf,
+ EXTRACT_32BITS(&nr->ports) >> 16);
+
+ if (ver == 5 || ver ==6) {
+ snprintf(buf, sizeof(buf), "/%d",
+ (EXTRACT_32BITS(&nr->masks) >> 16) & 0xff);
+ snprintf(asbuf, sizeof(asbuf), ":%u",
+ EXTRACT_32BITS(&nr->asses) & 0xffff);
+ }
+ printf("> %s%s%s:%u ", intoa(nr->dst_ina.s_addr), buf, asbuf,
+ EXTRACT_32BITS(&nr->ports) & 0xffff);
+
+ printf(">> %s\n ", intoa(nr->nhop_ina.s_addr));
+
+ pent = getprotobynumber((EXTRACT_32BITS(&nr->proto_tos) >> 8) & 0xff);
+ if (!pent || nflag)
+ printf("%u ",
+ (EXTRACT_32BITS(&nr->proto_tos) >> 8) & 0xff);
+ else
+ printf("%s ", pent->p_name);
+
+ /* tcp flags for tcp only */
+ if (pent && pent->p_proto == IPPROTO_TCP) {
+ int flags;
+ if (ver == 1)
+ flags = (EXTRACT_32BITS(&nr->asses) >> 24) & 0xff;
+ else
+ flags = (EXTRACT_32BITS(&nr->proto_tos) >> 16) & 0xff;
+ if (flags & TH_FIN) putchar('F');
+ if (flags & TH_SYN) putchar('S');
+ if (flags & TH_RST) putchar('R');
+ if (flags & TH_PUSH) putchar('P');
+ if (flags & TH_ACK) putchar('A');
+ if (flags & TH_URG) putchar('U');
+ if (flags)
+ putchar(' ');
+ }
+
+ buf[0]='\0';
+ if (ver == 6) {
+ snprintf(buf, sizeof(buf), "(%u<>%u encaps)",
+ (EXTRACT_32BITS(&nr->masks) >> 8) & 0xff,
+ (EXTRACT_32BITS(&nr->masks)) & 0xff);
+ }
+ printf("tos %u, %u (%u octets) %s",
+ EXTRACT_32BITS(&nr->proto_tos) & 0xff,
+ EXTRACT_32BITS(&nr->packets),
+ EXTRACT_32BITS(&nr->octets), buf);
+ }
+}
diff --git a/freebsd/contrib/tcpdump/print-dccp.c b/freebsd/contrib/tcpdump/print-dccp.c
new file mode 100644
index 00000000..59417c58
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-dccp.c
@@ -0,0 +1,466 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) Arnaldo Carvalho de Melo 2004
+ * Copyright (C) Ian McDonald 2005
+ * Copyright (C) Yoshifumi Nishida 2005
+ *
+ * This software may be distributed either under the terms of the
+ * BSD-style license that accompanies tcpdump or the GNU GPL version 2
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-dccp.c,v 1.8 2007-11-09 00:44:09 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include "dccp.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h" /* must come after interface.h */
+#include "ip.h"
+#ifdef INET6
+#include "ip6.h"
+#endif
+#include "ipproto.h"
+
+static const char *dccp_reset_codes[] = {
+ "unspecified",
+ "closed",
+ "aborted",
+ "no_connection",
+ "packet_error",
+ "option_error",
+ "mandatory_error",
+ "connection_refused",
+ "bad_service_code",
+ "too_busy",
+ "bad_init_cookie",
+ "aggression_penalty",
+};
+
+static const char *dccp_feature_nums[] = {
+ "reserved",
+ "ccid",
+ "allow_short_seqno",
+ "sequence_window",
+ "ecn_incapable",
+ "ack_ratio",
+ "send_ack_vector",
+ "send_ndp_count",
+ "minimum checksum coverage",
+ "check data checksum",
+};
+
+static inline u_int dccp_csum_coverage(const struct dccp_hdr* dh, u_int len)
+{
+ u_int cov;
+
+ if (DCCPH_CSCOV(dh) == 0)
+ return len;
+ cov = (dh->dccph_doff + DCCPH_CSCOV(dh) - 1) * sizeof(u_int32_t);
+ return (cov > len)? len : cov;
+}
+
+static int dccp_cksum(const struct ip *ip,
+ const struct dccp_hdr *dh, u_int len)
+{
+ return nextproto4_cksum(ip, (const u_int8_t *)(void *)dh,
+ dccp_csum_coverage(dh, len), IPPROTO_DCCP);
+}
+
+#ifdef INET6
+static int dccp6_cksum(const struct ip6_hdr *ip6, const struct dccp_hdr *dh, u_int len)
+{
+ return nextproto6_cksum(ip6, (const u_int8_t *)(void *)dh,
+ dccp_csum_coverage(dh, len), IPPROTO_DCCP);
+}
+#endif
+
+static const char *dccp_reset_code(u_int8_t code)
+{
+ if (code >= __DCCP_RESET_CODE_LAST)
+ return "invalid";
+ return dccp_reset_codes[code];
+}
+
+static u_int64_t dccp_seqno(const struct dccp_hdr *dh)
+{
+ u_int32_t seq_high = DCCPH_SEQ(dh);
+ u_int64_t seqno = EXTRACT_24BITS(&seq_high) & 0xFFFFFF;
+
+ if (DCCPH_X(dh) != 0) {
+ const struct dccp_hdr_ext *dhx = (void *)(dh + 1);
+ u_int32_t seq_low = dhx->dccph_seq_low;
+ seqno &= 0x00FFFF; /* clear reserved field */
+ seqno = (seqno << 32) + EXTRACT_32BITS(&seq_low);
+ }
+
+ return seqno;
+}
+
+static inline unsigned int dccp_basic_hdr_len(const struct dccp_hdr *dh)
+{
+ return sizeof(*dh) + (DCCPH_X(dh) ? sizeof(struct dccp_hdr_ext) : 0);
+}
+
+static void dccp_print_ack_no(const u_char *bp)
+{
+ const struct dccp_hdr *dh = (const struct dccp_hdr *)bp;
+ const struct dccp_hdr_ack_bits *dh_ack =
+ (struct dccp_hdr_ack_bits *)(bp + dccp_basic_hdr_len(dh));
+ u_int32_t ack_high;
+ u_int64_t ackno;
+
+ TCHECK2(*dh_ack,4);
+ ack_high = DCCPH_ACK(dh_ack);
+ ackno = EXTRACT_24BITS(&ack_high) & 0xFFFFFF;
+
+ if (DCCPH_X(dh) != 0) {
+ u_int32_t ack_low;
+
+ TCHECK2(*dh_ack,8);
+ ack_low = dh_ack->dccph_ack_nr_low;
+
+ ackno &= 0x00FFFF; /* clear reserved field */
+ ackno = (ackno << 32) + EXTRACT_32BITS(&ack_low);
+ }
+
+ (void)printf("(ack=%" PRIu64 ") ", ackno);
+trunc:
+ return;
+}
+
+static inline unsigned int dccp_packet_hdr_len(const u_int8_t type)
+{
+ if (type == DCCP_PKT_DATA)
+ return 0;
+ if (type == DCCP_PKT_DATAACK ||
+ type == DCCP_PKT_ACK ||
+ type == DCCP_PKT_SYNC ||
+ type == DCCP_PKT_SYNCACK ||
+ type == DCCP_PKT_CLOSE ||
+ type == DCCP_PKT_CLOSEREQ)
+ return sizeof(struct dccp_hdr_ack_bits);
+ if (type == DCCP_PKT_REQUEST)
+ return sizeof(struct dccp_hdr_request);
+ if (type == DCCP_PKT_RESPONSE)
+ return sizeof(struct dccp_hdr_response);
+ return sizeof(struct dccp_hdr_reset);
+}
+
+static int dccp_print_option(const u_char *option);
+
+/**
+ * dccp_print - show dccp packet
+ * @bp - beginning of dccp packet
+ * @data2 - beginning of enclosing
+ * @len - lenght of ip packet
+ */
+void dccp_print(const u_char *bp, const u_char *data2, u_int len)
+{
+ const struct dccp_hdr *dh;
+ const struct ip *ip;
+#ifdef INET6
+ const struct ip6_hdr *ip6;
+#endif
+ const u_char *cp;
+ u_short sport, dport;
+ u_int hlen;
+ u_int extlen = 0;
+
+ dh = (const struct dccp_hdr *)bp;
+
+ ip = (struct ip *)data2;
+#ifdef INET6
+ if (IP_V(ip) == 6)
+ ip6 = (const struct ip6_hdr *)data2;
+ else
+ ip6 = NULL;
+#endif /*INET6*/
+ cp = (const u_char *)(dh + 1);
+ if (cp > snapend) {
+ printf("[Invalid packet|dccp]");
+ return;
+ }
+
+ if (len < sizeof(struct dccp_hdr)) {
+ printf("truncated-dccp - %ld bytes missing!",
+ (long)len - sizeof(struct dccp_hdr));
+ return;
+ }
+
+ sport = EXTRACT_16BITS(&dh->dccph_sport);
+ dport = EXTRACT_16BITS(&dh->dccph_dport);
+ hlen = dh->dccph_doff * 4;
+
+#ifdef INET6
+ if (ip6) {
+ (void)printf("%s.%d > %s.%d: ",
+ ip6addr_string(&ip6->ip6_src), sport,
+ ip6addr_string(&ip6->ip6_dst), dport);
+ } else
+#endif /*INET6*/
+ {
+ (void)printf("%s.%d > %s.%d: ",
+ ipaddr_string(&ip->ip_src), sport,
+ ipaddr_string(&ip->ip_dst), dport);
+ }
+ fflush(stdout);
+
+ if (qflag) {
+ (void)printf(" %d", len - hlen);
+ if (hlen > len) {
+ (void)printf("dccp [bad hdr length %u - too long, > %u]",
+ hlen, len);
+ }
+ return;
+ }
+
+ /* other variables in generic header */
+ if (vflag) {
+ (void)printf("CCVal %d, CsCov %d, ", DCCPH_CCVAL(dh), DCCPH_CSCOV(dh));
+ }
+
+ /* checksum calculation */
+ if (vflag && TTEST2(bp[0], len)) {
+ u_int16_t sum = 0, dccp_sum;
+
+ dccp_sum = EXTRACT_16BITS(&dh->dccph_checksum);
+ (void)printf("cksum 0x%04x ", dccp_sum);
+ if (IP_V(ip) == 4)
+ sum = dccp_cksum(ip, dh, len);
+#ifdef INET6
+ else if (IP_V(ip) == 6)
+ sum = dccp6_cksum(ip6, dh, len);
+#endif
+ if (sum != 0)
+ (void)printf("(incorrect -> 0x%04x), ",in_cksum_shouldbe(dccp_sum, sum));
+ else
+ (void)printf("(correct), ");
+ }
+
+ switch (DCCPH_TYPE(dh)) {
+ case DCCP_PKT_REQUEST: {
+ struct dccp_hdr_request *dhr =
+ (struct dccp_hdr_request *)(bp + dccp_basic_hdr_len(dh));
+ TCHECK(*dhr);
+ (void)printf("request (service=%d) ",
+ EXTRACT_32BITS(&dhr->dccph_req_service));
+ extlen += 4;
+ break;
+ }
+ case DCCP_PKT_RESPONSE: {
+ struct dccp_hdr_response *dhr =
+ (struct dccp_hdr_response *)(bp + dccp_basic_hdr_len(dh));
+ TCHECK(*dhr);
+ (void)printf("response (service=%d) ",
+ EXTRACT_32BITS(&dhr->dccph_resp_service));
+ extlen += 12;
+ break;
+ }
+ case DCCP_PKT_DATA:
+ (void)printf("data ");
+ break;
+ case DCCP_PKT_ACK: {
+ (void)printf("ack ");
+ extlen += 8;
+ break;
+ }
+ case DCCP_PKT_DATAACK: {
+ (void)printf("dataack ");
+ extlen += 8;
+ break;
+ }
+ case DCCP_PKT_CLOSEREQ:
+ (void)printf("closereq ");
+ extlen += 8;
+ break;
+ case DCCP_PKT_CLOSE:
+ (void)printf("close ");
+ extlen += 8;
+ break;
+ case DCCP_PKT_RESET: {
+ struct dccp_hdr_reset *dhr =
+ (struct dccp_hdr_reset *)(bp + dccp_basic_hdr_len(dh));
+ TCHECK(*dhr);
+ (void)printf("reset (code=%s) ",
+ dccp_reset_code(dhr->dccph_reset_code));
+ extlen += 12;
+ break;
+ }
+ case DCCP_PKT_SYNC:
+ (void)printf("sync ");
+ extlen += 8;
+ break;
+ case DCCP_PKT_SYNCACK:
+ (void)printf("syncack ");
+ extlen += 8;
+ break;
+ default:
+ (void)printf("invalid ");
+ break;
+ }
+
+ if ((DCCPH_TYPE(dh) != DCCP_PKT_DATA) &&
+ (DCCPH_TYPE(dh) != DCCP_PKT_REQUEST))
+ dccp_print_ack_no(bp);
+
+ if (vflag < 2)
+ return;
+
+ (void)printf("seq %" PRIu64, dccp_seqno(dh));
+
+ /* process options */
+ if (hlen > dccp_basic_hdr_len(dh) + extlen){
+ const u_char *cp;
+ u_int optlen;
+ cp = bp + dccp_basic_hdr_len(dh) + extlen;
+ printf(" <");
+
+ hlen -= dccp_basic_hdr_len(dh) + extlen;
+ while(1){
+ TCHECK(*cp);
+ optlen = dccp_print_option(cp);
+ if (!optlen) goto trunc2;
+ if (hlen <= optlen) break;
+ hlen -= optlen;
+ cp += optlen;
+ printf(", ");
+ }
+ printf(">");
+ }
+ return;
+trunc:
+ printf("[|dccp]");
+trunc2:
+ return;
+}
+
+static int dccp_print_option(const u_char *option)
+{
+ u_int8_t optlen, i;
+
+ TCHECK(*option);
+
+ if (*option >= 32) {
+ TCHECK(*(option+1));
+ optlen = *(option +1);
+ if (optlen < 2) {
+ printf("Option %d optlen too short",*option);
+ return 1;
+ }
+ } else optlen = 1;
+
+ TCHECK2(*option,optlen);
+
+ switch (*option){
+ case 0:
+ printf("nop");
+ break;
+ case 1:
+ printf("mandatory");
+ break;
+ case 2:
+ printf("slowreceiver");
+ break;
+ case 32:
+ printf("change_l");
+ if (*(option +2) < 10){
+ printf(" %s", dccp_feature_nums[*(option +2)]);
+ for (i = 0; i < optlen -3; i ++) printf(" %d", *(option +3 + i));
+ }
+ break;
+ case 33:
+ printf("confirm_l");
+ if (*(option +2) < 10){
+ printf(" %s", dccp_feature_nums[*(option +2)]);
+ for (i = 0; i < optlen -3; i ++) printf(" %d", *(option +3 + i));
+ }
+ break;
+ case 34:
+ printf("change_r");
+ if (*(option +2) < 10){
+ printf(" %s", dccp_feature_nums[*(option +2)]);
+ for (i = 0; i < optlen -3; i ++) printf(" %d", *(option +3 + i));
+ }
+ break;
+ case 35:
+ printf("confirm_r");
+ if (*(option +2) < 10){
+ printf(" %s", dccp_feature_nums[*(option +2)]);
+ for (i = 0; i < optlen -3; i ++) printf(" %d", *(option +3 + i));
+ }
+ break;
+ case 36:
+ printf("initcookie 0x");
+ for (i = 0; i < optlen -2; i ++) printf("%02x", *(option +2 + i));
+ break;
+ case 37:
+ printf("ndp_count");
+ for (i = 0; i < optlen -2; i ++) printf(" %d", *(option +2 + i));
+ break;
+ case 38:
+ printf("ack_vector0 0x");
+ for (i = 0; i < optlen -2; i ++) printf("%02x", *(option +2 + i));
+ break;
+ case 39:
+ printf("ack_vector1 0x");
+ for (i = 0; i < optlen -2; i ++) printf("%02x", *(option +2 + i));
+ break;
+ case 40:
+ printf("data_dropped 0x");
+ for (i = 0; i < optlen -2; i ++) printf("%02x", *(option +2 + i));
+ break;
+ case 41:
+ printf("timestamp %u", EXTRACT_32BITS(option + 2));
+ break;
+ case 42:
+ printf("timestamp_echo %u", EXTRACT_32BITS(option + 2));
+ break;
+ case 43:
+ printf("elapsed_time ");
+ if (optlen == 6)
+ printf("%u", EXTRACT_32BITS(option + 2));
+ else
+ printf("%u", EXTRACT_16BITS(option + 2));
+ break;
+ case 44:
+ printf("data_checksum ");
+ for (i = 0; i < optlen -2; i ++) printf("%02x", *(option +2 + i));
+ break;
+ default :
+ if (*option >= 128) {
+ printf("CCID option %d",*option);
+ switch (optlen) {
+ case 4:
+ printf(" %u", EXTRACT_16BITS(option + 2));
+ break;
+ case 6:
+ printf(" %u", EXTRACT_32BITS(option + 2));
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+
+ printf("unknown_opt %d", *option);
+ break;
+ }
+
+ return optlen;
+trunc:
+ printf("[|dccp]");
+ return 0;
+}
diff --git a/freebsd/contrib/tcpdump/print-decnet.c b/freebsd/contrib/tcpdump/print-decnet.c
new file mode 100644
index 00000000..f453381c
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-decnet.c
@@ -0,0 +1,897 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-decnet.c,v 1.39 2005-05-06 02:16:26 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+struct mbuf;
+struct rtentry;
+
+#ifdef HAVE_NETDNET_DNETDB_H
+#include <netdnet/dnetdb.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "decnet.h"
+#include "extract.h"
+#include "interface.h"
+#include "addrtoname.h"
+
+/* Forwards */
+static int print_decnet_ctlmsg(const union routehdr *, u_int, u_int);
+static void print_t_info(int);
+static int print_l1_routes(const char *, u_int);
+static int print_l2_routes(const char *, u_int);
+static void print_i_info(int);
+static int print_elist(const char *, u_int);
+static int print_nsp(const u_char *, u_int);
+static void print_reason(int);
+#ifdef PRINT_NSPDATA
+static void pdata(u_char *, int);
+#endif
+
+#ifndef HAVE_NETDNET_DNETDB_H_DNET_HTOA
+extern char *dnet_htoa(struct dn_naddr *);
+#endif
+
+void
+decnet_print(register const u_char *ap, register u_int length,
+ register u_int caplen)
+{
+ register const union routehdr *rhp;
+ register int mflags;
+ int dst, src, hops;
+ u_int nsplen, pktlen;
+ const u_char *nspp;
+
+ if (length < sizeof(struct shorthdr)) {
+ (void)printf("[|decnet]");
+ return;
+ }
+
+ TCHECK2(*ap, sizeof(short));
+ pktlen = EXTRACT_LE_16BITS(ap);
+ if (pktlen < sizeof(struct shorthdr)) {
+ (void)printf("[|decnet]");
+ return;
+ }
+ if (pktlen > length) {
+ (void)printf("[|decnet]");
+ return;
+ }
+ length = pktlen;
+
+ rhp = (const union routehdr *)&(ap[sizeof(short)]);
+ TCHECK(rhp->rh_short.sh_flags);
+ mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
+
+ if (mflags & RMF_PAD) {
+ /* pad bytes of some sort in front of message */
+ u_int padlen = mflags & RMF_PADMASK;
+ if (vflag)
+ (void) printf("[pad:%d] ", padlen);
+ if (length < padlen + 2) {
+ (void)printf("[|decnet]");
+ return;
+ }
+ TCHECK2(ap[sizeof(short)], padlen);
+ ap += padlen;
+ length -= padlen;
+ caplen -= padlen;
+ rhp = (const union routehdr *)&(ap[sizeof(short)]);
+ mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
+ }
+
+ if (mflags & RMF_FVER) {
+ (void) printf("future-version-decnet");
+ default_print(ap, min(length, caplen));
+ return;
+ }
+
+ /* is it a control message? */
+ if (mflags & RMF_CTLMSG) {
+ if (!print_decnet_ctlmsg(rhp, length, caplen))
+ goto trunc;
+ return;
+ }
+
+ switch (mflags & RMF_MASK) {
+ case RMF_LONG:
+ if (length < sizeof(struct longhdr)) {
+ (void)printf("[|decnet]");
+ return;
+ }
+ TCHECK(rhp->rh_long);
+ dst =
+ EXTRACT_LE_16BITS(rhp->rh_long.lg_dst.dne_remote.dne_nodeaddr);
+ src =
+ EXTRACT_LE_16BITS(rhp->rh_long.lg_src.dne_remote.dne_nodeaddr);
+ hops = EXTRACT_LE_8BITS(rhp->rh_long.lg_visits);
+ nspp = &(ap[sizeof(short) + sizeof(struct longhdr)]);
+ nsplen = length - sizeof(struct longhdr);
+ break;
+ case RMF_SHORT:
+ TCHECK(rhp->rh_short);
+ dst = EXTRACT_LE_16BITS(rhp->rh_short.sh_dst);
+ src = EXTRACT_LE_16BITS(rhp->rh_short.sh_src);
+ hops = (EXTRACT_LE_8BITS(rhp->rh_short.sh_visits) & VIS_MASK)+1;
+ nspp = &(ap[sizeof(short) + sizeof(struct shorthdr)]);
+ nsplen = length - sizeof(struct shorthdr);
+ break;
+ default:
+ (void) printf("unknown message flags under mask");
+ default_print((u_char *)ap, min(length, caplen));
+ return;
+ }
+
+ (void)printf("%s > %s %d ",
+ dnaddr_string(src), dnaddr_string(dst), pktlen);
+ if (vflag) {
+ if (mflags & RMF_RQR)
+ (void)printf("RQR ");
+ if (mflags & RMF_RTS)
+ (void)printf("RTS ");
+ if (mflags & RMF_IE)
+ (void)printf("IE ");
+ (void)printf("%d hops ", hops);
+ }
+
+ if (!print_nsp(nspp, nsplen))
+ goto trunc;
+ return;
+
+trunc:
+ (void)printf("[|decnet]");
+ return;
+}
+
+static int
+print_decnet_ctlmsg(register const union routehdr *rhp, u_int length,
+ u_int caplen)
+{
+ int mflags = EXTRACT_LE_8BITS(rhp->rh_short.sh_flags);
+ register union controlmsg *cmp = (union controlmsg *)rhp;
+ int src, dst, info, blksize, eco, ueco, hello, other, vers;
+ etheraddr srcea, rtea;
+ int priority;
+ char *rhpx = (char *)rhp;
+ int ret;
+
+ switch (mflags & RMF_CTLMASK) {
+ case RMF_INIT:
+ (void)printf("init ");
+ if (length < sizeof(struct initmsg))
+ goto trunc;
+ TCHECK(cmp->cm_init);
+ src = EXTRACT_LE_16BITS(cmp->cm_init.in_src);
+ info = EXTRACT_LE_8BITS(cmp->cm_init.in_info);
+ blksize = EXTRACT_LE_16BITS(cmp->cm_init.in_blksize);
+ vers = EXTRACT_LE_8BITS(cmp->cm_init.in_vers);
+ eco = EXTRACT_LE_8BITS(cmp->cm_init.in_eco);
+ ueco = EXTRACT_LE_8BITS(cmp->cm_init.in_ueco);
+ hello = EXTRACT_LE_16BITS(cmp->cm_init.in_hello);
+ print_t_info(info);
+ (void)printf(
+ "src %sblksize %d vers %d eco %d ueco %d hello %d",
+ dnaddr_string(src), blksize, vers, eco, ueco,
+ hello);
+ ret = 1;
+ break;
+ case RMF_VER:
+ (void)printf("verification ");
+ if (length < sizeof(struct verifmsg))
+ goto trunc;
+ TCHECK(cmp->cm_ver);
+ src = EXTRACT_LE_16BITS(cmp->cm_ver.ve_src);
+ other = EXTRACT_LE_8BITS(cmp->cm_ver.ve_fcnval);
+ (void)printf("src %s fcnval %o", dnaddr_string(src), other);
+ ret = 1;
+ break;
+ case RMF_TEST:
+ (void)printf("test ");
+ if (length < sizeof(struct testmsg))
+ goto trunc;
+ TCHECK(cmp->cm_test);
+ src = EXTRACT_LE_16BITS(cmp->cm_test.te_src);
+ other = EXTRACT_LE_8BITS(cmp->cm_test.te_data);
+ (void)printf("src %s data %o", dnaddr_string(src), other);
+ ret = 1;
+ break;
+ case RMF_L1ROUT:
+ (void)printf("lev-1-routing ");
+ if (length < sizeof(struct l1rout))
+ goto trunc;
+ TCHECK(cmp->cm_l1rou);
+ src = EXTRACT_LE_16BITS(cmp->cm_l1rou.r1_src);
+ (void)printf("src %s ", dnaddr_string(src));
+ ret = print_l1_routes(&(rhpx[sizeof(struct l1rout)]),
+ length - sizeof(struct l1rout));
+ break;
+ case RMF_L2ROUT:
+ (void)printf("lev-2-routing ");
+ if (length < sizeof(struct l2rout))
+ goto trunc;
+ TCHECK(cmp->cm_l2rout);
+ src = EXTRACT_LE_16BITS(cmp->cm_l2rout.r2_src);
+ (void)printf("src %s ", dnaddr_string(src));
+ ret = print_l2_routes(&(rhpx[sizeof(struct l2rout)]),
+ length - sizeof(struct l2rout));
+ break;
+ case RMF_RHELLO:
+ (void)printf("router-hello ");
+ if (length < sizeof(struct rhellomsg))
+ goto trunc;
+ TCHECK(cmp->cm_rhello);
+ vers = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_vers);
+ eco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_eco);
+ ueco = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_ueco);
+ memcpy((char *)&srcea, (char *)&(cmp->cm_rhello.rh_src),
+ sizeof(srcea));
+ src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr);
+ info = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_info);
+ blksize = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_blksize);
+ priority = EXTRACT_LE_8BITS(cmp->cm_rhello.rh_priority);
+ hello = EXTRACT_LE_16BITS(cmp->cm_rhello.rh_hello);
+ print_i_info(info);
+ (void)printf(
+ "vers %d eco %d ueco %d src %s blksize %d pri %d hello %d",
+ vers, eco, ueco, dnaddr_string(src),
+ blksize, priority, hello);
+ ret = print_elist(&(rhpx[sizeof(struct rhellomsg)]),
+ length - sizeof(struct rhellomsg));
+ break;
+ case RMF_EHELLO:
+ (void)printf("endnode-hello ");
+ if (length < sizeof(struct ehellomsg))
+ goto trunc;
+ TCHECK(cmp->cm_ehello);
+ vers = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_vers);
+ eco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_eco);
+ ueco = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_ueco);
+ memcpy((char *)&srcea, (char *)&(cmp->cm_ehello.eh_src),
+ sizeof(srcea));
+ src = EXTRACT_LE_16BITS(srcea.dne_remote.dne_nodeaddr);
+ info = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_info);
+ blksize = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_blksize);
+ /*seed*/
+ memcpy((char *)&rtea, (char *)&(cmp->cm_ehello.eh_router),
+ sizeof(rtea));
+ dst = EXTRACT_LE_16BITS(rtea.dne_remote.dne_nodeaddr);
+ hello = EXTRACT_LE_16BITS(cmp->cm_ehello.eh_hello);
+ other = EXTRACT_LE_8BITS(cmp->cm_ehello.eh_data);
+ print_i_info(info);
+ (void)printf(
+ "vers %d eco %d ueco %d src %s blksize %d rtr %s hello %d data %o",
+ vers, eco, ueco, dnaddr_string(src),
+ blksize, dnaddr_string(dst), hello, other);
+ ret = 1;
+ break;
+
+ default:
+ (void)printf("unknown control message");
+ default_print((u_char *)rhp, min(length, caplen));
+ ret = 1;
+ break;
+ }
+ return (ret);
+
+trunc:
+ return (0);
+}
+
+static void
+print_t_info(int info)
+{
+ int ntype = info & 3;
+ switch (ntype) {
+ case 0: (void)printf("reserved-ntype? "); break;
+ case TI_L2ROUT: (void)printf("l2rout "); break;
+ case TI_L1ROUT: (void)printf("l1rout "); break;
+ case TI_ENDNODE: (void)printf("endnode "); break;
+ }
+ if (info & TI_VERIF)
+ (void)printf("verif ");
+ if (info & TI_BLOCK)
+ (void)printf("blo ");
+}
+
+static int
+print_l1_routes(const char *rp, u_int len)
+{
+ int count;
+ int id;
+ int info;
+
+ /* The last short is a checksum */
+ while (len > (3 * sizeof(short))) {
+ TCHECK2(*rp, 3 * sizeof(short));
+ count = EXTRACT_LE_16BITS(rp);
+ if (count > 1024)
+ return (1); /* seems to be bogus from here on */
+ rp += sizeof(short);
+ len -= sizeof(short);
+ id = EXTRACT_LE_16BITS(rp);
+ rp += sizeof(short);
+ len -= sizeof(short);
+ info = EXTRACT_LE_16BITS(rp);
+ rp += sizeof(short);
+ len -= sizeof(short);
+ (void)printf("{ids %d-%d cost %d hops %d} ", id, id + count,
+ RI_COST(info), RI_HOPS(info));
+ }
+ return (1);
+
+trunc:
+ return (0);
+}
+
+static int
+print_l2_routes(const char *rp, u_int len)
+{
+ int count;
+ int area;
+ int info;
+
+ /* The last short is a checksum */
+ while (len > (3 * sizeof(short))) {
+ TCHECK2(*rp, 3 * sizeof(short));
+ count = EXTRACT_LE_16BITS(rp);
+ if (count > 1024)
+ return (1); /* seems to be bogus from here on */
+ rp += sizeof(short);
+ len -= sizeof(short);
+ area = EXTRACT_LE_16BITS(rp);
+ rp += sizeof(short);
+ len -= sizeof(short);
+ info = EXTRACT_LE_16BITS(rp);
+ rp += sizeof(short);
+ len -= sizeof(short);
+ (void)printf("{areas %d-%d cost %d hops %d} ", area, area + count,
+ RI_COST(info), RI_HOPS(info));
+ }
+ return (1);
+
+trunc:
+ return (0);
+}
+
+static void
+print_i_info(int info)
+{
+ int ntype = info & II_TYPEMASK;
+ switch (ntype) {
+ case 0: (void)printf("reserved-ntype? "); break;
+ case II_L2ROUT: (void)printf("l2rout "); break;
+ case II_L1ROUT: (void)printf("l1rout "); break;
+ case II_ENDNODE: (void)printf("endnode "); break;
+ }
+ if (info & II_VERIF)
+ (void)printf("verif ");
+ if (info & II_NOMCAST)
+ (void)printf("nomcast ");
+ if (info & II_BLOCK)
+ (void)printf("blo ");
+}
+
+static int
+print_elist(const char *elp _U_, u_int len _U_)
+{
+ /* Not enough examples available for me to debug this */
+ return (1);
+}
+
+static int
+print_nsp(const u_char *nspp, u_int nsplen)
+{
+ const struct nsphdr *nsphp = (struct nsphdr *)nspp;
+ int dst, src, flags;
+
+ if (nsplen < sizeof(struct nsphdr))
+ goto trunc;
+ TCHECK(*nsphp);
+ flags = EXTRACT_LE_8BITS(nsphp->nh_flags);
+ dst = EXTRACT_LE_16BITS(nsphp->nh_dst);
+ src = EXTRACT_LE_16BITS(nsphp->nh_src);
+
+ switch (flags & NSP_TYPEMASK) {
+ case MFT_DATA:
+ switch (flags & NSP_SUBMASK) {
+ case MFS_BOM:
+ case MFS_MOM:
+ case MFS_EOM:
+ case MFS_BOM+MFS_EOM:
+ printf("data %d>%d ", src, dst);
+ {
+ struct seghdr *shp = (struct seghdr *)nspp;
+ int ack;
+#ifdef PRINT_NSPDATA
+ u_char *dp;
+#endif
+ u_int data_off = sizeof(struct minseghdr);
+
+ if (nsplen < data_off)
+ goto trunc;
+ TCHECK(shp->sh_seq[0]);
+ ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
+ if (ack & SGQ_ACK) { /* acknum field */
+ if ((ack & SGQ_NAK) == SGQ_NAK)
+ (void)printf("nak %d ", ack & SGQ_MASK);
+ else
+ (void)printf("ack %d ", ack & SGQ_MASK);
+ data_off += sizeof(short);
+ if (nsplen < data_off)
+ goto trunc;
+ TCHECK(shp->sh_seq[1]);
+ ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
+ if (ack & SGQ_OACK) { /* ackoth field */
+ if ((ack & SGQ_ONAK) == SGQ_ONAK)
+ (void)printf("onak %d ", ack & SGQ_MASK);
+ else
+ (void)printf("oack %d ", ack & SGQ_MASK);
+ data_off += sizeof(short);
+ if (nsplen < data_off)
+ goto trunc;
+ TCHECK(shp->sh_seq[2]);
+ ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
+ }
+ }
+ (void)printf("seg %d ", ack & SGQ_MASK);
+#ifdef PRINT_NSPDATA
+ if (nsplen > data_off) {
+ dp = &(nspp[data_off]);
+ TCHECK2(*dp, nsplen - data_off);
+ pdata(dp, nsplen - data_off);
+ }
+#endif
+ }
+ break;
+ case MFS_ILS+MFS_INT:
+ printf("intr ");
+ {
+ struct seghdr *shp = (struct seghdr *)nspp;
+ int ack;
+#ifdef PRINT_NSPDATA
+ u_char *dp;
+#endif
+ u_int data_off = sizeof(struct minseghdr);
+
+ if (nsplen < data_off)
+ goto trunc;
+ TCHECK(shp->sh_seq[0]);
+ ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
+ if (ack & SGQ_ACK) { /* acknum field */
+ if ((ack & SGQ_NAK) == SGQ_NAK)
+ (void)printf("nak %d ", ack & SGQ_MASK);
+ else
+ (void)printf("ack %d ", ack & SGQ_MASK);
+ data_off += sizeof(short);
+ if (nsplen < data_off)
+ goto trunc;
+ TCHECK(shp->sh_seq[1]);
+ ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
+ if (ack & SGQ_OACK) { /* ackdat field */
+ if ((ack & SGQ_ONAK) == SGQ_ONAK)
+ (void)printf("nakdat %d ", ack & SGQ_MASK);
+ else
+ (void)printf("ackdat %d ", ack & SGQ_MASK);
+ data_off += sizeof(short);
+ if (nsplen < data_off)
+ goto trunc;
+ TCHECK(shp->sh_seq[2]);
+ ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
+ }
+ }
+ (void)printf("seg %d ", ack & SGQ_MASK);
+#ifdef PRINT_NSPDATA
+ if (nsplen > data_off) {
+ dp = &(nspp[data_off]);
+ TCHECK2(*dp, nsplen - data_off);
+ pdata(dp, nsplen - data_off);
+ }
+#endif
+ }
+ break;
+ case MFS_ILS:
+ (void)printf("link-service %d>%d ", src, dst);
+ {
+ struct seghdr *shp = (struct seghdr *)nspp;
+ struct lsmsg *lsmp =
+ (struct lsmsg *)&(nspp[sizeof(struct seghdr)]);
+ int ack;
+ int lsflags, fcval;
+
+ if (nsplen < sizeof(struct seghdr) + sizeof(struct lsmsg))
+ goto trunc;
+ TCHECK(shp->sh_seq[0]);
+ ack = EXTRACT_LE_16BITS(shp->sh_seq[0]);
+ if (ack & SGQ_ACK) { /* acknum field */
+ if ((ack & SGQ_NAK) == SGQ_NAK)
+ (void)printf("nak %d ", ack & SGQ_MASK);
+ else
+ (void)printf("ack %d ", ack & SGQ_MASK);
+ TCHECK(shp->sh_seq[1]);
+ ack = EXTRACT_LE_16BITS(shp->sh_seq[1]);
+ if (ack & SGQ_OACK) { /* ackdat field */
+ if ((ack & SGQ_ONAK) == SGQ_ONAK)
+ (void)printf("nakdat %d ", ack & SGQ_MASK);
+ else
+ (void)printf("ackdat %d ", ack & SGQ_MASK);
+ TCHECK(shp->sh_seq[2]);
+ ack = EXTRACT_LE_16BITS(shp->sh_seq[2]);
+ }
+ }
+ (void)printf("seg %d ", ack & SGQ_MASK);
+ TCHECK(*lsmp);
+ lsflags = EXTRACT_LE_8BITS(lsmp->ls_lsflags);
+ fcval = EXTRACT_LE_8BITS(lsmp->ls_fcval);
+ switch (lsflags & LSI_MASK) {
+ case LSI_DATA:
+ (void)printf("dat seg count %d ", fcval);
+ switch (lsflags & LSM_MASK) {
+ case LSM_NOCHANGE:
+ break;
+ case LSM_DONOTSEND:
+ (void)printf("donotsend-data ");
+ break;
+ case LSM_SEND:
+ (void)printf("send-data ");
+ break;
+ default:
+ (void)printf("reserved-fcmod? %x", lsflags);
+ break;
+ }
+ break;
+ case LSI_INTR:
+ (void)printf("intr req count %d ", fcval);
+ break;
+ default:
+ (void)printf("reserved-fcval-int? %x", lsflags);
+ break;
+ }
+ }
+ break;
+ default:
+ (void)printf("reserved-subtype? %x %d > %d", flags, src, dst);
+ break;
+ }
+ break;
+ case MFT_ACK:
+ switch (flags & NSP_SUBMASK) {
+ case MFS_DACK:
+ (void)printf("data-ack %d>%d ", src, dst);
+ {
+ struct ackmsg *amp = (struct ackmsg *)nspp;
+ int ack;
+
+ if (nsplen < sizeof(struct ackmsg))
+ goto trunc;
+ TCHECK(*amp);
+ ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]);
+ if (ack & SGQ_ACK) { /* acknum field */
+ if ((ack & SGQ_NAK) == SGQ_NAK)
+ (void)printf("nak %d ", ack & SGQ_MASK);
+ else
+ (void)printf("ack %d ", ack & SGQ_MASK);
+ ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]);
+ if (ack & SGQ_OACK) { /* ackoth field */
+ if ((ack & SGQ_ONAK) == SGQ_ONAK)
+ (void)printf("onak %d ", ack & SGQ_MASK);
+ else
+ (void)printf("oack %d ", ack & SGQ_MASK);
+ }
+ }
+ }
+ break;
+ case MFS_IACK:
+ (void)printf("ils-ack %d>%d ", src, dst);
+ {
+ struct ackmsg *amp = (struct ackmsg *)nspp;
+ int ack;
+
+ if (nsplen < sizeof(struct ackmsg))
+ goto trunc;
+ TCHECK(*amp);
+ ack = EXTRACT_LE_16BITS(amp->ak_acknum[0]);
+ if (ack & SGQ_ACK) { /* acknum field */
+ if ((ack & SGQ_NAK) == SGQ_NAK)
+ (void)printf("nak %d ", ack & SGQ_MASK);
+ else
+ (void)printf("ack %d ", ack & SGQ_MASK);
+ TCHECK(amp->ak_acknum[1]);
+ ack = EXTRACT_LE_16BITS(amp->ak_acknum[1]);
+ if (ack & SGQ_OACK) { /* ackdat field */
+ if ((ack & SGQ_ONAK) == SGQ_ONAK)
+ (void)printf("nakdat %d ", ack & SGQ_MASK);
+ else
+ (void)printf("ackdat %d ", ack & SGQ_MASK);
+ }
+ }
+ }
+ break;
+ case MFS_CACK:
+ (void)printf("conn-ack %d", dst);
+ break;
+ default:
+ (void)printf("reserved-acktype? %x %d > %d", flags, src, dst);
+ break;
+ }
+ break;
+ case MFT_CTL:
+ switch (flags & NSP_SUBMASK) {
+ case MFS_CI:
+ case MFS_RCI:
+ if ((flags & NSP_SUBMASK) == MFS_CI)
+ (void)printf("conn-initiate ");
+ else
+ (void)printf("retrans-conn-initiate ");
+ (void)printf("%d>%d ", src, dst);
+ {
+ struct cimsg *cimp = (struct cimsg *)nspp;
+ int services, info, segsize;
+#ifdef PRINT_NSPDATA
+ u_char *dp;
+#endif
+
+ if (nsplen < sizeof(struct cimsg))
+ goto trunc;
+ TCHECK(*cimp);
+ services = EXTRACT_LE_8BITS(cimp->ci_services);
+ info = EXTRACT_LE_8BITS(cimp->ci_info);
+ segsize = EXTRACT_LE_16BITS(cimp->ci_segsize);
+
+ switch (services & COS_MASK) {
+ case COS_NONE:
+ break;
+ case COS_SEGMENT:
+ (void)printf("seg ");
+ break;
+ case COS_MESSAGE:
+ (void)printf("msg ");
+ break;
+ case COS_CRYPTSER:
+ (void)printf("crypt ");
+ break;
+ }
+ switch (info & COI_MASK) {
+ case COI_32:
+ (void)printf("ver 3.2 ");
+ break;
+ case COI_31:
+ (void)printf("ver 3.1 ");
+ break;
+ case COI_40:
+ (void)printf("ver 4.0 ");
+ break;
+ case COI_41:
+ (void)printf("ver 4.1 ");
+ break;
+ }
+ (void)printf("segsize %d ", segsize);
+#ifdef PRINT_NSPDATA
+ if (nsplen > sizeof(struct cimsg)) {
+ dp = &(nspp[sizeof(struct cimsg)]);
+ TCHECK2(*dp, nsplen - sizeof(struct cimsg));
+ pdata(dp, nsplen - sizeof(struct cimsg));
+ }
+#endif
+ }
+ break;
+ case MFS_CC:
+ (void)printf("conn-confirm %d>%d ", src, dst);
+ {
+ struct ccmsg *ccmp = (struct ccmsg *)nspp;
+ int services, info;
+ u_int segsize, optlen;
+#ifdef PRINT_NSPDATA
+ u_char *dp;
+#endif
+
+ if (nsplen < sizeof(struct ccmsg))
+ goto trunc;
+ TCHECK(*ccmp);
+ services = EXTRACT_LE_8BITS(ccmp->cc_services);
+ info = EXTRACT_LE_8BITS(ccmp->cc_info);
+ segsize = EXTRACT_LE_16BITS(ccmp->cc_segsize);
+ optlen = EXTRACT_LE_8BITS(ccmp->cc_optlen);
+
+ switch (services & COS_MASK) {
+ case COS_NONE:
+ break;
+ case COS_SEGMENT:
+ (void)printf("seg ");
+ break;
+ case COS_MESSAGE:
+ (void)printf("msg ");
+ break;
+ case COS_CRYPTSER:
+ (void)printf("crypt ");
+ break;
+ }
+ switch (info & COI_MASK) {
+ case COI_32:
+ (void)printf("ver 3.2 ");
+ break;
+ case COI_31:
+ (void)printf("ver 3.1 ");
+ break;
+ case COI_40:
+ (void)printf("ver 4.0 ");
+ break;
+ case COI_41:
+ (void)printf("ver 4.1 ");
+ break;
+ }
+ (void)printf("segsize %d ", segsize);
+ if (optlen) {
+ (void)printf("optlen %d ", optlen);
+#ifdef PRINT_NSPDATA
+ if (optlen > nsplen - sizeof(struct ccmsg))
+ goto trunc;
+ dp = &(nspp[sizeof(struct ccmsg)]);
+ TCHECK2(*dp, optlen);
+ pdata(dp, optlen);
+#endif
+ }
+ }
+ break;
+ case MFS_DI:
+ (void)printf("disconn-initiate %d>%d ", src, dst);
+ {
+ struct dimsg *dimp = (struct dimsg *)nspp;
+ int reason;
+ u_int optlen;
+#ifdef PRINT_NSPDATA
+ u_char *dp;
+#endif
+
+ if (nsplen < sizeof(struct dimsg))
+ goto trunc;
+ TCHECK(*dimp);
+ reason = EXTRACT_LE_16BITS(dimp->di_reason);
+ optlen = EXTRACT_LE_8BITS(dimp->di_optlen);
+
+ print_reason(reason);
+ if (optlen) {
+ (void)printf("optlen %d ", optlen);
+#ifdef PRINT_NSPDATA
+ if (optlen > nsplen - sizeof(struct dimsg))
+ goto trunc;
+ dp = &(nspp[sizeof(struct dimsg)]);
+ TCHECK2(*dp, optlen);
+ pdata(dp, optlen);
+#endif
+ }
+ }
+ break;
+ case MFS_DC:
+ (void)printf("disconn-confirm %d>%d ", src, dst);
+ {
+ struct dcmsg *dcmp = (struct dcmsg *)nspp;
+ int reason;
+
+ TCHECK(*dcmp);
+ reason = EXTRACT_LE_16BITS(dcmp->dc_reason);
+
+ print_reason(reason);
+ }
+ break;
+ default:
+ (void)printf("reserved-ctltype? %x %d > %d", flags, src, dst);
+ break;
+ }
+ break;
+ default:
+ (void)printf("reserved-type? %x %d > %d", flags, src, dst);
+ break;
+ }
+ return (1);
+
+trunc:
+ return (0);
+}
+
+static struct tok reason2str[] = {
+ { UC_OBJREJECT, "object rejected connect" },
+ { UC_RESOURCES, "insufficient resources" },
+ { UC_NOSUCHNODE, "unrecognized node name" },
+ { DI_SHUT, "node is shutting down" },
+ { UC_NOSUCHOBJ, "unrecognized object" },
+ { UC_INVOBJFORMAT, "invalid object name format" },
+ { UC_OBJTOOBUSY, "object too busy" },
+ { DI_PROTOCOL, "protocol error discovered" },
+ { DI_TPA, "third party abort" },
+ { UC_USERABORT, "user abort" },
+ { UC_INVNODEFORMAT, "invalid node name format" },
+ { UC_LOCALSHUT, "local node shutting down" },
+ { DI_LOCALRESRC, "insufficient local resources" },
+ { DI_REMUSERRESRC, "insufficient remote user resources" },
+ { UC_ACCESSREJECT, "invalid access control information" },
+ { DI_BADACCNT, "bad ACCOUNT information" },
+ { UC_NORESPONSE, "no response from object" },
+ { UC_UNREACHABLE, "node unreachable" },
+ { DC_NOLINK, "no link terminate" },
+ { DC_COMPLETE, "disconnect complete" },
+ { DI_BADIMAGE, "bad image data in connect" },
+ { DI_SERVMISMATCH, "cryptographic service mismatch" },
+ { 0, NULL }
+};
+
+static void
+print_reason(register int reason)
+{
+ printf("%s ", tok2str(reason2str, "reason-%d", reason));
+}
+
+const char *
+dnnum_string(u_short dnaddr)
+{
+ char *str;
+ size_t siz;
+ int area = (u_short)(dnaddr & AREAMASK) >> AREASHIFT;
+ int node = dnaddr & NODEMASK;
+
+ str = (char *)malloc(siz = sizeof("00.0000"));
+ if (str == NULL)
+ error("dnnum_string: malloc");
+ snprintf(str, siz, "%d.%d", area, node);
+ return(str);
+}
+
+const char *
+dnname_string(u_short dnaddr)
+{
+#ifdef HAVE_DNET_HTOA
+ struct dn_naddr dna;
+
+ dna.a_len = sizeof(short);
+ memcpy((char *)dna.a_addr, (char *)&dnaddr, sizeof(short));
+ return (strdup(dnet_htoa(&dna)));
+#else
+ return(dnnum_string(dnaddr)); /* punt */
+#endif
+}
+
+#ifdef PRINT_NSPDATA
+static void
+pdata(u_char *dp, u_int maxlen)
+{
+ char c;
+ u_int x = maxlen;
+
+ while (x-- > 0) {
+ c = *dp++;
+ safeputchar(c);
+ }
+}
+#endif
diff --git a/freebsd/contrib/tcpdump/print-dhcp6.c b/freebsd/contrib/tcpdump/print-dhcp6.c
new file mode 100644
index 00000000..fbb31261
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-dhcp6.c
@@ -0,0 +1,871 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 1998 and 1999 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * RFC3315: DHCPv6
+ * supported DHCPv6 options:
+ * RFC3319: Session Initiation Protocol (SIP) Servers options,
+ * RFC3633: IPv6 Prefix options,
+ * RFC3646: DNS Configuration options,
+ * RFC3898: Network Information Service (NIS) Configuration options,
+ * RFC4075: Simple Network Time Protocol (SNTP) Configuration option,
+ * RFC4242: Information Refresh Time option,
+ * RFC4280: Broadcast and Multicast Control Servers options,
+ * RFC6334: Dual-Stack Lite option,
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-dhcp6.c,v 1.37 2008-02-06 10:26:09 guy Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+/* lease duration */
+#define DHCP6_DURATITION_INFINITE 0xffffffff
+
+/* Error Values */
+#define DH6ERR_FAILURE 16
+#define DH6ERR_AUTHFAIL 17
+#define DH6ERR_POORLYFORMED 18
+#define DH6ERR_UNAVAIL 19
+#define DH6ERR_OPTUNAVAIL 20
+
+/* Message type */
+#define DH6_SOLICIT 1
+#define DH6_ADVERTISE 2
+#define DH6_REQUEST 3
+#define DH6_CONFIRM 4
+#define DH6_RENEW 5
+#define DH6_REBIND 6
+#define DH6_REPLY 7
+#define DH6_RELEASE 8
+#define DH6_DECLINE 9
+#define DH6_RECONFIGURE 10
+#define DH6_INFORM_REQ 11
+#define DH6_RELAY_FORW 12
+#define DH6_RELAY_REPLY 13
+#define DH6_LEASEQUERY 14
+#define DH6_LQ_REPLY 15
+
+/* DHCP6 base packet format */
+struct dhcp6 {
+ union {
+ u_int8_t m;
+ u_int32_t x;
+ } dh6_msgtypexid;
+ /* options follow */
+};
+#define dh6_msgtype dh6_msgtypexid.m
+#define dh6_xid dh6_msgtypexid.x
+#define DH6_XIDMASK 0x00ffffff
+
+/* DHCPv6 relay messages */
+struct dhcp6_relay {
+ u_int8_t dh6relay_msgtype;
+ u_int8_t dh6relay_hcnt;
+ u_int8_t dh6relay_linkaddr[16]; /* XXX: badly aligned */
+ u_int8_t dh6relay_peeraddr[16];
+ /* options follow */
+};
+
+/* options */
+#define DH6OPT_CLIENTID 1
+#define DH6OPT_SERVERID 2
+#define DH6OPT_IA_NA 3
+#define DH6OPT_IA_TA 4
+#define DH6OPT_IA_ADDR 5
+#define DH6OPT_ORO 6
+#define DH6OPT_PREFERENCE 7
+# define DH6OPT_PREF_MAX 255
+#define DH6OPT_ELAPSED_TIME 8
+#define DH6OPT_RELAY_MSG 9
+/*#define DH6OPT_SERVER_MSG 10 deprecated */
+#define DH6OPT_AUTH 11
+# define DH6OPT_AUTHPROTO_DELAYED 2
+# define DH6OPT_AUTHPROTO_RECONFIG 3
+# define DH6OPT_AUTHALG_HMACMD5 1
+# define DH6OPT_AUTHRDM_MONOCOUNTER 0
+# define DH6OPT_AUTHRECONFIG_KEY 1
+# define DH6OPT_AUTHRECONFIG_HMACMD5 2
+#define DH6OPT_UNICAST 12
+#define DH6OPT_STATUS_CODE 13
+# define DH6OPT_STCODE_SUCCESS 0
+# define DH6OPT_STCODE_UNSPECFAIL 1
+# define DH6OPT_STCODE_NOADDRAVAIL 2
+# define DH6OPT_STCODE_NOBINDING 3
+# define DH6OPT_STCODE_NOTONLINK 4
+# define DH6OPT_STCODE_USEMULTICAST 5
+# define DH6OPT_STCODE_NOPREFIXAVAIL 6
+# define DH6OPT_STCODE_UNKNOWNQUERYTYPE 7
+# define DH6OPT_STCODE_MALFORMEDQUERY 8
+# define DH6OPT_STCODE_NOTCONFIGURED 9
+# define DH6OPT_STCODE_NOTALLOWED 10
+#define DH6OPT_RAPID_COMMIT 14
+#define DH6OPT_USER_CLASS 15
+#define DH6OPT_VENDOR_CLASS 16
+#define DH6OPT_VENDOR_OPTS 17
+#define DH6OPT_INTERFACE_ID 18
+#define DH6OPT_RECONF_MSG 19
+#define DH6OPT_RECONF_ACCEPT 20
+#define DH6OPT_SIP_SERVER_D 21
+#define DH6OPT_SIP_SERVER_A 22
+#define DH6OPT_DNS 23
+#define DH6OPT_DNSNAME 24
+#define DH6OPT_IA_PD 25
+#define DH6OPT_IA_PD_PREFIX 26
+#define DH6OPT_NIS_SERVERS 27
+#define DH6OPT_NISP_SERVERS 28
+#define DH6OPT_NIS_NAME 29
+#define DH6OPT_NISP_NAME 30
+#define DH6OPT_NTP_SERVERS 31
+#define DH6OPT_LIFETIME 32
+#define DH6OPT_BCMCS_SERVER_D 33
+#define DH6OPT_BCMCS_SERVER_A 34
+#define DH6OPT_GEOCONF_CIVIC 36
+#define DH6OPT_REMOTE_ID 37
+#define DH6OPT_SUBSCRIBER_ID 38
+#define DH6OPT_CLIENT_FQDN 39
+#define DH6OPT_PANA_AGENT 40
+#define DH6OPT_NEW_POSIX_TIMEZONE 41
+#define DH6OPT_NEW_TZDB_TIMEZONE 42
+#define DH6OPT_ERO 43
+#define DH6OPT_LQ_QUERY 44
+#define DH6OPT_CLIENT_DATA 45
+#define DH6OPT_CLT_TIME 46
+#define DH6OPT_LQ_RELAY_DATA 47
+#define DH6OPT_LQ_CLIENT_LINK 48
+#define DH6OPT_AFTR_NAME 64
+
+struct dhcp6opt {
+ u_int16_t dh6opt_type;
+ u_int16_t dh6opt_len;
+ /* type-dependent data follows */
+};
+
+static const char *
+dhcp6opt_name(int type)
+{
+ static char genstr[sizeof("opt_65535") + 1]; /* XXX thread unsafe */
+
+ if (type > 65535)
+ return "INVALID-option";
+
+ switch(type) {
+ case DH6OPT_CLIENTID:
+ return "client-ID";
+ case DH6OPT_SERVERID:
+ return "server-ID";
+ case DH6OPT_IA_NA:
+ return "IA_NA";
+ case DH6OPT_IA_TA:
+ return "IA_TA";
+ case DH6OPT_IA_ADDR:
+ return "IA_ADDR";
+ case DH6OPT_ORO:
+ return "option-request";
+ case DH6OPT_PREFERENCE:
+ return "preference";
+ case DH6OPT_ELAPSED_TIME:
+ return "elapsed-time";
+ case DH6OPT_RELAY_MSG:
+ return "relay-message";
+ case DH6OPT_AUTH:
+ return "authentication";
+ case DH6OPT_UNICAST:
+ return "server-unicast";
+ case DH6OPT_STATUS_CODE:
+ return "status-code";
+ case DH6OPT_RAPID_COMMIT:
+ return "rapid-commit";
+ case DH6OPT_USER_CLASS:
+ return "user-class";
+ case DH6OPT_VENDOR_CLASS:
+ return "vendor-class";
+ case DH6OPT_VENDOR_OPTS:
+ return "vendor-specific-info";
+ case DH6OPT_INTERFACE_ID:
+ return "interface-ID";
+ case DH6OPT_RECONF_MSG:
+ return "reconfigure-message";
+ case DH6OPT_RECONF_ACCEPT:
+ return "reconfigure-accept";
+ case DH6OPT_SIP_SERVER_D:
+ return "SIP-servers-domain";
+ case DH6OPT_SIP_SERVER_A:
+ return "SIP-servers-address";
+ case DH6OPT_DNS:
+ return "DNS-server";
+ case DH6OPT_DNSNAME:
+ return "DNS-search-list";
+ case DH6OPT_IA_PD:
+ return "IA_PD";
+ case DH6OPT_IA_PD_PREFIX:
+ return "IA_PD-prefix";
+ case DH6OPT_NTP_SERVERS:
+ return "NTP-server";
+ case DH6OPT_LIFETIME:
+ return "lifetime";
+ case DH6OPT_NIS_SERVERS:
+ return "NIS-server";
+ case DH6OPT_NISP_SERVERS:
+ return "NIS+-server";
+ case DH6OPT_NIS_NAME:
+ return "NIS-domain-name";
+ case DH6OPT_NISP_NAME:
+ return "NIS+-domain-name";
+ case DH6OPT_BCMCS_SERVER_D:
+ return "BCMCS-domain-name";
+ case DH6OPT_BCMCS_SERVER_A:
+ return "BCMCS-server";
+ case DH6OPT_GEOCONF_CIVIC:
+ return "Geoconf-Civic";
+ case DH6OPT_REMOTE_ID:
+ return "Remote-ID";
+ case DH6OPT_SUBSCRIBER_ID:
+ return "Subscriber-ID";
+ case DH6OPT_CLIENT_FQDN:
+ return "Client-FQDN";
+ case DH6OPT_PANA_AGENT:
+ return "PANA-agent";
+ case DH6OPT_NEW_POSIX_TIMEZONE:
+ return "POSIX-timezone";
+ case DH6OPT_NEW_TZDB_TIMEZONE:
+ return "POSIX-tz-database";
+ case DH6OPT_ERO:
+ return "Echo-request-option";
+ case DH6OPT_LQ_QUERY:
+ return "Lease-query";
+ case DH6OPT_CLIENT_DATA:
+ return "LQ-client-data";
+ case DH6OPT_CLT_TIME:
+ return "Clt-time";
+ case DH6OPT_LQ_RELAY_DATA:
+ return "LQ-relay-data";
+ case DH6OPT_LQ_CLIENT_LINK:
+ return "LQ-client-link";
+ case DH6OPT_AFTR_NAME:
+ return "AFTR-Name";
+ default:
+ snprintf(genstr, sizeof(genstr), "opt_%d", type);
+ return(genstr);
+ }
+}
+
+static const char *
+dhcp6stcode(int code)
+{
+ static char genstr[sizeof("code255") + 1]; /* XXX thread unsafe */
+
+ if (code > 255)
+ return "INVALID code";
+
+ switch(code) {
+ case DH6OPT_STCODE_SUCCESS:
+ return "success";
+ case DH6OPT_STCODE_UNSPECFAIL:
+ return "unspec failure";
+ case DH6OPT_STCODE_NOADDRAVAIL:
+ return "no addresses";
+ case DH6OPT_STCODE_NOBINDING:
+ return "no binding";
+ case DH6OPT_STCODE_NOTONLINK:
+ return "not on-link";
+ case DH6OPT_STCODE_USEMULTICAST:
+ return "use multicast";
+ case DH6OPT_STCODE_NOPREFIXAVAIL:
+ return "no prefixes";
+ case DH6OPT_STCODE_UNKNOWNQUERYTYPE:
+ return "unknown query type";
+ case DH6OPT_STCODE_MALFORMEDQUERY:
+ return "malformed query";
+ case DH6OPT_STCODE_NOTCONFIGURED:
+ return "not configured";
+ case DH6OPT_STCODE_NOTALLOWED:
+ return "not allowed";
+ default:
+ snprintf(genstr, sizeof(genstr), "code%d", code);
+ return(genstr);
+ }
+}
+
+static void
+dhcp6opt_print(const u_char *cp, const u_char *ep)
+{
+ struct dhcp6opt *dh6o;
+ u_char *tp;
+ size_t i;
+ u_int16_t opttype;
+ size_t optlen;
+ u_int8_t auth_proto;
+ u_int authinfolen, authrealmlen;
+
+ if (cp == ep)
+ return;
+ while (cp < ep) {
+ if (ep < cp + sizeof(*dh6o))
+ goto trunc;
+ dh6o = (struct dhcp6opt *)cp;
+ TCHECK(*dh6o);
+ optlen = EXTRACT_16BITS(&dh6o->dh6opt_len);
+ if (ep < cp + sizeof(*dh6o) + optlen)
+ goto trunc;
+ opttype = EXTRACT_16BITS(&dh6o->dh6opt_type);
+ printf(" (%s", dhcp6opt_name(opttype));
+ switch (opttype) {
+ case DH6OPT_CLIENTID:
+ case DH6OPT_SERVERID:
+ if (optlen < 2) {
+ /*(*/
+ printf(" ?)");
+ break;
+ }
+ tp = (u_char *)(dh6o + 1);
+ switch (EXTRACT_16BITS(tp)) {
+ case 1:
+ if (optlen >= 2 + 6) {
+ printf(" hwaddr/time type %u time %u ",
+ EXTRACT_16BITS(&tp[2]),
+ EXTRACT_32BITS(&tp[4]));
+ for (i = 8; i < optlen; i++)
+ printf("%02x", tp[i]);
+ /*(*/
+ printf(")");
+ } else {
+ /*(*/
+ printf(" ?)");
+ }
+ break;
+ case 2:
+ if (optlen >= 2 + 8) {
+ printf(" vid ");
+ for (i = 2; i < 2 + 8; i++)
+ printf("%02x", tp[i]);
+ /*(*/
+ printf(")");
+ } else {
+ /*(*/
+ printf(" ?)");
+ }
+ break;
+ case 3:
+ if (optlen >= 2 + 2) {
+ printf(" hwaddr type %u ",
+ EXTRACT_16BITS(&tp[2]));
+ for (i = 4; i < optlen; i++)
+ printf("%02x", tp[i]);
+ /*(*/
+ printf(")");
+ } else {
+ /*(*/
+ printf(" ?)");
+ }
+ break;
+ default:
+ printf(" type %d)", EXTRACT_16BITS(tp));
+ break;
+ }
+ break;
+ case DH6OPT_IA_ADDR:
+ if (optlen < 24) {
+ /*(*/
+ printf(" ?)");
+ break;
+ }
+ tp = (u_char *)(dh6o + 1);
+ printf(" %s", ip6addr_string(&tp[0]));
+ printf(" pltime:%u vltime:%u",
+ EXTRACT_32BITS(&tp[16]),
+ EXTRACT_32BITS(&tp[20]));
+ if (optlen > 24) {
+ /* there are sub-options */
+ dhcp6opt_print(tp + 24, tp + optlen);
+ }
+ printf(")");
+ break;
+ case DH6OPT_ORO:
+ case DH6OPT_ERO:
+ if (optlen % 2) {
+ printf(" ?)");
+ break;
+ }
+ tp = (u_char *)(dh6o + 1);
+ for (i = 0; i < optlen; i += 2) {
+ printf(" %s",
+ dhcp6opt_name(EXTRACT_16BITS(&tp[i])));
+ }
+ printf(")");
+ break;
+ case DH6OPT_PREFERENCE:
+ if (optlen != 1) {
+ printf(" ?)");
+ break;
+ }
+ tp = (u_char *)(dh6o + 1);
+ printf(" %d)", *tp);
+ break;
+ case DH6OPT_ELAPSED_TIME:
+ if (optlen != 2) {
+ printf(" ?)");
+ break;
+ }
+ tp = (u_char *)(dh6o + 1);
+ printf(" %d)", EXTRACT_16BITS(tp));
+ break;
+ case DH6OPT_RELAY_MSG:
+ printf(" (");
+ tp = (u_char *)(dh6o + 1);
+ dhcp6_print(tp, optlen);
+ printf(")");
+ break;
+ case DH6OPT_AUTH:
+ if (optlen < 11) {
+ printf(" ?)");
+ break;
+ }
+ tp = (u_char *)(dh6o + 1);
+ auth_proto = *tp;
+ switch (auth_proto) {
+ case DH6OPT_AUTHPROTO_DELAYED:
+ printf(" proto: delayed");
+ break;
+ case DH6OPT_AUTHPROTO_RECONFIG:
+ printf(" proto: reconfigure");
+ break;
+ default:
+ printf(" proto: %d", auth_proto);
+ break;
+ }
+ tp++;
+ switch (*tp) {
+ case DH6OPT_AUTHALG_HMACMD5:
+ /* XXX: may depend on the protocol */
+ printf(", alg: HMAC-MD5");
+ break;
+ default:
+ printf(", alg: %d", *tp);
+ break;
+ }
+ tp++;
+ switch (*tp) {
+ case DH6OPT_AUTHRDM_MONOCOUNTER:
+ printf(", RDM: mono");
+ break;
+ default:
+ printf(", RDM: %d", *tp);
+ break;
+ }
+ tp++;
+ printf(", RD:");
+ for (i = 0; i < 4; i++, tp += 2)
+ printf(" %04x", EXTRACT_16BITS(tp));
+
+ /* protocol dependent part */
+ authinfolen = optlen - 11;
+ switch (auth_proto) {
+ case DH6OPT_AUTHPROTO_DELAYED:
+ if (authinfolen == 0)
+ break;
+ if (authinfolen < 20) {
+ printf(" ??");
+ break;
+ }
+ authrealmlen = authinfolen - 20;
+ if (authrealmlen > 0) {
+ printf(", realm: ");
+ }
+ for (i = 0; i < authrealmlen; i++, tp++)
+ printf("%02x", *tp);
+ printf(", key ID: %08x", EXTRACT_32BITS(tp));
+ tp += 4;
+ printf(", HMAC-MD5:");
+ for (i = 0; i < 4; i++, tp+= 4)
+ printf(" %08x", EXTRACT_32BITS(tp));
+ break;
+ case DH6OPT_AUTHPROTO_RECONFIG:
+ if (authinfolen != 17) {
+ printf(" ??");
+ break;
+ }
+ switch (*tp++) {
+ case DH6OPT_AUTHRECONFIG_KEY:
+ printf(" reconfig-key");
+ break;
+ case DH6OPT_AUTHRECONFIG_HMACMD5:
+ printf(" type: HMAC-MD5");
+ break;
+ default:
+ printf(" type: ??");
+ break;
+ }
+ printf(" value:");
+ for (i = 0; i < 4; i++, tp+= 4)
+ printf(" %08x", EXTRACT_32BITS(tp));
+ break;
+ default:
+ printf(" ??");
+ break;
+ }
+
+ printf(")");
+ break;
+ case DH6OPT_RAPID_COMMIT: /* nothing todo */
+ printf(")");
+ break;
+ case DH6OPT_INTERFACE_ID:
+ case DH6OPT_SUBSCRIBER_ID:
+ /*
+ * Since we cannot predict the encoding, print hex dump
+ * at most 10 characters.
+ */
+ tp = (u_char *)(dh6o + 1);
+ printf(" ");
+ for (i = 0; i < optlen && i < 10; i++)
+ printf("%02x", tp[i]);
+ printf("...)");
+ break;
+ case DH6OPT_RECONF_MSG:
+ tp = (u_char *)(dh6o + 1);
+ switch (*tp) {
+ case DH6_RENEW:
+ printf(" for renew)");
+ break;
+ case DH6_INFORM_REQ:
+ printf(" for inf-req)");
+ break;
+ default:
+ printf(" for ?\?\?(%02x))", *tp);
+ break;
+ }
+ break;
+ case DH6OPT_RECONF_ACCEPT: /* nothing todo */
+ printf(")");
+ break;
+ case DH6OPT_SIP_SERVER_A:
+ case DH6OPT_DNS:
+ case DH6OPT_NTP_SERVERS:
+ case DH6OPT_NIS_SERVERS:
+ case DH6OPT_NISP_SERVERS:
+ case DH6OPT_BCMCS_SERVER_A:
+ case DH6OPT_PANA_AGENT:
+ case DH6OPT_LQ_CLIENT_LINK:
+ if (optlen % 16) {
+ printf(" ?)");
+ break;
+ }
+ tp = (u_char *)(dh6o + 1);
+ for (i = 0; i < optlen; i += 16)
+ printf(" %s", ip6addr_string(&tp[i]));
+ printf(")");
+ break;
+ case DH6OPT_STATUS_CODE:
+ if (optlen < 2) {
+ printf(" ?)");
+ break;
+ }
+ tp = (u_char *)(dh6o + 1);
+ printf(" %s)", dhcp6stcode(EXTRACT_16BITS(&tp[0])));
+ break;
+ case DH6OPT_IA_NA:
+ case DH6OPT_IA_PD:
+ if (optlen < 12) {
+ printf(" ?)");
+ break;
+ }
+ tp = (u_char *)(dh6o + 1);
+ printf(" IAID:%u T1:%u T2:%u",
+ EXTRACT_32BITS(&tp[0]),
+ EXTRACT_32BITS(&tp[4]),
+ EXTRACT_32BITS(&tp[8]));
+ if (optlen > 12) {
+ /* there are sub-options */
+ dhcp6opt_print(tp + 12, tp + optlen);
+ }
+ printf(")");
+ break;
+ case DH6OPT_IA_TA:
+ if (optlen < 4) {
+ printf(" ?)");
+ break;
+ }
+ tp = (u_char *)(dh6o + 1);
+ printf(" IAID:%u", EXTRACT_32BITS(tp));
+ if (optlen > 4) {
+ /* there are sub-options */
+ dhcp6opt_print(tp + 4, tp + optlen);
+ }
+ printf(")");
+ break;
+ case DH6OPT_IA_PD_PREFIX:
+ if (optlen < 25) {
+ printf(" ?)");
+ break;
+ }
+ tp = (u_char *)(dh6o + 1);
+ printf(" %s/%d", ip6addr_string(&tp[9]), tp[8]);
+ printf(" pltime:%u vltime:%u",
+ EXTRACT_32BITS(&tp[0]),
+ EXTRACT_32BITS(&tp[4]));
+ if (optlen > 25) {
+ /* there are sub-options */
+ dhcp6opt_print(tp + 25, tp + optlen);
+ }
+ printf(")");
+ break;
+ case DH6OPT_LIFETIME:
+ case DH6OPT_CLT_TIME:
+ if (optlen != 4) {
+ printf(" ?)");
+ break;
+ }
+ tp = (u_char *)(dh6o + 1);
+ printf(" %d)", EXTRACT_32BITS(tp));
+ break;
+ case DH6OPT_REMOTE_ID:
+ if (optlen < 4) {
+ printf(" ?)");
+ break;
+ }
+ tp = (u_char *)(dh6o + 1);
+ printf(" %d ", EXTRACT_32BITS(tp));
+ /*
+ * Print hex dump first 10 characters.
+ */
+ for (i = 4; i < optlen && i < 14; i++)
+ printf("%02x", tp[i]);
+ printf("...)");
+ break;
+ case DH6OPT_LQ_QUERY:
+ if (optlen < 17) {
+ printf(" ?)");
+ break;
+ }
+ tp = (u_char *)(dh6o + 1);
+ switch (*tp) {
+ case 1:
+ printf(" by-address");
+ break;
+ case 2:
+ printf(" by-clientID");
+ break;
+ default:
+ printf(" type_%d", (int)*tp);
+ break;
+ }
+ printf(" %s", ip6addr_string(&tp[1]));
+ if (optlen > 17) {
+ /* there are query-options */
+ dhcp6opt_print(tp + 17, tp + optlen);
+ }
+ printf(")");
+ break;
+ case DH6OPT_CLIENT_DATA:
+ tp = (u_char *)(dh6o + 1);
+ if (optlen > 0) {
+ /* there are encapsulated options */
+ dhcp6opt_print(tp, tp + optlen);
+ }
+ printf(")");
+ break;
+ case DH6OPT_LQ_RELAY_DATA:
+ if (optlen < 16) {
+ printf(" ?)");
+ break;
+ }
+ tp = (u_char *)(dh6o + 1);
+ printf(" %s ", ip6addr_string(&tp[0]));
+ /*
+ * Print hex dump first 10 characters.
+ */
+ for (i = 16; i < optlen && i < 26; i++)
+ printf("%02x", tp[i]);
+ printf("...)");
+ break;
+ case DH6OPT_AFTR_NAME:
+ if (optlen < 3) {
+ printf(" ?)");
+ break;
+ }
+ tp = (u_char *)(dh6o + 1);
+ int remain_len = optlen;
+ printf(" ");
+ /* Encoding is described in section 3.1 of RFC 1035 */
+ int label_len; /* Label length */
+ while (remain_len && *tp) {
+ label_len = *tp++;
+ if (label_len < remain_len - 1) {
+ printf("%.*s", label_len, tp);
+ tp += label_len;
+ remain_len -= (label_len + 1);
+ if(*tp) printf(".");
+ } else {
+ printf(" ?");
+ break;
+ }
+ }
+ printf(")");
+ break;
+ default:
+ printf(")");
+ break;
+ }
+
+ cp += sizeof(*dh6o) + optlen;
+ }
+ return;
+
+trunc:
+ printf("[|dhcp6ext]");
+}
+
+/*
+ * Print dhcp6 packets
+ */
+void
+dhcp6_print(const u_char *cp, u_int length)
+{
+ struct dhcp6 *dh6;
+ struct dhcp6_relay *dh6relay;
+ const u_char *ep;
+ u_char *extp;
+ const char *name;
+
+ printf("dhcp6");
+
+ ep = (u_char *)snapend;
+ if (cp + length < ep)
+ ep = cp + length;
+
+ dh6 = (struct dhcp6 *)cp;
+ dh6relay = (struct dhcp6_relay *)cp;
+ TCHECK(dh6->dh6_xid);
+ switch (dh6->dh6_msgtype) {
+ case DH6_SOLICIT:
+ name = "solicit";
+ break;
+ case DH6_ADVERTISE:
+ name = "advertise";
+ break;
+ case DH6_REQUEST:
+ name = "request";
+ break;
+ case DH6_CONFIRM:
+ name = "confirm";
+ break;
+ case DH6_RENEW:
+ name = "renew";
+ break;
+ case DH6_REBIND:
+ name = "rebind";
+ break;
+ case DH6_REPLY:
+ name = "reply";
+ break;
+ case DH6_RELEASE:
+ name = "release";
+ break;
+ case DH6_DECLINE:
+ name = "decline";
+ break;
+ case DH6_RECONFIGURE:
+ name = "reconfigure";
+ break;
+ case DH6_INFORM_REQ:
+ name= "inf-req";
+ break;
+ case DH6_RELAY_FORW:
+ name= "relay-fwd";
+ break;
+ case DH6_RELAY_REPLY:
+ name= "relay-reply";
+ break;
+ case DH6_LEASEQUERY:
+ name= "leasequery";
+ break;
+ case DH6_LQ_REPLY:
+ name= "leasequery-reply";
+ break;
+ default:
+ name = NULL;
+ break;
+ }
+
+ if (!vflag) {
+ if (name)
+ printf(" %s", name);
+ else if (dh6->dh6_msgtype != DH6_RELAY_FORW &&
+ dh6->dh6_msgtype != DH6_RELAY_REPLY) {
+ printf(" msgtype-%u", dh6->dh6_msgtype);
+ }
+ return;
+ }
+
+ /* XXX relay agent messages have to be handled differently */
+
+ if (name)
+ printf(" %s (", name); /*)*/
+ else
+ printf(" msgtype-%u (", dh6->dh6_msgtype); /*)*/
+ if (dh6->dh6_msgtype != DH6_RELAY_FORW &&
+ dh6->dh6_msgtype != DH6_RELAY_REPLY) {
+ printf("xid=%x", EXTRACT_32BITS(&dh6->dh6_xid) & DH6_XIDMASK);
+ extp = (u_char *)(dh6 + 1);
+ dhcp6opt_print(extp, ep);
+ } else { /* relay messages */
+ struct in6_addr addr6;
+
+ TCHECK(dh6relay->dh6relay_peeraddr);
+
+ memcpy(&addr6, dh6relay->dh6relay_linkaddr, sizeof (addr6));
+ printf("linkaddr=%s", ip6addr_string(&addr6));
+
+ memcpy(&addr6, dh6relay->dh6relay_peeraddr, sizeof (addr6));
+ printf(" peeraddr=%s", ip6addr_string(&addr6));
+
+ dhcp6opt_print((u_char *)(dh6relay + 1), ep);
+ }
+ /*(*/
+ printf(")");
+ return;
+
+trunc:
+ printf("[|dhcp6]");
+}
diff --git a/freebsd/contrib/tcpdump/print-domain.c b/freebsd/contrib/tcpdump/print-domain.c
new file mode 100644
index 00000000..412e1308
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-domain.c
@@ -0,0 +1,755 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-domain.c,v 1.98 2007-12-09 01:40:32 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include "nameser.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h" /* must come after interface.h */
+
+static const char *ns_ops[] = {
+ "", " inv_q", " stat", " op3", " notify", " update", " op6", " op7",
+ " op8", " updataA", " updateD", " updateDA",
+ " updateM", " updateMA", " zoneInit", " zoneRef",
+};
+
+static const char *ns_resp[] = {
+ "", " FormErr", " ServFail", " NXDomain",
+ " NotImp", " Refused", " YXDomain", " YXRRSet",
+ " NXRRSet", " NotAuth", " NotZone", " Resp11",
+ " Resp12", " Resp13", " Resp14", " NoChange",
+};
+
+/* skip over a domain name */
+static const u_char *
+ns_nskip(register const u_char *cp)
+{
+ register u_char i;
+
+ if (!TTEST2(*cp, 1))
+ return (NULL);
+ i = *cp++;
+ while (i) {
+ if ((i & INDIR_MASK) == INDIR_MASK)
+ return (cp + 1);
+ if ((i & INDIR_MASK) == EDNS0_MASK) {
+ int bitlen, bytelen;
+
+ if ((i & ~INDIR_MASK) != EDNS0_ELT_BITLABEL)
+ return(NULL); /* unknown ELT */
+ if (!TTEST2(*cp, 1))
+ return (NULL);
+ if ((bitlen = *cp++) == 0)
+ bitlen = 256;
+ bytelen = (bitlen + 7) / 8;
+ cp += bytelen;
+ } else
+ cp += i;
+ if (!TTEST2(*cp, 1))
+ return (NULL);
+ i = *cp++;
+ }
+ return (cp);
+}
+
+/* print a <domain-name> */
+static const u_char *
+blabel_print(const u_char *cp)
+{
+ int bitlen, slen, b;
+ const u_char *bitp, *lim;
+ char tc;
+
+ if (!TTEST2(*cp, 1))
+ return(NULL);
+ if ((bitlen = *cp) == 0)
+ bitlen = 256;
+ slen = (bitlen + 3) / 4;
+ lim = cp + 1 + slen;
+
+ /* print the bit string as a hex string */
+ printf("\\[x");
+ for (bitp = cp + 1, b = bitlen; bitp < lim && b > 7; b -= 8, bitp++) {
+ TCHECK(*bitp);
+ printf("%02x", *bitp);
+ }
+ if (b > 4) {
+ TCHECK(*bitp);
+ tc = *bitp++;
+ printf("%02x", tc & (0xff << (8 - b)));
+ } else if (b > 0) {
+ TCHECK(*bitp);
+ tc = *bitp++;
+ printf("%1x", ((tc >> 4) & 0x0f) & (0x0f << (4 - b)));
+ }
+ printf("/%d]", bitlen);
+ return lim;
+trunc:
+ printf(".../%d]", bitlen);
+ return NULL;
+}
+
+static int
+labellen(const u_char *cp)
+{
+ register u_int i;
+
+ if (!TTEST2(*cp, 1))
+ return(-1);
+ i = *cp;
+ if ((i & INDIR_MASK) == EDNS0_MASK) {
+ int bitlen, elt;
+ if ((elt = (i & ~INDIR_MASK)) != EDNS0_ELT_BITLABEL) {
+ printf("<ELT %d>", elt);
+ return(-1);
+ }
+ if (!TTEST2(*(cp + 1), 1))
+ return(-1);
+ if ((bitlen = *(cp + 1)) == 0)
+ bitlen = 256;
+ return(((bitlen + 7) / 8) + 1);
+ } else
+ return(i);
+}
+
+const u_char *
+ns_nprint(register const u_char *cp, register const u_char *bp)
+{
+ register u_int i, l;
+ register const u_char *rp = NULL;
+ register int compress = 0;
+ int chars_processed;
+ int elt;
+ int data_size = snapend - bp;
+
+ if ((l = labellen(cp)) == (u_int)-1)
+ return(NULL);
+ if (!TTEST2(*cp, 1))
+ return(NULL);
+ chars_processed = 1;
+ if (((i = *cp++) & INDIR_MASK) != INDIR_MASK) {
+ compress = 0;
+ rp = cp + l;
+ }
+
+ if (i != 0)
+ while (i && cp < snapend) {
+ if ((i & INDIR_MASK) == INDIR_MASK) {
+ if (!compress) {
+ rp = cp + 1;
+ compress = 1;
+ }
+ if (!TTEST2(*cp, 1))
+ return(NULL);
+ cp = bp + (((i << 8) | *cp) & 0x3fff);
+ if ((l = labellen(cp)) == (u_int)-1)
+ return(NULL);
+ if (!TTEST2(*cp, 1))
+ return(NULL);
+ i = *cp++;
+ chars_processed++;
+
+ /*
+ * If we've looked at every character in
+ * the message, this pointer will make
+ * us look at some character again,
+ * which means we're looping.
+ */
+ if (chars_processed >= data_size) {
+ printf("<LOOP>");
+ return (NULL);
+ }
+ continue;
+ }
+ if ((i & INDIR_MASK) == EDNS0_MASK) {
+ elt = (i & ~INDIR_MASK);
+ switch(elt) {
+ case EDNS0_ELT_BITLABEL:
+ if (blabel_print(cp) == NULL)
+ return (NULL);
+ break;
+ default:
+ /* unknown ELT */
+ printf("<ELT %d>", elt);
+ return(NULL);
+ }
+ } else {
+ if (fn_printn(cp, l, snapend))
+ return(NULL);
+ }
+
+ cp += l;
+ chars_processed += l;
+ putchar('.');
+ if ((l = labellen(cp)) == (u_int)-1)
+ return(NULL);
+ if (!TTEST2(*cp, 1))
+ return(NULL);
+ i = *cp++;
+ chars_processed++;
+ if (!compress)
+ rp += l + 1;
+ }
+ else
+ putchar('.');
+ return (rp);
+}
+
+/* print a <character-string> */
+static const u_char *
+ns_cprint(register const u_char *cp)
+{
+ register u_int i;
+
+ if (!TTEST2(*cp, 1))
+ return (NULL);
+ i = *cp++;
+ if (fn_printn(cp, i, snapend))
+ return (NULL);
+ return (cp + i);
+}
+
+/* http://www.iana.org/assignments/dns-parameters */
+struct tok ns_type2str[] = {
+ { T_A, "A" }, /* RFC 1035 */
+ { T_NS, "NS" }, /* RFC 1035 */
+ { T_MD, "MD" }, /* RFC 1035 */
+ { T_MF, "MF" }, /* RFC 1035 */
+ { T_CNAME, "CNAME" }, /* RFC 1035 */
+ { T_SOA, "SOA" }, /* RFC 1035 */
+ { T_MB, "MB" }, /* RFC 1035 */
+ { T_MG, "MG" }, /* RFC 1035 */
+ { T_MR, "MR" }, /* RFC 1035 */
+ { T_NULL, "NULL" }, /* RFC 1035 */
+ { T_WKS, "WKS" }, /* RFC 1035 */
+ { T_PTR, "PTR" }, /* RFC 1035 */
+ { T_HINFO, "HINFO" }, /* RFC 1035 */
+ { T_MINFO, "MINFO" }, /* RFC 1035 */
+ { T_MX, "MX" }, /* RFC 1035 */
+ { T_TXT, "TXT" }, /* RFC 1035 */
+ { T_RP, "RP" }, /* RFC 1183 */
+ { T_AFSDB, "AFSDB" }, /* RFC 1183 */
+ { T_X25, "X25" }, /* RFC 1183 */
+ { T_ISDN, "ISDN" }, /* RFC 1183 */
+ { T_RT, "RT" }, /* RFC 1183 */
+ { T_NSAP, "NSAP" }, /* RFC 1706 */
+ { T_NSAP_PTR, "NSAP_PTR" },
+ { T_SIG, "SIG" }, /* RFC 2535 */
+ { T_KEY, "KEY" }, /* RFC 2535 */
+ { T_PX, "PX" }, /* RFC 2163 */
+ { T_GPOS, "GPOS" }, /* RFC 1712 */
+ { T_AAAA, "AAAA" }, /* RFC 1886 */
+ { T_LOC, "LOC" }, /* RFC 1876 */
+ { T_NXT, "NXT" }, /* RFC 2535 */
+ { T_EID, "EID" }, /* Nimrod */
+ { T_NIMLOC, "NIMLOC" }, /* Nimrod */
+ { T_SRV, "SRV" }, /* RFC 2782 */
+ { T_ATMA, "ATMA" }, /* ATM Forum */
+ { T_NAPTR, "NAPTR" }, /* RFC 2168, RFC 2915 */
+ { T_KX, "KX" }, /* RFC 2230 */
+ { T_CERT, "CERT" }, /* RFC 2538 */
+ { T_A6, "A6" }, /* RFC 2874 */
+ { T_DNAME, "DNAME" }, /* RFC 2672 */
+ { T_SINK, "SINK" },
+ { T_OPT, "OPT" }, /* RFC 2671 */
+ { T_APL, "APL" }, /* RFC 3123 */
+ { T_DS, "DS" }, /* RFC 4034 */
+ { T_SSHFP, "SSHFP" }, /* RFC 4255 */
+ { T_IPSECKEY, "IPSECKEY" }, /* RFC 4025 */
+ { T_RRSIG, "RRSIG" }, /* RFC 4034 */
+ { T_NSEC, "NSEC" }, /* RFC 4034 */
+ { T_DNSKEY, "DNSKEY" }, /* RFC 4034 */
+ { T_SPF, "SPF" }, /* RFC-schlitt-spf-classic-02.txt */
+ { T_UINFO, "UINFO" },
+ { T_UID, "UID" },
+ { T_GID, "GID" },
+ { T_UNSPEC, "UNSPEC" },
+ { T_UNSPECA, "UNSPECA" },
+ { T_TKEY, "TKEY" }, /* RFC 2930 */
+ { T_TSIG, "TSIG" }, /* RFC 2845 */
+ { T_IXFR, "IXFR" }, /* RFC 1995 */
+ { T_AXFR, "AXFR" }, /* RFC 1035 */
+ { T_MAILB, "MAILB" }, /* RFC 1035 */
+ { T_MAILA, "MAILA" }, /* RFC 1035 */
+ { T_ANY, "ANY" },
+ { 0, NULL }
+};
+
+struct tok ns_class2str[] = {
+ { C_IN, "IN" }, /* Not used */
+ { C_CHAOS, "CHAOS" },
+ { C_HS, "HS" },
+ { C_ANY, "ANY" },
+ { 0, NULL }
+};
+
+/* print a query */
+static const u_char *
+ns_qprint(register const u_char *cp, register const u_char *bp, int is_mdns)
+{
+ register const u_char *np = cp;
+ register u_int i, class;
+
+ cp = ns_nskip(cp);
+
+ if (cp == NULL || !TTEST2(*cp, 4))
+ return(NULL);
+
+ /* print the qtype */
+ i = EXTRACT_16BITS(cp);
+ cp += 2;
+ printf(" %s", tok2str(ns_type2str, "Type%d", i));
+ /* print the qclass (if it's not IN) */
+ i = EXTRACT_16BITS(cp);
+ cp += 2;
+ if (is_mdns)
+ class = (i & ~C_QU);
+ else
+ class = i;
+ if (class != C_IN)
+ printf(" %s", tok2str(ns_class2str, "(Class %d)", class));
+ if (is_mdns) {
+ if (i & C_QU)
+ printf(" (QU)");
+ else
+ printf(" (QM)");
+ }
+
+ fputs("? ", stdout);
+ cp = ns_nprint(np, bp);
+ return(cp ? cp + 4 : NULL);
+}
+
+/* print a reply */
+static const u_char *
+ns_rprint(register const u_char *cp, register const u_char *bp, int is_mdns)
+{
+ register u_int i, class, opt_flags = 0;
+ register u_short typ, len;
+ register const u_char *rp;
+
+ if (vflag) {
+ putchar(' ');
+ if ((cp = ns_nprint(cp, bp)) == NULL)
+ return NULL;
+ } else
+ cp = ns_nskip(cp);
+
+ if (cp == NULL || !TTEST2(*cp, 10))
+ return (snapend);
+
+ /* print the type/qtype */
+ typ = EXTRACT_16BITS(cp);
+ cp += 2;
+ /* print the class (if it's not IN and the type isn't OPT) */
+ i = EXTRACT_16BITS(cp);
+ cp += 2;
+ if (is_mdns)
+ class = (i & ~C_CACHE_FLUSH);
+ else
+ class = i;
+ if (class != C_IN && typ != T_OPT)
+ printf(" %s", tok2str(ns_class2str, "(Class %d)", class));
+ if (is_mdns) {
+ if (i & C_CACHE_FLUSH)
+ printf(" (Cache flush)");
+ }
+
+ if (typ == T_OPT) {
+ /* get opt flags */
+ cp += 2;
+ opt_flags = EXTRACT_16BITS(cp);
+ /* ignore rest of ttl field */
+ cp += 2;
+ } else if (vflag > 2) {
+ /* print ttl */
+ printf(" [");
+ relts_print(EXTRACT_32BITS(cp));
+ printf("]");
+ cp += 4;
+ } else {
+ /* ignore ttl */
+ cp += 4;
+ }
+
+ len = EXTRACT_16BITS(cp);
+ cp += 2;
+
+ rp = cp + len;
+
+ printf(" %s", tok2str(ns_type2str, "Type%d", typ));
+ if (rp > snapend)
+ return(NULL);
+
+ switch (typ) {
+ case T_A:
+ if (!TTEST2(*cp, sizeof(struct in_addr)))
+ return(NULL);
+ printf(" %s", intoa(htonl(EXTRACT_32BITS(cp))));
+ break;
+
+ case T_NS:
+ case T_CNAME:
+ case T_PTR:
+#ifdef T_DNAME
+ case T_DNAME:
+#endif
+ putchar(' ');
+ if (ns_nprint(cp, bp) == NULL)
+ return(NULL);
+ break;
+
+ case T_SOA:
+ if (!vflag)
+ break;
+ putchar(' ');
+ if ((cp = ns_nprint(cp, bp)) == NULL)
+ return(NULL);
+ putchar(' ');
+ if ((cp = ns_nprint(cp, bp)) == NULL)
+ return(NULL);
+ if (!TTEST2(*cp, 5 * 4))
+ return(NULL);
+ printf(" %u", EXTRACT_32BITS(cp));
+ cp += 4;
+ printf(" %u", EXTRACT_32BITS(cp));
+ cp += 4;
+ printf(" %u", EXTRACT_32BITS(cp));
+ cp += 4;
+ printf(" %u", EXTRACT_32BITS(cp));
+ cp += 4;
+ printf(" %u", EXTRACT_32BITS(cp));
+ cp += 4;
+ break;
+ case T_MX:
+ putchar(' ');
+ if (!TTEST2(*cp, 2))
+ return(NULL);
+ if (ns_nprint(cp + 2, bp) == NULL)
+ return(NULL);
+ printf(" %d", EXTRACT_16BITS(cp));
+ break;
+
+ case T_TXT:
+ while (cp < rp) {
+ printf(" \"");
+ cp = ns_cprint(cp);
+ if (cp == NULL)
+ return(NULL);
+ putchar('"');
+ }
+ break;
+
+ case T_SRV:
+ putchar(' ');
+ if (!TTEST2(*cp, 6))
+ return(NULL);
+ if (ns_nprint(cp + 6, bp) == NULL)
+ return(NULL);
+ printf(":%d %d %d", EXTRACT_16BITS(cp + 4),
+ EXTRACT_16BITS(cp), EXTRACT_16BITS(cp + 2));
+ break;
+
+#ifdef INET6
+ case T_AAAA:
+ {
+ struct in6_addr addr;
+ char ntop_buf[INET6_ADDRSTRLEN];
+
+ if (!TTEST2(*cp, sizeof(struct in6_addr)))
+ return(NULL);
+ memcpy(&addr, cp, sizeof(struct in6_addr));
+ printf(" %s",
+ inet_ntop(AF_INET6, &addr, ntop_buf, sizeof(ntop_buf)));
+
+ break;
+ }
+
+ case T_A6:
+ {
+ struct in6_addr a;
+ int pbit, pbyte;
+ char ntop_buf[INET6_ADDRSTRLEN];
+
+ if (!TTEST2(*cp, 1))
+ return(NULL);
+ pbit = *cp;
+ pbyte = (pbit & ~7) / 8;
+ if (pbit > 128) {
+ printf(" %u(bad plen)", pbit);
+ break;
+ } else if (pbit < 128) {
+ if (!TTEST2(*(cp + 1), sizeof(a) - pbyte))
+ return(NULL);
+ memset(&a, 0, sizeof(a));
+ memcpy(&a.s6_addr[pbyte], cp + 1, sizeof(a) - pbyte);
+ printf(" %u %s", pbit,
+ inet_ntop(AF_INET6, &a, ntop_buf, sizeof(ntop_buf)));
+ }
+ if (pbit > 0) {
+ putchar(' ');
+ if (ns_nprint(cp + 1 + sizeof(a) - pbyte, bp) == NULL)
+ return(NULL);
+ }
+ break;
+ }
+#endif /*INET6*/
+
+ case T_OPT:
+ printf(" UDPsize=%u", class);
+ if (opt_flags & 0x8000)
+ printf(" OK");
+ break;
+
+ case T_UNSPECA: /* One long string */
+ if (!TTEST2(*cp, len))
+ return(NULL);
+ if (fn_printn(cp, len, snapend))
+ return(NULL);
+ break;
+
+ case T_TSIG:
+ {
+ if (cp + len > snapend)
+ return(NULL);
+ if (!vflag)
+ break;
+ putchar(' ');
+ if ((cp = ns_nprint(cp, bp)) == NULL)
+ return(NULL);
+ cp += 6;
+ if (!TTEST2(*cp, 2))
+ return(NULL);
+ printf(" fudge=%u", EXTRACT_16BITS(cp));
+ cp += 2;
+ if (!TTEST2(*cp, 2))
+ return(NULL);
+ printf(" maclen=%u", EXTRACT_16BITS(cp));
+ cp += 2 + EXTRACT_16BITS(cp);
+ if (!TTEST2(*cp, 2))
+ return(NULL);
+ printf(" origid=%u", EXTRACT_16BITS(cp));
+ cp += 2;
+ if (!TTEST2(*cp, 2))
+ return(NULL);
+ printf(" error=%u", EXTRACT_16BITS(cp));
+ cp += 2;
+ if (!TTEST2(*cp, 2))
+ return(NULL);
+ printf(" otherlen=%u", EXTRACT_16BITS(cp));
+ cp += 2;
+ }
+ }
+ return (rp); /* XXX This isn't always right */
+}
+
+void
+ns_print(register const u_char *bp, u_int length, int is_mdns)
+{
+ register const HEADER *np;
+ register int qdcount, ancount, nscount, arcount;
+ register const u_char *cp;
+ u_int16_t b2;
+
+ np = (const HEADER *)bp;
+ TCHECK(*np);
+ /* get the byte-order right */
+ qdcount = EXTRACT_16BITS(&np->qdcount);
+ ancount = EXTRACT_16BITS(&np->ancount);
+ nscount = EXTRACT_16BITS(&np->nscount);
+ arcount = EXTRACT_16BITS(&np->arcount);
+
+ if (DNS_QR(np)) {
+ /* this is a response */
+ printf("%d%s%s%s%s%s%s",
+ EXTRACT_16BITS(&np->id),
+ ns_ops[DNS_OPCODE(np)],
+ ns_resp[DNS_RCODE(np)],
+ DNS_AA(np)? "*" : "",
+ DNS_RA(np)? "" : "-",
+ DNS_TC(np)? "|" : "",
+ DNS_AD(np)? "$" : "");
+
+ if (qdcount != 1)
+ printf(" [%dq]", qdcount);
+ /* Print QUESTION section on -vv */
+ cp = (const u_char *)(np + 1);
+ while (qdcount--) {
+ if (qdcount < EXTRACT_16BITS(&np->qdcount) - 1)
+ putchar(',');
+ if (vflag > 1) {
+ fputs(" q:", stdout);
+ if ((cp = ns_qprint(cp, bp, is_mdns)) == NULL)
+ goto trunc;
+ } else {
+ if ((cp = ns_nskip(cp)) == NULL)
+ goto trunc;
+ cp += 4; /* skip QTYPE and QCLASS */
+ }
+ }
+ printf(" %d/%d/%d", ancount, nscount, arcount);
+ if (ancount--) {
+ if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL)
+ goto trunc;
+ while (cp < snapend && ancount--) {
+ putchar(',');
+ if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL)
+ goto trunc;
+ }
+ }
+ if (ancount > 0)
+ goto trunc;
+ /* Print NS and AR sections on -vv */
+ if (vflag > 1) {
+ if (cp < snapend && nscount--) {
+ fputs(" ns:", stdout);
+ if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL)
+ goto trunc;
+ while (cp < snapend && nscount--) {
+ putchar(',');
+ if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL)
+ goto trunc;
+ }
+ }
+ if (nscount > 0)
+ goto trunc;
+ if (cp < snapend && arcount--) {
+ fputs(" ar:", stdout);
+ if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL)
+ goto trunc;
+ while (cp < snapend && arcount--) {
+ putchar(',');
+ if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL)
+ goto trunc;
+ }
+ }
+ if (arcount > 0)
+ goto trunc;
+ }
+ }
+ else {
+ /* this is a request */
+ printf("%d%s%s%s", EXTRACT_16BITS(&np->id), ns_ops[DNS_OPCODE(np)],
+ DNS_RD(np) ? "+" : "",
+ DNS_CD(np) ? "%" : "");
+
+ /* any weirdness? */
+ b2 = EXTRACT_16BITS(((u_short *)np)+1);
+ if (b2 & 0x6cf)
+ printf(" [b2&3=0x%x]", b2);
+
+ if (DNS_OPCODE(np) == IQUERY) {
+ if (qdcount)
+ printf(" [%dq]", qdcount);
+ if (ancount != 1)
+ printf(" [%da]", ancount);
+ }
+ else {
+ if (ancount)
+ printf(" [%da]", ancount);
+ if (qdcount != 1)
+ printf(" [%dq]", qdcount);
+ }
+ if (nscount)
+ printf(" [%dn]", nscount);
+ if (arcount)
+ printf(" [%dau]", arcount);
+
+ cp = (const u_char *)(np + 1);
+ if (qdcount--) {
+ cp = ns_qprint(cp, (const u_char *)np, is_mdns);
+ if (!cp)
+ goto trunc;
+ while (cp < snapend && qdcount--) {
+ cp = ns_qprint((const u_char *)cp,
+ (const u_char *)np,
+ is_mdns);
+ if (!cp)
+ goto trunc;
+ }
+ }
+ if (qdcount > 0)
+ goto trunc;
+
+ /* Print remaining sections on -vv */
+ if (vflag > 1) {
+ if (ancount--) {
+ if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL)
+ goto trunc;
+ while (cp < snapend && ancount--) {
+ putchar(',');
+ if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL)
+ goto trunc;
+ }
+ }
+ if (ancount > 0)
+ goto trunc;
+ if (cp < snapend && nscount--) {
+ fputs(" ns:", stdout);
+ if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL)
+ goto trunc;
+ while (nscount-- && cp < snapend) {
+ putchar(',');
+ if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL)
+ goto trunc;
+ }
+ }
+ if (nscount > 0)
+ goto trunc;
+ if (cp < snapend && arcount--) {
+ fputs(" ar:", stdout);
+ if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL)
+ goto trunc;
+ while (cp < snapend && arcount--) {
+ putchar(',');
+ if ((cp = ns_rprint(cp, bp, is_mdns)) == NULL)
+ goto trunc;
+ }
+ }
+ if (arcount > 0)
+ goto trunc;
+ }
+ }
+ printf(" (%d)", length);
+ return;
+
+ trunc:
+ printf("[|domain]");
+ return;
+}
diff --git a/freebsd/contrib/tcpdump/print-dtp.c b/freebsd/contrib/tcpdump/print-dtp.c
new file mode 100644
index 00000000..f1471e86
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-dtp.c
@@ -0,0 +1,125 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1998-2007 The TCPDUMP project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Dynamic Trunk Protocol (DTP)
+ *
+ * Original code by Carles Kishimoto <carles.kishimoto@gmail.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+#include "nlpid.h"
+
+#define DTP_HEADER_LEN 1
+#define DTP_DOMAIN_TLV 0x0001
+#define DTP_STATUS_TLV 0x0002
+#define DTP_DTP_TYPE_TLV 0x0003
+#define DTP_NEIGHBOR_TLV 0x0004
+
+static struct tok dtp_tlv_values[] = {
+ { DTP_DOMAIN_TLV, "Domain TLV"},
+ { DTP_STATUS_TLV, "Status TLV"},
+ { DTP_DTP_TYPE_TLV, "DTP type TLV"},
+ { DTP_NEIGHBOR_TLV, "Neighbor TLV"},
+ { 0, NULL}
+};
+
+void
+dtp_print (const u_char *pptr, u_int length)
+{
+ int type, len;
+ const u_char *tptr;
+
+ if (length < DTP_HEADER_LEN)
+ goto trunc;
+
+ tptr = pptr;
+
+ if (!TTEST2(*tptr, DTP_HEADER_LEN))
+ goto trunc;
+
+ printf("DTPv%u, length %u",
+ (*tptr),
+ length);
+
+ /*
+ * In non-verbose mode, just print version.
+ */
+ if (vflag < 1) {
+ return;
+ }
+
+ tptr += DTP_HEADER_LEN;
+
+ while (tptr < (pptr+length)) {
+
+ if (!TTEST2(*tptr, 4))
+ goto trunc;
+
+ type = EXTRACT_16BITS(tptr);
+ len = EXTRACT_16BITS(tptr+2);
+
+ /* infinite loop check */
+ if (type == 0 || len == 0) {
+ return;
+ }
+
+ printf("\n\t%s (0x%04x) TLV, length %u",
+ tok2str(dtp_tlv_values, "Unknown", type),
+ type, len);
+
+ switch (type) {
+ case DTP_DOMAIN_TLV:
+ printf(", %s", tptr+4);
+ break;
+
+ case DTP_STATUS_TLV:
+ case DTP_DTP_TYPE_TLV:
+ printf(", 0x%x", *(tptr+4));
+ break;
+
+ case DTP_NEIGHBOR_TLV:
+ printf(", %s", etheraddr_string(tptr+4));
+ break;
+
+ default:
+ break;
+ }
+ tptr += len;
+ }
+
+ return;
+
+ trunc:
+ printf("[|dtp]");
+}
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-dvmrp.c b/freebsd/contrib/tcpdump/print-dvmrp.c
new file mode 100644
index 00000000..4f553b7d
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-dvmrp.c
@@ -0,0 +1,371 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-dvmrp.c,v 1.27 2003-11-19 09:42:04 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+
+/*
+ * DVMRP message types and flag values shamelessly stolen from
+ * mrouted/dvmrp.h.
+ */
+#define DVMRP_PROBE 1 /* for finding neighbors */
+#define DVMRP_REPORT 2 /* for reporting some or all routes */
+#define DVMRP_ASK_NEIGHBORS 3 /* sent by mapper, asking for a list */
+ /* of this router's neighbors */
+#define DVMRP_NEIGHBORS 4 /* response to such a request */
+#define DVMRP_ASK_NEIGHBORS2 5 /* as above, want new format reply */
+#define DVMRP_NEIGHBORS2 6
+#define DVMRP_PRUNE 7 /* prune message */
+#define DVMRP_GRAFT 8 /* graft message */
+#define DVMRP_GRAFT_ACK 9 /* graft acknowledgement */
+
+/*
+ * 'flags' byte values in DVMRP_NEIGHBORS2 reply.
+ */
+#define DVMRP_NF_TUNNEL 0x01 /* neighbors reached via tunnel */
+#define DVMRP_NF_SRCRT 0x02 /* tunnel uses IP source routing */
+#define DVMRP_NF_DOWN 0x10 /* kernel state of interface */
+#define DVMRP_NF_DISABLED 0x20 /* administratively disabled */
+#define DVMRP_NF_QUERIER 0x40 /* I am the subnet's querier */
+
+static int print_probe(const u_char *, const u_char *, u_int);
+static int print_report(const u_char *, const u_char *, u_int);
+static int print_neighbors(const u_char *, const u_char *, u_int);
+static int print_neighbors2(const u_char *, const u_char *, u_int);
+static int print_prune(const u_char *);
+static int print_graft(const u_char *);
+static int print_graft_ack(const u_char *);
+
+static u_int32_t target_level;
+
+void
+dvmrp_print(register const u_char *bp, register u_int len)
+{
+ register const u_char *ep;
+ register u_char type;
+
+ ep = (const u_char *)snapend;
+ if (bp >= ep)
+ return;
+
+ TCHECK(bp[1]);
+ type = bp[1];
+
+ /* Skip IGMP header */
+ bp += 8;
+ len -= 8;
+
+ switch (type) {
+
+ case DVMRP_PROBE:
+ printf(" Probe");
+ if (vflag) {
+ if (print_probe(bp, ep, len) < 0)
+ goto trunc;
+ }
+ break;
+
+ case DVMRP_REPORT:
+ printf(" Report");
+ if (vflag > 1) {
+ if (print_report(bp, ep, len) < 0)
+ goto trunc;
+ }
+ break;
+
+ case DVMRP_ASK_NEIGHBORS:
+ printf(" Ask-neighbors(old)");
+ break;
+
+ case DVMRP_NEIGHBORS:
+ printf(" Neighbors(old)");
+ if (print_neighbors(bp, ep, len) < 0)
+ goto trunc;
+ break;
+
+ case DVMRP_ASK_NEIGHBORS2:
+ printf(" Ask-neighbors2");
+ break;
+
+ case DVMRP_NEIGHBORS2:
+ printf(" Neighbors2");
+ /*
+ * extract version and capabilities from IGMP group
+ * address field
+ */
+ bp -= 4;
+ TCHECK2(bp[0], 4);
+ target_level = (bp[0] << 24) | (bp[1] << 16) |
+ (bp[2] << 8) | bp[3];
+ bp += 4;
+ if (print_neighbors2(bp, ep, len) < 0)
+ goto trunc;
+ break;
+
+ case DVMRP_PRUNE:
+ printf(" Prune");
+ if (print_prune(bp) < 0)
+ goto trunc;
+ break;
+
+ case DVMRP_GRAFT:
+ printf(" Graft");
+ if (print_graft(bp) < 0)
+ goto trunc;
+ break;
+
+ case DVMRP_GRAFT_ACK:
+ printf(" Graft-ACK");
+ if (print_graft_ack(bp) < 0)
+ goto trunc;
+ break;
+
+ default:
+ printf(" [type %d]", type);
+ break;
+ }
+ return;
+
+trunc:
+ printf("[|dvmrp]");
+ return;
+}
+
+static int
+print_report(register const u_char *bp, register const u_char *ep,
+ register u_int len)
+{
+ register u_int32_t mask, origin;
+ register int metric, done;
+ register u_int i, width;
+
+ while (len > 0) {
+ if (len < 3) {
+ printf(" [|]");
+ return (0);
+ }
+ TCHECK2(bp[0], 3);
+ mask = (u_int32_t)0xff << 24 | bp[0] << 16 | bp[1] << 8 | bp[2];
+ width = 1;
+ if (bp[0])
+ width = 2;
+ if (bp[1])
+ width = 3;
+ if (bp[2])
+ width = 4;
+
+ printf("\n\tMask %s", intoa(htonl(mask)));
+ bp += 3;
+ len -= 3;
+ do {
+ if (bp + width + 1 > ep) {
+ printf(" [|]");
+ return (0);
+ }
+ if (len < width + 1) {
+ printf("\n\t [Truncated Report]");
+ return (0);
+ }
+ origin = 0;
+ for (i = 0; i < width; ++i) {
+ TCHECK(*bp);
+ origin = origin << 8 | *bp++;
+ }
+ for ( ; i < 4; ++i)
+ origin <<= 8;
+
+ TCHECK(*bp);
+ metric = *bp++;
+ done = metric & 0x80;
+ metric &= 0x7f;
+ printf("\n\t %s metric %d", intoa(htonl(origin)),
+ metric);
+ len -= width + 1;
+ } while (!done);
+ }
+ return (0);
+trunc:
+ return (-1);
+}
+
+static int
+print_probe(register const u_char *bp, register const u_char *ep,
+ register u_int len)
+{
+ register u_int32_t genid;
+
+ TCHECK2(bp[0], 4);
+ if ((len < 4) || ((bp + 4) > ep)) {
+ /* { (ctags) */
+ printf(" [|}");
+ return (0);
+ }
+ genid = (bp[0] << 24) | (bp[1] << 16) | (bp[2] << 8) | bp[3];
+ bp += 4;
+ len -= 4;
+ if (vflag > 1)
+ printf("\n\t");
+ else
+ printf(" ");
+ printf("genid %u", genid);
+ if (vflag < 2)
+ return (0);
+
+ while ((len > 0) && (bp < ep)) {
+ TCHECK2(bp[0], 4);
+ printf("\n\tneighbor %s", ipaddr_string(bp));
+ bp += 4; len -= 4;
+ }
+ return (0);
+trunc:
+ return (-1);
+}
+
+static int
+print_neighbors(register const u_char *bp, register const u_char *ep,
+ register u_int len)
+{
+ const u_char *laddr;
+ register u_char metric;
+ register u_char thresh;
+ register int ncount;
+
+ while (len > 0 && bp < ep) {
+ TCHECK2(bp[0], 7);
+ laddr = bp;
+ bp += 4;
+ metric = *bp++;
+ thresh = *bp++;
+ ncount = *bp++;
+ len -= 7;
+ while (--ncount >= 0) {
+ TCHECK2(bp[0], 4);
+ printf(" [%s ->", ipaddr_string(laddr));
+ printf(" %s, (%d/%d)]",
+ ipaddr_string(bp), metric, thresh);
+ bp += 4;
+ len -= 4;
+ }
+ }
+ return (0);
+trunc:
+ return (-1);
+}
+
+static int
+print_neighbors2(register const u_char *bp, register const u_char *ep,
+ register u_int len)
+{
+ const u_char *laddr;
+ register u_char metric, thresh, flags;
+ register int ncount;
+
+ printf(" (v %d.%d):",
+ (int)target_level & 0xff,
+ (int)(target_level >> 8) & 0xff);
+
+ while (len > 0 && bp < ep) {
+ TCHECK2(bp[0], 8);
+ laddr = bp;
+ bp += 4;
+ metric = *bp++;
+ thresh = *bp++;
+ flags = *bp++;
+ ncount = *bp++;
+ len -= 8;
+ while (--ncount >= 0 && (len >= 4) && (bp + 4) <= ep) {
+ printf(" [%s -> ", ipaddr_string(laddr));
+ printf("%s (%d/%d", ipaddr_string(bp),
+ metric, thresh);
+ if (flags & DVMRP_NF_TUNNEL)
+ printf("/tunnel");
+ if (flags & DVMRP_NF_SRCRT)
+ printf("/srcrt");
+ if (flags & DVMRP_NF_QUERIER)
+ printf("/querier");
+ if (flags & DVMRP_NF_DISABLED)
+ printf("/disabled");
+ if (flags & DVMRP_NF_DOWN)
+ printf("/down");
+ printf(")]");
+ bp += 4;
+ len -= 4;
+ }
+ if (ncount != -1) {
+ printf(" [|]");
+ return (0);
+ }
+ }
+ return (0);
+trunc:
+ return (-1);
+}
+
+static int
+print_prune(register const u_char *bp)
+{
+ TCHECK2(bp[0], 12);
+ printf(" src %s grp %s", ipaddr_string(bp), ipaddr_string(bp + 4));
+ bp += 8;
+ (void)printf(" timer ");
+ relts_print(EXTRACT_32BITS(bp));
+ return (0);
+trunc:
+ return (-1);
+}
+
+static int
+print_graft(register const u_char *bp)
+{
+ TCHECK2(bp[0], 8);
+ printf(" src %s grp %s", ipaddr_string(bp), ipaddr_string(bp + 4));
+ return (0);
+trunc:
+ return (-1);
+}
+
+static int
+print_graft_ack(register const u_char *bp)
+{
+ TCHECK2(bp[0], 8);
+ printf(" src %s grp %s", ipaddr_string(bp), ipaddr_string(bp + 4));
+ return (0);
+trunc:
+ return (-1);
+}
diff --git a/freebsd/contrib/tcpdump/print-eap.c b/freebsd/contrib/tcpdump/print-eap.c
new file mode 100644
index 00000000..5730dbb7
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-eap.c
@@ -0,0 +1,309 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 2004 - Michael Richardson <mcr@xelerance.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Format and print EAP packets.
+ *
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-eap.c,v 1.5 2007-10-04 16:41:33 hannes Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "netdissect.h"
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+#include "ether.h"
+
+#define EAP_FRAME_TYPE_PACKET 0
+#define EAP_FRAME_TYPE_START 1
+#define EAP_FRAME_TYPE_LOGOFF 2
+#define EAP_FRAME_TYPE_KEY 3
+#define EAP_FRAME_TYPE_ENCAP_ASF_ALERT 4
+
+struct eap_frame_t {
+ unsigned char version;
+ unsigned char type;
+ unsigned char length[2];
+};
+
+static const struct tok eap_frame_type_values[] = {
+ { EAP_FRAME_TYPE_PACKET, "EAP packet" },
+ { EAP_FRAME_TYPE_START, "EAPOL start" },
+ { EAP_FRAME_TYPE_LOGOFF, "EAPOL logoff" },
+ { EAP_FRAME_TYPE_KEY, "EAPOL key" },
+ { EAP_FRAME_TYPE_ENCAP_ASF_ALERT, "Encapsulated ASF alert" },
+ { 0, NULL}
+};
+
+/* RFC 3748 */
+struct eap_packet_t {
+ unsigned char code;
+ unsigned char id;
+ unsigned char length[2];
+};
+
+#define EAP_REQUEST 1
+#define EAP_RESPONSE 2
+#define EAP_SUCCESS 3
+#define EAP_FAILURE 4
+
+static const struct tok eap_code_values[] = {
+ { EAP_REQUEST, "Request" },
+ { EAP_RESPONSE, "Response" },
+ { EAP_SUCCESS, "Success" },
+ { EAP_FAILURE, "Failure" },
+ { 0, NULL}
+};
+
+#define EAP_TYPE_NO_PROPOSED 0
+#define EAP_TYPE_IDENTITY 1
+#define EAP_TYPE_NOTIFICATION 2
+#define EAP_TYPE_NAK 3
+#define EAP_TYPE_MD5_CHALLENGE 4
+#define EAP_TYPE_OTP 5
+#define EAP_TYPE_GTC 6
+#define EAP_TYPE_TLS 13 /* RFC 2716 */
+#define EAP_TYPE_SIM 18 /* RFC 4186 */
+#define EAP_TYPE_TTLS 21 /* draft-funk-eap-ttls-v0-01.txt */
+#define EAP_TYPE_AKA 23 /* RFC 4187 */
+#define EAP_TYPE_FAST 43 /* RFC 4851 */
+#define EAP_TYPE_EXPANDED_TYPES 254
+#define EAP_TYPE_EXPERIMENTAL 255
+
+static const struct tok eap_type_values[] = {
+ { EAP_TYPE_NO_PROPOSED, "No proposed" },
+ { EAP_TYPE_IDENTITY, "Identity" },
+ { EAP_TYPE_NOTIFICATION, "Notification" },
+ { EAP_TYPE_NAK, "Nak" },
+ { EAP_TYPE_MD5_CHALLENGE, "MD5-challenge" },
+ { EAP_TYPE_OTP, "OTP" },
+ { EAP_TYPE_GTC, "GTC" },
+ { EAP_TYPE_TLS, "TLS" },
+ { EAP_TYPE_SIM, "SIM" },
+ { EAP_TYPE_TTLS, "TTLS" },
+ { EAP_TYPE_AKA, "AKA" },
+ { EAP_TYPE_FAST, "FAST" },
+ { EAP_TYPE_EXPANDED_TYPES, "Expanded types" },
+ { EAP_TYPE_EXPERIMENTAL, "Experimental" },
+ { 0, NULL}
+};
+
+#define EAP_TLS_EXTRACT_BIT_L(x) (((x)&0x80)>>7)
+
+/* RFC 2716 - EAP TLS bits */
+#define EAP_TLS_FLAGS_LEN_INCLUDED (1 << 7)
+#define EAP_TLS_FLAGS_MORE_FRAGMENTS (1 << 6)
+#define EAP_TLS_FLAGS_START (1 << 5)
+
+static const struct tok eap_tls_flags_values[] = {
+ { EAP_TLS_FLAGS_LEN_INCLUDED, "L bit" },
+ { EAP_TLS_FLAGS_MORE_FRAGMENTS, "More fragments bit"},
+ { EAP_TLS_FLAGS_START, "Start bit"},
+ { 0, NULL}
+};
+
+#define EAP_TTLS_VERSION(x) ((x)&0x07)
+
+/* EAP-AKA and EAP-SIM - RFC 4187 */
+#define EAP_AKA_CHALLENGE 1
+#define EAP_AKA_AUTH_REJECT 2
+#define EAP_AKA_SYNC_FAILURE 4
+#define EAP_AKA_IDENTITY 5
+#define EAP_SIM_START 10
+#define EAP_SIM_CHALLENGE 11
+#define EAP_AKA_NOTIFICATION 12
+#define EAP_AKA_REAUTH 13
+#define EAP_AKA_CLIENT_ERROR 14
+
+static const struct tok eap_aka_subtype_values[] = {
+ { EAP_AKA_CHALLENGE, "Challenge" },
+ { EAP_AKA_AUTH_REJECT, "Auth reject" },
+ { EAP_AKA_SYNC_FAILURE, "Sync failure" },
+ { EAP_AKA_IDENTITY, "Identity" },
+ { EAP_SIM_START, "Start" },
+ { EAP_SIM_CHALLENGE, "Challenge" },
+ { EAP_AKA_NOTIFICATION, "Notification" },
+ { EAP_AKA_REAUTH, "Reauth" },
+ { EAP_AKA_CLIENT_ERROR, "Client error" },
+ { 0, NULL}
+};
+
+/*
+ * Print EAP requests / responses
+ */
+void
+eap_print(netdissect_options *ndo _U_,
+ register const u_char *cp,
+ u_int length _U_)
+{
+ const struct eap_frame_t *eap;
+ const u_char *tptr;
+ u_int tlen, type, subtype;
+ int count=0, len;
+
+ tptr = cp;
+ tlen = length;
+ eap = (const struct eap_frame_t *)cp;
+ TCHECK(*eap);
+
+ /* in non-verbose mode just lets print the basic info */
+ if (vflag < 1) {
+ printf("%s (%u) v%u, len %u",
+ tok2str(eap_frame_type_values, "unknown", eap->type),
+ eap->type,
+ eap->version,
+ EXTRACT_16BITS(eap->length));
+ return;
+ }
+
+ printf("%s (%u) v%u, len %u",
+ tok2str(eap_frame_type_values, "unknown", eap->type),
+ eap->type,
+ eap->version,
+ EXTRACT_16BITS(eap->length));
+
+ tptr += sizeof(const struct eap_frame_t);
+ tlen -= sizeof(const struct eap_frame_t);
+
+ switch (eap->type) {
+ case EAP_FRAME_TYPE_PACKET:
+ type = *(tptr);
+ len = EXTRACT_16BITS(tptr+2);
+ printf(", %s (%u), id %u, len %u",
+ tok2str(eap_code_values, "unknown", type),
+ type,
+ *(tptr+1),
+ len);
+
+ if (!TTEST2(*tptr, len))
+ goto trunc;
+
+ if (type <= 2) { /* For EAP_REQUEST and EAP_RESPONSE only */
+ subtype = *(tptr+4);
+ printf("\n\t\t Type %s (%u)",
+ tok2str(eap_type_values, "unknown", *(tptr+4)),
+ *(tptr+4));
+
+ switch (subtype) {
+ case EAP_TYPE_IDENTITY:
+ if (len - 5 > 0) {
+ printf(", Identity: ");
+ safeputs((const char *)tptr+5, len-5);
+ }
+ break;
+
+ case EAP_TYPE_NOTIFICATION:
+ if (len - 5 > 0) {
+ printf(", Notification: ");
+ safeputs((const char *)tptr+5, len-5);
+ }
+ break;
+
+ case EAP_TYPE_NAK:
+ count = 5;
+
+ /*
+ * one or more octets indicating
+ * the desired authentication
+ * type one octet per type
+ */
+ while (count < len) {
+ printf(" %s (%u),",
+ tok2str(eap_type_values, "unknown", *(tptr+count)),
+ *(tptr+count));
+ count++;
+ }
+ break;
+
+ case EAP_TYPE_TTLS:
+ printf(" TTLSv%u",
+ EAP_TTLS_VERSION(*(tptr+5))); /* fall through */
+ case EAP_TYPE_TLS:
+ printf(" flags [%s] 0x%02x,",
+ bittok2str(eap_tls_flags_values, "none", *(tptr+5)),
+ *(tptr+5));
+
+ if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) {
+ printf(" len %u", EXTRACT_32BITS(tptr+6));
+ }
+ break;
+
+ case EAP_TYPE_FAST:
+ printf(" FASTv%u",
+ EAP_TTLS_VERSION(*(tptr+5)));
+ printf(" flags [%s] 0x%02x,",
+ bittok2str(eap_tls_flags_values, "none", *(tptr+5)),
+ *(tptr+5));
+
+ if (EAP_TLS_EXTRACT_BIT_L(*(tptr+5))) {
+ printf(" len %u", EXTRACT_32BITS(tptr+6));
+ }
+
+ /* FIXME - TLV attributes follow */
+ break;
+
+ case EAP_TYPE_AKA:
+ case EAP_TYPE_SIM:
+ printf(" subtype [%s] 0x%02x,",
+ tok2str(eap_aka_subtype_values, "unknown", *(tptr+5)),
+ *(tptr+5));
+
+ /* FIXME - TLV attributes follow */
+ break;
+
+ case EAP_TYPE_MD5_CHALLENGE:
+ case EAP_TYPE_OTP:
+ case EAP_TYPE_GTC:
+ case EAP_TYPE_EXPANDED_TYPES:
+ case EAP_TYPE_EXPERIMENTAL:
+ default:
+ break;
+ }
+ }
+ break;
+
+ case EAP_FRAME_TYPE_LOGOFF:
+ case EAP_FRAME_TYPE_ENCAP_ASF_ALERT:
+ default:
+ break;
+ }
+ return;
+
+ trunc:
+ printf("\n\t[|EAP]");
+}
+
+/*
+ * Local Variables:
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-egp.c b/freebsd/contrib/tcpdump/print-egp.c
new file mode 100644
index 00000000..1c90bd86
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-egp.c
@@ -0,0 +1,364 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Lawrence Berkeley Laboratory,
+ * Berkeley, CA. The name of the University may not be used to
+ * endorse or promote products derived from this software without
+ * specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Initial contribution from Jeff Honig (jch@MITCHELL.CIT.CORNELL.EDU).
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-egp.c,v 1.38 2006-02-11 22:13:24 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+#include "ip.h"
+
+struct egp_packet {
+ u_int8_t egp_version;
+#define EGP_VERSION 2
+ u_int8_t egp_type;
+#define EGPT_ACQUIRE 3
+#define EGPT_REACH 5
+#define EGPT_POLL 2
+#define EGPT_UPDATE 1
+#define EGPT_ERROR 8
+ u_int8_t egp_code;
+#define EGPC_REQUEST 0
+#define EGPC_CONFIRM 1
+#define EGPC_REFUSE 2
+#define EGPC_CEASE 3
+#define EGPC_CEASEACK 4
+#define EGPC_HELLO 0
+#define EGPC_HEARDU 1
+ u_int8_t egp_status;
+#define EGPS_UNSPEC 0
+#define EGPS_ACTIVE 1
+#define EGPS_PASSIVE 2
+#define EGPS_NORES 3
+#define EGPS_ADMIN 4
+#define EGPS_GODOWN 5
+#define EGPS_PARAM 6
+#define EGPS_PROTO 7
+#define EGPS_INDET 0
+#define EGPS_UP 1
+#define EGPS_DOWN 2
+#define EGPS_UNSOL 0x80
+ u_int16_t egp_checksum;
+ u_int16_t egp_as;
+ u_int16_t egp_sequence;
+ union {
+ u_int16_t egpu_hello;
+ u_int8_t egpu_gws[2];
+ u_int16_t egpu_reason;
+#define EGPR_UNSPEC 0
+#define EGPR_BADHEAD 1
+#define EGPR_BADDATA 2
+#define EGPR_NOREACH 3
+#define EGPR_XSPOLL 4
+#define EGPR_NORESP 5
+#define EGPR_UVERSION 6
+ } egp_handg;
+#define egp_hello egp_handg.egpu_hello
+#define egp_intgw egp_handg.egpu_gws[0]
+#define egp_extgw egp_handg.egpu_gws[1]
+#define egp_reason egp_handg.egpu_reason
+ union {
+ u_int16_t egpu_poll;
+ u_int32_t egpu_sourcenet;
+ } egp_pands;
+#define egp_poll egp_pands.egpu_poll
+#define egp_sourcenet egp_pands.egpu_sourcenet
+};
+
+const char *egp_acquire_codes[] = {
+ "request",
+ "confirm",
+ "refuse",
+ "cease",
+ "cease_ack"
+};
+
+const char *egp_acquire_status[] = {
+ "unspecified",
+ "active_mode",
+ "passive_mode",
+ "insufficient_resources",
+ "administratively_prohibited",
+ "going_down",
+ "parameter_violation",
+ "protocol_violation"
+};
+
+const char *egp_reach_codes[] = {
+ "hello",
+ "i-h-u"
+};
+
+const char *egp_status_updown[] = {
+ "indeterminate",
+ "up",
+ "down"
+};
+
+const char *egp_reasons[] = {
+ "unspecified",
+ "bad_EGP_header_format",
+ "bad_EGP_data_field_format",
+ "reachability_info_unavailable",
+ "excessive_polling_rate",
+ "no_response",
+ "unsupported_version"
+};
+
+static void
+egpnrprint(register const struct egp_packet *egp)
+{
+ register const u_int8_t *cp;
+ u_int32_t addr;
+ register u_int32_t net;
+ register u_int netlen;
+ int gateways, distances, networks;
+ int t_gateways;
+ const char *comma;
+
+ addr = egp->egp_sourcenet;
+ if (IN_CLASSA(addr)) {
+ net = addr & IN_CLASSA_NET;
+ netlen = 1;
+ } else if (IN_CLASSB(addr)) {
+ net = addr & IN_CLASSB_NET;
+ netlen = 2;
+ } else if (IN_CLASSC(addr)) {
+ net = addr & IN_CLASSC_NET;
+ netlen = 3;
+ } else {
+ net = 0;
+ netlen = 0;
+ }
+ cp = (u_int8_t *)(egp + 1);
+
+ t_gateways = egp->egp_intgw + egp->egp_extgw;
+ for (gateways = 0; gateways < t_gateways; ++gateways) {
+ /* Pickup host part of gateway address */
+ addr = 0;
+ TCHECK2(cp[0], 4 - netlen);
+ switch (netlen) {
+
+ case 1:
+ addr = *cp++;
+ /* fall through */
+ case 2:
+ addr = (addr << 8) | *cp++;
+ /* fall through */
+ case 3:
+ addr = (addr << 8) | *cp++;
+ }
+ addr |= net;
+ TCHECK2(cp[0], 1);
+ distances = *cp++;
+ printf(" %s %s ",
+ gateways < (int)egp->egp_intgw ? "int" : "ext",
+ ipaddr_string(&addr));
+
+ comma = "";
+ putchar('(');
+ while (--distances >= 0) {
+ TCHECK2(cp[0], 2);
+ printf("%sd%d:", comma, (int)*cp++);
+ comma = ", ";
+ networks = *cp++;
+ while (--networks >= 0) {
+ /* Pickup network number */
+ TCHECK2(cp[0], 1);
+ addr = (u_int32_t)*cp++ << 24;
+ if (IN_CLASSB(addr)) {
+ TCHECK2(cp[0], 1);
+ addr |= (u_int32_t)*cp++ << 16;
+ } else if (!IN_CLASSA(addr)) {
+ TCHECK2(cp[0], 2);
+ addr |= (u_int32_t)*cp++ << 16;
+ addr |= (u_int32_t)*cp++ << 8;
+ }
+ printf(" %s", ipaddr_string(&addr));
+ }
+ }
+ putchar(')');
+ }
+ return;
+trunc:
+ fputs("[|]", stdout);
+}
+
+void
+egp_print(register const u_int8_t *bp, register u_int length)
+{
+ register const struct egp_packet *egp;
+ register int status;
+ register int code;
+ register int type;
+
+ egp = (struct egp_packet *)bp;
+ if (!TTEST2(*egp, length)) {
+ printf("[|egp]");
+ return;
+ }
+
+ if (!vflag) {
+ printf("EGPv%u, AS %u, seq %u, length %u",
+ egp->egp_version,
+ EXTRACT_16BITS(&egp->egp_as),
+ EXTRACT_16BITS(&egp->egp_sequence),
+ length);
+ return;
+ } else
+ printf("EGPv%u, length %u",
+ egp->egp_version,
+ length);
+
+ if (egp->egp_version != EGP_VERSION) {
+ printf("[version %d]", egp->egp_version);
+ return;
+ }
+
+ type = egp->egp_type;
+ code = egp->egp_code;
+ status = egp->egp_status;
+
+ switch (type) {
+ case EGPT_ACQUIRE:
+ printf(" acquire");
+ switch (code) {
+ case EGPC_REQUEST:
+ case EGPC_CONFIRM:
+ printf(" %s", egp_acquire_codes[code]);
+ switch (status) {
+ case EGPS_UNSPEC:
+ case EGPS_ACTIVE:
+ case EGPS_PASSIVE:
+ printf(" %s", egp_acquire_status[status]);
+ break;
+
+ default:
+ printf(" [status %d]", status);
+ break;
+ }
+ printf(" hello:%d poll:%d",
+ EXTRACT_16BITS(&egp->egp_hello),
+ EXTRACT_16BITS(&egp->egp_poll));
+ break;
+
+ case EGPC_REFUSE:
+ case EGPC_CEASE:
+ case EGPC_CEASEACK:
+ printf(" %s", egp_acquire_codes[code]);
+ switch (status ) {
+ case EGPS_UNSPEC:
+ case EGPS_NORES:
+ case EGPS_ADMIN:
+ case EGPS_GODOWN:
+ case EGPS_PARAM:
+ case EGPS_PROTO:
+ printf(" %s", egp_acquire_status[status]);
+ break;
+
+ default:
+ printf("[status %d]", status);
+ break;
+ }
+ break;
+
+ default:
+ printf("[code %d]", code);
+ break;
+ }
+ break;
+
+ case EGPT_REACH:
+ switch (code) {
+
+ case EGPC_HELLO:
+ case EGPC_HEARDU:
+ printf(" %s", egp_reach_codes[code]);
+ if (status <= EGPS_DOWN)
+ printf(" state:%s", egp_status_updown[status]);
+ else
+ printf(" [status %d]", status);
+ break;
+
+ default:
+ printf("[reach code %d]", code);
+ break;
+ }
+ break;
+
+ case EGPT_POLL:
+ printf(" poll");
+ if (egp->egp_status <= EGPS_DOWN)
+ printf(" state:%s", egp_status_updown[status]);
+ else
+ printf(" [status %d]", status);
+ printf(" net:%s", ipaddr_string(&egp->egp_sourcenet));
+ break;
+
+ case EGPT_UPDATE:
+ printf(" update");
+ if (status & EGPS_UNSOL) {
+ status &= ~EGPS_UNSOL;
+ printf(" unsolicited");
+ }
+ if (status <= EGPS_DOWN)
+ printf(" state:%s", egp_status_updown[status]);
+ else
+ printf(" [status %d]", status);
+ printf(" %s int %d ext %d",
+ ipaddr_string(&egp->egp_sourcenet),
+ egp->egp_intgw,
+ egp->egp_extgw);
+ if (vflag)
+ egpnrprint(egp);
+ break;
+
+ case EGPT_ERROR:
+ printf(" error");
+ if (status <= EGPS_DOWN)
+ printf(" state:%s", egp_status_updown[status]);
+ else
+ printf(" [status %d]", status);
+
+ if (EXTRACT_16BITS(&egp->egp_reason) <= EGPR_UVERSION)
+ printf(" %s", egp_reasons[EXTRACT_16BITS(&egp->egp_reason)]);
+ else
+ printf(" [reason %d]", EXTRACT_16BITS(&egp->egp_reason));
+ break;
+
+ default:
+ printf("[type %d]", type);
+ break;
+ }
+}
diff --git a/freebsd/contrib/tcpdump/print-eigrp.c b/freebsd/contrib/tcpdump/print-eigrp.c
new file mode 100644
index 00000000..599fe89a
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-eigrp.c
@@ -0,0 +1,482 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1998-2004 Hannes Gredler <hannes@tcpdump.org>
+ * The TCPDUMP project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-eigrp.c,v 1.7 2005-05-06 02:53:26 guy Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+
+/*
+ * packet format documented at
+ * http://www.rhyshaden.com/eigrp.htm
+ */
+
+struct eigrp_common_header {
+ u_int8_t version;
+ u_int8_t opcode;
+ u_int8_t checksum[2];
+ u_int8_t flags[4];
+ u_int8_t seq[4];
+ u_int8_t ack[4];
+ u_int8_t asn[4];
+};
+
+#define EIGRP_VERSION 2
+
+#define EIGRP_OPCODE_UPDATE 1
+#define EIGRP_OPCODE_QUERY 3
+#define EIGRP_OPCODE_REPLY 4
+#define EIGRP_OPCODE_HELLO 5
+#define EIGRP_OPCODE_IPXSAP 6
+#define EIGRP_OPCODE_PROBE 7
+
+static const struct tok eigrp_opcode_values[] = {
+ { EIGRP_OPCODE_UPDATE, "Update" },
+ { EIGRP_OPCODE_QUERY, "Query" },
+ { EIGRP_OPCODE_REPLY, "Reply" },
+ { EIGRP_OPCODE_HELLO, "Hello" },
+ { EIGRP_OPCODE_IPXSAP, "IPX SAP" },
+ { EIGRP_OPCODE_PROBE, "Probe" },
+ { 0, NULL}
+};
+
+static const struct tok eigrp_common_header_flag_values[] = {
+ { 0x01, "Init" },
+ { 0x02, "Conditionally Received" },
+ { 0, NULL}
+};
+
+struct eigrp_tlv_header {
+ u_int8_t type[2];
+ u_int8_t length[2];
+};
+
+#define EIGRP_TLV_GENERAL_PARM 0x0001
+#define EIGRP_TLV_AUTH 0x0002
+#define EIGRP_TLV_SEQ 0x0003
+#define EIGRP_TLV_SW_VERSION 0x0004
+#define EIGRP_TLV_MCAST_SEQ 0x0005
+#define EIGRP_TLV_IP_INT 0x0102
+#define EIGRP_TLV_IP_EXT 0x0103
+#define EIGRP_TLV_AT_INT 0x0202
+#define EIGRP_TLV_AT_EXT 0x0203
+#define EIGRP_TLV_AT_CABLE_SETUP 0x0204
+#define EIGRP_TLV_IPX_INT 0x0302
+#define EIGRP_TLV_IPX_EXT 0x0303
+
+static const struct tok eigrp_tlv_values[] = {
+ { EIGRP_TLV_GENERAL_PARM, "General Parameters"},
+ { EIGRP_TLV_AUTH, "Authentication"},
+ { EIGRP_TLV_SEQ, "Sequence"},
+ { EIGRP_TLV_SW_VERSION, "Software Version"},
+ { EIGRP_TLV_MCAST_SEQ, "Next Multicast Sequence"},
+ { EIGRP_TLV_IP_INT, "IP Internal routes"},
+ { EIGRP_TLV_IP_EXT, "IP External routes"},
+ { EIGRP_TLV_AT_INT, "AppleTalk Internal routes"},
+ { EIGRP_TLV_AT_EXT, "AppleTalk External routes"},
+ { EIGRP_TLV_AT_CABLE_SETUP, "AppleTalk Cable setup"},
+ { EIGRP_TLV_IPX_INT, "IPX Internal routes"},
+ { EIGRP_TLV_IPX_EXT, "IPX External routes"},
+ { 0, NULL}
+};
+
+struct eigrp_tlv_general_parm_t {
+ u_int8_t k1;
+ u_int8_t k2;
+ u_int8_t k3;
+ u_int8_t k4;
+ u_int8_t k5;
+ u_int8_t res;
+ u_int8_t holdtime[2];
+};
+
+struct eigrp_tlv_sw_version_t {
+ u_int8_t ios_major;
+ u_int8_t ios_minor;
+ u_int8_t eigrp_major;
+ u_int8_t eigrp_minor;
+};
+
+struct eigrp_tlv_ip_int_t {
+ u_int8_t nexthop[4];
+ u_int8_t delay[4];
+ u_int8_t bandwidth[4];
+ u_int8_t mtu[3];
+ u_int8_t hopcount;
+ u_int8_t reliability;
+ u_int8_t load;
+ u_int8_t reserved[2];
+ u_int8_t plen;
+ u_int8_t destination; /* variable length [1-4] bytes encoding */
+};
+
+struct eigrp_tlv_ip_ext_t {
+ u_int8_t nexthop[4];
+ u_int8_t origin_router[4];
+ u_int8_t origin_as[4];
+ u_int8_t tag[4];
+ u_int8_t metric[4];
+ u_int8_t reserved[2];
+ u_int8_t proto_id;
+ u_int8_t flags;
+ u_int8_t delay[4];
+ u_int8_t bandwidth[4];
+ u_int8_t mtu[3];
+ u_int8_t hopcount;
+ u_int8_t reliability;
+ u_int8_t load;
+ u_int8_t reserved2[2];
+ u_int8_t plen;
+ u_int8_t destination; /* variable length [1-4] bytes encoding */
+};
+
+struct eigrp_tlv_at_cable_setup_t {
+ u_int8_t cable_start[2];
+ u_int8_t cable_end[2];
+ u_int8_t router_id[4];
+};
+
+struct eigrp_tlv_at_int_t {
+ u_int8_t nexthop[4];
+ u_int8_t delay[4];
+ u_int8_t bandwidth[4];
+ u_int8_t mtu[3];
+ u_int8_t hopcount;
+ u_int8_t reliability;
+ u_int8_t load;
+ u_int8_t reserved[2];
+ u_int8_t cable_start[2];
+ u_int8_t cable_end[2];
+};
+
+struct eigrp_tlv_at_ext_t {
+ u_int8_t nexthop[4];
+ u_int8_t origin_router[4];
+ u_int8_t origin_as[4];
+ u_int8_t tag[4];
+ u_int8_t proto_id;
+ u_int8_t flags;
+ u_int8_t metric[2];
+ u_int8_t delay[4];
+ u_int8_t bandwidth[4];
+ u_int8_t mtu[3];
+ u_int8_t hopcount;
+ u_int8_t reliability;
+ u_int8_t load;
+ u_int8_t reserved2[2];
+ u_int8_t cable_start[2];
+ u_int8_t cable_end[2];
+};
+
+static const struct tok eigrp_ext_proto_id_values[] = {
+ { 0x01, "IGRP" },
+ { 0x02, "EIGRP" },
+ { 0x03, "Static" },
+ { 0x04, "RIP" },
+ { 0x05, "Hello" },
+ { 0x06, "OSPF" },
+ { 0x07, "IS-IS" },
+ { 0x08, "EGP" },
+ { 0x09, "BGP" },
+ { 0x0a, "IDRP" },
+ { 0x0b, "Connected" },
+ { 0, NULL}
+};
+
+void
+eigrp_print(register const u_char *pptr, register u_int len) {
+
+ const struct eigrp_common_header *eigrp_com_header;
+ const struct eigrp_tlv_header *eigrp_tlv_header;
+ const u_char *tptr,*tlv_tptr;
+ u_int tlen,eigrp_tlv_len,eigrp_tlv_type,tlv_tlen, byte_length, bit_length;
+ u_int8_t prefix[4];
+
+ union {
+ const struct eigrp_tlv_general_parm_t *eigrp_tlv_general_parm;
+ const struct eigrp_tlv_sw_version_t *eigrp_tlv_sw_version;
+ const struct eigrp_tlv_ip_int_t *eigrp_tlv_ip_int;
+ const struct eigrp_tlv_ip_ext_t *eigrp_tlv_ip_ext;
+ const struct eigrp_tlv_at_cable_setup_t *eigrp_tlv_at_cable_setup;
+ const struct eigrp_tlv_at_int_t *eigrp_tlv_at_int;
+ const struct eigrp_tlv_at_ext_t *eigrp_tlv_at_ext;
+ } tlv_ptr;
+
+ tptr=pptr;
+ eigrp_com_header = (const struct eigrp_common_header *)pptr;
+ TCHECK(*eigrp_com_header);
+
+ /*
+ * Sanity checking of the header.
+ */
+ if (eigrp_com_header->version != EIGRP_VERSION) {
+ printf("EIGRP version %u packet not supported",eigrp_com_header->version);
+ return;
+ }
+
+ /* in non-verbose mode just lets print the basic Message Type*/
+ if (vflag < 1) {
+ printf("EIGRP %s, length: %u",
+ tok2str(eigrp_opcode_values, "unknown (%u)",eigrp_com_header->opcode),
+ len);
+ return;
+ }
+
+ /* ok they seem to want to know everything - lets fully decode it */
+
+ tlen=len-sizeof(struct eigrp_common_header);
+
+ /* FIXME print other header info */
+ printf("\n\tEIGRP v%u, opcode: %s (%u), chksum: 0x%04x, Flags: [%s]\n\tseq: 0x%08x, ack: 0x%08x, AS: %u, length: %u",
+ eigrp_com_header->version,
+ tok2str(eigrp_opcode_values, "unknown, type: %u",eigrp_com_header->opcode),
+ eigrp_com_header->opcode,
+ EXTRACT_16BITS(&eigrp_com_header->checksum),
+ tok2str(eigrp_common_header_flag_values,
+ "none",
+ EXTRACT_32BITS(&eigrp_com_header->flags)),
+ EXTRACT_32BITS(&eigrp_com_header->seq),
+ EXTRACT_32BITS(&eigrp_com_header->ack),
+ EXTRACT_32BITS(&eigrp_com_header->asn),
+ tlen);
+
+ tptr+=sizeof(const struct eigrp_common_header);
+
+ while(tlen>0) {
+ /* did we capture enough for fully decoding the object header ? */
+ TCHECK2(*tptr, sizeof(struct eigrp_tlv_header));
+
+ eigrp_tlv_header = (const struct eigrp_tlv_header *)tptr;
+ eigrp_tlv_len=EXTRACT_16BITS(&eigrp_tlv_header->length);
+ eigrp_tlv_type=EXTRACT_16BITS(&eigrp_tlv_header->type);
+
+
+ if (eigrp_tlv_len < sizeof(struct eigrp_tlv_header) ||
+ eigrp_tlv_len > tlen) {
+ print_unknown_data(tptr+sizeof(struct eigrp_tlv_header),"\n\t ",tlen);
+ return;
+ }
+
+ printf("\n\t %s TLV (0x%04x), length: %u",
+ tok2str(eigrp_tlv_values,
+ "Unknown",
+ eigrp_tlv_type),
+ eigrp_tlv_type,
+ eigrp_tlv_len);
+
+ tlv_tptr=tptr+sizeof(struct eigrp_tlv_header);
+ tlv_tlen=eigrp_tlv_len-sizeof(struct eigrp_tlv_header);
+
+ /* did we capture enough for fully decoding the object ? */
+ TCHECK2(*tptr, eigrp_tlv_len);
+
+ switch(eigrp_tlv_type) {
+
+ case EIGRP_TLV_GENERAL_PARM:
+ tlv_ptr.eigrp_tlv_general_parm = (const struct eigrp_tlv_general_parm_t *)tlv_tptr;
+
+ printf("\n\t holdtime: %us, k1 %u, k2 %u, k3 %u, k4 %u, k5 %u",
+ EXTRACT_16BITS(tlv_ptr.eigrp_tlv_general_parm->holdtime),
+ tlv_ptr.eigrp_tlv_general_parm->k1,
+ tlv_ptr.eigrp_tlv_general_parm->k2,
+ tlv_ptr.eigrp_tlv_general_parm->k3,
+ tlv_ptr.eigrp_tlv_general_parm->k4,
+ tlv_ptr.eigrp_tlv_general_parm->k5);
+ break;
+
+ case EIGRP_TLV_SW_VERSION:
+ tlv_ptr.eigrp_tlv_sw_version = (const struct eigrp_tlv_sw_version_t *)tlv_tptr;
+
+ printf("\n\t IOS version: %u.%u, EIGRP version %u.%u",
+ tlv_ptr.eigrp_tlv_sw_version->ios_major,
+ tlv_ptr.eigrp_tlv_sw_version->ios_minor,
+ tlv_ptr.eigrp_tlv_sw_version->eigrp_major,
+ tlv_ptr.eigrp_tlv_sw_version->eigrp_minor);
+ break;
+
+ case EIGRP_TLV_IP_INT:
+ tlv_ptr.eigrp_tlv_ip_int = (const struct eigrp_tlv_ip_int_t *)tlv_tptr;
+
+ bit_length = tlv_ptr.eigrp_tlv_ip_int->plen;
+ if (bit_length > 32) {
+ printf("\n\t illegal prefix length %u",bit_length);
+ break;
+ }
+ byte_length = (bit_length + 7) / 8; /* variable length encoding */
+ memset(prefix, 0, 4);
+ memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_int->destination,byte_length);
+
+ printf("\n\t IPv4 prefix: %15s/%u, nexthop: ",
+ ipaddr_string(prefix),
+ bit_length);
+ if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->nexthop) == 0)
+ printf("self");
+ else
+ printf("%s",ipaddr_string(&tlv_ptr.eigrp_tlv_ip_int->nexthop));
+
+ printf("\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
+ (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->delay)/100),
+ EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->bandwidth),
+ EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_ip_int->mtu),
+ tlv_ptr.eigrp_tlv_ip_int->hopcount,
+ tlv_ptr.eigrp_tlv_ip_int->reliability,
+ tlv_ptr.eigrp_tlv_ip_int->load);
+ break;
+
+ case EIGRP_TLV_IP_EXT:
+ tlv_ptr.eigrp_tlv_ip_ext = (const struct eigrp_tlv_ip_ext_t *)tlv_tptr;
+
+ bit_length = tlv_ptr.eigrp_tlv_ip_ext->plen;
+ if (bit_length > 32) {
+ printf("\n\t illegal prefix length %u",bit_length);
+ break;
+ }
+ byte_length = (bit_length + 7) / 8; /* variable length encoding */
+ memset(prefix, 0, 4);
+ memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_ext->destination,byte_length);
+
+ printf("\n\t IPv4 prefix: %15s/%u, nexthop: ",
+ ipaddr_string(prefix),
+ bit_length);
+ if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->nexthop) == 0)
+ printf("self");
+ else
+ printf("%s",ipaddr_string(&tlv_ptr.eigrp_tlv_ip_ext->nexthop));
+
+ printf("\n\t origin-router %s, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u",
+ ipaddr_string(tlv_ptr.eigrp_tlv_ip_ext->origin_router),
+ EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->origin_as),
+ tok2str(eigrp_ext_proto_id_values,"unknown",tlv_ptr.eigrp_tlv_ip_ext->proto_id),
+ tlv_ptr.eigrp_tlv_ip_ext->flags,
+ EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->tag),
+ EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->metric));
+
+ printf("\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
+ (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->delay)/100),
+ EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->bandwidth),
+ EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_ip_ext->mtu),
+ tlv_ptr.eigrp_tlv_ip_ext->hopcount,
+ tlv_ptr.eigrp_tlv_ip_ext->reliability,
+ tlv_ptr.eigrp_tlv_ip_ext->load);
+ break;
+
+ case EIGRP_TLV_AT_CABLE_SETUP:
+ tlv_ptr.eigrp_tlv_at_cable_setup = (const struct eigrp_tlv_at_cable_setup_t *)tlv_tptr;
+
+ printf("\n\t Cable-range: %u-%u, Router-ID %u",
+ EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_start),
+ EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_end),
+ EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->router_id));
+ break;
+
+ case EIGRP_TLV_AT_INT:
+ tlv_ptr.eigrp_tlv_at_int = (const struct eigrp_tlv_at_int_t *)tlv_tptr;
+
+ printf("\n\t Cable-Range: %u-%u, nexthop: ",
+ EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_start),
+ EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_end));
+
+ if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop) == 0)
+ printf("self");
+ else
+ printf("%u.%u",
+ EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop),
+ EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop[2]));
+
+ printf("\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
+ (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->delay)/100),
+ EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->bandwidth),
+ EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_at_int->mtu),
+ tlv_ptr.eigrp_tlv_at_int->hopcount,
+ tlv_ptr.eigrp_tlv_at_int->reliability,
+ tlv_ptr.eigrp_tlv_at_int->load);
+ break;
+
+ case EIGRP_TLV_AT_EXT:
+ tlv_ptr.eigrp_tlv_at_ext = (const struct eigrp_tlv_at_ext_t *)tlv_tptr;
+
+ printf("\n\t Cable-Range: %u-%u, nexthop: ",
+ EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_start),
+ EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_end));
+
+ if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop) == 0)
+ printf("self");
+ else
+ printf("%u.%u",
+ EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop),
+ EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop[2]));
+
+ printf("\n\t origin-router %u, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u",
+ EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->origin_router),
+ EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->origin_as),
+ tok2str(eigrp_ext_proto_id_values,"unknown",tlv_ptr.eigrp_tlv_at_ext->proto_id),
+ tlv_ptr.eigrp_tlv_at_ext->flags,
+ EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->tag),
+ EXTRACT_16BITS(tlv_ptr.eigrp_tlv_at_ext->metric));
+
+ printf("\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
+ (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->delay)/100),
+ EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->bandwidth),
+ EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_at_ext->mtu),
+ tlv_ptr.eigrp_tlv_at_ext->hopcount,
+ tlv_ptr.eigrp_tlv_at_ext->reliability,
+ tlv_ptr.eigrp_tlv_at_ext->load);
+ break;
+
+ /*
+ * FIXME those are the defined TLVs that lack a decoder
+ * you are welcome to contribute code ;-)
+ */
+
+ case EIGRP_TLV_AUTH:
+ case EIGRP_TLV_SEQ:
+ case EIGRP_TLV_MCAST_SEQ:
+ case EIGRP_TLV_IPX_INT:
+ case EIGRP_TLV_IPX_EXT:
+
+ default:
+ if (vflag <= 1)
+ print_unknown_data(tlv_tptr,"\n\t ",tlv_tlen);
+ break;
+ }
+ /* do we want to see an additionally hexdump ? */
+ if (vflag > 1)
+ print_unknown_data(tptr+sizeof(struct eigrp_tlv_header),"\n\t ",
+ eigrp_tlv_len-sizeof(struct eigrp_tlv_header));
+
+ tptr+=eigrp_tlv_len;
+ tlen-=eigrp_tlv_len;
+ }
+ return;
+trunc:
+ printf("\n\t\t packet exceeded snapshot");
+}
diff --git a/freebsd/contrib/tcpdump/print-enc.c b/freebsd/contrib/tcpdump/print-enc.c
new file mode 100644
index 00000000..db16f933
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-enc.c
@@ -0,0 +1,100 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/* $OpenBSD: print-enc.c,v 1.7 2002/02/19 19:39:40 millert Exp $ */
+
+/*
+ * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-enc.c,v 1.6 2008-11-18 07:35:32 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <pcap.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+
+#include "enc.h"
+
+#define ENC_PRINT_TYPE(wh, xf, nam) \
+ if ((wh) & (xf)) { \
+ printf("%s%s", nam, (wh) == (xf) ? "): " : ","); \
+ (wh) &= ~(xf); \
+ }
+
+u_int
+enc_if_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ register u_int length = h->len;
+ register u_int caplen = h->caplen;
+ int flags;
+ const struct enchdr *hdr;
+
+ if (caplen < ENC_HDRLEN) {
+ printf("[|enc]");
+ goto out;
+ }
+
+ hdr = (struct enchdr *)p;
+ flags = hdr->flags;
+ if (flags == 0)
+ printf("(unprotected): ");
+ else
+ printf("(");
+ ENC_PRINT_TYPE(flags, M_AUTH, "authentic");
+ ENC_PRINT_TYPE(flags, M_CONF, "confidential");
+ /* ENC_PRINT_TYPE(flags, M_TUNNEL, "tunnel"); */
+ printf("SPI 0x%08x: ", EXTRACT_32BITS(&hdr->spi));
+
+ length -= ENC_HDRLEN;
+ caplen -= ENC_HDRLEN;
+ p += ENC_HDRLEN;
+
+ switch (hdr->af) {
+ case AF_INET:
+ ip_print(gndo, p, length);
+ break;
+#ifdef INET6
+ case AF_INET6:
+ ip6_print(gndo, p, length);
+ break;
+#endif /*INET6*/
+ }
+
+out:
+ return (ENC_HDRLEN);
+}
+
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-esp.c b/freebsd/contrib/tcpdump/print-esp.c
new file mode 100644
index 00000000..6bf04dd0
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-esp.c
@@ -0,0 +1,696 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/* $NetBSD: print-ah.c,v 1.4 1996/05/20 00:41:16 fvdl Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-esp.c,v 1.58 2007-12-07 00:03:07 mcr Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include <tcpdump-stdinc.h>
+
+#include <stdlib.h>
+
+#ifdef HAVE_LIBCRYPTO
+#ifdef HAVE_OPENSSL_EVP_H
+#include <openssl/evp.h>
+#endif
+#endif
+
+#include <stdio.h>
+
+#include "ip.h"
+#include "esp.h"
+#ifdef INET6
+#include "ip6.h"
+#endif
+
+#include "netdissect.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+#ifndef HAVE_SOCKADDR_STORAGE
+#ifdef INET6
+struct sockaddr_storage {
+ union {
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+ } un;
+};
+#else
+#define sockaddr_storage sockaddr
+#endif
+#endif /* HAVE_SOCKADDR_STORAGE */
+
+#ifdef HAVE_LIBCRYPTO
+struct sa_list {
+ struct sa_list *next;
+ struct sockaddr_storage daddr;
+ u_int32_t spi; /* if == 0, then IKEv2 */
+ int initiator;
+ u_char spii[8]; /* for IKEv2 */
+ u_char spir[8];
+ const EVP_CIPHER *evp;
+ int ivlen;
+ int authlen;
+ u_char authsecret[256];
+ int authsecret_len;
+ u_char secret[256]; /* is that big enough for all secrets? */
+ int secretlen;
+};
+
+/*
+ * this will adjust ndo_packetp and ndo_snapend to new buffer!
+ */
+int esp_print_decrypt_buffer_by_ikev2(netdissect_options *ndo,
+ int initiator,
+ u_char spii[8], u_char spir[8],
+ u_char *buf, u_char *end)
+{
+ struct sa_list *sa;
+ u_char *iv;
+ int len;
+ EVP_CIPHER_CTX ctx;
+
+ /* initiator arg is any non-zero value */
+ if(initiator) initiator=1;
+
+ /* see if we can find the SA, and if so, decode it */
+ for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
+ if (sa->spi == 0
+ && initiator == sa->initiator
+ && memcmp(spii, sa->spii, 8) == 0
+ && memcmp(spir, sa->spir, 8) == 0)
+ break;
+ }
+
+ if(sa == NULL) return 0;
+ if(sa->evp == NULL) return 0;
+
+ /*
+ * remove authenticator, and see if we still have something to
+ * work with
+ */
+ end = end - sa->authlen;
+ iv = buf;
+ buf = buf + sa->ivlen;
+ len = end-buf;
+
+ if(end <= buf) return 0;
+
+ memset(&ctx, 0, sizeof(ctx));
+ if (EVP_CipherInit(&ctx, sa->evp, sa->secret, NULL, 0) < 0)
+ (*ndo->ndo_warning)(ndo, "espkey init failed");
+ EVP_CipherInit(&ctx, NULL, NULL, iv, 0);
+ EVP_Cipher(&ctx, buf, buf, len);
+ EVP_CIPHER_CTX_cleanup(&ctx);
+
+ ndo->ndo_packetp = buf;
+ ndo->ndo_snapend = end;
+
+ return 1;
+
+}
+
+static void esp_print_addsa(netdissect_options *ndo,
+ struct sa_list *sa, int sa_def)
+{
+ /* copy the "sa" */
+
+ struct sa_list *nsa;
+
+ nsa = (struct sa_list *)malloc(sizeof(struct sa_list));
+ if (nsa == NULL)
+ (*ndo->ndo_error)(ndo, "ran out of memory to allocate sa structure");
+
+ *nsa = *sa;
+
+ if (sa_def)
+ ndo->ndo_sa_default = nsa;
+
+ nsa->next = ndo->ndo_sa_list_head;
+ ndo->ndo_sa_list_head = nsa;
+}
+
+
+static u_int hexdigit(netdissect_options *ndo, char hex)
+{
+ if (hex >= '0' && hex <= '9')
+ return (hex - '0');
+ else if (hex >= 'A' && hex <= 'F')
+ return (hex - 'A' + 10);
+ else if (hex >= 'a' && hex <= 'f')
+ return (hex - 'a' + 10);
+ else {
+ (*ndo->ndo_error)(ndo, "invalid hex digit %c in espsecret\n", hex);
+ return 0;
+ }
+}
+
+static u_int hex2byte(netdissect_options *ndo, char *hexstring)
+{
+ u_int byte;
+
+ byte = (hexdigit(ndo, hexstring[0]) << 4) + hexdigit(ndo, hexstring[1]);
+ return byte;
+}
+
+/*
+ * returns size of binary, 0 on failure.
+ */
+static
+int espprint_decode_hex(netdissect_options *ndo,
+ u_char *binbuf, unsigned int binbuf_len,
+ char *hex)
+{
+ unsigned int len;
+ int i;
+
+ len = strlen(hex) / 2;
+
+ if (len > binbuf_len) {
+ (*ndo->ndo_warning)(ndo, "secret is too big: %d\n", len);
+ return 0;
+ }
+
+ i = 0;
+ while (hex[0] != '\0' && hex[1]!='\0') {
+ binbuf[i] = hex2byte(ndo, hex);
+ hex += 2;
+ i++;
+ }
+
+ return i;
+}
+
+/*
+ * decode the form: SPINUM@IP <tab> ALGONAME:0xsecret
+ */
+
+static int
+espprint_decode_encalgo(netdissect_options *ndo,
+ char *decode, struct sa_list *sa)
+{
+ int len;
+ size_t i;
+ const EVP_CIPHER *evp;
+ int authlen = 0;
+ char *colon, *p;
+
+ colon = strchr(decode, ':');
+ if (colon == NULL) {
+ (*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode);
+ return 0;
+ }
+ *colon = '\0';
+
+ len = colon - decode;
+ if (strlen(decode) > strlen("-hmac96") &&
+ !strcmp(decode + strlen(decode) - strlen("-hmac96"),
+ "-hmac96")) {
+ p = strstr(decode, "-hmac96");
+ *p = '\0';
+ authlen = 12;
+ }
+ if (strlen(decode) > strlen("-cbc") &&
+ !strcmp(decode + strlen(decode) - strlen("-cbc"), "-cbc")) {
+ p = strstr(decode, "-cbc");
+ *p = '\0';
+ }
+ evp = EVP_get_cipherbyname(decode);
+
+ if (!evp) {
+ (*ndo->ndo_warning)(ndo, "failed to find cipher algo %s\n", decode);
+ sa->evp = NULL;
+ sa->authlen = 0;
+ sa->ivlen = 0;
+ return 0;
+ }
+
+ sa->evp = evp;
+ sa->authlen = authlen;
+ sa->ivlen = EVP_CIPHER_iv_length(evp);
+
+ colon++;
+ if (colon[0] == '0' && colon[1] == 'x') {
+ /* decode some hex! */
+
+ colon += 2;
+ sa->secretlen = espprint_decode_hex(ndo, sa->secret, sizeof(sa->secret), colon);
+ if(sa->secretlen == 0) return 0;
+ } else {
+ i = strlen(colon);
+
+ if (i < sizeof(sa->secret)) {
+ memcpy(sa->secret, colon, i);
+ sa->secretlen = i;
+ } else {
+ memcpy(sa->secret, colon, sizeof(sa->secret));
+ sa->secretlen = sizeof(sa->secret);
+ }
+ }
+
+ return 1;
+}
+
+/*
+ * for the moment, ignore the auth algorith, just hard code the authenticator
+ * length. Need to research how openssl looks up HMAC stuff.
+ */
+static int
+espprint_decode_authalgo(netdissect_options *ndo,
+ char *decode, struct sa_list *sa)
+{
+ char *colon;
+
+ colon = strchr(decode, ':');
+ if (colon == NULL) {
+ (*ndo->ndo_warning)(ndo, "failed to decode espsecret: %s\n", decode);
+ return 0;
+ }
+ *colon = '\0';
+
+ if(strcasecmp(colon,"sha1") == 0 ||
+ strcasecmp(colon,"md5") == 0) {
+ sa->authlen = 12;
+ }
+ return 1;
+}
+
+static void esp_print_decode_ikeline(netdissect_options *ndo, char *line,
+ const char *file, int lineno)
+{
+ /* it's an IKEv2 secret, store it instead */
+ struct sa_list sa1;
+
+ char *init;
+ char *icookie, *rcookie;
+ int ilen, rlen;
+ char *authkey;
+ char *enckey;
+
+ init = strsep(&line, " \t");
+ icookie = strsep(&line, " \t");
+ rcookie = strsep(&line, " \t");
+ authkey = strsep(&line, " \t");
+ enckey = strsep(&line, " \t");
+
+ /* if any fields are missing */
+ if(!init || !icookie || !rcookie || !authkey || !enckey) {
+ (*ndo->ndo_warning)(ndo, "print_esp: failed to find all fields for ikev2 at %s:%u",
+ file, lineno);
+
+ return;
+ }
+
+ ilen = strlen(icookie);
+ rlen = strlen(rcookie);
+
+ if((init[0]!='I' && init[0]!='R')
+ || icookie[0]!='0' || icookie[1]!='x'
+ || rcookie[0]!='0' || rcookie[1]!='x'
+ || ilen!=18
+ || rlen!=18) {
+ (*ndo->ndo_warning)(ndo, "print_esp: line %s:%u improperly formatted.",
+ file, lineno);
+
+ (*ndo->ndo_warning)(ndo, "init=%s icookie=%s(%u) rcookie=%s(%u)",
+ init, icookie, ilen, rcookie, rlen);
+
+ return;
+ }
+
+ sa1.spi = 0;
+ sa1.initiator = (init[0] == 'I');
+ if(espprint_decode_hex(ndo, sa1.spii, sizeof(sa1.spii), icookie+2)!=8)
+ return;
+
+ if(espprint_decode_hex(ndo, sa1.spir, sizeof(sa1.spir), rcookie+2)!=8)
+ return;
+
+ if(!espprint_decode_encalgo(ndo, enckey, &sa1)) return;
+
+ if(!espprint_decode_authalgo(ndo, authkey, &sa1)) return;
+
+ esp_print_addsa(ndo, &sa1, FALSE);
+}
+
+/*
+ *
+ * special form: file /name
+ * causes us to go read from this file instead.
+ *
+ */
+static void esp_print_decode_onesecret(netdissect_options *ndo, char *line,
+ const char *file, int lineno)
+{
+ struct sa_list sa1;
+ int sa_def;
+
+ char *spikey;
+ char *decode;
+
+ spikey = strsep(&line, " \t");
+ sa_def = 0;
+ memset(&sa1, 0, sizeof(struct sa_list));
+
+ /* if there is only one token, then it is an algo:key token */
+ if (line == NULL) {
+ decode = spikey;
+ spikey = NULL;
+ /* memset(&sa1.daddr, 0, sizeof(sa1.daddr)); */
+ /* sa1.spi = 0; */
+ sa_def = 1;
+ } else
+ decode = line;
+
+ if (spikey && strcasecmp(spikey, "file") == 0) {
+ /* open file and read it */
+ FILE *secretfile;
+ char fileline[1024];
+ int lineno=0;
+ char *nl;
+ char *filename = line;
+
+ secretfile = fopen(filename, FOPEN_READ_TXT);
+ if (secretfile == NULL) {
+ perror(filename);
+ exit(3);
+ }
+
+ while (fgets(fileline, sizeof(fileline)-1, secretfile) != NULL) {
+ lineno++;
+ /* remove newline from the line */
+ nl = strchr(fileline, '\n');
+ if (nl)
+ *nl = '\0';
+ if (fileline[0] == '#') continue;
+ if (fileline[0] == '\0') continue;
+
+ esp_print_decode_onesecret(ndo, fileline, filename, lineno);
+ }
+ fclose(secretfile);
+
+ return;
+ }
+
+ if (spikey && strcasecmp(spikey, "ikev2") == 0) {
+ esp_print_decode_ikeline(ndo, line, file, lineno);
+ return;
+ }
+
+ if (spikey) {
+
+ char *spistr, *foo;
+ u_int32_t spino;
+ struct sockaddr_in *sin;
+#ifdef INET6
+ struct sockaddr_in6 *sin6;
+#endif
+
+ spistr = strsep(&spikey, "@");
+
+ spino = strtoul(spistr, &foo, 0);
+ if (spistr == foo || !spikey) {
+ (*ndo->ndo_warning)(ndo, "print_esp: failed to decode spi# %s\n", foo);
+ return;
+ }
+
+ sa1.spi = spino;
+
+ sin = (struct sockaddr_in *)&sa1.daddr;
+#ifdef INET6
+ sin6 = (struct sockaddr_in6 *)&sa1.daddr;
+ if (inet_pton(AF_INET6, spikey, &sin6->sin6_addr) == 1) {
+#ifdef HAVE_SOCKADDR_SA_LEN
+ sin6->sin6_len = sizeof(struct sockaddr_in6);
+#endif
+ sin6->sin6_family = AF_INET6;
+ } else
+#endif
+ if (inet_pton(AF_INET, spikey, &sin->sin_addr) == 1) {
+#ifdef HAVE_SOCKADDR_SA_LEN
+ sin->sin_len = sizeof(struct sockaddr_in);
+#endif
+ sin->sin_family = AF_INET;
+ } else {
+ (*ndo->ndo_warning)(ndo, "print_esp: can not decode IP# %s\n", spikey);
+ return;
+ }
+ }
+
+ if (decode) {
+ /* skip any blank spaces */
+ while (isspace((unsigned char)*decode))
+ decode++;
+
+ if(!espprint_decode_encalgo(ndo, decode, &sa1)) {
+ return;
+ }
+ }
+
+ esp_print_addsa(ndo, &sa1, sa_def);
+}
+
+static void esp_init(netdissect_options *ndo _U_)
+{
+
+ OpenSSL_add_all_algorithms();
+ EVP_add_cipher_alias(SN_des_ede3_cbc, "3des");
+}
+
+void esp_print_decodesecret(netdissect_options *ndo)
+{
+ char *line;
+ char *p;
+ static int initialized = 0;
+
+ if (!initialized) {
+ esp_init(ndo);
+ initialized = 1;
+ }
+
+ p = ndo->ndo_espsecret;
+
+ while (p && p[0] != '\0') {
+ /* pick out the first line or first thing until a comma */
+ if ((line = strsep(&p, "\n,")) == NULL) {
+ line = p;
+ p = NULL;
+ }
+
+ esp_print_decode_onesecret(ndo, line, "cmdline", 0);
+ }
+
+ ndo->ndo_espsecret = NULL;
+}
+
+#endif
+
+int
+esp_print(netdissect_options *ndo,
+ const u_char *bp, const int length, const u_char *bp2
+#ifndef HAVE_LIBCRYPTO
+ _U_
+#endif
+ ,
+ int *nhdr
+#ifndef HAVE_LIBCRYPTO
+ _U_
+#endif
+ ,
+ int *padlen
+#ifndef HAVE_LIBCRYPTO
+ _U_
+#endif
+ )
+{
+ register const struct newesp *esp;
+ register const u_char *ep;
+#ifdef HAVE_LIBCRYPTO
+ struct ip *ip;
+ struct sa_list *sa = NULL;
+ int espsecret_keylen;
+#ifdef INET6
+ struct ip6_hdr *ip6 = NULL;
+#endif
+ int advance;
+ int len;
+ u_char *secret;
+ int ivlen = 0;
+ u_char *ivoff;
+ u_char *p;
+ EVP_CIPHER_CTX ctx;
+ int blocksz;
+#endif
+
+ esp = (struct newesp *)bp;
+
+#ifdef HAVE_LIBCRYPTO
+ secret = NULL;
+ advance = 0;
+#endif
+
+#if 0
+ /* keep secret out of a register */
+ p = (u_char *)&secret;
+#endif
+
+ /* 'ep' points to the end of available data. */
+ ep = ndo->ndo_snapend;
+
+ if ((u_char *)(esp + 1) >= ep) {
+ fputs("[|ESP]", stdout);
+ goto fail;
+ }
+ (*ndo->ndo_printf)(ndo, "ESP(spi=0x%08x", EXTRACT_32BITS(&esp->esp_spi));
+ (*ndo->ndo_printf)(ndo, ",seq=0x%x)", EXTRACT_32BITS(&esp->esp_seq));
+ (*ndo->ndo_printf)(ndo, ", length %u", length);
+
+#ifndef HAVE_LIBCRYPTO
+ goto fail;
+#else
+ /* initiailize SAs */
+ if (ndo->ndo_sa_list_head == NULL) {
+ if (!ndo->ndo_espsecret)
+ goto fail;
+
+ esp_print_decodesecret(ndo);
+ }
+
+ if (ndo->ndo_sa_list_head == NULL)
+ goto fail;
+
+ ip = (struct ip *)bp2;
+ switch (IP_V(ip)) {
+#ifdef INET6
+ case 6:
+ ip6 = (struct ip6_hdr *)bp2;
+ /* we do not attempt to decrypt jumbograms */
+ if (!EXTRACT_16BITS(&ip6->ip6_plen))
+ goto fail;
+ /* if we can't get nexthdr, we do not need to decrypt it */
+ len = sizeof(struct ip6_hdr) + EXTRACT_16BITS(&ip6->ip6_plen);
+
+ /* see if we can find the SA, and if so, decode it */
+ for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&sa->daddr;
+ if (sa->spi == EXTRACT_32BITS(&esp->esp_spi) &&
+ sin6->sin6_family == AF_INET6 &&
+ memcmp(&sin6->sin6_addr, &ip6->ip6_dst,
+ sizeof(struct in6_addr)) == 0) {
+ break;
+ }
+ }
+ break;
+#endif /*INET6*/
+ case 4:
+ /* nexthdr & padding are in the last fragment */
+ if (EXTRACT_16BITS(&ip->ip_off) & IP_MF)
+ goto fail;
+ len = EXTRACT_16BITS(&ip->ip_len);
+
+ /* see if we can find the SA, and if so, decode it */
+ for (sa = ndo->ndo_sa_list_head; sa != NULL; sa = sa->next) {
+ struct sockaddr_in *sin = (struct sockaddr_in *)&sa->daddr;
+ if (sa->spi == EXTRACT_32BITS(&esp->esp_spi) &&
+ sin->sin_family == AF_INET &&
+ sin->sin_addr.s_addr == ip->ip_dst.s_addr) {
+ break;
+ }
+ }
+ break;
+ default:
+ goto fail;
+ }
+
+ /* if we didn't find the specific one, then look for
+ * an unspecified one.
+ */
+ if (sa == NULL)
+ sa = ndo->ndo_sa_default;
+
+ /* if not found fail */
+ if (sa == NULL)
+ goto fail;
+
+ /* if we can't get nexthdr, we do not need to decrypt it */
+ if (ep - bp2 < len)
+ goto fail;
+ if (ep - bp2 > len) {
+ /* FCS included at end of frame (NetBSD 1.6 or later) */
+ ep = bp2 + len;
+ }
+
+ ivoff = (u_char *)(esp + 1) + 0;
+ ivlen = sa->ivlen;
+ secret = sa->secret;
+ espsecret_keylen = sa->secretlen;
+ ep = ep - sa->authlen;
+
+ if (sa->evp) {
+ memset(&ctx, 0, sizeof(ctx));
+ if (EVP_CipherInit(&ctx, sa->evp, secret, NULL, 0) < 0)
+ (*ndo->ndo_warning)(ndo, "espkey init failed");
+
+ blocksz = EVP_CIPHER_CTX_block_size(&ctx);
+
+ p = ivoff;
+ EVP_CipherInit(&ctx, NULL, NULL, p, 0);
+ EVP_Cipher(&ctx, p + ivlen, p + ivlen, ep - (p + ivlen));
+ EVP_CIPHER_CTX_cleanup(&ctx);
+ advance = ivoff - (u_char *)esp + ivlen;
+ } else
+ advance = sizeof(struct newesp);
+
+ /* sanity check for pad length */
+ if (ep - bp < *(ep - 2))
+ goto fail;
+
+ if (padlen)
+ *padlen = *(ep - 2) + 2;
+
+ if (nhdr)
+ *nhdr = *(ep - 1);
+
+ (ndo->ndo_printf)(ndo, ": ");
+ return advance;
+#endif
+
+fail:
+ return -1;
+}
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-ether.c b/freebsd/contrib/tcpdump/print-ether.c
new file mode 100644
index 00000000..aaf067b1
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-ether.c
@@ -0,0 +1,441 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ether.c,v 1.106 2008-02-06 10:47:53 guy Exp $ (LBL)";
+#endif
+
+#define NETDISSECT_REWORKED
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <pcap.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+#include "ether.h"
+
+const struct tok ethertype_values[] = {
+ { ETHERTYPE_IP, "IPv4" },
+ { ETHERTYPE_MPLS, "MPLS unicast" },
+ { ETHERTYPE_MPLS_MULTI, "MPLS multicast" },
+ { ETHERTYPE_IPV6, "IPv6" },
+ { ETHERTYPE_8021Q, "802.1Q" },
+ { ETHERTYPE_8021Q9100, "802.1Q-9100" },
+ { ETHERTYPE_8021QinQ, "802.1Q-QinQ" },
+ { ETHERTYPE_8021Q9200, "802.1Q-9200" },
+ { ETHERTYPE_VMAN, "VMAN" },
+ { ETHERTYPE_PUP, "PUP" },
+ { ETHERTYPE_ARP, "ARP"},
+ { ETHERTYPE_REVARP, "Reverse ARP"},
+ { ETHERTYPE_NS, "NS" },
+ { ETHERTYPE_SPRITE, "Sprite" },
+ { ETHERTYPE_TRAIL, "Trail" },
+ { ETHERTYPE_MOPDL, "MOP DL" },
+ { ETHERTYPE_MOPRC, "MOP RC" },
+ { ETHERTYPE_DN, "DN" },
+ { ETHERTYPE_LAT, "LAT" },
+ { ETHERTYPE_SCA, "SCA" },
+ { ETHERTYPE_TEB, "TEB" },
+ { ETHERTYPE_LANBRIDGE, "Lanbridge" },
+ { ETHERTYPE_DECDNS, "DEC DNS" },
+ { ETHERTYPE_DECDTS, "DEC DTS" },
+ { ETHERTYPE_VEXP, "VEXP" },
+ { ETHERTYPE_VPROD, "VPROD" },
+ { ETHERTYPE_ATALK, "Appletalk" },
+ { ETHERTYPE_AARP, "Appletalk ARP" },
+ { ETHERTYPE_IPX, "IPX" },
+ { ETHERTYPE_PPP, "PPP" },
+ { ETHERTYPE_MPCP, "MPCP" },
+ { ETHERTYPE_SLOW, "Slow Protocols" },
+ { ETHERTYPE_PPPOED, "PPPoE D" },
+ { ETHERTYPE_PPPOES, "PPPoE S" },
+ { ETHERTYPE_EAPOL, "EAPOL" },
+ { ETHERTYPE_RRCP, "RRCP" },
+ { ETHERTYPE_MS_NLB_HB, "MS NLB heartbeat" },
+ { ETHERTYPE_JUMBO, "Jumbo" },
+ { ETHERTYPE_LOOPBACK, "Loopback" },
+ { ETHERTYPE_ISO, "OSI" },
+ { ETHERTYPE_GRE_ISO, "GRE-OSI" },
+ { ETHERTYPE_CFM_OLD, "CFM (old)" },
+ { ETHERTYPE_CFM, "CFM" },
+ { ETHERTYPE_LLDP, "LLDP" },
+ { ETHERTYPE_TIPC, "TIPC"},
+ { 0, NULL}
+};
+
+static inline void
+ether_hdr_print(netdissect_options *ndo,
+ const u_char *bp, u_int length)
+{
+ register const struct ether_header *ep;
+ u_int16_t ether_type;
+
+ ep = (const struct ether_header *)bp;
+
+ (void)ND_PRINT((ndo, "%s > %s",
+ etheraddr_string(ESRC(ep)),
+ etheraddr_string(EDST(ep))));
+
+ ether_type = EXTRACT_16BITS(&ep->ether_type);
+ if (!ndo->ndo_qflag) {
+ if (ether_type <= ETHERMTU)
+ (void)ND_PRINT((ndo, ", 802.3"));
+ else
+ (void)ND_PRINT((ndo, ", ethertype %s (0x%04x)",
+ tok2str(ethertype_values,"Unknown", ether_type),
+ ether_type));
+ } else {
+ if (ether_type <= ETHERMTU)
+ (void)ND_PRINT((ndo, ", 802.3"));
+ else
+ (void)ND_PRINT((ndo, ", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", ether_type)));
+ }
+
+ (void)ND_PRINT((ndo, ", length %u: ", length));
+}
+
+/*
+ * Print an Ethernet frame.
+ * This might be encapsulated within another frame; we might be passed
+ * a pointer to a function that can print header information for that
+ * frame's protocol, and an argument to pass to that function.
+ */
+void
+ether_print(netdissect_options *ndo,
+ const u_char *p, u_int length, u_int caplen,
+ void (*print_encap_header)(netdissect_options *ndo, const u_char *), const u_char *encap_header_arg)
+{
+ struct ether_header *ep;
+ u_int orig_length;
+ u_short ether_type;
+ u_short extracted_ether_type;
+
+ if (caplen < ETHER_HDRLEN || length < ETHER_HDRLEN) {
+ ND_PRINT((ndo, "[|ether]"));
+ return;
+ }
+
+ if (ndo->ndo_eflag) {
+ if (print_encap_header != NULL)
+ (*print_encap_header)(ndo, encap_header_arg);
+ ether_hdr_print(ndo, p, length);
+ }
+ orig_length = length;
+
+ length -= ETHER_HDRLEN;
+ caplen -= ETHER_HDRLEN;
+ ep = (struct ether_header *)p;
+ p += ETHER_HDRLEN;
+
+ ether_type = EXTRACT_16BITS(&ep->ether_type);
+
+recurse:
+ /*
+ * Is it (gag) an 802.3 encapsulation?
+ */
+ if (ether_type <= ETHERMTU) {
+ /* Try to print the LLC-layer header & higher layers */
+ if (llc_print(p, length, caplen, ESRC(ep), EDST(ep),
+ &extracted_ether_type) == 0) {
+ /* ether_type not known, print raw packet */
+ if (!ndo->ndo_eflag) {
+ if (print_encap_header != NULL)
+ (*print_encap_header)(ndo, encap_header_arg);
+ ether_hdr_print(ndo, (u_char *)ep, orig_length);
+ }
+
+ if (!ndo->ndo_suppress_default_print)
+ ndo->ndo_default_print(ndo, p, caplen);
+ }
+ } else if (ether_type == ETHERTYPE_8021Q ||
+ ether_type == ETHERTYPE_8021Q9100 ||
+ ether_type == ETHERTYPE_8021Q9200 ||
+ ether_type == ETHERTYPE_8021QinQ) {
+ /*
+ * Print VLAN information, and then go back and process
+ * the enclosed type field.
+ */
+ if (caplen < 4 || length < 4) {
+ ND_PRINT((ndo, "[|vlan]"));
+ return;
+ }
+ if (ndo->ndo_eflag) {
+ u_int16_t tag = EXTRACT_16BITS(p);
+
+ ND_PRINT((ndo, "vlan %u, p %u%s, ",
+ tag & 0xfff,
+ tag >> 13,
+ (tag & 0x1000) ? ", CFI" : ""));
+ }
+
+ ether_type = EXTRACT_16BITS(p + 2);
+ if (ndo->ndo_eflag && ether_type > ETHERMTU)
+ ND_PRINT((ndo, "ethertype %s, ", tok2str(ethertype_values,"0x%04x", ether_type)));
+ p += 4;
+ length -= 4;
+ caplen -= 4;
+ goto recurse;
+ } else if (ether_type == ETHERTYPE_JUMBO) {
+ /*
+ * Alteon jumbo frames.
+ * See
+ *
+ * http://tools.ietf.org/html/draft-ietf-isis-ext-eth-01
+ *
+ * which indicates that, following the type field,
+ * there's an LLC header and payload.
+ */
+ /* Try to print the LLC-layer header & higher layers */
+ if (llc_print(p, length, caplen, ESRC(ep), EDST(ep),
+ &extracted_ether_type) == 0) {
+ /* ether_type not known, print raw packet */
+ if (!ndo->ndo_eflag) {
+ if (print_encap_header != NULL)
+ (*print_encap_header)(ndo, encap_header_arg);
+ ether_hdr_print(ndo, (u_char *)ep, orig_length);
+ }
+
+ if (!ndo->ndo_suppress_default_print)
+ ndo->ndo_default_print(ndo, p, caplen);
+ }
+ } else {
+ if (ethertype_print(ndo, ether_type, p, length, caplen) == 0) {
+ /* ether_type not known, print raw packet */
+ if (!ndo->ndo_eflag) {
+ if (print_encap_header != NULL)
+ (*print_encap_header)(ndo, encap_header_arg);
+ ether_hdr_print(ndo, (u_char *)ep, orig_length);
+ }
+
+ if (!ndo->ndo_suppress_default_print)
+ ndo->ndo_default_print(ndo, p, caplen);
+ }
+ }
+}
+
+/*
+ * This is the top level routine of the printer. 'p' points
+ * to the ether header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ */
+u_int
+ether_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
+ const u_char *p)
+{
+ ether_print(ndo, p, h->len, h->caplen, NULL, NULL);
+
+ return (ETHER_HDRLEN);
+}
+
+/*
+ * This is the top level routine of the printer. 'p' points
+ * to the ether header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ *
+ * This is for DLT_NETANALYZER, which has a 4-byte pseudo-header
+ * before the Ethernet header.
+ */
+u_int
+netanalyzer_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h,
+ const u_char *p)
+{
+ /*
+ * Fail if we don't have enough data for the Hilscher pseudo-header.
+ */
+ if (h->len < 4 || h->caplen < 4) {
+ printf("[|netanalyzer]");
+ return (h->caplen);
+ }
+
+ /* Skip the pseudo-header. */
+ ether_print(ndo, p + 4, h->len - 4, h->caplen - 4, NULL, NULL);
+
+ return (4 + ETHER_HDRLEN);
+}
+
+/*
+ * This is the top level routine of the printer. 'p' points
+ * to the ether header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ *
+ * This is for DLT_NETANALYZER_TRANSPARENT, which has a 4-byte
+ * pseudo-header, a 7-byte Ethernet preamble, and a 1-byte Ethernet SOF
+ * before the Ethernet header.
+ */
+u_int
+netanalyzer_transparent_if_print(netdissect_options *ndo,
+ const struct pcap_pkthdr *h,
+ const u_char *p)
+{
+ /*
+ * Fail if we don't have enough data for the Hilscher pseudo-header,
+ * preamble, and SOF.
+ */
+ if (h->len < 12 || h->caplen < 12) {
+ printf("[|netanalyzer-transparent]");
+ return (h->caplen);
+ }
+
+ /* Skip the pseudo-header, preamble, and SOF. */
+ ether_print(ndo, p + 12, h->len - 12, h->caplen - 12, NULL, NULL);
+
+ return (12 + ETHER_HDRLEN);
+}
+
+/*
+ * Prints the packet payload, given an Ethernet type code for the payload's
+ * protocol.
+ *
+ * Returns non-zero if it can do so, zero if the ethertype is unknown.
+ */
+
+int
+ethertype_print(netdissect_options *ndo,
+ u_short ether_type, const u_char *p,
+ u_int length, u_int caplen)
+{
+ switch (ether_type) {
+
+ case ETHERTYPE_IP:
+ ip_print(ndo, p, length);
+ return (1);
+
+#ifdef INET6
+ case ETHERTYPE_IPV6:
+ ip6_print(ndo, p, length);
+ return (1);
+#endif /*INET6*/
+
+ case ETHERTYPE_ARP:
+ case ETHERTYPE_REVARP:
+ arp_print(ndo, p, length, caplen);
+ return (1);
+
+ case ETHERTYPE_DN:
+ decnet_print(/*ndo,*/p, length, caplen);
+ return (1);
+
+ case ETHERTYPE_ATALK:
+ if (ndo->ndo_vflag)
+ fputs("et1 ", stdout);
+ atalk_print(/*ndo,*/p, length);
+ return (1);
+
+ case ETHERTYPE_AARP:
+ aarp_print(/*ndo,*/p, length);
+ return (1);
+
+ case ETHERTYPE_IPX:
+ ND_PRINT((ndo, "(NOV-ETHII) "));
+ ipx_print(/*ndo,*/p, length);
+ return (1);
+
+ case ETHERTYPE_ISO:
+ isoclns_print(/*ndo,*/p+1, length-1, length-1);
+ return(1);
+
+ case ETHERTYPE_PPPOED:
+ case ETHERTYPE_PPPOES:
+ case ETHERTYPE_PPPOED2:
+ case ETHERTYPE_PPPOES2:
+ pppoe_print(/*ndo,*/p, length);
+ return (1);
+
+ case ETHERTYPE_EAPOL:
+ eap_print(ndo, p, length);
+ return (1);
+
+ case ETHERTYPE_RRCP:
+ rrcp_print(ndo, p - 14 , length + 14);
+ return (1);
+
+ case ETHERTYPE_PPP:
+ if (length) {
+ printf(": ");
+ ppp_print(/*ndo,*/p, length);
+ }
+ return (1);
+
+ case ETHERTYPE_MPCP:
+ mpcp_print(/*ndo,*/p, length);
+ return (1);
+
+ case ETHERTYPE_SLOW:
+ slow_print(/*ndo,*/p, length);
+ return (1);
+
+ case ETHERTYPE_CFM:
+ case ETHERTYPE_CFM_OLD:
+ cfm_print(/*ndo,*/p, length);
+ return (1);
+
+ case ETHERTYPE_LLDP:
+ lldp_print(/*ndo,*/p, length);
+ return (1);
+
+ case ETHERTYPE_LOOPBACK:
+ return (1);
+
+ case ETHERTYPE_MPLS:
+ case ETHERTYPE_MPLS_MULTI:
+ mpls_print(/*ndo,*/p, length);
+ return (1);
+
+ case ETHERTYPE_TIPC:
+ tipc_print(ndo, p, length, caplen);
+ return (1);
+
+ case ETHERTYPE_MS_NLB_HB:
+ msnlb_print(ndo, p, length);
+ return (1);
+
+ case ETHERTYPE_LAT:
+ case ETHERTYPE_SCA:
+ case ETHERTYPE_MOPRC:
+ case ETHERTYPE_MOPDL:
+ /* default_print for now */
+ default:
+ return (0);
+ }
+}
+
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */
+
diff --git a/freebsd/contrib/tcpdump/print-fddi.c b/freebsd/contrib/tcpdump/print-fddi.c
new file mode 100644
index 00000000..9bca7077
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-fddi.c
@@ -0,0 +1,313 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-fddi.c,v 1.66 2005-11-13 12:12:41 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <pcap.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+
+#include "ether.h"
+#include "fddi.h"
+
+/*
+ * Some FDDI interfaces use bit-swapped addresses.
+ */
+#if defined(ultrix) || defined(__alpha) || defined(__bsdi) || defined(__NetBSD__) || defined(__linux__)
+int fddi_bitswap = 0;
+#else
+int fddi_bitswap = 1;
+#endif
+
+/*
+ * FDDI support for tcpdump, by Jeffrey Mogul [DECWRL], June 1992
+ *
+ * Based in part on code by Van Jacobson, which bears this note:
+ *
+ * NOTE: This is a very preliminary hack for FDDI support.
+ * There are all sorts of wired in constants & nothing (yet)
+ * to print SMT packets as anything other than hex dumps.
+ * Most of the necessary changes are waiting on my redoing
+ * the "header" that a kernel fddi driver supplies to bpf: I
+ * want it to look like one byte of 'direction' (0 or 1
+ * depending on whether the packet was inbound or outbound),
+ * two bytes of system/driver dependent data (anything an
+ * implementor thinks would be useful to filter on and/or
+ * save per-packet, then the real 21-byte FDDI header.
+ * Steve McCanne & I have also talked about adding the
+ * 'direction' byte to all bpf headers (e.g., in the two
+ * bytes of padding on an ethernet header). It's not clear
+ * we could do this in a backwards compatible way & we hate
+ * the idea of an incompatible bpf change. Discussions are
+ * proceeding.
+ *
+ * Also, to really support FDDI (and better support 802.2
+ * over ethernet) we really need to re-think the rather simple
+ * minded assumptions about fixed length & fixed format link
+ * level headers made in gencode.c. One day...
+ *
+ * - vj
+ */
+
+static u_char fddi_bit_swap[] = {
+ 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
+ 0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
+ 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
+ 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
+ 0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
+ 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
+ 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
+ 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
+ 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
+ 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
+ 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
+ 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
+ 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
+ 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
+ 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
+ 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
+ 0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
+ 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
+ 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
+ 0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
+ 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
+ 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
+ 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
+ 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
+ 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
+ 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
+ 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
+ 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
+ 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
+ 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
+ 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
+ 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
+};
+
+/*
+ * Print FDDI frame-control bits
+ */
+static inline void
+print_fddi_fc(u_char fc)
+{
+ switch (fc) {
+
+ case FDDIFC_VOID: /* Void frame */
+ printf("void ");
+ break;
+
+ case FDDIFC_NRT: /* Nonrestricted token */
+ printf("nrt ");
+ break;
+
+ case FDDIFC_RT: /* Restricted token */
+ printf("rt ");
+ break;
+
+ case FDDIFC_SMT_INFO: /* SMT Info */
+ printf("info ");
+ break;
+
+ case FDDIFC_SMT_NSA: /* SMT Next station adrs */
+ printf("nsa ");
+ break;
+
+ case FDDIFC_MAC_BEACON: /* MAC Beacon frame */
+ printf("beacon ");
+ break;
+
+ case FDDIFC_MAC_CLAIM: /* MAC Claim frame */
+ printf("claim ");
+ break;
+
+ default:
+ switch (fc & FDDIFC_CLFF) {
+
+ case FDDIFC_MAC:
+ printf("mac%1x ", fc & FDDIFC_ZZZZ);
+ break;
+
+ case FDDIFC_SMT:
+ printf("smt%1x ", fc & FDDIFC_ZZZZ);
+ break;
+
+ case FDDIFC_LLC_ASYNC:
+ printf("async%1x ", fc & FDDIFC_ZZZZ);
+ break;
+
+ case FDDIFC_LLC_SYNC:
+ printf("sync%1x ", fc & FDDIFC_ZZZZ);
+ break;
+
+ case FDDIFC_IMP_ASYNC:
+ printf("imp_async%1x ", fc & FDDIFC_ZZZZ);
+ break;
+
+ case FDDIFC_IMP_SYNC:
+ printf("imp_sync%1x ", fc & FDDIFC_ZZZZ);
+ break;
+
+ default:
+ printf("%02x ", fc);
+ break;
+ }
+ }
+}
+
+/* Extract src, dst addresses */
+static inline void
+extract_fddi_addrs(const struct fddi_header *fddip, char *fsrc, char *fdst)
+{
+ register int i;
+
+ if (fddi_bitswap) {
+ /*
+ * bit-swap the fddi addresses (isn't the IEEE standards
+ * process wonderful!) then convert them to names.
+ */
+ for (i = 0; i < 6; ++i)
+ fdst[i] = fddi_bit_swap[fddip->fddi_dhost[i]];
+ for (i = 0; i < 6; ++i)
+ fsrc[i] = fddi_bit_swap[fddip->fddi_shost[i]];
+ }
+ else {
+ memcpy(fdst, (const char *)fddip->fddi_dhost, 6);
+ memcpy(fsrc, (const char *)fddip->fddi_shost, 6);
+ }
+}
+
+/*
+ * Print the FDDI MAC header
+ */
+static inline void
+fddi_hdr_print(register const struct fddi_header *fddip, register u_int length,
+ register const u_char *fsrc, register const u_char *fdst)
+{
+ const char *srcname, *dstname;
+
+ srcname = etheraddr_string(fsrc);
+ dstname = etheraddr_string(fdst);
+
+ if (vflag)
+ (void) printf("%02x %s %s %d: ",
+ fddip->fddi_fc,
+ srcname, dstname,
+ length);
+ else if (qflag)
+ printf("%s %s %d: ", srcname, dstname, length);
+ else {
+ (void) print_fddi_fc(fddip->fddi_fc);
+ (void) printf("%s %s %d: ", srcname, dstname, length);
+ }
+}
+
+static inline void
+fddi_smt_print(const u_char *p _U_, u_int length _U_)
+{
+ printf("<SMT printer not yet implemented>");
+}
+
+void
+fddi_print(const u_char *p, u_int length, u_int caplen)
+{
+ const struct fddi_header *fddip = (const struct fddi_header *)p;
+ struct ether_header ehdr;
+ u_short extracted_ethertype;
+
+ if (caplen < FDDI_HDRLEN) {
+ printf("[|fddi]");
+ return;
+ }
+
+ /*
+ * Get the FDDI addresses into a canonical form
+ */
+ extract_fddi_addrs(fddip, (char *)ESRC(&ehdr), (char *)EDST(&ehdr));
+
+ if (eflag)
+ fddi_hdr_print(fddip, length, ESRC(&ehdr), EDST(&ehdr));
+
+ /* Skip over FDDI MAC header */
+ length -= FDDI_HDRLEN;
+ p += FDDI_HDRLEN;
+ caplen -= FDDI_HDRLEN;
+
+ /* Frame Control field determines interpretation of packet */
+ if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_LLC_ASYNC) {
+ /* Try to print the LLC-layer header & higher layers */
+ if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr),
+ &extracted_ethertype) == 0) {
+ /*
+ * Some kinds of LLC packet we cannot
+ * handle intelligently
+ */
+ if (!eflag)
+ fddi_hdr_print(fddip, length + FDDI_HDRLEN,
+ ESRC(&ehdr), EDST(&ehdr));
+ if (extracted_ethertype) {
+ printf("(LLC %s) ",
+ etherproto_string(htons(extracted_ethertype)));
+ }
+ if (!suppress_default_print)
+ default_print(p, caplen);
+ }
+ } else if ((fddip->fddi_fc & FDDIFC_CLFF) == FDDIFC_SMT)
+ fddi_smt_print(p, caplen);
+ else {
+ /* Some kinds of FDDI packet we cannot handle intelligently */
+ if (!eflag)
+ fddi_hdr_print(fddip, length + FDDI_HDRLEN, ESRC(&ehdr),
+ EDST(&ehdr));
+ if (!suppress_default_print)
+ default_print(p, caplen);
+ }
+}
+
+/*
+ * This is the top level routine of the printer. 'p' points
+ * to the FDDI header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ */
+u_int
+fddi_if_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ fddi_print(p, h->len, h->caplen);
+
+ return (FDDI_HDRLEN);
+}
diff --git a/freebsd/contrib/tcpdump/print-forces.c b/freebsd/contrib/tcpdump/print-forces.c
new file mode 100644
index 00000000..4b9f52dd
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-forces.c
@@ -0,0 +1,1057 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Copyright (c) 2009 Mojatatu Networks, Inc
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "interface.h"
+#include "extract.h"
+
+#include "forces.h"
+
+#define RESLEN 4
+
+int
+prestlv_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk _U_, int indent)
+{
+ const struct forces_tlv *tlv = (struct forces_tlv *)pptr;
+ register const u_char *tdp = (u_char *) TLV_DATA(tlv);
+ struct res_val *r = (struct res_val *)tdp;
+ u_int dlen;
+
+ /*
+ * pdatacnt_print() has ensured that len (the TLV length)
+ * >= TLV_HDRL.
+ */
+ dlen = len - TLV_HDRL;
+ if (dlen != RESLEN) {
+ printf("illegal RESULT-TLV: %d bytes!\n", dlen);
+ return -1;
+ }
+
+ TCHECK(*r);
+ if (r->result >= 0x18 && r->result <= 0xFE) {
+ printf("illegal reserved result code: 0x%x!\n", r->result);
+ return -1;
+ }
+
+ if (vflag >= 3) {
+ char *ib = indent_pr(indent, 0);
+ printf("%s Result: %s (code 0x%x)\n", ib,
+ tok2str(ForCES_errs, NULL, r->result), r->result);
+ }
+ return 0;
+
+trunc:
+ fputs("[|forces]", stdout);
+ return -1;
+}
+
+int
+fdatatlv_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk _U_, int indent)
+{
+ const struct forces_tlv *tlv = (struct forces_tlv *)pptr;
+ u_int rlen;
+ register const u_char *tdp = (u_char *) TLV_DATA(tlv);
+ u_int16_t type;
+
+ /*
+ * pdatacnt_print() or pkeyitlv_print() has ensured that len
+ * (the TLV length) >= TLV_HDRL.
+ */
+ rlen = len - TLV_HDRL;
+ TCHECK(*tlv);
+ type = EXTRACT_16BITS(&tlv->type);
+ if (type != F_TLV_FULD) {
+ printf("Error: expecting FULLDATA!\n");
+ return -1;
+ }
+
+ if (vflag >= 3) {
+ char *ib = indent_pr(indent + 2, 1);
+ printf("%s[", &ib[1]);
+ hex_print_with_offset(ib, tdp, rlen, 0);
+ printf("\n%s]\n", &ib[1]);
+ }
+ return 0;
+
+trunc:
+ fputs("[|forces]", stdout);
+ return -1;
+}
+
+int
+sdatailv_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk _U_, int indent)
+{
+ u_int rlen;
+ const struct forces_ilv *ilv = (struct forces_ilv *)pptr;
+ int invilv;
+
+ if (len < ILV_HDRL) {
+ printf("Error: BAD SPARSEDATA-TLV!\n");
+ return -1;
+ }
+ rlen = len;
+ indent += 1;
+ while (rlen != 0) {
+ char *ib = indent_pr(indent, 1);
+ register const u_char *tdp = (u_char *) ILV_DATA(ilv);
+ TCHECK(*ilv);
+ invilv = ilv_valid(ilv, rlen);
+ if (invilv) {
+ printf("%s[", &ib[1]);
+ hex_print_with_offset(ib, tdp, rlen, 0);
+ printf("\n%s]\n", &ib[1]);
+ return -1;
+ }
+ if (vflag >= 3) {
+ int ilvl = EXTRACT_32BITS(&ilv->length);
+ printf("\n%s ILV: type %x length %d\n", &ib[1],
+ EXTRACT_32BITS(&ilv->type), ilvl);
+ hex_print_with_offset("\t\t[", tdp, ilvl-ILV_HDRL, 0);
+ }
+
+ ilv = GO_NXT_ILV(ilv, rlen);
+ }
+
+ return 0;
+
+trunc:
+ fputs("[|forces]", stdout);
+ return -1;
+}
+
+int
+sdatatlv_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent)
+{
+ const struct forces_tlv *tlv = (struct forces_tlv *)pptr;
+ u_int rlen;
+ register const u_char *tdp = (u_char *) TLV_DATA(tlv);
+ u_int16_t type;
+
+ /*
+ * pdatacnt_print() has ensured that len (the TLV length)
+ * >= TLV_HDRL.
+ */
+ rlen = len - TLV_HDRL;
+ TCHECK(*tlv);
+ type = EXTRACT_16BITS(&tlv->type);
+ if (type != F_TLV_SPAD) {
+ printf("Error: expecting SPARSEDATA!\n");
+ return -1;
+ }
+
+ return sdatailv_print(tdp, rlen, op_msk, indent);
+
+trunc:
+ fputs("[|forces]", stdout);
+ return -1;
+}
+
+int
+pkeyitlv_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent)
+{
+ const struct forces_tlv *tlv = (struct forces_tlv *)pptr;
+ register const u_char *tdp = (u_char *) TLV_DATA(tlv);
+ register const u_char *dp = tdp + 4;
+ const struct forces_tlv *kdtlv = (struct forces_tlv *)dp;
+ u_int32_t id;
+ char *ib = indent_pr(indent, 0);
+ u_int16_t type, tll;
+ int invtlv;
+
+ TCHECK(*tdp);
+ id = EXTRACT_32BITS(tdp);
+ printf("%sKeyinfo: Key 0x%x\n", ib, id);
+ TCHECK(*kdtlv);
+ type = EXTRACT_16BITS(&kdtlv->type);
+ invtlv = tlv_valid(kdtlv, len);
+
+ if (invtlv) {
+ printf("%s TLV type 0x%x len %d\n",
+ tok2str(ForCES_TLV_err, NULL, invtlv), type,
+ EXTRACT_16BITS(&kdtlv->length));
+ return -1;
+ }
+ /*
+ * At this point, tlv_valid() has ensured that the TLV
+ * length is large enough but not too large (it doesn't
+ * go past the end of the containing TLV).
+ */
+ tll = EXTRACT_16BITS(&kdtlv->length);
+ dp = (u_char *) TLV_DATA(kdtlv);
+ return fdatatlv_print(dp, tll, op_msk, indent);
+
+trunc:
+ fputs("[|forces]", stdout);
+ return -1;
+}
+
+int
+pdatacnt_print(register const u_char * pptr, register u_int len,
+ u_int16_t IDcnt, u_int16_t op_msk, int indent)
+{
+ u_int i;
+ u_int32_t id;
+ char *ib = indent_pr(indent, 0);
+
+ for (i = 0; i < IDcnt; i++) {
+ TCHECK2(*pptr, 4);
+ if (len < 4)
+ goto trunc;
+ id = EXTRACT_32BITS(pptr);
+ if (vflag >= 3)
+ printf("%s ID#%02u: %d\n", ib, i + 1, id);
+ len -= 4;
+ pptr += 4;
+ }
+ if (len) {
+ const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr;
+ u_int16_t type;
+ u_int16_t tll;
+ int pad = 0;
+ u_int aln;
+ int invtlv;
+
+ TCHECK(*pdtlv);
+ type = EXTRACT_16BITS(&pdtlv->type);
+ invtlv = tlv_valid(pdtlv, len);
+ if (invtlv) {
+ printf
+ ("%s Outstanding bytes %d for TLV type 0x%x TLV len %d\n",
+ tok2str(ForCES_TLV_err, NULL, invtlv), len, type,
+ EXTRACT_16BITS(&pdtlv->length));
+ goto pd_err;
+ }
+ /*
+ * At this point, tlv_valid() has ensured that the TLV
+ * length is large enough but not too large (it doesn't
+ * go past the end of the containing TLV).
+ */
+ tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL;
+ aln = F_ALN_LEN(EXTRACT_16BITS(&pdtlv->length));
+ if (aln > EXTRACT_16BITS(&pdtlv->length)) {
+ if (aln > len) {
+ printf
+ ("Invalid padded pathdata TLV type 0x%x len %d missing %d pad bytes\n",
+ type, EXTRACT_16BITS(&pdtlv->length), aln - len);
+ } else {
+ pad = aln - EXTRACT_16BITS(&pdtlv->length);
+ }
+ }
+ if (pd_valid(type)) {
+ const struct pdata_ops *ops = get_forces_pd(type);
+
+ if (vflag >= 3 && ops->v != F_TLV_PDAT) {
+ if (pad)
+ printf
+ ("%s %s (Length %d DataLen %d pad %d Bytes)\n",
+ ib, ops->s, EXTRACT_16BITS(&pdtlv->length),
+ tll, pad);
+ else
+ printf
+ ("%s %s (Length %d DataLen %d Bytes)\n",
+ ib, ops->s, EXTRACT_16BITS(&pdtlv->length),
+ tll);
+ }
+
+ chk_op_type(type, op_msk, ops->op_msk);
+
+ if (ops->print((const u_char *)pdtlv,
+ tll + pad + TLV_HDRL, op_msk,
+ indent + 2) == -1)
+ return -1;
+ len -= (TLV_HDRL + pad + tll);
+ } else {
+ printf("Invalid path data content type 0x%x len %d\n",
+ type, EXTRACT_16BITS(&pdtlv->length));
+pd_err:
+ if (EXTRACT_16BITS(&pdtlv->length)) {
+ hex_print_with_offset("Bad Data val\n\t [",
+ pptr, len, 0);
+ printf("]\n");
+
+ return -1;
+ }
+ }
+ }
+ return len;
+
+trunc:
+ fputs("[|forces]", stdout);
+ return -1;
+}
+
+int
+pdata_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent)
+{
+ const struct pathdata_h *pdh = (struct pathdata_h *)pptr;
+ char *ib = indent_pr(indent, 0);
+ u_int minsize = 0;
+ int more_pd = 0;
+ u_int16_t idcnt = 0;
+
+ TCHECK(*pdh);
+ if (len < sizeof(struct pathdata_h))
+ goto trunc;
+ if (vflag >= 3) {
+ printf("\n%sPathdata: Flags 0x%x ID count %d\n",
+ ib, EXTRACT_16BITS(&pdh->pflags), EXTRACT_16BITS(&pdh->pIDcnt));
+ }
+
+ if (EXTRACT_16BITS(&pdh->pflags) & F_SELKEY) {
+ op_msk |= B_KEYIN;
+ }
+ pptr += sizeof(struct pathdata_h);
+ len -= sizeof(struct pathdata_h);
+ idcnt = EXTRACT_16BITS(&pdh->pIDcnt);
+ minsize = idcnt * 4;
+ if (len < minsize) {
+ printf("\t\t\ttruncated IDs expected %uB got %uB\n", minsize,
+ len);
+ hex_print_with_offset("\t\t\tID Data[", pptr, len, 0);
+ printf("]\n");
+ return -1;
+ }
+ more_pd = pdatacnt_print(pptr, len, idcnt, op_msk, indent);
+ if (more_pd > 0) {
+ int consumed = len - more_pd;
+ pptr += consumed;
+ len = more_pd;
+ /* XXX: Argh, recurse some more */
+ return recpdoptlv_print(pptr, len, op_msk, indent+1);
+ } else
+ return 0;
+
+trunc:
+ fputs("[|forces]", stdout);
+ return -1;
+}
+
+int
+genoptlv_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent)
+{
+ const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr;
+ u_int16_t type;
+ int tll;
+ int invtlv;
+ char *ib = indent_pr(indent, 0);
+
+ TCHECK(*pdtlv);
+ type = EXTRACT_16BITS(&pdtlv->type);
+ tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL;
+ invtlv = tlv_valid(pdtlv, len);
+ printf("genoptlvprint - %s TLV type 0x%x len %d\n",
+ tok2str(ForCES_TLV, NULL, type), type, EXTRACT_16BITS(&pdtlv->length));
+ if (!invtlv) {
+ /*
+ * At this point, tlv_valid() has ensured that the TLV
+ * length is large enough but not too large (it doesn't
+ * go past the end of the containing TLV).
+ */
+ register const u_char *dp = (u_char *) TLV_DATA(pdtlv);
+ if (!ttlv_valid(type)) {
+ printf("%s TLV type 0x%x len %d\n",
+ tok2str(ForCES_TLV_err, NULL, invtlv), type,
+ EXTRACT_16BITS(&pdtlv->length));
+ return -1;
+ }
+ if (vflag >= 3)
+ printf("%s%s, length %d (data length %d Bytes)",
+ ib, tok2str(ForCES_TLV, NULL, type),
+ EXTRACT_16BITS(&pdtlv->length), tll);
+
+ return pdata_print(dp, tll, op_msk, indent + 1);
+ } else {
+ printf("\t\t\tInvalid ForCES TLV type=%x", type);
+ return -1;
+ }
+
+trunc:
+ fputs("[|forces]", stdout);
+ return -1;
+}
+
+int
+recpdoptlv_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent)
+{
+ const struct forces_tlv *pdtlv = (struct forces_tlv *)pptr;
+ int tll;
+ int invtlv;
+ u_int16_t type;
+ register const u_char *dp;
+ char *ib;
+
+ while (len != 0) {
+ TCHECK(*pdtlv);
+ invtlv = tlv_valid(pdtlv, len);
+ if (invtlv) {
+ break;
+ }
+
+ /*
+ * At this point, tlv_valid() has ensured that the TLV
+ * length is large enough but not too large (it doesn't
+ * go past the end of the containing TLV).
+ */
+ ib = indent_pr(indent, 0);
+ type = EXTRACT_16BITS(&pdtlv->type);
+ dp = (u_char *) TLV_DATA(pdtlv);
+ tll = EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL;
+
+ if (vflag >= 3)
+ printf
+ ("%s%s, length %d (data encapsulated %d Bytes)",
+ ib, tok2str(ForCES_TLV, NULL, type),
+ EXTRACT_16BITS(&pdtlv->length),
+ EXTRACT_16BITS(&pdtlv->length) - TLV_HDRL);
+
+ if (pdata_print(dp, tll, op_msk, indent + 1) == -1)
+ return -1;
+ pdtlv = GO_NXT_TLV(pdtlv, len);
+ }
+
+ if (len) {
+ printf
+ ("\n\t\tMessy PATHDATA TLV header, type (0x%x)\n\t\texcess of %d Bytes ",
+ EXTRACT_16BITS(&pdtlv->type), len - EXTRACT_16BITS(&pdtlv->length));
+ return -1;
+ }
+
+ return 0;
+
+trunc:
+ fputs("[|forces]", stdout);
+ return -1;
+}
+
+int
+invoptlv_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk _U_, int indent)
+{
+ char *ib = indent_pr(indent, 1);
+
+ if (vflag >= 3) {
+ printf("%sData[", &ib[1]);
+ hex_print_with_offset(ib, pptr, len, 0);
+ printf("%s]\n", ib);
+ }
+ return -1;
+}
+
+int otlv_print(const struct forces_tlv *otlv, u_int16_t op_msk _U_, int indent)
+{
+ int rc = 0;
+ register const u_char *dp = (u_char *) TLV_DATA(otlv);
+ u_int16_t type;
+ int tll;
+ char *ib = indent_pr(indent, 0);
+ const struct optlv_h *ops;
+
+ /*
+ * lfbselect_print() has ensured that EXTRACT_16BITS(&otlv->length)
+ * >= TLV_HDRL.
+ */
+ TCHECK(*otlv);
+ type = EXTRACT_16BITS(&otlv->type);
+ tll = EXTRACT_16BITS(&otlv->length) - TLV_HDRL;
+ ops = get_forces_optlv_h(type);
+ if (vflag >= 3) {
+ printf("%sOper TLV %s(0x%x) length %d\n", ib, ops->s, type,
+ EXTRACT_16BITS(&otlv->length));
+ }
+ /* empty TLVs like COMMIT and TRCOMMIT are empty, we stop here .. */
+ if (!ops->flags & ZERO_TTLV) {
+ if (tll != 0) /* instead of "if (tll)" - for readability .. */
+ printf("%s: Illegal - MUST be empty\n", ops->s);
+ return rc;
+ }
+ /* rest of ops must at least have 12B {pathinfo} */
+ if (tll < OP_MIN_SIZ) {
+ printf("\t\tOper TLV %s(0x%x) length %d\n", ops->s, type,
+ EXTRACT_16BITS(&otlv->length));
+ printf("\t\tTruncated data size %d minimum required %d\n", tll,
+ OP_MIN_SIZ);
+ return invoptlv_print(dp, tll, ops->op_msk, indent);
+
+ }
+
+ rc = ops->print(dp, tll, ops->op_msk, indent + 1);
+ return rc;
+
+trunc:
+ fputs("[|forces]", stdout);
+ return -1;
+}
+
+#define ASTDLN 4
+#define ASTMCD 255
+int
+asttlv_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk _U_, int indent)
+{
+ u_int32_t rescode;
+ u_int dlen;
+ char *ib = indent_pr(indent, 0);
+
+ /*
+ * forces_type_print() has ensured that len (the TLV length)
+ * >= TLV_HDRL.
+ */
+ dlen = len - TLV_HDRL;
+ if (dlen != ASTDLN) {
+ printf("illegal ASTresult-TLV: %d bytes!\n", dlen);
+ return -1;
+ }
+ TCHECK2(*pptr, 4);
+ rescode = EXTRACT_32BITS(pptr);
+ if (rescode > ASTMCD) {
+ printf("illegal ASTresult result code: %d!\n", rescode);
+ return -1;
+ }
+
+ if (vflag >= 3) {
+ printf("Teardown reason:\n%s", ib);
+ switch (rescode) {
+ case 0:
+ printf("Normal Teardown");
+ break;
+ case 1:
+ printf("Loss of Heartbeats");
+ break;
+ case 2:
+ printf("Out of bandwidth");
+ break;
+ case 3:
+ printf("Out of Memory");
+ break;
+ case 4:
+ printf("Application Crash");
+ break;
+ default:
+ printf("Unknown Teardown reason");
+ break;
+ }
+ printf("(%x)\n%s", rescode, ib);
+ }
+ return 0;
+
+trunc:
+ fputs("[|forces]", stdout);
+ return -1;
+}
+
+#define ASRDLN 4
+#define ASRMCD 3
+int
+asrtlv_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk _U_, int indent)
+{
+ u_int32_t rescode;
+ u_int dlen;
+ char *ib = indent_pr(indent, 0);
+
+ /*
+ * forces_type_print() has ensured that len (the TLV length)
+ * >= TLV_HDRL.
+ */
+ dlen = len - TLV_HDRL;
+ if (dlen != ASRDLN) { /* id, instance, oper tlv */
+ printf("illegal ASRresult-TLV: %d bytes!\n", dlen);
+ return -1;
+ }
+ TCHECK2(*pptr, 4);
+ rescode = EXTRACT_32BITS(pptr);
+
+ if (rescode > ASRMCD) {
+ printf("illegal ASRresult result code: %d!\n", rescode);
+ return -1;
+ }
+
+ if (vflag >= 3) {
+ printf("\n%s", ib);
+ switch (rescode) {
+ case 0:
+ printf("Success ");
+ break;
+ case 1:
+ printf("FE ID invalid ");
+ break;
+ case 2:
+ printf("permission denied ");
+ break;
+ default:
+ printf("Unknown ");
+ break;
+ }
+ printf("(%x)\n%s", rescode, ib);
+ }
+ return 0;
+
+trunc:
+ fputs("[|forces]", stdout);
+ return -1;
+}
+
+/*
+ * XXX - not used.
+ */
+int
+gentltlv_print(register const u_char * pptr _U_, register u_int len,
+ u_int16_t op_msk _U_, int indent _U_)
+{
+ u_int dlen = len - TLV_HDRL;
+
+ if (dlen < 4) { /* at least 32 bits must exist */
+ printf("truncated TLV: %d bytes missing! ", 4 - dlen);
+ return -1;
+ }
+ return 0;
+}
+
+#define RD_MIN 8
+int
+print_metailv(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk _U_, int indent)
+{
+ u_int dlen;
+ u_int rlen;
+ char *ib = indent_pr(indent, 0);
+ /* XXX: check header length */
+ const struct forces_ilv *ilv = (struct forces_ilv *)pptr;
+
+ /*
+ * print_metatlv() has ensured that len (what remains in the
+ * ILV) >= ILV_HDRL.
+ */
+ dlen = len - ILV_HDRL;
+ rlen = dlen;
+ TCHECK(*ilv);
+ printf("\n%sMetaID 0x%x length %d\n", ib, EXTRACT_32BITS(&ilv->type),
+ EXTRACT_32BITS(&ilv->length));
+ hex_print_with_offset("\n\t\t\t\t[", ILV_DATA(ilv), rlen, 0);
+ return 0;
+
+trunc:
+ fputs("[|forces]", stdout);
+ return -1;
+}
+
+int
+print_metatlv(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk _U_, int indent)
+{
+ u_int dlen;
+ char *ib = indent_pr(indent, 0);
+ u_int rlen;
+ const struct forces_ilv *ilv = (struct forces_ilv *)pptr;
+ int invilv;
+
+ /*
+ * redirect_print() has ensured that len (what remains in the
+ * TLV) >= TLV_HDRL.
+ */
+ dlen = len - TLV_HDRL;
+ rlen = dlen;
+ printf("\n%s METADATA\n", ib);
+ while (rlen != 0) {
+ TCHECK(*ilv);
+ invilv = ilv_valid(ilv, rlen);
+ if (invilv)
+ break;
+
+ /*
+ * At this point, ilv_valid() has ensured that the ILV
+ * length is large enough but not too large (it doesn't
+ * go past the end of the containing TLV).
+ */
+ print_metailv((u_char *) ilv, rlen, 0, indent + 1);
+
+ ilv = GO_NXT_ILV(ilv, rlen);
+ }
+
+ return 0;
+
+trunc:
+ fputs("[|forces]", stdout);
+ return -1;
+}
+
+/*
+*/
+int
+print_reddata(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk _U_, int indent _U_)
+{
+ u_int dlen;
+ u_int rlen;
+ int invtlv;
+ const struct forces_tlv *tlv = (struct forces_tlv *)pptr;
+
+ /*
+ * redirect_print() has ensured that len (what remains in the
+ * TLV) >= TLV_HDRL.
+ */
+ dlen = len - TLV_HDRL;
+ printf("\n\t\t Redirect DATA\n");
+ if (dlen <= RD_MIN) {
+ printf("\n\t\ttruncated Redirect data: %d bytes missing! ",
+ RD_MIN - dlen);
+ return -1;
+ }
+
+ rlen = dlen;
+ TCHECK(*tlv);
+ invtlv = tlv_valid(tlv, rlen);
+
+ if (invtlv) {
+ printf("Redir data type 0x%x len %d\n", EXTRACT_16BITS(&tlv->type),
+ EXTRACT_16BITS(&tlv->length));
+ return -1;
+ }
+
+ /*
+ * At this point, tlv_valid() has ensured that the TLV
+ * length is large enough but not too large (it doesn't
+ * go past the end of the containing TLV).
+ */
+ rlen -= TLV_HDRL;
+ hex_print_with_offset("\n\t\t\t[", TLV_DATA(tlv), rlen, 0);
+ return 0;
+
+trunc:
+ fputs("[|forces]", stdout);
+ return -1;
+}
+
+int
+redirect_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk _U_, int indent)
+{
+ const struct forces_tlv *tlv = (struct forces_tlv *)pptr;
+ u_int dlen;
+ u_int rlen;
+ int invtlv;
+
+ /*
+ * forces_type_print() has ensured that len (the TLV length)
+ * >= TLV_HDRL.
+ */
+ dlen = len - TLV_HDRL;
+ if (dlen <= RD_MIN) {
+ printf("\n\t\ttruncated Redirect TLV: %d bytes missing! ",
+ RD_MIN - dlen);
+ return -1;
+ }
+
+ rlen = dlen;
+ indent += 1;
+ while (rlen != 0) {
+ TCHECK(*tlv);
+ invtlv = tlv_valid(tlv, rlen);
+ if (invtlv)
+ break;
+
+ /*
+ * At this point, tlv_valid() has ensured that the TLV
+ * length is large enough but not too large (it doesn't
+ * go past the end of the containing TLV).
+ */
+ if (EXTRACT_16BITS(&tlv->type) == F_TLV_METD) {
+ print_metatlv((u_char *) TLV_DATA(tlv), rlen, 0, indent);
+ } else if ((EXTRACT_16BITS(&tlv->type) == F_TLV_REDD)) {
+ print_reddata((u_char *) TLV_DATA(tlv), rlen, 0, indent);
+ } else {
+ printf("Unknown REDIRECT TLV 0x%x len %d\n",
+ EXTRACT_16BITS(&tlv->type), EXTRACT_16BITS(&tlv->length));
+ }
+
+ tlv = GO_NXT_TLV(tlv, rlen);
+ }
+
+ if (rlen) {
+ printf
+ ("\n\t\tMessy Redirect TLV header, type (0x%x)\n\t\texcess of %d Bytes ",
+ EXTRACT_16BITS(&tlv->type), rlen - EXTRACT_16BITS(&tlv->length));
+ return -1;
+ }
+
+ return 0;
+
+trunc:
+ fputs("[|forces]", stdout);
+ return -1;
+}
+
+#define OP_OFF 8
+#define OP_MIN 12
+
+int
+lfbselect_print(register const u_char * pptr, register u_int len,
+ u_int16_t op_msk, int indent)
+{
+ const struct forces_lfbsh *lfbs;
+ const struct forces_tlv *otlv;
+ char *ib = indent_pr(indent, 0);
+ u_int dlen;
+ u_int rlen;
+ int invtlv;
+
+ /*
+ * forces_type_print() has ensured that len (the TLV length)
+ * >= TLV_HDRL.
+ */
+ dlen = len - TLV_HDRL;
+ if (dlen <= OP_MIN) { /* id, instance, oper tlv header .. */
+ printf("\n\t\ttruncated lfb selector: %d bytes missing! ",
+ OP_MIN - dlen);
+ return -1;
+ }
+
+ /*
+ * At this point, we know that dlen > OP_MIN; OP_OFF < OP_MIN, so
+ * we also know that it's > OP_OFF.
+ */
+ rlen = dlen - OP_OFF;
+
+ lfbs = (const struct forces_lfbsh *)pptr;
+ TCHECK(*lfbs);
+ if (vflag >= 3) {
+ printf("\n%s%s(Classid %x) instance %x\n",
+ ib, tok2str(ForCES_LFBs, NULL, EXTRACT_32BITS(&lfbs->class)),
+ EXTRACT_32BITS(&lfbs->class),
+ EXTRACT_32BITS(&lfbs->instance));
+ }
+
+ otlv = (struct forces_tlv *)(lfbs + 1);
+
+ indent += 1;
+ while (rlen != 0) {
+ TCHECK(*otlv);
+ invtlv = tlv_valid(otlv, rlen);
+ if (invtlv)
+ break;
+
+ /*
+ * At this point, tlv_valid() has ensured that the TLV
+ * length is large enough but not too large (it doesn't
+ * go past the end of the containing TLV).
+ */
+ if (op_valid(EXTRACT_16BITS(&otlv->type), op_msk)) {
+ otlv_print(otlv, 0, indent);
+ } else {
+ if (vflag < 3)
+ printf("\n");
+ printf
+ ("\t\tINValid oper-TLV type 0x%x length %d for this ForCES message\n",
+ EXTRACT_16BITS(&otlv->type), EXTRACT_16BITS(&otlv->length));
+ invoptlv_print((u_char *)otlv, rlen, 0, indent);
+ }
+ otlv = GO_NXT_TLV(otlv, rlen);
+ }
+
+ if (rlen) {
+ printf
+ ("\n\t\tMessy oper TLV header, type (0x%x)\n\t\texcess of %d Bytes ",
+ EXTRACT_16BITS(&otlv->type), rlen - EXTRACT_16BITS(&otlv->length));
+ return -1;
+ }
+
+ return 0;
+
+trunc:
+ fputs("[|forces]", stdout);
+ return -1;
+}
+
+int
+forces_type_print(register const u_char * pptr, const struct forcesh *fhdr _U_,
+ register u_int mlen, const struct tom_h *tops)
+{
+ const struct forces_tlv *tltlv;
+ u_int rlen;
+ int invtlv;
+ int rc = 0;
+ int ttlv = 0;
+
+ /*
+ * forces_print() has already checked that mlen >= ForCES_HDRL
+ * by calling ForCES_HLN_VALID().
+ */
+ rlen = mlen - ForCES_HDRL;
+
+ if (rlen > TLV_HLN) {
+ if (tops->flags & ZERO_TTLV) {
+ printf("<0x%x>Illegal Top level TLV!\n", tops->flags);
+ return -1;
+ }
+ } else {
+ if (tops->flags & ZERO_MORE_TTLV)
+ return 0;
+ if (tops->flags & ONE_MORE_TTLV) {
+ printf("\tTop level TLV Data missing!\n");
+ return -1;
+ }
+ }
+
+ if (tops->flags & ZERO_TTLV) {
+ return 0;
+ }
+
+ ttlv = tops->flags >> 4;
+ tltlv = GET_TOP_TLV(pptr);
+
+ /*XXX: 15 top level tlvs will probably be fine
+ You are nuts if you send more ;-> */
+ while (rlen != 0) {
+ TCHECK(*tltlv);
+ invtlv = tlv_valid(tltlv, rlen);
+ if (invtlv)
+ break;
+
+ /*
+ * At this point, tlv_valid() has ensured that the TLV
+ * length is large enough but not too large (it doesn't
+ * go past the end of the packet).
+ */
+ if (!ttlv_valid(EXTRACT_16BITS(&tltlv->type))) {
+ printf("\n\tInvalid ForCES Top TLV type=0x%x",
+ EXTRACT_16BITS(&tltlv->type));
+ return -1;
+ }
+
+ if (vflag >= 3)
+ printf("\t%s, length %d (data length %d Bytes)",
+ tok2str(ForCES_TLV, NULL, EXTRACT_16BITS(&tltlv->type)),
+ EXTRACT_16BITS(&tltlv->length),
+ EXTRACT_16BITS(&tltlv->length) - TLV_HDRL);
+
+ rc = tops->print((u_char *) TLV_DATA(tltlv),
+ EXTRACT_16BITS(&tltlv->length), tops->op_msk, 9);
+ if (rc < 0) {
+ return -1;
+ }
+ tltlv = GO_NXT_TLV(tltlv, rlen);
+ ttlv--;
+ if (ttlv <= 0)
+ break;
+ }
+ /*
+ * XXX - if ttlv != 0, does that mean that the packet was too
+ * short, and didn't have *enough* TLVs in it?
+ */
+ if (rlen) {
+ printf("\tMess TopTLV header: min %u, total %d advertised %d ",
+ TLV_HDRL, rlen, EXTRACT_16BITS(&tltlv->length));
+ return -1;
+ }
+
+ return 0;
+
+trunc:
+ fputs("[|forces]", stdout);
+ return -1;
+}
+
+void forces_print(register const u_char * pptr, register u_int len)
+{
+ const struct forcesh *fhdr;
+ u_int mlen;
+ u_int32_t flg_raw;
+ const struct tom_h *tops;
+ int rc = 0;
+
+ fhdr = (const struct forcesh *)pptr;
+ TCHECK(*fhdr);
+ if (!tom_valid(fhdr->fm_tom)) {
+ printf("Invalid ForCES message type %d\n", fhdr->fm_tom);
+ goto error;
+ }
+
+ mlen = ForCES_BLN(fhdr);
+
+ tops = get_forces_tom(fhdr->fm_tom);
+ if (tops->v == TOM_RSVD) {
+ printf("\n\tUnknown ForCES message type=0x%x", fhdr->fm_tom);
+ goto error;
+ }
+
+ printf("\n\tForCES %s ", tops->s);
+ if (!ForCES_HLN_VALID(mlen, len)) {
+ printf
+ ("Illegal ForCES pkt len - min %u, total recvd %d, advertised %d ",
+ ForCES_HDRL, len, ForCES_BLN(fhdr));
+ goto error;
+ }
+
+ TCHECK2(*(pptr + 20), 4);
+ flg_raw = EXTRACT_32BITS(pptr + 20);
+ if (vflag >= 1) {
+ printf("\n\tForCES Version %d len %uB flags 0x%08x ",
+ ForCES_V(fhdr), mlen, flg_raw);
+ printf("\n\tSrcID 0x%x(%s) DstID 0x%x(%s) Correlator 0x%" PRIx64,
+ ForCES_SID(fhdr), ForCES_node(ForCES_SID(fhdr)),
+ ForCES_DID(fhdr), ForCES_node(ForCES_DID(fhdr)),
+ EXTRACT_64BITS(fhdr->fm_cor));
+
+ }
+ if (vflag >= 2) {
+ printf
+ ("\n\tForCES flags:\n\t %s(0x%x), prio=%d, %s(0x%x),\n\t %s(0x%x), %s(0x%x)\n",
+ ForCES_ACKp(ForCES_ACK(fhdr)), ForCES_ACK(fhdr),
+ ForCES_PRI(fhdr),
+ ForCES_EMp(ForCES_EM(fhdr)), ForCES_EM(fhdr),
+ ForCES_ATp(ForCES_AT(fhdr)), ForCES_AT(fhdr),
+ ForCES_TPp(ForCES_TP(fhdr)), ForCES_TP(fhdr));
+ printf
+ ("\t Extra flags: rsv(b5-7) 0x%x rsv(b13-31) 0x%x\n",
+ ForCES_RS1(fhdr), ForCES_RS2(fhdr));
+ }
+ rc = forces_type_print(pptr, fhdr, mlen, tops);
+ if (rc < 0) {
+error:
+ hex_print_with_offset("\n\t[", pptr, len, 0);
+ printf("\n\t]");
+ return;
+ }
+
+ if (vflag >= 4) {
+ printf("\n\t Raw ForCES message\n\t [");
+ hex_print_with_offset("\n\t ", pptr, len, 0);
+ printf("\n\t ]");
+ }
+ printf("\n");
+ return;
+
+trunc:
+ fputs("[|forces]", stdout);
+}
diff --git a/freebsd/contrib/tcpdump/print-fr.c b/freebsd/contrib/tcpdump/print-fr.c
new file mode 100644
index 00000000..73e056d4
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-fr.c
@@ -0,0 +1,887 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#)$Header: /tcpdump/master/tcpdump/print-fr.c,v 1.51 2006-06-23 22:20:32 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <pcap.h>
+
+#include "addrtoname.h"
+#include "interface.h"
+#include "ethertype.h"
+#include "nlpid.h"
+#include "extract.h"
+#include "oui.h"
+
+static void frf15_print(const u_char *, u_int);
+
+/*
+ * the frame relay header has a variable length
+ *
+ * the EA bit determines if there is another byte
+ * in the header
+ *
+ * minimum header length is 2 bytes
+ * maximum header length is 4 bytes
+ *
+ * 7 6 5 4 3 2 1 0
+ * +----+----+----+----+----+----+----+----+
+ * | DLCI (6 bits) | CR | EA |
+ * +----+----+----+----+----+----+----+----+
+ * | DLCI (4 bits) |FECN|BECN| DE | EA |
+ * +----+----+----+----+----+----+----+----+
+ * | DLCI (7 bits) | EA |
+ * +----+----+----+----+----+----+----+----+
+ * | DLCI (6 bits) |SDLC| EA |
+ * +----+----+----+----+----+----+----+----+
+ */
+
+#define FR_EA_BIT 0x01
+
+#define FR_CR_BIT 0x02000000
+#define FR_DE_BIT 0x00020000
+#define FR_BECN_BIT 0x00040000
+#define FR_FECN_BIT 0x00080000
+#define FR_SDLC_BIT 0x00000002
+
+
+struct tok fr_header_flag_values[] = {
+ { FR_CR_BIT, "C!" },
+ { FR_DE_BIT, "DE" },
+ { FR_BECN_BIT, "BECN" },
+ { FR_FECN_BIT, "FECN" },
+ { FR_SDLC_BIT, "sdlcore" },
+ { 0, NULL }
+};
+
+/* FRF.15 / FRF.16 */
+#define MFR_B_BIT 0x80
+#define MFR_E_BIT 0x40
+#define MFR_C_BIT 0x20
+#define MFR_BEC_MASK (MFR_B_BIT | MFR_E_BIT | MFR_C_BIT)
+#define MFR_CTRL_FRAME (MFR_B_BIT | MFR_E_BIT | MFR_C_BIT)
+#define MFR_FRAG_FRAME (MFR_B_BIT | MFR_E_BIT )
+
+struct tok frf_flag_values[] = {
+ { MFR_B_BIT, "Begin" },
+ { MFR_E_BIT, "End" },
+ { MFR_C_BIT, "Control" },
+ { 0, NULL }
+};
+
+/* Finds out Q.922 address length, DLCI and flags. Returns 0 on success
+ * save the flags dep. on address length
+ */
+static int parse_q922_addr(const u_char *p, u_int *dlci,
+ u_int *addr_len, u_int8_t *flags)
+{
+ if ((p[0] & FR_EA_BIT))
+ return -1;
+
+ *addr_len = 2;
+ *dlci = ((p[0] & 0xFC) << 2) | ((p[1] & 0xF0) >> 4);
+
+ flags[0] = p[0] & 0x02; /* populate the first flag fields */
+ flags[1] = p[1] & 0x0c;
+ flags[2] = 0; /* clear the rest of the flags */
+ flags[3] = 0;
+
+ if (p[1] & FR_EA_BIT)
+ return 0; /* 2-byte Q.922 address */
+
+ p += 2;
+ (*addr_len)++; /* 3- or 4-byte Q.922 address */
+ if ((p[0] & FR_EA_BIT) == 0) {
+ *dlci = (*dlci << 7) | (p[0] >> 1);
+ (*addr_len)++; /* 4-byte Q.922 address */
+ p++;
+ }
+
+ if ((p[0] & FR_EA_BIT) == 0)
+ return -1; /* more than 4 bytes of Q.922 address? */
+
+ flags[3] = p[0] & 0x02;
+
+ *dlci = (*dlci << 6) | (p[0] >> 2);
+
+ return 0;
+}
+
+char *q922_string(const u_char *p) {
+
+ static u_int dlci, addr_len;
+ static u_int8_t flags[4];
+ static char buffer[sizeof("DLCI xxxxxxxxxx")];
+ memset(buffer, 0, sizeof(buffer));
+
+ if (parse_q922_addr(p, &dlci, &addr_len, flags) == 0){
+ snprintf(buffer, sizeof(buffer), "DLCI %u", dlci);
+ }
+
+ return buffer;
+}
+
+
+/* Frame Relay packet structure, with flags and CRC removed
+
+ +---------------------------+
+ | Q.922 Address* |
+ +-- --+
+ | |
+ +---------------------------+
+ | Control (UI = 0x03) |
+ +---------------------------+
+ | Optional Pad (0x00) |
+ +---------------------------+
+ | NLPID |
+ +---------------------------+
+ | . |
+ | . |
+ | . |
+ | Data |
+ | . |
+ | . |
+ +---------------------------+
+
+ * Q.922 addresses, as presently defined, are two octets and
+ contain a 10-bit DLCI. In some networks Q.922 addresses
+ may optionally be increased to three or four octets.
+*/
+
+static u_int
+fr_hdrlen(const u_char *p, u_int addr_len)
+{
+ if (!p[addr_len + 1] /* pad exist */)
+ return addr_len + 1 /* UI */ + 1 /* pad */ + 1 /* NLPID */;
+ else
+ return addr_len + 1 /* UI */ + 1 /* NLPID */;
+}
+
+static void
+fr_hdr_print(int length, u_int addr_len, u_int dlci, u_int8_t *flags, u_int16_t nlpid)
+{
+ if (qflag) {
+ (void)printf("Q.922, DLCI %u, length %u: ",
+ dlci,
+ length);
+ } else {
+ if (nlpid <= 0xff) /* if its smaller than 256 then its a NLPID */
+ (void)printf("Q.922, hdr-len %u, DLCI %u, Flags [%s], NLPID %s (0x%02x), length %u: ",
+ addr_len,
+ dlci,
+ bittok2str(fr_header_flag_values, "none", EXTRACT_32BITS(flags)),
+ tok2str(nlpid_values,"unknown", nlpid),
+ nlpid,
+ length);
+ else /* must be an ethertype */
+ (void)printf("Q.922, hdr-len %u, DLCI %u, Flags [%s], cisco-ethertype %s (0x%04x), length %u: ",
+ addr_len,
+ dlci,
+ bittok2str(fr_header_flag_values, "none", EXTRACT_32BITS(flags)),
+ tok2str(ethertype_values, "unknown", nlpid),
+ nlpid,
+ length);
+ }
+}
+
+u_int
+fr_if_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ register u_int length = h->len;
+ register u_int caplen = h->caplen;
+
+ TCHECK2(*p, 4); /* minimum frame header length */
+
+ if ((length = fr_print(p, length)) == 0)
+ return (0);
+ else
+ return length;
+ trunc:
+ printf("[|fr]");
+ return caplen;
+}
+
+u_int
+fr_print(register const u_char *p, u_int length)
+{
+ u_int16_t extracted_ethertype;
+ u_int dlci;
+ u_int addr_len;
+ u_int16_t nlpid;
+ u_int hdr_len;
+ u_int8_t flags[4];
+
+ if (parse_q922_addr(p, &dlci, &addr_len, flags)) {
+ printf("Q.922, invalid address");
+ return 0;
+ }
+
+ TCHECK2(*p,addr_len+1+1);
+ hdr_len = fr_hdrlen(p, addr_len);
+ TCHECK2(*p,hdr_len);
+
+ if (p[addr_len] != 0x03 && dlci != 0) {
+
+ /* lets figure out if we have cisco style encapsulation: */
+ extracted_ethertype = EXTRACT_16BITS(p+addr_len);
+
+ if (eflag)
+ fr_hdr_print(length, addr_len, dlci, flags, extracted_ethertype);
+
+ if (ethertype_print(gndo, extracted_ethertype,
+ p+addr_len+ETHERTYPE_LEN,
+ length-addr_len-ETHERTYPE_LEN,
+ length-addr_len-ETHERTYPE_LEN) == 0)
+ /* ether_type not known, probably it wasn't one */
+ printf("UI %02x! ", p[addr_len]);
+ else
+ return hdr_len;
+ }
+
+ if (!p[addr_len + 1]) { /* pad byte should be used with 3-byte Q.922 */
+ if (addr_len != 3)
+ printf("Pad! ");
+ } else if (addr_len == 3)
+ printf("No pad! ");
+
+ nlpid = p[hdr_len - 1];
+
+ if (eflag)
+ fr_hdr_print(length, addr_len, dlci, flags, nlpid);
+ p += hdr_len;
+ length -= hdr_len;
+
+ switch (nlpid) {
+ case NLPID_IP:
+ ip_print(gndo, p, length);
+ break;
+
+#ifdef INET6
+ case NLPID_IP6:
+ ip6_print(gndo, p, length);
+ break;
+#endif
+ case NLPID_CLNP:
+ case NLPID_ESIS:
+ case NLPID_ISIS:
+ isoclns_print(p-1, length+1, length+1); /* OSI printers need the NLPID field */
+ break;
+
+ case NLPID_SNAP:
+ if (snap_print(p, length, length, 0) == 0) {
+ /* ether_type not known, print raw packet */
+ if (!eflag)
+ fr_hdr_print(length + hdr_len, hdr_len,
+ dlci, flags, nlpid);
+ if (!suppress_default_print)
+ default_print(p - hdr_len, length + hdr_len);
+ }
+ break;
+
+ case NLPID_Q933:
+ q933_print(p, length);
+ break;
+
+ case NLPID_MFR:
+ frf15_print(p, length);
+ break;
+
+ case NLPID_PPP:
+ ppp_print(p, length);
+ break;
+
+ default:
+ if (!eflag)
+ fr_hdr_print(length + hdr_len, addr_len,
+ dlci, flags, nlpid);
+ if (!xflag)
+ default_print(p, length);
+ }
+
+ return hdr_len;
+
+ trunc:
+ printf("[|fr]");
+ return 0;
+
+}
+
+u_int
+mfr_if_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ register u_int length = h->len;
+ register u_int caplen = h->caplen;
+
+ TCHECK2(*p, 2); /* minimum frame header length */
+
+ if ((length = mfr_print(p, length)) == 0)
+ return (0);
+ else
+ return length;
+ trunc:
+ printf("[|mfr]");
+ return caplen;
+}
+
+
+#define MFR_CTRL_MSG_ADD_LINK 1
+#define MFR_CTRL_MSG_ADD_LINK_ACK 2
+#define MFR_CTRL_MSG_ADD_LINK_REJ 3
+#define MFR_CTRL_MSG_HELLO 4
+#define MFR_CTRL_MSG_HELLO_ACK 5
+#define MFR_CTRL_MSG_REMOVE_LINK 6
+#define MFR_CTRL_MSG_REMOVE_LINK_ACK 7
+
+struct tok mfr_ctrl_msg_values[] = {
+ { MFR_CTRL_MSG_ADD_LINK, "Add Link" },
+ { MFR_CTRL_MSG_ADD_LINK_ACK, "Add Link ACK" },
+ { MFR_CTRL_MSG_ADD_LINK_REJ, "Add Link Reject" },
+ { MFR_CTRL_MSG_HELLO, "Hello" },
+ { MFR_CTRL_MSG_HELLO_ACK, "Hello ACK" },
+ { MFR_CTRL_MSG_REMOVE_LINK, "Remove Link" },
+ { MFR_CTRL_MSG_REMOVE_LINK_ACK, "Remove Link ACK" },
+ { 0, NULL }
+};
+
+#define MFR_CTRL_IE_BUNDLE_ID 1
+#define MFR_CTRL_IE_LINK_ID 2
+#define MFR_CTRL_IE_MAGIC_NUM 3
+#define MFR_CTRL_IE_TIMESTAMP 5
+#define MFR_CTRL_IE_VENDOR_EXT 6
+#define MFR_CTRL_IE_CAUSE 7
+
+struct tok mfr_ctrl_ie_values[] = {
+ { MFR_CTRL_IE_BUNDLE_ID, "Bundle ID"},
+ { MFR_CTRL_IE_LINK_ID, "Link ID"},
+ { MFR_CTRL_IE_MAGIC_NUM, "Magic Number"},
+ { MFR_CTRL_IE_TIMESTAMP, "Timestamp"},
+ { MFR_CTRL_IE_VENDOR_EXT, "Vendor Extension"},
+ { MFR_CTRL_IE_CAUSE, "Cause"},
+ { 0, NULL }
+};
+
+#define MFR_ID_STRING_MAXLEN 50
+
+struct ie_tlv_header_t {
+ u_int8_t ie_type;
+ u_int8_t ie_len;
+};
+
+u_int
+mfr_print(register const u_char *p, u_int length)
+{
+ u_int tlen,idx,hdr_len = 0;
+ u_int16_t sequence_num;
+ u_int8_t ie_type,ie_len;
+ const u_int8_t *tptr;
+
+
+/*
+ * FRF.16 Link Integrity Control Frame
+ *
+ * 7 6 5 4 3 2 1 0
+ * +----+----+----+----+----+----+----+----+
+ * | B | E | C=1| 0 0 0 0 | EA |
+ * +----+----+----+----+----+----+----+----+
+ * | 0 0 0 0 0 0 0 0 |
+ * +----+----+----+----+----+----+----+----+
+ * | message type |
+ * +----+----+----+----+----+----+----+----+
+ */
+
+ TCHECK2(*p, 4); /* minimum frame header length */
+
+ if ((p[0] & MFR_BEC_MASK) == MFR_CTRL_FRAME && p[1] == 0) {
+ printf("FRF.16 Control, Flags [%s], %s, length %u",
+ bittok2str(frf_flag_values,"none",(p[0] & MFR_BEC_MASK)),
+ tok2str(mfr_ctrl_msg_values,"Unknown Message (0x%02x)",p[2]),
+ length);
+ tptr = p + 3;
+ tlen = length -3;
+ hdr_len = 3;
+
+ if (!vflag)
+ return hdr_len;
+
+ while (tlen>sizeof(struct ie_tlv_header_t)) {
+ TCHECK2(*tptr, sizeof(struct ie_tlv_header_t));
+ ie_type=tptr[0];
+ ie_len=tptr[1];
+
+ printf("\n\tIE %s (%u), length %u: ",
+ tok2str(mfr_ctrl_ie_values,"Unknown",ie_type),
+ ie_type,
+ ie_len);
+
+ /* infinite loop check */
+ if (ie_type == 0 || ie_len <= sizeof(struct ie_tlv_header_t))
+ return hdr_len;
+
+ TCHECK2(*tptr,ie_len);
+ tptr+=sizeof(struct ie_tlv_header_t);
+ /* tlv len includes header */
+ ie_len-=sizeof(struct ie_tlv_header_t);
+ tlen-=sizeof(struct ie_tlv_header_t);
+
+ switch (ie_type) {
+
+ case MFR_CTRL_IE_MAGIC_NUM:
+ printf("0x%08x",EXTRACT_32BITS(tptr));
+ break;
+
+ case MFR_CTRL_IE_BUNDLE_ID: /* same message format */
+ case MFR_CTRL_IE_LINK_ID:
+ for (idx = 0; idx < ie_len && idx < MFR_ID_STRING_MAXLEN; idx++) {
+ if (*(tptr+idx) != 0) /* don't print null termination */
+ safeputchar(*(tptr+idx));
+ else
+ break;
+ }
+ break;
+
+ case MFR_CTRL_IE_TIMESTAMP:
+ if (ie_len == sizeof(struct timeval)) {
+ ts_print((const struct timeval *)tptr);
+ break;
+ }
+ /* fall through and hexdump if no unix timestamp */
+
+ /*
+ * FIXME those are the defined IEs that lack a decoder
+ * you are welcome to contribute code ;-)
+ */
+
+ case MFR_CTRL_IE_VENDOR_EXT:
+ case MFR_CTRL_IE_CAUSE:
+
+ default:
+ if (vflag <= 1)
+ print_unknown_data(tptr,"\n\t ",ie_len);
+ break;
+ }
+
+ /* do we want to see a hexdump of the IE ? */
+ if (vflag > 1 )
+ print_unknown_data(tptr,"\n\t ",ie_len);
+
+ tlen-=ie_len;
+ tptr+=ie_len;
+ }
+ return hdr_len;
+ }
+/*
+ * FRF.16 Fragmentation Frame
+ *
+ * 7 6 5 4 3 2 1 0
+ * +----+----+----+----+----+----+----+----+
+ * | B | E | C=0|seq. (high 4 bits) | EA |
+ * +----+----+----+----+----+----+----+----+
+ * | sequence (low 8 bits) |
+ * +----+----+----+----+----+----+----+----+
+ * | DLCI (6 bits) | CR | EA |
+ * +----+----+----+----+----+----+----+----+
+ * | DLCI (4 bits) |FECN|BECN| DE | EA |
+ * +----+----+----+----+----+----+----+----+
+ */
+
+ sequence_num = (p[0]&0x1e)<<7 | p[1];
+ /* whole packet or first fragment ? */
+ if ((p[0] & MFR_BEC_MASK) == MFR_FRAG_FRAME ||
+ (p[0] & MFR_BEC_MASK) == MFR_B_BIT) {
+ printf("FRF.16 Frag, seq %u, Flags [%s], ",
+ sequence_num,
+ bittok2str(frf_flag_values,"none",(p[0] & MFR_BEC_MASK)));
+ hdr_len = 2;
+ fr_print(p+hdr_len,length-hdr_len);
+ return hdr_len;
+ }
+
+ /* must be a middle or the last fragment */
+ printf("FRF.16 Frag, seq %u, Flags [%s]",
+ sequence_num,
+ bittok2str(frf_flag_values,"none",(p[0] & MFR_BEC_MASK)));
+ print_unknown_data(p,"\n\t",length);
+
+ return hdr_len;
+
+ trunc:
+ printf("[|mfr]");
+ return length;
+}
+
+/* an NLPID of 0xb1 indicates a 2-byte
+ * FRF.15 header
+ *
+ * 7 6 5 4 3 2 1 0
+ * +----+----+----+----+----+----+----+----+
+ * ~ Q.922 header ~
+ * +----+----+----+----+----+----+----+----+
+ * | NLPID (8 bits) | NLPID=0xb1
+ * +----+----+----+----+----+----+----+----+
+ * | B | E | C |seq. (high 4 bits) | R |
+ * +----+----+----+----+----+----+----+----+
+ * | sequence (low 8 bits) |
+ * +----+----+----+----+----+----+----+----+
+ */
+
+#define FR_FRF15_FRAGTYPE 0x01
+
+static void
+frf15_print (const u_char *p, u_int length) {
+
+ u_int16_t sequence_num, flags;
+
+ flags = p[0]&MFR_BEC_MASK;
+ sequence_num = (p[0]&0x1e)<<7 | p[1];
+
+ printf("FRF.15, seq 0x%03x, Flags [%s],%s Fragmentation, length %u",
+ sequence_num,
+ bittok2str(frf_flag_values,"none",flags),
+ p[0]&FR_FRF15_FRAGTYPE ? "Interface" : "End-to-End",
+ length);
+
+/* TODO:
+ * depending on all permutations of the B, E and C bit
+ * dig as deep as we can - e.g. on the first (B) fragment
+ * there is enough payload to print the IP header
+ * on non (B) fragments it depends if the fragmentation
+ * model is end-to-end or interface based wether we want to print
+ * another Q.922 header
+ */
+
+}
+
+/*
+ * Q.933 decoding portion for framerelay specific.
+ */
+
+/* Q.933 packet format
+ Format of Other Protocols
+ using Q.933 NLPID
+ +-------------------------------+
+ | Q.922 Address |
+ +---------------+---------------+
+ |Control 0x03 | NLPID 0x08 |
+ +---------------+---------------+
+ | L2 Protocol ID |
+ | octet 1 | octet 2 |
+ +-------------------------------+
+ | L3 Protocol ID |
+ | octet 2 | octet 2 |
+ +-------------------------------+
+ | Protocol Data |
+ +-------------------------------+
+ | FCS |
+ +-------------------------------+
+ */
+
+/* L2 (Octet 1)- Call Reference Usually is 0x0 */
+
+/*
+ * L2 (Octet 2)- Message Types definition 1 byte long.
+ */
+/* Call Establish */
+#define MSG_TYPE_ESC_TO_NATIONAL 0x00
+#define MSG_TYPE_ALERT 0x01
+#define MSG_TYPE_CALL_PROCEEDING 0x02
+#define MSG_TYPE_CONNECT 0x07
+#define MSG_TYPE_CONNECT_ACK 0x0F
+#define MSG_TYPE_PROGRESS 0x03
+#define MSG_TYPE_SETUP 0x05
+/* Call Clear */
+#define MSG_TYPE_DISCONNECT 0x45
+#define MSG_TYPE_RELEASE 0x4D
+#define MSG_TYPE_RELEASE_COMPLETE 0x5A
+#define MSG_TYPE_RESTART 0x46
+#define MSG_TYPE_RESTART_ACK 0x4E
+/* Status */
+#define MSG_TYPE_STATUS 0x7D
+#define MSG_TYPE_STATUS_ENQ 0x75
+
+struct tok fr_q933_msg_values[] = {
+ { MSG_TYPE_ESC_TO_NATIONAL, "ESC to National" },
+ { MSG_TYPE_ALERT, "Alert" },
+ { MSG_TYPE_CALL_PROCEEDING, "Call proceeding" },
+ { MSG_TYPE_CONNECT, "Connect" },
+ { MSG_TYPE_CONNECT_ACK, "Connect ACK" },
+ { MSG_TYPE_PROGRESS, "Progress" },
+ { MSG_TYPE_SETUP, "Setup" },
+ { MSG_TYPE_DISCONNECT, "Disconnect" },
+ { MSG_TYPE_RELEASE, "Release" },
+ { MSG_TYPE_RELEASE_COMPLETE, "Release Complete" },
+ { MSG_TYPE_RESTART, "Restart" },
+ { MSG_TYPE_RESTART_ACK, "Restart ACK" },
+ { MSG_TYPE_STATUS, "Status Reply" },
+ { MSG_TYPE_STATUS_ENQ, "Status Enquiry" },
+ { 0, NULL }
+};
+
+#define MSG_ANSI_LOCKING_SHIFT 0x95
+
+#define FR_LMI_ANSI_REPORT_TYPE_IE 0x01
+#define FR_LMI_ANSI_LINK_VERIFY_IE_91 0x19 /* details? */
+#define FR_LMI_ANSI_LINK_VERIFY_IE 0x03
+#define FR_LMI_ANSI_PVC_STATUS_IE 0x07
+
+#define FR_LMI_CCITT_REPORT_TYPE_IE 0x51
+#define FR_LMI_CCITT_LINK_VERIFY_IE 0x53
+#define FR_LMI_CCITT_PVC_STATUS_IE 0x57
+
+struct tok fr_q933_ie_values_codeset5[] = {
+ { FR_LMI_ANSI_REPORT_TYPE_IE, "ANSI Report Type" },
+ { FR_LMI_ANSI_LINK_VERIFY_IE_91, "ANSI Link Verify" },
+ { FR_LMI_ANSI_LINK_VERIFY_IE, "ANSI Link Verify" },
+ { FR_LMI_ANSI_PVC_STATUS_IE, "ANSI PVC Status" },
+ { FR_LMI_CCITT_REPORT_TYPE_IE, "CCITT Report Type" },
+ { FR_LMI_CCITT_LINK_VERIFY_IE, "CCITT Link Verify" },
+ { FR_LMI_CCITT_PVC_STATUS_IE, "CCITT PVC Status" },
+ { 0, NULL }
+};
+
+#define FR_LMI_REPORT_TYPE_IE_FULL_STATUS 0
+#define FR_LMI_REPORT_TYPE_IE_LINK_VERIFY 1
+#define FR_LMI_REPORT_TYPE_IE_ASYNC_PVC 2
+
+struct tok fr_lmi_report_type_ie_values[] = {
+ { FR_LMI_REPORT_TYPE_IE_FULL_STATUS, "Full Status" },
+ { FR_LMI_REPORT_TYPE_IE_LINK_VERIFY, "Link verify" },
+ { FR_LMI_REPORT_TYPE_IE_ASYNC_PVC, "Async PVC Status" },
+ { 0, NULL }
+};
+
+/* array of 16 codepages - currently we only support codepage 1,5 */
+static struct tok *fr_q933_ie_codesets[] = {
+ NULL,
+ fr_q933_ie_values_codeset5,
+ NULL,
+ NULL,
+ NULL,
+ fr_q933_ie_values_codeset5,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static int fr_q933_print_ie_codeset5(const struct ie_tlv_header_t *ie_p,
+ const u_char *p);
+
+typedef int (*codeset_pr_func_t)(const struct ie_tlv_header_t *ie_p,
+ const u_char *p);
+
+/* array of 16 codepages - currently we only support codepage 1,5 */
+static codeset_pr_func_t fr_q933_print_ie_codeset[] = {
+ NULL,
+ fr_q933_print_ie_codeset5,
+ NULL,
+ NULL,
+ NULL,
+ fr_q933_print_ie_codeset5,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+void
+q933_print(const u_char *p, u_int length)
+{
+ const u_char *ptemp = p;
+ struct ie_tlv_header_t *ie_p;
+ int olen;
+ int is_ansi = 0;
+ u_int codeset;
+ u_int ie_is_known = 0;
+
+ if (length < 9) { /* shortest: Q.933a LINK VERIFY */
+ printf("[|q.933]");
+ return;
+ }
+
+ codeset = p[2]&0x0f; /* extract the codeset */
+
+ if (p[2] == MSG_ANSI_LOCKING_SHIFT) {
+ is_ansi = 1;
+ }
+
+ printf("%s", eflag ? "" : "Q.933, ");
+
+ /* printing out header part */
+ printf("%s, codeset %u", is_ansi ? "ANSI" : "CCITT", codeset);
+
+ if (p[0]) {
+ printf(", Call Ref: 0x%02x", p[0]);
+ }
+ if (vflag) {
+ printf(", %s (0x%02x), length %u",
+ tok2str(fr_q933_msg_values,
+ "unknown message", p[1]),
+ p[1],
+ length);
+ } else {
+ printf(", %s",
+ tok2str(fr_q933_msg_values,
+ "unknown message 0x%02x", p[1]));
+ }
+
+ olen = length; /* preserve the original length for non verbose mode */
+
+ if (length < (u_int)(2 - is_ansi)) {
+ printf("[|q.933]");
+ return;
+ }
+ length -= 2 + is_ansi;
+ ptemp += 2 + is_ansi;
+
+ /* Loop through the rest of IE */
+ while (length > sizeof(struct ie_tlv_header_t)) {
+ ie_p = (struct ie_tlv_header_t *)ptemp;
+ if (length < sizeof(struct ie_tlv_header_t) ||
+ length < sizeof(struct ie_tlv_header_t) + ie_p->ie_len) {
+ if (vflag) { /* not bark if there is just a trailer */
+ printf("\n[|q.933]");
+ } else {
+ printf(", length %u",olen);
+ }
+ return;
+ }
+
+ /* lets do the full IE parsing only in verbose mode
+ * however some IEs (DLCI Status, Link Verify)
+ * are also interestting in non-verbose mode */
+ if (vflag) {
+ printf("\n\t%s IE (0x%02x), length %u: ",
+ tok2str(fr_q933_ie_codesets[codeset],
+ "unknown", ie_p->ie_type),
+ ie_p->ie_type,
+ ie_p->ie_len);
+ }
+
+ /* sanity check */
+ if (ie_p->ie_type == 0 || ie_p->ie_len == 0) {
+ return;
+ }
+
+ if (fr_q933_print_ie_codeset[codeset] != NULL) {
+ ie_is_known = fr_q933_print_ie_codeset[codeset](ie_p, ptemp);
+ }
+
+ if (vflag >= 1 && !ie_is_known) {
+ print_unknown_data(ptemp+2,"\n\t",ie_p->ie_len);
+ }
+
+ /* do we want to see a hexdump of the IE ? */
+ if (vflag> 1 && ie_is_known) {
+ print_unknown_data(ptemp+2,"\n\t ",ie_p->ie_len);
+ }
+
+ length = length - ie_p->ie_len - 2;
+ ptemp = ptemp + ie_p->ie_len + 2;
+ }
+ if (!vflag) {
+ printf(", length %u",olen);
+ }
+}
+
+static int
+fr_q933_print_ie_codeset5(const struct ie_tlv_header_t *ie_p, const u_char *p)
+{
+ u_int dlci;
+
+ switch (ie_p->ie_type) {
+
+ case FR_LMI_ANSI_REPORT_TYPE_IE: /* fall through */
+ case FR_LMI_CCITT_REPORT_TYPE_IE:
+ if (vflag) {
+ printf("%s (%u)",
+ tok2str(fr_lmi_report_type_ie_values,"unknown",p[2]),
+ p[2]);
+ }
+ return 1;
+
+ case FR_LMI_ANSI_LINK_VERIFY_IE: /* fall through */
+ case FR_LMI_CCITT_LINK_VERIFY_IE:
+ case FR_LMI_ANSI_LINK_VERIFY_IE_91:
+ if (!vflag) {
+ printf(", ");
+ }
+ printf("TX Seq: %3d, RX Seq: %3d", p[2], p[3]);
+ return 1;
+
+ case FR_LMI_ANSI_PVC_STATUS_IE: /* fall through */
+ case FR_LMI_CCITT_PVC_STATUS_IE:
+ if (!vflag) {
+ printf(", ");
+ }
+ /* now parse the DLCI information element. */
+ if ((ie_p->ie_len < 3) ||
+ (p[2] & 0x80) ||
+ ((ie_p->ie_len == 3) && !(p[3] & 0x80)) ||
+ ((ie_p->ie_len == 4) && ((p[3] & 0x80) || !(p[4] & 0x80))) ||
+ ((ie_p->ie_len == 5) && ((p[3] & 0x80) || (p[4] & 0x80) ||
+ !(p[5] & 0x80))) ||
+ (ie_p->ie_len > 5) ||
+ !(p[ie_p->ie_len + 1] & 0x80)) {
+ printf("Invalid DLCI IE");
+ }
+
+ dlci = ((p[2] & 0x3F) << 4) | ((p[3] & 0x78) >> 3);
+ if (ie_p->ie_len == 4) {
+ dlci = (dlci << 6) | ((p[4] & 0x7E) >> 1);
+ }
+ else if (ie_p->ie_len == 5) {
+ dlci = (dlci << 13) | (p[4] & 0x7F) | ((p[5] & 0x7E) >> 1);
+ }
+
+ printf("DLCI %u: status %s%s", dlci,
+ p[ie_p->ie_len + 1] & 0x8 ? "New, " : "",
+ p[ie_p->ie_len + 1] & 0x2 ? "Active" : "Inactive");
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/freebsd/contrib/tcpdump/print-frag6.c b/freebsd/contrib/tcpdump/print-frag6.c
new file mode 100644
index 00000000..5401de13
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-frag6.c
@@ -0,0 +1,84 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-frag6.c,v 1.20 2005-04-20 22:33:06 guy Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef INET6
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+
+#include "ip6.h"
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+int
+frag6_print(register const u_char *bp, register const u_char *bp2)
+{
+ register const struct ip6_frag *dp;
+ register const struct ip6_hdr *ip6;
+
+ dp = (const struct ip6_frag *)bp;
+ ip6 = (const struct ip6_hdr *)bp2;
+
+ TCHECK(dp->ip6f_offlg);
+
+ if (vflag) {
+ printf("frag (0x%08x:%d|%ld)",
+ EXTRACT_32BITS(&dp->ip6f_ident),
+ EXTRACT_16BITS(&dp->ip6f_offlg) & IP6F_OFF_MASK,
+ sizeof(struct ip6_hdr) + EXTRACT_16BITS(&ip6->ip6_plen) -
+ (long)(bp - bp2) - sizeof(struct ip6_frag));
+ } else {
+ printf("frag (%d|%ld)",
+ EXTRACT_16BITS(&dp->ip6f_offlg) & IP6F_OFF_MASK,
+ sizeof(struct ip6_hdr) + EXTRACT_16BITS(&ip6->ip6_plen) -
+ (long)(bp - bp2) - sizeof(struct ip6_frag));
+ }
+
+#if 1
+ /* it is meaningless to decode non-first fragment */
+ if ((EXTRACT_16BITS(&dp->ip6f_offlg) & IP6F_OFF_MASK) != 0)
+ return -1;
+ else
+#endif
+ {
+ fputs(" ", stdout);
+ return sizeof(struct ip6_frag);
+ }
+trunc:
+ fputs("[|frag]", stdout);
+ return -1;
+#undef TCHECK
+}
+#endif /* INET6 */
diff --git a/freebsd/contrib/tcpdump/print-gre.c b/freebsd/contrib/tcpdump/print-gre.c
new file mode 100644
index 00000000..a3e6c315
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-gre.c
@@ -0,0 +1,405 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/* $OpenBSD: print-gre.c,v 1.6 2002/10/30 03:04:04 fgsch Exp $ */
+
+/*
+ * Copyright (c) 2002 Jason L. Wright (jason@thought.net)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Jason L. Wright
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * tcpdump filter for GRE - Generic Routing Encapsulation
+ * RFC1701 (GRE), RFC1702 (GRE IPv4), and RFC2637 (Enhanced GRE)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-gre.c,v 1.28 2005-04-06 21:32:39 mcr Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+#include "ip.h"
+#include "ethertype.h"
+
+#define GRE_CP 0x8000 /* checksum present */
+#define GRE_RP 0x4000 /* routing present */
+#define GRE_KP 0x2000 /* key present */
+#define GRE_SP 0x1000 /* sequence# present */
+#define GRE_sP 0x0800 /* source routing */
+#define GRE_RECRS 0x0700 /* recursion count */
+#define GRE_AP 0x0080 /* acknowledgment# present */
+
+struct tok gre_flag_values[] = {
+ { GRE_CP, "checksum present"},
+ { GRE_RP, "routing present"},
+ { GRE_KP, "key present"},
+ { GRE_SP, "sequence# present"},
+ { GRE_sP, "source routing present"},
+ { GRE_RECRS, "recursion count"},
+ { GRE_AP, "ack present"},
+ { 0, NULL }
+};
+
+#define GRE_VERS_MASK 0x0007 /* protocol version */
+
+/* source route entry types */
+#define GRESRE_IP 0x0800 /* IP */
+#define GRESRE_ASN 0xfffe /* ASN */
+
+void gre_print_0(const u_char *, u_int);
+void gre_print_1(const u_char *, u_int);
+void gre_sre_print(u_int16_t, u_int8_t, u_int8_t, const u_char *, u_int);
+void gre_sre_ip_print(u_int8_t, u_int8_t, const u_char *, u_int);
+void gre_sre_asn_print(u_int8_t, u_int8_t, const u_char *, u_int);
+
+void
+gre_print(const u_char *bp, u_int length)
+{
+ u_int len = length, vers;
+
+ if (len < 2) {
+ printf("[|gre]");
+ return;
+ }
+ vers = EXTRACT_16BITS(bp) & GRE_VERS_MASK;
+ printf("GREv%u",vers);
+
+ switch(vers) {
+ case 0:
+ gre_print_0(bp, len);
+ break;
+ case 1:
+ gre_print_1(bp, len);
+ break;
+ default:
+ printf(" ERROR: unknown-version");
+ break;
+ }
+ return;
+
+}
+
+void
+gre_print_0(const u_char *bp, u_int length)
+{
+ u_int len = length;
+ u_int16_t flags, prot;
+
+ flags = EXTRACT_16BITS(bp);
+ if (vflag)
+ printf(", Flags [%s]",
+ bittok2str(gre_flag_values,"none",flags));
+
+ len -= 2;
+ bp += 2;
+
+ if (len < 2)
+ goto trunc;
+ prot = EXTRACT_16BITS(bp);
+ len -= 2;
+ bp += 2;
+
+ if ((flags & GRE_CP) | (flags & GRE_RP)) {
+ if (len < 2)
+ goto trunc;
+ if (vflag)
+ printf(", sum 0x%x", EXTRACT_16BITS(bp));
+ bp += 2;
+ len -= 2;
+
+ if (len < 2)
+ goto trunc;
+ printf(", off 0x%x", EXTRACT_16BITS(bp));
+ bp += 2;
+ len -= 2;
+ }
+
+ if (flags & GRE_KP) {
+ if (len < 4)
+ goto trunc;
+ printf(", key=0x%x", EXTRACT_32BITS(bp));
+ bp += 4;
+ len -= 4;
+ }
+
+ if (flags & GRE_SP) {
+ if (len < 4)
+ goto trunc;
+ printf(", seq %u", EXTRACT_32BITS(bp));
+ bp += 4;
+ len -= 4;
+ }
+
+ if (flags & GRE_RP) {
+ for (;;) {
+ u_int16_t af;
+ u_int8_t sreoff;
+ u_int8_t srelen;
+
+ if (len < 4)
+ goto trunc;
+ af = EXTRACT_16BITS(bp);
+ sreoff = *(bp + 2);
+ srelen = *(bp + 3);
+ bp += 4;
+ len -= 4;
+
+ if (af == 0 && srelen == 0)
+ break;
+
+ gre_sre_print(af, sreoff, srelen, bp, len);
+
+ if (len < srelen)
+ goto trunc;
+ bp += srelen;
+ len -= srelen;
+ }
+ }
+
+ if (eflag)
+ printf(", proto %s (0x%04x)",
+ tok2str(ethertype_values,"unknown",prot),
+ prot);
+
+ printf(", length %u",length);
+
+ if (vflag < 1)
+ printf(": "); /* put in a colon as protocol demarc */
+ else
+ printf("\n\t"); /* if verbose go multiline */
+
+ switch (prot) {
+ case ETHERTYPE_IP:
+ ip_print(gndo, bp, len);
+ break;
+#ifdef INET6
+ case ETHERTYPE_IPV6:
+ ip6_print(gndo, bp, len);
+ break;
+#endif
+ case ETHERTYPE_MPLS:
+ mpls_print(bp, len);
+ break;
+ case ETHERTYPE_IPX:
+ ipx_print(bp, len);
+ break;
+ case ETHERTYPE_ATALK:
+ atalk_print(bp, len);
+ break;
+ case ETHERTYPE_GRE_ISO:
+ isoclns_print(bp, len, len);
+ break;
+ case ETHERTYPE_TEB:
+ ether_print(gndo, bp, len, len, NULL, NULL);
+ break;
+ default:
+ printf("gre-proto-0x%x", prot);
+ }
+ return;
+
+trunc:
+ printf("[|gre]");
+}
+
+void
+gre_print_1(const u_char *bp, u_int length)
+{
+ u_int len = length;
+ u_int16_t flags, prot;
+
+ flags = EXTRACT_16BITS(bp);
+ len -= 2;
+ bp += 2;
+
+ if (vflag)
+ printf(", Flags [%s]",
+ bittok2str(gre_flag_values,"none",flags));
+
+ if (len < 2)
+ goto trunc;
+ prot = EXTRACT_16BITS(bp);
+ len -= 2;
+ bp += 2;
+
+
+ if (flags & GRE_KP) {
+ u_int32_t k;
+
+ if (len < 4)
+ goto trunc;
+ k = EXTRACT_32BITS(bp);
+ printf(", call %d", k & 0xffff);
+ len -= 4;
+ bp += 4;
+ }
+
+ if (flags & GRE_SP) {
+ if (len < 4)
+ goto trunc;
+ printf(", seq %u", EXTRACT_32BITS(bp));
+ bp += 4;
+ len -= 4;
+ }
+
+ if (flags & GRE_AP) {
+ if (len < 4)
+ goto trunc;
+ printf(", ack %u", EXTRACT_32BITS(bp));
+ bp += 4;
+ len -= 4;
+ }
+
+ if ((flags & GRE_SP) == 0)
+ printf(", no-payload");
+
+ if (eflag)
+ printf(", proto %s (0x%04x)",
+ tok2str(ethertype_values,"unknown",prot),
+ prot);
+
+ printf(", length %u",length);
+
+ if ((flags & GRE_SP) == 0)
+ return;
+
+ if (vflag < 1)
+ printf(": "); /* put in a colon as protocol demarc */
+ else
+ printf("\n\t"); /* if verbose go multiline */
+
+ switch (prot) {
+ case ETHERTYPE_PPP:
+ ppp_print(bp, len);
+ break;
+ default:
+ printf("gre-proto-0x%x", prot);
+ break;
+ }
+ return;
+
+trunc:
+ printf("[|gre]");
+}
+
+void
+gre_sre_print(u_int16_t af, u_int8_t sreoff, u_int8_t srelen,
+ const u_char *bp, u_int len)
+{
+ switch (af) {
+ case GRESRE_IP:
+ printf(", (rtaf=ip");
+ gre_sre_ip_print(sreoff, srelen, bp, len);
+ printf(") ");
+ break;
+ case GRESRE_ASN:
+ printf(", (rtaf=asn");
+ gre_sre_asn_print(sreoff, srelen, bp, len);
+ printf(") ");
+ break;
+ default:
+ printf(", (rtaf=0x%x) ", af);
+ }
+}
+void
+gre_sre_ip_print(u_int8_t sreoff, u_int8_t srelen, const u_char *bp, u_int len)
+{
+ struct in_addr a;
+ const u_char *up = bp;
+
+ if (sreoff & 3) {
+ printf(", badoffset=%u", sreoff);
+ return;
+ }
+ if (srelen & 3) {
+ printf(", badlength=%u", srelen);
+ return;
+ }
+ if (sreoff >= srelen) {
+ printf(", badoff/len=%u/%u", sreoff, srelen);
+ return;
+ }
+
+ for (;;) {
+ if (len < 4 || srelen == 0)
+ return;
+
+ memcpy(&a, bp, sizeof(a));
+ printf(" %s%s",
+ ((bp - up) == sreoff) ? "*" : "",
+ inet_ntoa(a));
+
+ bp += 4;
+ len -= 4;
+ srelen -= 4;
+ }
+}
+
+void
+gre_sre_asn_print(u_int8_t sreoff, u_int8_t srelen, const u_char *bp, u_int len)
+{
+ const u_char *up = bp;
+
+ if (sreoff & 1) {
+ printf(", badoffset=%u", sreoff);
+ return;
+ }
+ if (srelen & 1) {
+ printf(", badlength=%u", srelen);
+ return;
+ }
+ if (sreoff >= srelen) {
+ printf(", badoff/len=%u/%u", sreoff, srelen);
+ return;
+ }
+
+ for (;;) {
+ if (len < 2 || srelen == 0)
+ return;
+
+ printf(" %s%x",
+ ((bp - up) == sreoff) ? "*" : "",
+ EXTRACT_16BITS(bp));
+
+ bp += 2;
+ len -= 2;
+ srelen -= 2;
+ }
+}
diff --git a/freebsd/contrib/tcpdump/print-hsrp.c b/freebsd/contrib/tcpdump/print-hsrp.c
new file mode 100644
index 00000000..51d4b107
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-hsrp.c
@@ -0,0 +1,142 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2001 Julian Cowley
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* Cisco Hot Standby Router Protocol (HSRP). */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-hsrp.c,v 1.10 2005-05-06 07:56:52 guy Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+/* HSRP op code types. */
+static const char *op_code_str[] = {
+ "hello",
+ "coup",
+ "resign"
+};
+
+/* HSRP states and associated names. */
+static struct tok states[] = {
+ { 0, "initial" },
+ { 1, "learn" },
+ { 2, "listen" },
+ { 4, "speak" },
+ { 8, "standby" },
+ { 16, "active" },
+ { 0, NULL }
+};
+
+/*
+ * RFC 2281:
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Version | Op Code | State | Hellotime |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Holdtime | Priority | Group | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Authentication Data |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Authentication Data |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Virtual IP Address |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define HSRP_AUTH_SIZE 8
+
+/* HSRP protocol header. */
+struct hsrp {
+ u_int8_t hsrp_version;
+ u_int8_t hsrp_op_code;
+ u_int8_t hsrp_state;
+ u_int8_t hsrp_hellotime;
+ u_int8_t hsrp_holdtime;
+ u_int8_t hsrp_priority;
+ u_int8_t hsrp_group;
+ u_int8_t hsrp_reserved;
+ u_int8_t hsrp_authdata[HSRP_AUTH_SIZE];
+ struct in_addr hsrp_virtaddr;
+};
+
+void
+hsrp_print(register const u_int8_t *bp, register u_int len)
+{
+ struct hsrp *hp = (struct hsrp *) bp;
+
+ TCHECK(hp->hsrp_version);
+ printf("HSRPv%d", hp->hsrp_version);
+ if (hp->hsrp_version != 0)
+ return;
+ TCHECK(hp->hsrp_op_code);
+ printf("-");
+ printf("%s ", tok2strary(op_code_str, "unknown (%d)", hp->hsrp_op_code));
+ printf("%d: ", len);
+ TCHECK(hp->hsrp_state);
+ printf("state=%s ", tok2str(states, "Unknown (%d)", hp->hsrp_state));
+ TCHECK(hp->hsrp_group);
+ printf("group=%d ", hp->hsrp_group);
+ TCHECK(hp->hsrp_reserved);
+ if (hp->hsrp_reserved != 0) {
+ printf("[reserved=%d!] ", hp->hsrp_reserved);
+ }
+ TCHECK(hp->hsrp_virtaddr);
+ printf("addr=%s", ipaddr_string(&hp->hsrp_virtaddr));
+ if (vflag) {
+ printf(" hellotime=");
+ relts_print(hp->hsrp_hellotime);
+ printf(" holdtime=");
+ relts_print(hp->hsrp_holdtime);
+ printf(" priority=%d", hp->hsrp_priority);
+ printf(" auth=\"");
+ if (fn_printn(hp->hsrp_authdata, sizeof(hp->hsrp_authdata),
+ snapend)) {
+ printf("\"");
+ goto trunc;
+ }
+ printf("\"");
+ }
+ return;
+trunc:
+ printf("[|hsrp]");
+}
diff --git a/freebsd/contrib/tcpdump/print-icmp.c b/freebsd/contrib/tcpdump/print-icmp.c
new file mode 100644
index 00000000..8cdc3651
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-icmp.c
@@ -0,0 +1,699 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-icmp.c,v 1.87 2007-09-13 17:42:31 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h" /* must come after interface.h */
+
+#include "ip.h"
+#include "udp.h"
+#include "ipproto.h"
+#include "mpls.h"
+
+/*
+ * Interface Control Message Protocol Definitions.
+ * Per RFC 792, September 1981.
+ */
+
+/*
+ * Structure of an icmp header.
+ */
+struct icmp {
+ u_int8_t icmp_type; /* type of message, see below */
+ u_int8_t icmp_code; /* type sub code */
+ u_int16_t icmp_cksum; /* ones complement cksum of struct */
+ union {
+ u_int8_t ih_pptr; /* ICMP_PARAMPROB */
+ struct in_addr ih_gwaddr; /* ICMP_REDIRECT */
+ struct ih_idseq {
+ u_int16_t icd_id;
+ u_int16_t icd_seq;
+ } ih_idseq;
+ u_int32_t ih_void;
+ } icmp_hun;
+#define icmp_pptr icmp_hun.ih_pptr
+#define icmp_gwaddr icmp_hun.ih_gwaddr
+#define icmp_id icmp_hun.ih_idseq.icd_id
+#define icmp_seq icmp_hun.ih_idseq.icd_seq
+#define icmp_void icmp_hun.ih_void
+ union {
+ struct id_ts {
+ u_int32_t its_otime;
+ u_int32_t its_rtime;
+ u_int32_t its_ttime;
+ } id_ts;
+ struct id_ip {
+ struct ip idi_ip;
+ /* options and then 64 bits of data */
+ } id_ip;
+ u_int32_t id_mask;
+ u_int8_t id_data[1];
+ } icmp_dun;
+#define icmp_otime icmp_dun.id_ts.its_otime
+#define icmp_rtime icmp_dun.id_ts.its_rtime
+#define icmp_ttime icmp_dun.id_ts.its_ttime
+#define icmp_ip icmp_dun.id_ip.idi_ip
+#define icmp_mask icmp_dun.id_mask
+#define icmp_data icmp_dun.id_data
+};
+
+#define ICMP_MPLS_EXT_EXTRACT_VERSION(x) (((x)&0xf0)>>4)
+#define ICMP_MPLS_EXT_VERSION 2
+
+/*
+ * Lower bounds on packet lengths for various types.
+ * For the error advice packets must first insure that the
+ * packet is large enought to contain the returned ip header.
+ * Only then can we do the check to see if 64 bits of packet
+ * data have been returned, since we need to check the returned
+ * ip header length.
+ */
+#define ICMP_MINLEN 8 /* abs minimum */
+#define ICMP_EXTD_MINLEN (156 - sizeof (struct ip)) /* draft-bonica-internet-icmp-08 */
+#define ICMP_TSLEN (8 + 3 * sizeof (u_int32_t)) /* timestamp */
+#define ICMP_MASKLEN 12 /* address mask */
+#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */
+#define ICMP_ADVLEN(p) (8 + (IP_HL(&(p)->icmp_ip) << 2) + 8)
+ /* N.B.: must separately check that ip_hl >= 5 */
+
+/*
+ * Definition of type and code field values.
+ */
+#define ICMP_ECHOREPLY 0 /* echo reply */
+#define ICMP_UNREACH 3 /* dest unreachable, codes: */
+#define ICMP_UNREACH_NET 0 /* bad net */
+#define ICMP_UNREACH_HOST 1 /* bad host */
+#define ICMP_UNREACH_PROTOCOL 2 /* bad protocol */
+#define ICMP_UNREACH_PORT 3 /* bad port */
+#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */
+#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */
+#define ICMP_UNREACH_NET_UNKNOWN 6 /* unknown net */
+#define ICMP_UNREACH_HOST_UNKNOWN 7 /* unknown host */
+#define ICMP_UNREACH_ISOLATED 8 /* src host isolated */
+#define ICMP_UNREACH_NET_PROHIB 9 /* prohibited access */
+#define ICMP_UNREACH_HOST_PROHIB 10 /* ditto */
+#define ICMP_UNREACH_TOSNET 11 /* bad tos for net */
+#define ICMP_UNREACH_TOSHOST 12 /* bad tos for host */
+#define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */
+#define ICMP_REDIRECT 5 /* shorter route, codes: */
+#define ICMP_REDIRECT_NET 0 /* for network */
+#define ICMP_REDIRECT_HOST 1 /* for host */
+#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */
+#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */
+#define ICMP_ECHO 8 /* echo service */
+#define ICMP_ROUTERADVERT 9 /* router advertisement */
+#define ICMP_ROUTERSOLICIT 10 /* router solicitation */
+#define ICMP_TIMXCEED 11 /* time exceeded, code: */
+#define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */
+#define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */
+#define ICMP_PARAMPROB 12 /* ip header bad */
+#define ICMP_PARAMPROB_OPTABSENT 1 /* req. opt. absent */
+#define ICMP_TSTAMP 13 /* timestamp request */
+#define ICMP_TSTAMPREPLY 14 /* timestamp reply */
+#define ICMP_IREQ 15 /* information request */
+#define ICMP_IREQREPLY 16 /* information reply */
+#define ICMP_MASKREQ 17 /* address mask request */
+#define ICMP_MASKREPLY 18 /* address mask reply */
+
+#define ICMP_MAXTYPE 18
+
+#define ICMP_INFOTYPE(type) \
+ ((type) == ICMP_ECHOREPLY || (type) == ICMP_ECHO || \
+ (type) == ICMP_ROUTERADVERT || (type) == ICMP_ROUTERSOLICIT || \
+ (type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \
+ (type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \
+ (type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)
+#define ICMP_MPLS_EXT_TYPE(type) \
+ ((type) == ICMP_UNREACH || \
+ (type) == ICMP_TIMXCEED || \
+ (type) == ICMP_PARAMPROB)
+/* rfc1700 */
+#ifndef ICMP_UNREACH_NET_UNKNOWN
+#define ICMP_UNREACH_NET_UNKNOWN 6 /* destination net unknown */
+#endif
+#ifndef ICMP_UNREACH_HOST_UNKNOWN
+#define ICMP_UNREACH_HOST_UNKNOWN 7 /* destination host unknown */
+#endif
+#ifndef ICMP_UNREACH_ISOLATED
+#define ICMP_UNREACH_ISOLATED 8 /* source host isolated */
+#endif
+#ifndef ICMP_UNREACH_NET_PROHIB
+#define ICMP_UNREACH_NET_PROHIB 9 /* admin prohibited net */
+#endif
+#ifndef ICMP_UNREACH_HOST_PROHIB
+#define ICMP_UNREACH_HOST_PROHIB 10 /* admin prohibited host */
+#endif
+#ifndef ICMP_UNREACH_TOSNET
+#define ICMP_UNREACH_TOSNET 11 /* tos prohibited net */
+#endif
+#ifndef ICMP_UNREACH_TOSHOST
+#define ICMP_UNREACH_TOSHOST 12 /* tos prohibited host */
+#endif
+
+/* rfc1716 */
+#ifndef ICMP_UNREACH_FILTER_PROHIB
+#define ICMP_UNREACH_FILTER_PROHIB 13 /* admin prohibited filter */
+#endif
+#ifndef ICMP_UNREACH_HOST_PRECEDENCE
+#define ICMP_UNREACH_HOST_PRECEDENCE 14 /* host precedence violation */
+#endif
+#ifndef ICMP_UNREACH_PRECEDENCE_CUTOFF
+#define ICMP_UNREACH_PRECEDENCE_CUTOFF 15 /* precedence cutoff */
+#endif
+
+/* Most of the icmp types */
+static struct tok icmp2str[] = {
+ { ICMP_ECHOREPLY, "echo reply" },
+ { ICMP_SOURCEQUENCH, "source quench" },
+ { ICMP_ECHO, "echo request" },
+ { ICMP_ROUTERSOLICIT, "router solicitation" },
+ { ICMP_TSTAMP, "time stamp request" },
+ { ICMP_TSTAMPREPLY, "time stamp reply" },
+ { ICMP_IREQ, "information request" },
+ { ICMP_IREQREPLY, "information reply" },
+ { ICMP_MASKREQ, "address mask request" },
+ { 0, NULL }
+};
+
+/* Formats for most of the ICMP_UNREACH codes */
+static struct tok unreach2str[] = {
+ { ICMP_UNREACH_NET, "net %s unreachable" },
+ { ICMP_UNREACH_HOST, "host %s unreachable" },
+ { ICMP_UNREACH_SRCFAIL,
+ "%s unreachable - source route failed" },
+ { ICMP_UNREACH_NET_UNKNOWN, "net %s unreachable - unknown" },
+ { ICMP_UNREACH_HOST_UNKNOWN, "host %s unreachable - unknown" },
+ { ICMP_UNREACH_ISOLATED,
+ "%s unreachable - source host isolated" },
+ { ICMP_UNREACH_NET_PROHIB,
+ "net %s unreachable - admin prohibited" },
+ { ICMP_UNREACH_HOST_PROHIB,
+ "host %s unreachable - admin prohibited" },
+ { ICMP_UNREACH_TOSNET,
+ "net %s unreachable - tos prohibited" },
+ { ICMP_UNREACH_TOSHOST,
+ "host %s unreachable - tos prohibited" },
+ { ICMP_UNREACH_FILTER_PROHIB,
+ "host %s unreachable - admin prohibited filter" },
+ { ICMP_UNREACH_HOST_PRECEDENCE,
+ "host %s unreachable - host precedence violation" },
+ { ICMP_UNREACH_PRECEDENCE_CUTOFF,
+ "host %s unreachable - precedence cutoff" },
+ { 0, NULL }
+};
+
+/* Formats for the ICMP_REDIRECT codes */
+static struct tok type2str[] = {
+ { ICMP_REDIRECT_NET, "redirect %s to net %s" },
+ { ICMP_REDIRECT_HOST, "redirect %s to host %s" },
+ { ICMP_REDIRECT_TOSNET, "redirect-tos %s to net %s" },
+ { ICMP_REDIRECT_TOSHOST, "redirect-tos %s to host %s" },
+ { 0, NULL }
+};
+
+/* rfc1191 */
+struct mtu_discovery {
+ u_int16_t unused;
+ u_int16_t nexthopmtu;
+};
+
+/* rfc1256 */
+struct ih_rdiscovery {
+ u_int8_t ird_addrnum;
+ u_int8_t ird_addrsiz;
+ u_int16_t ird_lifetime;
+};
+
+struct id_rdiscovery {
+ u_int32_t ird_addr;
+ u_int32_t ird_pref;
+};
+
+/*
+ * draft-bonica-internet-icmp-08
+ *
+ * The Destination Unreachable, Time Exceeded
+ * and Parameter Problem messages are slighly changed as per
+ * the above draft. A new Length field gets added to give
+ * the caller an idea about the length of the piggypacked
+ * IP packet before the MPLS extension header starts.
+ *
+ * The Length field represents length of the padded "original datagram"
+ * field measured in 32-bit words.
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Type | Code | Checksum |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | unused | Length | unused |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Internet Header + leading octets of original datagram |
+ * | |
+ * | // |
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+struct icmp_ext_t {
+ u_int8_t icmp_type;
+ u_int8_t icmp_code;
+ u_int8_t icmp_checksum[2];
+ u_int8_t icmp_reserved;
+ u_int8_t icmp_length;
+ u_int8_t icmp_reserved2[2];
+ u_int8_t icmp_ext_legacy_header[128]; /* extension header starts 128 bytes after ICMP header */
+ u_int8_t icmp_ext_version_res[2];
+ u_int8_t icmp_ext_checksum[2];
+ u_int8_t icmp_ext_data[1];
+};
+
+struct icmp_mpls_ext_object_header_t {
+ u_int8_t length[2];
+ u_int8_t class_num;
+ u_int8_t ctype;
+};
+
+static const struct tok icmp_mpls_ext_obj_values[] = {
+ { 1, "MPLS Stack Entry" },
+ { 2, "Extended Payload" },
+ { 0, NULL}
+};
+
+/* prototypes */
+const char *icmp_tstamp_print(u_int);
+
+/* print the milliseconds since midnight UTC */
+const char *
+icmp_tstamp_print(u_int tstamp) {
+ u_int msec,sec,min,hrs;
+
+ static char buf[64];
+
+ msec = tstamp % 1000;
+ sec = tstamp / 1000;
+ min = sec / 60; sec -= min * 60;
+ hrs = min / 60; min -= hrs * 60;
+ snprintf(buf, sizeof(buf), "%02u:%02u:%02u.%03u",hrs,min,sec,msec);
+ return buf;
+}
+
+void
+icmp_print(const u_char *bp, u_int plen, const u_char *bp2, int fragmented)
+{
+ char *cp;
+ const struct icmp *dp;
+ const struct icmp_ext_t *ext_dp;
+ const struct ip *ip;
+ const char *str, *fmt;
+ const struct ip *oip;
+ const struct udphdr *ouh;
+ const u_int8_t *obj_tptr;
+ u_int32_t raw_label;
+ const u_char *snapend_save;
+ const struct icmp_mpls_ext_object_header_t *icmp_mpls_ext_object_header;
+ u_int hlen, dport, mtu, obj_tlen, obj_class_num, obj_ctype;
+ char buf[MAXHOSTNAMELEN + 100];
+ struct cksum_vec vec[1];
+
+ dp = (struct icmp *)bp;
+ ext_dp = (struct icmp_ext_t *)bp;
+ ip = (struct ip *)bp2;
+ str = buf;
+
+ TCHECK(dp->icmp_code);
+ switch (dp->icmp_type) {
+
+ case ICMP_ECHO:
+ case ICMP_ECHOREPLY:
+ TCHECK(dp->icmp_seq);
+ (void)snprintf(buf, sizeof(buf), "echo %s, id %u, seq %u",
+ dp->icmp_type == ICMP_ECHO ?
+ "request" : "reply",
+ EXTRACT_16BITS(&dp->icmp_id),
+ EXTRACT_16BITS(&dp->icmp_seq));
+ break;
+
+ case ICMP_UNREACH:
+ TCHECK(dp->icmp_ip.ip_dst);
+ switch (dp->icmp_code) {
+
+ case ICMP_UNREACH_PROTOCOL:
+ TCHECK(dp->icmp_ip.ip_p);
+ (void)snprintf(buf, sizeof(buf),
+ "%s protocol %d unreachable",
+ ipaddr_string(&dp->icmp_ip.ip_dst),
+ dp->icmp_ip.ip_p);
+ break;
+
+ case ICMP_UNREACH_PORT:
+ TCHECK(dp->icmp_ip.ip_p);
+ oip = &dp->icmp_ip;
+ hlen = IP_HL(oip) * 4;
+ ouh = (struct udphdr *)(((u_char *)oip) + hlen);
+ TCHECK(ouh->uh_dport);
+ dport = EXTRACT_16BITS(&ouh->uh_dport);
+ switch (oip->ip_p) {
+
+ case IPPROTO_TCP:
+ (void)snprintf(buf, sizeof(buf),
+ "%s tcp port %s unreachable",
+ ipaddr_string(&oip->ip_dst),
+ tcpport_string(dport));
+ break;
+
+ case IPPROTO_UDP:
+ (void)snprintf(buf, sizeof(buf),
+ "%s udp port %s unreachable",
+ ipaddr_string(&oip->ip_dst),
+ udpport_string(dport));
+ break;
+
+ default:
+ (void)snprintf(buf, sizeof(buf),
+ "%s protocol %d port %d unreachable",
+ ipaddr_string(&oip->ip_dst),
+ oip->ip_p, dport);
+ break;
+ }
+ break;
+
+ case ICMP_UNREACH_NEEDFRAG:
+ {
+ register const struct mtu_discovery *mp;
+ mp = (struct mtu_discovery *)(u_char *)&dp->icmp_void;
+ mtu = EXTRACT_16BITS(&mp->nexthopmtu);
+ if (mtu) {
+ (void)snprintf(buf, sizeof(buf),
+ "%s unreachable - need to frag (mtu %d)",
+ ipaddr_string(&dp->icmp_ip.ip_dst), mtu);
+ } else {
+ (void)snprintf(buf, sizeof(buf),
+ "%s unreachable - need to frag",
+ ipaddr_string(&dp->icmp_ip.ip_dst));
+ }
+ }
+ break;
+
+ default:
+ fmt = tok2str(unreach2str, "#%d %%s unreachable",
+ dp->icmp_code);
+ (void)snprintf(buf, sizeof(buf), fmt,
+ ipaddr_string(&dp->icmp_ip.ip_dst));
+ break;
+ }
+ break;
+
+ case ICMP_REDIRECT:
+ TCHECK(dp->icmp_ip.ip_dst);
+ fmt = tok2str(type2str, "redirect-#%d %%s to net %%s",
+ dp->icmp_code);
+ (void)snprintf(buf, sizeof(buf), fmt,
+ ipaddr_string(&dp->icmp_ip.ip_dst),
+ ipaddr_string(&dp->icmp_gwaddr));
+ break;
+
+ case ICMP_ROUTERADVERT:
+ {
+ register const struct ih_rdiscovery *ihp;
+ register const struct id_rdiscovery *idp;
+ u_int lifetime, num, size;
+
+ (void)snprintf(buf, sizeof(buf), "router advertisement");
+ cp = buf + strlen(buf);
+
+ ihp = (struct ih_rdiscovery *)&dp->icmp_void;
+ TCHECK(*ihp);
+ (void)strncpy(cp, " lifetime ", sizeof(buf) - (cp - buf));
+ cp = buf + strlen(buf);
+ lifetime = EXTRACT_16BITS(&ihp->ird_lifetime);
+ if (lifetime < 60) {
+ (void)snprintf(cp, sizeof(buf) - (cp - buf), "%u",
+ lifetime);
+ } else if (lifetime < 60 * 60) {
+ (void)snprintf(cp, sizeof(buf) - (cp - buf), "%u:%02u",
+ lifetime / 60, lifetime % 60);
+ } else {
+ (void)snprintf(cp, sizeof(buf) - (cp - buf),
+ "%u:%02u:%02u",
+ lifetime / 3600,
+ (lifetime % 3600) / 60,
+ lifetime % 60);
+ }
+ cp = buf + strlen(buf);
+
+ num = ihp->ird_addrnum;
+ (void)snprintf(cp, sizeof(buf) - (cp - buf), " %d:", num);
+ cp = buf + strlen(buf);
+
+ size = ihp->ird_addrsiz;
+ if (size != 2) {
+ (void)snprintf(cp, sizeof(buf) - (cp - buf),
+ " [size %d]", size);
+ break;
+ }
+ idp = (struct id_rdiscovery *)&dp->icmp_data;
+ while (num-- > 0) {
+ TCHECK(*idp);
+ (void)snprintf(cp, sizeof(buf) - (cp - buf), " {%s %u}",
+ ipaddr_string(&idp->ird_addr),
+ EXTRACT_32BITS(&idp->ird_pref));
+ cp = buf + strlen(buf);
+ ++idp;
+ }
+ }
+ break;
+
+ case ICMP_TIMXCEED:
+ TCHECK(dp->icmp_ip.ip_dst);
+ switch (dp->icmp_code) {
+
+ case ICMP_TIMXCEED_INTRANS:
+ str = "time exceeded in-transit";
+ break;
+
+ case ICMP_TIMXCEED_REASS:
+ str = "ip reassembly time exceeded";
+ break;
+
+ default:
+ (void)snprintf(buf, sizeof(buf), "time exceeded-#%d",
+ dp->icmp_code);
+ break;
+ }
+ break;
+
+ case ICMP_PARAMPROB:
+ if (dp->icmp_code)
+ (void)snprintf(buf, sizeof(buf),
+ "parameter problem - code %d", dp->icmp_code);
+ else {
+ TCHECK(dp->icmp_pptr);
+ (void)snprintf(buf, sizeof(buf),
+ "parameter problem - octet %d", dp->icmp_pptr);
+ }
+ break;
+
+ case ICMP_MASKREPLY:
+ TCHECK(dp->icmp_mask);
+ (void)snprintf(buf, sizeof(buf), "address mask is 0x%08x",
+ EXTRACT_32BITS(&dp->icmp_mask));
+ break;
+
+ case ICMP_TSTAMP:
+ TCHECK(dp->icmp_seq);
+ (void)snprintf(buf, sizeof(buf),
+ "time stamp query id %u seq %u",
+ EXTRACT_16BITS(&dp->icmp_id),
+ EXTRACT_16BITS(&dp->icmp_seq));
+ break;
+
+ case ICMP_TSTAMPREPLY:
+ TCHECK(dp->icmp_ttime);
+ (void)snprintf(buf, sizeof(buf),
+ "time stamp reply id %u seq %u: org %s",
+ EXTRACT_16BITS(&dp->icmp_id),
+ EXTRACT_16BITS(&dp->icmp_seq),
+ icmp_tstamp_print(EXTRACT_32BITS(&dp->icmp_otime)));
+
+ (void)snprintf(buf+strlen(buf),sizeof(buf)-strlen(buf),", recv %s",
+ icmp_tstamp_print(EXTRACT_32BITS(&dp->icmp_rtime)));
+ (void)snprintf(buf+strlen(buf),sizeof(buf)-strlen(buf),", xmit %s",
+ icmp_tstamp_print(EXTRACT_32BITS(&dp->icmp_ttime)));
+ break;
+
+ default:
+ str = tok2str(icmp2str, "type-#%d", dp->icmp_type);
+ break;
+ }
+ (void)printf("ICMP %s, length %u", str, plen);
+ if (vflag && !fragmented) { /* don't attempt checksumming if this is a frag */
+ u_int16_t sum, icmp_sum;
+ struct cksum_vec vec[1];
+ if (TTEST2(*bp, plen)) {
+ vec[0].ptr = (const u_int8_t *)(void *)dp;
+ vec[0].len = plen;
+ sum = in_cksum(vec, 1);
+ if (sum != 0) {
+ icmp_sum = EXTRACT_16BITS(&dp->icmp_cksum);
+ (void)printf(" (wrong icmp cksum %x (->%x)!)",
+ icmp_sum,
+ in_cksum_shouldbe(icmp_sum, sum));
+ }
+ }
+ }
+
+ /*
+ * print the remnants of the IP packet.
+ * save the snaplength as this may get overidden in the IP printer.
+ */
+ if (vflag >= 1 && !ICMP_INFOTYPE(dp->icmp_type)) {
+ bp += 8;
+ (void)printf("\n\t");
+ ip = (struct ip *)bp;
+ snaplen = snapend - bp;
+ snapend_save = snapend;
+ ip_print(gndo, bp, EXTRACT_16BITS(&ip->ip_len));
+ snapend = snapend_save;
+ }
+
+ /*
+ * Attempt to decode the MPLS extensions only for some ICMP types.
+ */
+ if (vflag >= 1 && plen > ICMP_EXTD_MINLEN && ICMP_MPLS_EXT_TYPE(dp->icmp_type)) {
+
+ TCHECK(*ext_dp);
+
+ /*
+ * Check first if the mpls extension header shows a non-zero length.
+ * If the length field is not set then silently verify the checksum
+ * to check if an extension header is present. This is expedient,
+ * however not all implementations set the length field proper.
+ */
+ if (!ext_dp->icmp_length) {
+ vec[0].ptr = (const u_int8_t *)(void *)&ext_dp->icmp_ext_version_res;
+ vec[0].len = plen - ICMP_EXTD_MINLEN;
+ if (in_cksum(vec, 1)) {
+ return;
+ }
+ }
+
+ printf("\n\tMPLS extension v%u",
+ ICMP_MPLS_EXT_EXTRACT_VERSION(*(ext_dp->icmp_ext_version_res)));
+
+ /*
+ * Sanity checking of the header.
+ */
+ if (ICMP_MPLS_EXT_EXTRACT_VERSION(*(ext_dp->icmp_ext_version_res)) !=
+ ICMP_MPLS_EXT_VERSION) {
+ printf(" packet not supported");
+ return;
+ }
+
+ hlen = plen - ICMP_EXTD_MINLEN;
+ vec[0].ptr = (const u_int8_t *)(void *)&ext_dp->icmp_ext_version_res;
+ vec[0].len = hlen;
+ printf(", checksum 0x%04x (%scorrect), length %u",
+ EXTRACT_16BITS(ext_dp->icmp_ext_checksum),
+ in_cksum(vec, 1) ? "in" : "",
+ hlen);
+
+ hlen -= 4; /* subtract common header size */
+ obj_tptr = (u_int8_t *)ext_dp->icmp_ext_data;
+
+ while (hlen > sizeof(struct icmp_mpls_ext_object_header_t)) {
+
+ icmp_mpls_ext_object_header = (struct icmp_mpls_ext_object_header_t *)obj_tptr;
+ TCHECK(*icmp_mpls_ext_object_header);
+ obj_tlen = EXTRACT_16BITS(icmp_mpls_ext_object_header->length);
+ obj_class_num = icmp_mpls_ext_object_header->class_num;
+ obj_ctype = icmp_mpls_ext_object_header->ctype;
+ obj_tptr += sizeof(struct icmp_mpls_ext_object_header_t);
+
+ printf("\n\t %s Object (%u), Class-Type: %u, length %u",
+ tok2str(icmp_mpls_ext_obj_values,"unknown",obj_class_num),
+ obj_class_num,
+ obj_ctype,
+ obj_tlen);
+
+ hlen-=sizeof(struct icmp_mpls_ext_object_header_t); /* length field includes tlv header */
+
+ /* infinite loop protection */
+ if ((obj_class_num == 0) ||
+ (obj_tlen < sizeof(struct icmp_mpls_ext_object_header_t))) {
+ return;
+ }
+ obj_tlen-=sizeof(struct icmp_mpls_ext_object_header_t);
+
+ switch (obj_class_num) {
+ case 1:
+ switch(obj_ctype) {
+ case 1:
+ TCHECK2(*obj_tptr, 4);
+ raw_label = EXTRACT_32BITS(obj_tptr);
+ printf("\n\t label %u, exp %u", MPLS_LABEL(raw_label), MPLS_EXP(raw_label));
+ if (MPLS_STACK(raw_label))
+ printf(", [S]");
+ printf(", ttl %u", MPLS_TTL(raw_label));
+ break;
+ default:
+ print_unknown_data(obj_tptr, "\n\t ", obj_tlen);
+ }
+ break;
+
+ /*
+ * FIXME those are the defined objects that lack a decoder
+ * you are welcome to contribute code ;-)
+ */
+ case 2:
+ default:
+ print_unknown_data(obj_tptr, "\n\t ", obj_tlen);
+ break;
+ }
+ if (hlen < obj_tlen)
+ break;
+ hlen -= obj_tlen;
+ obj_tptr += obj_tlen;
+ }
+ }
+
+ return;
+trunc:
+ fputs("[|icmp]", stdout);
+}
diff --git a/freebsd/contrib/tcpdump/print-icmp6.c b/freebsd/contrib/tcpdump/print-icmp6.c
new file mode 100644
index 00000000..69a4016c
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-icmp6.c
@@ -0,0 +1,1388 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-icmp6.c,v 1.86 2008-02-05 19:36:13 guy Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef INET6
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+#include "ip6.h"
+#include "icmp6.h"
+#include "ipproto.h"
+
+#include "udp.h"
+#include "ah.h"
+
+static const char *get_rtpref(u_int);
+static const char *get_lifetime(u_int32_t);
+static void print_lladdr(const u_char *, size_t);
+static void icmp6_opt_print(const u_char *, int);
+static void mld6_print(const u_char *);
+static void mldv2_report_print(const u_char *, u_int);
+static void mldv2_query_print(const u_char *, u_int);
+static struct udphdr *get_upperlayer(u_char *, u_int *);
+static void dnsname_print(const u_char *, const u_char *);
+static void icmp6_nodeinfo_print(u_int, const u_char *, const u_char *);
+static void icmp6_rrenum_print(const u_char *, const u_char *);
+
+#ifndef abs
+#define abs(a) ((0 < (a)) ? (a) : -(a))
+#endif
+
+/* inline the various RPL definitions */
+#define ND_RPL_MESSAGE 0x9B
+
+static struct tok icmp6_type_values[] = {
+ { ICMP6_DST_UNREACH, "destination unreachable"},
+ { ICMP6_PACKET_TOO_BIG, "packet too big"},
+ { ICMP6_TIME_EXCEEDED, "time exceeded in-transit"},
+ { ICMP6_PARAM_PROB, "parameter problem"},
+ { ICMP6_ECHO_REQUEST, "echo request"},
+ { ICMP6_ECHO_REPLY, "echo reply"},
+ { MLD6_LISTENER_QUERY, "multicast listener query"},
+ { MLD6_LISTENER_REPORT, "multicast listener report"},
+ { MLD6_LISTENER_DONE, "multicast listener done"},
+ { ND_ROUTER_SOLICIT, "router solicitation"},
+ { ND_ROUTER_ADVERT, "router advertisement"},
+ { ND_NEIGHBOR_SOLICIT, "neighbor solicitation"},
+ { ND_NEIGHBOR_ADVERT, "neighbor advertisement"},
+ { ND_REDIRECT, "redirect"},
+ { ICMP6_ROUTER_RENUMBERING, "router renumbering"},
+ { IND_SOLICIT, "inverse neighbor solicitation"},
+ { IND_ADVERT, "inverse neighbor advertisement"},
+ { MLDV2_LISTENER_REPORT, "multicast listener report v2"},
+ { ICMP6_HADISCOV_REQUEST, "ha discovery request"},
+ { ICMP6_HADISCOV_REPLY, "ha discovery reply"},
+ { ICMP6_MOBILEPREFIX_SOLICIT, "mobile router solicitation"},
+ { ICMP6_MOBILEPREFIX_ADVERT, "mobile router advertisement"},
+ { ICMP6_WRUREQUEST, "who-are-you request"},
+ { ICMP6_WRUREPLY, "who-are-you reply"},
+ { ICMP6_NI_QUERY, "node information query"},
+ { ICMP6_NI_REPLY, "node information reply"},
+ { MLD6_MTRACE, "mtrace message"},
+ { MLD6_MTRACE_RESP, "mtrace response"},
+ { ND_RPL_MESSAGE, "RPL"},
+ { 0, NULL }
+};
+
+static struct tok icmp6_dst_unreach_code_values[] = {
+ { ICMP6_DST_UNREACH_NOROUTE, "unreachable route" },
+ { ICMP6_DST_UNREACH_ADMIN, " unreachable prohibited"},
+ { ICMP6_DST_UNREACH_BEYONDSCOPE, "beyond scope"},
+ { ICMP6_DST_UNREACH_ADDR, "unreachable address"},
+ { ICMP6_DST_UNREACH_NOPORT, "unreachable port"},
+ { 0, NULL }
+};
+
+static struct tok icmp6_opt_pi_flag_values[] = {
+ { ND_OPT_PI_FLAG_ONLINK, "onlink" },
+ { ND_OPT_PI_FLAG_AUTO, "auto" },
+ { ND_OPT_PI_FLAG_ROUTER, "router" },
+ { 0, NULL }
+};
+
+static struct tok icmp6_opt_ra_flag_values[] = {
+ { ND_RA_FLAG_MANAGED, "managed" },
+ { ND_RA_FLAG_OTHER, "other stateful"},
+ { ND_RA_FLAG_HOME_AGENT, "home agent"},
+ { 0, NULL }
+};
+
+static struct tok icmp6_nd_na_flag_values[] = {
+ { ND_NA_FLAG_ROUTER, "router" },
+ { ND_NA_FLAG_SOLICITED, "solicited" },
+ { ND_NA_FLAG_OVERRIDE, "override" },
+ { 0, NULL }
+};
+
+
+static struct tok icmp6_opt_values[] = {
+ { ND_OPT_SOURCE_LINKADDR, "source link-address"},
+ { ND_OPT_TARGET_LINKADDR, "destination link-address"},
+ { ND_OPT_PREFIX_INFORMATION, "prefix info"},
+ { ND_OPT_REDIRECTED_HEADER, "redirected header"},
+ { ND_OPT_MTU, "mtu"},
+ { ND_OPT_RDNSS, "rdnss"},
+ { ND_OPT_DNSSL, "dnssl"},
+ { ND_OPT_ADVINTERVAL, "advertisement interval"},
+ { ND_OPT_HOMEAGENT_INFO, "homeagent information"},
+ { ND_OPT_ROUTE_INFO, "route info"},
+ { 0, NULL }
+};
+
+/* mldv2 report types */
+static struct tok mldv2report2str[] = {
+ { 1, "is_in" },
+ { 2, "is_ex" },
+ { 3, "to_in" },
+ { 4, "to_ex" },
+ { 5, "allow" },
+ { 6, "block" },
+ { 0, NULL }
+};
+
+static const char *
+get_rtpref(u_int v)
+{
+ static const char *rtpref_str[] = {
+ "medium", /* 00 */
+ "high", /* 01 */
+ "rsv", /* 10 */
+ "low" /* 11 */
+ };
+
+ return rtpref_str[((v & ND_RA_FLAG_RTPREF_MASK) >> 3) & 0xff];
+}
+
+static const char *
+get_lifetime(u_int32_t v)
+{
+ static char buf[20];
+
+ if (v == (u_int32_t)~0UL)
+ return "infinity";
+ else {
+ snprintf(buf, sizeof(buf), "%us", v);
+ return buf;
+ }
+}
+
+static void
+print_lladdr(const u_int8_t *p, size_t l)
+{
+ const u_int8_t *ep, *q;
+
+ q = p;
+ ep = p + l;
+ while (l > 0 && q < ep) {
+ if (q > p)
+ printf(":");
+ printf("%02x", *q++);
+ l--;
+ }
+}
+
+static int icmp6_cksum(const struct ip6_hdr *ip6, const struct icmp6_hdr *icp,
+ u_int len)
+{
+ return (nextproto6_cksum(ip6, (const u_int8_t *)(void *)icp, len,
+ IPPROTO_ICMPV6));
+}
+
+enum ND_RPL_CODE {
+ ND_RPL_DIS =0x00,
+ ND_RPL_DIO =0x01,
+ ND_RPL_DAO =0x02,
+ ND_RPL_DAO_ACK=0x03,
+ ND_RPL_SDIS =0x80,
+ ND_RPL_SDIO =0x81,
+ ND_RPL_SDAO =0x82,
+ ND_RPL_SDAO_ACK=0x83,
+ ND_RPL_SCC =0x8A,
+};
+
+enum ND_RPL_DIO_FLAGS {
+ ND_RPL_DIO_GROUNDED = 0x80,
+ ND_RPL_DIO_DATRIG = 0x40,
+ ND_RPL_DIO_DASUPPORT= 0x20,
+ ND_RPL_DIO_RES4 = 0x10,
+ ND_RPL_DIO_RES3 = 0x08,
+ ND_RPL_DIO_PRF_MASK = 0x07, /* 3-bit preference */
+};
+
+struct nd_rpl_dio {
+ u_int8_t rpl_flags;
+ u_int8_t rpl_seq;
+ u_int8_t rpl_instanceid;
+ u_int8_t rpl_dagrank;
+ u_int8_t rpl_dagid[16];
+};
+
+static void
+rpl_print(netdissect_options *ndo,
+ const struct icmp6_hdr *hdr,
+ const u_char *bp, u_int length _U_)
+{
+ struct nd_rpl_dio *dio = (struct nd_rpl_dio *)bp;
+ int secured = hdr->icmp6_code & 0x80;
+ int basecode= hdr->icmp6_code & 0x7f;
+
+ ND_TCHECK(dio->rpl_dagid);
+
+ if(secured) {
+ ND_PRINT((ndo, ", (SEC)"));
+ } else {
+ ND_PRINT((ndo, ", (CLR)"));
+ }
+
+ switch(basecode) {
+ case ND_RPL_DIS:
+ ND_PRINT((ndo, "DODAG Information Solicitation"));
+ if(ndo->ndo_vflag) {
+ }
+ break;
+ case ND_RPL_DIO:
+ ND_PRINT((ndo, "DODAG Information Object"));
+ if(ndo->ndo_vflag) {
+ char dagid[65];
+ char *d = dagid;
+ int i;
+ for(i=0;i<16;i++) {
+ if(isprint(dio->rpl_dagid[i])) {
+ *d++ = dio->rpl_dagid[i];
+ } else {
+ int cnt=snprintf(d,4,"0x%02x",
+ dio->rpl_dagid[i]);
+ d += cnt;
+ }
+ }
+ *d++ = '\0';
+ ND_PRINT((ndo, " [seq:%u,instance:%u,rank:%u,dagid:%s]",
+ dio->rpl_seq,
+ dio->rpl_instanceid,
+ dio->rpl_dagrank,
+ dagid));
+ }
+ break;
+ case ND_RPL_DAO:
+ ND_PRINT((ndo, "Destination Advertisement Object"));
+ if(ndo->ndo_vflag) {
+ }
+ break;
+ case ND_RPL_DAO_ACK:
+ ND_PRINT((ndo, "Destination Advertisement Object Ack"));
+ if(ndo->ndo_vflag) {
+ }
+ break;
+ default:
+ ND_PRINT((ndo, "RPL message, unknown code %u",hdr->icmp6_code));
+ break;
+ }
+ return;
+trunc:
+ ND_PRINT((ndo," [|truncated]"));
+ return;
+
+}
+
+
+void
+icmp6_print(netdissect_options *ndo,
+ const u_char *bp, u_int length, const u_char *bp2, int fragmented)
+{
+ const struct icmp6_hdr *dp;
+ const struct ip6_hdr *ip;
+ const struct ip6_hdr *oip;
+ const struct udphdr *ouh;
+ int dport;
+ const u_char *ep;
+ u_int prot;
+
+ dp = (struct icmp6_hdr *)bp;
+ ip = (struct ip6_hdr *)bp2;
+ oip = (struct ip6_hdr *)(dp + 1);
+ /* 'ep' points to the end of available data. */
+ ep = snapend;
+
+ TCHECK(dp->icmp6_cksum);
+
+ if (vflag && !fragmented) {
+ u_int16_t sum, udp_sum;
+
+ if (TTEST2(bp[0], length)) {
+ udp_sum = EXTRACT_16BITS(&dp->icmp6_cksum);
+ sum = icmp6_cksum(ip, dp, length);
+ if (sum != 0)
+ (void)printf("[bad icmp6 cksum 0x%04x -> 0x%04x!] ",
+ udp_sum,
+ in_cksum_shouldbe(udp_sum, sum));
+ else
+ (void)printf("[icmp6 sum ok] ");
+ }
+ }
+
+ printf("ICMP6, %s", tok2str(icmp6_type_values,"unknown icmp6 type (%u)",dp->icmp6_type));
+
+ /* display cosmetics: print the packet length for printer that use the vflag now */
+ if (vflag && (dp->icmp6_type == ND_ROUTER_SOLICIT ||
+ dp->icmp6_type == ND_ROUTER_ADVERT ||
+ dp->icmp6_type == ND_NEIGHBOR_ADVERT ||
+ dp->icmp6_type == ND_NEIGHBOR_SOLICIT ||
+ dp->icmp6_type == ND_REDIRECT ||
+ dp->icmp6_type == ICMP6_HADISCOV_REPLY ||
+ dp->icmp6_type == ICMP6_MOBILEPREFIX_ADVERT ))
+ printf(", length %u", length);
+
+ switch (dp->icmp6_type) {
+ case ICMP6_DST_UNREACH:
+ TCHECK(oip->ip6_dst);
+ printf(", %s", tok2str(icmp6_dst_unreach_code_values,"unknown unreach code (%u)",dp->icmp6_code));
+ switch (dp->icmp6_code) {
+
+ case ICMP6_DST_UNREACH_NOROUTE: /* fall through */
+ case ICMP6_DST_UNREACH_ADMIN:
+ case ICMP6_DST_UNREACH_ADDR:
+ printf(" %s",ip6addr_string(&oip->ip6_dst));
+ break;
+ case ICMP6_DST_UNREACH_BEYONDSCOPE:
+ printf(" %s, source address %s",
+ ip6addr_string(&oip->ip6_dst),
+ ip6addr_string(&oip->ip6_src));
+ break;
+ case ICMP6_DST_UNREACH_NOPORT:
+ if ((ouh = get_upperlayer((u_char *)oip, &prot))
+ == NULL)
+ goto trunc;
+
+ dport = EXTRACT_16BITS(&ouh->uh_dport);
+ switch (prot) {
+ case IPPROTO_TCP:
+ printf(", %s tcp port %s",
+ ip6addr_string(&oip->ip6_dst),
+ tcpport_string(dport));
+ break;
+ case IPPROTO_UDP:
+ printf(", %s udp port %s",
+ ip6addr_string(&oip->ip6_dst),
+ udpport_string(dport));
+ break;
+ default:
+ printf(", %s protocol %d port %d unreachable",
+ ip6addr_string(&oip->ip6_dst),
+ oip->ip6_nxt, dport);
+ break;
+ }
+ break;
+ default:
+ if (vflag <= 1) {
+ print_unknown_data(bp,"\n\t",length);
+ return;
+ }
+ break;
+ }
+ break;
+ case ICMP6_PACKET_TOO_BIG:
+ TCHECK(dp->icmp6_mtu);
+ printf(", mtu %u", EXTRACT_32BITS(&dp->icmp6_mtu));
+ break;
+ case ICMP6_TIME_EXCEEDED:
+ TCHECK(oip->ip6_dst);
+ switch (dp->icmp6_code) {
+ case ICMP6_TIME_EXCEED_TRANSIT:
+ printf(" for %s",
+ ip6addr_string(&oip->ip6_dst));
+ break;
+ case ICMP6_TIME_EXCEED_REASSEMBLY:
+ printf(" (reassembly)");
+ break;
+ default:
+ printf(", unknown code (%u)", dp->icmp6_code);
+ break;
+ }
+ break;
+ case ICMP6_PARAM_PROB:
+ TCHECK(oip->ip6_dst);
+ switch (dp->icmp6_code) {
+ case ICMP6_PARAMPROB_HEADER:
+ printf(", errorneous - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr));
+ break;
+ case ICMP6_PARAMPROB_NEXTHEADER:
+ printf(", next header - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr));
+ break;
+ case ICMP6_PARAMPROB_OPTION:
+ printf(", option - octet %u", EXTRACT_32BITS(&dp->icmp6_pptr));
+ break;
+ default:
+ printf(", code-#%d",
+ dp->icmp6_code);
+ break;
+ }
+ break;
+ case ICMP6_ECHO_REQUEST:
+ case ICMP6_ECHO_REPLY:
+ TCHECK(dp->icmp6_seq);
+ printf(", seq %u", EXTRACT_16BITS(&dp->icmp6_seq));
+ break;
+ case ICMP6_MEMBERSHIP_QUERY:
+ if (length == MLD_MINLEN) {
+ mld6_print((const u_char *)dp);
+ } else if (length >= MLDV2_MINLEN) {
+ printf(" v2");
+ mldv2_query_print((const u_char *)dp, length);
+ } else {
+ printf(" unknown-version (len %u) ", length);
+ }
+ break;
+ case ICMP6_MEMBERSHIP_REPORT:
+ mld6_print((const u_char *)dp);
+ break;
+ case ICMP6_MEMBERSHIP_REDUCTION:
+ mld6_print((const u_char *)dp);
+ break;
+ case ND_ROUTER_SOLICIT:
+#define RTSOLLEN 8
+ if (vflag) {
+ icmp6_opt_print((const u_char *)dp + RTSOLLEN,
+ length - RTSOLLEN);
+ }
+ break;
+ case ND_ROUTER_ADVERT:
+#define RTADVLEN 16
+ if (vflag) {
+ struct nd_router_advert *p;
+
+ p = (struct nd_router_advert *)dp;
+ TCHECK(p->nd_ra_retransmit);
+ printf("\n\thop limit %u, Flags [%s]" \
+ ", pref %s, router lifetime %us, reachable time %us, retrans time %us",
+ (u_int)p->nd_ra_curhoplimit,
+ bittok2str(icmp6_opt_ra_flag_values,"none",(p->nd_ra_flags_reserved)),
+ get_rtpref(p->nd_ra_flags_reserved),
+ EXTRACT_16BITS(&p->nd_ra_router_lifetime),
+ EXTRACT_32BITS(&p->nd_ra_reachable),
+ EXTRACT_32BITS(&p->nd_ra_retransmit));
+
+ icmp6_opt_print((const u_char *)dp + RTADVLEN,
+ length - RTADVLEN);
+ }
+ break;
+ case ND_NEIGHBOR_SOLICIT:
+ {
+ struct nd_neighbor_solicit *p;
+ p = (struct nd_neighbor_solicit *)dp;
+ TCHECK(p->nd_ns_target);
+ printf(", who has %s", ip6addr_string(&p->nd_ns_target));
+ if (vflag) {
+#define NDSOLLEN 24
+ icmp6_opt_print((const u_char *)dp + NDSOLLEN,
+ length - NDSOLLEN);
+ }
+ }
+ break;
+ case ND_NEIGHBOR_ADVERT:
+ {
+ struct nd_neighbor_advert *p;
+
+ p = (struct nd_neighbor_advert *)dp;
+ TCHECK(p->nd_na_target);
+ printf(", tgt is %s",
+ ip6addr_string(&p->nd_na_target));
+ if (vflag) {
+ printf(", Flags [%s]",
+ bittok2str(icmp6_nd_na_flag_values,
+ "none",
+ EXTRACT_32BITS(&p->nd_na_flags_reserved)));
+#define NDADVLEN 24
+ icmp6_opt_print((const u_char *)dp + NDADVLEN,
+ length - NDADVLEN);
+#undef NDADVLEN
+ }
+ }
+ break;
+ case ND_REDIRECT:
+#define RDR(i) ((struct nd_redirect *)(i))
+ TCHECK(RDR(dp)->nd_rd_dst);
+ printf(", %s", getname6((const u_char *)&RDR(dp)->nd_rd_dst));
+ TCHECK(RDR(dp)->nd_rd_target);
+ printf(" to %s",
+ getname6((const u_char*)&RDR(dp)->nd_rd_target));
+#define REDIRECTLEN 40
+ if (vflag) {
+ icmp6_opt_print((const u_char *)dp + REDIRECTLEN,
+ length - REDIRECTLEN);
+ }
+ break;
+#undef REDIRECTLEN
+#undef RDR
+ case ICMP6_ROUTER_RENUMBERING:
+ icmp6_rrenum_print(bp, ep);
+ break;
+ case ICMP6_NI_QUERY:
+ case ICMP6_NI_REPLY:
+ icmp6_nodeinfo_print(length, bp, ep);
+ break;
+ case IND_SOLICIT:
+ case IND_ADVERT:
+ break;
+ case ICMP6_V2_MEMBERSHIP_REPORT:
+ mldv2_report_print((const u_char *) dp, length);
+ break;
+ case ICMP6_MOBILEPREFIX_SOLICIT: /* fall through */
+ case ICMP6_HADISCOV_REQUEST:
+ TCHECK(dp->icmp6_data16[0]);
+ printf(", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0]));
+ break;
+ case ICMP6_HADISCOV_REPLY:
+ if (vflag) {
+ struct in6_addr *in6;
+ u_char *cp;
+
+ TCHECK(dp->icmp6_data16[0]);
+ printf(", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0]));
+ cp = (u_char *)dp + length;
+ in6 = (struct in6_addr *)(dp + 1);
+ for (; (u_char *)in6 < cp; in6++) {
+ TCHECK(*in6);
+ printf(", %s", ip6addr_string(in6));
+ }
+ }
+ break;
+ case ICMP6_MOBILEPREFIX_ADVERT:
+ if (vflag) {
+ TCHECK(dp->icmp6_data16[0]);
+ printf(", id 0x%04x", EXTRACT_16BITS(&dp->icmp6_data16[0]));
+ if (dp->icmp6_data16[1] & 0xc0)
+ printf(" ");
+ if (dp->icmp6_data16[1] & 0x80)
+ printf("M");
+ if (dp->icmp6_data16[1] & 0x40)
+ printf("O");
+#define MPADVLEN 8
+ icmp6_opt_print((const u_char *)dp + MPADVLEN,
+ length - MPADVLEN);
+ }
+ break;
+ case ND_RPL_MESSAGE:
+ rpl_print(ndo, dp, &dp->icmp6_data8[0], length);
+ break;
+ default:
+ printf(", length %u", length);
+ if (vflag <= 1)
+ print_unknown_data(bp,"\n\t", length);
+ return;
+ }
+ if (!vflag)
+ printf(", length %u", length);
+ return;
+trunc:
+ fputs("[|icmp6]", stdout);
+}
+
+static struct udphdr *
+get_upperlayer(u_char *bp, u_int *prot)
+{
+ const u_char *ep;
+ struct ip6_hdr *ip6 = (struct ip6_hdr *)bp;
+ struct udphdr *uh;
+ struct ip6_hbh *hbh;
+ struct ip6_frag *fragh;
+ struct ah *ah;
+ u_int nh;
+ int hlen;
+
+ /* 'ep' points to the end of available data. */
+ ep = snapend;
+
+ if (!TTEST(ip6->ip6_nxt))
+ return NULL;
+
+ nh = ip6->ip6_nxt;
+ hlen = sizeof(struct ip6_hdr);
+
+ while (bp < ep) {
+ bp += hlen;
+
+ switch(nh) {
+ case IPPROTO_UDP:
+ case IPPROTO_TCP:
+ uh = (struct udphdr *)bp;
+ if (TTEST(uh->uh_dport)) {
+ *prot = nh;
+ return(uh);
+ }
+ else
+ return(NULL);
+ /* NOTREACHED */
+
+ case IPPROTO_HOPOPTS:
+ case IPPROTO_DSTOPTS:
+ case IPPROTO_ROUTING:
+ hbh = (struct ip6_hbh *)bp;
+ if (!TTEST(hbh->ip6h_len))
+ return(NULL);
+ nh = hbh->ip6h_nxt;
+ hlen = (hbh->ip6h_len + 1) << 3;
+ break;
+
+ case IPPROTO_FRAGMENT: /* this should be odd, but try anyway */
+ fragh = (struct ip6_frag *)bp;
+ if (!TTEST(fragh->ip6f_offlg))
+ return(NULL);
+ /* fragments with non-zero offset are meaningless */
+ if ((EXTRACT_16BITS(&fragh->ip6f_offlg) & IP6F_OFF_MASK) != 0)
+ return(NULL);
+ nh = fragh->ip6f_nxt;
+ hlen = sizeof(struct ip6_frag);
+ break;
+
+ case IPPROTO_AH:
+ ah = (struct ah *)bp;
+ if (!TTEST(ah->ah_len))
+ return(NULL);
+ nh = ah->ah_nxt;
+ hlen = (ah->ah_len + 2) << 2;
+ break;
+
+ default: /* unknown or undecodable header */
+ *prot = nh; /* meaningless, but set here anyway */
+ return(NULL);
+ }
+ }
+
+ return(NULL); /* should be notreached, though */
+}
+
+static void
+icmp6_opt_print(const u_char *bp, int resid)
+{
+ const struct nd_opt_hdr *op;
+ const struct nd_opt_hdr *opl; /* why there's no struct? */
+ const struct nd_opt_prefix_info *opp;
+ const struct icmp6_opts_redirect *opr;
+ const struct nd_opt_mtu *opm;
+ const struct nd_opt_rdnss *oprd;
+ const struct nd_opt_dnssl *opds;
+ const struct nd_opt_advinterval *opa;
+ const struct nd_opt_homeagent_info *oph;
+ const struct nd_opt_route_info *opri;
+ const u_char *cp, *ep, *domp;
+ struct in6_addr in6, *in6p;
+ size_t l;
+ u_int i;
+
+#define ECHECK(var) if ((u_char *)&(var) > ep - sizeof(var)) return
+
+ cp = bp;
+ /* 'ep' points to the end of available data. */
+ ep = snapend;
+
+ while (cp < ep) {
+ op = (struct nd_opt_hdr *)cp;
+
+ ECHECK(op->nd_opt_len);
+ if (resid <= 0)
+ return;
+ if (op->nd_opt_len == 0)
+ goto trunc;
+ if (cp + (op->nd_opt_len << 3) > ep)
+ goto trunc;
+
+ printf("\n\t %s option (%u), length %u (%u): ",
+ tok2str(icmp6_opt_values, "unknown", op->nd_opt_type),
+ op->nd_opt_type,
+ op->nd_opt_len << 3,
+ op->nd_opt_len);
+
+ switch (op->nd_opt_type) {
+ case ND_OPT_SOURCE_LINKADDR:
+ opl = (struct nd_opt_hdr *)op;
+ l = (op->nd_opt_len << 3) - 2;
+ print_lladdr(cp + 2, l);
+ break;
+ case ND_OPT_TARGET_LINKADDR:
+ opl = (struct nd_opt_hdr *)op;
+ l = (op->nd_opt_len << 3) - 2;
+ print_lladdr(cp + 2, l);
+ break;
+ case ND_OPT_PREFIX_INFORMATION:
+ opp = (struct nd_opt_prefix_info *)op;
+ TCHECK(opp->nd_opt_pi_prefix);
+ printf("%s/%u%s, Flags [%s], valid time %s",
+ ip6addr_string(&opp->nd_opt_pi_prefix),
+ opp->nd_opt_pi_prefix_len,
+ (op->nd_opt_len != 4) ? "badlen" : "",
+ bittok2str(icmp6_opt_pi_flag_values, "none", opp->nd_opt_pi_flags_reserved),
+ get_lifetime(EXTRACT_32BITS(&opp->nd_opt_pi_valid_time)));
+ printf(", pref. time %s", get_lifetime(EXTRACT_32BITS(&opp->nd_opt_pi_preferred_time)));
+ break;
+ case ND_OPT_REDIRECTED_HEADER:
+ opr = (struct icmp6_opts_redirect *)op;
+ print_unknown_data(bp,"\n\t ",op->nd_opt_len<<3);
+ /* xxx */
+ break;
+ case ND_OPT_MTU:
+ opm = (struct nd_opt_mtu *)op;
+ TCHECK(opm->nd_opt_mtu_mtu);
+ printf(" %u%s",
+ EXTRACT_32BITS(&opm->nd_opt_mtu_mtu),
+ (op->nd_opt_len != 1) ? "bad option length" : "" );
+ break;
+ case ND_OPT_RDNSS:
+ oprd = (struct nd_opt_rdnss *)op;
+ l = (op->nd_opt_len - 1) / 2;
+ printf(" lifetime %us,",
+ EXTRACT_32BITS(&oprd->nd_opt_rdnss_lifetime));
+ for (i = 0; i < l; i++) {
+ TCHECK(oprd->nd_opt_rdnss_addr[i]);
+ printf(" addr: %s",
+ ip6addr_string(&oprd->nd_opt_rdnss_addr[i]));
+ }
+ break;
+ case ND_OPT_DNSSL:
+ opds = (struct nd_opt_dnssl *)op;
+ printf(" lifetime %us, domain(s):",
+ EXTRACT_32BITS(&opds->nd_opt_dnssl_lifetime));
+ domp = cp + 8; /* domain names, variable-sized, RFC1035-encoded */
+ while (domp < cp + (op->nd_opt_len << 3) && *domp != '\0')
+ {
+ printf (" ");
+ if ((domp = ns_nprint (domp, bp)) == NULL)
+ goto trunc;
+ }
+ break;
+ case ND_OPT_ADVINTERVAL:
+ opa = (struct nd_opt_advinterval *)op;
+ TCHECK(opa->nd_opt_adv_interval);
+ printf(" %ums", EXTRACT_32BITS(&opa->nd_opt_adv_interval));
+ break;
+ case ND_OPT_HOMEAGENT_INFO:
+ oph = (struct nd_opt_homeagent_info *)op;
+ TCHECK(oph->nd_opt_hai_lifetime);
+ printf(" preference %u, lifetime %u",
+ EXTRACT_16BITS(&oph->nd_opt_hai_preference),
+ EXTRACT_16BITS(&oph->nd_opt_hai_lifetime));
+ break;
+ case ND_OPT_ROUTE_INFO:
+ opri = (struct nd_opt_route_info *)op;
+ TCHECK(opri->nd_opt_rti_lifetime);
+ memset(&in6, 0, sizeof(in6));
+ in6p = (struct in6_addr *)(opri + 1);
+ switch (op->nd_opt_len) {
+ case 1:
+ break;
+ case 2:
+ TCHECK2(*in6p, 8);
+ memcpy(&in6, opri + 1, 8);
+ break;
+ case 3:
+ TCHECK(*in6p);
+ memcpy(&in6, opri + 1, sizeof(in6));
+ break;
+ default:
+ goto trunc;
+ }
+ printf(" %s/%u", ip6addr_string(&in6),
+ opri->nd_opt_rti_prefixlen);
+ printf(", pref=%s", get_rtpref(opri->nd_opt_rti_flags));
+ printf(", lifetime=%s",
+ get_lifetime(EXTRACT_32BITS(&opri->nd_opt_rti_lifetime)));
+ break;
+ default:
+ if (vflag <= 1) {
+ print_unknown_data(cp+2,"\n\t ", (op->nd_opt_len << 3) - 2); /* skip option header */
+ return;
+ }
+ break;
+ }
+ /* do we want to see an additional hexdump ? */
+ if (vflag> 1)
+ print_unknown_data(cp+2,"\n\t ", (op->nd_opt_len << 3) - 2); /* skip option header */
+
+ cp += op->nd_opt_len << 3;
+ resid -= op->nd_opt_len << 3;
+ }
+ return;
+
+ trunc:
+ fputs("[ndp opt]", stdout);
+ return;
+#undef ECHECK
+}
+
+static void
+mld6_print(const u_char *bp)
+{
+ struct mld6_hdr *mp = (struct mld6_hdr *)bp;
+ const u_char *ep;
+
+ /* 'ep' points to the end of available data. */
+ ep = snapend;
+
+ if ((u_char *)mp + sizeof(*mp) > ep)
+ return;
+
+ printf("max resp delay: %d ", EXTRACT_16BITS(&mp->mld6_maxdelay));
+ printf("addr: %s", ip6addr_string(&mp->mld6_addr));
+}
+
+static void
+mldv2_report_print(const u_char *bp, u_int len)
+{
+ struct icmp6_hdr *icp = (struct icmp6_hdr *) bp;
+ u_int group, nsrcs, ngroups;
+ u_int i, j;
+
+ /* Minimum len is 8 */
+ if (len < 8) {
+ printf(" [invalid len %d]", len);
+ return;
+ }
+
+ TCHECK(icp->icmp6_data16[1]);
+ ngroups = EXTRACT_16BITS(&icp->icmp6_data16[1]);
+ printf(", %d group record(s)", ngroups);
+ if (vflag > 0) {
+ /* Print the group records */
+ group = 8;
+ for (i = 0; i < ngroups; i++) {
+ /* type(1) + auxlen(1) + numsrc(2) + grp(16) */
+ if (len < group + 20) {
+ printf(" [invalid number of groups]");
+ return;
+ }
+ TCHECK2(bp[group + 4], sizeof(struct in6_addr));
+ printf(" [gaddr %s", ip6addr_string(&bp[group + 4]));
+ printf(" %s", tok2str(mldv2report2str, " [v2-report-#%d]",
+ bp[group]));
+ nsrcs = (bp[group + 2] << 8) + bp[group + 3];
+ /* Check the number of sources and print them */
+ if (len < group + 20 + (nsrcs * sizeof(struct in6_addr))) {
+ printf(" [invalid number of sources %d]", nsrcs);
+ return;
+ }
+ if (vflag == 1)
+ printf(", %d source(s)", nsrcs);
+ else {
+ /* Print the sources */
+ (void)printf(" {");
+ for (j = 0; j < nsrcs; j++) {
+ TCHECK2(bp[group + 20 + j * sizeof(struct in6_addr)],
+ sizeof(struct in6_addr));
+ printf(" %s", ip6addr_string(&bp[group + 20 + j * sizeof(struct in6_addr)]));
+ }
+ (void)printf(" }");
+ }
+ /* Next group record */
+ group += 20 + nsrcs * sizeof(struct in6_addr);
+ printf("]");
+ }
+ }
+ return;
+trunc:
+ (void)printf("[|icmp6]");
+ return;
+}
+
+static void
+mldv2_query_print(const u_char *bp, u_int len)
+{
+ struct icmp6_hdr *icp = (struct icmp6_hdr *) bp;
+ u_int mrc;
+ int mrt, qqi;
+ u_int nsrcs;
+ register u_int i;
+
+ /* Minimum len is 28 */
+ if (len < 28) {
+ printf(" [invalid len %d]", len);
+ return;
+ }
+ TCHECK(icp->icmp6_data16[0]);
+ mrc = EXTRACT_16BITS(&icp->icmp6_data16[0]);
+ if (mrc < 32768) {
+ mrt = mrc;
+ } else {
+ mrt = ((mrc & 0x0fff) | 0x1000) << (((mrc & 0x7000) >> 12) + 3);
+ }
+ if (vflag) {
+ (void)printf(" [max resp delay=%d]", mrt);
+ }
+ TCHECK2(bp[8], sizeof(struct in6_addr));
+ printf(" [gaddr %s", ip6addr_string(&bp[8]));
+
+ if (vflag) {
+ TCHECK(bp[25]);
+ if (bp[24] & 0x08) {
+ printf(" sflag");
+ }
+ if (bp[24] & 0x07) {
+ printf(" robustness=%d", bp[24] & 0x07);
+ }
+ if (bp[25] < 128) {
+ qqi = bp[25];
+ } else {
+ qqi = ((bp[25] & 0x0f) | 0x10) << (((bp[25] & 0x70) >> 4) + 3);
+ }
+ printf(" qqi=%d", qqi);
+ }
+
+ TCHECK2(bp[26], 2);
+ nsrcs = EXTRACT_16BITS(&bp[26]);
+ if (nsrcs > 0) {
+ if (len < 28 + nsrcs * sizeof(struct in6_addr))
+ printf(" [invalid number of sources]");
+ else if (vflag > 1) {
+ printf(" {");
+ for (i = 0; i < nsrcs; i++) {
+ TCHECK2(bp[28 + i * sizeof(struct in6_addr)],
+ sizeof(struct in6_addr));
+ printf(" %s", ip6addr_string(&bp[28 + i * sizeof(struct in6_addr)]));
+ }
+ printf(" }");
+ } else
+ printf(", %d source(s)", nsrcs);
+ }
+ printf("]");
+ return;
+trunc:
+ (void)printf("[|icmp6]");
+ return;
+}
+
+static void
+dnsname_print(const u_char *cp, const u_char *ep)
+{
+ int i;
+
+ /* DNS name decoding - no decompression */
+ printf(", \"");
+ while (cp < ep) {
+ i = *cp++;
+ if (i) {
+ if (i > ep - cp) {
+ printf("???");
+ break;
+ }
+ while (i-- && cp < ep) {
+ safeputchar(*cp);
+ cp++;
+ }
+ if (cp + 1 < ep && *cp)
+ printf(".");
+ } else {
+ if (cp == ep) {
+ /* FQDN */
+ printf(".");
+ } else if (cp + 1 == ep && *cp == '\0') {
+ /* truncated */
+ } else {
+ /* invalid */
+ printf("???");
+ }
+ break;
+ }
+ }
+ printf("\"");
+}
+
+static void
+icmp6_nodeinfo_print(u_int icmp6len, const u_char *bp, const u_char *ep)
+{
+ struct icmp6_nodeinfo *ni6;
+ struct icmp6_hdr *dp;
+ const u_char *cp;
+ size_t siz, i;
+ int needcomma;
+
+ if (ep < bp)
+ return;
+ dp = (struct icmp6_hdr *)bp;
+ ni6 = (struct icmp6_nodeinfo *)bp;
+ siz = ep - bp;
+
+ switch (ni6->ni_type) {
+ case ICMP6_NI_QUERY:
+ if (siz == sizeof(*dp) + 4) {
+ /* KAME who-are-you */
+ printf(" who-are-you request");
+ break;
+ }
+ printf(" node information query");
+
+ TCHECK2(*dp, sizeof(*ni6));
+ ni6 = (struct icmp6_nodeinfo *)dp;
+ printf(" ("); /*)*/
+ switch (EXTRACT_16BITS(&ni6->ni_qtype)) {
+ case NI_QTYPE_NOOP:
+ printf("noop");
+ break;
+ case NI_QTYPE_SUPTYPES:
+ printf("supported qtypes");
+ i = EXTRACT_16BITS(&ni6->ni_flags);
+ if (i)
+ printf(" [%s]", (i & 0x01) ? "C" : "");
+ break;
+ break;
+ case NI_QTYPE_FQDN:
+ printf("DNS name");
+ break;
+ case NI_QTYPE_NODEADDR:
+ printf("node addresses");
+ i = ni6->ni_flags;
+ if (!i)
+ break;
+ /* NI_NODEADDR_FLAG_TRUNCATE undefined for query */
+ printf(" [%s%s%s%s%s%s]",
+ (i & NI_NODEADDR_FLAG_ANYCAST) ? "a" : "",
+ (i & NI_NODEADDR_FLAG_GLOBAL) ? "G" : "",
+ (i & NI_NODEADDR_FLAG_SITELOCAL) ? "S" : "",
+ (i & NI_NODEADDR_FLAG_LINKLOCAL) ? "L" : "",
+ (i & NI_NODEADDR_FLAG_COMPAT) ? "C" : "",
+ (i & NI_NODEADDR_FLAG_ALL) ? "A" : "");
+ break;
+ default:
+ printf("unknown");
+ break;
+ }
+
+ if (ni6->ni_qtype == NI_QTYPE_NOOP ||
+ ni6->ni_qtype == NI_QTYPE_SUPTYPES) {
+ if (siz != sizeof(*ni6))
+ if (vflag)
+ printf(", invalid len");
+ /*(*/
+ printf(")");
+ break;
+ }
+
+
+ /* XXX backward compat, icmp-name-lookup-03 */
+ if (siz == sizeof(*ni6)) {
+ printf(", 03 draft");
+ /*(*/
+ printf(")");
+ break;
+ }
+
+ switch (ni6->ni_code) {
+ case ICMP6_NI_SUBJ_IPV6:
+ if (!TTEST2(*dp,
+ sizeof(*ni6) + sizeof(struct in6_addr)))
+ break;
+ if (siz != sizeof(*ni6) + sizeof(struct in6_addr)) {
+ if (vflag)
+ printf(", invalid subject len");
+ break;
+ }
+ printf(", subject=%s",
+ getname6((const u_char *)(ni6 + 1)));
+ break;
+ case ICMP6_NI_SUBJ_FQDN:
+ printf(", subject=DNS name");
+ cp = (const u_char *)(ni6 + 1);
+ if (cp[0] == ep - cp - 1) {
+ /* icmp-name-lookup-03, pascal string */
+ if (vflag)
+ printf(", 03 draft");
+ cp++;
+ printf(", \"");
+ while (cp < ep) {
+ safeputchar(*cp);
+ cp++;
+ }
+ printf("\"");
+ } else
+ dnsname_print(cp, ep);
+ break;
+ case ICMP6_NI_SUBJ_IPV4:
+ if (!TTEST2(*dp, sizeof(*ni6) + sizeof(struct in_addr)))
+ break;
+ if (siz != sizeof(*ni6) + sizeof(struct in_addr)) {
+ if (vflag)
+ printf(", invalid subject len");
+ break;
+ }
+ printf(", subject=%s",
+ getname((const u_char *)(ni6 + 1)));
+ break;
+ default:
+ printf(", unknown subject");
+ break;
+ }
+
+ /*(*/
+ printf(")");
+ break;
+
+ case ICMP6_NI_REPLY:
+ if (icmp6len > siz) {
+ printf("[|icmp6: node information reply]");
+ break;
+ }
+
+ needcomma = 0;
+
+ ni6 = (struct icmp6_nodeinfo *)dp;
+ printf(" node information reply");
+ printf(" ("); /*)*/
+ switch (ni6->ni_code) {
+ case ICMP6_NI_SUCCESS:
+ if (vflag) {
+ printf("success");
+ needcomma++;
+ }
+ break;
+ case ICMP6_NI_REFUSED:
+ printf("refused");
+ needcomma++;
+ if (siz != sizeof(*ni6))
+ if (vflag)
+ printf(", invalid length");
+ break;
+ case ICMP6_NI_UNKNOWN:
+ printf("unknown");
+ needcomma++;
+ if (siz != sizeof(*ni6))
+ if (vflag)
+ printf(", invalid length");
+ break;
+ }
+
+ if (ni6->ni_code != ICMP6_NI_SUCCESS) {
+ /*(*/
+ printf(")");
+ break;
+ }
+
+ switch (EXTRACT_16BITS(&ni6->ni_qtype)) {
+ case NI_QTYPE_NOOP:
+ if (needcomma)
+ printf(", ");
+ printf("noop");
+ if (siz != sizeof(*ni6))
+ if (vflag)
+ printf(", invalid length");
+ break;
+ case NI_QTYPE_SUPTYPES:
+ if (needcomma)
+ printf(", ");
+ printf("supported qtypes");
+ i = EXTRACT_16BITS(&ni6->ni_flags);
+ if (i)
+ printf(" [%s]", (i & 0x01) ? "C" : "");
+ break;
+ case NI_QTYPE_FQDN:
+ if (needcomma)
+ printf(", ");
+ printf("DNS name");
+ cp = (const u_char *)(ni6 + 1) + 4;
+ if (cp[0] == ep - cp - 1) {
+ /* icmp-name-lookup-03, pascal string */
+ if (vflag)
+ printf(", 03 draft");
+ cp++;
+ printf(", \"");
+ while (cp < ep) {
+ safeputchar(*cp);
+ cp++;
+ }
+ printf("\"");
+ } else
+ dnsname_print(cp, ep);
+ if ((EXTRACT_16BITS(&ni6->ni_flags) & 0x01) != 0)
+ printf(" [TTL=%u]", *(u_int32_t *)(ni6 + 1));
+ break;
+ case NI_QTYPE_NODEADDR:
+ if (needcomma)
+ printf(", ");
+ printf("node addresses");
+ i = sizeof(*ni6);
+ while (i < siz) {
+ if (i + sizeof(struct in6_addr) + sizeof(int32_t) > siz)
+ break;
+ printf(" %s", getname6(bp + i));
+ i += sizeof(struct in6_addr);
+ printf("(%d)", (int32_t)EXTRACT_32BITS(bp + i));
+ i += sizeof(int32_t);
+ }
+ i = ni6->ni_flags;
+ if (!i)
+ break;
+ printf(" [%s%s%s%s%s%s%s]",
+ (i & NI_NODEADDR_FLAG_ANYCAST) ? "a" : "",
+ (i & NI_NODEADDR_FLAG_GLOBAL) ? "G" : "",
+ (i & NI_NODEADDR_FLAG_SITELOCAL) ? "S" : "",
+ (i & NI_NODEADDR_FLAG_LINKLOCAL) ? "L" : "",
+ (i & NI_NODEADDR_FLAG_COMPAT) ? "C" : "",
+ (i & NI_NODEADDR_FLAG_ALL) ? "A" : "",
+ (i & NI_NODEADDR_FLAG_TRUNCATE) ? "T" : "");
+ break;
+ default:
+ if (needcomma)
+ printf(", ");
+ printf("unknown");
+ break;
+ }
+
+ /*(*/
+ printf(")");
+ break;
+ }
+ return;
+
+trunc:
+ fputs("[|icmp6]", stdout);
+}
+
+static void
+icmp6_rrenum_print(const u_char *bp, const u_char *ep)
+{
+ struct icmp6_router_renum *rr6;
+ const char *cp;
+ struct rr_pco_match *match;
+ struct rr_pco_use *use;
+ char hbuf[NI_MAXHOST];
+ int n;
+
+ if (ep < bp)
+ return;
+ rr6 = (struct icmp6_router_renum *)bp;
+ cp = (const char *)(rr6 + 1);
+
+ TCHECK(rr6->rr_reserved);
+ switch (rr6->rr_code) {
+ case ICMP6_ROUTER_RENUMBERING_COMMAND:
+ printf("router renum: command");
+ break;
+ case ICMP6_ROUTER_RENUMBERING_RESULT:
+ printf("router renum: result");
+ break;
+ case ICMP6_ROUTER_RENUMBERING_SEQNUM_RESET:
+ printf("router renum: sequence number reset");
+ break;
+ default:
+ printf("router renum: code-#%d", rr6->rr_code);
+ break;
+ }
+
+ printf(", seq=%u", EXTRACT_32BITS(&rr6->rr_seqnum));
+
+ if (vflag) {
+#define F(x, y) ((rr6->rr_flags) & (x) ? (y) : "")
+ printf("["); /*]*/
+ if (rr6->rr_flags) {
+ printf("%s%s%s%s%s,", F(ICMP6_RR_FLAGS_TEST, "T"),
+ F(ICMP6_RR_FLAGS_REQRESULT, "R"),
+ F(ICMP6_RR_FLAGS_FORCEAPPLY, "A"),
+ F(ICMP6_RR_FLAGS_SPECSITE, "S"),
+ F(ICMP6_RR_FLAGS_PREVDONE, "P"));
+ }
+ printf("seg=%u,", rr6->rr_segnum);
+ printf("maxdelay=%u", EXTRACT_16BITS(&rr6->rr_maxdelay));
+ if (rr6->rr_reserved)
+ printf("rsvd=0x%x", EXTRACT_32BITS(&rr6->rr_reserved));
+ /*[*/
+ printf("]");
+#undef F
+ }
+
+ if (rr6->rr_code == ICMP6_ROUTER_RENUMBERING_COMMAND) {
+ match = (struct rr_pco_match *)cp;
+ cp = (const char *)(match + 1);
+
+ TCHECK(match->rpm_prefix);
+
+ if (vflag > 1)
+ printf("\n\t");
+ else
+ printf(" ");
+ printf("match("); /*)*/
+ switch (match->rpm_code) {
+ case RPM_PCO_ADD: printf("add"); break;
+ case RPM_PCO_CHANGE: printf("change"); break;
+ case RPM_PCO_SETGLOBAL: printf("setglobal"); break;
+ default: printf("#%u", match->rpm_code); break;
+ }
+
+ if (vflag) {
+ printf(",ord=%u", match->rpm_ordinal);
+ printf(",min=%u", match->rpm_minlen);
+ printf(",max=%u", match->rpm_maxlen);
+ }
+ if (inet_ntop(AF_INET6, &match->rpm_prefix, hbuf, sizeof(hbuf)))
+ printf(",%s/%u", hbuf, match->rpm_matchlen);
+ else
+ printf(",?/%u", match->rpm_matchlen);
+ /*(*/
+ printf(")");
+
+ n = match->rpm_len - 3;
+ if (n % 4)
+ goto trunc;
+ n /= 4;
+ while (n-- > 0) {
+ use = (struct rr_pco_use *)cp;
+ cp = (const char *)(use + 1);
+
+ TCHECK(use->rpu_prefix);
+
+ if (vflag > 1)
+ printf("\n\t");
+ else
+ printf(" ");
+ printf("use("); /*)*/
+ if (use->rpu_flags) {
+#define F(x, y) ((use->rpu_flags) & (x) ? (y) : "")
+ printf("%s%s,",
+ F(ICMP6_RR_PCOUSE_FLAGS_DECRVLTIME, "V"),
+ F(ICMP6_RR_PCOUSE_FLAGS_DECRPLTIME, "P"));
+#undef F
+ }
+ if (vflag) {
+ printf("mask=0x%x,", use->rpu_ramask);
+ printf("raflags=0x%x,", use->rpu_raflags);
+ if (~use->rpu_vltime == 0)
+ printf("vltime=infty,");
+ else
+ printf("vltime=%u,",
+ EXTRACT_32BITS(&use->rpu_vltime));
+ if (~use->rpu_pltime == 0)
+ printf("pltime=infty,");
+ else
+ printf("pltime=%u,",
+ EXTRACT_32BITS(&use->rpu_pltime));
+ }
+ if (inet_ntop(AF_INET6, &use->rpu_prefix, hbuf,
+ sizeof(hbuf)))
+ printf("%s/%u/%u", hbuf, use->rpu_uselen,
+ use->rpu_keeplen);
+ else
+ printf("?/%u/%u", use->rpu_uselen,
+ use->rpu_keeplen);
+ /*(*/
+ printf(")");
+ }
+ }
+
+ return;
+
+trunc:
+ fputs("[|icmp6]", stdout);
+}
+
+#endif /* INET6 */
diff --git a/freebsd/contrib/tcpdump/print-igmp.c b/freebsd/contrib/tcpdump/print-igmp.c
new file mode 100644
index 00000000..e2bc597e
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-igmp.c
@@ -0,0 +1,346 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-igmp.c,v 1.15 2004-03-24 00:59:16 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h" /* must come after interface.h */
+
+#ifndef IN_CLASSD
+#define IN_CLASSD(i) (((int32_t)(i) & 0xf0000000) == 0xe0000000)
+#endif
+
+/* (following from ipmulti/mrouted/prune.h) */
+
+/*
+ * The packet format for a traceroute request.
+ */
+struct tr_query {
+ u_int32_t tr_src; /* traceroute source */
+ u_int32_t tr_dst; /* traceroute destination */
+ u_int32_t tr_raddr; /* traceroute response address */
+ u_int32_t tr_rttlqid; /* response ttl and qid */
+};
+
+#define TR_GETTTL(x) (int)(((x) >> 24) & 0xff)
+#define TR_GETQID(x) ((x) & 0x00ffffff)
+
+/*
+ * Traceroute response format. A traceroute response has a tr_query at the
+ * beginning, followed by one tr_resp for each hop taken.
+ */
+struct tr_resp {
+ u_int32_t tr_qarr; /* query arrival time */
+ u_int32_t tr_inaddr; /* incoming interface address */
+ u_int32_t tr_outaddr; /* outgoing interface address */
+ u_int32_t tr_rmtaddr; /* parent address in source tree */
+ u_int32_t tr_vifin; /* input packet count on interface */
+ u_int32_t tr_vifout; /* output packet count on interface */
+ u_int32_t tr_pktcnt; /* total incoming packets for src-grp */
+ u_int8_t tr_rproto; /* routing proto deployed on router */
+ u_int8_t tr_fttl; /* ttl required to forward on outvif */
+ u_int8_t tr_smask; /* subnet mask for src addr */
+ u_int8_t tr_rflags; /* forwarding error codes */
+};
+
+/* defs within mtrace */
+#define TR_QUERY 1
+#define TR_RESP 2
+
+/* fields for tr_rflags (forwarding error codes) */
+#define TR_NO_ERR 0
+#define TR_WRONG_IF 1
+#define TR_PRUNED 2
+#define TR_OPRUNED 3
+#define TR_SCOPED 4
+#define TR_NO_RTE 5
+#define TR_NO_FWD 7
+#define TR_NO_SPACE 0x81
+#define TR_OLD_ROUTER 0x82
+
+/* fields for tr_rproto (routing protocol) */
+#define TR_PROTO_DVMRP 1
+#define TR_PROTO_MOSPF 2
+#define TR_PROTO_PIM 3
+#define TR_PROTO_CBT 4
+
+/* igmpv3 report types */
+static struct tok igmpv3report2str[] = {
+ { 1, "is_in" },
+ { 2, "is_ex" },
+ { 3, "to_in" },
+ { 4, "to_ex" },
+ { 5, "allow" },
+ { 6, "block" },
+ { 0, NULL }
+};
+
+static void
+print_mtrace(register const u_char *bp, register u_int len)
+{
+ register const struct tr_query *tr = (const struct tr_query *)(bp + 8);
+
+ TCHECK(*tr);
+ if (len < 8 + sizeof (struct tr_query)) {
+ (void)printf(" [invalid len %d]", len);
+ return;
+ }
+ printf("mtrace %u: %s to %s reply-to %s",
+ TR_GETQID(EXTRACT_32BITS(&tr->tr_rttlqid)),
+ ipaddr_string(&tr->tr_src), ipaddr_string(&tr->tr_dst),
+ ipaddr_string(&tr->tr_raddr));
+ if (IN_CLASSD(EXTRACT_32BITS(&tr->tr_raddr)))
+ printf(" with-ttl %d", TR_GETTTL(EXTRACT_32BITS(&tr->tr_rttlqid)));
+ return;
+trunc:
+ (void)printf("[|igmp]");
+ return;
+}
+
+static void
+print_mresp(register const u_char *bp, register u_int len)
+{
+ register const struct tr_query *tr = (const struct tr_query *)(bp + 8);
+
+ TCHECK(*tr);
+ if (len < 8 + sizeof (struct tr_query)) {
+ (void)printf(" [invalid len %d]", len);
+ return;
+ }
+ printf("mresp %lu: %s to %s reply-to %s",
+ (u_long)TR_GETQID(EXTRACT_32BITS(&tr->tr_rttlqid)),
+ ipaddr_string(&tr->tr_src), ipaddr_string(&tr->tr_dst),
+ ipaddr_string(&tr->tr_raddr));
+ if (IN_CLASSD(EXTRACT_32BITS(&tr->tr_raddr)))
+ printf(" with-ttl %d", TR_GETTTL(EXTRACT_32BITS(&tr->tr_rttlqid)));
+ return;
+trunc:
+ (void)printf("[|igmp]");
+ return;
+}
+
+static void
+print_igmpv3_report(register const u_char *bp, register u_int len)
+{
+ u_int group, nsrcs, ngroups;
+ register u_int i, j;
+
+ /* Minimum len is 16, and should be a multiple of 4 */
+ if (len < 16 || len & 0x03) {
+ (void)printf(" [invalid len %d]", len);
+ return;
+ }
+ TCHECK2(bp[6], 2);
+ ngroups = EXTRACT_16BITS(&bp[6]);
+ (void)printf(", %d group record(s)", ngroups);
+ if (vflag > 0) {
+ /* Print the group records */
+ group = 8;
+ for (i=0; i<ngroups; i++) {
+ if (len < group+8) {
+ (void)printf(" [invalid number of groups]");
+ return;
+ }
+ TCHECK2(bp[group+4], 4);
+ (void)printf(" [gaddr %s", ipaddr_string(&bp[group+4]));
+ (void)printf(" %s", tok2str(igmpv3report2str, " [v3-report-#%d]",
+ bp[group]));
+ nsrcs = EXTRACT_16BITS(&bp[group+2]);
+ /* Check the number of sources and print them */
+ if (len < group+8+(nsrcs<<2)) {
+ (void)printf(" [invalid number of sources %d]", nsrcs);
+ return;
+ }
+ if (vflag == 1)
+ (void)printf(", %d source(s)", nsrcs);
+ else {
+ /* Print the sources */
+ (void)printf(" {");
+ for (j=0; j<nsrcs; j++) {
+ TCHECK2(bp[group+8+(j<<2)], 4);
+ (void)printf(" %s", ipaddr_string(&bp[group+8+(j<<2)]));
+ }
+ (void)printf(" }");
+ }
+ /* Next group record */
+ group += 8 + (nsrcs << 2);
+ (void)printf("]");
+ }
+ }
+ return;
+trunc:
+ (void)printf("[|igmp]");
+ return;
+}
+
+static void
+print_igmpv3_query(register const u_char *bp, register u_int len)
+{
+ u_int mrc;
+ int mrt;
+ u_int nsrcs;
+ register u_int i;
+
+ (void)printf(" v3");
+ /* Minimum len is 12, and should be a multiple of 4 */
+ if (len < 12 || len & 0x03) {
+ (void)printf(" [invalid len %d]", len);
+ return;
+ }
+ TCHECK(bp[1]);
+ mrc = bp[1];
+ if (mrc < 128) {
+ mrt = mrc;
+ } else {
+ mrt = ((mrc & 0x0f) | 0x10) << (((mrc & 0x70) >> 4) + 3);
+ }
+ if (mrc != 100) {
+ (void)printf(" [max resp time ");
+ if (mrt < 600) {
+ (void)printf("%.1fs", mrt * 0.1);
+ } else {
+ relts_print(mrt / 10);
+ }
+ (void)printf("]");
+ }
+ TCHECK2(bp[4], 4);
+ if (EXTRACT_32BITS(&bp[4]) == 0)
+ return;
+ (void)printf(" [gaddr %s", ipaddr_string(&bp[4]));
+ TCHECK2(bp[10], 2);
+ nsrcs = EXTRACT_16BITS(&bp[10]);
+ if (nsrcs > 0) {
+ if (len < 12 + (nsrcs << 2))
+ (void)printf(" [invalid number of sources]");
+ else if (vflag > 1) {
+ (void)printf(" {");
+ for (i=0; i<nsrcs; i++) {
+ TCHECK2(bp[12+(i<<2)], 4);
+ (void)printf(" %s", ipaddr_string(&bp[12+(i<<2)]));
+ }
+ (void)printf(" }");
+ } else
+ (void)printf(", %d source(s)", nsrcs);
+ }
+ (void)printf("]");
+ return;
+trunc:
+ (void)printf("[|igmp]");
+ return;
+}
+
+void
+igmp_print(register const u_char *bp, register u_int len)
+{
+ struct cksum_vec vec[1];
+
+ if (qflag) {
+ (void)printf("igmp");
+ return;
+ }
+
+ TCHECK(bp[0]);
+ switch (bp[0]) {
+ case 0x11:
+ (void)printf("igmp query");
+ if (len >= 12)
+ print_igmpv3_query(bp, len);
+ else {
+ TCHECK(bp[1]);
+ if (bp[1]) {
+ (void)printf(" v2");
+ if (bp[1] != 100)
+ (void)printf(" [max resp time %d]", bp[1]);
+ } else
+ (void)printf(" v1");
+ TCHECK2(bp[4], 4);
+ if (EXTRACT_32BITS(&bp[4]))
+ (void)printf(" [gaddr %s]", ipaddr_string(&bp[4]));
+ if (len != 8)
+ (void)printf(" [len %d]", len);
+ }
+ break;
+ case 0x12:
+ TCHECK2(bp[4], 4);
+ (void)printf("igmp v1 report %s", ipaddr_string(&bp[4]));
+ if (len != 8)
+ (void)printf(" [len %d]", len);
+ break;
+ case 0x16:
+ TCHECK2(bp[4], 4);
+ (void)printf("igmp v2 report %s", ipaddr_string(&bp[4]));
+ break;
+ case 0x22:
+ (void)printf("igmp v3 report");
+ print_igmpv3_report(bp, len);
+ break;
+ case 0x17:
+ TCHECK2(bp[4], 4);
+ (void)printf("igmp leave %s", ipaddr_string(&bp[4]));
+ break;
+ case 0x13:
+ (void)printf("igmp dvmrp");
+ if (len < 8)
+ (void)printf(" [len %d]", len);
+ else
+ dvmrp_print(bp, len);
+ break;
+ case 0x14:
+ (void)printf("igmp pimv1");
+ pimv1_print(bp, len);
+ break;
+ case 0x1e:
+ print_mresp(bp, len);
+ break;
+ case 0x1f:
+ print_mtrace(bp, len);
+ break;
+ default:
+ (void)printf("igmp-%d", bp[0]);
+ break;
+ }
+
+ if (vflag && TTEST2(bp[0], len)) {
+ /* Check the IGMP checksum */
+ vec[0].ptr = bp;
+ vec[0].len = len;
+ if (in_cksum(vec, 1))
+ printf(" bad igmp cksum %x!", EXTRACT_16BITS(&bp[2]));
+ }
+ return;
+trunc:
+ fputs("[|igmp]", stdout);
+}
diff --git a/freebsd/contrib/tcpdump/print-igrp.c b/freebsd/contrib/tcpdump/print-igrp.c
new file mode 100644
index 00000000..77c63283
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-igrp.c
@@ -0,0 +1,132 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Initial contribution from Francis Dupont (francis.dupont@inria.fr)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-igrp.c,v 1.21 2005-04-20 21:01:56 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "igrp.h"
+#include "ip.h"
+#include "extract.h" /* must come after interface.h */
+
+static void
+igrp_entry_print(register struct igrprte *igr, register int is_interior,
+ register int is_exterior)
+{
+ register u_int delay, bandwidth;
+ u_int metric, mtu;
+
+ if (is_interior)
+ printf(" *.%d.%d.%d", igr->igr_net[0],
+ igr->igr_net[1], igr->igr_net[2]);
+ else if (is_exterior)
+ printf(" X%d.%d.%d.0", igr->igr_net[0],
+ igr->igr_net[1], igr->igr_net[2]);
+ else
+ printf(" %d.%d.%d.0", igr->igr_net[0],
+ igr->igr_net[1], igr->igr_net[2]);
+
+ delay = EXTRACT_24BITS(igr->igr_dly);
+ bandwidth = EXTRACT_24BITS(igr->igr_bw);
+ metric = bandwidth + delay;
+ if (metric > 0xffffff)
+ metric = 0xffffff;
+ mtu = EXTRACT_16BITS(igr->igr_mtu);
+
+ printf(" d=%d b=%d r=%d l=%d M=%d mtu=%d in %d hops",
+ 10 * delay, bandwidth == 0 ? 0 : 10000000 / bandwidth,
+ igr->igr_rel, igr->igr_ld, metric,
+ mtu, igr->igr_hct);
+}
+
+static struct tok op2str[] = {
+ { IGRP_UPDATE, "update" },
+ { IGRP_REQUEST, "request" },
+ { 0, NULL }
+};
+
+void
+igrp_print(register const u_char *bp, u_int length, const u_char *bp2 _U_)
+{
+ register struct igrphdr *hdr;
+ register u_char *cp;
+ u_int nint, nsys, next;
+
+ hdr = (struct igrphdr *)bp;
+ cp = (u_char *)(hdr + 1);
+ (void)printf("igrp:");
+
+ /* Header */
+ TCHECK(*hdr);
+ nint = EXTRACT_16BITS(&hdr->ig_ni);
+ nsys = EXTRACT_16BITS(&hdr->ig_ns);
+ next = EXTRACT_16BITS(&hdr->ig_nx);
+
+ (void)printf(" %s V%d edit=%d AS=%d (%d/%d/%d)",
+ tok2str(op2str, "op-#%d", IGRP_OP(hdr->ig_vop)),
+ IGRP_V(hdr->ig_vop),
+ hdr->ig_ed,
+ EXTRACT_16BITS(&hdr->ig_as),
+ nint,
+ nsys,
+ next);
+
+ length -= sizeof(*hdr);
+ while (length >= IGRP_RTE_SIZE) {
+ if (nint > 0) {
+ TCHECK2(*cp, IGRP_RTE_SIZE);
+ igrp_entry_print((struct igrprte *)cp, 1, 0);
+ --nint;
+ } else if (nsys > 0) {
+ TCHECK2(*cp, IGRP_RTE_SIZE);
+ igrp_entry_print((struct igrprte *)cp, 0, 0);
+ --nsys;
+ } else if (next > 0) {
+ TCHECK2(*cp, IGRP_RTE_SIZE);
+ igrp_entry_print((struct igrprte *)cp, 0, 1);
+ --next;
+ } else {
+ (void)printf(" [extra bytes %d]", length);
+ break;
+ }
+ cp += IGRP_RTE_SIZE;
+ length -= IGRP_RTE_SIZE;
+ }
+ if (nint == 0 && nsys == 0 && next == 0)
+ return;
+trunc:
+ fputs(" [|igrp]", stdout);
+}
diff --git a/freebsd/contrib/tcpdump/print-ip.c b/freebsd/contrib/tcpdump/print-ip.c
new file mode 100644
index 00000000..947964cb
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-ip.c
@@ -0,0 +1,713 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ip.c,v 1.159 2007-09-14 01:29:28 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "addrtoname.h"
+#include "interface.h"
+#include "extract.h" /* must come after interface.h */
+
+#include "ip.h"
+#include "ipproto.h"
+
+struct tok ip_option_values[] = {
+ { IPOPT_EOL, "EOL" },
+ { IPOPT_NOP, "NOP" },
+ { IPOPT_TS, "timestamp" },
+ { IPOPT_SECURITY, "security" },
+ { IPOPT_RR, "RR" },
+ { IPOPT_SSRR, "SSRR" },
+ { IPOPT_LSRR, "LSRR" },
+ { IPOPT_RA, "RA" },
+ { IPOPT_RFC1393, "traceroute" },
+ { 0, NULL }
+};
+
+/*
+ * print the recorded route in an IP RR, LSRR or SSRR option.
+ */
+static void
+ip_printroute(register const u_char *cp, u_int length)
+{
+ register u_int ptr;
+ register u_int len;
+
+ if (length < 3) {
+ printf(" [bad length %u]", length);
+ return;
+ }
+ if ((length + 1) & 3)
+ printf(" [bad length %u]", length);
+ ptr = cp[2] - 1;
+ if (ptr < 3 || ((ptr + 1) & 3) || ptr > length + 1)
+ printf(" [bad ptr %u]", cp[2]);
+
+ for (len = 3; len < length; len += 4) {
+ printf(" %s", ipaddr_string(&cp[len]));
+ if (ptr > len)
+ printf(",");
+ }
+}
+
+/*
+ * If source-routing is present and valid, return the final destination.
+ * Otherwise, return IP destination.
+ *
+ * This is used for UDP and TCP pseudo-header in the checksum
+ * calculation.
+ */
+static u_int32_t
+ip_finddst(const struct ip *ip)
+{
+ int length;
+ int len;
+ const u_char *cp;
+ u_int32_t retval;
+
+ cp = (const u_char *)(ip + 1);
+ length = (IP_HL(ip) << 2) - sizeof(struct ip);
+
+ for (; length > 0; cp += len, length -= len) {
+ int tt;
+
+ TCHECK(*cp);
+ tt = *cp;
+ if (tt == IPOPT_EOL)
+ break;
+ else if (tt == IPOPT_NOP)
+ len = 1;
+ else {
+ TCHECK(cp[1]);
+ len = cp[1];
+ if (len < 2)
+ break;
+ }
+ TCHECK2(*cp, len);
+ switch (tt) {
+
+ case IPOPT_SSRR:
+ case IPOPT_LSRR:
+ if (len < 7)
+ break;
+ memcpy(&retval, cp + len - 4, 4);
+ return retval;
+ }
+ }
+trunc:
+ memcpy(&retval, &ip->ip_dst.s_addr, sizeof(u_int32_t));
+ return retval;
+}
+
+/*
+ * Compute a V4-style checksum by building a pseudoheader.
+ */
+int
+nextproto4_cksum(const struct ip *ip, const u_int8_t *data,
+ u_int len, u_int next_proto)
+{
+ struct phdr {
+ u_int32_t src;
+ u_int32_t dst;
+ u_char mbz;
+ u_char proto;
+ u_int16_t len;
+ } ph;
+ struct cksum_vec vec[2];
+
+ /* pseudo-header.. */
+ ph.len = htons((u_int16_t)len);
+ ph.mbz = 0;
+ ph.proto = next_proto;
+ memcpy(&ph.src, &ip->ip_src.s_addr, sizeof(u_int32_t));
+ if (IP_HL(ip) == 5)
+ memcpy(&ph.dst, &ip->ip_dst.s_addr, sizeof(u_int32_t));
+ else
+ ph.dst = ip_finddst(ip);
+
+ vec[0].ptr = (const u_int8_t *)(void *)&ph;
+ vec[0].len = sizeof(ph);
+ vec[1].ptr = data;
+ vec[1].len = len;
+ return (in_cksum(vec, 2));
+}
+
+static void
+ip_printts(register const u_char *cp, u_int length)
+{
+ register u_int ptr;
+ register u_int len;
+ int hoplen;
+ const char *type;
+
+ if (length < 4) {
+ printf("[bad length %u]", length);
+ return;
+ }
+ printf(" TS{");
+ hoplen = ((cp[3]&0xF) != IPOPT_TS_TSONLY) ? 8 : 4;
+ if ((length - 4) & (hoplen-1))
+ printf("[bad length %u]", length);
+ ptr = cp[2] - 1;
+ len = 0;
+ if (ptr < 4 || ((ptr - 4) & (hoplen-1)) || ptr > length + 1)
+ printf("[bad ptr %u]", cp[2]);
+ switch (cp[3]&0xF) {
+ case IPOPT_TS_TSONLY:
+ printf("TSONLY");
+ break;
+ case IPOPT_TS_TSANDADDR:
+ printf("TS+ADDR");
+ break;
+ /*
+ * prespecified should really be 3, but some ones might send 2
+ * instead, and the IPOPT_TS_PRESPEC constant can apparently
+ * have both values, so we have to hard-code it here.
+ */
+
+ case 2:
+ printf("PRESPEC2.0");
+ break;
+ case 3: /* IPOPT_TS_PRESPEC */
+ printf("PRESPEC");
+ break;
+ default:
+ printf("[bad ts type %d]", cp[3]&0xF);
+ goto done;
+ }
+
+ type = " ";
+ for (len = 4; len < length; len += hoplen) {
+ if (ptr == len)
+ type = " ^ ";
+ printf("%s%d@%s", type, EXTRACT_32BITS(&cp[len+hoplen-4]),
+ hoplen!=8 ? "" : ipaddr_string(&cp[len]));
+ type = " ";
+ }
+
+done:
+ printf("%s", ptr == len ? " ^ " : "");
+
+ if (cp[3]>>4)
+ printf(" [%d hops not recorded]} ", cp[3]>>4);
+ else
+ printf("}");
+}
+
+/*
+ * print IP options.
+ */
+static void
+ip_optprint(register const u_char *cp, u_int length)
+{
+ register u_int option_len;
+ const char *sep = "";
+
+ for (; length > 0; cp += option_len, length -= option_len) {
+ u_int option_code;
+
+ printf("%s", sep);
+ sep = ",";
+
+ TCHECK(*cp);
+ option_code = *cp;
+
+ printf("%s",
+ tok2str(ip_option_values,"unknown %u",option_code));
+
+ if (option_code == IPOPT_NOP ||
+ option_code == IPOPT_EOL)
+ option_len = 1;
+
+ else {
+ TCHECK(cp[1]);
+ option_len = cp[1];
+ if (option_len < 2) {
+ printf(" [bad length %u]", option_len);
+ return;
+ }
+ }
+
+ if (option_len > length) {
+ printf(" [bad length %u]", option_len);
+ return;
+ }
+
+ TCHECK2(*cp, option_len);
+
+ switch (option_code) {
+ case IPOPT_EOL:
+ return;
+
+ case IPOPT_TS:
+ ip_printts(cp, option_len);
+ break;
+
+ case IPOPT_RR: /* fall through */
+ case IPOPT_SSRR:
+ case IPOPT_LSRR:
+ ip_printroute(cp, option_len);
+ break;
+
+ case IPOPT_RA:
+ if (option_len < 4) {
+ printf(" [bad length %u]", option_len);
+ break;
+ }
+ TCHECK(cp[3]);
+ if (EXTRACT_16BITS(&cp[2]) != 0)
+ printf(" value %u", EXTRACT_16BITS(&cp[2]));
+ break;
+
+ case IPOPT_NOP: /* nothing to print - fall through */
+ case IPOPT_SECURITY:
+ default:
+ break;
+ }
+ }
+ return;
+
+trunc:
+ printf("[|ip]");
+}
+
+#define IP_RES 0x8000
+
+static struct tok ip_frag_values[] = {
+ { IP_MF, "+" },
+ { IP_DF, "DF" },
+ { IP_RES, "rsvd" }, /* The RFC3514 evil ;-) bit */
+ { 0, NULL }
+};
+
+struct ip_print_demux_state {
+ const struct ip *ip;
+ const u_char *cp;
+ u_int len, off;
+ u_char nh;
+ int advance;
+};
+
+static void
+ip_print_demux(netdissect_options *ndo,
+ struct ip_print_demux_state *ipds)
+{
+ struct protoent *proto;
+ struct cksum_vec vec[1];
+
+again:
+ switch (ipds->nh) {
+
+ case IPPROTO_AH:
+ ipds->nh = *ipds->cp;
+ ipds->advance = ah_print(ipds->cp);
+ if (ipds->advance <= 0)
+ break;
+ ipds->cp += ipds->advance;
+ ipds->len -= ipds->advance;
+ goto again;
+
+ case IPPROTO_ESP:
+ {
+ int enh, padlen;
+ ipds->advance = esp_print(ndo, ipds->cp, ipds->len,
+ (const u_char *)ipds->ip,
+ &enh, &padlen);
+ if (ipds->advance <= 0)
+ break;
+ ipds->cp += ipds->advance;
+ ipds->len -= ipds->advance + padlen;
+ ipds->nh = enh & 0xff;
+ goto again;
+ }
+
+ case IPPROTO_IPCOMP:
+ {
+ int enh;
+ ipds->advance = ipcomp_print(ipds->cp, &enh);
+ if (ipds->advance <= 0)
+ break;
+ ipds->cp += ipds->advance;
+ ipds->len -= ipds->advance;
+ ipds->nh = enh & 0xff;
+ goto again;
+ }
+
+ case IPPROTO_SCTP:
+ sctp_print(ipds->cp, (const u_char *)ipds->ip, ipds->len);
+ break;
+
+ case IPPROTO_DCCP:
+ dccp_print(ipds->cp, (const u_char *)ipds->ip, ipds->len);
+ break;
+
+ case IPPROTO_TCP:
+ /* pass on the MF bit plus the offset to detect fragments */
+ tcp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip,
+ ipds->off & (IP_MF|IP_OFFMASK));
+ break;
+
+ case IPPROTO_UDP:
+ /* pass on the MF bit plus the offset to detect fragments */
+ udp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip,
+ ipds->off & (IP_MF|IP_OFFMASK));
+ break;
+
+ case IPPROTO_ICMP:
+ /* pass on the MF bit plus the offset to detect fragments */
+ icmp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip,
+ ipds->off & (IP_MF|IP_OFFMASK));
+ break;
+
+ case IPPROTO_PIGP:
+ /*
+ * XXX - the current IANA protocol number assignments
+ * page lists 9 as "any private interior gateway
+ * (used by Cisco for their IGRP)" and 88 as
+ * "EIGRP" from Cisco.
+ *
+ * Recent BSD <netinet/in.h> headers define
+ * IP_PROTO_PIGP as 9 and IP_PROTO_IGRP as 88.
+ * We define IP_PROTO_PIGP as 9 and
+ * IP_PROTO_EIGRP as 88; those names better
+ * match was the current protocol number
+ * assignments say.
+ */
+ igrp_print(ipds->cp, ipds->len, (const u_char *)ipds->ip);
+ break;
+
+ case IPPROTO_EIGRP:
+ eigrp_print(ipds->cp, ipds->len);
+ break;
+
+ case IPPROTO_ND:
+ ND_PRINT((ndo, " nd %d", ipds->len));
+ break;
+
+ case IPPROTO_EGP:
+ egp_print(ipds->cp, ipds->len);
+ break;
+
+ case IPPROTO_OSPF:
+ ospf_print(ipds->cp, ipds->len, (const u_char *)ipds->ip);
+ break;
+
+ case IPPROTO_IGMP:
+ igmp_print(ipds->cp, ipds->len);
+ break;
+
+ case IPPROTO_IPV4:
+ /* DVMRP multicast tunnel (ip-in-ip encapsulation) */
+ ip_print(ndo, ipds->cp, ipds->len);
+ if (! vflag) {
+ ND_PRINT((ndo, " (ipip-proto-4)"));
+ return;
+ }
+ break;
+
+#ifdef INET6
+ case IPPROTO_IPV6:
+ /* ip6-in-ip encapsulation */
+ ip6_print(ndo, ipds->cp, ipds->len);
+ break;
+#endif /*INET6*/
+
+ case IPPROTO_RSVP:
+ rsvp_print(ipds->cp, ipds->len);
+ break;
+
+ case IPPROTO_GRE:
+ /* do it */
+ gre_print(ipds->cp, ipds->len);
+ break;
+
+ case IPPROTO_MOBILE:
+ mobile_print(ipds->cp, ipds->len);
+ break;
+
+ case IPPROTO_PIM:
+ vec[0].ptr = ipds->cp;
+ vec[0].len = ipds->len;
+ pim_print(ipds->cp, ipds->len, in_cksum(vec, 1));
+ break;
+
+ case IPPROTO_VRRP:
+ if (packettype == PT_CARP) {
+ if (vflag)
+ (void)printf("carp %s > %s: ",
+ ipaddr_string(&ipds->ip->ip_src),
+ ipaddr_string(&ipds->ip->ip_dst));
+ carp_print(ipds->cp, ipds->len, ipds->ip->ip_ttl);
+ } else {
+ if (vflag)
+ (void)printf("vrrp %s > %s: ",
+ ipaddr_string(&ipds->ip->ip_src),
+ ipaddr_string(&ipds->ip->ip_dst));
+ vrrp_print(ipds->cp, ipds->len, ipds->ip->ip_ttl);
+ }
+ break;
+
+ case IPPROTO_PGM:
+ pgm_print(ipds->cp, ipds->len, (const u_char *)ipds->ip);
+ break;
+
+ case IPPROTO_PFSYNC:
+ pfsync_ip_print(ipds->cp, ipds->len);
+ break;
+
+ default:
+ if (ndo->ndo_nflag==0 && (proto = getprotobynumber(ipds->nh)) != NULL)
+ ND_PRINT((ndo, " %s", proto->p_name));
+ else
+ ND_PRINT((ndo, " ip-proto-%d", ipds->nh));
+ ND_PRINT((ndo, " %d", ipds->len));
+ break;
+ }
+}
+
+void
+ip_print_inner(netdissect_options *ndo,
+ const u_char *bp,
+ u_int length, u_int nh,
+ const u_char *bp2)
+{
+ struct ip_print_demux_state ipd;
+
+ ipd.ip = (const struct ip *)bp2;
+ ipd.cp = bp;
+ ipd.len = length;
+ ipd.off = 0;
+ ipd.nh = nh;
+ ipd.advance = 0;
+
+ ip_print_demux(ndo, &ipd);
+}
+
+
+/*
+ * print an IP datagram.
+ */
+void
+ip_print(netdissect_options *ndo,
+ const u_char *bp,
+ u_int length)
+{
+ struct ip_print_demux_state ipd;
+ struct ip_print_demux_state *ipds=&ipd;
+ const u_char *ipend;
+ u_int hlen;
+ struct cksum_vec vec[1];
+ u_int16_t sum, ip_sum;
+ struct protoent *proto;
+
+ ipds->ip = (const struct ip *)bp;
+ if (IP_V(ipds->ip) != 4) { /* print version if != 4 */
+ printf("IP%u ", IP_V(ipds->ip));
+ if (IP_V(ipds->ip) == 6)
+ printf(", wrong link-layer encapsulation");
+ }
+ else if (!eflag)
+ printf("IP ");
+
+ if ((u_char *)(ipds->ip + 1) > ndo->ndo_snapend) {
+ printf("[|ip]");
+ return;
+ }
+ if (length < sizeof (struct ip)) {
+ (void)printf("truncated-ip %u", length);
+ return;
+ }
+ hlen = IP_HL(ipds->ip) * 4;
+ if (hlen < sizeof (struct ip)) {
+ (void)printf("bad-hlen %u", hlen);
+ return;
+ }
+
+ ipds->len = EXTRACT_16BITS(&ipds->ip->ip_len);
+ if (length < ipds->len)
+ (void)printf("truncated-ip - %u bytes missing! ",
+ ipds->len - length);
+ if (ipds->len < hlen) {
+#ifdef GUESS_TSO
+ if (ipds->len) {
+ (void)printf("bad-len %u", ipds->len);
+ return;
+ }
+ else {
+ /* we guess that it is a TSO send */
+ ipds->len = length;
+ }
+#else
+ (void)printf("bad-len %u", ipds->len);
+ return;
+#endif /* GUESS_TSO */
+ }
+
+ /*
+ * Cut off the snapshot length to the end of the IP payload.
+ */
+ ipend = bp + ipds->len;
+ if (ipend < ndo->ndo_snapend)
+ ndo->ndo_snapend = ipend;
+
+ ipds->len -= hlen;
+
+ ipds->off = EXTRACT_16BITS(&ipds->ip->ip_off);
+
+ if (vflag) {
+ (void)printf("(tos 0x%x", (int)ipds->ip->ip_tos);
+ /* ECN bits */
+ if (ipds->ip->ip_tos & 0x03) {
+ switch (ipds->ip->ip_tos & 0x03) {
+ case 1:
+ (void)printf(",ECT(1)");
+ break;
+ case 2:
+ (void)printf(",ECT(0)");
+ break;
+ case 3:
+ (void)printf(",CE");
+ }
+ }
+
+ if (ipds->ip->ip_ttl >= 1)
+ (void)printf(", ttl %u", ipds->ip->ip_ttl);
+
+ /*
+ * for the firewall guys, print id, offset.
+ * On all but the last stick a "+" in the flags portion.
+ * For unfragmented datagrams, note the don't fragment flag.
+ */
+
+ (void)printf(", id %u, offset %u, flags [%s], proto %s (%u)",
+ EXTRACT_16BITS(&ipds->ip->ip_id),
+ (ipds->off & 0x1fff) * 8,
+ bittok2str(ip_frag_values, "none", ipds->off&0xe000),
+ tok2str(ipproto_values,"unknown",ipds->ip->ip_p),
+ ipds->ip->ip_p);
+
+ (void)printf(", length %u", EXTRACT_16BITS(&ipds->ip->ip_len));
+
+ if ((hlen - sizeof(struct ip)) > 0) {
+ printf(", options (");
+ ip_optprint((u_char *)(ipds->ip + 1), hlen - sizeof(struct ip));
+ printf(")");
+ }
+
+ if (!Kflag && (u_char *)ipds->ip + hlen <= ndo->ndo_snapend) {
+ vec[0].ptr = (const u_int8_t *)(void *)ipds->ip;
+ vec[0].len = hlen;
+ sum = in_cksum(vec, 1);
+ if (sum != 0) {
+ ip_sum = EXTRACT_16BITS(&ipds->ip->ip_sum);
+ (void)printf(", bad cksum %x (->%x)!", ip_sum,
+ in_cksum_shouldbe(ip_sum, sum));
+ }
+ }
+
+ printf(")\n ");
+ }
+
+ /*
+ * If this is fragment zero, hand it to the next higher
+ * level protocol.
+ */
+ if ((ipds->off & 0x1fff) == 0) {
+ ipds->cp = (const u_char *)ipds->ip + hlen;
+ ipds->nh = ipds->ip->ip_p;
+
+ if (ipds->nh != IPPROTO_TCP && ipds->nh != IPPROTO_UDP &&
+ ipds->nh != IPPROTO_SCTP && ipds->nh != IPPROTO_DCCP) {
+ (void)printf("%s > %s: ",
+ ipaddr_string(&ipds->ip->ip_src),
+ ipaddr_string(&ipds->ip->ip_dst));
+ }
+ ip_print_demux(ndo, ipds);
+ } else {
+ /* Ultra quiet now means that all this stuff should be suppressed */
+ if (qflag > 1) return;
+
+ /*
+ * if this isn't the first frag, we're missing the
+ * next level protocol header. print the ip addr
+ * and the protocol.
+ */
+ if (ipds->off & 0x1fff) {
+ (void)printf("%s > %s:", ipaddr_string(&ipds->ip->ip_src),
+ ipaddr_string(&ipds->ip->ip_dst));
+ if (!ndo->ndo_nflag && (proto = getprotobynumber(ipds->ip->ip_p)) != NULL)
+ (void)printf(" %s", proto->p_name);
+ else
+ (void)printf(" ip-proto-%d", ipds->ip->ip_p);
+ }
+ }
+}
+
+void
+ipN_print(register const u_char *bp, register u_int length)
+{
+ struct ip *ip, hdr;
+
+ ip = (struct ip *)bp;
+ if (length < 4) {
+ (void)printf("truncated-ip %d", length);
+ return;
+ }
+ memcpy (&hdr, (char *)ip, 4);
+ switch (IP_V(&hdr)) {
+ case 4:
+ ip_print (gndo, bp, length);
+ return;
+#ifdef INET6
+ case 6:
+ ip6_print (gndo, bp, length);
+ return;
+#endif
+ default:
+ (void)printf("unknown ip %d", IP_V(&hdr));
+ return;
+ }
+}
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */
+
+
diff --git a/freebsd/contrib/tcpdump/print-ip6.c b/freebsd/contrib/tcpdump/print-ip6.c
new file mode 100644
index 00000000..387067b7
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-ip6.c
@@ -0,0 +1,275 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ip6.c,v 1.52 2007-09-21 07:05:33 hannes Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef INET6
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "netdissect.h"
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+#include "ip6.h"
+#include "ipproto.h"
+
+/*
+ * Compute a V6-style checksum by building a pseudoheader.
+ */
+int
+nextproto6_cksum(const struct ip6_hdr *ip6, const u_int8_t *data,
+ u_int len, u_int next_proto)
+{
+ struct {
+ struct in6_addr ph_src;
+ struct in6_addr ph_dst;
+ u_int32_t ph_len;
+ u_int8_t ph_zero[3];
+ u_int8_t ph_nxt;
+ } ph;
+ struct cksum_vec vec[2];
+
+ /* pseudo-header */
+ memset(&ph, 0, sizeof(ph));
+ ph.ph_src = ip6->ip6_src;
+ ph.ph_dst = ip6->ip6_dst;
+ ph.ph_len = htonl(len);
+ ph.ph_nxt = next_proto;
+
+ vec[0].ptr = (const u_int8_t *)(void *)&ph;
+ vec[0].len = sizeof(ph);
+ vec[1].ptr = data;
+ vec[1].len = len;
+
+ return in_cksum(vec, 2);
+}
+
+/*
+ * print an IP6 datagram.
+ */
+void
+ip6_print(netdissect_options *ndo, const u_char *bp, u_int length)
+{
+ register const struct ip6_hdr *ip6;
+ register int advance;
+ u_int len;
+ const u_char *ipend;
+ register const u_char *cp;
+ register u_int payload_len;
+ int nh;
+ int fragmented = 0;
+ u_int flow;
+
+ ip6 = (const struct ip6_hdr *)bp;
+
+ TCHECK(*ip6);
+ if (length < sizeof (struct ip6_hdr)) {
+ (void)ND_PRINT((ndo, "truncated-ip6 %u", length));
+ return;
+ }
+
+ if (!ndo->ndo_eflag)
+ ND_PRINT((ndo, "IP6 "));
+
+ payload_len = EXTRACT_16BITS(&ip6->ip6_plen);
+ len = payload_len + sizeof(struct ip6_hdr);
+ if (length < len)
+ (void)ND_PRINT((ndo, "truncated-ip6 - %u bytes missing!",
+ len - length));
+
+ if (ndo->ndo_vflag) {
+ flow = EXTRACT_32BITS(&ip6->ip6_flow);
+ ND_PRINT((ndo, "("));
+#if 0
+ /* rfc1883 */
+ if (flow & 0x0f000000)
+ (void)ND_PRINT((ndo, "pri 0x%02x, ", (flow & 0x0f000000) >> 24));
+ if (flow & 0x00ffffff)
+ (void)ND_PRINT((ndo, "flowlabel 0x%06x, ", flow & 0x00ffffff));
+#else
+ /* RFC 2460 */
+ if (flow & 0x0ff00000)
+ (void)ND_PRINT((ndo, "class 0x%02x, ", (flow & 0x0ff00000) >> 20));
+ if (flow & 0x000fffff)
+ (void)ND_PRINT((ndo, "flowlabel 0x%05x, ", flow & 0x000fffff));
+#endif
+
+ (void)ND_PRINT((ndo, "hlim %u, next-header %s (%u) payload length: %u) ",
+ ip6->ip6_hlim,
+ tok2str(ipproto_values,"unknown",ip6->ip6_nxt),
+ ip6->ip6_nxt,
+ payload_len));
+ }
+
+ /*
+ * Cut off the snapshot length to the end of the IP payload.
+ */
+ ipend = bp + len;
+ if (ipend < ndo->ndo_snapend)
+ ndo->ndo_snapend = ipend;
+
+ cp = (const u_char *)ip6;
+ advance = sizeof(struct ip6_hdr);
+ nh = ip6->ip6_nxt;
+ while (cp < ndo->ndo_snapend && advance > 0) {
+ cp += advance;
+ len -= advance;
+
+ if (cp == (const u_char *)(ip6 + 1) &&
+ nh != IPPROTO_TCP && nh != IPPROTO_UDP &&
+ nh != IPPROTO_DCCP && nh != IPPROTO_SCTP) {
+ (void)ND_PRINT((ndo, "%s > %s: ", ip6addr_string(&ip6->ip6_src),
+ ip6addr_string(&ip6->ip6_dst)));
+ }
+
+ switch (nh) {
+ case IPPROTO_HOPOPTS:
+ advance = hbhopt_print(cp);
+ nh = *cp;
+ break;
+ case IPPROTO_DSTOPTS:
+ advance = dstopt_print(cp);
+ nh = *cp;
+ break;
+ case IPPROTO_FRAGMENT:
+ advance = frag6_print(cp, (const u_char *)ip6);
+ if (ndo->ndo_snapend <= cp + advance)
+ return;
+ nh = *cp;
+ fragmented = 1;
+ break;
+
+ case IPPROTO_MOBILITY_OLD:
+ case IPPROTO_MOBILITY:
+ /*
+ * XXX - we don't use "advance"; the current
+ * "Mobility Support in IPv6" draft
+ * (draft-ietf-mobileip-ipv6-24) says that
+ * the next header field in a mobility header
+ * should be IPPROTO_NONE, but speaks of
+ * the possiblity of a future extension in
+ * which payload can be piggybacked atop a
+ * mobility header.
+ */
+ advance = mobility_print(cp, (const u_char *)ip6);
+ nh = *cp;
+ return;
+ case IPPROTO_ROUTING:
+ advance = rt6_print(cp, (const u_char *)ip6);
+ nh = *cp;
+ break;
+ case IPPROTO_SCTP:
+ sctp_print(cp, (const u_char *)ip6, len);
+ return;
+ case IPPROTO_DCCP:
+ dccp_print(cp, (const u_char *)ip6, len);
+ return;
+ case IPPROTO_TCP:
+ tcp_print(cp, len, (const u_char *)ip6, fragmented);
+ return;
+ case IPPROTO_UDP:
+ udp_print(cp, len, (const u_char *)ip6, fragmented);
+ return;
+ case IPPROTO_ICMPV6:
+ icmp6_print(ndo, cp, len, (const u_char *)ip6, fragmented);
+ return;
+ case IPPROTO_AH:
+ advance = ah_print(cp);
+ nh = *cp;
+ break;
+ case IPPROTO_ESP:
+ {
+ int enh, padlen;
+ advance = esp_print(ndo, cp, len, (const u_char *)ip6, &enh, &padlen);
+ nh = enh & 0xff;
+ len -= padlen;
+ break;
+ }
+ case IPPROTO_IPCOMP:
+ {
+ int enh;
+ advance = ipcomp_print(cp, &enh);
+ nh = enh & 0xff;
+ break;
+ }
+
+ case IPPROTO_PIM:
+ pim_print(cp, len, nextproto6_cksum(ip6, cp, len,
+ IPPROTO_PIM));
+ return;
+
+ case IPPROTO_OSPF:
+ ospf6_print(cp, len);
+ return;
+
+ case IPPROTO_IPV6:
+ ip6_print(ndo, cp, len);
+ return;
+
+ case IPPROTO_IPV4:
+ ip_print(ndo, cp, len);
+ return;
+
+ case IPPROTO_PGM:
+ pgm_print(cp, len, (const u_char *)ip6);
+ return;
+
+ case IPPROTO_GRE:
+ gre_print(cp, len);
+ return;
+
+ case IPPROTO_RSVP:
+ rsvp_print(cp, len);
+ return;
+
+ case IPPROTO_NONE:
+ (void)ND_PRINT((ndo, "no next header"));
+ return;
+
+ default:
+ (void)ND_PRINT((ndo, "ip-proto-%d %d", nh, len));
+ return;
+ }
+ }
+
+ return;
+trunc:
+ (void)ND_PRINT((ndo, "[|ip6]"));
+}
+
+#endif /* INET6 */
diff --git a/freebsd/contrib/tcpdump/print-ip6opts.c b/freebsd/contrib/tcpdump/print-ip6opts.c
new file mode 100644
index 00000000..a01a86bc
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-ip6opts.c
@@ -0,0 +1,334 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ip6opts.c,v 1.18 2005-04-20 22:18:50 guy Exp $";
+#endif
+
+#ifdef INET6
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+
+#include "ip6.h"
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+/* items outside of rfc2292bis */
+#ifndef IP6OPT_MINLEN
+#define IP6OPT_MINLEN 2
+#endif
+#ifndef IP6OPT_RTALERT_LEN
+#define IP6OPT_RTALERT_LEN 4
+#endif
+#ifndef IP6OPT_JUMBO_LEN
+#define IP6OPT_JUMBO_LEN 6
+#endif
+#define IP6OPT_HOMEADDR_MINLEN 18
+#define IP6OPT_BU_MINLEN 10
+#define IP6OPT_BA_MINLEN 13
+#define IP6OPT_BR_MINLEN 2
+#define IP6SOPT_UI 0x2
+#define IP6SOPT_UI_MINLEN 4
+#define IP6SOPT_ALTCOA 0x3
+#define IP6SOPT_ALTCOA_MINLEN 18
+#define IP6SOPT_AUTH 0x4
+#define IP6SOPT_AUTH_MINLEN 6
+
+static void ip6_sopt_print(const u_char *, int);
+
+static void
+ip6_sopt_print(const u_char *bp, int len)
+{
+ int i;
+ int optlen;
+
+ for (i = 0; i < len; i += optlen) {
+ if (bp[i] == IP6OPT_PAD1)
+ optlen = 1;
+ else {
+ if (i + 1 < len)
+ optlen = bp[i + 1] + 2;
+ else
+ goto trunc;
+ }
+ if (i + optlen > len)
+ goto trunc;
+
+ switch (bp[i]) {
+ case IP6OPT_PAD1:
+ printf(", pad1");
+ break;
+ case IP6OPT_PADN:
+ if (len - i < IP6OPT_MINLEN) {
+ printf(", padn: trunc");
+ goto trunc;
+ }
+ printf(", padn");
+ break;
+ case IP6SOPT_UI:
+ if (len - i < IP6SOPT_UI_MINLEN) {
+ printf(", ui: trunc");
+ goto trunc;
+ }
+ printf(", ui: 0x%04x ", EXTRACT_16BITS(&bp[i + 2]));
+ break;
+ case IP6SOPT_ALTCOA:
+ if (len - i < IP6SOPT_ALTCOA_MINLEN) {
+ printf(", altcoa: trunc");
+ goto trunc;
+ }
+ printf(", alt-CoA: %s", ip6addr_string(&bp[i+2]));
+ break;
+ case IP6SOPT_AUTH:
+ if (len - i < IP6SOPT_AUTH_MINLEN) {
+ printf(", auth: trunc");
+ goto trunc;
+ }
+ printf(", auth spi: 0x%08x", EXTRACT_32BITS(&bp[i + 2]));
+ break;
+ default:
+ if (len - i < IP6OPT_MINLEN) {
+ printf(", sopt_type %d: trunc)", bp[i]);
+ goto trunc;
+ }
+ printf(", sopt_type 0x%02x: len=%d", bp[i], bp[i + 1]);
+ break;
+ }
+ }
+ return;
+
+trunc:
+ printf("[trunc] ");
+}
+
+void
+ip6_opt_print(const u_char *bp, int len)
+{
+ int i;
+ int optlen = 0;
+
+ if (len == 0)
+ return;
+ for (i = 0; i < len; i += optlen) {
+ if (bp[i] == IP6OPT_PAD1)
+ optlen = 1;
+ else {
+ if (i + 1 < len)
+ optlen = bp[i + 1] + 2;
+ else
+ goto trunc;
+ }
+ if (i + optlen > len)
+ goto trunc;
+
+ switch (bp[i]) {
+ case IP6OPT_PAD1:
+ printf("(pad1)");
+ break;
+ case IP6OPT_PADN:
+ if (len - i < IP6OPT_MINLEN) {
+ printf("(padn: trunc)");
+ goto trunc;
+ }
+ printf("(padn)");
+ break;
+ case IP6OPT_ROUTER_ALERT:
+ if (len - i < IP6OPT_RTALERT_LEN) {
+ printf("(rtalert: trunc)");
+ goto trunc;
+ }
+ if (bp[i + 1] != IP6OPT_RTALERT_LEN - 2) {
+ printf("(rtalert: invalid len %d)", bp[i + 1]);
+ goto trunc;
+ }
+ printf("(rtalert: 0x%04x) ", EXTRACT_16BITS(&bp[i + 2]));
+ break;
+ case IP6OPT_JUMBO:
+ if (len - i < IP6OPT_JUMBO_LEN) {
+ printf("(jumbo: trunc)");
+ goto trunc;
+ }
+ if (bp[i + 1] != IP6OPT_JUMBO_LEN - 2) {
+ printf("(jumbo: invalid len %d)", bp[i + 1]);
+ goto trunc;
+ }
+ printf("(jumbo: %u) ", EXTRACT_32BITS(&bp[i + 2]));
+ break;
+ case IP6OPT_HOME_ADDRESS:
+ if (len - i < IP6OPT_HOMEADDR_MINLEN) {
+ printf("(homeaddr: trunc)");
+ goto trunc;
+ }
+ if (bp[i + 1] < IP6OPT_HOMEADDR_MINLEN - 2) {
+ printf("(homeaddr: invalid len %d)", bp[i + 1]);
+ goto trunc;
+ }
+ printf("(homeaddr: %s", ip6addr_string(&bp[i + 2]));
+ if (bp[i + 1] > IP6OPT_HOMEADDR_MINLEN - 2) {
+ ip6_sopt_print(&bp[i + IP6OPT_HOMEADDR_MINLEN],
+ (optlen - IP6OPT_HOMEADDR_MINLEN));
+ }
+ printf(")");
+ break;
+ case IP6OPT_BINDING_UPDATE:
+ if (len - i < IP6OPT_BU_MINLEN) {
+ printf("(bu: trunc)");
+ goto trunc;
+ }
+ if (bp[i + 1] < IP6OPT_BU_MINLEN - 2) {
+ printf("(bu: invalid len %d)", bp[i + 1]);
+ goto trunc;
+ }
+ printf("(bu: ");
+ if (bp[i + 2] & 0x80)
+ printf("A");
+ if (bp[i + 2] & 0x40)
+ printf("H");
+ if (bp[i + 2] & 0x20)
+ printf("S");
+ if (bp[i + 2] & 0x10)
+ printf("D");
+ if ((bp[i + 2] & 0x0f) || bp[i + 3] || bp[i + 4])
+ printf("res");
+ printf(", sequence: %u", bp[i + 5]);
+ printf(", lifetime: %u", EXTRACT_32BITS(&bp[i + 6]));
+
+ if (bp[i + 1] > IP6OPT_BU_MINLEN - 2) {
+ ip6_sopt_print(&bp[i + IP6OPT_BU_MINLEN],
+ (optlen - IP6OPT_BU_MINLEN));
+ }
+ printf(")");
+ break;
+ case IP6OPT_BINDING_ACK:
+ if (len - i < IP6OPT_BA_MINLEN) {
+ printf("(ba: trunc)");
+ goto trunc;
+ }
+ if (bp[i + 1] < IP6OPT_BA_MINLEN - 2) {
+ printf("(ba: invalid len %d)", bp[i + 1]);
+ goto trunc;
+ }
+ printf("(ba: ");
+ printf("status: %u", bp[i + 2]);
+ if (bp[i + 3])
+ printf("res");
+ printf(", sequence: %u", bp[i + 4]);
+ printf(", lifetime: %u", EXTRACT_32BITS(&bp[i + 5]));
+ printf(", refresh: %u", EXTRACT_32BITS(&bp[i + 9]));
+
+ if (bp[i + 1] > IP6OPT_BA_MINLEN - 2) {
+ ip6_sopt_print(&bp[i + IP6OPT_BA_MINLEN],
+ (optlen - IP6OPT_BA_MINLEN));
+ }
+ printf(")");
+ break;
+ case IP6OPT_BINDING_REQ:
+ if (len - i < IP6OPT_BR_MINLEN) {
+ printf("(br: trunc)");
+ goto trunc;
+ }
+ printf("(br");
+ if (bp[i + 1] > IP6OPT_BR_MINLEN - 2) {
+ ip6_sopt_print(&bp[i + IP6OPT_BR_MINLEN],
+ (optlen - IP6OPT_BR_MINLEN));
+ }
+ printf(")");
+ break;
+ default:
+ if (len - i < IP6OPT_MINLEN) {
+ printf("(type %d: trunc)", bp[i]);
+ goto trunc;
+ }
+ printf("(opt_type 0x%02x: len=%d)", bp[i], bp[i + 1]);
+ break;
+ }
+ }
+ printf(" ");
+
+#if 0
+end:
+#endif
+ return;
+
+trunc:
+ printf("[trunc] ");
+}
+
+int
+hbhopt_print(register const u_char *bp)
+{
+ const struct ip6_hbh *dp = (struct ip6_hbh *)bp;
+ int hbhlen = 0;
+
+ TCHECK(dp->ip6h_len);
+ hbhlen = (int)((dp->ip6h_len + 1) << 3);
+ TCHECK2(*dp, hbhlen);
+ printf("HBH ");
+ if (vflag)
+ ip6_opt_print((const u_char *)dp + sizeof(*dp), hbhlen - sizeof(*dp));
+
+ return(hbhlen);
+
+ trunc:
+ fputs("[|HBH]", stdout);
+ return(-1);
+}
+
+int
+dstopt_print(register const u_char *bp)
+{
+ const struct ip6_dest *dp = (struct ip6_dest *)bp;
+ int dstoptlen = 0;
+
+ TCHECK(dp->ip6d_len);
+ dstoptlen = (int)((dp->ip6d_len + 1) << 3);
+ TCHECK2(*dp, dstoptlen);
+ printf("DSTOPT ");
+ if (vflag) {
+ ip6_opt_print((const u_char *)dp + sizeof(*dp),
+ dstoptlen - sizeof(*dp));
+ }
+
+ return(dstoptlen);
+
+ trunc:
+ fputs("[|DSTOPT]", stdout);
+ return(-1);
+}
+#endif /* INET6 */
diff --git a/freebsd/contrib/tcpdump/print-ipcomp.c b/freebsd/contrib/tcpdump/print-ipcomp.c
new file mode 100644
index 00000000..04f16b38
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-ipcomp.c
@@ -0,0 +1,93 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ipcomp.c,v 1.20 2003-11-19 00:36:08 guy Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+
+struct ipcomp {
+ u_int8_t comp_nxt; /* Next Header */
+ u_int8_t comp_flags; /* Length of data, in 32bit */
+ u_int16_t comp_cpi; /* Compression parameter index */
+};
+
+#if defined(HAVE_LIBZ) && defined(HAVE_ZLIB_H)
+#include <zlib.h>
+#endif
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+int
+ipcomp_print(register const u_char *bp, int *nhdr _U_)
+{
+ register const struct ipcomp *ipcomp;
+ register const u_char *ep;
+ u_int16_t cpi;
+#if defined(HAVE_LIBZ) && defined(HAVE_ZLIB_H)
+ int advance;
+#endif
+
+ ipcomp = (struct ipcomp *)bp;
+ cpi = EXTRACT_16BITS(&ipcomp->comp_cpi);
+
+ /* 'ep' points to the end of available data. */
+ ep = snapend;
+
+ if ((u_char *)(ipcomp + 1) >= ep - sizeof(struct ipcomp)) {
+ fputs("[|IPCOMP]", stdout);
+ goto fail;
+ }
+ printf("IPComp(cpi=0x%04x)", cpi);
+
+#if defined(HAVE_LIBZ) && defined(HAVE_ZLIB_H)
+ if (1)
+ goto fail;
+
+ /*
+ * We may want to decompress the packet here. Packet buffer
+ * management is a headache (if we decompress, packet will become
+ * larger).
+ */
+ if (nhdr)
+ *nhdr = ipcomp->comp_nxt;
+ advance = sizeof(struct ipcomp);
+
+ printf(": ");
+ return advance;
+
+#endif
+fail:
+ return -1;
+}
diff --git a/freebsd/contrib/tcpdump/print-ipfc.c b/freebsd/contrib/tcpdump/print-ipfc.c
new file mode 100644
index 00000000..4e431d32
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-ipfc.c
@@ -0,0 +1,137 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ipfc.c,v 1.9 2005-11-13 12:12:42 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <pcap.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+
+#include "ether.h"
+#include "ipfc.h"
+
+/*
+ * RFC 2625 IP-over-Fibre Channel.
+ */
+
+/* Extract src, dst addresses */
+static inline void
+extract_ipfc_addrs(const struct ipfc_header *ipfcp, char *ipfcsrc,
+ char *ipfcdst)
+{
+ /*
+ * We assume that, as per RFC 2625, the lower 48 bits of the
+ * source and destination addresses are MAC addresses.
+ */
+ memcpy(ipfcdst, (const char *)&ipfcp->ipfc_dhost[2], 6);
+ memcpy(ipfcsrc, (const char *)&ipfcp->ipfc_shost[2], 6);
+}
+
+/*
+ * Print the Network_Header
+ */
+static inline void
+ipfc_hdr_print(register const struct ipfc_header *ipfcp _U_,
+ register u_int length, register const u_char *ipfcsrc,
+ register const u_char *ipfcdst)
+{
+ const char *srcname, *dstname;
+
+ srcname = etheraddr_string(ipfcsrc);
+ dstname = etheraddr_string(ipfcdst);
+
+ /*
+ * XXX - show the upper 16 bits? Do so only if "vflag" is set?
+ */
+ (void) printf("%s %s %d: ", srcname, dstname, length);
+}
+
+static void
+ipfc_print(const u_char *p, u_int length, u_int caplen)
+{
+ const struct ipfc_header *ipfcp = (const struct ipfc_header *)p;
+ struct ether_header ehdr;
+ u_short extracted_ethertype;
+
+ if (caplen < IPFC_HDRLEN) {
+ printf("[|ipfc]");
+ return;
+ }
+ /*
+ * Get the network addresses into a canonical form
+ */
+ extract_ipfc_addrs(ipfcp, (char *)ESRC(&ehdr), (char *)EDST(&ehdr));
+
+ if (eflag)
+ ipfc_hdr_print(ipfcp, length, ESRC(&ehdr), EDST(&ehdr));
+
+ /* Skip over Network_Header */
+ length -= IPFC_HDRLEN;
+ p += IPFC_HDRLEN;
+ caplen -= IPFC_HDRLEN;
+
+ /* Try to print the LLC-layer header & higher layers */
+ if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr),
+ &extracted_ethertype) == 0) {
+ /*
+ * Some kinds of LLC packet we cannot
+ * handle intelligently
+ */
+ if (!eflag)
+ ipfc_hdr_print(ipfcp, length + IPFC_HDRLEN,
+ ESRC(&ehdr), EDST(&ehdr));
+ if (extracted_ethertype) {
+ printf("(LLC %s) ",
+ etherproto_string(htons(extracted_ethertype)));
+ }
+ if (!suppress_default_print)
+ default_print(p, caplen);
+ }
+}
+
+/*
+ * This is the top level routine of the printer. 'p' points
+ * to the Network_Header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ */
+u_int
+ipfc_if_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ ipfc_print(p, h->len, h->caplen);
+
+ return (IPFC_HDRLEN);
+}
diff --git a/freebsd/contrib/tcpdump/print-ipnet.c b/freebsd/contrib/tcpdump/print-ipnet.c
new file mode 100644
index 00000000..75863458
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-ipnet.c
@@ -0,0 +1,111 @@
+#include <machine/rtems-bsd-user-space.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <pcap.h>
+
+#include "netdissect.h"
+#include "interface.h"
+#include "addrtoname.h"
+#include "ipnet.h"
+
+#ifdef DLT_IPNET
+
+const struct tok ipnet_values[] = {
+ { IPH_AF_INET, "IPv4" },
+ { IPH_AF_INET6, "IPv6" },
+ { 0, NULL }
+};
+
+static inline void
+ipnet_hdr_print(struct netdissect_options *ndo, const u_char *bp, u_int length)
+{
+ const ipnet_hdr_t *hdr;
+ hdr = (const ipnet_hdr_t *)bp;
+
+ ND_PRINT((ndo, "%d > %d", hdr->iph_zsrc, hdr->iph_zdst));
+
+ if (!ndo->ndo_qflag) {
+ ND_PRINT((ndo,", family %s (%d)",
+ tok2str(ipnet_values, "Unknown",
+ hdr->iph_family),
+ hdr->iph_family));
+ } else {
+ ND_PRINT((ndo,", %s",
+ tok2str(ipnet_values,
+ "Unknown Ethertype (0x%04x)",
+ hdr->iph_family)));
+ }
+
+ ND_PRINT((ndo, ", length %u: ", length));
+}
+
+static void
+ipnet_print(struct netdissect_options *ndo, const u_char *p, u_int length, u_int caplen)
+{
+ ipnet_hdr_t *hdr;
+
+ if (caplen < sizeof(ipnet_hdr_t)) {
+ ND_PRINT((ndo, "[|ipnet]"));
+ return;
+ }
+
+ if (ndo->ndo_eflag)
+ ipnet_hdr_print(ndo, p, length);
+
+ length -= sizeof(ipnet_hdr_t);
+ caplen -= sizeof(ipnet_hdr_t);
+ hdr = (ipnet_hdr_t *)p;
+ p += sizeof(ipnet_hdr_t);
+
+ switch (hdr->iph_family) {
+
+ case IPH_AF_INET:
+ ip_print(ndo, p, length);
+ break;
+
+#ifdef INET6
+ case IPH_AF_INET6:
+ ip6_print(ndo, p, length);
+ break;
+#endif /*INET6*/
+
+ default:
+ if (!ndo->ndo_eflag)
+ ipnet_hdr_print(ndo, (u_char *)hdr,
+ length + sizeof(ipnet_hdr_t));
+
+ if (!ndo->ndo_suppress_default_print)
+ ndo->ndo_default_print(ndo, p, caplen);
+ break;
+ }
+}
+
+/*
+ * This is the top level routine of the printer. 'p' points
+ * to the ether header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ */
+u_int
+ipnet_if_print(struct netdissect_options *ndo,
+ const struct pcap_pkthdr *h, const u_char *p)
+{
+ ipnet_print(ndo, p, h->len, h->caplen);
+
+ return (sizeof(ipnet_hdr_t));
+}
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */
+
+#endif /* DLT_IPNET */
diff --git a/freebsd/contrib/tcpdump/print-ipx.c b/freebsd/contrib/tcpdump/print-ipx.c
new file mode 100644
index 00000000..ae136429
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-ipx.c
@@ -0,0 +1,225 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Format and print Novell IPX packets.
+ * Contributed by Brad Parker (brad@fcr.com).
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ipx.c,v 1.42 2005-05-06 08:26:44 guy Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ipx.h"
+#include "extract.h"
+
+
+static const char *ipxaddr_string(u_int32_t, const u_char *);
+void ipx_decode(const struct ipxHdr *, const u_char *, u_int);
+void ipx_sap_print(const u_short *, u_int);
+void ipx_rip_print(const u_short *, u_int);
+
+/*
+ * Print IPX datagram packets.
+ */
+void
+ipx_print(const u_char *p, u_int length)
+{
+ const struct ipxHdr *ipx = (const struct ipxHdr *)p;
+
+ if (!eflag)
+ printf("IPX ");
+
+ TCHECK(ipx->srcSkt);
+ (void)printf("%s.%04x > ",
+ ipxaddr_string(EXTRACT_32BITS(ipx->srcNet), ipx->srcNode),
+ EXTRACT_16BITS(&ipx->srcSkt));
+
+ (void)printf("%s.%04x: ",
+ ipxaddr_string(EXTRACT_32BITS(ipx->dstNet), ipx->dstNode),
+ EXTRACT_16BITS(&ipx->dstSkt));
+
+ /* take length from ipx header */
+ TCHECK(ipx->length);
+ length = EXTRACT_16BITS(&ipx->length);
+
+ ipx_decode(ipx, (u_char *)ipx + ipxSize, length - ipxSize);
+ return;
+trunc:
+ printf("[|ipx %d]", length);
+}
+
+static const char *
+ipxaddr_string(u_int32_t net, const u_char *node)
+{
+ static char line[256];
+
+ snprintf(line, sizeof(line), "%08x.%02x:%02x:%02x:%02x:%02x:%02x",
+ net, node[0], node[1], node[2], node[3], node[4], node[5]);
+
+ return line;
+}
+
+void
+ipx_decode(const struct ipxHdr *ipx, const u_char *datap, u_int length)
+{
+ register u_short dstSkt;
+
+ dstSkt = EXTRACT_16BITS(&ipx->dstSkt);
+ switch (dstSkt) {
+ case IPX_SKT_NCP:
+ (void)printf("ipx-ncp %d", length);
+ break;
+ case IPX_SKT_SAP:
+ ipx_sap_print((u_short *)datap, length);
+ break;
+ case IPX_SKT_RIP:
+ ipx_rip_print((u_short *)datap, length);
+ break;
+ case IPX_SKT_NETBIOS:
+ (void)printf("ipx-netbios %d", length);
+#ifdef TCPDUMP_DO_SMB
+ ipx_netbios_print(datap, length);
+#endif
+ break;
+ case IPX_SKT_DIAGNOSTICS:
+ (void)printf("ipx-diags %d", length);
+ break;
+ case IPX_SKT_NWLINK_DGM:
+ (void)printf("ipx-nwlink-dgm %d", length);
+#ifdef TCPDUMP_DO_SMB
+ ipx_netbios_print(datap, length);
+#endif
+ break;
+ case IPX_SKT_EIGRP:
+ eigrp_print(datap, length);
+ break;
+ default:
+ (void)printf("ipx-#%x %d", dstSkt, length);
+ break;
+ }
+}
+
+void
+ipx_sap_print(const u_short *ipx, u_int length)
+{
+ int command, i;
+
+ TCHECK(ipx[0]);
+ command = EXTRACT_16BITS(ipx);
+ ipx++;
+ length -= 2;
+
+ switch (command) {
+ case 1:
+ case 3:
+ if (command == 1)
+ (void)printf("ipx-sap-req");
+ else
+ (void)printf("ipx-sap-nearest-req");
+
+ TCHECK(ipx[0]);
+ (void)printf(" %s", ipxsap_string(htons(EXTRACT_16BITS(&ipx[0]))));
+ break;
+
+ case 2:
+ case 4:
+ if (command == 2)
+ (void)printf("ipx-sap-resp");
+ else
+ (void)printf("ipx-sap-nearest-resp");
+
+ for (i = 0; i < 8 && length > 0; i++) {
+ TCHECK(ipx[0]);
+ (void)printf(" %s '", ipxsap_string(htons(EXTRACT_16BITS(&ipx[0]))));
+ if (fn_printzp((u_char *)&ipx[1], 48, snapend)) {
+ printf("'");
+ goto trunc;
+ }
+ TCHECK2(ipx[25], 10);
+ printf("' addr %s",
+ ipxaddr_string(EXTRACT_32BITS(&ipx[25]), (u_char *)&ipx[27]));
+ ipx += 32;
+ length -= 64;
+ }
+ break;
+ default:
+ (void)printf("ipx-sap-?%x", command);
+ break;
+ }
+ return;
+trunc:
+ printf("[|ipx %d]", length);
+}
+
+void
+ipx_rip_print(const u_short *ipx, u_int length)
+{
+ int command, i;
+
+ TCHECK(ipx[0]);
+ command = EXTRACT_16BITS(ipx);
+ ipx++;
+ length -= 2;
+
+ switch (command) {
+ case 1:
+ (void)printf("ipx-rip-req");
+ if (length > 0) {
+ TCHECK(ipx[3]);
+ (void)printf(" %08x/%d.%d", EXTRACT_32BITS(&ipx[0]),
+ EXTRACT_16BITS(&ipx[2]), EXTRACT_16BITS(&ipx[3]));
+ }
+ break;
+ case 2:
+ (void)printf("ipx-rip-resp");
+ for (i = 0; i < 50 && length > 0; i++) {
+ TCHECK(ipx[3]);
+ (void)printf(" %08x/%d.%d", EXTRACT_32BITS(&ipx[0]),
+ EXTRACT_16BITS(&ipx[2]), EXTRACT_16BITS(&ipx[3]));
+
+ ipx += 4;
+ length -= 8;
+ }
+ break;
+ default:
+ (void)printf("ipx-rip-?%x", command);
+ break;
+ }
+ return;
+trunc:
+ printf("[|ipx %d]", length);
+}
diff --git a/freebsd/contrib/tcpdump/print-isakmp.c b/freebsd/contrib/tcpdump/print-isakmp.c
new file mode 100644
index 00000000..8b9e3508
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-isakmp.c
@@ -0,0 +1,2572 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.61 2008-02-05 19:34:25 guy Exp $ (LBL)";
+#endif
+
+#define NETDISSECT_REWORKED
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <string.h>
+
+#include <stdio.h>
+
+#include "isakmp.h"
+#include "ipsec_doi.h"
+#include "oakley.h"
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h" /* must come after interface.h */
+
+#include "ip.h"
+#ifdef INET6
+#include "ip6.h"
+#endif
+
+#ifndef HAVE_SOCKADDR_STORAGE
+#define sockaddr_storage sockaddr
+#endif
+
+#define DECLARE_PRINTER(func) static const u_char *ike##func##_print( \
+ netdissect_options *ndo, u_char tpay, \
+ const struct isakmp_gen *ext, \
+ u_int item_len, \
+ const u_char *end_pointer, \
+ u_int32_t phase,\
+ u_int32_t doi0, \
+ u_int32_t proto0, int depth)
+
+DECLARE_PRINTER(v1_sa);
+DECLARE_PRINTER(v1_p);
+DECLARE_PRINTER(v1_t);
+DECLARE_PRINTER(v1_ke);
+DECLARE_PRINTER(v1_id);
+DECLARE_PRINTER(v1_cert);
+DECLARE_PRINTER(v1_cr);
+DECLARE_PRINTER(v1_sig);
+DECLARE_PRINTER(v1_hash);
+DECLARE_PRINTER(v1_nonce);
+DECLARE_PRINTER(v1_n);
+DECLARE_PRINTER(v1_d);
+DECLARE_PRINTER(v1_vid);
+
+DECLARE_PRINTER(v2_sa);
+DECLARE_PRINTER(v2_ke);
+DECLARE_PRINTER(v2_ID);
+DECLARE_PRINTER(v2_cert);
+DECLARE_PRINTER(v2_cr);
+DECLARE_PRINTER(v2_auth);
+DECLARE_PRINTER(v2_nonce);
+DECLARE_PRINTER(v2_n);
+DECLARE_PRINTER(v2_d);
+DECLARE_PRINTER(v2_vid);
+DECLARE_PRINTER(v2_TS);
+DECLARE_PRINTER(v2_cp);
+DECLARE_PRINTER(v2_eap);
+
+static const u_char *ikev2_e_print(netdissect_options *ndo,
+ struct isakmp *base,
+ u_char tpay,
+ const struct isakmp_gen *ext,
+ u_int item_len,
+ const u_char *end_pointer,
+ u_int32_t phase,
+ u_int32_t doi0,
+ u_int32_t proto0, int depth);
+
+
+static const u_char *ike_sub0_print(netdissect_options *ndo,u_char, const struct isakmp_gen *,
+ const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
+static const u_char *ikev1_sub_print(netdissect_options *ndo,u_char, const struct isakmp_gen *,
+ const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
+
+static const u_char *ikev2_sub_print(netdissect_options *ndo,
+ struct isakmp *base,
+ u_char np, const struct isakmp_gen *ext,
+ const u_char *ep, u_int32_t phase,
+ u_int32_t doi, u_int32_t proto,
+ int depth);
+
+
+static char *numstr(int);
+static void safememcpy(void *, const void *, size_t);
+
+static void
+ikev1_print(netdissect_options *ndo,
+ const u_char *bp, u_int length,
+ const u_char *bp2, struct isakmp *base);
+
+#define MAXINITIATORS 20
+int ninitiator = 0;
+struct {
+ cookie_t initiator;
+ struct sockaddr_storage iaddr;
+ struct sockaddr_storage raddr;
+} cookiecache[MAXINITIATORS];
+
+/* protocol id */
+static const char *protoidstr[] = {
+ NULL, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp",
+};
+
+/* isakmp->np */
+static const char *npstr[] = {
+ "none", "sa", "p", "t", "ke", "id", "cert", "cr", "hash", /* 0 - 8 */
+ "sig", "nonce", "n", "d", "vid", /* 9 - 13 */
+ "pay14", "pay15", "pay16", "pay17", "pay18", /* 14- 18 */
+ "pay19", "pay20", "pay21", "pay22", "pay23", /* 19- 23 */
+ "pay24", "pay25", "pay26", "pay27", "pay28", /* 24- 28 */
+ "pay29", "pay30", "pay31", "pay32", /* 29- 32 */
+ "v2sa", "v2ke", "v2IDi", "v2IDr", "v2cert",/* 33- 37 */
+ "v2cr", "v2auth","v2nonce", "v2n", "v2d", /* 38- 42 */
+ "v2vid", "v2TSi", "v2TSr", "v2e", "v2cp", /* 43- 47 */
+ "v2eap", /* 48 */
+
+};
+
+/* isakmp->np */
+static const u_char *(*npfunc[])(netdissect_options *ndo, u_char tpay,
+ const struct isakmp_gen *ext,
+ u_int item_len,
+ const u_char *end_pointer,
+ u_int32_t phase,
+ u_int32_t doi0,
+ u_int32_t proto0, int depth) = {
+ NULL,
+ ikev1_sa_print,
+ ikev1_p_print,
+ ikev1_t_print,
+ ikev1_ke_print,
+ ikev1_id_print,
+ ikev1_cert_print,
+ ikev1_cr_print,
+ ikev1_hash_print,
+ ikev1_sig_print,
+ ikev1_nonce_print,
+ ikev1_n_print,
+ ikev1_d_print,
+ ikev1_vid_print, /* 13 */
+ NULL, NULL, NULL, NULL, NULL, /* 14- 18 */
+ NULL, NULL, NULL, NULL, NULL, /* 19- 23 */
+ NULL, NULL, NULL, NULL, NULL, /* 24- 28 */
+ NULL, NULL, NULL, NULL, /* 29- 32 */
+ ikev2_sa_print, /* 33 */
+ ikev2_ke_print, /* 34 */
+ ikev2_ID_print, /* 35 */
+ ikev2_ID_print, /* 36 */
+ ikev2_cert_print, /* 37 */
+ ikev2_cr_print, /* 38 */
+ ikev2_auth_print, /* 39 */
+ ikev2_nonce_print, /* 40 */
+ ikev2_n_print, /* 41 */
+ ikev2_d_print, /* 42 */
+ ikev2_vid_print, /* 43 */
+ ikev2_TS_print, /* 44 */
+ ikev2_TS_print, /* 45 */
+ NULL, /* ikev2_e_print,*/ /* 46 - special */
+ ikev2_cp_print, /* 47 */
+ ikev2_eap_print, /* 48 */
+};
+
+/* isakmp->etype */
+static const char *etypestr[] = {
+/* IKEv1 exchange types */
+ "none", "base", "ident", "auth", "agg", "inf", NULL, NULL, /* 0-7 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 8-15 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 16-23 */
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 24-31 */
+ "oakley-quick", "oakley-newgroup", /* 32-33 */
+/* IKEv2 exchange types */
+ "ikev2_init", "ikev2_auth", "child_sa", "inf2" /* 34-37 */
+};
+
+#define STR_OR_ID(x, tab) \
+ (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x))
+#define PROTOIDSTR(x) STR_OR_ID(x, protoidstr)
+#define NPSTR(x) STR_OR_ID(x, npstr)
+#define ETYPESTR(x) STR_OR_ID(x, etypestr)
+
+#define CHECKLEN(p, np) \
+ if (ep < (u_char *)(p)) { \
+ ND_PRINT((ndo," [|%s]", NPSTR(np))); \
+ goto done; \
+ }
+
+
+#define NPFUNC(x) \
+ (((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) \
+ ? npfunc[(x)] : NULL)
+
+static int
+iszero(u_char *p, size_t l)
+{
+ while (l--) {
+ if (*p++)
+ return 0;
+ }
+ return 1;
+}
+
+/* find cookie from initiator cache */
+static int
+cookie_find(cookie_t *in)
+{
+ int i;
+
+ for (i = 0; i < MAXINITIATORS; i++) {
+ if (memcmp(in, &cookiecache[i].initiator, sizeof(*in)) == 0)
+ return i;
+ }
+
+ return -1;
+}
+
+/* record initiator */
+static void
+cookie_record(cookie_t *in, const u_char *bp2)
+{
+ int i;
+ struct ip *ip;
+ struct sockaddr_in *sin;
+#ifdef INET6
+ struct ip6_hdr *ip6;
+ struct sockaddr_in6 *sin6;
+#endif
+
+ i = cookie_find(in);
+ if (0 <= i) {
+ ninitiator = (i + 1) % MAXINITIATORS;
+ return;
+ }
+
+ ip = (struct ip *)bp2;
+ switch (IP_V(ip)) {
+ case 4:
+ memset(&cookiecache[ninitiator].iaddr, 0,
+ sizeof(cookiecache[ninitiator].iaddr));
+ memset(&cookiecache[ninitiator].raddr, 0,
+ sizeof(cookiecache[ninitiator].raddr));
+
+ sin = (struct sockaddr_in *)&cookiecache[ninitiator].iaddr;
+#ifdef HAVE_SOCKADDR_SA_LEN
+ sin->sin_len = sizeof(struct sockaddr_in);
+#endif
+ sin->sin_family = AF_INET;
+ memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));
+ sin = (struct sockaddr_in *)&cookiecache[ninitiator].raddr;
+#ifdef HAVE_SOCKADDR_SA_LEN
+ sin->sin_len = sizeof(struct sockaddr_in);
+#endif
+ sin->sin_family = AF_INET;
+ memcpy(&sin->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst));
+ break;
+#ifdef INET6
+ case 6:
+ memset(&cookiecache[ninitiator].iaddr, 0,
+ sizeof(cookiecache[ninitiator].iaddr));
+ memset(&cookiecache[ninitiator].raddr, 0,
+ sizeof(cookiecache[ninitiator].raddr));
+
+ ip6 = (struct ip6_hdr *)bp2;
+ sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].iaddr;
+#ifdef HAVE_SOCKADDR_SA_LEN
+ sin6->sin6_len = sizeof(struct sockaddr_in6);
+#endif
+ sin6->sin6_family = AF_INET6;
+ memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src));
+ sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].raddr;
+#ifdef HAVE_SOCKADDR_SA_LEN
+ sin6->sin6_len = sizeof(struct sockaddr_in6);
+#endif
+ sin6->sin6_family = AF_INET6;
+ memcpy(&sin6->sin6_addr, &ip6->ip6_dst, sizeof(ip6->ip6_dst));
+ break;
+#endif
+ default:
+ return;
+ }
+ memcpy(&cookiecache[ninitiator].initiator, in, sizeof(*in));
+ ninitiator = (ninitiator + 1) % MAXINITIATORS;
+}
+
+#define cookie_isinitiator(x, y) cookie_sidecheck((x), (y), 1)
+#define cookie_isresponder(x, y) cookie_sidecheck((x), (y), 0)
+static int
+cookie_sidecheck(int i, const u_char *bp2, int initiator)
+{
+ struct sockaddr_storage ss;
+ struct sockaddr *sa;
+ struct ip *ip;
+ struct sockaddr_in *sin;
+#ifdef INET6
+ struct ip6_hdr *ip6;
+ struct sockaddr_in6 *sin6;
+#endif
+ int salen;
+
+ memset(&ss, 0, sizeof(ss));
+ ip = (struct ip *)bp2;
+ switch (IP_V(ip)) {
+ case 4:
+ sin = (struct sockaddr_in *)&ss;
+#ifdef HAVE_SOCKADDR_SA_LEN
+ sin->sin_len = sizeof(struct sockaddr_in);
+#endif
+ sin->sin_family = AF_INET;
+ memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));
+ break;
+#ifdef INET6
+ case 6:
+ ip6 = (struct ip6_hdr *)bp2;
+ sin6 = (struct sockaddr_in6 *)&ss;
+#ifdef HAVE_SOCKADDR_SA_LEN
+ sin6->sin6_len = sizeof(struct sockaddr_in6);
+#endif
+ sin6->sin6_family = AF_INET6;
+ memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src));
+ break;
+#endif
+ default:
+ return 0;
+ }
+
+ sa = (struct sockaddr *)&ss;
+ if (initiator) {
+ if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].iaddr)->sa_family)
+ return 0;
+#ifdef HAVE_SOCKADDR_SA_LEN
+ salen = sa->sa_len;
+#else
+#ifdef INET6
+ if (sa->sa_family == AF_INET6)
+ salen = sizeof(struct sockaddr_in6);
+ else
+ salen = sizeof(struct sockaddr);
+#else
+ salen = sizeof(struct sockaddr);
+#endif
+#endif
+ if (memcmp(&ss, &cookiecache[i].iaddr, salen) == 0)
+ return 1;
+ } else {
+ if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].raddr)->sa_family)
+ return 0;
+#ifdef HAVE_SOCKADDR_SA_LEN
+ salen = sa->sa_len;
+#else
+#ifdef INET6
+ if (sa->sa_family == AF_INET6)
+ salen = sizeof(struct sockaddr_in6);
+ else
+ salen = sizeof(struct sockaddr);
+#else
+ salen = sizeof(struct sockaddr);
+#endif
+#endif
+ if (memcmp(&ss, &cookiecache[i].raddr, salen) == 0)
+ return 1;
+ }
+ return 0;
+}
+
+static void
+hexprint(netdissect_options *ndo, caddr_t loc, size_t len)
+{
+ u_char *p;
+ size_t i;
+
+ p = (u_char *)loc;
+ for (i = 0; i < len; i++)
+ ND_PRINT((ndo,"%02x", p[i] & 0xff));
+}
+
+static int
+rawprint(netdissect_options *ndo, caddr_t loc, size_t len)
+{
+ ND_TCHECK2(*loc, len);
+
+ hexprint(ndo, loc, len);
+ return 1;
+trunc:
+ return 0;
+}
+
+
+/*
+ * returns false if we run out of data buffer
+ */
+static int ike_show_somedata(struct netdissect_options *ndo,
+ const u_char *cp, const u_char *ep)
+{
+ /* there is too much data, just show some of it */
+ const u_char *end = ep - 20;
+ int elen = 20;
+ int len = ep - cp;
+ if(len > 10) {
+ len = 10;
+ }
+
+ /* really shouldn't happen because of above */
+ if(end < cp + len) {
+ end = cp+len;
+ elen = ep - end;
+ }
+
+ ND_PRINT((ndo," data=("));
+ if(!rawprint(ndo, (caddr_t)(cp), len)) goto trunc;
+ ND_PRINT((ndo, "..."));
+ if(elen) {
+ if(!rawprint(ndo, (caddr_t)(end), elen)) goto trunc;
+ }
+ ND_PRINT((ndo,")"));
+ return 1;
+
+trunc:
+ return 0;
+}
+
+struct attrmap {
+ const char *type;
+ u_int nvalue;
+ const char *value[30]; /*XXX*/
+};
+
+static const u_char *
+ikev1_attrmap_print(netdissect_options *ndo,
+ const u_char *p, const u_char *ep,
+ const struct attrmap *map, size_t nmap)
+{
+ u_int16_t *q;
+ int totlen;
+ u_int32_t t, v;
+
+ q = (u_int16_t *)p;
+ if (p[0] & 0x80)
+ totlen = 4;
+ else
+ totlen = 4 + EXTRACT_16BITS(&q[1]);
+ if (ep < p + totlen) {
+ ND_PRINT((ndo,"[|attr]"));
+ return ep + 1;
+ }
+
+ ND_PRINT((ndo,"("));
+ t = EXTRACT_16BITS(&q[0]) & 0x7fff;
+ if (map && t < nmap && map[t].type)
+ ND_PRINT((ndo,"type=%s ", map[t].type));
+ else
+ ND_PRINT((ndo,"type=#%d ", t));
+ if (p[0] & 0x80) {
+ ND_PRINT((ndo,"value="));
+ v = EXTRACT_16BITS(&q[1]);
+ if (map && t < nmap && v < map[t].nvalue && map[t].value[v])
+ ND_PRINT((ndo,"%s", map[t].value[v]));
+ else
+ rawprint(ndo, (caddr_t)&q[1], 2);
+ } else {
+ ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&q[1])));
+ rawprint(ndo, (caddr_t)&p[4], EXTRACT_16BITS(&q[1]));
+ }
+ ND_PRINT((ndo,")"));
+ return p + totlen;
+}
+
+static const u_char *
+ikev1_attr_print(netdissect_options *ndo, const u_char *p, const u_char *ep)
+{
+ u_int16_t *q;
+ int totlen;
+ u_int32_t t;
+
+ q = (u_int16_t *)p;
+ if (p[0] & 0x80)
+ totlen = 4;
+ else
+ totlen = 4 + EXTRACT_16BITS(&q[1]);
+ if (ep < p + totlen) {
+ ND_PRINT((ndo,"[|attr]"));
+ return ep + 1;
+ }
+
+ ND_PRINT((ndo,"("));
+ t = EXTRACT_16BITS(&q[0]) & 0x7fff;
+ ND_PRINT((ndo,"type=#%d ", t));
+ if (p[0] & 0x80) {
+ ND_PRINT((ndo,"value="));
+ t = q[1];
+ rawprint(ndo, (caddr_t)&q[1], 2);
+ } else {
+ ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&q[1])));
+ rawprint(ndo, (caddr_t)&p[2], EXTRACT_16BITS(&q[1]));
+ }
+ ND_PRINT((ndo,")"));
+ return p + totlen;
+}
+
+static const u_char *
+ikev1_sa_print(netdissect_options *ndo, u_char tpay _U_,
+ const struct isakmp_gen *ext,
+ u_int item_len _U_,
+ const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_,
+ u_int32_t proto0, int depth)
+{
+ const struct ikev1_pl_sa *p;
+ struct ikev1_pl_sa sa;
+ const u_int32_t *q;
+ u_int32_t doi, sit, ident;
+ const u_char *cp, *np;
+ int t;
+
+ ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SA)));
+
+ p = (struct ikev1_pl_sa *)ext;
+ ND_TCHECK(*p);
+ safememcpy(&sa, ext, sizeof(sa));
+ doi = ntohl(sa.doi);
+ sit = ntohl(sa.sit);
+ if (doi != 1) {
+ ND_PRINT((ndo," doi=%d", doi));
+ ND_PRINT((ndo," situation=%u", (u_int32_t)ntohl(sa.sit)));
+ return (u_char *)(p + 1);
+ }
+
+ ND_PRINT((ndo," doi=ipsec"));
+ q = (u_int32_t *)&sa.sit;
+ ND_PRINT((ndo," situation="));
+ t = 0;
+ if (sit & 0x01) {
+ ND_PRINT((ndo,"identity"));
+ t++;
+ }
+ if (sit & 0x02) {
+ ND_PRINT((ndo,"%ssecrecy", t ? "+" : ""));
+ t++;
+ }
+ if (sit & 0x04)
+ ND_PRINT((ndo,"%sintegrity", t ? "+" : ""));
+
+ np = (u_char *)ext + sizeof(sa);
+ if (sit != 0x01) {
+ ND_TCHECK2(*(ext + 1), sizeof(ident));
+ safememcpy(&ident, ext + 1, sizeof(ident));
+ ND_PRINT((ndo," ident=%u", (u_int32_t)ntohl(ident)));
+ np += sizeof(ident);
+ }
+
+ ext = (struct isakmp_gen *)np;
+ ND_TCHECK(*ext);
+
+ cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0,
+ depth);
+
+ return cp;
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_SA)));
+ return NULL;
+}
+
+static const u_char *
+ikev1_p_print(netdissect_options *ndo, u_char tpay _U_,
+ const struct isakmp_gen *ext, u_int item_len _U_,
+ const u_char *ep, u_int32_t phase, u_int32_t doi0,
+ u_int32_t proto0 _U_, int depth)
+{
+ const struct ikev1_pl_p *p;
+ struct ikev1_pl_p prop;
+ const u_char *cp;
+
+ ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_P)));
+
+ p = (struct ikev1_pl_p *)ext;
+ ND_TCHECK(*p);
+ safememcpy(&prop, ext, sizeof(prop));
+ ND_PRINT((ndo," #%d protoid=%s transform=%d",
+ prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t));
+ if (prop.spi_size) {
+ ND_PRINT((ndo," spi="));
+ if (!rawprint(ndo, (caddr_t)(p + 1), prop.spi_size))
+ goto trunc;
+ }
+
+ ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size);
+ ND_TCHECK(*ext);
+
+ cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_T, ext, ep, phase, doi0,
+ prop.prot_id, depth);
+
+ return cp;
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_P)));
+ return NULL;
+}
+
+static const char *ikev1_p_map[] = {
+ NULL, "ike",
+};
+
+static const char *ikev2_t_type_map[]={
+ NULL, "encr", "prf", "integ", "dh", "esn"
+};
+
+static const char *ah_p_map[] = {
+ NULL, "(reserved)", "md5", "sha", "1des",
+ "sha2-256", "sha2-384", "sha2-512",
+};
+
+static const char *prf_p_map[] = {
+ NULL, "hmac-md5", "hmac-sha", "hmac-tiger",
+ "aes128_xcbc"
+};
+
+static const char *integ_p_map[] = {
+ NULL, "hmac-md5", "hmac-sha", "dec-mac",
+ "kpdk-md5", "aes-xcbc"
+};
+
+static const char *esn_p_map[] = {
+ "no-esn", "esn"
+};
+
+static const char *dh_p_map[] = {
+ NULL, "modp768",
+ "modp1024", /* group 2 */
+ "EC2N 2^155", /* group 3 */
+ "EC2N 2^185", /* group 4 */
+ "modp1536", /* group 5 */
+ "iana-grp06", "iana-grp07", /* reserved */
+ "iana-grp08", "iana-grp09",
+ "iana-grp10", "iana-grp11",
+ "iana-grp12", "iana-grp13",
+ "modp2048", /* group 14 */
+ "modp3072", /* group 15 */
+ "modp4096", /* group 16 */
+ "modp6144", /* group 17 */
+ "modp8192", /* group 18 */
+};
+
+static const char *esp_p_map[] = {
+ NULL, "1des-iv64", "1des", "3des", "rc5", "idea", "cast",
+ "blowfish", "3idea", "1des-iv32", "rc4", "null", "aes"
+};
+
+static const char *ipcomp_p_map[] = {
+ NULL, "oui", "deflate", "lzs",
+};
+
+const struct attrmap ipsec_t_map[] = {
+ { NULL, 0, { NULL } },
+ { "lifetype", 3, { NULL, "sec", "kb", }, },
+ { "life", 0, { NULL } },
+ { "group desc", 18, { NULL, "modp768",
+ "modp1024", /* group 2 */
+ "EC2N 2^155", /* group 3 */
+ "EC2N 2^185", /* group 4 */
+ "modp1536", /* group 5 */
+ "iana-grp06", "iana-grp07", /* reserved */
+ "iana-grp08", "iana-grp09",
+ "iana-grp10", "iana-grp11",
+ "iana-grp12", "iana-grp13",
+ "modp2048", /* group 14 */
+ "modp3072", /* group 15 */
+ "modp4096", /* group 16 */
+ "modp6144", /* group 17 */
+ "modp8192", /* group 18 */
+ }, },
+ { "enc mode", 3, { NULL, "tunnel", "transport", }, },
+ { "auth", 5, { NULL, "hmac-md5", "hmac-sha1", "1des-mac", "keyed", }, },
+ { "keylen", 0, { NULL } },
+ { "rounds", 0, { NULL } },
+ { "dictsize", 0, { NULL } },
+ { "privalg", 0, { NULL } },
+};
+
+const struct attrmap encr_t_map[] = {
+ { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 0, 1 */
+ { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 2, 3 */
+ { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 4, 5 */
+ { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 6, 7 */
+ { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 8, 9 */
+ { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 10,11*/
+ { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 12,13*/
+ { "keylen", 14, { NULL }},
+};
+
+const struct attrmap oakley_t_map[] = {
+ { NULL, 0, { NULL } },
+ { "enc", 8, { NULL, "1des", "idea", "blowfish", "rc5",
+ "3des", "cast", "aes", }, },
+ { "hash", 7, { NULL, "md5", "sha1", "tiger",
+ "sha2-256", "sha2-384", "sha2-512", }, },
+ { "auth", 6, { NULL, "preshared", "dss", "rsa sig", "rsa enc",
+ "rsa enc revised", }, },
+ { "group desc", 18, { NULL, "modp768",
+ "modp1024", /* group 2 */
+ "EC2N 2^155", /* group 3 */
+ "EC2N 2^185", /* group 4 */
+ "modp1536", /* group 5 */
+ "iana-grp06", "iana-grp07", /* reserved */
+ "iana-grp08", "iana-grp09",
+ "iana-grp10", "iana-grp11",
+ "iana-grp12", "iana-grp13",
+ "modp2048", /* group 14 */
+ "modp3072", /* group 15 */
+ "modp4096", /* group 16 */
+ "modp6144", /* group 17 */
+ "modp8192", /* group 18 */
+ }, },
+ { "group type", 4, { NULL, "MODP", "ECP", "EC2N", }, },
+ { "group prime", 0, { NULL } },
+ { "group gen1", 0, { NULL } },
+ { "group gen2", 0, { NULL } },
+ { "group curve A", 0, { NULL } },
+ { "group curve B", 0, { NULL } },
+ { "lifetype", 3, { NULL, "sec", "kb", }, },
+ { "lifeduration", 0, { NULL } },
+ { "prf", 0, { NULL } },
+ { "keylen", 0, { NULL } },
+ { "field", 0, { NULL } },
+ { "order", 0, { NULL } },
+};
+
+static const u_char *
+ikev1_t_print(netdissect_options *ndo, u_char tpay _U_,
+ const struct isakmp_gen *ext, u_int item_len,
+ const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_,
+ u_int32_t proto, int depth _U_)
+{
+ const struct ikev1_pl_t *p;
+ struct ikev1_pl_t t;
+ const u_char *cp;
+ const char *idstr;
+ const struct attrmap *map;
+ size_t nmap;
+ const u_char *ep2;
+
+ ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_T)));
+
+ p = (struct ikev1_pl_t *)ext;
+ ND_TCHECK(*p);
+ safememcpy(&t, ext, sizeof(t));
+
+ switch (proto) {
+ case 1:
+ idstr = STR_OR_ID(t.t_id, ikev1_p_map);
+ map = oakley_t_map;
+ nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
+ break;
+ case 2:
+ idstr = STR_OR_ID(t.t_id, ah_p_map);
+ map = ipsec_t_map;
+ nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
+ break;
+ case 3:
+ idstr = STR_OR_ID(t.t_id, esp_p_map);
+ map = ipsec_t_map;
+ nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
+ break;
+ case 4:
+ idstr = STR_OR_ID(t.t_id, ipcomp_p_map);
+ map = ipsec_t_map;
+ nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
+ break;
+ default:
+ idstr = NULL;
+ map = NULL;
+ nmap = 0;
+ break;
+ }
+
+ if (idstr)
+ ND_PRINT((ndo," #%d id=%s ", t.t_no, idstr));
+ else
+ ND_PRINT((ndo," #%d id=%d ", t.t_no, t.t_id));
+ cp = (u_char *)(p + 1);
+ ep2 = (u_char *)p + item_len;
+ while (cp < ep && cp < ep2) {
+ if (map && nmap) {
+ cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2,
+ map, nmap);
+ } else
+ cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2);
+ }
+ if (ep < ep2)
+ ND_PRINT((ndo,"..."));
+ return cp;
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_T)));
+ return NULL;
+}
+
+static const u_char *
+ikev1_ke_print(netdissect_options *ndo, u_char tpay _U_,
+ const struct isakmp_gen *ext, u_int item_len _U_,
+ const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_,
+ u_int32_t proto _U_, int depth _U_)
+{
+ struct isakmp_gen e;
+
+ ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_KE)));
+
+ ND_TCHECK(*ext);
+ safememcpy(&e, ext, sizeof(e));
+ ND_PRINT((ndo," key len=%d", ntohs(e.len) - 4));
+ if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+ ND_PRINT((ndo," "));
+ if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
+ goto trunc;
+ }
+ return (u_char *)ext + ntohs(e.len);
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_KE)));
+ return NULL;
+}
+
+static const u_char *
+ikev1_id_print(netdissect_options *ndo, u_char tpay _U_,
+ const struct isakmp_gen *ext, u_int item_len _U_,
+ const u_char *ep _U_, u_int32_t phase, u_int32_t doi _U_,
+ u_int32_t proto _U_, int depth _U_)
+{
+#define USE_IPSECDOI_IN_PHASE1 1
+ const struct ikev1_pl_id *p;
+ struct ikev1_pl_id id;
+ static const char *idtypestr[] = {
+ "IPv4", "IPv4net", "IPv6", "IPv6net",
+ };
+ static const char *ipsecidtypestr[] = {
+ NULL, "IPv4", "FQDN", "user FQDN", "IPv4net", "IPv6",
+ "IPv6net", "IPv4range", "IPv6range", "ASN1 DN", "ASN1 GN",
+ "keyid",
+ };
+ int len;
+ const u_char *data;
+
+ ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_ID)));
+
+ p = (struct ikev1_pl_id *)ext;
+ ND_TCHECK(*p);
+ safememcpy(&id, ext, sizeof(id));
+ if (sizeof(*p) < item_len) {
+ data = (u_char *)(p + 1);
+ len = item_len - sizeof(*p);
+ } else {
+ data = NULL;
+ len = 0;
+ }
+
+#if 0 /*debug*/
+ ND_PRINT((ndo," [phase=%d doi=%d proto=%d]", phase, doi, proto));
+#endif
+ switch (phase) {
+#ifndef USE_IPSECDOI_IN_PHASE1
+ case 1:
+#endif
+ default:
+ ND_PRINT((ndo," idtype=%s", STR_OR_ID(id.d.id_type, idtypestr)));
+ ND_PRINT((ndo," doi_data=%u",
+ (u_int32_t)(ntohl(id.d.doi_data) & 0xffffff)));
+ break;
+
+#ifdef USE_IPSECDOI_IN_PHASE1
+ case 1:
+#endif
+ case 2:
+ {
+ const struct ipsecdoi_id *p;
+ struct ipsecdoi_id id;
+ struct protoent *pe;
+
+ p = (struct ipsecdoi_id *)ext;
+ ND_TCHECK(*p);
+ safememcpy(&id, ext, sizeof(id));
+ ND_PRINT((ndo," idtype=%s", STR_OR_ID(id.type, ipsecidtypestr)));
+ if (id.proto_id) {
+#ifndef WIN32
+ setprotoent(1);
+#endif /* WIN32 */
+ pe = getprotobynumber(id.proto_id);
+ if (pe)
+ ND_PRINT((ndo," protoid=%s", pe->p_name));
+#ifndef WIN32
+ endprotoent();
+#endif /* WIN32 */
+ } else {
+ /* it DOES NOT mean IPPROTO_IP! */
+ ND_PRINT((ndo," protoid=%s", "0"));
+ }
+ ND_PRINT((ndo," port=%d", ntohs(id.port)));
+ if (!len)
+ break;
+ if (data == NULL)
+ goto trunc;
+ ND_TCHECK2(*data, len);
+ switch (id.type) {
+ case IPSECDOI_ID_IPV4_ADDR:
+ if (len < 4)
+ ND_PRINT((ndo," len=%d [bad: < 4]", len));
+ else
+ ND_PRINT((ndo," len=%d %s", len, ipaddr_string(data)));
+ len = 0;
+ break;
+ case IPSECDOI_ID_FQDN:
+ case IPSECDOI_ID_USER_FQDN:
+ {
+ int i;
+ ND_PRINT((ndo," len=%d ", len));
+ for (i = 0; i < len; i++)
+ safeputchar(data[i]);
+ len = 0;
+ break;
+ }
+ case IPSECDOI_ID_IPV4_ADDR_SUBNET:
+ {
+ const u_char *mask;
+ if (len < 8)
+ ND_PRINT((ndo," len=%d [bad: < 8]", len));
+ else {
+ mask = data + sizeof(struct in_addr);
+ ND_PRINT((ndo," len=%d %s/%u.%u.%u.%u", len,
+ ipaddr_string(data),
+ mask[0], mask[1], mask[2], mask[3]));
+ }
+ len = 0;
+ break;
+ }
+#ifdef INET6
+ case IPSECDOI_ID_IPV6_ADDR:
+ if (len < 16)
+ ND_PRINT((ndo," len=%d [bad: < 16]", len));
+ else
+ ND_PRINT((ndo," len=%d %s", len, ip6addr_string(data)));
+ len = 0;
+ break;
+ case IPSECDOI_ID_IPV6_ADDR_SUBNET:
+ {
+ const u_int32_t *mask;
+ if (len < 20)
+ ND_PRINT((ndo," len=%d [bad: < 20]", len));
+ else {
+ mask = (u_int32_t *)(data + sizeof(struct in6_addr));
+ /*XXX*/
+ ND_PRINT((ndo," len=%d %s/0x%08x%08x%08x%08x", len,
+ ip6addr_string(data),
+ mask[0], mask[1], mask[2], mask[3]));
+ }
+ len = 0;
+ break;
+ }
+#endif /*INET6*/
+ case IPSECDOI_ID_IPV4_ADDR_RANGE:
+ if (len < 8)
+ ND_PRINT((ndo," len=%d [bad: < 8]", len));
+ else {
+ ND_PRINT((ndo," len=%d %s-%s", len,
+ ipaddr_string(data),
+ ipaddr_string(data + sizeof(struct in_addr))));
+ }
+ len = 0;
+ break;
+#ifdef INET6
+ case IPSECDOI_ID_IPV6_ADDR_RANGE:
+ if (len < 32)
+ ND_PRINT((ndo," len=%d [bad: < 32]", len));
+ else {
+ ND_PRINT((ndo," len=%d %s-%s", len,
+ ip6addr_string(data),
+ ip6addr_string(data + sizeof(struct in6_addr))));
+ }
+ len = 0;
+ break;
+#endif /*INET6*/
+ case IPSECDOI_ID_DER_ASN1_DN:
+ case IPSECDOI_ID_DER_ASN1_GN:
+ case IPSECDOI_ID_KEY_ID:
+ break;
+ }
+ break;
+ }
+ }
+ if (data && len) {
+ ND_PRINT((ndo," len=%d", len));
+ if (2 < ndo->ndo_vflag) {
+ ND_PRINT((ndo," "));
+ if (!rawprint(ndo, (caddr_t)data, len))
+ goto trunc;
+ }
+ }
+ return (u_char *)ext + item_len;
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_ID)));
+ return NULL;
+}
+
+static const u_char *
+ikev1_cert_print(netdissect_options *ndo, u_char tpay _U_,
+ const struct isakmp_gen *ext, u_int item_len _U_,
+ const u_char *ep _U_, u_int32_t phase _U_,
+ u_int32_t doi0 _U_,
+ u_int32_t proto0 _U_, int depth _U_)
+{
+ const struct ikev1_pl_cert *p;
+ struct ikev1_pl_cert cert;
+ static const char *certstr[] = {
+ "none", "pkcs7", "pgp", "dns",
+ "x509sign", "x509ke", "kerberos", "crl",
+ "arl", "spki", "x509attr",
+ };
+
+ ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CERT)));
+
+ p = (struct ikev1_pl_cert *)ext;
+ ND_TCHECK(*p);
+ safememcpy(&cert, ext, sizeof(cert));
+ ND_PRINT((ndo," len=%d", item_len - 4));
+ ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
+ if (2 < ndo->ndo_vflag && 4 < item_len) {
+ ND_PRINT((ndo," "));
+ if (!rawprint(ndo, (caddr_t)(ext + 1), item_len - 4))
+ goto trunc;
+ }
+ return (u_char *)ext + item_len;
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_CERT)));
+ return NULL;
+}
+
+static const u_char *
+ikev1_cr_print(netdissect_options *ndo, u_char tpay _U_,
+ const struct isakmp_gen *ext, u_int item_len _U_,
+ const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi0 _U_,
+ u_int32_t proto0 _U_, int depth _U_)
+{
+ const struct ikev1_pl_cert *p;
+ struct ikev1_pl_cert cert;
+ static const char *certstr[] = {
+ "none", "pkcs7", "pgp", "dns",
+ "x509sign", "x509ke", "kerberos", "crl",
+ "arl", "spki", "x509attr",
+ };
+
+ ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CR)));
+
+ p = (struct ikev1_pl_cert *)ext;
+ ND_TCHECK(*p);
+ safememcpy(&cert, ext, sizeof(cert));
+ ND_PRINT((ndo," len=%d", item_len - 4));
+ ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
+ if (2 < ndo->ndo_vflag && 4 < item_len) {
+ ND_PRINT((ndo," "));
+ if (!rawprint(ndo, (caddr_t)(ext + 1), item_len - 4))
+ goto trunc;
+ }
+ return (u_char *)ext + item_len;
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_CR)));
+ return NULL;
+}
+
+static const u_char *
+ikev1_hash_print(netdissect_options *ndo, u_char tpay _U_,
+ const struct isakmp_gen *ext, u_int item_len _U_,
+ const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_,
+ u_int32_t proto _U_, int depth _U_)
+{
+ struct isakmp_gen e;
+
+ ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_HASH)));
+
+ ND_TCHECK(*ext);
+ safememcpy(&e, ext, sizeof(e));
+ ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
+ if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+ ND_PRINT((ndo," "));
+ if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
+ goto trunc;
+ }
+ return (u_char *)ext + ntohs(e.len);
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_HASH)));
+ return NULL;
+}
+
+static const u_char *
+ikev1_sig_print(netdissect_options *ndo, u_char tpay _U_,
+ const struct isakmp_gen *ext, u_int item_len _U_,
+ const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_,
+ u_int32_t proto _U_, int depth _U_)
+{
+ struct isakmp_gen e;
+
+ ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SIG)));
+
+ ND_TCHECK(*ext);
+ safememcpy(&e, ext, sizeof(e));
+ ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
+ if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+ ND_PRINT((ndo," "));
+ if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
+ goto trunc;
+ }
+ return (u_char *)ext + ntohs(e.len);
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_SIG)));
+ return NULL;
+}
+
+static const u_char *
+ikev1_nonce_print(netdissect_options *ndo, u_char tpay _U_,
+ const struct isakmp_gen *ext,
+ u_int item_len _U_,
+ const u_char *ep _U_,
+ u_int32_t phase _U_, u_int32_t doi _U_,
+ u_int32_t proto _U_, int depth _U_)
+{
+ struct isakmp_gen e;
+
+ ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_NONCE)));
+
+ ND_TCHECK(*ext);
+ safememcpy(&e, ext, sizeof(e));
+ ND_PRINT((ndo," n len=%d", ntohs(e.len) - 4));
+ if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+ ND_PRINT((ndo," "));
+ if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
+ goto trunc;
+ } else if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+ ND_PRINT((ndo," "));
+ if (!ike_show_somedata(ndo, (u_char *)(caddr_t)(ext + 1), ep))
+ goto trunc;
+ }
+ return (u_char *)ext + ntohs(e.len);
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_NONCE)));
+ return NULL;
+}
+
+static const u_char *
+ikev1_n_print(netdissect_options *ndo, u_char tpay _U_,
+ const struct isakmp_gen *ext, u_int item_len,
+ const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_,
+ u_int32_t proto0 _U_, int depth)
+{
+ struct ikev1_pl_n *p, n;
+ const u_char *cp;
+ u_char *ep2;
+ u_int32_t doi;
+ u_int32_t proto;
+ static const char *notify_error_str[] = {
+ NULL, "INVALID-PAYLOAD-TYPE",
+ "DOI-NOT-SUPPORTED", "SITUATION-NOT-SUPPORTED",
+ "INVALID-COOKIE", "INVALID-MAJOR-VERSION",
+ "INVALID-MINOR-VERSION", "INVALID-EXCHANGE-TYPE",
+ "INVALID-FLAGS", "INVALID-MESSAGE-ID",
+ "INVALID-PROTOCOL-ID", "INVALID-SPI",
+ "INVALID-TRANSFORM-ID", "ATTRIBUTES-NOT-SUPPORTED",
+ "NO-PROPOSAL-CHOSEN", "BAD-PROPOSAL-SYNTAX",
+ "PAYLOAD-MALFORMED", "INVALID-KEY-INFORMATION",
+ "INVALID-ID-INFORMATION", "INVALID-CERT-ENCODING",
+ "INVALID-CERTIFICATE", "CERT-TYPE-UNSUPPORTED",
+ "INVALID-CERT-AUTHORITY", "INVALID-HASH-INFORMATION",
+ "AUTHENTICATION-FAILED", "INVALID-SIGNATURE",
+ "ADDRESS-NOTIFICATION", "NOTIFY-SA-LIFETIME",
+ "CERTIFICATE-UNAVAILABLE", "UNSUPPORTED-EXCHANGE-TYPE",
+ "UNEQUAL-PAYLOAD-LENGTHS",
+ };
+ static const char *ipsec_notify_error_str[] = {
+ "RESERVED",
+ };
+ static const char *notify_status_str[] = {
+ "CONNECTED",
+ };
+ static const char *ipsec_notify_status_str[] = {
+ "RESPONDER-LIFETIME", "REPLAY-STATUS",
+ "INITIAL-CONTACT",
+ };
+/* NOTE: these macro must be called with x in proper range */
+
+/* 0 - 8191 */
+#define NOTIFY_ERROR_STR(x) \
+ STR_OR_ID((x), notify_error_str)
+
+/* 8192 - 16383 */
+#define IPSEC_NOTIFY_ERROR_STR(x) \
+ STR_OR_ID((u_int)((x) - 8192), ipsec_notify_error_str)
+
+/* 16384 - 24575 */
+#define NOTIFY_STATUS_STR(x) \
+ STR_OR_ID((u_int)((x) - 16384), notify_status_str)
+
+/* 24576 - 32767 */
+#define IPSEC_NOTIFY_STATUS_STR(x) \
+ STR_OR_ID((u_int)((x) - 24576), ipsec_notify_status_str)
+
+ ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_N)));
+
+ p = (struct ikev1_pl_n *)ext;
+ ND_TCHECK(*p);
+ safememcpy(&n, ext, sizeof(n));
+ doi = ntohl(n.doi);
+ proto = n.prot_id;
+ if (doi != 1) {
+ ND_PRINT((ndo," doi=%d", doi));
+ ND_PRINT((ndo," proto=%d", proto));
+ if (ntohs(n.type) < 8192)
+ ND_PRINT((ndo," type=%s", NOTIFY_ERROR_STR(ntohs(n.type))));
+ else if (ntohs(n.type) < 16384)
+ ND_PRINT((ndo," type=%s", numstr(ntohs(n.type))));
+ else if (ntohs(n.type) < 24576)
+ ND_PRINT((ndo," type=%s", NOTIFY_STATUS_STR(ntohs(n.type))));
+ else
+ ND_PRINT((ndo," type=%s", numstr(ntohs(n.type))));
+ if (n.spi_size) {
+ ND_PRINT((ndo," spi="));
+ if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size))
+ goto trunc;
+ }
+ return (u_char *)(p + 1) + n.spi_size;
+ }
+
+ ND_PRINT((ndo," doi=ipsec"));
+ ND_PRINT((ndo," proto=%s", PROTOIDSTR(proto)));
+ if (ntohs(n.type) < 8192)
+ ND_PRINT((ndo," type=%s", NOTIFY_ERROR_STR(ntohs(n.type))));
+ else if (ntohs(n.type) < 16384)
+ ND_PRINT((ndo," type=%s", IPSEC_NOTIFY_ERROR_STR(ntohs(n.type))));
+ else if (ntohs(n.type) < 24576)
+ ND_PRINT((ndo," type=%s", NOTIFY_STATUS_STR(ntohs(n.type))));
+ else if (ntohs(n.type) < 32768)
+ ND_PRINT((ndo," type=%s", IPSEC_NOTIFY_STATUS_STR(ntohs(n.type))));
+ else
+ ND_PRINT((ndo," type=%s", numstr(ntohs(n.type))));
+ if (n.spi_size) {
+ ND_PRINT((ndo," spi="));
+ if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size))
+ goto trunc;
+ }
+
+ cp = (u_char *)(p + 1) + n.spi_size;
+ ep2 = (u_char *)p + item_len;
+
+ if (cp < ep) {
+ ND_PRINT((ndo," orig=("));
+ switch (ntohs(n.type)) {
+ case IPSECDOI_NTYPE_RESPONDER_LIFETIME:
+ {
+ const struct attrmap *map = oakley_t_map;
+ size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
+ while (cp < ep && cp < ep2) {
+ cp = ikev1_attrmap_print(ndo, cp,
+ (ep < ep2) ? ep : ep2, map, nmap);
+ }
+ break;
+ }
+ case IPSECDOI_NTYPE_REPLAY_STATUS:
+ ND_PRINT((ndo,"replay detection %sabled",
+ (*(u_int32_t *)cp) ? "en" : "dis"));
+ break;
+ case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN:
+ if (ikev1_sub_print(ndo, ISAKMP_NPTYPE_SA,
+ (struct isakmp_gen *)cp, ep, phase, doi, proto,
+ depth) == NULL)
+ return NULL;
+ break;
+ default:
+ /* NULL is dummy */
+ isakmp_print(ndo, cp,
+ item_len - sizeof(*p) - n.spi_size,
+ NULL);
+ }
+ ND_PRINT((ndo,")"));
+ }
+ return (u_char *)ext + item_len;
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_N)));
+ return NULL;
+}
+
+static const u_char *
+ikev1_d_print(netdissect_options *ndo, u_char tpay _U_,
+ const struct isakmp_gen *ext, u_int item_len _U_,
+ const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi0 _U_,
+ u_int32_t proto0 _U_, int depth _U_)
+{
+ const struct ikev1_pl_d *p;
+ struct ikev1_pl_d d;
+ const u_int8_t *q;
+ u_int32_t doi;
+ u_int32_t proto;
+ int i;
+
+ ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_D)));
+
+ p = (struct ikev1_pl_d *)ext;
+ ND_TCHECK(*p);
+ safememcpy(&d, ext, sizeof(d));
+ doi = ntohl(d.doi);
+ proto = d.prot_id;
+ if (doi != 1) {
+ ND_PRINT((ndo," doi=%u", doi));
+ ND_PRINT((ndo," proto=%u", proto));
+ } else {
+ ND_PRINT((ndo," doi=ipsec"));
+ ND_PRINT((ndo," proto=%s", PROTOIDSTR(proto)));
+ }
+ ND_PRINT((ndo," spilen=%u", d.spi_size));
+ ND_PRINT((ndo," nspi=%u", ntohs(d.num_spi)));
+ ND_PRINT((ndo," spi="));
+ q = (u_int8_t *)(p + 1);
+ for (i = 0; i < ntohs(d.num_spi); i++) {
+ if (i != 0)
+ ND_PRINT((ndo,","));
+ if (!rawprint(ndo, (caddr_t)q, d.spi_size))
+ goto trunc;
+ q += d.spi_size;
+ }
+ return q;
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_D)));
+ return NULL;
+}
+
+static const u_char *
+ikev1_vid_print(netdissect_options *ndo, u_char tpay _U_,
+ const struct isakmp_gen *ext,
+ u_int item_len _U_, const u_char *ep _U_,
+ u_int32_t phase _U_, u_int32_t doi _U_,
+ u_int32_t proto _U_, int depth _U_)
+{
+ struct isakmp_gen e;
+
+ ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_VID)));
+
+ ND_TCHECK(*ext);
+ safememcpy(&e, ext, sizeof(e));
+ ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
+ if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+ ND_PRINT((ndo," "));
+ if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
+ goto trunc;
+ }
+ return (u_char *)ext + ntohs(e.len);
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_VID)));
+ return NULL;
+}
+
+/************************************************************/
+/* */
+/* IKE v2 - rfc4306 - dissector */
+/* */
+/************************************************************/
+
+static void
+ikev2_pay_print(netdissect_options *ndo, const char *payname, int critical)
+{
+ ND_PRINT((ndo,"%s%s:", payname, critical&0x80 ? "[C]" : ""));
+}
+
+static const u_char *
+ikev2_gen_print(netdissect_options *ndo, u_char tpay,
+ const struct isakmp_gen *ext)
+{
+ struct isakmp_gen e;
+
+ ND_TCHECK(*ext);
+ safememcpy(&e, ext, sizeof(e));
+ ikev2_pay_print(ndo, NPSTR(tpay), e.critical);
+
+ ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
+ if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+ ND_PRINT((ndo," "));
+ if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
+ goto trunc;
+ }
+ return (u_char *)ext + ntohs(e.len);
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
+ return NULL;
+}
+
+static const u_char *
+ikev2_t_print(netdissect_options *ndo, u_char tpay _U_, int pcount,
+ const struct isakmp_gen *ext, u_int item_len,
+ const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_,
+ u_int32_t proto _U_, int depth _U_)
+{
+ const struct ikev2_t *p;
+ struct ikev2_t t;
+ u_int16_t t_id;
+ const u_char *cp;
+ const char *idstr;
+ const struct attrmap *map;
+ size_t nmap;
+ const u_char *ep2;
+
+ p = (struct ikev2_t *)ext;
+ ND_TCHECK(*p);
+ safememcpy(&t, ext, sizeof(t));
+ ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_T), t.h.critical);
+
+ t_id = ntohs(t.t_id);
+
+ map = NULL;
+ nmap = 0;
+
+ switch (t.t_type) {
+ case IV2_T_ENCR:
+ idstr = STR_OR_ID(t_id, esp_p_map);
+ map = encr_t_map;
+ nmap = sizeof(encr_t_map)/sizeof(encr_t_map[0]);
+ break;
+
+ case IV2_T_PRF:
+ idstr = STR_OR_ID(t_id, prf_p_map);
+ break;
+
+ case IV2_T_INTEG:
+ idstr = STR_OR_ID(t_id, integ_p_map);
+ break;
+
+ case IV2_T_DH:
+ idstr = STR_OR_ID(t_id, dh_p_map);
+ break;
+
+ case IV2_T_ESN:
+ idstr = STR_OR_ID(t_id, esn_p_map);
+ break;
+
+ default:
+ idstr = NULL;
+ break;
+ }
+
+ if (idstr)
+ ND_PRINT((ndo," #%u type=%s id=%s ", pcount,
+ STR_OR_ID(t.t_type, ikev2_t_type_map),
+ idstr));
+ else
+ ND_PRINT((ndo," #%u type=%s id=%u ", pcount,
+ STR_OR_ID(t.t_type, ikev2_t_type_map),
+ t.t_id));
+ cp = (u_char *)(p + 1);
+ ep2 = (u_char *)p + item_len;
+ while (cp < ep && cp < ep2) {
+ if (map && nmap) {
+ cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2,
+ map, nmap);
+ } else
+ cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2);
+ }
+ if (ep < ep2)
+ ND_PRINT((ndo,"..."));
+ return cp;
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_T)));
+ return NULL;
+}
+
+static const u_char *
+ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_,
+ const struct isakmp_gen *ext, u_int item_len _U_,
+ const u_char *ep, u_int32_t phase, u_int32_t doi0,
+ u_int32_t proto0 _U_, int depth)
+{
+ const struct ikev2_p *p;
+ struct ikev2_p prop;
+ const u_char *cp;
+
+ p = (struct ikev2_p *)ext;
+ ND_TCHECK(*p);
+ safememcpy(&prop, ext, sizeof(prop));
+ ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_P), prop.h.critical);
+
+ ND_PRINT((ndo," #%u protoid=%s transform=%d len=%u",
+ prop.p_no, PROTOIDSTR(prop.prot_id),
+ prop.num_t, ntohs(prop.h.len)));
+ if (prop.spi_size) {
+ ND_PRINT((ndo," spi="));
+ if (!rawprint(ndo, (caddr_t)(p + 1), prop.spi_size))
+ goto trunc;
+ }
+
+ ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size);
+ ND_TCHECK(*ext);
+
+ cp = ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_T, ext, ep, phase, doi0,
+ prop.prot_id, depth);
+
+ return cp;
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_P)));
+ return NULL;
+}
+
+static const u_char *
+ikev2_sa_print(netdissect_options *ndo, u_char tpay,
+ const struct isakmp_gen *ext1,
+ u_int item_len _U_, const u_char *ep _U_,
+ u_int32_t phase _U_, u_int32_t doi _U_,
+ u_int32_t proto _U_, int depth _U_)
+{
+ struct isakmp_gen e;
+ int osa_length, sa_length;
+
+ ND_TCHECK(*ext1);
+ safememcpy(&e, ext1, sizeof(e));
+ ikev2_pay_print(ndo, "sa", e.critical);
+
+ osa_length= ntohs(e.len);
+ sa_length = osa_length - 4;
+ ND_PRINT((ndo," len=%d", sa_length));
+
+ ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_P,
+ ext1+1, ep,
+ 0, 0, 0, depth);
+
+ return (u_char *)ext1 + osa_length;
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
+ return NULL;
+}
+
+static const u_char *
+ikev2_ke_print(netdissect_options *ndo, u_char tpay,
+ const struct isakmp_gen *ext,
+ u_int item_len _U_, const u_char *ep _U_,
+ u_int32_t phase _U_, u_int32_t doi _U_,
+ u_int32_t proto _U_, int depth _U_)
+{
+ struct ikev2_ke ke;
+ struct ikev2_ke *k;
+
+ k = (struct ikev2_ke *)ext;
+ ND_TCHECK(*ext);
+ safememcpy(&ke, ext, sizeof(ke));
+ ikev2_pay_print(ndo, NPSTR(tpay), ke.h.critical);
+
+ ND_PRINT((ndo," len=%u group=%s", ntohs(ke.h.len) - 8,
+ STR_OR_ID(ntohs(ke.ke_group), dh_p_map)));
+
+ if (2 < ndo->ndo_vflag && 8 < ntohs(ke.h.len)) {
+ ND_PRINT((ndo," "));
+ if (!rawprint(ndo, (caddr_t)(k + 1), ntohs(ke.h.len) - 8))
+ goto trunc;
+ }
+ return (u_char *)ext + ntohs(ke.h.len);
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
+ return NULL;
+}
+
+static const u_char *
+ikev2_ID_print(netdissect_options *ndo, u_char tpay,
+ const struct isakmp_gen *ext,
+ u_int item_len _U_, const u_char *ep _U_,
+ u_int32_t phase _U_, u_int32_t doi _U_,
+ u_int32_t proto _U_, int depth _U_)
+{
+ struct ikev2_id id;
+ int id_len, idtype_len, i;
+ unsigned int dumpascii, dumphex;
+ unsigned char *typedata;
+
+ ND_TCHECK(*ext);
+ safememcpy(&id, ext, sizeof(id));
+ ikev2_pay_print(ndo, NPSTR(tpay), id.h.critical);
+
+ id_len = ntohs(id.h.len);
+
+ ND_PRINT((ndo," len=%d", id_len - 4));
+ if (2 < ndo->ndo_vflag && 4 < id_len) {
+ ND_PRINT((ndo," "));
+ if (!rawprint(ndo, (caddr_t)(ext + 1), id_len - 4))
+ goto trunc;
+ }
+
+ idtype_len =id_len - sizeof(struct ikev2_id);
+ dumpascii = 0;
+ dumphex = 0;
+ typedata = (unsigned char *)(ext)+sizeof(struct ikev2_id);
+
+ switch(id.type) {
+ case ID_IPV4_ADDR:
+ ND_PRINT((ndo, " ipv4:"));
+ dumphex=1;
+ break;
+ case ID_FQDN:
+ ND_PRINT((ndo, " fqdn:"));
+ dumpascii=1;
+ break;
+ case ID_RFC822_ADDR:
+ ND_PRINT((ndo, " rfc822:"));
+ dumpascii=1;
+ break;
+ case ID_IPV6_ADDR:
+ ND_PRINT((ndo, " ipv6:"));
+ dumphex=1;
+ break;
+ case ID_DER_ASN1_DN:
+ ND_PRINT((ndo, " dn:"));
+ dumphex=1;
+ break;
+ case ID_DER_ASN1_GN:
+ ND_PRINT((ndo, " gn:"));
+ dumphex=1;
+ break;
+ case ID_KEY_ID:
+ ND_PRINT((ndo, " keyid:"));
+ dumphex=1;
+ break;
+ }
+
+ if(dumpascii) {
+ ND_TCHECK2(*typedata, idtype_len);
+ for(i=0; i<idtype_len; i++) {
+ if(isprint(typedata[i])) {
+ ND_PRINT((ndo, "%c", typedata[i]));
+ } else {
+ ND_PRINT((ndo, "."));
+ }
+ }
+ }
+ if(dumphex) {
+ if (!rawprint(ndo, (caddr_t)typedata, idtype_len))
+ goto trunc;
+ }
+
+ return (u_char *)ext + id_len;
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
+ return NULL;
+}
+
+static const u_char *
+ikev2_cert_print(netdissect_options *ndo, u_char tpay,
+ const struct isakmp_gen *ext,
+ u_int item_len _U_, const u_char *ep _U_,
+ u_int32_t phase _U_, u_int32_t doi _U_,
+ u_int32_t proto _U_, int depth _U_)
+{
+ return ikev2_gen_print(ndo, tpay, ext);
+}
+
+static const u_char *
+ikev2_cr_print(netdissect_options *ndo, u_char tpay,
+ const struct isakmp_gen *ext,
+ u_int item_len _U_, const u_char *ep _U_,
+ u_int32_t phase _U_, u_int32_t doi _U_,
+ u_int32_t proto _U_, int depth _U_)
+{
+ return ikev2_gen_print(ndo, tpay, ext);
+}
+
+static const u_char *
+ikev2_auth_print(netdissect_options *ndo, u_char tpay,
+ const struct isakmp_gen *ext,
+ u_int item_len _U_, const u_char *ep _U_,
+ u_int32_t phase _U_, u_int32_t doi _U_,
+ u_int32_t proto _U_, int depth _U_)
+{
+ struct ikev2_auth a;
+ const char *v2_auth[]={ "invalid", "rsasig",
+ "shared-secret", "dsssig" };
+ u_char *authdata = (u_char*)ext + sizeof(a);
+ unsigned int len;
+
+ ND_TCHECK(*ext);
+ safememcpy(&a, ext, sizeof(a));
+ ikev2_pay_print(ndo, NPSTR(tpay), a.h.critical);
+ len = ntohs(a.h.len);
+
+ ND_PRINT((ndo," len=%d method=%s", len-4,
+ STR_OR_ID(a.auth_method, v2_auth)));
+
+ if (1 < ndo->ndo_vflag && 4 < len) {
+ ND_PRINT((ndo," authdata=("));
+ if (!rawprint(ndo, (caddr_t)authdata, len - sizeof(a)))
+ goto trunc;
+ ND_PRINT((ndo,") "));
+ } else if(ndo->ndo_vflag && 4 < len) {
+ if(!ike_show_somedata(ndo, authdata, ep)) goto trunc;
+ }
+
+ return (u_char *)ext + len;
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
+ return NULL;
+}
+
+static const u_char *
+ikev2_nonce_print(netdissect_options *ndo, u_char tpay,
+ const struct isakmp_gen *ext,
+ u_int item_len _U_, const u_char *ep _U_,
+ u_int32_t phase _U_, u_int32_t doi _U_,
+ u_int32_t proto _U_, int depth _U_)
+{
+ struct isakmp_gen e;
+
+ ND_TCHECK(*ext);
+ safememcpy(&e, ext, sizeof(e));
+ ikev2_pay_print(ndo, "nonce", e.critical);
+
+ ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
+ if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
+ ND_PRINT((ndo," nonce=("));
+ if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
+ goto trunc;
+ ND_PRINT((ndo,") "));
+ } else if(ndo->ndo_vflag && 4 < ntohs(e.len)) {
+ if(!ike_show_somedata(ndo, (const u_char *)(ext+1), ep)) goto trunc;
+ }
+
+ return (u_char *)ext + ntohs(e.len);
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
+ return NULL;
+}
+
+/* notify payloads */
+static const u_char *
+ikev2_n_print(netdissect_options *ndo, u_char tpay _U_,
+ const struct isakmp_gen *ext,
+ u_int item_len _U_, const u_char *ep _U_,
+ u_int32_t phase _U_, u_int32_t doi _U_,
+ u_int32_t proto _U_, int depth _U_)
+{
+ struct ikev2_n *p, n;
+ const u_char *cp;
+ u_char *ep2;
+ u_char showspi, showdata, showsomedata;
+ const char *notify_name;
+ u_int32_t type;
+
+ p = (struct ikev2_n *)ext;
+ ND_TCHECK(*p);
+ safememcpy(&n, ext, sizeof(n));
+ ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_N), n.h.critical);
+
+ showspi = 1;
+ showdata = 0;
+ showsomedata=0;
+ notify_name=NULL;
+
+ ND_PRINT((ndo," prot_id=%s", PROTOIDSTR(n.prot_id)));
+
+ type = ntohs(n.type);
+
+ /* notify space is annoying sparse */
+ switch(type) {
+ case IV2_NOTIFY_UNSUPPORTED_CRITICAL_PAYLOAD:
+ notify_name = "unsupported_critical_payload";
+ showspi = 0;
+ break;
+
+ case IV2_NOTIFY_INVALID_IKE_SPI:
+ notify_name = "invalid_ike_spi";
+ showspi = 1;
+ break;
+
+ case IV2_NOTIFY_INVALID_MAJOR_VERSION:
+ notify_name = "invalid_major_version";
+ showspi = 0;
+ break;
+
+ case IV2_NOTIFY_INVALID_SYNTAX:
+ notify_name = "invalid_syntax";
+ showspi = 1;
+ break;
+
+ case IV2_NOTIFY_INVALID_MESSAGE_ID:
+ notify_name = "invalid_message_id";
+ showspi = 1;
+ break;
+
+ case IV2_NOTIFY_INVALID_SPI:
+ notify_name = "invalid_spi";
+ showspi = 1;
+ break;
+
+ case IV2_NOTIFY_NO_PROPOSAL_CHOSEN:
+ notify_name = "no_protocol_chosen";
+ showspi = 1;
+ break;
+
+ case IV2_NOTIFY_INVALID_KE_PAYLOAD:
+ notify_name = "invalid_ke_payload";
+ showspi = 1;
+ break;
+
+ case IV2_NOTIFY_AUTHENTICATION_FAILED:
+ notify_name = "authentication_failed";
+ showspi = 1;
+ break;
+
+ case IV2_NOTIFY_SINGLE_PAIR_REQUIRED:
+ notify_name = "single_pair_required";
+ showspi = 1;
+ break;
+
+ case IV2_NOTIFY_NO_ADDITIONAL_SAS:
+ notify_name = "no_additional_sas";
+ showspi = 0;
+ break;
+
+ case IV2_NOTIFY_INTERNAL_ADDRESS_FAILURE:
+ notify_name = "internal_address_failure";
+ showspi = 0;
+ break;
+
+ case IV2_NOTIFY_FAILED_CP_REQUIRED:
+ notify_name = "failed:cp_required";
+ showspi = 0;
+ break;
+
+ case IV2_NOTIFY_INVALID_SELECTORS:
+ notify_name = "invalid_selectors";
+ showspi = 0;
+ break;
+
+ case IV2_NOTIFY_INITIAL_CONTACT:
+ notify_name = "initial_contact";
+ showspi = 0;
+ break;
+
+ case IV2_NOTIFY_SET_WINDOW_SIZE:
+ notify_name = "set_window_size";
+ showspi = 0;
+ break;
+
+ case IV2_NOTIFY_ADDITIONAL_TS_POSSIBLE:
+ notify_name = "additional_ts_possible";
+ showspi = 0;
+ break;
+
+ case IV2_NOTIFY_IPCOMP_SUPPORTED:
+ notify_name = "ipcomp_supported";
+ showspi = 0;
+ break;
+
+ case IV2_NOTIFY_NAT_DETECTION_SOURCE_IP:
+ notify_name = "nat_detection_source_ip";
+ showspi = 1;
+ break;
+
+ case IV2_NOTIFY_NAT_DETECTION_DESTINATION_IP:
+ notify_name = "nat_detection_destination_ip";
+ showspi = 1;
+ break;
+
+ case IV2_NOTIFY_COOKIE:
+ notify_name = "cookie";
+ showspi = 1;
+ showsomedata= 1;
+ showdata= 0;
+ break;
+
+ case IV2_NOTIFY_USE_TRANSPORT_MODE:
+ notify_name = "use_transport_mode";
+ showspi = 0;
+ break;
+
+ case IV2_NOTIFY_HTTP_CERT_LOOKUP_SUPPORTED:
+ notify_name = "http_cert_lookup_supported";
+ showspi = 0;
+ break;
+
+ case IV2_NOTIFY_REKEY_SA:
+ notify_name = "rekey_sa";
+ showspi = 1;
+ break;
+
+ case IV2_NOTIFY_ESP_TFC_PADDING_NOT_SUPPORTED:
+ notify_name = "tfc_padding_not_supported";
+ showspi = 0;
+ break;
+
+ case IV2_NOTIFY_NON_FIRST_FRAGMENTS_ALSO:
+ notify_name = "non_first_fragment_also";
+ showspi = 0;
+ break;
+
+ default:
+ if (type < 8192) {
+ notify_name="error";
+ } else if(type < 16384) {
+ notify_name="private-error";
+ } else if(type < 40960) {
+ notify_name="status";
+ } else {
+ notify_name="private-status";
+ }
+ }
+
+ if(notify_name) {
+ ND_PRINT((ndo," type=%u(%s)", type, notify_name));
+ }
+
+
+ if (showspi && n.spi_size) {
+ ND_PRINT((ndo," spi="));
+ if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size))
+ goto trunc;
+ }
+
+ cp = (u_char *)(p + 1) + n.spi_size;
+ ep2 = (u_char *)p + item_len;
+
+ if(3 < ndo->ndo_vflag) {
+ showdata = 1;
+ }
+
+ if ((showdata || (showsomedata && ep-cp < 30)) && cp < ep) {
+ ND_PRINT((ndo," data=("));
+ if (!rawprint(ndo, (caddr_t)(cp), ep - cp))
+ goto trunc;
+
+ ND_PRINT((ndo,")"));
+
+ } else if(showsomedata && cp < ep) {
+ if(!ike_show_somedata(ndo, cp, ep)) goto trunc;
+ }
+
+ return (u_char *)ext + item_len;
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_N)));
+ return NULL;
+}
+
+static const u_char *
+ikev2_d_print(netdissect_options *ndo, u_char tpay,
+ const struct isakmp_gen *ext,
+ u_int item_len _U_, const u_char *ep _U_,
+ u_int32_t phase _U_, u_int32_t doi _U_,
+ u_int32_t proto _U_, int depth _U_)
+{
+ return ikev2_gen_print(ndo, tpay, ext);
+}
+
+static const u_char *
+ikev2_vid_print(netdissect_options *ndo, u_char tpay,
+ const struct isakmp_gen *ext,
+ u_int item_len _U_, const u_char *ep _U_,
+ u_int32_t phase _U_, u_int32_t doi _U_,
+ u_int32_t proto _U_, int depth _U_)
+{
+ struct isakmp_gen e;
+ const u_char *vid;
+ int i, len;
+
+ ND_TCHECK(*ext);
+ safememcpy(&e, ext, sizeof(e));
+ ikev2_pay_print(ndo, NPSTR(tpay), e.critical);
+ ND_PRINT((ndo," len=%d vid=", ntohs(e.len) - 4));
+
+ vid = (const u_char *)(ext+1);
+ len = ntohs(e.len) - 4;
+ ND_TCHECK2(*vid, len);
+ for(i=0; i<len; i++) {
+ if(isprint(vid[i])) ND_PRINT((ndo, "%c", vid[i]));
+ else ND_PRINT((ndo, "."));
+ }
+ if (2 < ndo->ndo_vflag && 4 < len) {
+ ND_PRINT((ndo," "));
+ if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
+ goto trunc;
+ }
+ return (u_char *)ext + ntohs(e.len);
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
+ return NULL;
+}
+
+static const u_char *
+ikev2_TS_print(netdissect_options *ndo, u_char tpay,
+ const struct isakmp_gen *ext,
+ u_int item_len _U_, const u_char *ep _U_,
+ u_int32_t phase _U_, u_int32_t doi _U_,
+ u_int32_t proto _U_, int depth _U_)
+{
+ return ikev2_gen_print(ndo, tpay, ext);
+}
+
+static const u_char *
+ikev2_e_print(netdissect_options *ndo,
+#ifndef HAVE_LIBCRYPTO
+ _U_
+#endif
+ struct isakmp *base,
+ u_char tpay,
+ const struct isakmp_gen *ext,
+ u_int item_len _U_, const u_char *ep _U_,
+#ifndef HAVE_LIBCRYPTO
+ _U_
+#endif
+ u_int32_t phase,
+#ifndef HAVE_LIBCRYPTO
+ _U_
+#endif
+ u_int32_t doi,
+#ifndef HAVE_LIBCRYPTO
+ _U_
+#endif
+ u_int32_t proto,
+#ifndef HAVE_LIBCRYPTO
+ _U_
+#endif
+ int depth)
+{
+ struct isakmp_gen e;
+ u_char *dat;
+ volatile int dlen;
+
+ ND_TCHECK(*ext);
+ safememcpy(&e, ext, sizeof(e));
+ ikev2_pay_print(ndo, NPSTR(tpay), e.critical);
+
+ dlen = ntohs(e.len)-4;
+
+ ND_PRINT((ndo," len=%d", dlen));
+ if (2 < ndo->ndo_vflag && 4 < dlen) {
+ ND_PRINT((ndo," "));
+ if (!rawprint(ndo, (caddr_t)(ext + 1), dlen))
+ goto trunc;
+ }
+
+ dat = (u_char *)(ext+1);
+ ND_TCHECK2(*dat, dlen);
+
+#ifdef HAVE_LIBCRYPTO
+ /* try to decypt it! */
+ if(esp_print_decrypt_buffer_by_ikev2(ndo,
+ base->flags & ISAKMP_FLAG_I,
+ base->i_ck, base->r_ck,
+ dat, dat+dlen)) {
+
+ ext = (const struct isakmp_gen *)ndo->ndo_packetp;
+
+ /* got it decrypted, print stuff inside. */
+ ikev2_sub_print(ndo, base, e.np, ext, ndo->ndo_snapend,
+ phase, doi, proto, depth+1);
+ }
+#endif
+
+
+ /* always return NULL, because E must be at end, and NP refers
+ * to what was inside.
+ */
+ return NULL;
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
+ return NULL;
+}
+
+static const u_char *
+ikev2_cp_print(netdissect_options *ndo, u_char tpay,
+ const struct isakmp_gen *ext,
+ u_int item_len _U_, const u_char *ep _U_,
+ u_int32_t phase _U_, u_int32_t doi _U_,
+ u_int32_t proto _U_, int depth _U_)
+{
+ return ikev2_gen_print(ndo, tpay, ext);
+}
+
+static const u_char *
+ikev2_eap_print(netdissect_options *ndo, u_char tpay,
+ const struct isakmp_gen *ext,
+ u_int item_len _U_, const u_char *ep _U_,
+ u_int32_t phase _U_, u_int32_t doi _U_,
+ u_int32_t proto _U_, int depth _U_)
+{
+ return ikev2_gen_print(ndo, tpay, ext);
+}
+
+static const u_char *
+ike_sub0_print(netdissect_options *ndo,
+ u_char np, const struct isakmp_gen *ext, const u_char *ep,
+
+ u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
+{
+ const u_char *cp;
+ struct isakmp_gen e;
+ u_int item_len;
+
+ cp = (u_char *)ext;
+ ND_TCHECK(*ext);
+ safememcpy(&e, ext, sizeof(e));
+
+ /*
+ * Since we can't have a payload length of less than 4 bytes,
+ * we need to bail out here if the generic header is nonsensical
+ * or truncated, otherwise we could loop forever processing
+ * zero-length items or otherwise misdissect the packet.
+ */
+ item_len = ntohs(e.len);
+ if (item_len <= 4)
+ return NULL;
+
+ if (NPFUNC(np)) {
+ /*
+ * XXX - what if item_len is too short, or too long,
+ * for this payload type?
+ */
+ cp = (*npfunc[np])(ndo, np, ext, item_len, ep, phase, doi, proto, depth);
+ } else {
+ ND_PRINT((ndo,"%s", NPSTR(np)));
+ cp += item_len;
+ }
+
+ return cp;
+trunc:
+ ND_PRINT((ndo," [|isakmp]"));
+ return NULL;
+}
+
+static const u_char *
+ikev1_sub_print(netdissect_options *ndo,
+ u_char np, const struct isakmp_gen *ext, const u_char *ep,
+ u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
+{
+ const u_char *cp;
+ int i;
+ struct isakmp_gen e;
+
+ cp = (const u_char *)ext;
+
+ while (np) {
+ ND_TCHECK(*ext);
+
+ safememcpy(&e, ext, sizeof(e));
+
+ ND_TCHECK2(*ext, ntohs(e.len));
+
+ depth++;
+ ND_PRINT((ndo,"\n"));
+ for (i = 0; i < depth; i++)
+ ND_PRINT((ndo," "));
+ ND_PRINT((ndo,"("));
+ cp = ike_sub0_print(ndo, np, ext, ep, phase, doi, proto, depth);
+ ND_PRINT((ndo,")"));
+ depth--;
+
+ if (cp == NULL) {
+ /* Zero-length subitem */
+ return NULL;
+ }
+
+ np = e.np;
+ ext = (struct isakmp_gen *)cp;
+ }
+ return cp;
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(np)));
+ return NULL;
+}
+
+static char *
+numstr(int x)
+{
+ static char buf[20];
+ snprintf(buf, sizeof(buf), "#%d", x);
+ return buf;
+}
+
+/*
+ * some compiler tries to optimize memcpy(), using the alignment constraint
+ * on the argument pointer type. by using this function, we try to avoid the
+ * optimization.
+ */
+static void
+safememcpy(void *p, const void *q, size_t l)
+{
+ memcpy(p, q, l);
+}
+
+static void
+ikev1_print(netdissect_options *ndo,
+ const u_char *bp, u_int length,
+ const u_char *bp2, struct isakmp *base)
+{
+ const struct isakmp *p;
+ const u_char *ep;
+ u_char np;
+ int i;
+ int phase;
+
+ p = (const struct isakmp *)bp;
+ ep = ndo->ndo_snapend;
+
+ phase = (*(u_int32_t *)base->msgid == 0) ? 1 : 2;
+ if (phase == 1)
+ ND_PRINT((ndo," phase %d", phase));
+ else
+ ND_PRINT((ndo," phase %d/others", phase));
+
+ i = cookie_find(&base->i_ck);
+ if (i < 0) {
+ if (iszero((u_char *)&base->r_ck, sizeof(base->r_ck))) {
+ /* the first packet */
+ ND_PRINT((ndo," I"));
+ if (bp2)
+ cookie_record(&base->i_ck, bp2);
+ } else
+ ND_PRINT((ndo," ?"));
+ } else {
+ if (bp2 && cookie_isinitiator(i, bp2))
+ ND_PRINT((ndo," I"));
+ else if (bp2 && cookie_isresponder(i, bp2))
+ ND_PRINT((ndo," R"));
+ else
+ ND_PRINT((ndo," ?"));
+ }
+
+ ND_PRINT((ndo," %s", ETYPESTR(base->etype)));
+ if (base->flags) {
+ ND_PRINT((ndo,"[%s%s]", base->flags & ISAKMP_FLAG_E ? "E" : "",
+ base->flags & ISAKMP_FLAG_C ? "C" : ""));
+ }
+
+ if (ndo->ndo_vflag) {
+ const struct isakmp_gen *ext;
+ int nparen;
+
+ ND_PRINT((ndo,":"));
+
+ /* regardless of phase... */
+ if (base->flags & ISAKMP_FLAG_E) {
+ /*
+ * encrypted, nothing we can do right now.
+ * we hope to decrypt the packet in the future...
+ */
+ ND_PRINT((ndo," [encrypted %s]", NPSTR(base->np)));
+ goto done;
+ }
+
+ nparen = 0;
+ CHECKLEN(p + 1, base->np);
+ np = base->np;
+ ext = (struct isakmp_gen *)(p + 1);
+ ikev1_sub_print(ndo, np, ext, ep, phase, 0, 0, 0);
+ }
+
+done:
+ if (ndo->ndo_vflag) {
+ if (ntohl(base->len) != length) {
+ ND_PRINT((ndo," (len mismatch: isakmp %u/ip %u)",
+ (u_int32_t)ntohl(base->len), length));
+ }
+ }
+}
+
+static const u_char *
+ikev2_sub0_print(netdissect_options *ndo, struct isakmp *base,
+ u_char np, int pcount,
+ const struct isakmp_gen *ext, const u_char *ep,
+ u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
+{
+ const u_char *cp;
+ struct isakmp_gen e;
+ u_int item_len;
+
+ cp = (u_char *)ext;
+ ND_TCHECK(*ext);
+ safememcpy(&e, ext, sizeof(e));
+
+ /*
+ * Since we can't have a payload length of less than 4 bytes,
+ * we need to bail out here if the generic header is nonsensical
+ * or truncated, otherwise we could loop forever processing
+ * zero-length items or otherwise misdissect the packet.
+ */
+ item_len = ntohs(e.len);
+ if (item_len <= 4)
+ return NULL;
+
+ if(np == ISAKMP_NPTYPE_P) {
+ cp = ikev2_p_print(ndo, np, pcount, ext, item_len,
+ ep, phase, doi, proto, depth);
+ } else if(np == ISAKMP_NPTYPE_T) {
+ cp = ikev2_t_print(ndo, np, pcount, ext, item_len,
+ ep, phase, doi, proto, depth);
+ } else if(np == ISAKMP_NPTYPE_v2E) {
+ cp = ikev2_e_print(ndo, base, np, ext, item_len,
+ ep, phase, doi, proto, depth);
+ } else if (NPFUNC(np)) {
+ /*
+ * XXX - what if item_len is too short, or too long,
+ * for this payload type?
+ */
+ cp = (*npfunc[np])(ndo, np, /*pcount,*/ ext, item_len,
+ ep, phase, doi, proto, depth);
+ } else {
+ ND_PRINT((ndo,"%s", NPSTR(np)));
+ cp += item_len;
+ }
+
+ return cp;
+trunc:
+ ND_PRINT((ndo," [|isakmp]"));
+ return NULL;
+}
+
+static const u_char *
+ikev2_sub_print(netdissect_options *ndo,
+ struct isakmp *base,
+ u_char np, const struct isakmp_gen *ext, const u_char *ep,
+ u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
+{
+ const u_char *cp;
+ int i;
+ int pcount;
+ struct isakmp_gen e;
+
+ cp = (const u_char *)ext;
+ pcount = 0;
+ while (np) {
+ pcount++;
+ ND_TCHECK(*ext);
+
+ safememcpy(&e, ext, sizeof(e));
+
+ ND_TCHECK2(*ext, ntohs(e.len));
+
+ depth++;
+ ND_PRINT((ndo,"\n"));
+ for (i = 0; i < depth; i++)
+ ND_PRINT((ndo," "));
+ ND_PRINT((ndo,"("));
+ cp = ikev2_sub0_print(ndo, base, np, pcount,
+ ext, ep, phase, doi, proto, depth);
+ ND_PRINT((ndo,")"));
+ depth--;
+
+ if (cp == NULL) {
+ /* Zero-length subitem */
+ return NULL;
+ }
+
+ np = e.np;
+ ext = (struct isakmp_gen *)cp;
+ }
+ return cp;
+trunc:
+ ND_PRINT((ndo," [|%s]", NPSTR(np)));
+ return NULL;
+}
+
+static void
+ikev2_print(netdissect_options *ndo,
+ const u_char *bp, u_int length,
+ const u_char *bp2 _U_, struct isakmp *base)
+{
+ const struct isakmp *p;
+ const u_char *ep;
+ u_char np;
+ int phase;
+
+ p = (const struct isakmp *)bp;
+ ep = ndo->ndo_snapend;
+
+ phase = (*(u_int32_t *)base->msgid == 0) ? 1 : 2;
+ if (phase == 1)
+ ND_PRINT((ndo, " parent_sa"));
+ else
+ ND_PRINT((ndo, " child_sa "));
+
+ ND_PRINT((ndo, " %s", ETYPESTR(base->etype)));
+ if (base->flags) {
+ ND_PRINT((ndo, "[%s%s%s]",
+ base->flags & ISAKMP_FLAG_I ? "I" : "",
+ base->flags & ISAKMP_FLAG_V ? "V" : "",
+ base->flags & ISAKMP_FLAG_R ? "R" : ""));
+ }
+
+ if (ndo->ndo_vflag) {
+ const struct isakmp_gen *ext;
+ int nparen;
+
+ ND_PRINT((ndo, ":"));
+
+ /* regardless of phase... */
+ if (base->flags & ISAKMP_FLAG_E) {
+ /*
+ * encrypted, nothing we can do right now.
+ * we hope to decrypt the packet in the future...
+ */
+ ND_PRINT((ndo, " [encrypted %s]", NPSTR(base->np)));
+ goto done;
+ }
+
+ nparen = 0;
+ CHECKLEN(p + 1, base->np)
+
+ np = base->np;
+ ext = (struct isakmp_gen *)(p + 1);
+ ikev2_sub_print(ndo, base, np, ext, ep, phase, 0, 0, 0);
+ }
+
+done:
+ if (ndo->ndo_vflag) {
+ if (ntohl(base->len) != length) {
+ ND_PRINT((ndo, " (len mismatch: isakmp %u/ip %u)",
+ (u_int32_t)ntohl(base->len), length));
+ }
+ }
+}
+
+void
+isakmp_print(netdissect_options *ndo,
+ const u_char *bp, u_int length,
+ const u_char *bp2)
+{
+ const struct isakmp *p;
+ struct isakmp base;
+ const u_char *ep;
+ int major, minor;
+
+#ifdef HAVE_LIBCRYPTO
+ /* initialize SAs */
+ if (ndo->ndo_sa_list_head == NULL) {
+ if (ndo->ndo_espsecret)
+ esp_print_decodesecret(ndo);
+ }
+#endif
+
+ p = (const struct isakmp *)bp;
+ ep = ndo->ndo_snapend;
+
+ if ((struct isakmp *)ep < p + 1) {
+ ND_PRINT((ndo,"[|isakmp]"));
+ return;
+ }
+
+ safememcpy(&base, p, sizeof(base));
+
+ ND_PRINT((ndo,"isakmp"));
+ major = (base.vers & ISAKMP_VERS_MAJOR)
+ >> ISAKMP_VERS_MAJOR_SHIFT;
+ minor = (base.vers & ISAKMP_VERS_MINOR)
+ >> ISAKMP_VERS_MINOR_SHIFT;
+
+ if (ndo->ndo_vflag) {
+ ND_PRINT((ndo," %d.%d", major, minor));
+ }
+
+ if (ndo->ndo_vflag) {
+ ND_PRINT((ndo," msgid "));
+ hexprint(ndo, (caddr_t)&base.msgid, sizeof(base.msgid));
+ }
+
+ if (1 < ndo->ndo_vflag) {
+ ND_PRINT((ndo," cookie "));
+ hexprint(ndo, (caddr_t)&base.i_ck, sizeof(base.i_ck));
+ ND_PRINT((ndo,"->"));
+ hexprint(ndo, (caddr_t)&base.r_ck, sizeof(base.r_ck));
+ }
+ ND_PRINT((ndo,":"));
+
+ switch(major) {
+ case IKEv1_MAJOR_VERSION:
+ ikev1_print(ndo, bp, length, bp2, &base);
+ break;
+
+ case IKEv2_MAJOR_VERSION:
+ ikev2_print(ndo, bp, length, bp2, &base);
+ break;
+ }
+}
+
+void
+isakmp_rfc3948_print(netdissect_options *ndo,
+ const u_char *bp, u_int length,
+ const u_char *bp2)
+{
+ const u_char *ep;
+ ep = ndo->ndo_snapend;
+
+ if(length == 1 && bp[0]==0xff) {
+ ND_PRINT((ndo, "isakmp-nat-keep-alive"));
+ return;
+ }
+
+ if(length < 4) {
+ goto trunc;
+ }
+
+ /*
+ * see if this is an IKE packet
+ */
+ if(bp[0]==0 && bp[1]==0 && bp[2]==0 && bp[3]==0) {
+ ND_PRINT((ndo, "NONESP-encap: "));
+ isakmp_print(ndo, bp+4, length-4, bp2);
+ return;
+ }
+
+ /* must be an ESP packet */
+ {
+ int nh, enh, padlen;
+ int advance;
+
+ ND_PRINT((ndo, "UDP-encap: "));
+
+ advance = esp_print(ndo, bp, length, bp2, &enh, &padlen);
+ if(advance <= 0)
+ return;
+
+ bp += advance;
+ length -= advance + padlen;
+ nh = enh & 0xff;
+
+ ip_print_inner(ndo, bp, length, nh, bp2);
+ return;
+ }
+
+trunc:
+ ND_PRINT((ndo,"[|isakmp]"));
+ return;
+}
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */
+
+
+
+
diff --git a/freebsd/contrib/tcpdump/print-isoclns.c b/freebsd/contrib/tcpdump/print-isoclns.c
new file mode 100644
index 00000000..a4b9fb95
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-isoclns.c
@@ -0,0 +1,3117 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1992, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Matt Thomas, Digital Equipment Corporation
+ *
+ * Extensively modified by Hannes Gredler (hannes@juniper.net) for more
+ * complete IS-IS & CLNP support.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-isoclns.c,v 1.165 2008-08-16 13:38:15 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+#include "ether.h"
+#include "nlpid.h"
+#include "extract.h"
+#include "gmpls.h"
+#include "oui.h"
+#include "signature.h"
+
+/*
+ * IS-IS is defined in ISO 10589. Look there for protocol definitions.
+ */
+
+#define SYSTEM_ID_LEN ETHER_ADDR_LEN
+#define NODE_ID_LEN SYSTEM_ID_LEN+1
+#define LSP_ID_LEN SYSTEM_ID_LEN+2
+
+#define ISIS_VERSION 1
+#define ESIS_VERSION 1
+#define CLNP_VERSION 1
+
+#define ISIS_PDU_TYPE_MASK 0x1F
+#define ESIS_PDU_TYPE_MASK 0x1F
+#define CLNP_PDU_TYPE_MASK 0x1F
+#define CLNP_FLAG_MASK 0xE0
+#define ISIS_LAN_PRIORITY_MASK 0x7F
+
+#define ISIS_PDU_L1_LAN_IIH 15
+#define ISIS_PDU_L2_LAN_IIH 16
+#define ISIS_PDU_PTP_IIH 17
+#define ISIS_PDU_L1_LSP 18
+#define ISIS_PDU_L2_LSP 20
+#define ISIS_PDU_L1_CSNP 24
+#define ISIS_PDU_L2_CSNP 25
+#define ISIS_PDU_L1_PSNP 26
+#define ISIS_PDU_L2_PSNP 27
+
+static struct tok isis_pdu_values[] = {
+ { ISIS_PDU_L1_LAN_IIH, "L1 Lan IIH"},
+ { ISIS_PDU_L2_LAN_IIH, "L2 Lan IIH"},
+ { ISIS_PDU_PTP_IIH, "p2p IIH"},
+ { ISIS_PDU_L1_LSP, "L1 LSP"},
+ { ISIS_PDU_L2_LSP, "L2 LSP"},
+ { ISIS_PDU_L1_CSNP, "L1 CSNP"},
+ { ISIS_PDU_L2_CSNP, "L2 CSNP"},
+ { ISIS_PDU_L1_PSNP, "L1 PSNP"},
+ { ISIS_PDU_L2_PSNP, "L2 PSNP"},
+ { 0, NULL}
+};
+
+/*
+ * A TLV is a tuple of a type, length and a value and is normally used for
+ * encoding information in all sorts of places. This is an enumeration of
+ * the well known types.
+ *
+ * list taken from rfc3359 plus some memory from veterans ;-)
+ */
+
+#define ISIS_TLV_AREA_ADDR 1 /* iso10589 */
+#define ISIS_TLV_IS_REACH 2 /* iso10589 */
+#define ISIS_TLV_ESNEIGH 3 /* iso10589 */
+#define ISIS_TLV_PART_DIS 4 /* iso10589 */
+#define ISIS_TLV_PREFIX_NEIGH 5 /* iso10589 */
+#define ISIS_TLV_ISNEIGH 6 /* iso10589 */
+#define ISIS_TLV_ISNEIGH_VARLEN 7 /* iso10589 */
+#define ISIS_TLV_PADDING 8 /* iso10589 */
+#define ISIS_TLV_LSP 9 /* iso10589 */
+#define ISIS_TLV_AUTH 10 /* iso10589, rfc3567 */
+#define ISIS_TLV_CHECKSUM 12 /* rfc3358 */
+#define ISIS_TLV_CHECKSUM_MINLEN 2
+#define ISIS_TLV_LSP_BUFFERSIZE 14 /* iso10589 rev2 */
+#define ISIS_TLV_LSP_BUFFERSIZE_MINLEN 2
+#define ISIS_TLV_EXT_IS_REACH 22 /* draft-ietf-isis-traffic-05 */
+#define ISIS_TLV_IS_ALIAS_ID 24 /* draft-ietf-isis-ext-lsp-frags-02 */
+#define ISIS_TLV_DECNET_PHASE4 42
+#define ISIS_TLV_LUCENT_PRIVATE 66
+#define ISIS_TLV_INT_IP_REACH 128 /* rfc1195, rfc2966 */
+#define ISIS_TLV_PROTOCOLS 129 /* rfc1195 */
+#define ISIS_TLV_EXT_IP_REACH 130 /* rfc1195, rfc2966 */
+#define ISIS_TLV_IDRP_INFO 131 /* rfc1195 */
+#define ISIS_TLV_IDRP_INFO_MINLEN 1
+#define ISIS_TLV_IPADDR 132 /* rfc1195 */
+#define ISIS_TLV_IPAUTH 133 /* rfc1195 */
+#define ISIS_TLV_TE_ROUTER_ID 134 /* draft-ietf-isis-traffic-05 */
+#define ISIS_TLV_EXTD_IP_REACH 135 /* draft-ietf-isis-traffic-05 */
+#define ISIS_TLV_HOSTNAME 137 /* rfc2763 */
+#define ISIS_TLV_SHARED_RISK_GROUP 138 /* draft-ietf-isis-gmpls-extensions */
+#define ISIS_TLV_MT_PORT_CAP 143 /* rfc6165 */
+#define ISIS_TLV_MT_CAPABILITY 144 /* rfc6329 */
+#define ISIS_TLV_NORTEL_PRIVATE1 176
+#define ISIS_TLV_NORTEL_PRIVATE2 177
+#define ISIS_TLV_RESTART_SIGNALING 211 /* rfc3847 */
+#define ISIS_TLV_RESTART_SIGNALING_FLAGLEN 1
+#define ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN 2
+#define ISIS_TLV_MT_IS_REACH 222 /* draft-ietf-isis-wg-multi-topology-05 */
+#define ISIS_TLV_MT_SUPPORTED 229 /* draft-ietf-isis-wg-multi-topology-05 */
+#define ISIS_TLV_MT_SUPPORTED_MINLEN 2
+#define ISIS_TLV_IP6ADDR 232 /* draft-ietf-isis-ipv6-02 */
+#define ISIS_TLV_MT_IP_REACH 235 /* draft-ietf-isis-wg-multi-topology-05 */
+#define ISIS_TLV_IP6_REACH 236 /* draft-ietf-isis-ipv6-02 */
+#define ISIS_TLV_MT_IP6_REACH 237 /* draft-ietf-isis-wg-multi-topology-05 */
+#define ISIS_TLV_PTP_ADJ 240 /* rfc3373 */
+#define ISIS_TLV_IIH_SEQNR 241 /* draft-shen-isis-iih-sequence-00 */
+#define ISIS_TLV_IIH_SEQNR_MINLEN 4
+#define ISIS_TLV_VENDOR_PRIVATE 250 /* draft-ietf-isis-experimental-tlv-01 */
+#define ISIS_TLV_VENDOR_PRIVATE_MINLEN 3
+
+static struct tok isis_tlv_values[] = {
+ { ISIS_TLV_AREA_ADDR, "Area address(es)"},
+ { ISIS_TLV_IS_REACH, "IS Reachability"},
+ { ISIS_TLV_ESNEIGH, "ES Neighbor(s)"},
+ { ISIS_TLV_PART_DIS, "Partition DIS"},
+ { ISIS_TLV_PREFIX_NEIGH, "Prefix Neighbors"},
+ { ISIS_TLV_ISNEIGH, "IS Neighbor(s)"},
+ { ISIS_TLV_ISNEIGH_VARLEN, "IS Neighbor(s) (variable length)"},
+ { ISIS_TLV_PADDING, "Padding"},
+ { ISIS_TLV_LSP, "LSP entries"},
+ { ISIS_TLV_AUTH, "Authentication"},
+ { ISIS_TLV_CHECKSUM, "Checksum"},
+ { ISIS_TLV_LSP_BUFFERSIZE, "LSP Buffersize"},
+ { ISIS_TLV_EXT_IS_REACH, "Extended IS Reachability"},
+ { ISIS_TLV_IS_ALIAS_ID, "IS Alias ID"},
+ { ISIS_TLV_DECNET_PHASE4, "DECnet Phase IV"},
+ { ISIS_TLV_LUCENT_PRIVATE, "Lucent Proprietary"},
+ { ISIS_TLV_INT_IP_REACH, "IPv4 Internal Reachability"},
+ { ISIS_TLV_PROTOCOLS, "Protocols supported"},
+ { ISIS_TLV_EXT_IP_REACH, "IPv4 External Reachability"},
+ { ISIS_TLV_IDRP_INFO, "Inter-Domain Information Type"},
+ { ISIS_TLV_IPADDR, "IPv4 Interface address(es)"},
+ { ISIS_TLV_IPAUTH, "IPv4 authentication (deprecated)"},
+ { ISIS_TLV_TE_ROUTER_ID, "Traffic Engineering Router ID"},
+ { ISIS_TLV_EXTD_IP_REACH, "Extended IPv4 Reachability"},
+ { ISIS_TLV_SHARED_RISK_GROUP, "Shared Risk Link Group"},
+ { ISIS_TLV_MT_PORT_CAP, "Multi-Topology-Aware Port Capability"},
+ { ISIS_TLV_MT_CAPABILITY, "Multi-Topology Capability"},
+ { ISIS_TLV_NORTEL_PRIVATE1, "Nortel Proprietary"},
+ { ISIS_TLV_NORTEL_PRIVATE2, "Nortel Proprietary"},
+ { ISIS_TLV_HOSTNAME, "Hostname"},
+ { ISIS_TLV_RESTART_SIGNALING, "Restart Signaling"},
+ { ISIS_TLV_MT_IS_REACH, "Multi Topology IS Reachability"},
+ { ISIS_TLV_MT_SUPPORTED, "Multi Topology"},
+ { ISIS_TLV_IP6ADDR, "IPv6 Interface address(es)"},
+ { ISIS_TLV_MT_IP_REACH, "Multi-Topology IPv4 Reachability"},
+ { ISIS_TLV_IP6_REACH, "IPv6 reachability"},
+ { ISIS_TLV_MT_IP6_REACH, "Multi-Topology IP6 Reachability"},
+ { ISIS_TLV_PTP_ADJ, "Point-to-point Adjacency State"},
+ { ISIS_TLV_IIH_SEQNR, "Hello PDU Sequence Number"},
+ { ISIS_TLV_VENDOR_PRIVATE, "Vendor Private"},
+ { 0, NULL }
+};
+
+#define ESIS_OPTION_PROTOCOLS 129
+#define ESIS_OPTION_QOS_MAINTENANCE 195 /* iso9542 */
+#define ESIS_OPTION_SECURITY 197 /* iso9542 */
+#define ESIS_OPTION_ES_CONF_TIME 198 /* iso9542 */
+#define ESIS_OPTION_PRIORITY 205 /* iso9542 */
+#define ESIS_OPTION_ADDRESS_MASK 225 /* iso9542 */
+#define ESIS_OPTION_SNPA_MASK 226 /* iso9542 */
+
+static struct tok esis_option_values[] = {
+ { ESIS_OPTION_PROTOCOLS, "Protocols supported"},
+ { ESIS_OPTION_QOS_MAINTENANCE, "QoS Maintenance" },
+ { ESIS_OPTION_SECURITY, "Security" },
+ { ESIS_OPTION_ES_CONF_TIME, "ES Configuration Time" },
+ { ESIS_OPTION_PRIORITY, "Priority" },
+ { ESIS_OPTION_ADDRESS_MASK, "Addressk Mask" },
+ { ESIS_OPTION_SNPA_MASK, "SNPA Mask" },
+ { 0, NULL }
+};
+
+#define CLNP_OPTION_DISCARD_REASON 193
+#define CLNP_OPTION_QOS_MAINTENANCE 195 /* iso8473 */
+#define CLNP_OPTION_SECURITY 197 /* iso8473 */
+#define CLNP_OPTION_SOURCE_ROUTING 200 /* iso8473 */
+#define CLNP_OPTION_ROUTE_RECORDING 203 /* iso8473 */
+#define CLNP_OPTION_PADDING 204 /* iso8473 */
+#define CLNP_OPTION_PRIORITY 205 /* iso8473 */
+
+static struct tok clnp_option_values[] = {
+ { CLNP_OPTION_DISCARD_REASON, "Discard Reason"},
+ { CLNP_OPTION_PRIORITY, "Priority"},
+ { CLNP_OPTION_QOS_MAINTENANCE, "QoS Maintenance"},
+ { CLNP_OPTION_SECURITY, "Security"},
+ { CLNP_OPTION_SOURCE_ROUTING, "Source Routing"},
+ { CLNP_OPTION_ROUTE_RECORDING, "Route Recording"},
+ { CLNP_OPTION_PADDING, "Padding"},
+ { 0, NULL }
+};
+
+static struct tok clnp_option_rfd_class_values[] = {
+ { 0x0, "General"},
+ { 0x8, "Address"},
+ { 0x9, "Source Routeing"},
+ { 0xa, "Lifetime"},
+ { 0xb, "PDU Discarded"},
+ { 0xc, "Reassembly"},
+ { 0, NULL }
+};
+
+static struct tok clnp_option_rfd_general_values[] = {
+ { 0x0, "Reason not specified"},
+ { 0x1, "Protocol procedure error"},
+ { 0x2, "Incorrect checksum"},
+ { 0x3, "PDU discarded due to congestion"},
+ { 0x4, "Header syntax error (cannot be parsed)"},
+ { 0x5, "Segmentation needed but not permitted"},
+ { 0x6, "Incomplete PDU received"},
+ { 0x7, "Duplicate option"},
+ { 0, NULL }
+};
+
+static struct tok clnp_option_rfd_address_values[] = {
+ { 0x0, "Destination address unreachable"},
+ { 0x1, "Destination address unknown"},
+ { 0, NULL }
+};
+
+static struct tok clnp_option_rfd_source_routeing_values[] = {
+ { 0x0, "Unspecified source routeing error"},
+ { 0x1, "Syntax error in source routeing field"},
+ { 0x2, "Unknown address in source routeing field"},
+ { 0x3, "Path not acceptable"},
+ { 0, NULL }
+};
+
+static struct tok clnp_option_rfd_lifetime_values[] = {
+ { 0x0, "Lifetime expired while data unit in transit"},
+ { 0x1, "Lifetime expired during reassembly"},
+ { 0, NULL }
+};
+
+static struct tok clnp_option_rfd_pdu_discard_values[] = {
+ { 0x0, "Unsupported option not specified"},
+ { 0x1, "Unsupported protocol version"},
+ { 0x2, "Unsupported security option"},
+ { 0x3, "Unsupported source routeing option"},
+ { 0x4, "Unsupported recording of route option"},
+ { 0, NULL }
+};
+
+static struct tok clnp_option_rfd_reassembly_values[] = {
+ { 0x0, "Reassembly interference"},
+ { 0, NULL }
+};
+
+/* array of 16 error-classes */
+static struct tok *clnp_option_rfd_error_class[] = {
+ clnp_option_rfd_general_values,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ clnp_option_rfd_address_values,
+ clnp_option_rfd_source_routeing_values,
+ clnp_option_rfd_lifetime_values,
+ clnp_option_rfd_pdu_discard_values,
+ clnp_option_rfd_reassembly_values,
+ NULL,
+ NULL,
+ NULL
+};
+
+#define CLNP_OPTION_OPTION_QOS_MASK 0x3f
+#define CLNP_OPTION_SCOPE_MASK 0xc0
+#define CLNP_OPTION_SCOPE_SA_SPEC 0x40
+#define CLNP_OPTION_SCOPE_DA_SPEC 0x80
+#define CLNP_OPTION_SCOPE_GLOBAL 0xc0
+
+static struct tok clnp_option_scope_values[] = {
+ { CLNP_OPTION_SCOPE_SA_SPEC, "Source Address Specific"},
+ { CLNP_OPTION_SCOPE_DA_SPEC, "Destination Address Specific"},
+ { CLNP_OPTION_SCOPE_GLOBAL, "Globally unique"},
+ { 0, NULL }
+};
+
+static struct tok clnp_option_sr_rr_values[] = {
+ { 0x0, "partial"},
+ { 0x1, "complete"},
+ { 0, NULL }
+};
+
+static struct tok clnp_option_sr_rr_string_values[] = {
+ { CLNP_OPTION_SOURCE_ROUTING, "source routing"},
+ { CLNP_OPTION_ROUTE_RECORDING, "recording of route in progress"},
+ { 0, NULL }
+};
+
+static struct tok clnp_option_qos_global_values[] = {
+ { 0x20, "reserved"},
+ { 0x10, "sequencing vs. delay"},
+ { 0x08, "congested"},
+ { 0x04, "delay vs. cost"},
+ { 0x02, "error vs. delay"},
+ { 0x01, "error vs. cost"},
+ { 0, NULL }
+};
+
+#define ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP 3 /* draft-ietf-isis-traffic-05 */
+#define ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID 4 /* rfc4205 */
+#define ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID 5 /* draft-ietf-isis-traffic-05 */
+#define ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR 6 /* draft-ietf-isis-traffic-05 */
+#define ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR 8 /* draft-ietf-isis-traffic-05 */
+#define ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW 9 /* draft-ietf-isis-traffic-05 */
+#define ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW 10 /* draft-ietf-isis-traffic-05 */
+#define ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW 11 /* rfc4124 */
+#define ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD 12 /* draft-ietf-tewg-diff-te-proto-06 */
+#define ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC 18 /* draft-ietf-isis-traffic-05 */
+#define ISIS_SUBTLV_EXT_IS_REACH_LINK_ATTRIBUTE 19 /* draft-ietf-isis-link-attr-01 */
+#define ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE 20 /* rfc4205 */
+#define ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR 21 /* rfc4205 */
+#define ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS 22 /* rfc4124 */
+
+#define ISIS_SUBTLV_SPB_METRIC 29 /* rfc6329 */
+
+static struct tok isis_ext_is_reach_subtlv_values[] = {
+ { ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP, "Administrative groups" },
+ { ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID, "Link Local/Remote Identifier" },
+ { ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID, "Link Remote Identifier" },
+ { ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR, "IPv4 interface address" },
+ { ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR, "IPv4 neighbor address" },
+ { ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW, "Maximum link bandwidth" },
+ { ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW, "Reservable link bandwidth" },
+ { ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW, "Unreserved bandwidth" },
+ { ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC, "Traffic Engineering Metric" },
+ { ISIS_SUBTLV_EXT_IS_REACH_LINK_ATTRIBUTE, "Link Attribute" },
+ { ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE, "Link Protection Type" },
+ { ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR, "Interface Switching Capability" },
+ { ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD, "Bandwidth Constraints (old)" },
+ { ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS, "Bandwidth Constraints" },
+ { ISIS_SUBTLV_SPB_METRIC, "SPB Metric" },
+ { 250, "Reserved for cisco specific extensions" },
+ { 251, "Reserved for cisco specific extensions" },
+ { 252, "Reserved for cisco specific extensions" },
+ { 253, "Reserved for cisco specific extensions" },
+ { 254, "Reserved for cisco specific extensions" },
+ { 255, "Reserved for future expansion" },
+ { 0, NULL }
+};
+
+#define ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32 1 /* draft-ietf-isis-admin-tags-01 */
+#define ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64 2 /* draft-ietf-isis-admin-tags-01 */
+#define ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR 117 /* draft-ietf-isis-wg-multi-topology-05 */
+
+static struct tok isis_ext_ip_reach_subtlv_values[] = {
+ { ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32, "32-Bit Administrative tag" },
+ { ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64, "64-Bit Administrative tag" },
+ { ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR, "Management Prefix Color" },
+ { 0, NULL }
+};
+
+static struct tok isis_subtlv_link_attribute_values[] = {
+ { 0x01, "Local Protection Available" },
+ { 0x02, "Link excluded from local protection path" },
+ { 0x04, "Local maintenance required"},
+ { 0, NULL }
+};
+
+#define ISIS_SUBTLV_AUTH_SIMPLE 1
+#define ISIS_SUBTLV_AUTH_GENERIC 3 /* rfc 5310 */
+#define ISIS_SUBTLV_AUTH_MD5 54
+#define ISIS_SUBTLV_AUTH_MD5_LEN 16
+#define ISIS_SUBTLV_AUTH_PRIVATE 255
+
+static struct tok isis_subtlv_auth_values[] = {
+ { ISIS_SUBTLV_AUTH_SIMPLE, "simple text password"},
+ { ISIS_SUBTLV_AUTH_GENERIC, "Generic Crypto key-id"},
+ { ISIS_SUBTLV_AUTH_MD5, "HMAC-MD5 password"},
+ { ISIS_SUBTLV_AUTH_PRIVATE, "Routing Domain private password"},
+ { 0, NULL }
+};
+
+#define ISIS_SUBTLV_IDRP_RES 0
+#define ISIS_SUBTLV_IDRP_LOCAL 1
+#define ISIS_SUBTLV_IDRP_ASN 2
+
+static struct tok isis_subtlv_idrp_values[] = {
+ { ISIS_SUBTLV_IDRP_RES, "Reserved"},
+ { ISIS_SUBTLV_IDRP_LOCAL, "Routing-Domain Specific"},
+ { ISIS_SUBTLV_IDRP_ASN, "AS Number Tag"},
+ { 0, NULL}
+};
+
+#define ISIS_SUBTLV_SPB_MCID 4
+#define ISIS_SUBTLV_SPB_DIGEST 5
+#define ISIS_SUBTLV_SPB_BVID 6
+
+#define ISIS_SUBTLV_SPB_INSTANCE 1
+#define ISIS_SUBTLV_SPBM_SI 3
+
+#define ISIS_SPB_MCID_LEN 51
+#define ISIS_SUBTLV_SPB_MCID_MIN_LEN 102
+#define ISIS_SUBTLV_SPB_DIGEST_MIN_LEN 33
+#define ISIS_SUBTLV_SPB_BVID_MIN_LEN 6
+#define ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN 19
+#define ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN 8
+
+static struct tok isis_mt_port_cap_subtlv_values[] = {
+ { ISIS_SUBTLV_SPB_MCID, "SPB MCID" },
+ { ISIS_SUBTLV_SPB_DIGEST, "SPB Digest" },
+ { ISIS_SUBTLV_SPB_BVID, "SPB BVID" },
+ { 0, NULL }
+};
+
+static struct tok isis_mt_capability_subtlv_values[] = {
+ { ISIS_SUBTLV_SPB_INSTANCE, "SPB Instance" },
+ { ISIS_SUBTLV_SPBM_SI, "SPBM Service Identifier and Unicast Address" },
+ { 0, NULL }
+};
+
+struct isis_spb_mcid {
+ u_int8_t format_id;
+ u_int8_t name[32];
+ u_int8_t revision_lvl[2];
+ u_int8_t digest[16];
+};
+
+struct isis_subtlv_spb_mcid {
+ struct isis_spb_mcid mcid;
+ struct isis_spb_mcid aux_mcid;
+};
+
+struct isis_subtlv_spb_instance {
+ u_int8_t cist_root_id[8];
+ u_int8_t cist_external_root_path_cost[4];
+ u_int8_t bridge_priority[2];
+ u_int8_t spsourceid[4];
+ u_int8_t no_of_trees;
+};
+
+#define CLNP_SEGMENT_PART 0x80
+#define CLNP_MORE_SEGMENTS 0x40
+#define CLNP_REQUEST_ER 0x20
+
+static struct tok clnp_flag_values[] = {
+ { CLNP_SEGMENT_PART, "Segmentation permitted"},
+ { CLNP_MORE_SEGMENTS, "more Segments"},
+ { CLNP_REQUEST_ER, "request Error Report"},
+ { 0, NULL}
+};
+
+#define ISIS_MASK_LSP_OL_BIT(x) ((x)&0x4)
+#define ISIS_MASK_LSP_ISTYPE_BITS(x) ((x)&0x3)
+#define ISIS_MASK_LSP_PARTITION_BIT(x) ((x)&0x80)
+#define ISIS_MASK_LSP_ATT_BITS(x) ((x)&0x78)
+#define ISIS_MASK_LSP_ATT_ERROR_BIT(x) ((x)&0x40)
+#define ISIS_MASK_LSP_ATT_EXPENSE_BIT(x) ((x)&0x20)
+#define ISIS_MASK_LSP_ATT_DELAY_BIT(x) ((x)&0x10)
+#define ISIS_MASK_LSP_ATT_DEFAULT_BIT(x) ((x)&0x8)
+
+#define ISIS_MASK_MTID(x) ((x)&0x0fff)
+#define ISIS_MASK_MTFLAGS(x) ((x)&0xf000)
+
+static struct tok isis_mt_flag_values[] = {
+ { 0x4000, "ATT bit set"},
+ { 0x8000, "Overload bit set"},
+ { 0, NULL}
+};
+
+#define ISIS_MASK_TLV_EXTD_IP_UPDOWN(x) ((x)&0x80)
+#define ISIS_MASK_TLV_EXTD_IP_SUBTLV(x) ((x)&0x40)
+
+#define ISIS_MASK_TLV_EXTD_IP6_IE(x) ((x)&0x40)
+#define ISIS_MASK_TLV_EXTD_IP6_SUBTLV(x) ((x)&0x20)
+
+#define ISIS_LSP_TLV_METRIC_SUPPORTED(x) ((x)&0x80)
+#define ISIS_LSP_TLV_METRIC_IE(x) ((x)&0x40)
+#define ISIS_LSP_TLV_METRIC_UPDOWN(x) ((x)&0x80)
+#define ISIS_LSP_TLV_METRIC_VALUE(x) ((x)&0x3f)
+
+#define ISIS_MASK_TLV_SHARED_RISK_GROUP(x) ((x)&0x1)
+
+static struct tok isis_mt_values[] = {
+ { 0, "IPv4 unicast"},
+ { 1, "In-Band Management"},
+ { 2, "IPv6 unicast"},
+ { 3, "Multicast"},
+ { 4095, "Development, Experimental or Proprietary"},
+ { 0, NULL }
+};
+
+static struct tok isis_iih_circuit_type_values[] = {
+ { 1, "Level 1 only"},
+ { 2, "Level 2 only"},
+ { 3, "Level 1, Level 2"},
+ { 0, NULL}
+};
+
+#define ISIS_LSP_TYPE_UNUSED0 0
+#define ISIS_LSP_TYPE_LEVEL_1 1
+#define ISIS_LSP_TYPE_UNUSED2 2
+#define ISIS_LSP_TYPE_LEVEL_2 3
+
+static struct tok isis_lsp_istype_values[] = {
+ { ISIS_LSP_TYPE_UNUSED0, "Unused 0x0 (invalid)"},
+ { ISIS_LSP_TYPE_LEVEL_1, "L1 IS"},
+ { ISIS_LSP_TYPE_UNUSED2, "Unused 0x2 (invalid)"},
+ { ISIS_LSP_TYPE_LEVEL_2, "L2 IS"},
+ { 0, NULL }
+};
+
+/*
+ * Katz's point to point adjacency TLV uses codes to tell us the state of
+ * the remote adjacency. Enumerate them.
+ */
+
+#define ISIS_PTP_ADJ_UP 0
+#define ISIS_PTP_ADJ_INIT 1
+#define ISIS_PTP_ADJ_DOWN 2
+
+static struct tok isis_ptp_adjancey_values[] = {
+ { ISIS_PTP_ADJ_UP, "Up" },
+ { ISIS_PTP_ADJ_INIT, "Initializing" },
+ { ISIS_PTP_ADJ_DOWN, "Down" },
+ { 0, NULL}
+};
+
+struct isis_tlv_ptp_adj {
+ u_int8_t adjacency_state;
+ u_int8_t extd_local_circuit_id[4];
+ u_int8_t neighbor_sysid[SYSTEM_ID_LEN];
+ u_int8_t neighbor_extd_local_circuit_id[4];
+};
+
+static void osi_print_cksum(const u_int8_t *pptr, u_int16_t checksum,
+ u_int checksum_offset, u_int length);
+static int clnp_print(const u_int8_t *, u_int);
+static void esis_print(const u_int8_t *, u_int);
+static int isis_print(const u_int8_t *, u_int);
+
+struct isis_metric_block {
+ u_int8_t metric_default;
+ u_int8_t metric_delay;
+ u_int8_t metric_expense;
+ u_int8_t metric_error;
+};
+
+struct isis_tlv_is_reach {
+ struct isis_metric_block isis_metric_block;
+ u_int8_t neighbor_nodeid[NODE_ID_LEN];
+};
+
+struct isis_tlv_es_reach {
+ struct isis_metric_block isis_metric_block;
+ u_int8_t neighbor_sysid[SYSTEM_ID_LEN];
+};
+
+struct isis_tlv_ip_reach {
+ struct isis_metric_block isis_metric_block;
+ u_int8_t prefix[4];
+ u_int8_t mask[4];
+};
+
+static struct tok isis_is_reach_virtual_values[] = {
+ { 0, "IsNotVirtual"},
+ { 1, "IsVirtual"},
+ { 0, NULL }
+};
+
+static struct tok isis_restart_flag_values[] = {
+ { 0x1, "Restart Request"},
+ { 0x2, "Restart Acknowledgement"},
+ { 0x4, "Suppress adjacency advertisement"},
+ { 0, NULL }
+};
+
+struct isis_common_header {
+ u_int8_t nlpid;
+ u_int8_t fixed_len;
+ u_int8_t version; /* Protocol version */
+ u_int8_t id_length;
+ u_int8_t pdu_type; /* 3 MSbits are reserved */
+ u_int8_t pdu_version; /* Packet format version */
+ u_int8_t reserved;
+ u_int8_t max_area;
+};
+
+struct isis_iih_lan_header {
+ u_int8_t circuit_type;
+ u_int8_t source_id[SYSTEM_ID_LEN];
+ u_int8_t holding_time[2];
+ u_int8_t pdu_len[2];
+ u_int8_t priority;
+ u_int8_t lan_id[NODE_ID_LEN];
+};
+
+struct isis_iih_ptp_header {
+ u_int8_t circuit_type;
+ u_int8_t source_id[SYSTEM_ID_LEN];
+ u_int8_t holding_time[2];
+ u_int8_t pdu_len[2];
+ u_int8_t circuit_id;
+};
+
+struct isis_lsp_header {
+ u_int8_t pdu_len[2];
+ u_int8_t remaining_lifetime[2];
+ u_int8_t lsp_id[LSP_ID_LEN];
+ u_int8_t sequence_number[4];
+ u_int8_t checksum[2];
+ u_int8_t typeblock;
+};
+
+struct isis_csnp_header {
+ u_int8_t pdu_len[2];
+ u_int8_t source_id[NODE_ID_LEN];
+ u_int8_t start_lsp_id[LSP_ID_LEN];
+ u_int8_t end_lsp_id[LSP_ID_LEN];
+};
+
+struct isis_psnp_header {
+ u_int8_t pdu_len[2];
+ u_int8_t source_id[NODE_ID_LEN];
+};
+
+struct isis_tlv_lsp {
+ u_int8_t remaining_lifetime[2];
+ u_int8_t lsp_id[LSP_ID_LEN];
+ u_int8_t sequence_number[4];
+ u_int8_t checksum[2];
+};
+
+#define ISIS_COMMON_HEADER_SIZE (sizeof(struct isis_common_header))
+#define ISIS_IIH_LAN_HEADER_SIZE (sizeof(struct isis_iih_lan_header))
+#define ISIS_IIH_PTP_HEADER_SIZE (sizeof(struct isis_iih_ptp_header))
+#define ISIS_LSP_HEADER_SIZE (sizeof(struct isis_lsp_header))
+#define ISIS_CSNP_HEADER_SIZE (sizeof(struct isis_csnp_header))
+#define ISIS_PSNP_HEADER_SIZE (sizeof(struct isis_psnp_header))
+
+void isoclns_print(const u_int8_t *p, u_int length, u_int caplen)
+{
+ if (caplen <= 1) { /* enough bytes on the wire ? */
+ printf("|OSI");
+ return;
+ }
+
+ if (eflag)
+ printf("OSI NLPID %s (0x%02x): ",
+ tok2str(nlpid_values,"Unknown",*p),
+ *p);
+
+ switch (*p) {
+
+ case NLPID_CLNP:
+ if (!clnp_print(p, length))
+ print_unknown_data(p,"\n\t",caplen);
+ break;
+
+ case NLPID_ESIS:
+ esis_print(p, length);
+ return;
+
+ case NLPID_ISIS:
+ if (!isis_print(p, length))
+ print_unknown_data(p,"\n\t",caplen);
+ break;
+
+ case NLPID_NULLNS:
+ (void)printf("%slength: %u",
+ eflag ? "" : ", ",
+ length);
+ break;
+
+ case NLPID_Q933:
+ q933_print(p+1, length-1);
+ break;
+
+ case NLPID_IP:
+ ip_print(gndo, p+1, length-1);
+ break;
+
+#ifdef INET6
+ case NLPID_IP6:
+ ip6_print(gndo, p+1, length-1);
+ break;
+#endif
+
+ case NLPID_PPP:
+ ppp_print(p+1, length-1);
+ break;
+
+ default:
+ if (!eflag)
+ printf("OSI NLPID 0x%02x unknown",*p);
+ (void)printf("%slength: %u",
+ eflag ? "" : ", ",
+ length);
+ if (caplen > 1)
+ print_unknown_data(p,"\n\t",caplen);
+ break;
+ }
+}
+
+#define CLNP_PDU_ER 1
+#define CLNP_PDU_DT 28
+#define CLNP_PDU_MD 29
+#define CLNP_PDU_ERQ 30
+#define CLNP_PDU_ERP 31
+
+static struct tok clnp_pdu_values[] = {
+ { CLNP_PDU_ER, "Error Report"},
+ { CLNP_PDU_MD, "MD"},
+ { CLNP_PDU_DT, "Data"},
+ { CLNP_PDU_ERQ, "Echo Request"},
+ { CLNP_PDU_ERP, "Echo Response"},
+ { 0, NULL }
+};
+
+struct clnp_header_t {
+ u_int8_t nlpid;
+ u_int8_t length_indicator;
+ u_int8_t version;
+ u_int8_t lifetime; /* units of 500ms */
+ u_int8_t type;
+ u_int8_t segment_length[2];
+ u_int8_t cksum[2];
+};
+
+struct clnp_segment_header_t {
+ u_int8_t data_unit_id[2];
+ u_int8_t segment_offset[2];
+ u_int8_t total_length[2];
+};
+
+/*
+ * clnp_print
+ * Decode CLNP packets. Return 0 on error.
+ */
+
+static int clnp_print (const u_int8_t *pptr, u_int length)
+{
+ const u_int8_t *optr,*source_address,*dest_address;
+ u_int li,tlen,nsap_offset,source_address_length,dest_address_length, clnp_pdu_type, clnp_flags;
+ const struct clnp_header_t *clnp_header;
+ const struct clnp_segment_header_t *clnp_segment_header;
+ u_int8_t rfd_error_major,rfd_error_minor;
+
+ clnp_header = (const struct clnp_header_t *) pptr;
+ TCHECK(*clnp_header);
+
+ li = clnp_header->length_indicator;
+ optr = pptr;
+
+ if (!eflag)
+ printf("CLNP");
+
+ /*
+ * Sanity checking of the header.
+ */
+
+ if (clnp_header->version != CLNP_VERSION) {
+ printf("version %d packet not supported", clnp_header->version);
+ return (0);
+ }
+
+ /* FIXME further header sanity checking */
+
+ clnp_pdu_type = clnp_header->type & CLNP_PDU_TYPE_MASK;
+ clnp_flags = clnp_header->type & CLNP_FLAG_MASK;
+
+ pptr += sizeof(struct clnp_header_t);
+ li -= sizeof(struct clnp_header_t);
+ dest_address_length = *pptr;
+ dest_address = pptr + 1;
+
+ pptr += (1 + dest_address_length);
+ li -= (1 + dest_address_length);
+ source_address_length = *pptr;
+ source_address = pptr +1;
+
+ pptr += (1 + source_address_length);
+ li -= (1 + source_address_length);
+
+ if (vflag < 1) {
+ printf("%s%s > %s, %s, length %u",
+ eflag ? "" : ", ",
+ isonsap_string(source_address, source_address_length),
+ isonsap_string(dest_address, dest_address_length),
+ tok2str(clnp_pdu_values,"unknown (%u)",clnp_pdu_type),
+ length);
+ return (1);
+ }
+ printf("%slength %u",eflag ? "" : ", ",length);
+
+ printf("\n\t%s PDU, hlen: %u, v: %u, lifetime: %u.%us, Segment PDU length: %u, checksum: 0x%04x",
+ tok2str(clnp_pdu_values, "unknown (%u)",clnp_pdu_type),
+ clnp_header->length_indicator,
+ clnp_header->version,
+ clnp_header->lifetime/2,
+ (clnp_header->lifetime%2)*5,
+ EXTRACT_16BITS(clnp_header->segment_length),
+ EXTRACT_16BITS(clnp_header->cksum));
+
+ osi_print_cksum(optr, EXTRACT_16BITS(clnp_header->cksum), 7,
+ clnp_header->length_indicator);
+
+ printf("\n\tFlags [%s]",
+ bittok2str(clnp_flag_values,"none",clnp_flags));
+
+ printf("\n\tsource address (length %u): %s\n\tdest address (length %u): %s",
+ source_address_length,
+ isonsap_string(source_address, source_address_length),
+ dest_address_length,
+ isonsap_string(dest_address,dest_address_length));
+
+ if (clnp_flags & CLNP_SEGMENT_PART) {
+ clnp_segment_header = (const struct clnp_segment_header_t *) pptr;
+ TCHECK(*clnp_segment_header);
+ printf("\n\tData Unit ID: 0x%04x, Segment Offset: %u, Total PDU Length: %u",
+ EXTRACT_16BITS(clnp_segment_header->data_unit_id),
+ EXTRACT_16BITS(clnp_segment_header->segment_offset),
+ EXTRACT_16BITS(clnp_segment_header->total_length));
+ pptr+=sizeof(const struct clnp_segment_header_t);
+ li-=sizeof(const struct clnp_segment_header_t);
+ }
+
+ /* now walk the options */
+ while (li >= 2) {
+ u_int op, opli;
+ const u_int8_t *tptr;
+
+ TCHECK2(*pptr, 2);
+ if (li < 2) {
+ printf(", bad opts/li");
+ return (0);
+ }
+ op = *pptr++;
+ opli = *pptr++;
+ li -= 2;
+ TCHECK2(*pptr, opli);
+ if (opli > li) {
+ printf(", opt (%d) too long", op);
+ return (0);
+ }
+ li -= opli;
+ tptr = pptr;
+ tlen = opli;
+
+ printf("\n\t %s Option #%u, length %u, value: ",
+ tok2str(clnp_option_values,"Unknown",op),
+ op,
+ opli);
+
+ switch (op) {
+
+
+ case CLNP_OPTION_ROUTE_RECORDING: /* those two options share the format */
+ case CLNP_OPTION_SOURCE_ROUTING:
+ printf("%s %s",
+ tok2str(clnp_option_sr_rr_values,"Unknown",*tptr),
+ tok2str(clnp_option_sr_rr_string_values,"Unknown Option %u",op));
+ nsap_offset=*(tptr+1);
+ if (nsap_offset == 0) {
+ printf(" Bad NSAP offset (0)");
+ break;
+ }
+ nsap_offset-=1; /* offset to nsap list */
+ if (nsap_offset > tlen) {
+ printf(" Bad NSAP offset (past end of option)");
+ break;
+ }
+ tptr+=nsap_offset;
+ tlen-=nsap_offset;
+ while (tlen > 0) {
+ source_address_length=*tptr;
+ if (tlen < source_address_length+1) {
+ printf("\n\t NSAP address goes past end of option");
+ break;
+ }
+ if (source_address_length > 0) {
+ source_address=(tptr+1);
+ TCHECK2(*source_address, source_address_length);
+ printf("\n\t NSAP address (length %u): %s",
+ source_address_length,
+ isonsap_string(source_address, source_address_length));
+ }
+ tlen-=source_address_length+1;
+ }
+ break;
+
+ case CLNP_OPTION_PRIORITY:
+ printf("0x%1x", *tptr&0x0f);
+ break;
+
+ case CLNP_OPTION_QOS_MAINTENANCE:
+ printf("\n\t Format Code: %s",
+ tok2str(clnp_option_scope_values,"Reserved",*tptr&CLNP_OPTION_SCOPE_MASK));
+
+ if ((*tptr&CLNP_OPTION_SCOPE_MASK) == CLNP_OPTION_SCOPE_GLOBAL)
+ printf("\n\t QoS Flags [%s]",
+ bittok2str(clnp_option_qos_global_values,
+ "none",
+ *tptr&CLNP_OPTION_OPTION_QOS_MASK));
+ break;
+
+ case CLNP_OPTION_SECURITY:
+ printf("\n\t Format Code: %s, Security-Level %u",
+ tok2str(clnp_option_scope_values,"Reserved",*tptr&CLNP_OPTION_SCOPE_MASK),
+ *(tptr+1));
+ break;
+
+ case CLNP_OPTION_DISCARD_REASON:
+ rfd_error_major = (*tptr&0xf0) >> 4;
+ rfd_error_minor = *tptr&0x0f;
+ printf("\n\t Class: %s Error (0x%01x), %s (0x%01x)",
+ tok2str(clnp_option_rfd_class_values,"Unknown",rfd_error_major),
+ rfd_error_major,
+ tok2str(clnp_option_rfd_error_class[rfd_error_major],"Unknown",rfd_error_minor),
+ rfd_error_minor);
+ break;
+
+ case CLNP_OPTION_PADDING:
+ printf("padding data");
+ break;
+
+ /*
+ * FIXME those are the defined Options that lack a decoder
+ * you are welcome to contribute code ;-)
+ */
+
+ default:
+ print_unknown_data(tptr,"\n\t ",opli);
+ break;
+ }
+ if (vflag > 1)
+ print_unknown_data(pptr,"\n\t ",opli);
+ pptr += opli;
+ }
+
+ switch (clnp_pdu_type) {
+
+ case CLNP_PDU_ER: /* fall through */
+ case CLNP_PDU_ERP:
+ TCHECK(*pptr);
+ if (*(pptr) == NLPID_CLNP) {
+ printf("\n\t-----original packet-----\n\t");
+ /* FIXME recursion protection */
+ clnp_print(pptr, length-clnp_header->length_indicator);
+ break;
+ }
+
+ case CLNP_PDU_DT:
+ case CLNP_PDU_MD:
+ case CLNP_PDU_ERQ:
+
+ default:
+ /* dump the PDU specific data */
+ if (length-(pptr-optr) > 0) {
+ printf("\n\t undecoded non-header data, length %u",length-clnp_header->length_indicator);
+ print_unknown_data(pptr,"\n\t ",length-(pptr-optr));
+ }
+ }
+
+ return (1);
+
+ trunc:
+ fputs("[|clnp]", stdout);
+ return (1);
+
+}
+
+
+#define ESIS_PDU_REDIRECT 6
+#define ESIS_PDU_ESH 2
+#define ESIS_PDU_ISH 4
+
+static struct tok esis_pdu_values[] = {
+ { ESIS_PDU_REDIRECT, "redirect"},
+ { ESIS_PDU_ESH, "ESH"},
+ { ESIS_PDU_ISH, "ISH"},
+ { 0, NULL }
+};
+
+struct esis_header_t {
+ u_int8_t nlpid;
+ u_int8_t length_indicator;
+ u_int8_t version;
+ u_int8_t reserved;
+ u_int8_t type;
+ u_int8_t holdtime[2];
+ u_int8_t cksum[2];
+};
+
+static void
+esis_print(const u_int8_t *pptr, u_int length)
+{
+ const u_int8_t *optr;
+ u_int li,esis_pdu_type,source_address_length, source_address_number;
+ const struct esis_header_t *esis_header;
+
+ if (!eflag)
+ printf("ES-IS");
+
+ if (length <= 2) {
+ if (qflag)
+ printf("bad pkt!");
+ else
+ printf("no header at all!");
+ return;
+ }
+
+ esis_header = (const struct esis_header_t *) pptr;
+ TCHECK(*esis_header);
+ li = esis_header->length_indicator;
+ optr = pptr;
+
+ /*
+ * Sanity checking of the header.
+ */
+
+ if (esis_header->nlpid != NLPID_ESIS) {
+ printf(" nlpid 0x%02x packet not supported", esis_header->nlpid);
+ return;
+ }
+
+ if (esis_header->version != ESIS_VERSION) {
+ printf(" version %d packet not supported", esis_header->version);
+ return;
+ }
+
+ if (li > length) {
+ printf(" length indicator(%d) > PDU size (%d)!", li, length);
+ return;
+ }
+
+ if (li < sizeof(struct esis_header_t) + 2) {
+ printf(" length indicator < min PDU size %d:", li);
+ while (--length != 0)
+ printf("%02X", *pptr++);
+ return;
+ }
+
+ esis_pdu_type = esis_header->type & ESIS_PDU_TYPE_MASK;
+
+ if (vflag < 1) {
+ printf("%s%s, length %u",
+ eflag ? "" : ", ",
+ tok2str(esis_pdu_values,"unknown type (%u)",esis_pdu_type),
+ length);
+ return;
+ } else
+ printf("%slength %u\n\t%s (%u)",
+ eflag ? "" : ", ",
+ length,
+ tok2str(esis_pdu_values,"unknown type: %u", esis_pdu_type),
+ esis_pdu_type);
+
+ printf(", v: %u%s", esis_header->version, esis_header->version == ESIS_VERSION ? "" : "unsupported" );
+ printf(", checksum: 0x%04x", EXTRACT_16BITS(esis_header->cksum));
+
+ osi_print_cksum(pptr, EXTRACT_16BITS(esis_header->cksum), 7, li);
+
+ printf(", holding time: %us, length indicator: %u",EXTRACT_16BITS(esis_header->holdtime),li);
+
+ if (vflag > 1)
+ print_unknown_data(optr,"\n\t",sizeof(struct esis_header_t));
+
+ pptr += sizeof(struct esis_header_t);
+ li -= sizeof(struct esis_header_t);
+
+ switch (esis_pdu_type) {
+ case ESIS_PDU_REDIRECT: {
+ const u_int8_t *dst, *snpa, *neta;
+ u_int dstl, snpal, netal;
+
+ TCHECK(*pptr);
+ if (li < 1) {
+ printf(", bad redirect/li");
+ return;
+ }
+ dstl = *pptr;
+ pptr++;
+ li--;
+ TCHECK2(*pptr, dstl);
+ if (li < dstl) {
+ printf(", bad redirect/li");
+ return;
+ }
+ dst = pptr;
+ pptr += dstl;
+ li -= dstl;
+ printf("\n\t %s", isonsap_string(dst,dstl));
+
+ TCHECK(*pptr);
+ if (li < 1) {
+ printf(", bad redirect/li");
+ return;
+ }
+ snpal = *pptr;
+ pptr++;
+ li--;
+ TCHECK2(*pptr, snpal);
+ if (li < snpal) {
+ printf(", bad redirect/li");
+ return;
+ }
+ snpa = pptr;
+ pptr += snpal;
+ li -= snpal;
+ TCHECK(*pptr);
+ if (li < 1) {
+ printf(", bad redirect/li");
+ return;
+ }
+ netal = *pptr;
+ pptr++;
+ TCHECK2(*pptr, netal);
+ if (li < netal) {
+ printf(", bad redirect/li");
+ return;
+ }
+ neta = pptr;
+ pptr += netal;
+ li -= netal;
+
+ if (netal == 0)
+ printf("\n\t %s", etheraddr_string(snpa));
+ else
+ printf("\n\t %s", isonsap_string(neta,netal));
+ break;
+ }
+
+ case ESIS_PDU_ESH:
+ TCHECK(*pptr);
+ if (li < 1) {
+ printf(", bad esh/li");
+ return;
+ }
+ source_address_number = *pptr;
+ pptr++;
+ li--;
+
+ printf("\n\t Number of Source Addresses: %u", source_address_number);
+
+ while (source_address_number > 0) {
+ TCHECK(*pptr);
+ if (li < 1) {
+ printf(", bad esh/li");
+ return;
+ }
+ source_address_length = *pptr;
+ pptr++;
+ li--;
+
+ TCHECK2(*pptr, source_address_length);
+ if (li < source_address_length) {
+ printf(", bad esh/li");
+ return;
+ }
+ printf("\n\t NET (length: %u): %s",
+ source_address_length,
+ isonsap_string(pptr,source_address_length));
+ pptr += source_address_length;
+ li -= source_address_length;
+ source_address_number--;
+ }
+
+ break;
+
+ case ESIS_PDU_ISH: {
+ TCHECK(*pptr);
+ if (li < 1) {
+ printf(", bad ish/li");
+ return;
+ }
+ source_address_length = *pptr;
+ pptr++;
+ li--;
+ TCHECK2(*pptr, source_address_length);
+ if (li < source_address_length) {
+ printf(", bad ish/li");
+ return;
+ }
+ printf("\n\t NET (length: %u): %s", source_address_length, isonsap_string(pptr, source_address_length));
+ pptr += source_address_length;
+ li -= source_address_length;
+ break;
+ }
+
+ default:
+ if (vflag <= 1) {
+ if (pptr < snapend)
+ print_unknown_data(pptr,"\n\t ",snapend-pptr);
+ }
+ return;
+ }
+
+ /* now walk the options */
+ while (li != 0) {
+ u_int op, opli;
+ const u_int8_t *tptr;
+
+ if (li < 2) {
+ printf(", bad opts/li");
+ return;
+ }
+ TCHECK2(*pptr, 2);
+ op = *pptr++;
+ opli = *pptr++;
+ li -= 2;
+ if (opli > li) {
+ printf(", opt (%d) too long", op);
+ return;
+ }
+ li -= opli;
+ tptr = pptr;
+
+ printf("\n\t %s Option #%u, length %u, value: ",
+ tok2str(esis_option_values,"Unknown",op),
+ op,
+ opli);
+
+ switch (op) {
+
+ case ESIS_OPTION_ES_CONF_TIME:
+ if (opli == 2) {
+ TCHECK2(*pptr, 2);
+ printf("%us", EXTRACT_16BITS(tptr));
+ } else
+ printf("(bad length)");
+ break;
+
+ case ESIS_OPTION_PROTOCOLS:
+ while (opli>0) {
+ TCHECK(*pptr);
+ printf("%s (0x%02x)",
+ tok2str(nlpid_values,
+ "unknown",
+ *tptr),
+ *tptr);
+ if (opli>1) /* further NPLIDs ? - put comma */
+ printf(", ");
+ tptr++;
+ opli--;
+ }
+ break;
+
+ /*
+ * FIXME those are the defined Options that lack a decoder
+ * you are welcome to contribute code ;-)
+ */
+
+ case ESIS_OPTION_QOS_MAINTENANCE:
+ case ESIS_OPTION_SECURITY:
+ case ESIS_OPTION_PRIORITY:
+ case ESIS_OPTION_ADDRESS_MASK:
+ case ESIS_OPTION_SNPA_MASK:
+
+ default:
+ print_unknown_data(tptr,"\n\t ",opli);
+ break;
+ }
+ if (vflag > 1)
+ print_unknown_data(pptr,"\n\t ",opli);
+ pptr += opli;
+ }
+trunc:
+ return;
+}
+
+
+static void
+isis_print_mcid (const struct isis_spb_mcid *mcid)
+{
+ int i;
+
+ printf( "ID: %d, Name: ", mcid->format_id);
+
+ for(i=0; i<32; i++)
+ {
+ printf("%c", mcid->name[i]);
+ if(mcid->name[i] == '\0')
+ break;
+ }
+
+ printf("\n\t Lvl: %d",
+ EXTRACT_16BITS(mcid->revision_lvl));
+
+ printf( ", Digest: ");
+
+ for(i=0;i<16;i++)
+ printf("%.2x ",mcid->digest[i]);
+}
+
+static int
+isis_print_mt_port_cap_subtlv (const u_int8_t *tptr, int len)
+{
+ int stlv_type, stlv_len;
+ const struct isis_subtlv_spb_mcid *subtlv_spb_mcid;
+ int i;
+
+ while (len > 0)
+ {
+ stlv_type = *(tptr++);
+ stlv_len = *(tptr++);
+
+ /* first lets see if we know the subTLVs name*/
+ printf("\n\t %s subTLV #%u, length: %u",
+ tok2str(isis_mt_port_cap_subtlv_values, "unknown", stlv_type),
+ stlv_type,
+ stlv_len);
+
+ /*len -= TLV_TYPE_LEN_OFFSET;*/
+ len = len -2;
+
+ switch (stlv_type)
+ {
+ case ISIS_SUBTLV_SPB_MCID:
+ {
+ if (!TTEST2(*(tptr), ISIS_SUBTLV_SPB_MCID_MIN_LEN))
+ goto trunctlv;
+
+ subtlv_spb_mcid = (struct isis_subtlv_spb_mcid *)tptr;
+
+ printf( "\n\t MCID: ");
+ isis_print_mcid (&(subtlv_spb_mcid->mcid));
+
+ /*tptr += SPB_MCID_MIN_LEN;
+ len -= SPB_MCID_MIN_LEN; */
+
+ printf( "\n\t AUX-MCID: ");
+ isis_print_mcid (&(subtlv_spb_mcid->aux_mcid));
+
+ /*tptr += SPB_MCID_MIN_LEN;
+ len -= SPB_MCID_MIN_LEN; */
+ tptr = tptr + sizeof(struct isis_subtlv_spb_mcid);
+ len = len - sizeof(struct isis_subtlv_spb_mcid);
+
+ break;
+ }
+
+ case ISIS_SUBTLV_SPB_DIGEST:
+ {
+ if (!TTEST2(*(tptr), ISIS_SUBTLV_SPB_DIGEST_MIN_LEN))
+ goto trunctlv;
+
+ printf ("\n\t RES: %d V: %d A: %d D: %d",
+ (*(tptr) >> 5), (((*tptr)>> 4) & 0x01),
+ ((*(tptr) >> 2) & 0x03), ((*tptr) & 0x03));
+
+ tptr++;
+
+ printf( "\n\t Digest: ");
+
+ for(i=1;i<=8; i++)
+ {
+ printf("%08x ", EXTRACT_32BITS(tptr));
+ if (i%4 == 0 && i != 8)
+ printf("\n\t ");
+ tptr = tptr + 4;
+ }
+
+ len = len - ISIS_SUBTLV_SPB_DIGEST_MIN_LEN;
+
+ break;
+ }
+
+ case ISIS_SUBTLV_SPB_BVID:
+ {
+ if (!TTEST2(*(tptr), stlv_len))
+ goto trunctlv;
+
+ while (len)
+ {
+ if (!TTEST2(*(tptr), ISIS_SUBTLV_SPB_BVID_MIN_LEN))
+ goto trunctlv;
+
+ printf("\n\t ECT: %08x",
+ EXTRACT_32BITS(tptr));
+
+ tptr = tptr+4;
+
+ printf(" BVID: %d, U:%01x M:%01x ",
+ (EXTRACT_16BITS (tptr) >> 4) ,
+ (EXTRACT_16BITS (tptr) >> 3) & 0x01,
+ (EXTRACT_16BITS (tptr) >> 2) & 0x01);
+
+ tptr = tptr + 2;
+ len = len - ISIS_SUBTLV_SPB_BVID_MIN_LEN;
+ }
+
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ return 0;
+
+ trunctlv:
+ printf("\n\t\t packet exceeded snapshot");
+ return(1);
+}
+
+static int
+isis_print_mt_capability_subtlv (const u_int8_t *tptr, int len)
+{
+ int stlv_type, stlv_len, tmp;
+
+ while (len > 0)
+ {
+ stlv_type = *(tptr++);
+ stlv_len = *(tptr++);
+
+ /* first lets see if we know the subTLVs name*/
+ printf("\n\t %s subTLV #%u, length: %u",
+ tok2str(isis_mt_capability_subtlv_values, "unknown", stlv_type),
+ stlv_type,
+ stlv_len);
+
+ len = len - 2;
+
+ switch (stlv_type)
+ {
+ case ISIS_SUBTLV_SPB_INSTANCE:
+
+ if (!TTEST2(*(tptr), ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN))
+ goto trunctlv;
+
+ printf("\n\t CIST Root-ID: %08x", EXTRACT_32BITS(tptr));
+ tptr = tptr+4;
+ printf(" %08x", EXTRACT_32BITS(tptr));
+ tptr = tptr+4;
+ printf(", Path Cost: %08x", EXTRACT_32BITS(tptr));
+ tptr = tptr+4;
+ printf(", Prio: %d", EXTRACT_16BITS(tptr));
+ tptr = tptr + 2;
+ printf("\n\t RES: %d",
+ EXTRACT_16BITS(tptr) >> 5);
+ printf(", V: %d",
+ (EXTRACT_16BITS(tptr) >> 4) & 0x0001);
+ printf(", SPSource-ID: %d",
+ (EXTRACT_32BITS(tptr) & 0x000fffff));
+ tptr = tptr+4;
+ printf(", No of Trees: %x", *(tptr));
+
+ tmp = *(tptr++);
+
+ len = len - ISIS_SUBTLV_SPB_INSTANCE_MIN_LEN;
+
+ while (tmp)
+ {
+ if (!TTEST2(*(tptr), ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN))
+ goto trunctlv;
+
+ printf ("\n\t U:%d, M:%d, A:%d, RES:%d",
+ *(tptr) >> 7, (*(tptr) >> 6) & 0x01,
+ (*(tptr) >> 5) & 0x01, (*(tptr) & 0x1f));
+
+ tptr++;
+
+ printf (", ECT: %08x", EXTRACT_32BITS(tptr));
+
+ tptr = tptr + 4;
+
+ printf (", BVID: %d, SPVID: %d",
+ (EXTRACT_24BITS(tptr) >> 12) & 0x000fff,
+ EXTRACT_24BITS(tptr) & 0x000fff);
+
+ tptr = tptr + 3;
+ len = len - ISIS_SUBTLV_SPB_INSTANCE_VLAN_TUPLE_LEN;
+ tmp--;
+ }
+
+ break;
+
+ case ISIS_SUBTLV_SPBM_SI:
+
+ if (!TTEST2(*(tptr), 6))
+ goto trunctlv;
+
+ printf("\n\t BMAC: %08x", EXTRACT_32BITS(tptr));
+ tptr = tptr+4;
+ printf("%04x", EXTRACT_16BITS(tptr));
+ tptr = tptr+2;
+
+ printf (", RES: %d, VID: %d", EXTRACT_16BITS(tptr) >> 12,
+ (EXTRACT_16BITS(tptr)) & 0x0fff);
+
+ tptr = tptr+2;
+ len = len - 8;
+ stlv_len = stlv_len - 8;
+
+ while (stlv_len)
+ {
+ printf("\n\t T: %d, R: %d, RES: %d, ISID: %d",
+ (EXTRACT_32BITS(tptr) >> 31),
+ (EXTRACT_32BITS(tptr) >> 30) & 0x01,
+ (EXTRACT_32BITS(tptr) >> 24) & 0x03f,
+ (EXTRACT_32BITS(tptr)) & 0x0ffffff);
+
+ tptr = tptr + 4;
+ len = len - 4;
+ stlv_len = stlv_len - 4;
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ }
+ return 0;
+
+ trunctlv:
+ printf("\n\t\t packet exceeded snapshot");
+ return(1);
+}
+
+
+/* shared routine for printing system, node and lsp-ids */
+static char *
+isis_print_id(const u_int8_t *cp, int id_len)
+{
+ int i;
+ static char id[sizeof("xxxx.xxxx.xxxx.yy-zz")];
+ char *pos = id;
+
+ for (i = 1; i <= SYSTEM_ID_LEN; i++) {
+ snprintf(pos, sizeof(id) - (pos - id), "%02x", *cp++);
+ pos += strlen(pos);
+ if (i == 2 || i == 4)
+ *pos++ = '.';
+ }
+ if (id_len >= NODE_ID_LEN) {
+ snprintf(pos, sizeof(id) - (pos - id), ".%02x", *cp++);
+ pos += strlen(pos);
+ }
+ if (id_len == LSP_ID_LEN)
+ snprintf(pos, sizeof(id) - (pos - id), "-%02x", *cp);
+ return (id);
+}
+
+/* print the 4-byte metric block which is common found in the old-style TLVs */
+static int
+isis_print_metric_block (const struct isis_metric_block *isis_metric_block)
+{
+ printf(", Default Metric: %d, %s",
+ ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_default),
+ ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_default) ? "External" : "Internal");
+ if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_delay))
+ printf("\n\t\t Delay Metric: %d, %s",
+ ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_delay),
+ ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_delay) ? "External" : "Internal");
+ if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_expense))
+ printf("\n\t\t Expense Metric: %d, %s",
+ ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_expense),
+ ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_expense) ? "External" : "Internal");
+ if (!ISIS_LSP_TLV_METRIC_SUPPORTED(isis_metric_block->metric_error))
+ printf("\n\t\t Error Metric: %d, %s",
+ ISIS_LSP_TLV_METRIC_VALUE(isis_metric_block->metric_error),
+ ISIS_LSP_TLV_METRIC_IE(isis_metric_block->metric_error) ? "External" : "Internal");
+
+ return(1); /* everything is ok */
+}
+
+static int
+isis_print_tlv_ip_reach (const u_int8_t *cp, const char *ident, int length)
+{
+ int prefix_len;
+ const struct isis_tlv_ip_reach *tlv_ip_reach;
+
+ tlv_ip_reach = (const struct isis_tlv_ip_reach *)cp;
+
+ while (length > 0) {
+ if ((size_t)length < sizeof(*tlv_ip_reach)) {
+ printf("short IPv4 Reachability (%d vs %lu)",
+ length,
+ (unsigned long)sizeof(*tlv_ip_reach));
+ return (0);
+ }
+
+ if (!TTEST(*tlv_ip_reach))
+ return (0);
+
+ prefix_len = mask2plen(EXTRACT_32BITS(tlv_ip_reach->mask));
+
+ if (prefix_len == -1)
+ printf("%sIPv4 prefix: %s mask %s",
+ ident,
+ ipaddr_string((tlv_ip_reach->prefix)),
+ ipaddr_string((tlv_ip_reach->mask)));
+ else
+ printf("%sIPv4 prefix: %15s/%u",
+ ident,
+ ipaddr_string((tlv_ip_reach->prefix)),
+ prefix_len);
+
+ printf(", Distribution: %s, Metric: %u, %s",
+ ISIS_LSP_TLV_METRIC_UPDOWN(tlv_ip_reach->isis_metric_block.metric_default) ? "down" : "up",
+ ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_default),
+ ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_default) ? "External" : "Internal");
+
+ if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_delay))
+ printf("%s Delay Metric: %u, %s",
+ ident,
+ ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_delay),
+ ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_delay) ? "External" : "Internal");
+
+ if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_expense))
+ printf("%s Expense Metric: %u, %s",
+ ident,
+ ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_expense),
+ ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_expense) ? "External" : "Internal");
+
+ if (!ISIS_LSP_TLV_METRIC_SUPPORTED(tlv_ip_reach->isis_metric_block.metric_error))
+ printf("%s Error Metric: %u, %s",
+ ident,
+ ISIS_LSP_TLV_METRIC_VALUE(tlv_ip_reach->isis_metric_block.metric_error),
+ ISIS_LSP_TLV_METRIC_IE(tlv_ip_reach->isis_metric_block.metric_error) ? "External" : "Internal");
+
+ length -= sizeof(struct isis_tlv_ip_reach);
+ tlv_ip_reach++;
+ }
+ return (1);
+}
+
+/*
+ * this is the common IP-REACH subTLV decoder it is called
+ * from various EXTD-IP REACH TLVs (135,235,236,237)
+ */
+
+static int
+isis_print_ip_reach_subtlv (const u_int8_t *tptr,int subt,int subl,const char *ident) {
+
+ /* first lets see if we know the subTLVs name*/
+ printf("%s%s subTLV #%u, length: %u",
+ ident,
+ tok2str(isis_ext_ip_reach_subtlv_values,
+ "unknown",
+ subt),
+ subt,
+ subl);
+
+ if (!TTEST2(*tptr,subl))
+ goto trunctlv;
+
+ switch(subt) {
+ case ISIS_SUBTLV_EXTD_IP_REACH_MGMT_PREFIX_COLOR: /* fall through */
+ case ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG32:
+ while (subl >= 4) {
+ printf(", 0x%08x (=%u)",
+ EXTRACT_32BITS(tptr),
+ EXTRACT_32BITS(tptr));
+ tptr+=4;
+ subl-=4;
+ }
+ break;
+ case ISIS_SUBTLV_EXTD_IP_REACH_ADMIN_TAG64:
+ while (subl >= 8) {
+ printf(", 0x%08x%08x",
+ EXTRACT_32BITS(tptr),
+ EXTRACT_32BITS(tptr+4));
+ tptr+=8;
+ subl-=8;
+ }
+ break;
+ default:
+ if(!print_unknown_data(tptr,"\n\t\t ",
+ subl))
+ return(0);
+ break;
+ }
+ return(1);
+
+trunctlv:
+ printf("%spacket exceeded snapshot",ident);
+ return(0);
+}
+
+/*
+ * this is the common IS-REACH subTLV decoder it is called
+ * from isis_print_ext_is_reach()
+ */
+
+static int
+isis_print_is_reach_subtlv (const u_int8_t *tptr,u_int subt,u_int subl,const char *ident) {
+
+ u_int te_class,priority_level,gmpls_switch_cap;
+ union { /* int to float conversion buffer for several subTLVs */
+ float f;
+ u_int32_t i;
+ } bw;
+
+ /* first lets see if we know the subTLVs name*/
+ printf("%s%s subTLV #%u, length: %u",
+ ident,
+ tok2str(isis_ext_is_reach_subtlv_values,
+ "unknown",
+ subt),
+ subt,
+ subl);
+
+ if (!TTEST2(*tptr,subl))
+ goto trunctlv;
+
+ switch(subt) {
+ case ISIS_SUBTLV_EXT_IS_REACH_ADMIN_GROUP:
+ case ISIS_SUBTLV_EXT_IS_REACH_LINK_LOCAL_REMOTE_ID:
+ case ISIS_SUBTLV_EXT_IS_REACH_LINK_REMOTE_ID:
+ if (subl >= 4) {
+ printf(", 0x%08x", EXTRACT_32BITS(tptr));
+ if (subl == 8) /* rfc4205 */
+ printf(", 0x%08x", EXTRACT_32BITS(tptr+4));
+ }
+ break;
+ case ISIS_SUBTLV_EXT_IS_REACH_IPV4_INTF_ADDR:
+ case ISIS_SUBTLV_EXT_IS_REACH_IPV4_NEIGHBOR_ADDR:
+ if (subl >= sizeof(struct in_addr))
+ printf(", %s", ipaddr_string(tptr));
+ break;
+ case ISIS_SUBTLV_EXT_IS_REACH_MAX_LINK_BW :
+ case ISIS_SUBTLV_EXT_IS_REACH_RESERVABLE_BW:
+ if (subl >= 4) {
+ bw.i = EXTRACT_32BITS(tptr);
+ printf(", %.3f Mbps", bw.f*8/1000000 );
+ }
+ break;
+ case ISIS_SUBTLV_EXT_IS_REACH_UNRESERVED_BW :
+ if (subl >= 32) {
+ for (te_class = 0; te_class < 8; te_class++) {
+ bw.i = EXTRACT_32BITS(tptr);
+ printf("%s TE-Class %u: %.3f Mbps",
+ ident,
+ te_class,
+ bw.f*8/1000000 );
+ tptr+=4;
+ }
+ }
+ break;
+ case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS: /* fall through */
+ case ISIS_SUBTLV_EXT_IS_REACH_BW_CONSTRAINTS_OLD:
+ printf("%sBandwidth Constraints Model ID: %s (%u)",
+ ident,
+ tok2str(diffserv_te_bc_values, "unknown", *tptr),
+ *tptr);
+ tptr++;
+ /* decode BCs until the subTLV ends */
+ for (te_class = 0; te_class < (subl-1)/4; te_class++) {
+ bw.i = EXTRACT_32BITS(tptr);
+ printf("%s Bandwidth constraint CT%u: %.3f Mbps",
+ ident,
+ te_class,
+ bw.f*8/1000000 );
+ tptr+=4;
+ }
+ break;
+ case ISIS_SUBTLV_EXT_IS_REACH_TE_METRIC:
+ if (subl >= 3)
+ printf(", %u", EXTRACT_24BITS(tptr));
+ break;
+ case ISIS_SUBTLV_EXT_IS_REACH_LINK_ATTRIBUTE:
+ if (subl == 2) {
+ printf(", [ %s ] (0x%04x)",
+ bittok2str(isis_subtlv_link_attribute_values,
+ "Unknown",
+ EXTRACT_16BITS(tptr)),
+ EXTRACT_16BITS(tptr));
+ }
+ break;
+ case ISIS_SUBTLV_EXT_IS_REACH_LINK_PROTECTION_TYPE:
+ if (subl >= 2) {
+ printf(", %s, Priority %u",
+ bittok2str(gmpls_link_prot_values, "none", *tptr),
+ *(tptr+1));
+ }
+ break;
+ case ISIS_SUBTLV_SPB_METRIC:
+ if (subl >= 6) {
+ printf (", LM: %u", EXTRACT_24BITS(tptr));
+ tptr=tptr+3;
+ printf (", P: %u", *(tptr));
+ printf (", P-ID: %u", EXTRACT_16BITS(++tptr));
+ }
+ break;
+ case ISIS_SUBTLV_EXT_IS_REACH_INTF_SW_CAP_DESCR:
+ if (subl >= 36) {
+ gmpls_switch_cap = *tptr;
+ printf("%s Interface Switching Capability:%s",
+ ident,
+ tok2str(gmpls_switch_cap_values, "Unknown", gmpls_switch_cap));
+ printf(", LSP Encoding: %s",
+ tok2str(gmpls_encoding_values, "Unknown", *(tptr+1)));
+ tptr+=4;
+ printf("%s Max LSP Bandwidth:",ident);
+ for (priority_level = 0; priority_level < 8; priority_level++) {
+ bw.i = EXTRACT_32BITS(tptr);
+ printf("%s priority level %d: %.3f Mbps",
+ ident,
+ priority_level,
+ bw.f*8/1000000 );
+ tptr+=4;
+ }
+ subl-=36;
+ switch (gmpls_switch_cap) {
+ case GMPLS_PSC1:
+ case GMPLS_PSC2:
+ case GMPLS_PSC3:
+ case GMPLS_PSC4:
+ bw.i = EXTRACT_32BITS(tptr);
+ printf("%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f*8/1000000);
+ printf("%s Interface MTU: %u", ident, EXTRACT_16BITS(tptr+4));
+ break;
+ case GMPLS_TSC:
+ bw.i = EXTRACT_32BITS(tptr);
+ printf("%s Min LSP Bandwidth: %.3f Mbps", ident, bw.f*8/1000000);
+ printf("%s Indication %s", ident,
+ tok2str(gmpls_switch_cap_tsc_indication_values, "Unknown (%u)", *(tptr+4)));
+ break;
+ default:
+ /* there is some optional stuff left to decode but this is as of yet
+ not specified so just lets hexdump what is left */
+ if(subl>0){
+ if(!print_unknown_data(tptr,"\n\t\t ",
+ subl))
+ return(0);
+ }
+ }
+ }
+ break;
+ default:
+ if(!print_unknown_data(tptr,"\n\t\t ",
+ subl))
+ return(0);
+ break;
+ }
+ return(1);
+
+trunctlv:
+ printf("%spacket exceeded snapshot",ident);
+ return(0);
+}
+
+
+/*
+ * this is the common IS-REACH decoder it is called
+ * from various EXTD-IS REACH style TLVs (22,24,222)
+ */
+
+static int
+isis_print_ext_is_reach (const u_int8_t *tptr,const char *ident, int tlv_type) {
+
+ char ident_buffer[20];
+ int subtlv_type,subtlv_len,subtlv_sum_len;
+ int proc_bytes = 0; /* how many bytes did we process ? */
+
+ if (!TTEST2(*tptr, NODE_ID_LEN))
+ return(0);
+
+ printf("%sIS Neighbor: %s", ident, isis_print_id(tptr, NODE_ID_LEN));
+ tptr+=(NODE_ID_LEN);
+
+ if (tlv_type != ISIS_TLV_IS_ALIAS_ID) { /* the Alias TLV Metric field is implicit 0 */
+ if (!TTEST2(*tptr, 3)) /* and is therefore skipped */
+ return(0);
+ printf(", Metric: %d",EXTRACT_24BITS(tptr));
+ tptr+=3;
+ }
+
+ if (!TTEST2(*tptr, 1))
+ return(0);
+ subtlv_sum_len=*(tptr++); /* read out subTLV length */
+ proc_bytes=NODE_ID_LEN+3+1;
+ printf(", %ssub-TLVs present",subtlv_sum_len ? "" : "no ");
+ if (subtlv_sum_len) {
+ printf(" (%u)",subtlv_sum_len);
+ while (subtlv_sum_len>0) {
+ if (!TTEST2(*tptr,2))
+ return(0);
+ subtlv_type=*(tptr++);
+ subtlv_len=*(tptr++);
+ /* prepend the ident string */
+ snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident);
+ if(!isis_print_is_reach_subtlv(tptr,subtlv_type,subtlv_len,ident_buffer))
+ return(0);
+ tptr+=subtlv_len;
+ subtlv_sum_len-=(subtlv_len+2);
+ proc_bytes+=(subtlv_len+2);
+ }
+ }
+ return(proc_bytes);
+}
+
+/*
+ * this is the common Multi Topology ID decoder
+ * it is called from various MT-TLVs (222,229,235,237)
+ */
+
+static int
+isis_print_mtid (const u_int8_t *tptr,const char *ident) {
+
+ if (!TTEST2(*tptr, 2))
+ return(0);
+
+ printf("%s%s",
+ ident,
+ tok2str(isis_mt_values,
+ "Reserved for IETF Consensus",
+ ISIS_MASK_MTID(EXTRACT_16BITS(tptr))));
+
+ printf(" Topology (0x%03x), Flags: [%s]",
+ ISIS_MASK_MTID(EXTRACT_16BITS(tptr)),
+ bittok2str(isis_mt_flag_values, "none",ISIS_MASK_MTFLAGS(EXTRACT_16BITS(tptr))));
+
+ return(2);
+}
+
+/*
+ * this is the common extended IP reach decoder
+ * it is called from TLVs (135,235,236,237)
+ * we process the TLV and optional subTLVs and return
+ * the amount of processed bytes
+ */
+
+static int
+isis_print_extd_ip_reach (const u_int8_t *tptr, const char *ident, u_int16_t afi) {
+
+ char ident_buffer[20];
+#ifdef INET6
+ u_int8_t prefix[sizeof(struct in6_addr)]; /* shared copy buffer for IPv4 and IPv6 prefixes */
+#else
+ u_int8_t prefix[sizeof(struct in_addr)]; /* shared copy buffer for IPv4 prefixes */
+#endif
+ u_int metric, status_byte, bit_length, byte_length, sublen, processed, subtlvtype, subtlvlen;
+
+ if (!TTEST2(*tptr, 4))
+ return (0);
+ metric = EXTRACT_32BITS(tptr);
+ processed=4;
+ tptr+=4;
+
+ if (afi == AF_INET) {
+ if (!TTEST2(*tptr, 1)) /* fetch status byte */
+ return (0);
+ status_byte=*(tptr++);
+ bit_length = status_byte&0x3f;
+ if (bit_length > 32) {
+ printf("%sIPv4 prefix: bad bit length %u",
+ ident,
+ bit_length);
+ return (0);
+ }
+ processed++;
+#ifdef INET6
+ } else if (afi == AF_INET6) {
+ if (!TTEST2(*tptr, 1)) /* fetch status & prefix_len byte */
+ return (0);
+ status_byte=*(tptr++);
+ bit_length=*(tptr++);
+ if (bit_length > 128) {
+ printf("%sIPv6 prefix: bad bit length %u",
+ ident,
+ bit_length);
+ return (0);
+ }
+ processed+=2;
+#endif
+ } else
+ return (0); /* somebody is fooling us */
+
+ byte_length = (bit_length + 7) / 8; /* prefix has variable length encoding */
+
+ if (!TTEST2(*tptr, byte_length))
+ return (0);
+ memset(prefix, 0, sizeof prefix); /* clear the copy buffer */
+ memcpy(prefix,tptr,byte_length); /* copy as much as is stored in the TLV */
+ tptr+=byte_length;
+ processed+=byte_length;
+
+ if (afi == AF_INET)
+ printf("%sIPv4 prefix: %15s/%u",
+ ident,
+ ipaddr_string(prefix),
+ bit_length);
+#ifdef INET6
+ if (afi == AF_INET6)
+ printf("%sIPv6 prefix: %s/%u",
+ ident,
+ ip6addr_string(prefix),
+ bit_length);
+#endif
+
+ printf(", Distribution: %s, Metric: %u",
+ ISIS_MASK_TLV_EXTD_IP_UPDOWN(status_byte) ? "down" : "up",
+ metric);
+
+ if (afi == AF_INET && ISIS_MASK_TLV_EXTD_IP_SUBTLV(status_byte))
+ printf(", sub-TLVs present");
+#ifdef INET6
+ if (afi == AF_INET6)
+ printf(", %s%s",
+ ISIS_MASK_TLV_EXTD_IP6_IE(status_byte) ? "External" : "Internal",
+ ISIS_MASK_TLV_EXTD_IP6_SUBTLV(status_byte) ? ", sub-TLVs present" : "");
+#endif
+
+ if ((afi == AF_INET && ISIS_MASK_TLV_EXTD_IP_SUBTLV(status_byte))
+#ifdef INET6
+ || (afi == AF_INET6 && ISIS_MASK_TLV_EXTD_IP6_SUBTLV(status_byte))
+#endif
+ ) {
+ /* assume that one prefix can hold more
+ than one subTLV - therefore the first byte must reflect
+ the aggregate bytecount of the subTLVs for this prefix
+ */
+ if (!TTEST2(*tptr, 1))
+ return (0);
+ sublen=*(tptr++);
+ processed+=sublen+1;
+ printf(" (%u)",sublen); /* print out subTLV length */
+
+ while (sublen>0) {
+ if (!TTEST2(*tptr,2))
+ return (0);
+ subtlvtype=*(tptr++);
+ subtlvlen=*(tptr++);
+ /* prepend the ident string */
+ snprintf(ident_buffer, sizeof(ident_buffer), "%s ",ident);
+ if(!isis_print_ip_reach_subtlv(tptr,subtlvtype,subtlvlen,ident_buffer))
+ return(0);
+ tptr+=subtlvlen;
+ sublen-=(subtlvlen+2);
+ }
+ }
+ return (processed);
+}
+
+/*
+ * isis_print
+ * Decode IS-IS packets. Return 0 on error.
+ */
+
+static int isis_print (const u_int8_t *p, u_int length)
+{
+ const struct isis_common_header *isis_header;
+
+ const struct isis_iih_lan_header *header_iih_lan;
+ const struct isis_iih_ptp_header *header_iih_ptp;
+ struct isis_lsp_header *header_lsp;
+ const struct isis_csnp_header *header_csnp;
+ const struct isis_psnp_header *header_psnp;
+
+ const struct isis_tlv_lsp *tlv_lsp;
+ const struct isis_tlv_ptp_adj *tlv_ptp_adj;
+ const struct isis_tlv_is_reach *tlv_is_reach;
+ const struct isis_tlv_es_reach *tlv_es_reach;
+
+ u_int8_t pdu_type, max_area, id_length, tlv_type, tlv_len, tmp, alen, lan_alen, prefix_len;
+ u_int8_t ext_is_len, ext_ip_len, mt_len;
+ const u_int8_t *optr, *pptr, *tptr;
+ u_short packet_len,pdu_len, key_id;
+ u_int i,vendor_id;
+ int sigcheck;
+
+ packet_len=length;
+ optr = p; /* initialize the _o_riginal pointer to the packet start -
+ need it for parsing the checksum TLV and authentication
+ TLV verification */
+ isis_header = (const struct isis_common_header *)p;
+ TCHECK(*isis_header);
+ pptr = p+(ISIS_COMMON_HEADER_SIZE);
+ header_iih_lan = (const struct isis_iih_lan_header *)pptr;
+ header_iih_ptp = (const struct isis_iih_ptp_header *)pptr;
+ header_lsp = (struct isis_lsp_header *)pptr;
+ header_csnp = (const struct isis_csnp_header *)pptr;
+ header_psnp = (const struct isis_psnp_header *)pptr;
+
+ if (!eflag)
+ printf("IS-IS");
+
+ /*
+ * Sanity checking of the header.
+ */
+
+ if (isis_header->version != ISIS_VERSION) {
+ printf("version %d packet not supported", isis_header->version);
+ return (0);
+ }
+
+ if ((isis_header->id_length != SYSTEM_ID_LEN) && (isis_header->id_length != 0)) {
+ printf("system ID length of %d is not supported",
+ isis_header->id_length);
+ return (0);
+ }
+
+ if (isis_header->pdu_version != ISIS_VERSION) {
+ printf("version %d packet not supported", isis_header->pdu_version);
+ return (0);
+ }
+
+ max_area = isis_header->max_area;
+ switch(max_area) {
+ case 0:
+ max_area = 3; /* silly shit */
+ break;
+ case 255:
+ printf("bad packet -- 255 areas");
+ return (0);
+ default:
+ break;
+ }
+
+ id_length = isis_header->id_length;
+ switch(id_length) {
+ case 0:
+ id_length = 6; /* silly shit again */
+ break;
+ case 1: /* 1-8 are valid sys-ID lenghts */
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ break;
+ case 255:
+ id_length = 0; /* entirely useless */
+ break;
+ default:
+ break;
+ }
+
+ /* toss any non 6-byte sys-ID len PDUs */
+ if (id_length != 6 ) {
+ printf("bad packet -- illegal sys-ID length (%u)", id_length);
+ return (0);
+ }
+
+ pdu_type=isis_header->pdu_type;
+
+ /* in non-verbose mode print the basic PDU Type plus PDU specific brief information*/
+ if (vflag < 1) {
+ printf("%s%s",
+ eflag ? "" : ", ",
+ tok2str(isis_pdu_values,"unknown PDU-Type %u",pdu_type));
+
+ switch (pdu_type) {
+
+ case ISIS_PDU_L1_LAN_IIH:
+ case ISIS_PDU_L2_LAN_IIH:
+ printf(", src-id %s",
+ isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN));
+ printf(", lan-id %s, prio %u",
+ isis_print_id(header_iih_lan->lan_id,NODE_ID_LEN),
+ header_iih_lan->priority);
+ break;
+ case ISIS_PDU_PTP_IIH:
+ printf(", src-id %s", isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN));
+ break;
+ case ISIS_PDU_L1_LSP:
+ case ISIS_PDU_L2_LSP:
+ printf(", lsp-id %s, seq 0x%08x, lifetime %5us",
+ isis_print_id(header_lsp->lsp_id, LSP_ID_LEN),
+ EXTRACT_32BITS(header_lsp->sequence_number),
+ EXTRACT_16BITS(header_lsp->remaining_lifetime));
+ break;
+ case ISIS_PDU_L1_CSNP:
+ case ISIS_PDU_L2_CSNP:
+ printf(", src-id %s", isis_print_id(header_csnp->source_id,NODE_ID_LEN));
+ break;
+ case ISIS_PDU_L1_PSNP:
+ case ISIS_PDU_L2_PSNP:
+ printf(", src-id %s", isis_print_id(header_psnp->source_id,NODE_ID_LEN));
+ break;
+
+ }
+ printf(", length %u", length);
+
+ return(1);
+ }
+
+ /* ok they seem to want to know everything - lets fully decode it */
+ printf("%slength %u", eflag ? "" : ", ",length);
+
+ printf("\n\t%s, hlen: %u, v: %u, pdu-v: %u, sys-id-len: %u (%u), max-area: %u (%u)",
+ tok2str(isis_pdu_values,
+ "unknown, type %u",
+ pdu_type),
+ isis_header->fixed_len,
+ isis_header->version,
+ isis_header->pdu_version,
+ id_length,
+ isis_header->id_length,
+ max_area,
+ isis_header->max_area);
+
+ if (vflag > 1) {
+ if(!print_unknown_data(optr,"\n\t",8)) /* provide the _o_riginal pointer */
+ return(0); /* for optionally debugging the common header */
+ }
+
+ switch (pdu_type) {
+
+ case ISIS_PDU_L1_LAN_IIH:
+ case ISIS_PDU_L2_LAN_IIH:
+ if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE)) {
+ printf(", bogus fixed header length %u should be %lu",
+ isis_header->fixed_len, (unsigned long)ISIS_IIH_LAN_HEADER_SIZE);
+ return (0);
+ }
+
+ pdu_len=EXTRACT_16BITS(header_iih_lan->pdu_len);
+ if (packet_len>pdu_len) {
+ packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
+ length=pdu_len;
+ }
+
+ TCHECK(*header_iih_lan);
+ printf("\n\t source-id: %s, holding time: %us, Flags: [%s]",
+ isis_print_id(header_iih_lan->source_id,SYSTEM_ID_LEN),
+ EXTRACT_16BITS(header_iih_lan->holding_time),
+ tok2str(isis_iih_circuit_type_values,
+ "unknown circuit type 0x%02x",
+ header_iih_lan->circuit_type));
+
+ printf("\n\t lan-id: %s, Priority: %u, PDU length: %u",
+ isis_print_id(header_iih_lan->lan_id, NODE_ID_LEN),
+ (header_iih_lan->priority) & ISIS_LAN_PRIORITY_MASK,
+ pdu_len);
+
+ if (vflag > 1) {
+ if(!print_unknown_data(pptr,"\n\t ",ISIS_IIH_LAN_HEADER_SIZE))
+ return(0);
+ }
+
+ packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
+ pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_LAN_HEADER_SIZE);
+ break;
+
+ case ISIS_PDU_PTP_IIH:
+ if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE)) {
+ printf(", bogus fixed header length %u should be %lu",
+ isis_header->fixed_len, (unsigned long)ISIS_IIH_PTP_HEADER_SIZE);
+ return (0);
+ }
+
+ pdu_len=EXTRACT_16BITS(header_iih_ptp->pdu_len);
+ if (packet_len>pdu_len) {
+ packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
+ length=pdu_len;
+ }
+
+ TCHECK(*header_iih_ptp);
+ printf("\n\t source-id: %s, holding time: %us, Flags: [%s]",
+ isis_print_id(header_iih_ptp->source_id,SYSTEM_ID_LEN),
+ EXTRACT_16BITS(header_iih_ptp->holding_time),
+ tok2str(isis_iih_circuit_type_values,
+ "unknown circuit type 0x%02x",
+ header_iih_ptp->circuit_type));
+
+ printf("\n\t circuit-id: 0x%02x, PDU length: %u",
+ header_iih_ptp->circuit_id,
+ pdu_len);
+
+ if (vflag > 1) {
+ if(!print_unknown_data(pptr,"\n\t ",ISIS_IIH_PTP_HEADER_SIZE))
+ return(0);
+ }
+
+ packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
+ pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_IIH_PTP_HEADER_SIZE);
+ break;
+
+ case ISIS_PDU_L1_LSP:
+ case ISIS_PDU_L2_LSP:
+ if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE)) {
+ printf(", bogus fixed header length %u should be %lu",
+ isis_header->fixed_len, (unsigned long)ISIS_LSP_HEADER_SIZE);
+ return (0);
+ }
+
+ pdu_len=EXTRACT_16BITS(header_lsp->pdu_len);
+ if (packet_len>pdu_len) {
+ packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
+ length=pdu_len;
+ }
+
+ TCHECK(*header_lsp);
+ printf("\n\t lsp-id: %s, seq: 0x%08x, lifetime: %5us\n\t chksum: 0x%04x",
+ isis_print_id(header_lsp->lsp_id, LSP_ID_LEN),
+ EXTRACT_32BITS(header_lsp->sequence_number),
+ EXTRACT_16BITS(header_lsp->remaining_lifetime),
+ EXTRACT_16BITS(header_lsp->checksum));
+
+
+ osi_print_cksum((u_int8_t *)header_lsp->lsp_id,
+ EXTRACT_16BITS(header_lsp->checksum), 12, length-12);
+
+ /*
+ * Clear checksum and lifetime prior to signature verification.
+ */
+ header_lsp->checksum[0] = 0;
+ header_lsp->checksum[1] = 0;
+ header_lsp->remaining_lifetime[0] = 0;
+ header_lsp->remaining_lifetime[1] = 0;
+
+
+ printf(", PDU length: %u, Flags: [ %s",
+ pdu_len,
+ ISIS_MASK_LSP_OL_BIT(header_lsp->typeblock) ? "Overload bit set, " : "");
+
+ if (ISIS_MASK_LSP_ATT_BITS(header_lsp->typeblock)) {
+ printf("%s", ISIS_MASK_LSP_ATT_DEFAULT_BIT(header_lsp->typeblock) ? "default " : "");
+ printf("%s", ISIS_MASK_LSP_ATT_DELAY_BIT(header_lsp->typeblock) ? "delay " : "");
+ printf("%s", ISIS_MASK_LSP_ATT_EXPENSE_BIT(header_lsp->typeblock) ? "expense " : "");
+ printf("%s", ISIS_MASK_LSP_ATT_ERROR_BIT(header_lsp->typeblock) ? "error " : "");
+ printf("ATT bit set, ");
+ }
+ printf("%s", ISIS_MASK_LSP_PARTITION_BIT(header_lsp->typeblock) ? "P bit set, " : "");
+ printf("%s ]", tok2str(isis_lsp_istype_values,"Unknown(0x%x)",ISIS_MASK_LSP_ISTYPE_BITS(header_lsp->typeblock)));
+
+ if (vflag > 1) {
+ if(!print_unknown_data(pptr,"\n\t ",ISIS_LSP_HEADER_SIZE))
+ return(0);
+ }
+
+ packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
+ pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_LSP_HEADER_SIZE);
+ break;
+
+ case ISIS_PDU_L1_CSNP:
+ case ISIS_PDU_L2_CSNP:
+ if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE)) {
+ printf(", bogus fixed header length %u should be %lu",
+ isis_header->fixed_len, (unsigned long)ISIS_CSNP_HEADER_SIZE);
+ return (0);
+ }
+
+ pdu_len=EXTRACT_16BITS(header_csnp->pdu_len);
+ if (packet_len>pdu_len) {
+ packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
+ length=pdu_len;
+ }
+
+ TCHECK(*header_csnp);
+ printf("\n\t source-id: %s, PDU length: %u",
+ isis_print_id(header_csnp->source_id, NODE_ID_LEN),
+ pdu_len);
+ printf("\n\t start lsp-id: %s",
+ isis_print_id(header_csnp->start_lsp_id, LSP_ID_LEN));
+ printf("\n\t end lsp-id: %s",
+ isis_print_id(header_csnp->end_lsp_id, LSP_ID_LEN));
+
+ if (vflag > 1) {
+ if(!print_unknown_data(pptr,"\n\t ",ISIS_CSNP_HEADER_SIZE))
+ return(0);
+ }
+
+ packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
+ pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_CSNP_HEADER_SIZE);
+ break;
+
+ case ISIS_PDU_L1_PSNP:
+ case ISIS_PDU_L2_PSNP:
+ if (isis_header->fixed_len != (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE)) {
+ printf("- bogus fixed header length %u should be %lu",
+ isis_header->fixed_len, (unsigned long)ISIS_PSNP_HEADER_SIZE);
+ return (0);
+ }
+
+ pdu_len=EXTRACT_16BITS(header_psnp->pdu_len);
+ if (packet_len>pdu_len) {
+ packet_len=pdu_len; /* do TLV decoding as long as it makes sense */
+ length=pdu_len;
+ }
+
+ TCHECK(*header_psnp);
+ printf("\n\t source-id: %s, PDU length: %u",
+ isis_print_id(header_psnp->source_id, NODE_ID_LEN),
+ pdu_len);
+
+ if (vflag > 1) {
+ if(!print_unknown_data(pptr,"\n\t ",ISIS_PSNP_HEADER_SIZE))
+ return(0);
+ }
+
+ packet_len -= (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
+ pptr = p + (ISIS_COMMON_HEADER_SIZE+ISIS_PSNP_HEADER_SIZE);
+ break;
+
+ default:
+ if(!print_unknown_data(pptr,"\n\t ",length))
+ return(0);
+ return (0);
+ }
+
+ /*
+ * Now print the TLV's.
+ */
+
+ while (packet_len >= 2) {
+ if (pptr == snapend) {
+ return (1);
+ }
+
+ if (!TTEST2(*pptr, 2)) {
+ printf("\n\t\t packet exceeded snapshot (%ld) bytes",
+ (long)(pptr-snapend));
+ return (1);
+ }
+ tlv_type = *pptr++;
+ tlv_len = *pptr++;
+ tmp =tlv_len; /* copy temporary len & pointer to packet data */
+ tptr = pptr;
+ packet_len -= 2;
+ if (tlv_len > packet_len) {
+ break;
+ }
+
+ /* first lets see if we know the TLVs name*/
+ printf("\n\t %s TLV #%u, length: %u",
+ tok2str(isis_tlv_values,
+ "unknown",
+ tlv_type),
+ tlv_type,
+ tlv_len);
+
+ if (tlv_len == 0) /* something is malformed */
+ continue;
+
+ /* now check if we have a decoder otherwise do a hexdump at the end*/
+ switch (tlv_type) {
+ case ISIS_TLV_AREA_ADDR:
+ if (!TTEST2(*tptr, 1))
+ goto trunctlv;
+ alen = *tptr++;
+ while (tmp && alen < tmp) {
+ printf("\n\t Area address (length: %u): %s",
+ alen,
+ isonsap_string(tptr,alen));
+ tptr += alen;
+ tmp -= alen + 1;
+ if (tmp==0) /* if this is the last area address do not attemt a boundary check */
+ break;
+ if (!TTEST2(*tptr, 1))
+ goto trunctlv;
+ alen = *tptr++;
+ }
+ break;
+ case ISIS_TLV_ISNEIGH:
+ while (tmp >= ETHER_ADDR_LEN) {
+ if (!TTEST2(*tptr, ETHER_ADDR_LEN))
+ goto trunctlv;
+ printf("\n\t SNPA: %s",isis_print_id(tptr,ETHER_ADDR_LEN));
+ tmp -= ETHER_ADDR_LEN;
+ tptr += ETHER_ADDR_LEN;
+ }
+ break;
+
+ case ISIS_TLV_ISNEIGH_VARLEN:
+ if (!TTEST2(*tptr, 1) || tmp < 3) /* min. TLV length */
+ goto trunctlv;
+ lan_alen = *tptr++; /* LAN address length */
+ if (lan_alen == 0) {
+ printf("\n\t LAN address length 0 bytes (invalid)");
+ break;
+ }
+ tmp --;
+ printf("\n\t LAN address length %u bytes ",lan_alen);
+ while (tmp >= lan_alen) {
+ if (!TTEST2(*tptr, lan_alen))
+ goto trunctlv;
+ printf("\n\t\tIS Neighbor: %s",isis_print_id(tptr,lan_alen));
+ tmp -= lan_alen;
+ tptr +=lan_alen;
+ }
+ break;
+
+ case ISIS_TLV_PADDING:
+ break;
+
+ case ISIS_TLV_MT_IS_REACH:
+ mt_len = isis_print_mtid(tptr, "\n\t ");
+ if (mt_len == 0) /* did something go wrong ? */
+ goto trunctlv;
+ tptr+=mt_len;
+ tmp-=mt_len;
+ while (tmp >= 2+NODE_ID_LEN+3+1) {
+ ext_is_len = isis_print_ext_is_reach(tptr,"\n\t ",tlv_type);
+ if (ext_is_len == 0) /* did something go wrong ? */
+ goto trunctlv;
+
+ tmp-=ext_is_len;
+ tptr+=ext_is_len;
+ }
+ break;
+
+ case ISIS_TLV_IS_ALIAS_ID:
+ while (tmp >= NODE_ID_LEN+1) { /* is it worth attempting a decode ? */
+ ext_is_len = isis_print_ext_is_reach(tptr,"\n\t ",tlv_type);
+ if (ext_is_len == 0) /* did something go wrong ? */
+ goto trunctlv;
+ tmp-=ext_is_len;
+ tptr+=ext_is_len;
+ }
+ break;
+
+ case ISIS_TLV_EXT_IS_REACH:
+ while (tmp >= NODE_ID_LEN+3+1) { /* is it worth attempting a decode ? */
+ ext_is_len = isis_print_ext_is_reach(tptr,"\n\t ",tlv_type);
+ if (ext_is_len == 0) /* did something go wrong ? */
+ goto trunctlv;
+ tmp-=ext_is_len;
+ tptr+=ext_is_len;
+ }
+ break;
+ case ISIS_TLV_IS_REACH:
+ if (!TTEST2(*tptr,1)) /* check if there is one byte left to read out the virtual flag */
+ goto trunctlv;
+ printf("\n\t %s",
+ tok2str(isis_is_reach_virtual_values,
+ "bogus virtual flag 0x%02x",
+ *tptr++));
+ tlv_is_reach = (const struct isis_tlv_is_reach *)tptr;
+ while (tmp >= sizeof(struct isis_tlv_is_reach)) {
+ if (!TTEST(*tlv_is_reach))
+ goto trunctlv;
+ printf("\n\t IS Neighbor: %s",
+ isis_print_id(tlv_is_reach->neighbor_nodeid, NODE_ID_LEN));
+ isis_print_metric_block(&tlv_is_reach->isis_metric_block);
+ tmp -= sizeof(struct isis_tlv_is_reach);
+ tlv_is_reach++;
+ }
+ break;
+
+ case ISIS_TLV_ESNEIGH:
+ tlv_es_reach = (const struct isis_tlv_es_reach *)tptr;
+ while (tmp >= sizeof(struct isis_tlv_es_reach)) {
+ if (!TTEST(*tlv_es_reach))
+ goto trunctlv;
+ printf("\n\t ES Neighbor: %s",
+ isis_print_id(tlv_es_reach->neighbor_sysid,SYSTEM_ID_LEN));
+ isis_print_metric_block(&tlv_es_reach->isis_metric_block);
+ tmp -= sizeof(struct isis_tlv_es_reach);
+ tlv_es_reach++;
+ }
+ break;
+
+ /* those two TLVs share the same format */
+ case ISIS_TLV_INT_IP_REACH:
+ case ISIS_TLV_EXT_IP_REACH:
+ if (!isis_print_tlv_ip_reach(pptr, "\n\t ", tlv_len))
+ return (1);
+ break;
+
+ case ISIS_TLV_EXTD_IP_REACH:
+ while (tmp>0) {
+ ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", AF_INET);
+ if (ext_ip_len == 0) /* did something go wrong ? */
+ goto trunctlv;
+ tptr+=ext_ip_len;
+ tmp-=ext_ip_len;
+ }
+ break;
+
+ case ISIS_TLV_MT_IP_REACH:
+ mt_len = isis_print_mtid(tptr, "\n\t ");
+ if (mt_len == 0) { /* did something go wrong ? */
+ goto trunctlv;
+ }
+ tptr+=mt_len;
+ tmp-=mt_len;
+
+ while (tmp>0) {
+ ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", AF_INET);
+ if (ext_ip_len == 0) /* did something go wrong ? */
+ goto trunctlv;
+ tptr+=ext_ip_len;
+ tmp-=ext_ip_len;
+ }
+ break;
+
+#ifdef INET6
+ case ISIS_TLV_IP6_REACH:
+ while (tmp>0) {
+ ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", AF_INET6);
+ if (ext_ip_len == 0) /* did something go wrong ? */
+ goto trunctlv;
+ tptr+=ext_ip_len;
+ tmp-=ext_ip_len;
+ }
+ break;
+
+ case ISIS_TLV_MT_IP6_REACH:
+ mt_len = isis_print_mtid(tptr, "\n\t ");
+ if (mt_len == 0) { /* did something go wrong ? */
+ goto trunctlv;
+ }
+ tptr+=mt_len;
+ tmp-=mt_len;
+
+ while (tmp>0) {
+ ext_ip_len = isis_print_extd_ip_reach(tptr, "\n\t ", AF_INET6);
+ if (ext_ip_len == 0) /* did something go wrong ? */
+ goto trunctlv;
+ tptr+=ext_ip_len;
+ tmp-=ext_ip_len;
+ }
+ break;
+
+ case ISIS_TLV_IP6ADDR:
+ while (tmp>=sizeof(struct in6_addr)) {
+ if (!TTEST2(*tptr, sizeof(struct in6_addr)))
+ goto trunctlv;
+
+ printf("\n\t IPv6 interface address: %s",
+ ip6addr_string(tptr));
+
+ tptr += sizeof(struct in6_addr);
+ tmp -= sizeof(struct in6_addr);
+ }
+ break;
+#endif
+ case ISIS_TLV_AUTH:
+ if (!TTEST2(*tptr, 1))
+ goto trunctlv;
+
+ printf("\n\t %s: ",
+ tok2str(isis_subtlv_auth_values,
+ "unknown Authentication type 0x%02x",
+ *tptr));
+
+ switch (*tptr) {
+ case ISIS_SUBTLV_AUTH_SIMPLE:
+ for(i=1;i<tlv_len;i++) {
+ if (!TTEST2(*(tptr+i), 1))
+ goto trunctlv;
+ printf("%c",*(tptr+i));
+ }
+ break;
+ case ISIS_SUBTLV_AUTH_MD5:
+ for(i=1;i<tlv_len;i++) {
+ if (!TTEST2(*(tptr+i), 1))
+ goto trunctlv;
+ printf("%02x",*(tptr+i));
+ }
+ if (tlv_len != ISIS_SUBTLV_AUTH_MD5_LEN+1)
+ printf(", (malformed subTLV) ");
+
+#ifdef HAVE_LIBCRYPTO
+ sigcheck = signature_verify(optr, length,
+ (unsigned char *)tptr + 1);
+#else
+ sigcheck = CANT_CHECK_SIGNATURE;
+#endif
+ printf(" (%s)", tok2str(signature_check_values, "Unknown", sigcheck));
+
+ break;
+ case ISIS_SUBTLV_AUTH_GENERIC:
+ key_id = EXTRACT_16BITS((tptr+1));
+ printf("%u, password: ", key_id);
+ for(i=1 + sizeof(u_int16_t);i<tlv_len;i++) {
+ if (!TTEST2(*(tptr+i), 1))
+ goto trunctlv;
+ printf("%02x",*(tptr+i));
+ }
+ break;
+ case ISIS_SUBTLV_AUTH_PRIVATE:
+ default:
+ if(!print_unknown_data(tptr+1,"\n\t\t ",tlv_len-1))
+ return(0);
+ break;
+ }
+ break;
+
+ case ISIS_TLV_PTP_ADJ:
+ tlv_ptp_adj = (const struct isis_tlv_ptp_adj *)tptr;
+ if(tmp>=1) {
+ if (!TTEST2(*tptr, 1))
+ goto trunctlv;
+ printf("\n\t Adjacency State: %s (%u)",
+ tok2str(isis_ptp_adjancey_values, "unknown", *tptr),
+ *tptr);
+ tmp--;
+ }
+ if(tmp>sizeof(tlv_ptp_adj->extd_local_circuit_id)) {
+ if (!TTEST2(tlv_ptp_adj->extd_local_circuit_id,
+ sizeof(tlv_ptp_adj->extd_local_circuit_id)))
+ goto trunctlv;
+ printf("\n\t Extended Local circuit-ID: 0x%08x",
+ EXTRACT_32BITS(tlv_ptp_adj->extd_local_circuit_id));
+ tmp-=sizeof(tlv_ptp_adj->extd_local_circuit_id);
+ }
+ if(tmp>=SYSTEM_ID_LEN) {
+ if (!TTEST2(tlv_ptp_adj->neighbor_sysid, SYSTEM_ID_LEN))
+ goto trunctlv;
+ printf("\n\t Neighbor System-ID: %s",
+ isis_print_id(tlv_ptp_adj->neighbor_sysid,SYSTEM_ID_LEN));
+ tmp-=SYSTEM_ID_LEN;
+ }
+ if(tmp>=sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id)) {
+ if (!TTEST2(tlv_ptp_adj->neighbor_extd_local_circuit_id,
+ sizeof(tlv_ptp_adj->neighbor_extd_local_circuit_id)))
+ goto trunctlv;
+ printf("\n\t Neighbor Extended Local circuit-ID: 0x%08x",
+ EXTRACT_32BITS(tlv_ptp_adj->neighbor_extd_local_circuit_id));
+ }
+ break;
+
+ case ISIS_TLV_PROTOCOLS:
+ printf("\n\t NLPID(s): ");
+ while (tmp>0) {
+ if (!TTEST2(*(tptr), 1))
+ goto trunctlv;
+ printf("%s (0x%02x)",
+ tok2str(nlpid_values,
+ "unknown",
+ *tptr),
+ *tptr);
+ if (tmp>1) /* further NPLIDs ? - put comma */
+ printf(", ");
+ tptr++;
+ tmp--;
+ }
+ break;
+
+ case ISIS_TLV_MT_PORT_CAP:
+ {
+ if (!TTEST2(*(tptr), 2))
+ goto trunctlv;
+
+ printf("\n\t RES: %d, MTID(s): %d",
+ (EXTRACT_16BITS (tptr) >> 12),
+ (EXTRACT_16BITS (tptr) & 0x0fff));
+
+ tmp = tmp-2;
+ tptr = tptr+2;
+
+ if (tmp)
+ isis_print_mt_port_cap_subtlv (tptr, tmp);
+
+ break;
+ }
+
+ case ISIS_TLV_MT_CAPABILITY:
+
+ if (!TTEST2(*(tptr), 2))
+ goto trunctlv;
+
+ printf("\n\t O: %d, RES: %d, MTID(s): %d",
+ (EXTRACT_16BITS(tptr) >> 15) & 0x01,
+ (EXTRACT_16BITS(tptr) >> 12) & 0x07,
+ EXTRACT_16BITS(tptr) & 0x0fff);
+
+ tmp = tmp-2;
+ tptr = tptr+2;
+
+ if (tmp)
+ isis_print_mt_capability_subtlv (tptr, tmp);
+
+ break;
+
+ case ISIS_TLV_TE_ROUTER_ID:
+ if (!TTEST2(*pptr, sizeof(struct in_addr)))
+ goto trunctlv;
+ printf("\n\t Traffic Engineering Router ID: %s", ipaddr_string(pptr));
+ break;
+
+ case ISIS_TLV_IPADDR:
+ while (tmp>=sizeof(struct in_addr)) {
+ if (!TTEST2(*tptr, sizeof(struct in_addr)))
+ goto trunctlv;
+ printf("\n\t IPv4 interface address: %s", ipaddr_string(tptr));
+ tptr += sizeof(struct in_addr);
+ tmp -= sizeof(struct in_addr);
+ }
+ break;
+
+ case ISIS_TLV_HOSTNAME:
+ printf("\n\t Hostname: ");
+ while (tmp>0) {
+ if (!TTEST2(*tptr, 1))
+ goto trunctlv;
+ printf("%c",*tptr++);
+ tmp--;
+ }
+ break;
+
+ case ISIS_TLV_SHARED_RISK_GROUP:
+ if (tmp < NODE_ID_LEN)
+ break;
+ if (!TTEST2(*tptr, NODE_ID_LEN))
+ goto trunctlv;
+ printf("\n\t IS Neighbor: %s", isis_print_id(tptr, NODE_ID_LEN));
+ tptr+=(NODE_ID_LEN);
+ tmp-=(NODE_ID_LEN);
+
+ if (tmp < 1)
+ break;
+ if (!TTEST2(*tptr, 1))
+ goto trunctlv;
+ printf(", Flags: [%s]", ISIS_MASK_TLV_SHARED_RISK_GROUP(*tptr++) ? "numbered" : "unnumbered");
+ tmp--;
+
+ if (tmp < sizeof(struct in_addr))
+ break;
+ if (!TTEST2(*tptr,sizeof(struct in_addr)))
+ goto trunctlv;
+ printf("\n\t IPv4 interface address: %s", ipaddr_string(tptr));
+ tptr+=sizeof(struct in_addr);
+ tmp-=sizeof(struct in_addr);
+
+ if (tmp < sizeof(struct in_addr))
+ break;
+ if (!TTEST2(*tptr,sizeof(struct in_addr)))
+ goto trunctlv;
+ printf("\n\t IPv4 neighbor address: %s", ipaddr_string(tptr));
+ tptr+=sizeof(struct in_addr);
+ tmp-=sizeof(struct in_addr);
+
+ while (tmp>=4) {
+ if (!TTEST2(*tptr, 4))
+ goto trunctlv;
+ printf("\n\t Link-ID: 0x%08x", EXTRACT_32BITS(tptr));
+ tptr+=4;
+ tmp-=4;
+ }
+ break;
+
+ case ISIS_TLV_LSP:
+ tlv_lsp = (const struct isis_tlv_lsp *)tptr;
+ while(tmp>=sizeof(struct isis_tlv_lsp)) {
+ if (!TTEST((tlv_lsp->lsp_id)[LSP_ID_LEN-1]))
+ goto trunctlv;
+ printf("\n\t lsp-id: %s",
+ isis_print_id(tlv_lsp->lsp_id, LSP_ID_LEN));
+ if (!TTEST2(tlv_lsp->sequence_number, 4))
+ goto trunctlv;
+ printf(", seq: 0x%08x",EXTRACT_32BITS(tlv_lsp->sequence_number));
+ if (!TTEST2(tlv_lsp->remaining_lifetime, 2))
+ goto trunctlv;
+ printf(", lifetime: %5ds",EXTRACT_16BITS(tlv_lsp->remaining_lifetime));
+ if (!TTEST2(tlv_lsp->checksum, 2))
+ goto trunctlv;
+ printf(", chksum: 0x%04x",EXTRACT_16BITS(tlv_lsp->checksum));
+ tmp-=sizeof(struct isis_tlv_lsp);
+ tlv_lsp++;
+ }
+ break;
+
+ case ISIS_TLV_CHECKSUM:
+ if (tmp < ISIS_TLV_CHECKSUM_MINLEN)
+ break;
+ if (!TTEST2(*tptr, ISIS_TLV_CHECKSUM_MINLEN))
+ goto trunctlv;
+ printf("\n\t checksum: 0x%04x ", EXTRACT_16BITS(tptr));
+ /* do not attempt to verify the checksum if it is zero
+ * most likely a HMAC-MD5 TLV is also present and
+ * to avoid conflicts the checksum TLV is zeroed.
+ * see rfc3358 for details
+ */
+ osi_print_cksum(optr, EXTRACT_16BITS(tptr), tptr-optr, length);
+ break;
+
+ case ISIS_TLV_MT_SUPPORTED:
+ if (tmp < ISIS_TLV_MT_SUPPORTED_MINLEN)
+ break;
+ while (tmp>1) {
+ /* length can only be a multiple of 2, otherwise there is
+ something broken -> so decode down until length is 1 */
+ if (tmp!=1) {
+ mt_len = isis_print_mtid(tptr, "\n\t ");
+ if (mt_len == 0) /* did something go wrong ? */
+ goto trunctlv;
+ tptr+=mt_len;
+ tmp-=mt_len;
+ } else {
+ printf("\n\t malformed MT-ID");
+ break;
+ }
+ }
+ break;
+
+ case ISIS_TLV_RESTART_SIGNALING:
+ /* first attempt to decode the flags */
+ if (tmp < ISIS_TLV_RESTART_SIGNALING_FLAGLEN)
+ break;
+ if (!TTEST2(*tptr, ISIS_TLV_RESTART_SIGNALING_FLAGLEN))
+ goto trunctlv;
+ printf("\n\t Flags [%s]",
+ bittok2str(isis_restart_flag_values, "none", *tptr));
+ tptr+=ISIS_TLV_RESTART_SIGNALING_FLAGLEN;
+ tmp-=ISIS_TLV_RESTART_SIGNALING_FLAGLEN;
+
+ /* is there anything other than the flags field? */
+ if (tmp == 0)
+ break;
+
+ if (tmp < ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN)
+ break;
+ if (!TTEST2(*tptr, ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN))
+ goto trunctlv;
+
+ printf(", Remaining holding time %us", EXTRACT_16BITS(tptr));
+ tptr+=ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN;
+ tmp-=ISIS_TLV_RESTART_SIGNALING_HOLDTIMELEN;
+
+ /* is there an additional sysid field present ?*/
+ if (tmp == SYSTEM_ID_LEN) {
+ if (!TTEST2(*tptr, SYSTEM_ID_LEN))
+ goto trunctlv;
+ printf(", for %s",isis_print_id(tptr,SYSTEM_ID_LEN));
+ }
+ break;
+
+ case ISIS_TLV_IDRP_INFO:
+ if (tmp < ISIS_TLV_IDRP_INFO_MINLEN)
+ break;
+ if (!TTEST2(*tptr, ISIS_TLV_IDRP_INFO_MINLEN))
+ goto trunctlv;
+ printf("\n\t Inter-Domain Information Type: %s",
+ tok2str(isis_subtlv_idrp_values,
+ "Unknown (0x%02x)",
+ *tptr));
+ switch (*tptr++) {
+ case ISIS_SUBTLV_IDRP_ASN:
+ if (!TTEST2(*tptr, 2)) /* fetch AS number */
+ goto trunctlv;
+ printf("AS Number: %u",EXTRACT_16BITS(tptr));
+ break;
+ case ISIS_SUBTLV_IDRP_LOCAL:
+ case ISIS_SUBTLV_IDRP_RES:
+ default:
+ if(!print_unknown_data(tptr,"\n\t ",tlv_len-1))
+ return(0);
+ break;
+ }
+ break;
+
+ case ISIS_TLV_LSP_BUFFERSIZE:
+ if (tmp < ISIS_TLV_LSP_BUFFERSIZE_MINLEN)
+ break;
+ if (!TTEST2(*tptr, ISIS_TLV_LSP_BUFFERSIZE_MINLEN))
+ goto trunctlv;
+ printf("\n\t LSP Buffersize: %u",EXTRACT_16BITS(tptr));
+ break;
+
+ case ISIS_TLV_PART_DIS:
+ while (tmp >= SYSTEM_ID_LEN) {
+ if (!TTEST2(*tptr, SYSTEM_ID_LEN))
+ goto trunctlv;
+ printf("\n\t %s",isis_print_id(tptr,SYSTEM_ID_LEN));
+ tptr+=SYSTEM_ID_LEN;
+ tmp-=SYSTEM_ID_LEN;
+ }
+ break;
+
+ case ISIS_TLV_PREFIX_NEIGH:
+ if (tmp < sizeof(struct isis_metric_block))
+ break;
+ if (!TTEST2(*tptr, sizeof(struct isis_metric_block)))
+ goto trunctlv;
+ printf("\n\t Metric Block");
+ isis_print_metric_block((const struct isis_metric_block *)tptr);
+ tptr+=sizeof(struct isis_metric_block);
+ tmp-=sizeof(struct isis_metric_block);
+
+ while(tmp>0) {
+ if (!TTEST2(*tptr, 1))
+ goto trunctlv;
+ prefix_len=*tptr++; /* read out prefix length in semioctets*/
+ if (prefix_len < 2) {
+ printf("\n\t\tAddress: prefix length %u < 2", prefix_len);
+ break;
+ }
+ tmp--;
+ if (tmp < prefix_len/2)
+ break;
+ if (!TTEST2(*tptr, prefix_len/2))
+ goto trunctlv;
+ printf("\n\t\tAddress: %s/%u",
+ isonsap_string(tptr,prefix_len/2),
+ prefix_len*4);
+ tptr+=prefix_len/2;
+ tmp-=prefix_len/2;
+ }
+ break;
+
+ case ISIS_TLV_IIH_SEQNR:
+ if (tmp < ISIS_TLV_IIH_SEQNR_MINLEN)
+ break;
+ if (!TTEST2(*tptr, ISIS_TLV_IIH_SEQNR_MINLEN)) /* check if four bytes are on the wire */
+ goto trunctlv;
+ printf("\n\t Sequence number: %u", EXTRACT_32BITS(tptr) );
+ break;
+
+ case ISIS_TLV_VENDOR_PRIVATE:
+ if (tmp < ISIS_TLV_VENDOR_PRIVATE_MINLEN)
+ break;
+ if (!TTEST2(*tptr, ISIS_TLV_VENDOR_PRIVATE_MINLEN)) /* check if enough byte for a full oui */
+ goto trunctlv;
+ vendor_id = EXTRACT_24BITS(tptr);
+ printf("\n\t Vendor: %s (%u)",
+ tok2str(oui_values,"Unknown",vendor_id),
+ vendor_id);
+ tptr+=3;
+ tmp-=3;
+ if (tmp > 0) /* hexdump the rest */
+ if(!print_unknown_data(tptr,"\n\t\t",tmp))
+ return(0);
+ break;
+ /*
+ * FIXME those are the defined TLVs that lack a decoder
+ * you are welcome to contribute code ;-)
+ */
+
+ case ISIS_TLV_DECNET_PHASE4:
+ case ISIS_TLV_LUCENT_PRIVATE:
+ case ISIS_TLV_IPAUTH:
+ case ISIS_TLV_NORTEL_PRIVATE1:
+ case ISIS_TLV_NORTEL_PRIVATE2:
+
+ default:
+ if (vflag <= 1) {
+ if(!print_unknown_data(pptr,"\n\t\t",tlv_len))
+ return(0);
+ }
+ break;
+ }
+ /* do we want to see an additionally hexdump ? */
+ if (vflag> 1) {
+ if(!print_unknown_data(pptr,"\n\t ",tlv_len))
+ return(0);
+ }
+
+ pptr += tlv_len;
+ packet_len -= tlv_len;
+ }
+
+ if (packet_len != 0) {
+ printf("\n\t %u straggler bytes", packet_len);
+ }
+ return (1);
+
+ trunc:
+ fputs("[|isis]", stdout);
+ return (1);
+
+ trunctlv:
+ printf("\n\t\t packet exceeded snapshot");
+ return(1);
+}
+
+static void
+osi_print_cksum (const u_int8_t *pptr, u_int16_t checksum,
+ u_int checksum_offset, u_int length)
+{
+ u_int16_t calculated_checksum;
+
+ /* do not attempt to verify the checksum if it is zero */
+ if (!checksum) {
+ printf("(unverified)");
+ } else {
+ calculated_checksum = create_osi_cksum(pptr, checksum_offset, length);
+ if (checksum == calculated_checksum) {
+ printf(" (correct)");
+ } else {
+ printf(" (incorrect should be 0x%04x)", calculated_checksum);
+ }
+ }
+}
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-juniper.c b/freebsd/contrib/tcpdump/print-juniper.c
new file mode 100644
index 00000000..e221835f
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-juniper.c
@@ -0,0 +1,1458 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/* NetBSD: print-juniper.c,v 1.2 2007/07/24 11:53:45 drochner Exp */
+
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-juniper.c,v 1.34 2007-08-29 02:31:44 mcr Exp $ (LBL)";
+#else
+__RCSID("NetBSD: print-juniper.c,v 1.3 2007/07/25 06:31:32 dogcow Exp ");
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <pcap.h>
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+#include "ppp.h"
+#include "llc.h"
+#include "nlpid.h"
+#include "ethertype.h"
+#include "atm.h"
+
+#define JUNIPER_BPF_OUT 0 /* Outgoing packet */
+#define JUNIPER_BPF_IN 1 /* Incoming packet */
+#define JUNIPER_BPF_PKT_IN 0x1 /* Incoming packet */
+#define JUNIPER_BPF_NO_L2 0x2 /* L2 header stripped */
+#define JUNIPER_BPF_IIF 0x4 /* IIF is valid */
+#define JUNIPER_BPF_FILTER 0x40 /* BPF filtering is supported */
+#define JUNIPER_BPF_EXT 0x80 /* extensions present */
+#define JUNIPER_MGC_NUMBER 0x4d4743 /* = "MGC" */
+
+#define JUNIPER_LSQ_COOKIE_RE (1 << 3)
+#define JUNIPER_LSQ_COOKIE_DIR (1 << 2)
+#define JUNIPER_LSQ_L3_PROTO_SHIFT 4
+#define JUNIPER_LSQ_L3_PROTO_MASK (0x17 << JUNIPER_LSQ_L3_PROTO_SHIFT)
+#define JUNIPER_LSQ_L3_PROTO_IPV4 (0 << JUNIPER_LSQ_L3_PROTO_SHIFT)
+#define JUNIPER_LSQ_L3_PROTO_IPV6 (1 << JUNIPER_LSQ_L3_PROTO_SHIFT)
+#define JUNIPER_LSQ_L3_PROTO_MPLS (2 << JUNIPER_LSQ_L3_PROTO_SHIFT)
+#define JUNIPER_LSQ_L3_PROTO_ISO (3 << JUNIPER_LSQ_L3_PROTO_SHIFT)
+#define AS_PIC_COOKIE_LEN 8
+
+#define JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE 1
+#define JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE 2
+#define JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE 3
+#define JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE 4
+#define JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE 5
+
+static struct tok juniper_ipsec_type_values[] = {
+ { JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE, "ESP ENCR-AUTH" },
+ { JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE, "ESP ENCR-AH AUTH" },
+ { JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE, "ESP AUTH" },
+ { JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE, "AH AUTH" },
+ { JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE, "ESP ENCR" },
+ { 0, NULL}
+};
+
+static struct tok juniper_direction_values[] = {
+ { JUNIPER_BPF_IN, "In"},
+ { JUNIPER_BPF_OUT, "Out"},
+ { 0, NULL}
+};
+
+/* codepoints for encoding extensions to a .pcap file */
+enum {
+ JUNIPER_EXT_TLV_IFD_IDX = 1,
+ JUNIPER_EXT_TLV_IFD_NAME = 2,
+ JUNIPER_EXT_TLV_IFD_MEDIATYPE = 3,
+ JUNIPER_EXT_TLV_IFL_IDX = 4,
+ JUNIPER_EXT_TLV_IFL_UNIT = 5,
+ JUNIPER_EXT_TLV_IFL_ENCAPS = 6,
+ JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE = 7,
+ JUNIPER_EXT_TLV_TTP_IFL_ENCAPS = 8
+};
+
+/* 1 byte type and 1-byte length */
+#define JUNIPER_EXT_TLV_OVERHEAD 2
+
+struct tok jnx_ext_tlv_values[] = {
+ { JUNIPER_EXT_TLV_IFD_IDX, "Device Interface Index" },
+ { JUNIPER_EXT_TLV_IFD_NAME,"Device Interface Name" },
+ { JUNIPER_EXT_TLV_IFD_MEDIATYPE, "Device Media Type" },
+ { JUNIPER_EXT_TLV_IFL_IDX, "Logical Interface Index" },
+ { JUNIPER_EXT_TLV_IFL_UNIT,"Logical Unit Number" },
+ { JUNIPER_EXT_TLV_IFL_ENCAPS, "Logical Interface Encapsulation" },
+ { JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE, "TTP derived Device Media Type" },
+ { JUNIPER_EXT_TLV_TTP_IFL_ENCAPS, "TTP derived Logical Interface Encapsulation" },
+ { 0, NULL }
+};
+
+struct tok jnx_flag_values[] = {
+ { JUNIPER_BPF_EXT, "Ext" },
+ { JUNIPER_BPF_FILTER, "Filter" },
+ { JUNIPER_BPF_IIF, "IIF" },
+ { JUNIPER_BPF_NO_L2, "no-L2" },
+ { JUNIPER_BPF_PKT_IN, "In" },
+ { 0, NULL }
+};
+
+#define JUNIPER_IFML_ETHER 1
+#define JUNIPER_IFML_FDDI 2
+#define JUNIPER_IFML_TOKENRING 3
+#define JUNIPER_IFML_PPP 4
+#define JUNIPER_IFML_FRAMERELAY 5
+#define JUNIPER_IFML_CISCOHDLC 6
+#define JUNIPER_IFML_SMDSDXI 7
+#define JUNIPER_IFML_ATMPVC 8
+#define JUNIPER_IFML_PPP_CCC 9
+#define JUNIPER_IFML_FRAMERELAY_CCC 10
+#define JUNIPER_IFML_IPIP 11
+#define JUNIPER_IFML_GRE 12
+#define JUNIPER_IFML_PIM 13
+#define JUNIPER_IFML_PIMD 14
+#define JUNIPER_IFML_CISCOHDLC_CCC 15
+#define JUNIPER_IFML_VLAN_CCC 16
+#define JUNIPER_IFML_MLPPP 17
+#define JUNIPER_IFML_MLFR 18
+#define JUNIPER_IFML_ML 19
+#define JUNIPER_IFML_LSI 20
+#define JUNIPER_IFML_DFE 21
+#define JUNIPER_IFML_ATM_CELLRELAY_CCC 22
+#define JUNIPER_IFML_CRYPTO 23
+#define JUNIPER_IFML_GGSN 24
+#define JUNIPER_IFML_LSI_PPP 25
+#define JUNIPER_IFML_LSI_CISCOHDLC 26
+#define JUNIPER_IFML_PPP_TCC 27
+#define JUNIPER_IFML_FRAMERELAY_TCC 28
+#define JUNIPER_IFML_CISCOHDLC_TCC 29
+#define JUNIPER_IFML_ETHERNET_CCC 30
+#define JUNIPER_IFML_VT 31
+#define JUNIPER_IFML_EXTENDED_VLAN_CCC 32
+#define JUNIPER_IFML_ETHER_OVER_ATM 33
+#define JUNIPER_IFML_MONITOR 34
+#define JUNIPER_IFML_ETHERNET_TCC 35
+#define JUNIPER_IFML_VLAN_TCC 36
+#define JUNIPER_IFML_EXTENDED_VLAN_TCC 37
+#define JUNIPER_IFML_CONTROLLER 38
+#define JUNIPER_IFML_MFR 39
+#define JUNIPER_IFML_LS 40
+#define JUNIPER_IFML_ETHERNET_VPLS 41
+#define JUNIPER_IFML_ETHERNET_VLAN_VPLS 42
+#define JUNIPER_IFML_ETHERNET_EXTENDED_VLAN_VPLS 43
+#define JUNIPER_IFML_LT 44
+#define JUNIPER_IFML_SERVICES 45
+#define JUNIPER_IFML_ETHER_VPLS_OVER_ATM 46
+#define JUNIPER_IFML_FR_PORT_CCC 47
+#define JUNIPER_IFML_FRAMERELAY_EXT_CCC 48
+#define JUNIPER_IFML_FRAMERELAY_EXT_TCC 49
+#define JUNIPER_IFML_FRAMERELAY_FLEX 50
+#define JUNIPER_IFML_GGSNI 51
+#define JUNIPER_IFML_ETHERNET_FLEX 52
+#define JUNIPER_IFML_COLLECTOR 53
+#define JUNIPER_IFML_AGGREGATOR 54
+#define JUNIPER_IFML_LAPD 55
+#define JUNIPER_IFML_PPPOE 56
+#define JUNIPER_IFML_PPP_SUBORDINATE 57
+#define JUNIPER_IFML_CISCOHDLC_SUBORDINATE 58
+#define JUNIPER_IFML_DFC 59
+#define JUNIPER_IFML_PICPEER 60
+
+struct tok juniper_ifmt_values[] = {
+ { JUNIPER_IFML_ETHER, "Ethernet" },
+ { JUNIPER_IFML_FDDI, "FDDI" },
+ { JUNIPER_IFML_TOKENRING, "Token-Ring" },
+ { JUNIPER_IFML_PPP, "PPP" },
+ { JUNIPER_IFML_PPP_SUBORDINATE, "PPP-Subordinate" },
+ { JUNIPER_IFML_FRAMERELAY, "Frame-Relay" },
+ { JUNIPER_IFML_CISCOHDLC, "Cisco-HDLC" },
+ { JUNIPER_IFML_SMDSDXI, "SMDS-DXI" },
+ { JUNIPER_IFML_ATMPVC, "ATM-PVC" },
+ { JUNIPER_IFML_PPP_CCC, "PPP-CCC" },
+ { JUNIPER_IFML_FRAMERELAY_CCC, "Frame-Relay-CCC" },
+ { JUNIPER_IFML_FRAMERELAY_EXT_CCC, "Extended FR-CCC" },
+ { JUNIPER_IFML_IPIP, "IP-over-IP" },
+ { JUNIPER_IFML_GRE, "GRE" },
+ { JUNIPER_IFML_PIM, "PIM-Encapsulator" },
+ { JUNIPER_IFML_PIMD, "PIM-Decapsulator" },
+ { JUNIPER_IFML_CISCOHDLC_CCC, "Cisco-HDLC-CCC" },
+ { JUNIPER_IFML_VLAN_CCC, "VLAN-CCC" },
+ { JUNIPER_IFML_EXTENDED_VLAN_CCC, "Extended-VLAN-CCC" },
+ { JUNIPER_IFML_MLPPP, "Multilink-PPP" },
+ { JUNIPER_IFML_MLFR, "Multilink-FR" },
+ { JUNIPER_IFML_MFR, "Multilink-FR-UNI-NNI" },
+ { JUNIPER_IFML_ML, "Multilink" },
+ { JUNIPER_IFML_LS, "LinkService" },
+ { JUNIPER_IFML_LSI, "LSI" },
+ { JUNIPER_IFML_ATM_CELLRELAY_CCC, "ATM-CCC-Cell-Relay" },
+ { JUNIPER_IFML_CRYPTO, "IPSEC-over-IP" },
+ { JUNIPER_IFML_GGSN, "GGSN" },
+ { JUNIPER_IFML_PPP_TCC, "PPP-TCC" },
+ { JUNIPER_IFML_FRAMERELAY_TCC, "Frame-Relay-TCC" },
+ { JUNIPER_IFML_FRAMERELAY_EXT_TCC, "Extended FR-TCC" },
+ { JUNIPER_IFML_CISCOHDLC_TCC, "Cisco-HDLC-TCC" },
+ { JUNIPER_IFML_ETHERNET_CCC, "Ethernet-CCC" },
+ { JUNIPER_IFML_VT, "VPN-Loopback-tunnel" },
+ { JUNIPER_IFML_ETHER_OVER_ATM, "Ethernet-over-ATM" },
+ { JUNIPER_IFML_ETHER_VPLS_OVER_ATM, "Ethernet-VPLS-over-ATM" },
+ { JUNIPER_IFML_MONITOR, "Monitor" },
+ { JUNIPER_IFML_ETHERNET_TCC, "Ethernet-TCC" },
+ { JUNIPER_IFML_VLAN_TCC, "VLAN-TCC" },
+ { JUNIPER_IFML_EXTENDED_VLAN_TCC, "Extended-VLAN-TCC" },
+ { JUNIPER_IFML_CONTROLLER, "Controller" },
+ { JUNIPER_IFML_ETHERNET_VPLS, "VPLS" },
+ { JUNIPER_IFML_ETHERNET_VLAN_VPLS, "VLAN-VPLS" },
+ { JUNIPER_IFML_ETHERNET_EXTENDED_VLAN_VPLS, "Extended-VLAN-VPLS" },
+ { JUNIPER_IFML_LT, "Logical-tunnel" },
+ { JUNIPER_IFML_SERVICES, "General-Services" },
+ { JUNIPER_IFML_PPPOE, "PPPoE" },
+ { JUNIPER_IFML_ETHERNET_FLEX, "Flexible-Ethernet-Services" },
+ { JUNIPER_IFML_FRAMERELAY_FLEX, "Flexible-FrameRelay" },
+ { JUNIPER_IFML_COLLECTOR, "Flow-collection" },
+ { JUNIPER_IFML_PICPEER, "PIC Peer" },
+ { JUNIPER_IFML_DFC, "Dynamic-Flow-Capture" },
+ {0, NULL}
+};
+
+#define JUNIPER_IFLE_ATM_SNAP 2
+#define JUNIPER_IFLE_ATM_NLPID 3
+#define JUNIPER_IFLE_ATM_VCMUX 4
+#define JUNIPER_IFLE_ATM_LLC 5
+#define JUNIPER_IFLE_ATM_PPP_VCMUX 6
+#define JUNIPER_IFLE_ATM_PPP_LLC 7
+#define JUNIPER_IFLE_ATM_PPP_FUNI 8
+#define JUNIPER_IFLE_ATM_CCC 9
+#define JUNIPER_IFLE_FR_NLPID 10
+#define JUNIPER_IFLE_FR_SNAP 11
+#define JUNIPER_IFLE_FR_PPP 12
+#define JUNIPER_IFLE_FR_CCC 13
+#define JUNIPER_IFLE_ENET2 14
+#define JUNIPER_IFLE_IEEE8023_SNAP 15
+#define JUNIPER_IFLE_IEEE8023_LLC 16
+#define JUNIPER_IFLE_PPP 17
+#define JUNIPER_IFLE_CISCOHDLC 18
+#define JUNIPER_IFLE_PPP_CCC 19
+#define JUNIPER_IFLE_IPIP_NULL 20
+#define JUNIPER_IFLE_PIM_NULL 21
+#define JUNIPER_IFLE_GRE_NULL 22
+#define JUNIPER_IFLE_GRE_PPP 23
+#define JUNIPER_IFLE_PIMD_DECAPS 24
+#define JUNIPER_IFLE_CISCOHDLC_CCC 25
+#define JUNIPER_IFLE_ATM_CISCO_NLPID 26
+#define JUNIPER_IFLE_VLAN_CCC 27
+#define JUNIPER_IFLE_MLPPP 28
+#define JUNIPER_IFLE_MLFR 29
+#define JUNIPER_IFLE_LSI_NULL 30
+#define JUNIPER_IFLE_AGGREGATE_UNUSED 31
+#define JUNIPER_IFLE_ATM_CELLRELAY_CCC 32
+#define JUNIPER_IFLE_CRYPTO 33
+#define JUNIPER_IFLE_GGSN 34
+#define JUNIPER_IFLE_ATM_TCC 35
+#define JUNIPER_IFLE_FR_TCC 36
+#define JUNIPER_IFLE_PPP_TCC 37
+#define JUNIPER_IFLE_CISCOHDLC_TCC 38
+#define JUNIPER_IFLE_ETHERNET_CCC 39
+#define JUNIPER_IFLE_VT 40
+#define JUNIPER_IFLE_ATM_EOA_LLC 41
+#define JUNIPER_IFLE_EXTENDED_VLAN_CCC 42
+#define JUNIPER_IFLE_ATM_SNAP_TCC 43
+#define JUNIPER_IFLE_MONITOR 44
+#define JUNIPER_IFLE_ETHERNET_TCC 45
+#define JUNIPER_IFLE_VLAN_TCC 46
+#define JUNIPER_IFLE_EXTENDED_VLAN_TCC 47
+#define JUNIPER_IFLE_MFR 48
+#define JUNIPER_IFLE_ETHERNET_VPLS 49
+#define JUNIPER_IFLE_ETHERNET_VLAN_VPLS 50
+#define JUNIPER_IFLE_ETHERNET_EXTENDED_VLAN_VPLS 51
+#define JUNIPER_IFLE_SERVICES 52
+#define JUNIPER_IFLE_ATM_ETHER_VPLS_ATM_LLC 53
+#define JUNIPER_IFLE_FR_PORT_CCC 54
+#define JUNIPER_IFLE_ATM_MLPPP_LLC 55
+#define JUNIPER_IFLE_ATM_EOA_CCC 56
+#define JUNIPER_IFLE_LT_VLAN 57
+#define JUNIPER_IFLE_COLLECTOR 58
+#define JUNIPER_IFLE_AGGREGATOR 59
+#define JUNIPER_IFLE_LAPD 60
+#define JUNIPER_IFLE_ATM_PPPOE_LLC 61
+#define JUNIPER_IFLE_ETHERNET_PPPOE 62
+#define JUNIPER_IFLE_PPPOE 63
+#define JUNIPER_IFLE_PPP_SUBORDINATE 64
+#define JUNIPER_IFLE_CISCOHDLC_SUBORDINATE 65
+#define JUNIPER_IFLE_DFC 66
+#define JUNIPER_IFLE_PICPEER 67
+
+struct tok juniper_ifle_values[] = {
+ { JUNIPER_IFLE_AGGREGATOR, "Aggregator" },
+ { JUNIPER_IFLE_ATM_CCC, "CCC over ATM" },
+ { JUNIPER_IFLE_ATM_CELLRELAY_CCC, "ATM CCC Cell Relay" },
+ { JUNIPER_IFLE_ATM_CISCO_NLPID, "CISCO compatible NLPID" },
+ { JUNIPER_IFLE_ATM_EOA_CCC, "Ethernet over ATM CCC" },
+ { JUNIPER_IFLE_ATM_EOA_LLC, "Ethernet over ATM LLC" },
+ { JUNIPER_IFLE_ATM_ETHER_VPLS_ATM_LLC, "Ethernet VPLS over ATM LLC" },
+ { JUNIPER_IFLE_ATM_LLC, "ATM LLC" },
+ { JUNIPER_IFLE_ATM_MLPPP_LLC, "MLPPP over ATM LLC" },
+ { JUNIPER_IFLE_ATM_NLPID, "ATM NLPID" },
+ { JUNIPER_IFLE_ATM_PPPOE_LLC, "PPPoE over ATM LLC" },
+ { JUNIPER_IFLE_ATM_PPP_FUNI, "PPP over FUNI" },
+ { JUNIPER_IFLE_ATM_PPP_LLC, "PPP over ATM LLC" },
+ { JUNIPER_IFLE_ATM_PPP_VCMUX, "PPP over ATM VCMUX" },
+ { JUNIPER_IFLE_ATM_SNAP, "ATM SNAP" },
+ { JUNIPER_IFLE_ATM_SNAP_TCC, "ATM SNAP TCC" },
+ { JUNIPER_IFLE_ATM_TCC, "ATM VCMUX TCC" },
+ { JUNIPER_IFLE_ATM_VCMUX, "ATM VCMUX" },
+ { JUNIPER_IFLE_CISCOHDLC, "C-HDLC" },
+ { JUNIPER_IFLE_CISCOHDLC_CCC, "C-HDLC CCC" },
+ { JUNIPER_IFLE_CISCOHDLC_SUBORDINATE, "C-HDLC via dialer" },
+ { JUNIPER_IFLE_CISCOHDLC_TCC, "C-HDLC TCC" },
+ { JUNIPER_IFLE_COLLECTOR, "Collector" },
+ { JUNIPER_IFLE_CRYPTO, "Crypto" },
+ { JUNIPER_IFLE_ENET2, "Ethernet" },
+ { JUNIPER_IFLE_ETHERNET_CCC, "Ethernet CCC" },
+ { JUNIPER_IFLE_ETHERNET_EXTENDED_VLAN_VPLS, "Extended VLAN VPLS" },
+ { JUNIPER_IFLE_ETHERNET_PPPOE, "PPPoE over Ethernet" },
+ { JUNIPER_IFLE_ETHERNET_TCC, "Ethernet TCC" },
+ { JUNIPER_IFLE_ETHERNET_VLAN_VPLS, "VLAN VPLS" },
+ { JUNIPER_IFLE_ETHERNET_VPLS, "VPLS" },
+ { JUNIPER_IFLE_EXTENDED_VLAN_CCC, "Extended VLAN CCC" },
+ { JUNIPER_IFLE_EXTENDED_VLAN_TCC, "Extended VLAN TCC" },
+ { JUNIPER_IFLE_FR_CCC, "FR CCC" },
+ { JUNIPER_IFLE_FR_NLPID, "FR NLPID" },
+ { JUNIPER_IFLE_FR_PORT_CCC, "FR CCC" },
+ { JUNIPER_IFLE_FR_PPP, "FR PPP" },
+ { JUNIPER_IFLE_FR_SNAP, "FR SNAP" },
+ { JUNIPER_IFLE_FR_TCC, "FR TCC" },
+ { JUNIPER_IFLE_GGSN, "GGSN" },
+ { JUNIPER_IFLE_GRE_NULL, "GRE NULL" },
+ { JUNIPER_IFLE_GRE_PPP, "PPP over GRE" },
+ { JUNIPER_IFLE_IPIP_NULL, "IPIP" },
+ { JUNIPER_IFLE_LAPD, "LAPD" },
+ { JUNIPER_IFLE_LSI_NULL, "LSI Null" },
+ { JUNIPER_IFLE_LT_VLAN, "LT VLAN" },
+ { JUNIPER_IFLE_MFR, "MFR" },
+ { JUNIPER_IFLE_MLFR, "MLFR" },
+ { JUNIPER_IFLE_MLPPP, "MLPPP" },
+ { JUNIPER_IFLE_MONITOR, "Monitor" },
+ { JUNIPER_IFLE_PIMD_DECAPS, "PIMd" },
+ { JUNIPER_IFLE_PIM_NULL, "PIM Null" },
+ { JUNIPER_IFLE_PPP, "PPP" },
+ { JUNIPER_IFLE_PPPOE, "PPPoE" },
+ { JUNIPER_IFLE_PPP_CCC, "PPP CCC" },
+ { JUNIPER_IFLE_PPP_SUBORDINATE, "" },
+ { JUNIPER_IFLE_PPP_TCC, "PPP TCC" },
+ { JUNIPER_IFLE_SERVICES, "General Services" },
+ { JUNIPER_IFLE_VLAN_CCC, "VLAN CCC" },
+ { JUNIPER_IFLE_VLAN_TCC, "VLAN TCC" },
+ { JUNIPER_IFLE_VT, "VT" },
+ {0, NULL}
+};
+
+struct juniper_cookie_table_t {
+ u_int32_t pictype; /* pic type */
+ u_int8_t cookie_len; /* cookie len */
+ const char *s; /* pic name */
+};
+
+static struct juniper_cookie_table_t juniper_cookie_table[] = {
+#ifdef DLT_JUNIPER_ATM1
+ { DLT_JUNIPER_ATM1, 4, "ATM1"},
+#endif
+#ifdef DLT_JUNIPER_ATM2
+ { DLT_JUNIPER_ATM2, 8, "ATM2"},
+#endif
+#ifdef DLT_JUNIPER_MLPPP
+ { DLT_JUNIPER_MLPPP, 2, "MLPPP"},
+#endif
+#ifdef DLT_JUNIPER_MLFR
+ { DLT_JUNIPER_MLFR, 2, "MLFR"},
+#endif
+#ifdef DLT_JUNIPER_MFR
+ { DLT_JUNIPER_MFR, 4, "MFR"},
+#endif
+#ifdef DLT_JUNIPER_PPPOE
+ { DLT_JUNIPER_PPPOE, 0, "PPPoE"},
+#endif
+#ifdef DLT_JUNIPER_PPPOE_ATM
+ { DLT_JUNIPER_PPPOE_ATM, 0, "PPPoE ATM"},
+#endif
+#ifdef DLT_JUNIPER_GGSN
+ { DLT_JUNIPER_GGSN, 8, "GGSN"},
+#endif
+#ifdef DLT_JUNIPER_MONITOR
+ { DLT_JUNIPER_MONITOR, 8, "MONITOR"},
+#endif
+#ifdef DLT_JUNIPER_SERVICES
+ { DLT_JUNIPER_SERVICES, 8, "AS"},
+#endif
+#ifdef DLT_JUNIPER_ES
+ { DLT_JUNIPER_ES, 0, "ES"},
+#endif
+ { 0, 0, NULL }
+};
+
+struct juniper_l2info_t {
+ u_int32_t length;
+ u_int32_t caplen;
+ u_int32_t pictype;
+ u_int8_t direction;
+ u_int8_t header_len;
+ u_int8_t cookie_len;
+ u_int8_t cookie_type;
+ u_int8_t cookie[8];
+ u_int8_t bundle;
+ u_int16_t proto;
+ u_int8_t flags;
+};
+
+#define LS_COOKIE_ID 0x54
+#define AS_COOKIE_ID 0x47
+#define LS_MLFR_COOKIE_LEN 4
+#define ML_MLFR_COOKIE_LEN 2
+#define LS_MFR_COOKIE_LEN 6
+#define ATM1_COOKIE_LEN 4
+#define ATM2_COOKIE_LEN 8
+
+#define ATM2_PKT_TYPE_MASK 0x70
+#define ATM2_GAP_COUNT_MASK 0x3F
+
+#define JUNIPER_PROTO_NULL 1
+#define JUNIPER_PROTO_IPV4 2
+#define JUNIPER_PROTO_IPV6 6
+
+#define MFR_BE_MASK 0xc0
+
+static struct tok juniper_protocol_values[] = {
+ { JUNIPER_PROTO_NULL, "Null" },
+ { JUNIPER_PROTO_IPV4, "IPv4" },
+ { JUNIPER_PROTO_IPV6, "IPv6" },
+ { 0, NULL}
+};
+
+int ip_heuristic_guess(register const u_char *, u_int);
+int juniper_ppp_heuristic_guess(register const u_char *, u_int);
+int juniper_read_tlv_value(const u_char *, u_int, u_int);
+static int juniper_parse_header (const u_char *, const struct pcap_pkthdr *, struct juniper_l2info_t *);
+
+#ifdef DLT_JUNIPER_GGSN
+u_int
+juniper_ggsn_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ struct juniper_l2info_t l2info;
+ struct juniper_ggsn_header {
+ u_int8_t svc_id;
+ u_int8_t flags_len;
+ u_int8_t proto;
+ u_int8_t flags;
+ u_int8_t vlan_id[2];
+ u_int8_t res[2];
+ };
+ const struct juniper_ggsn_header *gh;
+
+ l2info.pictype = DLT_JUNIPER_GGSN;
+ if(juniper_parse_header(p, h, &l2info) == 0)
+ return l2info.header_len;
+
+ p+=l2info.header_len;
+ gh = (struct juniper_ggsn_header *)&l2info.cookie;
+
+ if (eflag) {
+ printf("proto %s (%u), vlan %u: ",
+ tok2str(juniper_protocol_values,"Unknown",gh->proto),
+ gh->proto,
+ EXTRACT_16BITS(&gh->vlan_id[0]));
+ }
+
+ switch (gh->proto) {
+ case JUNIPER_PROTO_IPV4:
+ ip_print(gndo, p, l2info.length);
+ break;
+#ifdef INET6
+ case JUNIPER_PROTO_IPV6:
+ ip6_print(gndo, p, l2info.length);
+ break;
+#endif /* INET6 */
+ default:
+ if (!eflag)
+ printf("unknown GGSN proto (%u)", gh->proto);
+ }
+
+ return l2info.header_len;
+}
+#endif
+
+#ifdef DLT_JUNIPER_ES
+u_int
+juniper_es_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ struct juniper_l2info_t l2info;
+ struct juniper_ipsec_header {
+ u_int8_t sa_index[2];
+ u_int8_t ttl;
+ u_int8_t type;
+ u_int8_t spi[4];
+ u_int8_t src_ip[4];
+ u_int8_t dst_ip[4];
+ };
+ u_int rewrite_len,es_type_bundle;
+ const struct juniper_ipsec_header *ih;
+
+ l2info.pictype = DLT_JUNIPER_ES;
+ if(juniper_parse_header(p, h, &l2info) == 0)
+ return l2info.header_len;
+
+ p+=l2info.header_len;
+ ih = (struct juniper_ipsec_header *)p;
+
+ switch (ih->type) {
+ case JUNIPER_IPSEC_O_ESP_ENCRYPT_ESP_AUTHEN_TYPE:
+ case JUNIPER_IPSEC_O_ESP_ENCRYPT_AH_AUTHEN_TYPE:
+ rewrite_len = 0;
+ es_type_bundle = 1;
+ break;
+ case JUNIPER_IPSEC_O_ESP_AUTHENTICATION_TYPE:
+ case JUNIPER_IPSEC_O_AH_AUTHENTICATION_TYPE:
+ case JUNIPER_IPSEC_O_ESP_ENCRYPTION_TYPE:
+ rewrite_len = 16;
+ es_type_bundle = 0;
+ default:
+ printf("ES Invalid type %u, length %u",
+ ih->type,
+ l2info.length);
+ return l2info.header_len;
+ }
+
+ l2info.length-=rewrite_len;
+ p+=rewrite_len;
+
+ if (eflag) {
+ if (!es_type_bundle) {
+ printf("ES SA, index %u, ttl %u type %s (%u), spi %u, Tunnel %s > %s, length %u\n",
+ EXTRACT_16BITS(&ih->sa_index),
+ ih->ttl,
+ tok2str(juniper_ipsec_type_values,"Unknown",ih->type),
+ ih->type,
+ EXTRACT_32BITS(&ih->spi),
+ ipaddr_string(&ih->src_ip),
+ ipaddr_string(&ih->dst_ip),
+ l2info.length);
+ } else {
+ printf("ES SA, index %u, ttl %u type %s (%u), length %u\n",
+ EXTRACT_16BITS(&ih->sa_index),
+ ih->ttl,
+ tok2str(juniper_ipsec_type_values,"Unknown",ih->type),
+ ih->type,
+ l2info.length);
+ }
+ }
+
+ ip_print(gndo, p, l2info.length);
+ return l2info.header_len;
+}
+#endif
+
+#ifdef DLT_JUNIPER_MONITOR
+u_int
+juniper_monitor_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ struct juniper_l2info_t l2info;
+ struct juniper_monitor_header {
+ u_int8_t pkt_type;
+ u_int8_t padding;
+ u_int8_t iif[2];
+ u_int8_t service_id[4];
+ };
+ const struct juniper_monitor_header *mh;
+
+ l2info.pictype = DLT_JUNIPER_MONITOR;
+ if(juniper_parse_header(p, h, &l2info) == 0)
+ return l2info.header_len;
+
+ p+=l2info.header_len;
+ mh = (struct juniper_monitor_header *)p;
+
+ if (eflag)
+ printf("service-id %u, iif %u, pkt-type %u: ",
+ EXTRACT_32BITS(&mh->service_id),
+ EXTRACT_16BITS(&mh->iif),
+ mh->pkt_type);
+
+ /* no proto field - lets guess by first byte of IP header*/
+ ip_heuristic_guess(p, l2info.length);
+
+ return l2info.header_len;
+}
+#endif
+
+#ifdef DLT_JUNIPER_SERVICES
+u_int
+juniper_services_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ struct juniper_l2info_t l2info;
+ struct juniper_services_header {
+ u_int8_t svc_id;
+ u_int8_t flags_len;
+ u_int8_t svc_set_id[2];
+ u_int8_t dir_iif[4];
+ };
+ const struct juniper_services_header *sh;
+
+ l2info.pictype = DLT_JUNIPER_SERVICES;
+ if(juniper_parse_header(p, h, &l2info) == 0)
+ return l2info.header_len;
+
+ p+=l2info.header_len;
+ sh = (struct juniper_services_header *)p;
+
+ if (eflag)
+ printf("service-id %u flags 0x%02x service-set-id 0x%04x iif %u: ",
+ sh->svc_id,
+ sh->flags_len,
+ EXTRACT_16BITS(&sh->svc_set_id),
+ EXTRACT_24BITS(&sh->dir_iif[1]));
+
+ /* no proto field - lets guess by first byte of IP header*/
+ ip_heuristic_guess(p, l2info.length);
+
+ return l2info.header_len;
+}
+#endif
+
+#ifdef DLT_JUNIPER_PPPOE
+u_int
+juniper_pppoe_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ struct juniper_l2info_t l2info;
+
+ l2info.pictype = DLT_JUNIPER_PPPOE;
+ if(juniper_parse_header(p, h, &l2info) == 0)
+ return l2info.header_len;
+
+ p+=l2info.header_len;
+ /* this DLT contains nothing but raw ethernet frames */
+ ether_print(gndo, p, l2info.length, l2info.caplen, NULL, NULL);
+ return l2info.header_len;
+}
+#endif
+
+#ifdef DLT_JUNIPER_ETHER
+u_int
+juniper_ether_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ struct juniper_l2info_t l2info;
+
+ l2info.pictype = DLT_JUNIPER_ETHER;
+ if(juniper_parse_header(p, h, &l2info) == 0)
+ return l2info.header_len;
+
+ p+=l2info.header_len;
+ /* this DLT contains nothing but raw Ethernet frames */
+ ether_print(gndo, p, l2info.length, l2info.caplen, NULL, NULL);
+ return l2info.header_len;
+}
+#endif
+
+#ifdef DLT_JUNIPER_PPP
+u_int
+juniper_ppp_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ struct juniper_l2info_t l2info;
+
+ l2info.pictype = DLT_JUNIPER_PPP;
+ if(juniper_parse_header(p, h, &l2info) == 0)
+ return l2info.header_len;
+
+ p+=l2info.header_len;
+ /* this DLT contains nothing but raw ppp frames */
+ ppp_print(p, l2info.length);
+ return l2info.header_len;
+}
+#endif
+
+#ifdef DLT_JUNIPER_FRELAY
+u_int
+juniper_frelay_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ struct juniper_l2info_t l2info;
+
+ l2info.pictype = DLT_JUNIPER_FRELAY;
+ if(juniper_parse_header(p, h, &l2info) == 0)
+ return l2info.header_len;
+
+ p+=l2info.header_len;
+ /* this DLT contains nothing but raw frame-relay frames */
+ fr_print(p, l2info.length);
+ return l2info.header_len;
+}
+#endif
+
+#ifdef DLT_JUNIPER_CHDLC
+u_int
+juniper_chdlc_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ struct juniper_l2info_t l2info;
+
+ l2info.pictype = DLT_JUNIPER_CHDLC;
+ if(juniper_parse_header(p, h, &l2info) == 0)
+ return l2info.header_len;
+
+ p+=l2info.header_len;
+ /* this DLT contains nothing but raw c-hdlc frames */
+ chdlc_print(p, l2info.length);
+ return l2info.header_len;
+}
+#endif
+
+#ifdef DLT_JUNIPER_PPPOE_ATM
+u_int
+juniper_pppoe_atm_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ struct juniper_l2info_t l2info;
+ u_int16_t extracted_ethertype;
+
+ l2info.pictype = DLT_JUNIPER_PPPOE_ATM;
+ if(juniper_parse_header(p, h, &l2info) == 0)
+ return l2info.header_len;
+
+ p+=l2info.header_len;
+
+ extracted_ethertype = EXTRACT_16BITS(p);
+ /* this DLT contains nothing but raw PPPoE frames,
+ * prepended with a type field*/
+ if (ethertype_print(gndo, extracted_ethertype,
+ p+ETHERTYPE_LEN,
+ l2info.length-ETHERTYPE_LEN,
+ l2info.caplen-ETHERTYPE_LEN) == 0)
+ /* ether_type not known, probably it wasn't one */
+ printf("unknown ethertype 0x%04x", extracted_ethertype);
+
+ return l2info.header_len;
+}
+#endif
+
+#ifdef DLT_JUNIPER_MLPPP
+u_int
+juniper_mlppp_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ struct juniper_l2info_t l2info;
+
+ l2info.pictype = DLT_JUNIPER_MLPPP;
+ if(juniper_parse_header(p, h, &l2info) == 0)
+ return l2info.header_len;
+
+ /* suppress Bundle-ID if frame was captured on a child-link
+ * best indicator if the cookie looks like a proto */
+ if (eflag &&
+ EXTRACT_16BITS(&l2info.cookie) != PPP_OSI &&
+ EXTRACT_16BITS(&l2info.cookie) != (PPP_ADDRESS << 8 | PPP_CONTROL))
+ printf("Bundle-ID %u: ",l2info.bundle);
+
+ p+=l2info.header_len;
+
+ /* first try the LSQ protos */
+ switch(l2info.proto) {
+ case JUNIPER_LSQ_L3_PROTO_IPV4:
+ /* IP traffic going to the RE would not have a cookie
+ * -> this must be incoming IS-IS over PPP
+ */
+ if (l2info.cookie[4] == (JUNIPER_LSQ_COOKIE_RE|JUNIPER_LSQ_COOKIE_DIR))
+ ppp_print(p, l2info.length);
+ else
+ ip_print(gndo, p, l2info.length);
+ return l2info.header_len;
+#ifdef INET6
+ case JUNIPER_LSQ_L3_PROTO_IPV6:
+ ip6_print(gndo, p,l2info.length);
+ return l2info.header_len;
+#endif
+ case JUNIPER_LSQ_L3_PROTO_MPLS:
+ mpls_print(p,l2info.length);
+ return l2info.header_len;
+ case JUNIPER_LSQ_L3_PROTO_ISO:
+ isoclns_print(p,l2info.length,l2info.caplen);
+ return l2info.header_len;
+ default:
+ break;
+ }
+
+ /* zero length cookie ? */
+ switch (EXTRACT_16BITS(&l2info.cookie)) {
+ case PPP_OSI:
+ ppp_print(p-2,l2info.length+2);
+ break;
+ case (PPP_ADDRESS << 8 | PPP_CONTROL): /* fall through */
+ default:
+ ppp_print(p,l2info.length);
+ break;
+ }
+
+ return l2info.header_len;
+}
+#endif
+
+
+#ifdef DLT_JUNIPER_MFR
+u_int
+juniper_mfr_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ struct juniper_l2info_t l2info;
+
+ l2info.pictype = DLT_JUNIPER_MFR;
+ if(juniper_parse_header(p, h, &l2info) == 0)
+ return l2info.header_len;
+
+ p+=l2info.header_len;
+
+ /* child-link ? */
+ if (l2info.cookie_len == 0) {
+ mfr_print(p,l2info.length);
+ return l2info.header_len;
+ }
+
+ /* first try the LSQ protos */
+ if (l2info.cookie_len == AS_PIC_COOKIE_LEN) {
+ switch(l2info.proto) {
+ case JUNIPER_LSQ_L3_PROTO_IPV4:
+ ip_print(gndo, p, l2info.length);
+ return l2info.header_len;
+#ifdef INET6
+ case JUNIPER_LSQ_L3_PROTO_IPV6:
+ ip6_print(gndo, p,l2info.length);
+ return l2info.header_len;
+#endif
+ case JUNIPER_LSQ_L3_PROTO_MPLS:
+ mpls_print(p,l2info.length);
+ return l2info.header_len;
+ case JUNIPER_LSQ_L3_PROTO_ISO:
+ isoclns_print(p,l2info.length,l2info.caplen);
+ return l2info.header_len;
+ default:
+ break;
+ }
+ return l2info.header_len;
+ }
+
+ /* suppress Bundle-ID if frame was captured on a child-link */
+ if (eflag && EXTRACT_32BITS(l2info.cookie) != 1) printf("Bundle-ID %u, ",l2info.bundle);
+ switch (l2info.proto) {
+ case (LLCSAP_ISONS<<8 | LLCSAP_ISONS):
+ isoclns_print(p+1, l2info.length-1, l2info.caplen-1);
+ break;
+ case (LLC_UI<<8 | NLPID_Q933):
+ case (LLC_UI<<8 | NLPID_IP):
+ case (LLC_UI<<8 | NLPID_IP6):
+ /* pass IP{4,6} to the OSI layer for proper link-layer printing */
+ isoclns_print(p-1, l2info.length+1, l2info.caplen+1);
+ break;
+ default:
+ printf("unknown protocol 0x%04x, length %u",l2info.proto, l2info.length);
+ }
+
+ return l2info.header_len;
+}
+#endif
+
+#ifdef DLT_JUNIPER_MLFR
+u_int
+juniper_mlfr_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ struct juniper_l2info_t l2info;
+
+ l2info.pictype = DLT_JUNIPER_MLFR;
+ if(juniper_parse_header(p, h, &l2info) == 0)
+ return l2info.header_len;
+
+ p+=l2info.header_len;
+
+ /* suppress Bundle-ID if frame was captured on a child-link */
+ if (eflag && EXTRACT_32BITS(l2info.cookie) != 1) printf("Bundle-ID %u, ",l2info.bundle);
+ switch (l2info.proto) {
+ case (LLC_UI):
+ case (LLC_UI<<8):
+ isoclns_print(p, l2info.length, l2info.caplen);
+ break;
+ case (LLC_UI<<8 | NLPID_Q933):
+ case (LLC_UI<<8 | NLPID_IP):
+ case (LLC_UI<<8 | NLPID_IP6):
+ /* pass IP{4,6} to the OSI layer for proper link-layer printing */
+ isoclns_print(p-1, l2info.length+1, l2info.caplen+1);
+ break;
+ default:
+ printf("unknown protocol 0x%04x, length %u",l2info.proto, l2info.length);
+ }
+
+ return l2info.header_len;
+}
+#endif
+
+/*
+ * ATM1 PIC cookie format
+ *
+ * +-----+-------------------------+-------------------------------+
+ * |fmtid| vc index | channel ID |
+ * +-----+-------------------------+-------------------------------+
+ */
+
+#ifdef DLT_JUNIPER_ATM1
+u_int
+juniper_atm1_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ u_int16_t extracted_ethertype;
+
+ struct juniper_l2info_t l2info;
+
+ l2info.pictype = DLT_JUNIPER_ATM1;
+ if(juniper_parse_header(p, h, &l2info) == 0)
+ return l2info.header_len;
+
+ p+=l2info.header_len;
+
+ if (l2info.cookie[0] == 0x80) { /* OAM cell ? */
+ oam_print(p,l2info.length,ATM_OAM_NOHEC);
+ return l2info.header_len;
+ }
+
+ if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */
+ EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */
+
+ if (llc_print(p, l2info.length, l2info.caplen, NULL, NULL,
+ &extracted_ethertype) != 0)
+ return l2info.header_len;
+ }
+
+ if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */
+ isoclns_print(p + 1, l2info.length - 1, l2info.caplen - 1);
+ /* FIXME check if frame was recognized */
+ return l2info.header_len;
+ }
+
+ if(ip_heuristic_guess(p, l2info.length) != 0) /* last try - vcmux encaps ? */
+ return l2info.header_len;
+
+ return l2info.header_len;
+}
+#endif
+
+/*
+ * ATM2 PIC cookie format
+ *
+ * +-------------------------------+---------+---+-----+-----------+
+ * | channel ID | reserv |AAL| CCRQ| gap cnt |
+ * +-------------------------------+---------+---+-----+-----------+
+ */
+
+#ifdef DLT_JUNIPER_ATM2
+u_int
+juniper_atm2_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ u_int16_t extracted_ethertype;
+
+ struct juniper_l2info_t l2info;
+
+ l2info.pictype = DLT_JUNIPER_ATM2;
+ if(juniper_parse_header(p, h, &l2info) == 0)
+ return l2info.header_len;
+
+ p+=l2info.header_len;
+
+ if (l2info.cookie[7] & ATM2_PKT_TYPE_MASK) { /* OAM cell ? */
+ oam_print(p,l2info.length,ATM_OAM_NOHEC);
+ return l2info.header_len;
+ }
+
+ if (EXTRACT_24BITS(p) == 0xfefe03 || /* NLPID encaps ? */
+ EXTRACT_24BITS(p) == 0xaaaa03) { /* SNAP encaps ? */
+
+ if (llc_print(p, l2info.length, l2info.caplen, NULL, NULL,
+ &extracted_ethertype) != 0)
+ return l2info.header_len;
+ }
+
+ if (l2info.direction != JUNIPER_BPF_PKT_IN && /* ether-over-1483 encaps ? */
+ (EXTRACT_32BITS(l2info.cookie) & ATM2_GAP_COUNT_MASK)) {
+ ether_print(gndo, p, l2info.length, l2info.caplen, NULL, NULL);
+ return l2info.header_len;
+ }
+
+ if (p[0] == 0x03) { /* Cisco style NLPID encaps ? */
+ isoclns_print(p + 1, l2info.length - 1, l2info.caplen - 1);
+ /* FIXME check if frame was recognized */
+ return l2info.header_len;
+ }
+
+ if(juniper_ppp_heuristic_guess(p, l2info.length) != 0) /* PPPoA vcmux encaps ? */
+ return l2info.header_len;
+
+ if(ip_heuristic_guess(p, l2info.length) != 0) /* last try - vcmux encaps ? */
+ return l2info.header_len;
+
+ return l2info.header_len;
+}
+#endif
+
+
+/* try to guess, based on all PPP protos that are supported in
+ * a juniper router if the payload data is encapsulated using PPP */
+int
+juniper_ppp_heuristic_guess(register const u_char *p, u_int length) {
+
+ switch(EXTRACT_16BITS(p)) {
+ case PPP_IP :
+ case PPP_OSI :
+ case PPP_MPLS_UCAST :
+ case PPP_MPLS_MCAST :
+ case PPP_IPCP :
+ case PPP_OSICP :
+ case PPP_MPLSCP :
+ case PPP_LCP :
+ case PPP_PAP :
+ case PPP_CHAP :
+ case PPP_ML :
+#ifdef INET6
+ case PPP_IPV6 :
+ case PPP_IPV6CP :
+#endif
+ ppp_print(p, length);
+ break;
+
+ default:
+ return 0; /* did not find a ppp header */
+ break;
+ }
+ return 1; /* we printed a ppp packet */
+}
+
+int
+ip_heuristic_guess(register const u_char *p, u_int length) {
+
+ switch(p[0]) {
+ case 0x45:
+ case 0x46:
+ case 0x47:
+ case 0x48:
+ case 0x49:
+ case 0x4a:
+ case 0x4b:
+ case 0x4c:
+ case 0x4d:
+ case 0x4e:
+ case 0x4f:
+ ip_print(gndo, p, length);
+ break;
+#ifdef INET6
+ case 0x60:
+ case 0x61:
+ case 0x62:
+ case 0x63:
+ case 0x64:
+ case 0x65:
+ case 0x66:
+ case 0x67:
+ case 0x68:
+ case 0x69:
+ case 0x6a:
+ case 0x6b:
+ case 0x6c:
+ case 0x6d:
+ case 0x6e:
+ case 0x6f:
+ ip6_print(gndo, p, length);
+ break;
+#endif
+ default:
+ return 0; /* did not find a ip header */
+ break;
+ }
+ return 1; /* we printed an v4/v6 packet */
+}
+
+int
+juniper_read_tlv_value(const u_char *p, u_int tlv_type, u_int tlv_len) {
+
+ int tlv_value;
+
+ /* TLVs < 128 are little endian encoded */
+ if (tlv_type < 128) {
+ switch (tlv_len) {
+ case 1:
+ tlv_value = *p;
+ break;
+ case 2:
+ tlv_value = EXTRACT_LE_16BITS(p);
+ break;
+ case 3:
+ tlv_value = EXTRACT_LE_24BITS(p);
+ break;
+ case 4:
+ tlv_value = EXTRACT_LE_32BITS(p);
+ break;
+ default:
+ tlv_value = -1;
+ break;
+ }
+ } else {
+ /* TLVs >= 128 are big endian encoded */
+ switch (tlv_len) {
+ case 1:
+ tlv_value = *p;
+ break;
+ case 2:
+ tlv_value = EXTRACT_16BITS(p);
+ break;
+ case 3:
+ tlv_value = EXTRACT_24BITS(p);
+ break;
+ case 4:
+ tlv_value = EXTRACT_32BITS(p);
+ break;
+ default:
+ tlv_value = -1;
+ break;
+ }
+ }
+ return tlv_value;
+}
+
+static int
+juniper_parse_header (const u_char *p, const struct pcap_pkthdr *h, struct juniper_l2info_t *l2info) {
+
+ struct juniper_cookie_table_t *lp = juniper_cookie_table;
+ u_int idx, jnx_ext_len, jnx_header_len = 0;
+ u_int8_t tlv_type,tlv_len;
+ u_int32_t control_word;
+ int tlv_value;
+ const u_char *tptr;
+
+
+ l2info->header_len = 0;
+ l2info->cookie_len = 0;
+ l2info->proto = 0;
+
+
+ l2info->length = h->len;
+ l2info->caplen = h->caplen;
+ TCHECK2(p[0],4);
+ l2info->flags = p[3];
+ l2info->direction = p[3]&JUNIPER_BPF_PKT_IN;
+
+ if (EXTRACT_24BITS(p) != JUNIPER_MGC_NUMBER) { /* magic number found ? */
+ printf("no magic-number found!");
+ return 0;
+ }
+
+ if (eflag) /* print direction */
+ printf("%3s ",tok2str(juniper_direction_values,"---",l2info->direction));
+
+ /* magic number + flags */
+ jnx_header_len = 4;
+
+ if (vflag>1)
+ printf("\n\tJuniper PCAP Flags [%s]",
+ bittok2str(jnx_flag_values, "none", l2info->flags));
+
+ /* extensions present ? - calculate how much bytes to skip */
+ if ((l2info->flags & JUNIPER_BPF_EXT ) == JUNIPER_BPF_EXT ) {
+
+ tptr = p+jnx_header_len;
+
+ /* ok to read extension length ? */
+ TCHECK2(tptr[0], 2);
+ jnx_ext_len = EXTRACT_16BITS(tptr);
+ jnx_header_len += 2;
+ tptr +=2;
+
+ /* nail up the total length -
+ * just in case something goes wrong
+ * with TLV parsing */
+ jnx_header_len += jnx_ext_len;
+
+ if (vflag>1)
+ printf(", PCAP Extension(s) total length %u",
+ jnx_ext_len);
+
+ TCHECK2(tptr[0], jnx_ext_len);
+ while (jnx_ext_len > JUNIPER_EXT_TLV_OVERHEAD) {
+ tlv_type = *(tptr++);
+ tlv_len = *(tptr++);
+ tlv_value = 0;
+
+ /* sanity check */
+ if (tlv_type == 0 || tlv_len == 0)
+ break;
+
+ if (vflag>1)
+ printf("\n\t %s Extension TLV #%u, length %u, value ",
+ tok2str(jnx_ext_tlv_values,"Unknown",tlv_type),
+ tlv_type,
+ tlv_len);
+
+ tlv_value = juniper_read_tlv_value(tptr, tlv_type, tlv_len);
+ switch (tlv_type) {
+ case JUNIPER_EXT_TLV_IFD_NAME:
+ /* FIXME */
+ break;
+ case JUNIPER_EXT_TLV_IFD_MEDIATYPE:
+ case JUNIPER_EXT_TLV_TTP_IFD_MEDIATYPE:
+ if (tlv_value != -1) {
+ if (vflag>1)
+ printf("%s (%u)",
+ tok2str(juniper_ifmt_values, "Unknown", tlv_value),
+ tlv_value);
+ }
+ break;
+ case JUNIPER_EXT_TLV_IFL_ENCAPS:
+ case JUNIPER_EXT_TLV_TTP_IFL_ENCAPS:
+ if (tlv_value != -1) {
+ if (vflag>1)
+ printf("%s (%u)",
+ tok2str(juniper_ifle_values, "Unknown", tlv_value),
+ tlv_value);
+ }
+ break;
+ case JUNIPER_EXT_TLV_IFL_IDX: /* fall through */
+ case JUNIPER_EXT_TLV_IFL_UNIT:
+ case JUNIPER_EXT_TLV_IFD_IDX:
+ default:
+ if (tlv_value != -1) {
+ if (vflag>1)
+ printf("%u",tlv_value);
+ }
+ break;
+ }
+
+ tptr+=tlv_len;
+ jnx_ext_len -= tlv_len+JUNIPER_EXT_TLV_OVERHEAD;
+ }
+
+ if (vflag>1)
+ printf("\n\t-----original packet-----\n\t");
+ }
+
+ if ((l2info->flags & JUNIPER_BPF_NO_L2 ) == JUNIPER_BPF_NO_L2 ) {
+ if (eflag)
+ printf("no-L2-hdr, ");
+
+ /* there is no link-layer present -
+ * perform the v4/v6 heuristics
+ * to figure out what it is
+ */
+ TCHECK2(p[jnx_header_len+4],1);
+ if(ip_heuristic_guess(p+jnx_header_len+4,l2info->length-(jnx_header_len+4)) == 0)
+ printf("no IP-hdr found!");
+
+ l2info->header_len=jnx_header_len+4;
+ return 0; /* stop parsing the output further */
+
+ }
+ l2info->header_len = jnx_header_len;
+ p+=l2info->header_len;
+ l2info->length -= l2info->header_len;
+ l2info->caplen -= l2info->header_len;
+
+ /* search through the cookie table and copy values matching for our PIC type */
+ while (lp->s != NULL) {
+ if (lp->pictype == l2info->pictype) {
+
+ l2info->cookie_len += lp->cookie_len;
+
+ switch (p[0]) {
+ case LS_COOKIE_ID:
+ l2info->cookie_type = LS_COOKIE_ID;
+ l2info->cookie_len += 2;
+ break;
+ case AS_COOKIE_ID:
+ l2info->cookie_type = AS_COOKIE_ID;
+ l2info->cookie_len = 8;
+ break;
+
+ default:
+ l2info->bundle = l2info->cookie[0];
+ break;
+ }
+
+
+#ifdef DLT_JUNIPER_MFR
+ /* MFR child links don't carry cookies */
+ if (l2info->pictype == DLT_JUNIPER_MFR &&
+ (p[0] & MFR_BE_MASK) == MFR_BE_MASK) {
+ l2info->cookie_len = 0;
+ }
+#endif
+
+ l2info->header_len += l2info->cookie_len;
+ l2info->length -= l2info->cookie_len;
+ l2info->caplen -= l2info->cookie_len;
+
+ if (eflag)
+ printf("%s-PIC, cookie-len %u",
+ lp->s,
+ l2info->cookie_len);
+
+ if (l2info->cookie_len > 0) {
+ TCHECK2(p[0],l2info->cookie_len);
+ if (eflag)
+ printf(", cookie 0x");
+ for (idx = 0; idx < l2info->cookie_len; idx++) {
+ l2info->cookie[idx] = p[idx]; /* copy cookie data */
+ if (eflag) printf("%02x",p[idx]);
+ }
+ }
+
+ if (eflag) printf(": "); /* print demarc b/w L2/L3*/
+
+
+ l2info->proto = EXTRACT_16BITS(p+l2info->cookie_len);
+ break;
+ }
+ ++lp;
+ }
+ p+=l2info->cookie_len;
+
+ /* DLT_ specific parsing */
+ switch(l2info->pictype) {
+#ifdef DLT_JUNIPER_MLPPP
+ case DLT_JUNIPER_MLPPP:
+ switch (l2info->cookie_type) {
+ case LS_COOKIE_ID:
+ l2info->bundle = l2info->cookie[1];
+ break;
+ case AS_COOKIE_ID:
+ l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff;
+ l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
+ break;
+ default:
+ l2info->bundle = l2info->cookie[0];
+ break;
+ }
+ break;
+#endif
+#ifdef DLT_JUNIPER_MLFR
+ case DLT_JUNIPER_MLFR:
+ switch (l2info->cookie_type) {
+ case LS_COOKIE_ID:
+ l2info->bundle = l2info->cookie[1];
+ l2info->proto = EXTRACT_16BITS(p);
+ l2info->header_len += 2;
+ l2info->length -= 2;
+ l2info->caplen -= 2;
+ break;
+ case AS_COOKIE_ID:
+ l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff;
+ l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
+ break;
+ default:
+ l2info->bundle = l2info->cookie[0];
+ l2info->header_len += 2;
+ l2info->length -= 2;
+ l2info->caplen -= 2;
+ break;
+ }
+ break;
+#endif
+#ifdef DLT_JUNIPER_MFR
+ case DLT_JUNIPER_MFR:
+ switch (l2info->cookie_type) {
+ case LS_COOKIE_ID:
+ l2info->bundle = l2info->cookie[1];
+ l2info->proto = EXTRACT_16BITS(p);
+ l2info->header_len += 2;
+ l2info->length -= 2;
+ l2info->caplen -= 2;
+ break;
+ case AS_COOKIE_ID:
+ l2info->bundle = (EXTRACT_16BITS(&l2info->cookie[6])>>3)&0xfff;
+ l2info->proto = (l2info->cookie[5])&JUNIPER_LSQ_L3_PROTO_MASK;
+ break;
+ default:
+ l2info->bundle = l2info->cookie[0];
+ break;
+ }
+ break;
+#endif
+#ifdef DLT_JUNIPER_ATM2
+ case DLT_JUNIPER_ATM2:
+ TCHECK2(p[0],4);
+ /* ATM cell relay control word present ? */
+ if (l2info->cookie[7] & ATM2_PKT_TYPE_MASK) {
+ control_word = EXTRACT_32BITS(p);
+ /* some control word heuristics */
+ switch(control_word) {
+ case 0: /* zero control word */
+ case 0x08000000: /* < JUNOS 7.4 control-word */
+ case 0x08380000: /* cntl word plus cell length (56) >= JUNOS 7.4*/
+ l2info->header_len += 4;
+ break;
+ default:
+ break;
+ }
+
+ if (eflag)
+ printf("control-word 0x%08x ", control_word);
+ }
+ break;
+#endif
+#ifdef DLT_JUNIPER_GGSN
+ case DLT_JUNIPER_GGSN:
+ break;
+#endif
+#ifdef DLT_JUNIPER_ATM1
+ case DLT_JUNIPER_ATM1:
+ break;
+#endif
+#ifdef DLT_JUNIPER_PPP
+ case DLT_JUNIPER_PPP:
+ break;
+#endif
+#ifdef DLT_JUNIPER_CHDLC
+ case DLT_JUNIPER_CHDLC:
+ break;
+#endif
+#ifdef DLT_JUNIPER_ETHER
+ case DLT_JUNIPER_ETHER:
+ break;
+#endif
+#ifdef DLT_JUNIPER_FRELAY
+ case DLT_JUNIPER_FRELAY:
+ break;
+#endif
+
+ default:
+ printf("Unknown Juniper DLT_ type %u: ", l2info->pictype);
+ break;
+ }
+
+ if (eflag > 1)
+ printf("hlen %u, proto 0x%04x, ",l2info->header_len,l2info->proto);
+
+ return 1; /* everything went ok so far. continue parsing */
+ trunc:
+ printf("[|juniper_hdr], length %u",h->len);
+ return 0;
+}
+
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-krb.c b/freebsd/contrib/tcpdump/print-krb.c
new file mode 100644
index 00000000..b18203b1
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-krb.c
@@ -0,0 +1,263 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Initial contribution from John Hawkinson (jhawk@mit.edu).
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-krb.c,v 1.23 2003-11-16 09:36:26 guy Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+static const u_char *c_print(register const u_char *, register const u_char *);
+static const u_char *krb4_print_hdr(const u_char *);
+static void krb4_print(const u_char *);
+
+#define AUTH_MSG_KDC_REQUEST 1<<1
+#define AUTH_MSG_KDC_REPLY 2<<1
+#define AUTH_MSG_APPL_REQUEST 3<<1
+#define AUTH_MSG_APPL_REQUEST_MUTUAL 4<<1
+#define AUTH_MSG_ERR_REPLY 5<<1
+#define AUTH_MSG_PRIVATE 6<<1
+#define AUTH_MSG_SAFE 7<<1
+#define AUTH_MSG_APPL_ERR 8<<1
+#define AUTH_MSG_DIE 63<<1
+
+#define KERB_ERR_OK 0
+#define KERB_ERR_NAME_EXP 1
+#define KERB_ERR_SERVICE_EXP 2
+#define KERB_ERR_AUTH_EXP 3
+#define KERB_ERR_PKT_VER 4
+#define KERB_ERR_NAME_MAST_KEY_VER 5
+#define KERB_ERR_SERV_MAST_KEY_VER 6
+#define KERB_ERR_BYTE_ORDER 7
+#define KERB_ERR_PRINCIPAL_UNKNOWN 8
+#define KERB_ERR_PRINCIPAL_NOT_UNIQUE 9
+#define KERB_ERR_NULL_KEY 10
+
+struct krb {
+ u_int8_t pvno; /* Protocol Version */
+ u_int8_t type; /* Type+B */
+};
+
+static char tstr[] = " [|kerberos]";
+
+static struct tok type2str[] = {
+ { AUTH_MSG_KDC_REQUEST, "KDC_REQUEST" },
+ { AUTH_MSG_KDC_REPLY, "KDC_REPLY" },
+ { AUTH_MSG_APPL_REQUEST, "APPL_REQUEST" },
+ { AUTH_MSG_APPL_REQUEST_MUTUAL, "APPL_REQUEST_MUTUAL" },
+ { AUTH_MSG_ERR_REPLY, "ERR_REPLY" },
+ { AUTH_MSG_PRIVATE, "PRIVATE" },
+ { AUTH_MSG_SAFE, "SAFE" },
+ { AUTH_MSG_APPL_ERR, "APPL_ERR" },
+ { AUTH_MSG_DIE, "DIE" },
+ { 0, NULL }
+};
+
+static struct tok kerr2str[] = {
+ { KERB_ERR_OK, "OK" },
+ { KERB_ERR_NAME_EXP, "NAME_EXP" },
+ { KERB_ERR_SERVICE_EXP, "SERVICE_EXP" },
+ { KERB_ERR_AUTH_EXP, "AUTH_EXP" },
+ { KERB_ERR_PKT_VER, "PKT_VER" },
+ { KERB_ERR_NAME_MAST_KEY_VER, "NAME_MAST_KEY_VER" },
+ { KERB_ERR_SERV_MAST_KEY_VER, "SERV_MAST_KEY_VER" },
+ { KERB_ERR_BYTE_ORDER, "BYTE_ORDER" },
+ { KERB_ERR_PRINCIPAL_UNKNOWN, "PRINCIPAL_UNKNOWN" },
+ { KERB_ERR_PRINCIPAL_NOT_UNIQUE,"PRINCIPAL_NOT_UNIQUE" },
+ { KERB_ERR_NULL_KEY, "NULL_KEY"},
+ { 0, NULL}
+};
+
+static const u_char *
+c_print(register const u_char *s, register const u_char *ep)
+{
+ register u_char c;
+ register int flag;
+
+ flag = 1;
+ while (s < ep) {
+ c = *s++;
+ if (c == '\0') {
+ flag = 0;
+ break;
+ }
+ if (!isascii(c)) {
+ c = toascii(c);
+ putchar('M');
+ putchar('-');
+ }
+ if (!isprint(c)) {
+ c ^= 0x40; /* DEL to ?, others to alpha */
+ putchar('^');
+ }
+ putchar(c);
+ }
+ if (flag)
+ return NULL;
+ return (s);
+}
+
+static const u_char *
+krb4_print_hdr(const u_char *cp)
+{
+ cp += 2;
+
+#define PRINT if ((cp = c_print(cp, snapend)) == NULL) goto trunc
+
+ PRINT;
+ putchar('.');
+ PRINT;
+ putchar('@');
+ PRINT;
+ return (cp);
+
+trunc:
+ fputs(tstr, stdout);
+ return (NULL);
+
+#undef PRINT
+}
+
+static void
+krb4_print(const u_char *cp)
+{
+ register const struct krb *kp;
+ u_char type;
+ u_short len;
+
+#define PRINT if ((cp = c_print(cp, snapend)) == NULL) goto trunc
+/* True if struct krb is little endian */
+#define IS_LENDIAN(kp) (((kp)->type & 0x01) != 0)
+#define KTOHSP(kp, cp) (IS_LENDIAN(kp) ? EXTRACT_LE_16BITS(cp) : EXTRACT_16BITS(cp))
+
+ kp = (struct krb *)cp;
+
+ if ((&kp->type) >= snapend) {
+ fputs(tstr, stdout);
+ return;
+ }
+
+ type = kp->type & (0xFF << 1);
+
+ printf(" %s %s: ",
+ IS_LENDIAN(kp) ? "le" : "be", tok2str(type2str, NULL, type));
+
+ switch (type) {
+
+ case AUTH_MSG_KDC_REQUEST:
+ if ((cp = krb4_print_hdr(cp)) == NULL)
+ return;
+ cp += 4; /* ctime */
+ TCHECK(*cp);
+ printf(" %dmin ", *cp++ * 5);
+ PRINT;
+ putchar('.');
+ PRINT;
+ break;
+
+ case AUTH_MSG_APPL_REQUEST:
+ cp += 2;
+ TCHECK(*cp);
+ printf("v%d ", *cp++);
+ PRINT;
+ TCHECK(*cp);
+ printf(" (%d)", *cp++);
+ TCHECK(*cp);
+ printf(" (%d)", *cp);
+ break;
+
+ case AUTH_MSG_KDC_REPLY:
+ if ((cp = krb4_print_hdr(cp)) == NULL)
+ return;
+ cp += 10; /* timestamp + n + exp + kvno */
+ TCHECK2(*cp, sizeof(short));
+ len = KTOHSP(kp, cp);
+ printf(" (%d)", len);
+ break;
+
+ case AUTH_MSG_ERR_REPLY:
+ if ((cp = krb4_print_hdr(cp)) == NULL)
+ return;
+ cp += 4; /* timestamp */
+ TCHECK2(*cp, sizeof(short));
+ printf(" %s ", tok2str(kerr2str, NULL, KTOHSP(kp, cp)));
+ cp += 4;
+ PRINT;
+ break;
+
+ default:
+ fputs("(unknown)", stdout);
+ break;
+ }
+
+ return;
+trunc:
+ fputs(tstr, stdout);
+}
+
+void
+krb_print(const u_char *dat)
+{
+ register const struct krb *kp;
+
+ kp = (struct krb *)dat;
+
+ if (dat >= snapend) {
+ fputs(tstr, stdout);
+ return;
+ }
+
+ switch (kp->pvno) {
+
+ case 1:
+ case 2:
+ case 3:
+ printf(" v%d", kp->pvno);
+ break;
+
+ case 4:
+ printf(" v%d", kp->pvno);
+ krb4_print((const u_char *)kp);
+ break;
+
+ case 106:
+ case 107:
+ fputs(" v5", stdout);
+ /* Decode ASN.1 here "someday" */
+ break;
+ }
+ return;
+}
diff --git a/freebsd/contrib/tcpdump/print-l2tp.c b/freebsd/contrib/tcpdump/print-l2tp.c
new file mode 100644
index 00000000..d62e1c8e
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-l2tp.c
@@ -0,0 +1,721 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1991, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * L2TP support contributed by Motonori Shindo (mshindo@mshindo.net)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-l2tp.c,v 1.20 2006-06-23 02:03:09 hannes Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+
+#include "l2tp.h"
+#include "interface.h"
+#include "extract.h"
+
+static char tstr[] = " [|l2tp]";
+
+#define L2TP_MSGTYPE_SCCRQ 1 /* Start-Control-Connection-Request */
+#define L2TP_MSGTYPE_SCCRP 2 /* Start-Control-Connection-Reply */
+#define L2TP_MSGTYPE_SCCCN 3 /* Start-Control-Connection-Connected */
+#define L2TP_MSGTYPE_STOPCCN 4 /* Stop-Control-Connection-Notification */
+#define L2TP_MSGTYPE_HELLO 6 /* Hello */
+#define L2TP_MSGTYPE_OCRQ 7 /* Outgoing-Call-Request */
+#define L2TP_MSGTYPE_OCRP 8 /* Outgoing-Call-Reply */
+#define L2TP_MSGTYPE_OCCN 9 /* Outgoing-Call-Connected */
+#define L2TP_MSGTYPE_ICRQ 10 /* Incoming-Call-Request */
+#define L2TP_MSGTYPE_ICRP 11 /* Incoming-Call-Reply */
+#define L2TP_MSGTYPE_ICCN 12 /* Incoming-Call-Connected */
+#define L2TP_MSGTYPE_CDN 14 /* Call-Disconnect-Notify */
+#define L2TP_MSGTYPE_WEN 15 /* WAN-Error-Notify */
+#define L2TP_MSGTYPE_SLI 16 /* Set-Link-Info */
+
+static struct tok l2tp_msgtype2str[] = {
+ { L2TP_MSGTYPE_SCCRQ, "SCCRQ" },
+ { L2TP_MSGTYPE_SCCRP, "SCCRP" },
+ { L2TP_MSGTYPE_SCCCN, "SCCCN" },
+ { L2TP_MSGTYPE_STOPCCN, "StopCCN" },
+ { L2TP_MSGTYPE_HELLO, "HELLO" },
+ { L2TP_MSGTYPE_OCRQ, "OCRQ" },
+ { L2TP_MSGTYPE_OCRP, "OCRP" },
+ { L2TP_MSGTYPE_OCCN, "OCCN" },
+ { L2TP_MSGTYPE_ICRQ, "ICRQ" },
+ { L2TP_MSGTYPE_ICRP, "ICRP" },
+ { L2TP_MSGTYPE_ICCN, "ICCN" },
+ { L2TP_MSGTYPE_CDN, "CDN" },
+ { L2TP_MSGTYPE_WEN, "WEN" },
+ { L2TP_MSGTYPE_SLI, "SLI" },
+ { 0, NULL }
+};
+
+#define L2TP_AVP_MSGTYPE 0 /* Message Type */
+#define L2TP_AVP_RESULT_CODE 1 /* Result Code */
+#define L2TP_AVP_PROTO_VER 2 /* Protocol Version */
+#define L2TP_AVP_FRAMING_CAP 3 /* Framing Capabilities */
+#define L2TP_AVP_BEARER_CAP 4 /* Bearer Capabilities */
+#define L2TP_AVP_TIE_BREAKER 5 /* Tie Breaker */
+#define L2TP_AVP_FIRM_VER 6 /* Firmware Revision */
+#define L2TP_AVP_HOST_NAME 7 /* Host Name */
+#define L2TP_AVP_VENDOR_NAME 8 /* Vendor Name */
+#define L2TP_AVP_ASSND_TUN_ID 9 /* Assigned Tunnel ID */
+#define L2TP_AVP_RECV_WIN_SIZE 10 /* Receive Window Size */
+#define L2TP_AVP_CHALLENGE 11 /* Challenge */
+#define L2TP_AVP_Q931_CC 12 /* Q.931 Cause Code */
+#define L2TP_AVP_CHALLENGE_RESP 13 /* Challenge Response */
+#define L2TP_AVP_ASSND_SESS_ID 14 /* Assigned Session ID */
+#define L2TP_AVP_CALL_SER_NUM 15 /* Call Serial Number */
+#define L2TP_AVP_MINIMUM_BPS 16 /* Minimum BPS */
+#define L2TP_AVP_MAXIMUM_BPS 17 /* Maximum BPS */
+#define L2TP_AVP_BEARER_TYPE 18 /* Bearer Type */
+#define L2TP_AVP_FRAMING_TYPE 19 /* Framing Type */
+#define L2TP_AVP_PACKET_PROC_DELAY 20 /* Packet Processing Delay (OBSOLETE) */
+#define L2TP_AVP_CALLED_NUMBER 21 /* Called Number */
+#define L2TP_AVP_CALLING_NUMBER 22 /* Calling Number */
+#define L2TP_AVP_SUB_ADDRESS 23 /* Sub-Address */
+#define L2TP_AVP_TX_CONN_SPEED 24 /* (Tx) Connect Speed */
+#define L2TP_AVP_PHY_CHANNEL_ID 25 /* Physical Channel ID */
+#define L2TP_AVP_INI_RECV_LCP 26 /* Initial Received LCP CONFREQ */
+#define L2TP_AVP_LAST_SENT_LCP 27 /* Last Sent LCP CONFREQ */
+#define L2TP_AVP_LAST_RECV_LCP 28 /* Last Received LCP CONFREQ */
+#define L2TP_AVP_PROXY_AUTH_TYPE 29 /* Proxy Authen Type */
+#define L2TP_AVP_PROXY_AUTH_NAME 30 /* Proxy Authen Name */
+#define L2TP_AVP_PROXY_AUTH_CHAL 31 /* Proxy Authen Challenge */
+#define L2TP_AVP_PROXY_AUTH_ID 32 /* Proxy Authen ID */
+#define L2TP_AVP_PROXY_AUTH_RESP 33 /* Proxy Authen Response */
+#define L2TP_AVP_CALL_ERRORS 34 /* Call Errors */
+#define L2TP_AVP_ACCM 35 /* ACCM */
+#define L2TP_AVP_RANDOM_VECTOR 36 /* Random Vector */
+#define L2TP_AVP_PRIVATE_GRP_ID 37 /* Private Group ID */
+#define L2TP_AVP_RX_CONN_SPEED 38 /* (Rx) Connect Speed */
+#define L2TP_AVP_SEQ_REQUIRED 39 /* Sequencing Required */
+#define L2TP_AVP_PPP_DISCON_CC 46 /* PPP Disconnect Cause Code */
+
+static struct tok l2tp_avp2str[] = {
+ { L2TP_AVP_MSGTYPE, "MSGTYPE" },
+ { L2TP_AVP_RESULT_CODE, "RESULT_CODE" },
+ { L2TP_AVP_PROTO_VER, "PROTO_VER" },
+ { L2TP_AVP_FRAMING_CAP, "FRAMING_CAP" },
+ { L2TP_AVP_BEARER_CAP, "BEARER_CAP" },
+ { L2TP_AVP_TIE_BREAKER, "TIE_BREAKER" },
+ { L2TP_AVP_FIRM_VER, "FIRM_VER" },
+ { L2TP_AVP_HOST_NAME, "HOST_NAME" },
+ { L2TP_AVP_VENDOR_NAME, "VENDOR_NAME" },
+ { L2TP_AVP_ASSND_TUN_ID, "ASSND_TUN_ID" },
+ { L2TP_AVP_RECV_WIN_SIZE, "RECV_WIN_SIZE" },
+ { L2TP_AVP_CHALLENGE, "CHALLENGE" },
+ { L2TP_AVP_Q931_CC, "Q931_CC", },
+ { L2TP_AVP_CHALLENGE_RESP, "CHALLENGE_RESP" },
+ { L2TP_AVP_ASSND_SESS_ID, "ASSND_SESS_ID" },
+ { L2TP_AVP_CALL_SER_NUM, "CALL_SER_NUM" },
+ { L2TP_AVP_MINIMUM_BPS, "MINIMUM_BPS" },
+ { L2TP_AVP_MAXIMUM_BPS, "MAXIMUM_BPS" },
+ { L2TP_AVP_BEARER_TYPE, "BEARER_TYPE" },
+ { L2TP_AVP_FRAMING_TYPE, "FRAMING_TYPE" },
+ { L2TP_AVP_PACKET_PROC_DELAY, "PACKET_PROC_DELAY" },
+ { L2TP_AVP_CALLED_NUMBER, "CALLED_NUMBER" },
+ { L2TP_AVP_CALLING_NUMBER, "CALLING_NUMBER" },
+ { L2TP_AVP_SUB_ADDRESS, "SUB_ADDRESS" },
+ { L2TP_AVP_TX_CONN_SPEED, "TX_CONN_SPEED" },
+ { L2TP_AVP_PHY_CHANNEL_ID, "PHY_CHANNEL_ID" },
+ { L2TP_AVP_INI_RECV_LCP, "INI_RECV_LCP" },
+ { L2TP_AVP_LAST_SENT_LCP, "LAST_SENT_LCP" },
+ { L2TP_AVP_LAST_RECV_LCP, "LAST_RECV_LCP" },
+ { L2TP_AVP_PROXY_AUTH_TYPE, "PROXY_AUTH_TYPE" },
+ { L2TP_AVP_PROXY_AUTH_NAME, "PROXY_AUTH_NAME" },
+ { L2TP_AVP_PROXY_AUTH_CHAL, "PROXY_AUTH_CHAL" },
+ { L2TP_AVP_PROXY_AUTH_ID, "PROXY_AUTH_ID" },
+ { L2TP_AVP_PROXY_AUTH_RESP, "PROXY_AUTH_RESP" },
+ { L2TP_AVP_CALL_ERRORS, "CALL_ERRORS" },
+ { L2TP_AVP_ACCM, "ACCM" },
+ { L2TP_AVP_RANDOM_VECTOR, "RANDOM_VECTOR" },
+ { L2TP_AVP_PRIVATE_GRP_ID, "PRIVATE_GRP_ID" },
+ { L2TP_AVP_RX_CONN_SPEED, "RX_CONN_SPEED" },
+ { L2TP_AVP_SEQ_REQUIRED, "SEQ_REQUIRED" },
+ { L2TP_AVP_PPP_DISCON_CC, "PPP_DISCON_CC" },
+ { 0, NULL }
+};
+
+static struct tok l2tp_authentype2str[] = {
+ { L2TP_AUTHEN_TYPE_RESERVED, "Reserved" },
+ { L2TP_AUTHEN_TYPE_TEXTUAL, "Textual" },
+ { L2TP_AUTHEN_TYPE_CHAP, "CHAP" },
+ { L2TP_AUTHEN_TYPE_PAP, "PAP" },
+ { L2TP_AUTHEN_TYPE_NO_AUTH, "No Auth" },
+ { L2TP_AUTHEN_TYPE_MSCHAPv1, "MS-CHAPv1" },
+ { 0, NULL }
+};
+
+#define L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL 0
+#define L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER 1
+#define L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL 2
+
+static struct tok l2tp_cc_direction2str[] = {
+ { L2TP_PPP_DISCON_CC_DIRECTION_GLOBAL, "global error" },
+ { L2TP_PPP_DISCON_CC_DIRECTION_AT_PEER, "at peer" },
+ { L2TP_PPP_DISCON_CC_DIRECTION_AT_LOCAL,"at local" },
+ { 0, NULL }
+};
+
+#if 0
+static char *l2tp_result_code_StopCCN[] = {
+ "Reserved",
+ "General request to clear control connection",
+ "General error--Error Code indicates the problem",
+ "Control channel already exists",
+ "Requester is not authorized to establish a control channel",
+ "The protocol version of the requester is not supported",
+ "Requester is being shut down",
+ "Finite State Machine error"
+#define L2TP_MAX_RESULT_CODE_STOPCC_INDEX 8
+};
+#endif
+
+#if 0
+static char *l2tp_result_code_CDN[] = {
+ "Reserved",
+ "Call disconnected due to loss of carrier",
+ "Call disconnected for the reason indicated in error code",
+ "Call disconnected for administrative reasons",
+ "Call failed due to lack of appropriate facilities being " \
+ "available (temporary condition)",
+ "Call failed due to lack of appropriate facilities being " \
+ "available (permanent condition)",
+ "Invalid destination",
+ "Call failed due to no carrier detected",
+ "Call failed due to detection of a busy signal",
+ "Call failed due to lack of a dial tone",
+ "Call was not established within time allotted by LAC",
+ "Call was connected but no appropriate framing was detected"
+#define L2TP_MAX_RESULT_CODE_CDN_INDEX 12
+};
+#endif
+
+#if 0
+static char *l2tp_error_code_general[] = {
+ "No general error",
+ "No control connection exists yet for this LAC-LNS pair",
+ "Length is wrong",
+ "One of the field values was out of range or " \
+ "reserved field was non-zero"
+ "Insufficient resources to handle this operation now",
+ "The Session ID is invalid in this context",
+ "A generic vendor-specific error occurred in the LAC",
+ "Try another"
+#define L2TP_MAX_ERROR_CODE_GENERAL_INDEX 8
+};
+#endif
+
+/******************************/
+/* generic print out routines */
+/******************************/
+static void
+print_string(const u_char *dat, u_int length)
+{
+ u_int i;
+ for (i=0; i<length; i++) {
+ printf("%c", *dat++);
+ }
+}
+
+static void
+print_octets(const u_char *dat, u_int length)
+{
+ u_int i;
+ for (i=0; i<length; i++) {
+ printf("%02x", *dat++);
+ }
+}
+
+static void
+print_16bits_val(const u_int16_t *dat)
+{
+ printf("%u", EXTRACT_16BITS(dat));
+}
+
+static void
+print_32bits_val(const u_int32_t *dat)
+{
+ printf("%lu", (u_long)EXTRACT_32BITS(dat));
+}
+
+/***********************************/
+/* AVP-specific print out routines */
+/***********************************/
+static void
+l2tp_msgtype_print(const u_char *dat)
+{
+ u_int16_t *ptr = (u_int16_t*)dat;
+
+ printf("%s", tok2str(l2tp_msgtype2str, "MSGTYPE-#%u",
+ EXTRACT_16BITS(ptr)));
+}
+
+static void
+l2tp_result_code_print(const u_char *dat, u_int length)
+{
+ u_int16_t *ptr = (u_int16_t *)dat;
+
+ printf("%u", EXTRACT_16BITS(ptr)); ptr++; /* Result Code */
+ if (length > 2) { /* Error Code (opt) */
+ printf("/%u", EXTRACT_16BITS(ptr)); ptr++;
+ }
+ if (length > 4) { /* Error Message (opt) */
+ printf(" ");
+ print_string((u_char *)ptr, length - 4);
+ }
+}
+
+static void
+l2tp_proto_ver_print(const u_int16_t *dat)
+{
+ printf("%u.%u", (EXTRACT_16BITS(dat) >> 8),
+ (EXTRACT_16BITS(dat) & 0xff));
+}
+
+static void
+l2tp_framing_cap_print(const u_char *dat)
+{
+ u_int32_t *ptr = (u_int32_t *)dat;
+
+ if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_CAP_ASYNC_MASK) {
+ printf("A");
+ }
+ if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_CAP_SYNC_MASK) {
+ printf("S");
+ }
+}
+
+static void
+l2tp_bearer_cap_print(const u_char *dat)
+{
+ u_int32_t *ptr = (u_int32_t *)dat;
+
+ if (EXTRACT_32BITS(ptr) & L2TP_BEARER_CAP_ANALOG_MASK) {
+ printf("A");
+ }
+ if (EXTRACT_32BITS(ptr) & L2TP_BEARER_CAP_DIGITAL_MASK) {
+ printf("D");
+ }
+}
+
+static void
+l2tp_q931_cc_print(const u_char *dat, u_int length)
+{
+ print_16bits_val((u_int16_t *)dat);
+ printf(", %02x", dat[2]);
+ if (length > 3) {
+ printf(" ");
+ print_string(dat+3, length-3);
+ }
+}
+
+static void
+l2tp_bearer_type_print(const u_char *dat)
+{
+ u_int32_t *ptr = (u_int32_t *)dat;
+
+ if (EXTRACT_32BITS(ptr) & L2TP_BEARER_TYPE_ANALOG_MASK) {
+ printf("A");
+ }
+ if (EXTRACT_32BITS(ptr) & L2TP_BEARER_TYPE_DIGITAL_MASK) {
+ printf("D");
+ }
+}
+
+static void
+l2tp_framing_type_print(const u_char *dat)
+{
+ u_int32_t *ptr = (u_int32_t *)dat;
+
+ if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_TYPE_ASYNC_MASK) {
+ printf("A");
+ }
+ if (EXTRACT_32BITS(ptr) & L2TP_FRAMING_TYPE_SYNC_MASK) {
+ printf("S");
+ }
+}
+
+static void
+l2tp_packet_proc_delay_print(void)
+{
+ printf("obsolete");
+}
+
+static void
+l2tp_proxy_auth_type_print(const u_char *dat)
+{
+ u_int16_t *ptr = (u_int16_t *)dat;
+
+ printf("%s", tok2str(l2tp_authentype2str,
+ "AuthType-#%u", EXTRACT_16BITS(ptr)));
+}
+
+static void
+l2tp_proxy_auth_id_print(const u_char *dat)
+{
+ u_int16_t *ptr = (u_int16_t *)dat;
+
+ printf("%u", EXTRACT_16BITS(ptr) & L2TP_PROXY_AUTH_ID_MASK);
+}
+
+static void
+l2tp_call_errors_print(const u_char *dat)
+{
+ u_int16_t *ptr = (u_int16_t *)dat;
+ u_int16_t val_h, val_l;
+
+ ptr++; /* skip "Reserved" */
+
+ val_h = EXTRACT_16BITS(ptr); ptr++;
+ val_l = EXTRACT_16BITS(ptr); ptr++;
+ printf("CRCErr=%u ", (val_h<<16) + val_l);
+
+ val_h = EXTRACT_16BITS(ptr); ptr++;
+ val_l = EXTRACT_16BITS(ptr); ptr++;
+ printf("FrameErr=%u ", (val_h<<16) + val_l);
+
+ val_h = EXTRACT_16BITS(ptr); ptr++;
+ val_l = EXTRACT_16BITS(ptr); ptr++;
+ printf("HardOver=%u ", (val_h<<16) + val_l);
+
+ val_h = EXTRACT_16BITS(ptr); ptr++;
+ val_l = EXTRACT_16BITS(ptr); ptr++;
+ printf("BufOver=%u ", (val_h<<16) + val_l);
+
+ val_h = EXTRACT_16BITS(ptr); ptr++;
+ val_l = EXTRACT_16BITS(ptr); ptr++;
+ printf("Timeout=%u ", (val_h<<16) + val_l);
+
+ val_h = EXTRACT_16BITS(ptr); ptr++;
+ val_l = EXTRACT_16BITS(ptr); ptr++;
+ printf("AlignErr=%u ", (val_h<<16) + val_l);
+}
+
+static void
+l2tp_accm_print(const u_char *dat)
+{
+ u_int16_t *ptr = (u_int16_t *)dat;
+ u_int16_t val_h, val_l;
+
+ ptr++; /* skip "Reserved" */
+
+ val_h = EXTRACT_16BITS(ptr); ptr++;
+ val_l = EXTRACT_16BITS(ptr); ptr++;
+ printf("send=%08x ", (val_h<<16) + val_l);
+
+ val_h = EXTRACT_16BITS(ptr); ptr++;
+ val_l = EXTRACT_16BITS(ptr); ptr++;
+ printf("recv=%08x ", (val_h<<16) + val_l);
+}
+
+static void
+l2tp_ppp_discon_cc_print(const u_char *dat, u_int length)
+{
+ u_int16_t *ptr = (u_int16_t *)dat;
+
+ printf("%04x, ", EXTRACT_16BITS(ptr)); ptr++; /* Disconnect Code */
+ printf("%04x ", EXTRACT_16BITS(ptr)); ptr++; /* Control Protocol Number */
+ printf("%s", tok2str(l2tp_cc_direction2str,
+ "Direction-#%u", *((u_char *)ptr++)));
+
+ if (length > 5) {
+ printf(" ");
+ print_string((const u_char *)ptr, length-5);
+ }
+}
+
+static void
+l2tp_avp_print(const u_char *dat, int length)
+{
+ u_int len;
+ const u_int16_t *ptr = (u_int16_t *)dat;
+ u_int16_t attr_type;
+ int hidden = FALSE;
+
+ if (length <= 0) {
+ return;
+ }
+
+ printf(" ");
+
+ TCHECK(*ptr); /* Flags & Length */
+ len = EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_LEN_MASK;
+
+ /* If it is not long enough to contain the header, we'll give up. */
+ if (len < 6)
+ goto trunc;
+
+ /* If it goes past the end of the remaining length of the packet,
+ we'll give up. */
+ if (len > (u_int)length)
+ goto trunc;
+
+ /* If it goes past the end of the remaining length of the captured
+ data, we'll give up. */
+ TCHECK2(*ptr, len);
+ /* After this point, no need to worry about truncation */
+
+ if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_MANDATORY) {
+ printf("*");
+ }
+ if (EXTRACT_16BITS(ptr) & L2TP_AVP_HDR_FLAG_HIDDEN) {
+ hidden = TRUE;
+ printf("?");
+ }
+ ptr++;
+
+ if (EXTRACT_16BITS(ptr)) {
+ /* Vendor Specific Attribute */
+ printf("VENDOR%04x:", EXTRACT_16BITS(ptr)); ptr++;
+ printf("ATTR%04x", EXTRACT_16BITS(ptr)); ptr++;
+ printf("(");
+ print_octets((u_char *)ptr, len-6);
+ printf(")");
+ } else {
+ /* IETF-defined Attributes */
+ ptr++;
+ attr_type = EXTRACT_16BITS(ptr); ptr++;
+ printf("%s", tok2str(l2tp_avp2str, "AVP-#%u", attr_type));
+ printf("(");
+ if (hidden) {
+ printf("???");
+ } else {
+ switch (attr_type) {
+ case L2TP_AVP_MSGTYPE:
+ l2tp_msgtype_print((u_char *)ptr);
+ break;
+ case L2TP_AVP_RESULT_CODE:
+ l2tp_result_code_print((u_char *)ptr, len-6);
+ break;
+ case L2TP_AVP_PROTO_VER:
+ l2tp_proto_ver_print(ptr);
+ break;
+ case L2TP_AVP_FRAMING_CAP:
+ l2tp_framing_cap_print((u_char *)ptr);
+ break;
+ case L2TP_AVP_BEARER_CAP:
+ l2tp_bearer_cap_print((u_char *)ptr);
+ break;
+ case L2TP_AVP_TIE_BREAKER:
+ print_octets((u_char *)ptr, 8);
+ break;
+ case L2TP_AVP_FIRM_VER:
+ case L2TP_AVP_ASSND_TUN_ID:
+ case L2TP_AVP_RECV_WIN_SIZE:
+ case L2TP_AVP_ASSND_SESS_ID:
+ print_16bits_val(ptr);
+ break;
+ case L2TP_AVP_HOST_NAME:
+ case L2TP_AVP_VENDOR_NAME:
+ case L2TP_AVP_CALLING_NUMBER:
+ case L2TP_AVP_CALLED_NUMBER:
+ case L2TP_AVP_SUB_ADDRESS:
+ case L2TP_AVP_PROXY_AUTH_NAME:
+ case L2TP_AVP_PRIVATE_GRP_ID:
+ print_string((u_char *)ptr, len-6);
+ break;
+ case L2TP_AVP_CHALLENGE:
+ case L2TP_AVP_INI_RECV_LCP:
+ case L2TP_AVP_LAST_SENT_LCP:
+ case L2TP_AVP_LAST_RECV_LCP:
+ case L2TP_AVP_PROXY_AUTH_CHAL:
+ case L2TP_AVP_PROXY_AUTH_RESP:
+ case L2TP_AVP_RANDOM_VECTOR:
+ print_octets((u_char *)ptr, len-6);
+ break;
+ case L2TP_AVP_Q931_CC:
+ l2tp_q931_cc_print((u_char *)ptr, len-6);
+ break;
+ case L2TP_AVP_CHALLENGE_RESP:
+ print_octets((u_char *)ptr, 16);
+ break;
+ case L2TP_AVP_CALL_SER_NUM:
+ case L2TP_AVP_MINIMUM_BPS:
+ case L2TP_AVP_MAXIMUM_BPS:
+ case L2TP_AVP_TX_CONN_SPEED:
+ case L2TP_AVP_PHY_CHANNEL_ID:
+ case L2TP_AVP_RX_CONN_SPEED:
+ print_32bits_val((u_int32_t *)ptr);
+ break;
+ case L2TP_AVP_BEARER_TYPE:
+ l2tp_bearer_type_print((u_char *)ptr);
+ break;
+ case L2TP_AVP_FRAMING_TYPE:
+ l2tp_framing_type_print((u_char *)ptr);
+ break;
+ case L2TP_AVP_PACKET_PROC_DELAY:
+ l2tp_packet_proc_delay_print();
+ break;
+ case L2TP_AVP_PROXY_AUTH_TYPE:
+ l2tp_proxy_auth_type_print((u_char *)ptr);
+ break;
+ case L2TP_AVP_PROXY_AUTH_ID:
+ l2tp_proxy_auth_id_print((u_char *)ptr);
+ break;
+ case L2TP_AVP_CALL_ERRORS:
+ l2tp_call_errors_print((u_char *)ptr);
+ break;
+ case L2TP_AVP_ACCM:
+ l2tp_accm_print((u_char *)ptr);
+ break;
+ case L2TP_AVP_SEQ_REQUIRED:
+ break; /* No Attribute Value */
+ case L2TP_AVP_PPP_DISCON_CC:
+ l2tp_ppp_discon_cc_print((u_char *)ptr, len-6);
+ break;
+ default:
+ break;
+ }
+ }
+ printf(")");
+ }
+
+ l2tp_avp_print(dat+len, length-len);
+ return;
+
+ trunc:
+ printf("|...");
+}
+
+
+void
+l2tp_print(const u_char *dat, u_int length)
+{
+ const u_char *ptr = dat;
+ u_int cnt = 0; /* total octets consumed */
+ u_int16_t pad;
+ int flag_t, flag_l, flag_s, flag_o;
+ u_int16_t l2tp_len;
+
+ flag_t = flag_l = flag_s = flag_o = FALSE;
+
+ TCHECK2(*ptr, 2); /* Flags & Version */
+ if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2TP) {
+ printf(" l2tp:");
+ } else if ((EXTRACT_16BITS(ptr) & L2TP_VERSION_MASK) == L2TP_VERSION_L2F) {
+ printf(" l2f:");
+ return; /* nothing to do */
+ } else {
+ printf(" Unknown Version, neither L2F(1) nor L2TP(2)");
+ return; /* nothing we can do */
+ }
+
+ printf("[");
+ if (EXTRACT_16BITS(ptr) & L2TP_FLAG_TYPE) {
+ flag_t = TRUE;
+ printf("T");
+ }
+ if (EXTRACT_16BITS(ptr) & L2TP_FLAG_LENGTH) {
+ flag_l = TRUE;
+ printf("L");
+ }
+ if (EXTRACT_16BITS(ptr) & L2TP_FLAG_SEQUENCE) {
+ flag_s = TRUE;
+ printf("S");
+ }
+ if (EXTRACT_16BITS(ptr) & L2TP_FLAG_OFFSET) {
+ flag_o = TRUE;
+ printf("O");
+ }
+ if (EXTRACT_16BITS(ptr) & L2TP_FLAG_PRIORITY)
+ printf("P");
+ printf("]");
+
+ ptr += 2;
+ cnt += 2;
+
+ if (flag_l) {
+ TCHECK2(*ptr, 2); /* Length */
+ l2tp_len = EXTRACT_16BITS(ptr);
+ ptr += 2;
+ cnt += 2;
+ } else {
+ l2tp_len = 0;
+ }
+
+ TCHECK2(*ptr, 2); /* Tunnel ID */
+ printf("(%u/", EXTRACT_16BITS(ptr));
+ ptr += 2;
+ cnt += 2;
+ TCHECK2(*ptr, 2); /* Session ID */
+ printf("%u)", EXTRACT_16BITS(ptr));
+ ptr += 2;
+ cnt += 2;
+
+ if (flag_s) {
+ TCHECK2(*ptr, 2); /* Ns */
+ printf("Ns=%u,", EXTRACT_16BITS(ptr));
+ ptr += 2;
+ cnt += 2;
+ TCHECK2(*ptr, 2); /* Nr */
+ printf("Nr=%u", EXTRACT_16BITS(ptr));
+ ptr += 2;
+ cnt += 2;
+ }
+
+ if (flag_o) {
+ TCHECK2(*ptr, 2); /* Offset Size */
+ pad = EXTRACT_16BITS(ptr);
+ ptr += (2 + pad);
+ cnt += (2 + pad);
+ }
+
+ if (flag_l) {
+ if (length < l2tp_len) {
+ printf(" Length %u larger than packet", l2tp_len);
+ return;
+ }
+ length = l2tp_len;
+ }
+ if (length < cnt) {
+ printf(" Length %u smaller than header length", length);
+ return;
+ }
+ if (flag_t) {
+ if (!flag_l) {
+ printf(" No length");
+ return;
+ }
+ if (length - cnt == 0) {
+ printf(" ZLB");
+ } else {
+ l2tp_avp_print(ptr, length - cnt);
+ }
+ } else {
+ printf(" {");
+ ppp_print(ptr, length - cnt);
+ printf("}");
+ }
+
+ return;
+
+ trunc:
+ printf("%s", tstr);
+}
diff --git a/freebsd/contrib/tcpdump/print-lane.c b/freebsd/contrib/tcpdump/print-lane.c
new file mode 100644
index 00000000..b637b984
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-lane.c
@@ -0,0 +1,120 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Marko Kiiskila carnil@cs.tut.fi
+ *
+ * Tampere University of Technology - Telecommunications Laboratory
+ *
+ * Permission to use, copy, modify and distribute this
+ * software and its documentation is hereby granted,
+ * provided that both the copyright notice and this
+ * permission notice appear in all copies of the software,
+ * derivative works or modified versions, and any portions
+ * thereof, that both notices appear in supporting
+ * documentation, and that the use of this software is
+ * acknowledged in any publications resulting from using
+ * the software.
+ *
+ * TUT ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION AND DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS
+ * SOFTWARE.
+ *
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-lane.c,v 1.25 2005-11-13 12:12:42 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <pcap.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+#include "ether.h"
+#include "lane.h"
+
+static const struct tok lecop2str[] = {
+ { 0x0001, "configure request" },
+ { 0x0101, "configure response" },
+ { 0x0002, "join request" },
+ { 0x0102, "join response" },
+ { 0x0003, "ready query" },
+ { 0x0103, "ready indication" },
+ { 0x0004, "register request" },
+ { 0x0104, "register response" },
+ { 0x0005, "unregister request" },
+ { 0x0105, "unregister response" },
+ { 0x0006, "ARP request" },
+ { 0x0106, "ARP response" },
+ { 0x0007, "flush request" },
+ { 0x0107, "flush response" },
+ { 0x0008, "NARP request" },
+ { 0x0009, "topology request" },
+ { 0, NULL }
+};
+
+static void
+lane_hdr_print(netdissect_options *ndo, const u_char *bp)
+{
+ (void)ND_PRINT((ndo, "lecid:%x ", EXTRACT_16BITS(bp)));
+}
+
+/*
+ * This is the top level routine of the printer. 'p' points
+ * to the LANE header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ *
+ * This assumes 802.3, not 802.5, LAN emulation.
+ */
+void
+lane_print(const u_char *p, u_int length, u_int caplen)
+{
+ struct lane_controlhdr *lec;
+
+ if (caplen < sizeof(struct lane_controlhdr)) {
+ printf("[|lane]");
+ return;
+ }
+
+ lec = (struct lane_controlhdr *)p;
+ if (EXTRACT_16BITS(&lec->lec_header) == 0xff00) {
+ /*
+ * LE Control.
+ */
+ printf("lec: proto %x vers %x %s",
+ lec->lec_proto, lec->lec_vers,
+ tok2str(lecop2str, "opcode-#%u", EXTRACT_16BITS(&lec->lec_opcode)));
+ return;
+ }
+
+ /*
+ * Go past the LE header.
+ */
+ length -= 2;
+ caplen -= 2;
+ p += 2;
+
+ /*
+ * Now print the encapsulated frame, under the assumption
+ * that it's an Ethernet frame.
+ */
+ ether_print(gndo, p, length, caplen, lane_hdr_print, p - 2);
+}
+
+u_int
+lane_if_print(const struct pcap_pkthdr *h, const u_char *p)
+{
+ lane_print(p, h->len, h->caplen);
+
+ return (sizeof(struct lecdatahdr_8023));
+}
diff --git a/freebsd/contrib/tcpdump/print-ldp.c b/freebsd/contrib/tcpdump/print-ldp.c
new file mode 100644
index 00000000..a02f1271
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-ldp.c
@@ -0,0 +1,678 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ * and Steinar Haug (sthaug@nethelp.no)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ldp.c,v 1.20 2006-06-23 02:03:09 hannes Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "interface.h"
+#include "decode_prefix.h"
+#include "extract.h"
+#include "addrtoname.h"
+
+#include "l2vpn.h"
+#include "af.h"
+
+/*
+ * ldp common header
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Version | PDU Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | LDP Identifier |
+ * + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+struct ldp_common_header {
+ u_int8_t version[2];
+ u_int8_t pdu_length[2];
+ u_int8_t lsr_id[4];
+ u_int8_t label_space[2];
+};
+
+#define LDP_VERSION 1
+
+/*
+ * ldp message header
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |U| Message Type | Message Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Message ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * + +
+ * | Mandatory Parameters |
+ * + +
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * + +
+ * | Optional Parameters |
+ * + +
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+struct ldp_msg_header {
+ u_int8_t type[2];
+ u_int8_t length[2];
+ u_int8_t id[4];
+};
+
+#define LDP_MASK_MSG_TYPE(x) ((x)&0x7fff)
+#define LDP_MASK_U_BIT(x) ((x)&0x8000)
+
+#define LDP_MSG_NOTIF 0x0001
+#define LDP_MSG_HELLO 0x0100
+#define LDP_MSG_INIT 0x0200
+#define LDP_MSG_KEEPALIVE 0x0201
+#define LDP_MSG_ADDRESS 0x0300
+#define LDP_MSG_ADDRESS_WITHDRAW 0x0301
+#define LDP_MSG_LABEL_MAPPING 0x0400
+#define LDP_MSG_LABEL_REQUEST 0x0401
+#define LDP_MSG_LABEL_WITHDRAW 0x0402
+#define LDP_MSG_LABEL_RELEASE 0x0403
+#define LDP_MSG_LABEL_ABORT_REQUEST 0x0404
+
+#define LDP_VENDOR_PRIVATE_MIN 0x3e00
+#define LDP_VENDOR_PRIVATE_MAX 0x3eff
+#define LDP_EXPERIMENTAL_MIN 0x3f00
+#define LDP_EXPERIMENTAL_MAX 0x3fff
+
+static const struct tok ldp_msg_values[] = {
+ { LDP_MSG_NOTIF, "Notification" },
+ { LDP_MSG_HELLO, "Hello" },
+ { LDP_MSG_INIT, "Initialization" },
+ { LDP_MSG_KEEPALIVE, "Keepalive" },
+ { LDP_MSG_ADDRESS, "Address" },
+ { LDP_MSG_ADDRESS_WITHDRAW, "Address Withdraw" },
+ { LDP_MSG_LABEL_MAPPING, "Label Mapping" },
+ { LDP_MSG_LABEL_REQUEST, "Label Request" },
+ { LDP_MSG_LABEL_WITHDRAW, "Label Withdraw" },
+ { LDP_MSG_LABEL_RELEASE, "Label Release" },
+ { LDP_MSG_LABEL_ABORT_REQUEST, "Label Abort Request" },
+ { 0, NULL}
+};
+
+#define LDP_MASK_TLV_TYPE(x) ((x)&0x3fff)
+#define LDP_MASK_F_BIT(x) ((x)&0x4000)
+
+#define LDP_TLV_FEC 0x0100
+#define LDP_TLV_ADDRESS_LIST 0x0101
+#define LDP_TLV_ADDRESS_LIST_AFNUM_LEN 2
+#define LDP_TLV_HOP_COUNT 0x0103
+#define LDP_TLV_PATH_VECTOR 0x0104
+#define LDP_TLV_GENERIC_LABEL 0x0200
+#define LDP_TLV_ATM_LABEL 0x0201
+#define LDP_TLV_FR_LABEL 0x0202
+#define LDP_TLV_STATUS 0x0300
+#define LDP_TLV_EXTD_STATUS 0x0301
+#define LDP_TLV_RETURNED_PDU 0x0302
+#define LDP_TLV_RETURNED_MSG 0x0303
+#define LDP_TLV_COMMON_HELLO 0x0400
+#define LDP_TLV_IPV4_TRANSPORT_ADDR 0x0401
+#define LDP_TLV_CONFIG_SEQ_NUMBER 0x0402
+#define LDP_TLV_IPV6_TRANSPORT_ADDR 0x0403
+#define LDP_TLV_COMMON_SESSION 0x0500
+#define LDP_TLV_ATM_SESSION_PARM 0x0501
+#define LDP_TLV_FR_SESSION_PARM 0x0502
+#define LDP_TLV_FT_SESSION 0x0503
+#define LDP_TLV_LABEL_REQUEST_MSG_ID 0x0600
+#define LDP_TLV_MTU 0x0601 /* rfc 3988 */
+
+static const struct tok ldp_tlv_values[] = {
+ { LDP_TLV_FEC, "FEC" },
+ { LDP_TLV_ADDRESS_LIST, "Address List" },
+ { LDP_TLV_HOP_COUNT, "Hop Count" },
+ { LDP_TLV_PATH_VECTOR, "Path Vector" },
+ { LDP_TLV_GENERIC_LABEL, "Generic Label" },
+ { LDP_TLV_ATM_LABEL, "ATM Label" },
+ { LDP_TLV_FR_LABEL, "Frame-Relay Label" },
+ { LDP_TLV_STATUS, "Status" },
+ { LDP_TLV_EXTD_STATUS, "Extended Status" },
+ { LDP_TLV_RETURNED_PDU, "Returned PDU" },
+ { LDP_TLV_RETURNED_MSG, "Returned Message" },
+ { LDP_TLV_COMMON_HELLO, "Common Hello Parameters" },
+ { LDP_TLV_IPV4_TRANSPORT_ADDR, "IPv4 Transport Address" },
+ { LDP_TLV_CONFIG_SEQ_NUMBER, "Configuration Sequence Number" },
+ { LDP_TLV_IPV6_TRANSPORT_ADDR, "IPv6 Transport Address" },
+ { LDP_TLV_COMMON_SESSION, "Common Session Parameters" },
+ { LDP_TLV_ATM_SESSION_PARM, "ATM Session Parameters" },
+ { LDP_TLV_FR_SESSION_PARM, "Frame-Relay Session Parameters" },
+ { LDP_TLV_FT_SESSION, "Fault-Tolerant Session Parameters" },
+ { LDP_TLV_LABEL_REQUEST_MSG_ID, "Label Request Message ID" },
+ { LDP_TLV_MTU, "MTU" },
+ { 0, NULL}
+};
+
+#define LDP_FEC_WILDCARD 0x01
+#define LDP_FEC_PREFIX 0x02
+#define LDP_FEC_HOSTADDRESS 0x03
+/* From RFC 4906; should probably be updated to RFC 4447 (e.g., VC -> PW) */
+#define LDP_FEC_MARTINI_VC 0x80
+
+static const struct tok ldp_fec_values[] = {
+ { LDP_FEC_WILDCARD, "Wildcard" },
+ { LDP_FEC_PREFIX, "Prefix" },
+ { LDP_FEC_HOSTADDRESS, "Host address" },
+ { LDP_FEC_MARTINI_VC, "Martini VC" },
+ { 0, NULL}
+};
+
+#define LDP_FEC_MARTINI_IFPARM_MTU 0x01
+#define LDP_FEC_MARTINI_IFPARM_DESC 0x03
+#define LDP_FEC_MARTINI_IFPARM_VCCV 0x0c
+
+static const struct tok ldp_fec_martini_ifparm_values[] = {
+ { LDP_FEC_MARTINI_IFPARM_MTU, "MTU" },
+ { LDP_FEC_MARTINI_IFPARM_DESC, "Description" },
+ { LDP_FEC_MARTINI_IFPARM_VCCV, "VCCV" },
+ { 0, NULL}
+};
+
+/* draft-ietf-pwe3-vccv-04.txt */
+static const struct tok ldp_fec_martini_ifparm_vccv_cc_values[] = {
+ { 0x01, "PWE3 control word" },
+ { 0x02, "MPLS Router Alert Label" },
+ { 0x04, "MPLS inner label TTL = 1" },
+ { 0, NULL}
+};
+
+/* draft-ietf-pwe3-vccv-04.txt */
+static const struct tok ldp_fec_martini_ifparm_vccv_cv_values[] = {
+ { 0x01, "ICMP Ping" },
+ { 0x02, "LSP Ping" },
+ { 0x04, "BFD" },
+ { 0, NULL}
+};
+
+int ldp_msg_print(register const u_char *);
+int ldp_tlv_print(register const u_char *);
+
+/*
+ * ldp tlv header
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |U|F| Type | Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * | Value |
+ * ~ ~
+ * | |
+ * | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+#define TLV_TCHECK(minlen) \
+ TCHECK2(*tptr, minlen); if (tlv_tlen < minlen) goto badtlv;
+
+int
+ldp_tlv_print(register const u_char *tptr) {
+
+ struct ldp_tlv_header {
+ u_int8_t type[2];
+ u_int8_t length[2];
+ };
+
+ const struct ldp_tlv_header *ldp_tlv_header;
+ u_short tlv_type,tlv_len,tlv_tlen,af,ft_flags;
+ u_char fec_type;
+ u_int ui,vc_info_len, vc_info_tlv_type, vc_info_tlv_len,idx;
+ char buf[100];
+ int i;
+
+ ldp_tlv_header = (const struct ldp_tlv_header *)tptr;
+ tlv_len=EXTRACT_16BITS(ldp_tlv_header->length);
+ tlv_tlen=tlv_len;
+ tlv_type=LDP_MASK_TLV_TYPE(EXTRACT_16BITS(ldp_tlv_header->type));
+
+ /* FIXME vendor private / experimental check */
+ printf("\n\t %s TLV (0x%04x), length: %u, Flags: [%s and %s forward if unknown]",
+ tok2str(ldp_tlv_values,
+ "Unknown",
+ tlv_type),
+ tlv_type,
+ tlv_len,
+ LDP_MASK_U_BIT(EXTRACT_16BITS(&ldp_tlv_header->type)) ? "continue processing" : "ignore",
+ LDP_MASK_F_BIT(EXTRACT_16BITS(&ldp_tlv_header->type)) ? "do" : "don't");
+
+ tptr+=sizeof(struct ldp_tlv_header);
+
+ switch(tlv_type) {
+
+ case LDP_TLV_COMMON_HELLO:
+ TLV_TCHECK(4);
+ printf("\n\t Hold Time: %us, Flags: [%s Hello%s]",
+ EXTRACT_16BITS(tptr),
+ (EXTRACT_16BITS(tptr+2)&0x8000) ? "Targeted" : "Link",
+ (EXTRACT_16BITS(tptr+2)&0x4000) ? ", Request for targeted Hellos" : "");
+ break;
+
+ case LDP_TLV_IPV4_TRANSPORT_ADDR:
+ TLV_TCHECK(4);
+ printf("\n\t IPv4 Transport Address: %s", ipaddr_string(tptr));
+ break;
+#ifdef INET6
+ case LDP_TLV_IPV6_TRANSPORT_ADDR:
+ TLV_TCHECK(16);
+ printf("\n\t IPv6 Transport Address: %s", ip6addr_string(tptr));
+ break;
+#endif
+ case LDP_TLV_CONFIG_SEQ_NUMBER:
+ TLV_TCHECK(4);
+ printf("\n\t Sequence Number: %u", EXTRACT_32BITS(tptr));
+ break;
+
+ case LDP_TLV_ADDRESS_LIST:
+ TLV_TCHECK(LDP_TLV_ADDRESS_LIST_AFNUM_LEN);
+ af = EXTRACT_16BITS(tptr);
+ tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
+ tlv_tlen -= LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
+ printf("\n\t Address Family: %s, addresses",
+ tok2str(af_values, "Unknown (%u)", af));
+ switch (af) {
+ case AFNUM_INET:
+ while(tlv_tlen >= sizeof(struct in_addr)) {
+ TCHECK2(*tptr, sizeof(struct in_addr));
+ printf(" %s",ipaddr_string(tptr));
+ tlv_tlen-=sizeof(struct in_addr);
+ tptr+=sizeof(struct in_addr);
+ }
+ break;
+#ifdef INET6
+ case AFNUM_INET6:
+ while(tlv_tlen >= sizeof(struct in6_addr)) {
+ TCHECK2(*tptr, sizeof(struct in6_addr));
+ printf(" %s",ip6addr_string(tptr));
+ tlv_tlen-=sizeof(struct in6_addr);
+ tptr+=sizeof(struct in6_addr);
+ }
+ break;
+#endif
+ default:
+ /* unknown AF */
+ break;
+ }
+ break;
+
+ case LDP_TLV_COMMON_SESSION:
+ TLV_TCHECK(8);
+ printf("\n\t Version: %u, Keepalive: %us, Flags: [Downstream %s, Loop Detection %s]",
+ EXTRACT_16BITS(tptr), EXTRACT_16BITS(tptr+2),
+ (EXTRACT_16BITS(tptr+6)&0x8000) ? "On Demand" : "Unsolicited",
+ (EXTRACT_16BITS(tptr+6)&0x4000) ? "Enabled" : "Disabled"
+ );
+ break;
+
+ case LDP_TLV_FEC:
+ TLV_TCHECK(1);
+ fec_type = *tptr;
+ printf("\n\t %s FEC (0x%02x)",
+ tok2str(ldp_fec_values, "Unknown", fec_type),
+ fec_type);
+
+ tptr+=1;
+ tlv_tlen-=1;
+ switch(fec_type) {
+
+ case LDP_FEC_WILDCARD:
+ break;
+ case LDP_FEC_PREFIX:
+ TLV_TCHECK(2);
+ af = EXTRACT_16BITS(tptr);
+ tptr+=LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
+ tlv_tlen-=LDP_TLV_ADDRESS_LIST_AFNUM_LEN;
+ if (af == AFNUM_INET) {
+ i=decode_prefix4(tptr,tlv_tlen,buf,sizeof(buf));
+ if (i == -2)
+ goto trunc;
+ if (i == -3)
+ printf(": IPv4 prefix (goes past end of TLV)");
+ else if (i == -1)
+ printf(": IPv4 prefix (invalid length)");
+ else
+ printf(": IPv4 prefix %s",buf);
+ }
+#ifdef INET6
+ else if (af == AFNUM_INET6) {
+ i=decode_prefix6(tptr,tlv_tlen,buf,sizeof(buf));
+ if (i == -2)
+ goto trunc;
+ if (i == -3)
+ printf(": IPv4 prefix (goes past end of TLV)");
+ else if (i == -1)
+ printf(": IPv6 prefix (invalid length)");
+ else
+ printf(": IPv6 prefix %s",buf);
+ }
+#endif
+ else
+ printf(": Address family %u prefix", af);
+ break;
+ case LDP_FEC_HOSTADDRESS:
+ break;
+ case LDP_FEC_MARTINI_VC:
+ /*
+ * According to RFC 4908, the VC info Length field can be zero,
+ * in which case not only are there no interface parameters,
+ * there's no VC ID.
+ */
+ TLV_TCHECK(7);
+ vc_info_len = *(tptr+2);
+
+ if (vc_info_len == 0) {
+ printf(": %s, %scontrol word, group-ID %u, VC-info-length: %u",
+ tok2str(l2vpn_encaps_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff),
+ EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ",
+ EXTRACT_32BITS(tptr+3),
+ vc_info_len);
+ break;
+ }
+
+ /* Make sure we have the VC ID as well */
+ TLV_TCHECK(11);
+ printf(": %s, %scontrol word, group-ID %u, VC-ID %u, VC-info-length: %u",
+ tok2str(l2vpn_encaps_values, "Unknown", EXTRACT_16BITS(tptr)&0x7fff),
+ EXTRACT_16BITS(tptr)&0x8000 ? "" : "no ",
+ EXTRACT_32BITS(tptr+3),
+ EXTRACT_32BITS(tptr+7),
+ vc_info_len);
+ if (vc_info_len < 4)
+ goto trunc; /* minimum 4, for the VC ID */
+ vc_info_len -= 4; /* subtract out the VC ID, giving the length of the interface parameters */
+
+ /* Skip past the fixed information and the VC ID */
+ tptr+=11;
+ tlv_tlen-=11;
+ TLV_TCHECK(vc_info_len);
+
+ while (vc_info_len > 2) {
+ vc_info_tlv_type = *tptr;
+ vc_info_tlv_len = *(tptr+1);
+ if (vc_info_tlv_len < 2)
+ break;
+ if (vc_info_len < vc_info_tlv_len)
+ break;
+
+ printf("\n\t\tInterface Parameter: %s (0x%02x), len %u",
+ tok2str(ldp_fec_martini_ifparm_values,"Unknown",vc_info_tlv_type),
+ vc_info_tlv_type,
+ vc_info_tlv_len);
+
+ switch(vc_info_tlv_type) {
+ case LDP_FEC_MARTINI_IFPARM_MTU:
+ printf(": %u",EXTRACT_16BITS(tptr+2));
+ break;
+
+ case LDP_FEC_MARTINI_IFPARM_DESC:
+ printf(": ");
+ for (idx = 2; idx < vc_info_tlv_len; idx++)
+ safeputchar(*(tptr+idx));
+ break;
+
+ case LDP_FEC_MARTINI_IFPARM_VCCV:
+ printf("\n\t\t Control Channels (0x%02x) = [%s]",
+ *(tptr+2),
+ bittok2str(ldp_fec_martini_ifparm_vccv_cc_values,"none",*(tptr+2)));
+ printf("\n\t\t CV Types (0x%02x) = [%s]",
+ *(tptr+3),
+ bittok2str(ldp_fec_martini_ifparm_vccv_cv_values,"none",*(tptr+3)));
+ break;
+
+ default:
+ print_unknown_data(tptr+2,"\n\t\t ",vc_info_tlv_len-2);
+ break;
+ }
+
+ vc_info_len -= vc_info_tlv_len;
+ tptr += vc_info_tlv_len;
+ }
+ break;
+ }
+
+ break;
+
+ case LDP_TLV_GENERIC_LABEL:
+ TLV_TCHECK(4);
+ printf("\n\t Label: %u", EXTRACT_32BITS(tptr) & 0xfffff);
+ break;
+
+ case LDP_TLV_STATUS:
+ TLV_TCHECK(8);
+ ui = EXTRACT_32BITS(tptr);
+ tptr+=4;
+ printf("\n\t Status: 0x%02x, Flags: [%s and %s forward]",
+ ui&0x3fffffff,
+ ui&0x80000000 ? "Fatal error" : "Advisory Notification",
+ ui&0x40000000 ? "do" : "don't");
+ ui = EXTRACT_32BITS(tptr);
+ tptr+=4;
+ if (ui)
+ printf(", causing Message ID: 0x%08x", ui);
+ break;
+
+ case LDP_TLV_FT_SESSION:
+ TLV_TCHECK(8);
+ ft_flags = EXTRACT_16BITS(tptr);
+ printf("\n\t Flags: [%sReconnect, %sSave State, %sAll-Label Protection, %s Checkpoint, %sRe-Learn State]",
+ ft_flags&0x8000 ? "" : "No ",
+ ft_flags&0x8 ? "" : "Don't ",
+ ft_flags&0x4 ? "" : "No ",
+ ft_flags&0x2 ? "Sequence Numbered Label" : "All Labels",
+ ft_flags&0x1 ? "" : "Don't ");
+ tptr+=4;
+ ui = EXTRACT_32BITS(tptr);
+ if (ui)
+ printf(", Reconnect Timeout: %ums", ui);
+ tptr+=4;
+ ui = EXTRACT_32BITS(tptr);
+ if (ui)
+ printf(", Recovery Time: %ums", ui);
+ break;
+
+ case LDP_TLV_MTU:
+ TLV_TCHECK(2);
+ printf("\n\t MTU: %u", EXTRACT_16BITS(tptr));
+ break;
+
+
+ /*
+ * FIXME those are the defined TLVs that lack a decoder
+ * you are welcome to contribute code ;-)
+ */
+
+ case LDP_TLV_HOP_COUNT:
+ case LDP_TLV_PATH_VECTOR:
+ case LDP_TLV_ATM_LABEL:
+ case LDP_TLV_FR_LABEL:
+ case LDP_TLV_EXTD_STATUS:
+ case LDP_TLV_RETURNED_PDU:
+ case LDP_TLV_RETURNED_MSG:
+ case LDP_TLV_ATM_SESSION_PARM:
+ case LDP_TLV_FR_SESSION_PARM:
+ case LDP_TLV_LABEL_REQUEST_MSG_ID:
+
+ default:
+ if (vflag <= 1)
+ print_unknown_data(tptr,"\n\t ",tlv_tlen);
+ break;
+ }
+ return(tlv_len+4); /* Type & Length fields not included */
+
+trunc:
+ printf("\n\t\t packet exceeded snapshot");
+ return 0;
+
+badtlv:
+ printf("\n\t\t TLV contents go past end of TLV");
+ return(tlv_len+4); /* Type & Length fields not included */
+}
+
+void
+ldp_print(register const u_char *pptr, register u_int len) {
+
+ int processed;
+ while (len > (sizeof(struct ldp_common_header) + sizeof(struct ldp_msg_header))) {
+ processed = ldp_msg_print(pptr);
+ if (processed == 0)
+ return;
+ len -= processed;
+ pptr += processed;
+ }
+}
+
+
+int
+ldp_msg_print(register const u_char *pptr) {
+
+ const struct ldp_common_header *ldp_com_header;
+ const struct ldp_msg_header *ldp_msg_header;
+ const u_char *tptr,*msg_tptr;
+ u_short tlen;
+ u_short pdu_len,msg_len,msg_type,msg_tlen;
+ int hexdump,processed;
+
+ tptr=pptr;
+ ldp_com_header = (const struct ldp_common_header *)pptr;
+ TCHECK(*ldp_com_header);
+
+ /*
+ * Sanity checking of the header.
+ */
+ if (EXTRACT_16BITS(&ldp_com_header->version) != LDP_VERSION) {
+ printf("%sLDP version %u packet not supported",
+ (vflag < 1) ? "" : "\n\t",
+ EXTRACT_16BITS(&ldp_com_header->version));
+ return 0;
+ }
+
+ /* print the LSR-ID, label-space & length */
+ pdu_len = EXTRACT_16BITS(&ldp_com_header->pdu_length);
+ printf("%sLDP, Label-Space-ID: %s:%u, pdu-length: %u",
+ (vflag < 1) ? "" : "\n\t",
+ ipaddr_string(&ldp_com_header->lsr_id),
+ EXTRACT_16BITS(&ldp_com_header->label_space),
+ pdu_len);
+
+ /* bail out if non-verbose */
+ if (vflag < 1)
+ return 0;
+
+ /* ok they seem to want to know everything - lets fully decode it */
+ tlen=pdu_len;
+
+ tptr += sizeof(const struct ldp_common_header);
+ tlen -= sizeof(const struct ldp_common_header)-4; /* Type & Length fields not included */
+
+ while(tlen>0) {
+ /* did we capture enough for fully decoding the msg header ? */
+ TCHECK2(*tptr, sizeof(struct ldp_msg_header));
+
+ ldp_msg_header = (const struct ldp_msg_header *)tptr;
+ msg_len=EXTRACT_16BITS(ldp_msg_header->length);
+ msg_type=LDP_MASK_MSG_TYPE(EXTRACT_16BITS(ldp_msg_header->type));
+
+ /* FIXME vendor private / experimental check */
+ printf("\n\t %s Message (0x%04x), length: %u, Message ID: 0x%08x, Flags: [%s if unknown]",
+ tok2str(ldp_msg_values,
+ "Unknown",
+ msg_type),
+ msg_type,
+ msg_len,
+ EXTRACT_32BITS(&ldp_msg_header->id),
+ LDP_MASK_U_BIT(EXTRACT_16BITS(&ldp_msg_header->type)) ? "continue processing" : "ignore");
+
+ if (msg_len == 0) /* infinite loop protection */
+ return 0;
+
+ msg_tptr=tptr+sizeof(struct ldp_msg_header);
+ msg_tlen=msg_len-sizeof(struct ldp_msg_header)+4; /* Type & Length fields not included */
+
+ /* did we capture enough for fully decoding the message ? */
+ TCHECK2(*tptr, msg_len);
+ hexdump=FALSE;
+
+ switch(msg_type) {
+
+ case LDP_MSG_NOTIF:
+ case LDP_MSG_HELLO:
+ case LDP_MSG_INIT:
+ case LDP_MSG_KEEPALIVE:
+ case LDP_MSG_ADDRESS:
+ case LDP_MSG_LABEL_MAPPING:
+ case LDP_MSG_ADDRESS_WITHDRAW:
+ case LDP_MSG_LABEL_WITHDRAW:
+ while(msg_tlen >= 4) {
+ processed = ldp_tlv_print(msg_tptr);
+ if (processed == 0)
+ break;
+ msg_tlen-=processed;
+ msg_tptr+=processed;
+ }
+ break;
+
+ /*
+ * FIXME those are the defined messages that lack a decoder
+ * you are welcome to contribute code ;-)
+ */
+
+ case LDP_MSG_LABEL_REQUEST:
+ case LDP_MSG_LABEL_RELEASE:
+ case LDP_MSG_LABEL_ABORT_REQUEST:
+
+ default:
+ if (vflag <= 1)
+ print_unknown_data(msg_tptr,"\n\t ",msg_tlen);
+ break;
+ }
+ /* do we want to see an additionally hexdump ? */
+ if (vflag > 1 || hexdump==TRUE)
+ print_unknown_data(tptr+sizeof(struct ldp_msg_header),"\n\t ",
+ msg_len);
+
+ tptr += msg_len+4;
+ tlen -= msg_len+4;
+ }
+ return pdu_len+4;
+trunc:
+ printf("\n\t\t packet exceeded snapshot");
+ return 0;
+}
+
diff --git a/freebsd/contrib/tcpdump/print-llc.c b/freebsd/contrib/tcpdump/print-llc.c
new file mode 100644
index 00000000..f8801d39
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-llc.c
@@ -0,0 +1,549 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Code by Matt Thomas, Digital Equipment Corporation
+ * with an awful lot of hacking by Jeffrey Mogul, DECWRL
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-llc.c,v 1.75 2007-04-13 09:43:11 hannes Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h" /* must come after interface.h */
+
+#include "llc.h"
+#include "ethertype.h"
+#include "oui.h"
+
+static struct tok llc_values[] = {
+ { LLCSAP_NULL, "Null" },
+ { LLCSAP_GLOBAL, "Global" },
+ { LLCSAP_8021B_I, "802.1B I" },
+ { LLCSAP_8021B_G, "802.1B G" },
+ { LLCSAP_IP, "IP" },
+ { LLCSAP_SNA, "SNA" },
+ { LLCSAP_PROWAYNM, "ProWay NM" },
+ { LLCSAP_8021D, "STP" },
+ { LLCSAP_RS511, "RS511" },
+ { LLCSAP_ISO8208, "ISO8208" },
+ { LLCSAP_PROWAY, "ProWay" },
+ { LLCSAP_SNAP, "SNAP" },
+ { LLCSAP_IPX, "IPX" },
+ { LLCSAP_NETBEUI, "NetBeui" },
+ { LLCSAP_ISONS, "OSI" },
+ { 0, NULL },
+};
+
+static struct tok llc_cmd_values[] = {
+ { LLC_UI, "ui" },
+ { LLC_TEST, "test" },
+ { LLC_XID, "xid" },
+ { LLC_UA, "ua" },
+ { LLC_DISC, "disc" },
+ { LLC_DM, "dm" },
+ { LLC_SABME, "sabme" },
+ { LLC_FRMR, "frmr" },
+ { 0, NULL }
+};
+
+static const struct tok llc_flag_values[] = {
+ { 0, "Command" },
+ { LLC_GSAP, "Response" },
+ { LLC_U_POLL, "Poll" },
+ { LLC_GSAP|LLC_U_POLL, "Final" },
+ { LLC_IS_POLL, "Poll" },
+ { LLC_GSAP|LLC_IS_POLL, "Final" },
+ { 0, NULL }
+};
+
+
+static const struct tok llc_ig_flag_values[] = {
+ { 0, "Individual" },
+ { LLC_IG, "Group" },
+ { 0, NULL }
+};
+
+
+static const struct tok llc_supervisory_values[] = {
+ { 0, "Receiver Ready" },
+ { 1, "Receiver not Ready" },
+ { 2, "Reject" },
+ { 0, NULL }
+};
+
+
+static const struct tok cisco_values[] = {
+ { PID_CISCO_CDP, "CDP" },
+ { PID_CISCO_VTP, "VTP" },
+ { PID_CISCO_DTP, "DTP" },
+ { PID_CISCO_UDLD, "UDLD" },
+ { PID_CISCO_PVST, "PVST" },
+ { 0, NULL }
+};
+
+static const struct tok bridged_values[] = {
+ { PID_RFC2684_ETH_FCS, "Ethernet + FCS" },
+ { PID_RFC2684_ETH_NOFCS, "Ethernet w/o FCS" },
+ { PID_RFC2684_802_4_FCS, "802.4 + FCS" },
+ { PID_RFC2684_802_4_NOFCS, "802.4 w/o FCS" },
+ { PID_RFC2684_802_5_FCS, "Token Ring + FCS" },
+ { PID_RFC2684_802_5_NOFCS, "Token Ring w/o FCS" },
+ { PID_RFC2684_FDDI_FCS, "FDDI + FCS" },
+ { PID_RFC2684_FDDI_NOFCS, "FDDI w/o FCS" },
+ { PID_RFC2684_802_6_FCS, "802.6 + FCS" },
+ { PID_RFC2684_802_6_NOFCS, "802.6 w/o FCS" },
+ { PID_RFC2684_BPDU, "BPDU" },
+ { 0, NULL },
+};
+
+static const struct tok null_values[] = {
+ { 0, NULL }
+};
+
+struct oui_tok {
+ u_int32_t oui;
+ const struct tok *tok;
+};
+
+static const struct oui_tok oui_to_tok[] = {
+ { OUI_ENCAP_ETHER, ethertype_values },
+ { OUI_CISCO_90, ethertype_values }, /* uses some Ethertype values */
+ { OUI_APPLETALK, ethertype_values }, /* uses some Ethertype values */
+ { OUI_CISCO, cisco_values },
+ { OUI_RFC2684, bridged_values }, /* bridged, RFC 2427 FR or RFC 2864 ATM */
+ { 0, NULL }
+};
+
+/*
+ * Returns non-zero IFF it succeeds in printing the header
+ */
+int
+llc_print(const u_char *p, u_int length, u_int caplen,
+ const u_char *esrc, const u_char *edst, u_short *extracted_ethertype)
+{
+ u_int8_t dsap_field, dsap, ssap_field, ssap;
+ u_int16_t control;
+ int is_u;
+ register int ret;
+
+ *extracted_ethertype = 0;
+
+ if (caplen < 3) {
+ (void)printf("[|llc]");
+ default_print((u_char *)p, caplen);
+ return(0);
+ }
+
+ dsap_field = *p;
+ ssap_field = *(p + 1);
+
+ /*
+ * OK, what type of LLC frame is this? The length
+ * of the control field depends on that - I frames
+ * have a two-byte control field, and U frames have
+ * a one-byte control field.
+ */
+ control = *(p + 2);
+ if ((control & LLC_U_FMT) == LLC_U_FMT) {
+ /*
+ * U frame.
+ */
+ is_u = 1;
+ } else {
+ /*
+ * The control field in I and S frames is
+ * 2 bytes...
+ */
+ if (caplen < 4) {
+ (void)printf("[|llc]");
+ default_print((u_char *)p, caplen);
+ return(0);
+ }
+
+ /*
+ * ...and is little-endian.
+ */
+ control = EXTRACT_LE_16BITS(p + 2);
+ is_u = 0;
+ }
+
+ if (ssap_field == LLCSAP_GLOBAL && dsap_field == LLCSAP_GLOBAL) {
+ /*
+ * This is an Ethernet_802.3 IPX frame; it has an
+ * 802.3 header (i.e., an Ethernet header where the
+ * type/length field is <= ETHERMTU, i.e. it's a length
+ * field, not a type field), but has no 802.2 header -
+ * the IPX packet starts right after the Ethernet header,
+ * with a signature of two bytes of 0xFF (which is
+ * LLCSAP_GLOBAL).
+ *
+ * (It might also have been an Ethernet_802.3 IPX at
+ * one time, but got bridged onto another network,
+ * such as an 802.11 network; this has appeared in at
+ * least one capture file.)
+ */
+
+ if (eflag)
+ printf("IPX 802.3: ");
+
+ ipx_print(p, length);
+ return (1);
+ }
+
+ dsap = dsap_field & ~LLC_IG;
+ ssap = ssap_field & ~LLC_GSAP;
+
+ if (eflag) {
+ printf("LLC, dsap %s (0x%02x) %s, ssap %s (0x%02x) %s",
+ tok2str(llc_values, "Unknown", dsap),
+ dsap,
+ tok2str(llc_ig_flag_values, "Unknown", dsap_field & LLC_IG),
+ tok2str(llc_values, "Unknown", ssap),
+ ssap,
+ tok2str(llc_flag_values, "Unknown", ssap_field & LLC_GSAP));
+
+ if (is_u) {
+ printf(", ctrl 0x%02x: ", control);
+ } else {
+ printf(", ctrl 0x%04x: ", control);
+ }
+ }
+
+ if (ssap == LLCSAP_8021D && dsap == LLCSAP_8021D &&
+ control == LLC_UI) {
+ stp_print(p+3, length-3);
+ return (1);
+ }
+
+ if (ssap == LLCSAP_IP && dsap == LLCSAP_IP &&
+ control == LLC_UI) {
+ ip_print(gndo, p+4, length-4);
+ return (1);
+ }
+
+ if (ssap == LLCSAP_IPX && dsap == LLCSAP_IPX &&
+ control == LLC_UI) {
+ /*
+ * This is an Ethernet_802.2 IPX frame, with an 802.3
+ * header and an 802.2 LLC header with the source and
+ * destination SAPs being the IPX SAP.
+ *
+ * Skip DSAP, LSAP, and control field.
+ */
+ if (eflag)
+ printf("IPX 802.2: ");
+
+ ipx_print(p+3, length-3);
+ return (1);
+ }
+
+#ifdef TCPDUMP_DO_SMB
+ if (ssap == LLCSAP_NETBEUI && dsap == LLCSAP_NETBEUI
+ && (!(control & LLC_S_FMT) || control == LLC_U_FMT)) {
+ /*
+ * we don't actually have a full netbeui parser yet, but the
+ * smb parser can handle many smb-in-netbeui packets, which
+ * is very useful, so we call that
+ *
+ * We don't call it for S frames, however, just I frames
+ * (which are frames that don't have the low-order bit,
+ * LLC_S_FMT, set in the first byte of the control field)
+ * and UI frames (whose control field is just 3, LLC_U_FMT).
+ */
+
+ /*
+ * Skip the LLC header.
+ */
+ if (is_u) {
+ p += 3;
+ length -= 3;
+ caplen -= 3;
+ } else {
+ p += 4;
+ length -= 4;
+ caplen -= 4;
+ }
+ netbeui_print(control, p, length);
+ return (1);
+ }
+#endif
+ if (ssap == LLCSAP_ISONS && dsap == LLCSAP_ISONS
+ && control == LLC_UI) {
+ isoclns_print(p + 3, length - 3, caplen - 3);
+ return (1);
+ }
+
+ if (ssap == LLCSAP_SNAP && dsap == LLCSAP_SNAP
+ && control == LLC_UI) {
+ /*
+ * XXX - what *is* the right bridge pad value here?
+ * Does anybody ever bridge one form of LAN traffic
+ * over a networking type that uses 802.2 LLC?
+ */
+ ret = snap_print(p+3, length-3, caplen-3, 2);
+ if (ret)
+ return (ret);
+ }
+
+ if (!eflag) {
+ if (ssap == dsap) {
+ if (esrc == NULL || edst == NULL)
+ (void)printf("%s ", tok2str(llc_values, "Unknown DSAP 0x%02x", dsap));
+ else
+ (void)printf("%s > %s %s ",
+ etheraddr_string(esrc),
+ etheraddr_string(edst),
+ tok2str(llc_values, "Unknown DSAP 0x%02x", dsap));
+ } else {
+ if (esrc == NULL || edst == NULL)
+ (void)printf("%s > %s ",
+ tok2str(llc_values, "Unknown SSAP 0x%02x", ssap),
+ tok2str(llc_values, "Unknown DSAP 0x%02x", dsap));
+ else
+ (void)printf("%s %s > %s %s ",
+ etheraddr_string(esrc),
+ tok2str(llc_values, "Unknown SSAP 0x%02x", ssap),
+ etheraddr_string(edst),
+ tok2str(llc_values, "Unknown DSAP 0x%02x", dsap));
+ }
+ }
+
+ if (is_u) {
+ printf("Unnumbered, %s, Flags [%s], length %u",
+ tok2str(llc_cmd_values, "%02x", LLC_U_CMD(control)),
+ tok2str(llc_flag_values,"?",(ssap_field & LLC_GSAP) | (control & LLC_U_POLL)),
+ length);
+
+ p += 3;
+ length -= 3;
+ caplen -= 3;
+
+ if ((control & ~LLC_U_POLL) == LLC_XID) {
+ if (*p == LLC_XID_FI) {
+ printf(": %02x %02x", p[1], p[2]);
+ p += 3;
+ length -= 3;
+ caplen -= 3;
+ }
+ }
+ } else {
+ if ((control & LLC_S_FMT) == LLC_S_FMT) {
+ (void)printf("Supervisory, %s, rcv seq %u, Flags [%s], length %u",
+ tok2str(llc_supervisory_values,"?",LLC_S_CMD(control)),
+ LLC_IS_NR(control),
+ tok2str(llc_flag_values,"?",(ssap_field & LLC_GSAP) | (control & LLC_IS_POLL)),
+ length);
+ } else {
+ (void)printf("Information, send seq %u, rcv seq %u, Flags [%s], length %u",
+ LLC_I_NS(control),
+ LLC_IS_NR(control),
+ tok2str(llc_flag_values,"?",(ssap_field & LLC_GSAP) | (control & LLC_IS_POLL)),
+ length);
+ }
+ p += 4;
+ length -= 4;
+ caplen -= 4;
+ }
+ return(1);
+}
+
+int
+snap_print(const u_char *p, u_int length, u_int caplen, u_int bridge_pad)
+{
+ u_int32_t orgcode;
+ register u_short et;
+ register int ret;
+
+ TCHECK2(*p, 5);
+ orgcode = EXTRACT_24BITS(p);
+ et = EXTRACT_16BITS(p + 3);
+
+ if (eflag) {
+ const struct tok *tok = null_values;
+ const struct oui_tok *otp;
+
+ for (otp = &oui_to_tok[0]; otp->tok != NULL; otp++) {
+ if (otp->oui == orgcode) {
+ tok = otp->tok;
+ break;
+ }
+ }
+ (void)printf("oui %s (0x%06x), %s %s (0x%04x): ",
+ tok2str(oui_values, "Unknown", orgcode),
+ orgcode,
+ (orgcode == 0x000000 ? "ethertype" : "pid"),
+ tok2str(tok, "Unknown", et),
+ et);
+ }
+ p += 5;
+ length -= 5;
+ caplen -= 5;
+
+ switch (orgcode) {
+ case OUI_ENCAP_ETHER:
+ case OUI_CISCO_90:
+ /*
+ * This is an encapsulated Ethernet packet,
+ * or a packet bridged by some piece of
+ * Cisco hardware; the protocol ID is
+ * an Ethernet protocol type.
+ */
+ ret = ethertype_print(gndo, et, p, length, caplen);
+ if (ret)
+ return (ret);
+ break;
+
+ case OUI_APPLETALK:
+ if (et == ETHERTYPE_ATALK) {
+ /*
+ * No, I have no idea why Apple used one
+ * of their own OUIs, rather than
+ * 0x000000, and an Ethernet packet
+ * type, for Appletalk data packets,
+ * but used 0x000000 and an Ethernet
+ * packet type for AARP packets.
+ */
+ ret = ethertype_print(gndo, et, p, length, caplen);
+ if (ret)
+ return (ret);
+ }
+ break;
+
+ case OUI_CISCO:
+ switch (et) {
+ case PID_CISCO_CDP:
+ cdp_print(p, length, caplen);
+ return (1);
+ case PID_CISCO_DTP:
+ dtp_print(p, length);
+ return (1);
+ case PID_CISCO_UDLD:
+ udld_print(p, length);
+ return (1);
+ case PID_CISCO_VTP:
+ vtp_print(p, length);
+ return (1);
+ case PID_CISCO_PVST:
+ stp_print(p, length);
+ return (1);
+ default:
+ break;
+ }
+
+ case OUI_RFC2684:
+ switch (et) {
+
+ case PID_RFC2684_ETH_FCS:
+ case PID_RFC2684_ETH_NOFCS:
+ /*
+ * XXX - remove the last two bytes for
+ * PID_RFC2684_ETH_FCS?
+ */
+ /*
+ * Skip the padding.
+ */
+ TCHECK2(*p, bridge_pad);
+ caplen -= bridge_pad;
+ length -= bridge_pad;
+ p += bridge_pad;
+
+ /*
+ * What remains is an Ethernet packet.
+ */
+ ether_print(gndo, p, length, caplen, NULL, NULL);
+ return (1);
+
+ case PID_RFC2684_802_5_FCS:
+ case PID_RFC2684_802_5_NOFCS:
+ /*
+ * XXX - remove the last two bytes for
+ * PID_RFC2684_ETH_FCS?
+ */
+ /*
+ * Skip the padding, but not the Access
+ * Control field.
+ */
+ TCHECK2(*p, bridge_pad);
+ caplen -= bridge_pad;
+ length -= bridge_pad;
+ p += bridge_pad;
+
+ /*
+ * What remains is an 802.5 Token Ring
+ * packet.
+ */
+ token_print(p, length, caplen);
+ return (1);
+
+ case PID_RFC2684_FDDI_FCS:
+ case PID_RFC2684_FDDI_NOFCS:
+ /*
+ * XXX - remove the last two bytes for
+ * PID_RFC2684_ETH_FCS?
+ */
+ /*
+ * Skip the padding.
+ */
+ TCHECK2(*p, bridge_pad + 1);
+ caplen -= bridge_pad + 1;
+ length -= bridge_pad + 1;
+ p += bridge_pad + 1;
+
+ /*
+ * What remains is an FDDI packet.
+ */
+ fddi_print(p, length, caplen);
+ return (1);
+
+ case PID_RFC2684_BPDU:
+ stp_print(p, length);
+ return (1);
+ }
+ }
+ return (0);
+
+trunc:
+ (void)printf("[|snap]");
+ return (1);
+}
+
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-lldp.c b/freebsd/contrib/tcpdump/print-lldp.c
new file mode 100644
index 00000000..24e1c860
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-lldp.c
@@ -0,0 +1,1415 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1998-2007 The TCPDUMP project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * support for the IEEE Link Discovery Protocol as per 802.1AB
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ * IEEE and TIA extensions by Carles Kishimoto <carles.kishimoto@gmail.com>
+ * DCBX extensions by Kaladhar Musunuru <kaladharm@sourceforge.net>
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+"@(#) $Header: /tcpdump/master/tcpdump/print-lldp.c,v 1.10 2008-03-20 09:30:56 hannes Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+#include "af.h"
+#include "oui.h"
+
+#define LLDP_EXTRACT_TYPE(x) (((x)&0xfe00)>>9)
+#define LLDP_EXTRACT_LEN(x) ((x)&0x01ff)
+
+/*
+ * TLV type codes
+ */
+#define LLDP_END_TLV 0
+#define LLDP_CHASSIS_ID_TLV 1
+#define LLDP_PORT_ID_TLV 2
+#define LLDP_TTL_TLV 3
+#define LLDP_PORT_DESCR_TLV 4
+#define LLDP_SYSTEM_NAME_TLV 5
+#define LLDP_SYSTEM_DESCR_TLV 6
+#define LLDP_SYSTEM_CAP_TLV 7
+#define LLDP_MGMT_ADDR_TLV 8
+#define LLDP_PRIVATE_TLV 127
+
+static const struct tok lldp_tlv_values[] = {
+ { LLDP_END_TLV, "End" },
+ { LLDP_CHASSIS_ID_TLV, "Chassis ID" },
+ { LLDP_PORT_ID_TLV, "Port ID" },
+ { LLDP_TTL_TLV, "Time to Live" },
+ { LLDP_PORT_DESCR_TLV, "Port Description" },
+ { LLDP_SYSTEM_NAME_TLV, "System Name" },
+ { LLDP_SYSTEM_DESCR_TLV, "System Description" },
+ { LLDP_SYSTEM_CAP_TLV, "System Capabilities" },
+ { LLDP_MGMT_ADDR_TLV, "Management Address" },
+ { LLDP_PRIVATE_TLV, "Organization specific" },
+ { 0, NULL}
+};
+
+/*
+ * Chassis ID subtypes
+ */
+#define LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE 1
+#define LLDP_CHASSIS_INTF_ALIAS_SUBTYPE 2
+#define LLDP_CHASSIS_PORT_COMP_SUBTYPE 3
+#define LLDP_CHASSIS_MAC_ADDR_SUBTYPE 4
+#define LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE 5
+#define LLDP_CHASSIS_INTF_NAME_SUBTYPE 6
+#define LLDP_CHASSIS_LOCAL_SUBTYPE 7
+
+static const struct tok lldp_chassis_subtype_values[] = {
+ { LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE, "Chassis component"},
+ { LLDP_CHASSIS_INTF_ALIAS_SUBTYPE, "Interface alias"},
+ { LLDP_CHASSIS_PORT_COMP_SUBTYPE, "Port component"},
+ { LLDP_CHASSIS_MAC_ADDR_SUBTYPE, "MAC address"},
+ { LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE, "Network address"},
+ { LLDP_CHASSIS_INTF_NAME_SUBTYPE, "Interface name"},
+ { LLDP_CHASSIS_LOCAL_SUBTYPE, "Local"},
+ { 0, NULL}
+};
+
+/*
+ * Port ID subtypes
+ */
+#define LLDP_PORT_INTF_ALIAS_SUBTYPE 1
+#define LLDP_PORT_PORT_COMP_SUBTYPE 2
+#define LLDP_PORT_MAC_ADDR_SUBTYPE 3
+#define LLDP_PORT_NETWORK_ADDR_SUBTYPE 4
+#define LLDP_PORT_INTF_NAME_SUBTYPE 5
+#define LLDP_PORT_AGENT_CIRC_ID_SUBTYPE 6
+#define LLDP_PORT_LOCAL_SUBTYPE 7
+
+static const struct tok lldp_port_subtype_values[] = {
+ { LLDP_PORT_INTF_ALIAS_SUBTYPE, "Interface alias"},
+ { LLDP_PORT_PORT_COMP_SUBTYPE, "Port component"},
+ { LLDP_PORT_MAC_ADDR_SUBTYPE, "MAC address"},
+ { LLDP_PORT_NETWORK_ADDR_SUBTYPE, "Network Address"},
+ { LLDP_PORT_INTF_NAME_SUBTYPE, "Interface Name"},
+ { LLDP_PORT_AGENT_CIRC_ID_SUBTYPE, "Agent circuit ID"},
+ { LLDP_PORT_LOCAL_SUBTYPE, "Local"},
+ { 0, NULL}
+};
+
+/*
+ * System Capabilities
+ */
+#define LLDP_CAP_OTHER (1 << 0)
+#define LLDP_CAP_REPEATER (1 << 1)
+#define LLDP_CAP_BRIDGE (1 << 2)
+#define LLDP_CAP_WLAN_AP (1 << 3)
+#define LLDP_CAP_ROUTER (1 << 4)
+#define LLDP_CAP_PHONE (1 << 5)
+#define LLDP_CAP_DOCSIS (1 << 6)
+#define LLDP_CAP_STATION_ONLY (1 << 7)
+
+static const struct tok lldp_cap_values[] = {
+ { LLDP_CAP_OTHER, "Other"},
+ { LLDP_CAP_REPEATER, "Repeater"},
+ { LLDP_CAP_BRIDGE, "Bridge"},
+ { LLDP_CAP_WLAN_AP, "WLAN AP"},
+ { LLDP_CAP_ROUTER, "Router"},
+ { LLDP_CAP_PHONE, "Telephone"},
+ { LLDP_CAP_DOCSIS, "Docsis"},
+ { LLDP_CAP_STATION_ONLY, "Station Only"},
+ { 0, NULL}
+};
+
+#define LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID 1
+#define LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID 2
+#define LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME 3
+#define LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY 4
+
+static const struct tok lldp_8021_subtype_values[] = {
+ { LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID, "Port VLAN Id"},
+ { LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID, "Port and Protocol VLAN ID"},
+ { LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME, "VLAN name"},
+ { LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY, "Protocol Identity"},
+ { 0, NULL}
+};
+
+#define LLDP_8021_PORT_PROTOCOL_VLAN_SUPPORT (1 << 1)
+#define LLDP_8021_PORT_PROTOCOL_VLAN_STATUS (1 << 2)
+
+static const struct tok lldp_8021_port_protocol_id_values[] = {
+ { LLDP_8021_PORT_PROTOCOL_VLAN_SUPPORT, "supported"},
+ { LLDP_8021_PORT_PROTOCOL_VLAN_STATUS, "enabled"},
+ { 0, NULL}
+};
+
+#define LLDP_PRIVATE_8023_SUBTYPE_MACPHY 1
+#define LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER 2
+#define LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR 3
+#define LLDP_PRIVATE_8023_SUBTYPE_MTU 4
+
+static const struct tok lldp_8023_subtype_values[] = {
+ { LLDP_PRIVATE_8023_SUBTYPE_MACPHY, "MAC/PHY configuration/status"},
+ { LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER, "Power via MDI"},
+ { LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR, "Link aggregation"},
+ { LLDP_PRIVATE_8023_SUBTYPE_MTU, "Max frame size"},
+ { 0, NULL}
+};
+
+#define LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES 1
+#define LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY 2
+#define LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID 3
+#define LLDP_PRIVATE_TIA_SUBTYPE_EXTENDED_POWER_MDI 4
+#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV 5
+#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV 6
+#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV 7
+#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER 8
+#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME 9
+#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME 10
+#define LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID 11
+
+static const struct tok lldp_tia_subtype_values[] = {
+ { LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES, "LLDP-MED Capabilities" },
+ { LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY, "Network policy" },
+ { LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID, "Location identification" },
+ { LLDP_PRIVATE_TIA_SUBTYPE_EXTENDED_POWER_MDI, "Extended power-via-MDI" },
+ { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV, "Inventory - hardware revision" },
+ { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV, "Inventory - firmware revision" },
+ { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV, "Inventory - software revision" },
+ { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER, "Inventory - serial number" },
+ { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME, "Inventory - manufacturer name" },
+ { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME, "Inventory - model name" },
+ { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID, "Inventory - asset ID" },
+ { 0, NULL}
+};
+
+#define LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_METERS 1
+#define LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_FLOORS 2
+
+static const struct tok lldp_tia_location_altitude_type_values[] = {
+ { LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_METERS, "meters"},
+ { LLDP_PRIVATE_TIA_LOCATION_ALTITUDE_FLOORS, "floors"},
+ { 0, NULL}
+};
+
+/* ANSI/TIA-1057 - Annex B */
+#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A1 1
+#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A2 2
+#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A3 3
+#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A4 4
+#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A5 5
+#define LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A6 6
+
+static const struct tok lldp_tia_location_lci_catype_values[] = {
+ { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A1, "national subdivisions (state,canton,region,province,prefecture)"},
+ { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A2, "county, parish, gun, district"},
+ { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A3, "city, township, shi"},
+ { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A4, "city division, borough, city district, ward chou"},
+ { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A5, "neighborhood, block"},
+ { LLDP_PRIVATE_TIA_LOCATION_LCI_CATYPE_A6, "street"},
+ { 0, NULL}
+};
+
+static const struct tok lldp_tia_location_lci_what_values[] = {
+ { 0, "location of DHCP server"},
+ { 1, "location of the network element believed to be closest to the client"},
+ { 2, "location of the client"},
+ { 0, NULL}
+};
+
+/*
+ * From RFC 3636 - dot3MauType
+ */
+#define LLDP_MAU_TYPE_UNKNOWN 0
+#define LLDP_MAU_TYPE_AUI 1
+#define LLDP_MAU_TYPE_10BASE_5 2
+#define LLDP_MAU_TYPE_FOIRL 3
+#define LLDP_MAU_TYPE_10BASE_2 4
+#define LLDP_MAU_TYPE_10BASE_T 5
+#define LLDP_MAU_TYPE_10BASE_FP 6
+#define LLDP_MAU_TYPE_10BASE_FB 7
+#define LLDP_MAU_TYPE_10BASE_FL 8
+#define LLDP_MAU_TYPE_10BROAD36 9
+#define LLDP_MAU_TYPE_10BASE_T_HD 10
+#define LLDP_MAU_TYPE_10BASE_T_FD 11
+#define LLDP_MAU_TYPE_10BASE_FL_HD 12
+#define LLDP_MAU_TYPE_10BASE_FL_FD 13
+#define LLDP_MAU_TYPE_100BASE_T4 14
+#define LLDP_MAU_TYPE_100BASE_TX_HD 15
+#define LLDP_MAU_TYPE_100BASE_TX_FD 16
+#define LLDP_MAU_TYPE_100BASE_FX_HD 17
+#define LLDP_MAU_TYPE_100BASE_FX_FD 18
+#define LLDP_MAU_TYPE_100BASE_T2_HD 19
+#define LLDP_MAU_TYPE_100BASE_T2_FD 20
+#define LLDP_MAU_TYPE_1000BASE_X_HD 21
+#define LLDP_MAU_TYPE_1000BASE_X_FD 22
+#define LLDP_MAU_TYPE_1000BASE_LX_HD 23
+#define LLDP_MAU_TYPE_1000BASE_LX_FD 24
+#define LLDP_MAU_TYPE_1000BASE_SX_HD 25
+#define LLDP_MAU_TYPE_1000BASE_SX_FD 26
+#define LLDP_MAU_TYPE_1000BASE_CX_HD 27
+#define LLDP_MAU_TYPE_1000BASE_CX_FD 28
+#define LLDP_MAU_TYPE_1000BASE_T_HD 29
+#define LLDP_MAU_TYPE_1000BASE_T_FD 30
+#define LLDP_MAU_TYPE_10GBASE_X 31
+#define LLDP_MAU_TYPE_10GBASE_LX4 32
+#define LLDP_MAU_TYPE_10GBASE_R 33
+#define LLDP_MAU_TYPE_10GBASE_ER 34
+#define LLDP_MAU_TYPE_10GBASE_LR 35
+#define LLDP_MAU_TYPE_10GBASE_SR 36
+#define LLDP_MAU_TYPE_10GBASE_W 37
+#define LLDP_MAU_TYPE_10GBASE_EW 38
+#define LLDP_MAU_TYPE_10GBASE_LW 39
+#define LLDP_MAU_TYPE_10GBASE_SW 40
+
+static const struct tok lldp_mau_types_values[] = {
+ { LLDP_MAU_TYPE_UNKNOWN, "Unknown"},
+ { LLDP_MAU_TYPE_AUI, "AUI"},
+ { LLDP_MAU_TYPE_10BASE_5, "10BASE_5"},
+ { LLDP_MAU_TYPE_FOIRL, "FOIRL"},
+ { LLDP_MAU_TYPE_10BASE_2, "10BASE2"},
+ { LLDP_MAU_TYPE_10BASE_T, "10BASET duplex mode unknown"},
+ { LLDP_MAU_TYPE_10BASE_FP, "10BASEFP"},
+ { LLDP_MAU_TYPE_10BASE_FB, "10BASEFB"},
+ { LLDP_MAU_TYPE_10BASE_FL, "10BASEFL duplex mode unknown"},
+ { LLDP_MAU_TYPE_10BROAD36, "10BROAD36"},
+ { LLDP_MAU_TYPE_10BASE_T_HD, "10BASET hdx"},
+ { LLDP_MAU_TYPE_10BASE_T_FD, "10BASET fdx"},
+ { LLDP_MAU_TYPE_10BASE_FL_HD, "10BASEFL hdx"},
+ { LLDP_MAU_TYPE_10BASE_FL_FD, "10BASEFL fdx"},
+ { LLDP_MAU_TYPE_100BASE_T4, "100BASET4"},
+ { LLDP_MAU_TYPE_100BASE_TX_HD, "100BASETX hdx"},
+ { LLDP_MAU_TYPE_100BASE_TX_FD, "100BASETX fdx"},
+ { LLDP_MAU_TYPE_100BASE_FX_HD, "100BASEFX hdx"},
+ { LLDP_MAU_TYPE_100BASE_FX_FD, "100BASEFX fdx"},
+ { LLDP_MAU_TYPE_100BASE_T2_HD, "100BASET2 hdx"},
+ { LLDP_MAU_TYPE_100BASE_T2_FD, "100BASET2 fdx"},
+ { LLDP_MAU_TYPE_1000BASE_X_HD, "1000BASEX hdx"},
+ { LLDP_MAU_TYPE_1000BASE_X_FD, "1000BASEX fdx"},
+ { LLDP_MAU_TYPE_1000BASE_LX_HD, "1000BASELX hdx"},
+ { LLDP_MAU_TYPE_1000BASE_LX_FD, "1000BASELX fdx"},
+ { LLDP_MAU_TYPE_1000BASE_SX_HD, "1000BASESX hdx"},
+ { LLDP_MAU_TYPE_1000BASE_SX_FD, "1000BASESX fdx"},
+ { LLDP_MAU_TYPE_1000BASE_CX_HD, "1000BASECX hdx"},
+ { LLDP_MAU_TYPE_1000BASE_CX_FD, "1000BASECX fdx"},
+ { LLDP_MAU_TYPE_1000BASE_T_HD, "1000BASET hdx"},
+ { LLDP_MAU_TYPE_1000BASE_T_FD, "1000BASET fdx"},
+ { LLDP_MAU_TYPE_10GBASE_X, "10GBASEX"},
+ { LLDP_MAU_TYPE_10GBASE_LX4, "10GBASELX4"},
+ { LLDP_MAU_TYPE_10GBASE_R, "10GBASER"},
+ { LLDP_MAU_TYPE_10GBASE_ER, "10GBASEER"},
+ { LLDP_MAU_TYPE_10GBASE_LR, "10GBASELR"},
+ { LLDP_MAU_TYPE_10GBASE_SR, "10GBASESR"},
+ { LLDP_MAU_TYPE_10GBASE_W, "10GBASEW"},
+ { LLDP_MAU_TYPE_10GBASE_EW, "10GBASEEW"},
+ { LLDP_MAU_TYPE_10GBASE_LW, "10GBASELW"},
+ { LLDP_MAU_TYPE_10GBASE_SW, "10GBASESW"},
+ { 0, NULL}
+};
+
+#define LLDP_8023_AUTONEGOTIATION_SUPPORT (1 << 0)
+#define LLDP_8023_AUTONEGOTIATION_STATUS (1 << 1)
+
+static const struct tok lldp_8023_autonegotiation_values[] = {
+ { LLDP_8023_AUTONEGOTIATION_SUPPORT, "supported"},
+ { LLDP_8023_AUTONEGOTIATION_STATUS, "enabled"},
+ { 0, NULL}
+};
+
+#define LLDP_TIA_CAPABILITY_MED (1 << 0)
+#define LLDP_TIA_CAPABILITY_NETWORK_POLICY (1 << 1)
+#define LLDP_TIA_CAPABILITY_LOCATION_IDENTIFICATION (1 << 2)
+#define LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PSE (1 << 3)
+#define LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PD (1 << 4)
+#define LLDP_TIA_CAPABILITY_INVENTORY (1 << 5)
+
+static const struct tok lldp_tia_capabilities_values[] = {
+ { LLDP_TIA_CAPABILITY_MED, "LLDP-MED capabilities"},
+ { LLDP_TIA_CAPABILITY_NETWORK_POLICY, "network policy"},
+ { LLDP_TIA_CAPABILITY_LOCATION_IDENTIFICATION, "location identification"},
+ { LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PSE, "extended power via MDI-PSE"},
+ { LLDP_TIA_CAPABILITY_EXTENDED_POWER_MDI_PD, "extended power via MDI-PD"},
+ { LLDP_TIA_CAPABILITY_INVENTORY, "Inventory"},
+ { 0, NULL}
+};
+
+#define LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_1 1
+#define LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_2 2
+#define LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_3 3
+#define LLDP_TIA_DEVICE_TYPE_NETWORK_CONNECTIVITY 4
+
+static const struct tok lldp_tia_device_type_values[] = {
+ { LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_1, "endpoint class 1"},
+ { LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_2, "endpoint class 2"},
+ { LLDP_TIA_DEVICE_TYPE_ENDPOINT_CLASS_3, "endpoint class 3"},
+ { LLDP_TIA_DEVICE_TYPE_NETWORK_CONNECTIVITY, "network connectivity"},
+ { 0, NULL}
+};
+
+#define LLDP_TIA_APPLICATION_TYPE_VOICE 1
+#define LLDP_TIA_APPLICATION_TYPE_VOICE_SIGNALING 2
+#define LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE 3
+#define LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE_SIGNALING 4
+#define LLDP_TIA_APPLICATION_TYPE_SOFTPHONE_VOICE 5
+#define LLDP_TIA_APPLICATION_TYPE_VIDEO_CONFERENCING 6
+#define LLDP_TIA_APPLICATION_TYPE_STREAMING_VIDEO 7
+#define LLDP_TIA_APPLICATION_TYPE_VIDEO_SIGNALING 8
+
+static const struct tok lldp_tia_application_type_values[] = {
+ { LLDP_TIA_APPLICATION_TYPE_VOICE, "voice"},
+ { LLDP_TIA_APPLICATION_TYPE_VOICE_SIGNALING, "voice signaling"},
+ { LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE, "guest voice"},
+ { LLDP_TIA_APPLICATION_TYPE_GUEST_VOICE_SIGNALING, "guest voice signaling"},
+ { LLDP_TIA_APPLICATION_TYPE_SOFTPHONE_VOICE, "softphone voice"},
+ { LLDP_TIA_APPLICATION_TYPE_VIDEO_CONFERENCING, "video conferencing"},
+ { LLDP_TIA_APPLICATION_TYPE_STREAMING_VIDEO, "streaming video"},
+ { LLDP_TIA_APPLICATION_TYPE_VIDEO_SIGNALING, "video signaling"},
+ { 0, NULL}
+};
+
+#define LLDP_TIA_NETWORK_POLICY_X_BIT (1 << 5)
+#define LLDP_TIA_NETWORK_POLICY_T_BIT (1 << 6)
+#define LLDP_TIA_NETWORK_POLICY_U_BIT (1 << 7)
+
+static const struct tok lldp_tia_network_policy_bits_values[] = {
+ { LLDP_TIA_NETWORK_POLICY_U_BIT, "Unknown"},
+ { LLDP_TIA_NETWORK_POLICY_T_BIT, "Tagged"},
+ { LLDP_TIA_NETWORK_POLICY_X_BIT, "reserved"},
+ { 0, NULL}
+};
+
+#define LLDP_EXTRACT_NETWORK_POLICY_VLAN(x) (((x)&0x1ffe)>>1)
+#define LLDP_EXTRACT_NETWORK_POLICY_L2_PRIORITY(x) (((x)&0x01ff)>>6)
+#define LLDP_EXTRACT_NETWORK_POLICY_DSCP(x) ((x)&0x003f)
+
+#define LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED 1
+#define LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS 2
+#define LLDP_TIA_LOCATION_DATA_FORMAT_ECS_ELIN 3
+
+static const struct tok lldp_tia_location_data_format_values[] = {
+ { LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED, "coordinate-based LCI"},
+ { LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS, "civic address LCI"},
+ { LLDP_TIA_LOCATION_DATA_FORMAT_ECS_ELIN, "ECS ELIN"},
+ { 0, NULL}
+};
+
+#define LLDP_TIA_LOCATION_DATUM_WGS_84 1
+#define LLDP_TIA_LOCATION_DATUM_NAD_83_NAVD_88 2
+#define LLDP_TIA_LOCATION_DATUM_NAD_83_MLLW 3
+
+static const struct tok lldp_tia_location_datum_type_values[] = {
+ { LLDP_TIA_LOCATION_DATUM_WGS_84, "World Geodesic System 1984"},
+ { LLDP_TIA_LOCATION_DATUM_NAD_83_NAVD_88, "North American Datum 1983 (NAVD88)"},
+ { LLDP_TIA_LOCATION_DATUM_NAD_83_MLLW, "North American Datum 1983 (MLLW)"},
+ { 0, NULL}
+};
+
+#define LLDP_TIA_POWER_SOURCE_PSE 1
+#define LLDP_TIA_POWER_SOURCE_LOCAL 2
+#define LLDP_TIA_POWER_SOURCE_PSE_AND_LOCAL 3
+
+static const struct tok lldp_tia_power_source_values[] = {
+ { LLDP_TIA_POWER_SOURCE_PSE, "PSE - primary power source"},
+ { LLDP_TIA_POWER_SOURCE_LOCAL, "local - backup power source"},
+ { LLDP_TIA_POWER_SOURCE_PSE_AND_LOCAL, "PSE+local - reserved"},
+ { 0, NULL}
+};
+
+#define LLDP_TIA_POWER_PRIORITY_CRITICAL 1
+#define LLDP_TIA_POWER_PRIORITY_HIGH 2
+#define LLDP_TIA_POWER_PRIORITY_LOW 3
+
+static const struct tok lldp_tia_power_priority_values[] = {
+ { LLDP_TIA_POWER_PRIORITY_CRITICAL, "critical"},
+ { LLDP_TIA_POWER_PRIORITY_HIGH, "high"},
+ { LLDP_TIA_POWER_PRIORITY_LOW, "low"},
+ { 0, NULL}
+};
+
+#define LLDP_TIA_POWER_VAL_MAX 1024
+
+static const struct tok lldp_tia_inventory_values[] = {
+ { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV, "Hardware revision" },
+ { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV, "Firmware revision" },
+ { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV, "Software revision" },
+ { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER, "Serial number" },
+ { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME, "Manufacturer name" },
+ { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME, "Model name" },
+ { LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID, "Asset ID" },
+ { 0, NULL}
+};
+
+/*
+ * From RFC 3636 - ifMauAutoNegCapAdvertisedBits
+ */
+#define LLDP_MAU_PMD_OTHER (1 << 15)
+#define LLDP_MAU_PMD_10BASE_T (1 << 14)
+#define LLDP_MAU_PMD_10BASE_T_FD (1 << 13)
+#define LLDP_MAU_PMD_100BASE_T4 (1 << 12)
+#define LLDP_MAU_PMD_100BASE_TX (1 << 11)
+#define LLDP_MAU_PMD_100BASE_TX_FD (1 << 10)
+#define LLDP_MAU_PMD_100BASE_T2 (1 << 9)
+#define LLDP_MAU_PMD_100BASE_T2_FD (1 << 8)
+#define LLDP_MAU_PMD_FDXPAUSE (1 << 7)
+#define LLDP_MAU_PMD_FDXAPAUSE (1 << 6)
+#define LLDP_MAU_PMD_FDXSPAUSE (1 << 5)
+#define LLDP_MAU_PMD_FDXBPAUSE (1 << 4)
+#define LLDP_MAU_PMD_1000BASE_X (1 << 3)
+#define LLDP_MAU_PMD_1000BASE_X_FD (1 << 2)
+#define LLDP_MAU_PMD_1000BASE_T (1 << 1)
+#define LLDP_MAU_PMD_1000BASE_T_FD (1 << 0)
+
+static const struct tok lldp_pmd_capability_values[] = {
+ { LLDP_MAU_PMD_10BASE_T, "10BASE-T hdx"},
+ { LLDP_MAU_PMD_10BASE_T_FD, "10BASE-T fdx"},
+ { LLDP_MAU_PMD_100BASE_T4, "100BASE-T4"},
+ { LLDP_MAU_PMD_100BASE_TX, "100BASE-TX hdx"},
+ { LLDP_MAU_PMD_100BASE_TX_FD, "100BASE-TX fdx"},
+ { LLDP_MAU_PMD_100BASE_T2, "100BASE-T2 hdx"},
+ { LLDP_MAU_PMD_100BASE_T2_FD, "100BASE-T2 fdx"},
+ { LLDP_MAU_PMD_FDXPAUSE, "Pause for fdx links"},
+ { LLDP_MAU_PMD_FDXAPAUSE, "Asym PAUSE for fdx"},
+ { LLDP_MAU_PMD_FDXSPAUSE, "Sym PAUSE for fdx"},
+ { LLDP_MAU_PMD_FDXBPAUSE, "Asym and Sym PAUSE for fdx"},
+ { LLDP_MAU_PMD_1000BASE_X, "1000BASE-{X LX SX CX} hdx"},
+ { LLDP_MAU_PMD_1000BASE_X_FD, "1000BASE-{X LX SX CX} fdx"},
+ { LLDP_MAU_PMD_1000BASE_T, "1000BASE-T hdx"},
+ { LLDP_MAU_PMD_1000BASE_T_FD, "1000BASE-T fdx"},
+ { 0, NULL}
+};
+
+#define LLDP_MDI_PORT_CLASS (1 << 0)
+#define LLDP_MDI_POWER_SUPPORT (1 << 1)
+#define LLDP_MDI_POWER_STATE (1 << 2)
+#define LLDP_MDI_PAIR_CONTROL_ABILITY (1 << 3)
+
+static const struct tok lldp_mdi_values[] = {
+ { LLDP_MDI_PORT_CLASS, "PSE"},
+ { LLDP_MDI_POWER_SUPPORT, "supported"},
+ { LLDP_MDI_POWER_STATE, "enabled"},
+ { LLDP_MDI_PAIR_CONTROL_ABILITY, "can be controlled"},
+ { 0, NULL}
+};
+
+#define LLDP_MDI_PSE_PORT_POWER_PAIRS_SIGNAL 1
+#define LLDP_MDI_PSE_PORT_POWER_PAIRS_SPARE 2
+
+static const struct tok lldp_mdi_power_pairs_values[] = {
+ { LLDP_MDI_PSE_PORT_POWER_PAIRS_SIGNAL, "signal"},
+ { LLDP_MDI_PSE_PORT_POWER_PAIRS_SPARE, "spare"},
+ { 0, NULL}
+};
+
+#define LLDP_MDI_POWER_CLASS0 1
+#define LLDP_MDI_POWER_CLASS1 2
+#define LLDP_MDI_POWER_CLASS2 3
+#define LLDP_MDI_POWER_CLASS3 4
+#define LLDP_MDI_POWER_CLASS4 5
+
+static const struct tok lldp_mdi_power_class_values[] = {
+ { LLDP_MDI_POWER_CLASS0, "class0"},
+ { LLDP_MDI_POWER_CLASS1, "class1"},
+ { LLDP_MDI_POWER_CLASS2, "class2"},
+ { LLDP_MDI_POWER_CLASS3, "class3"},
+ { LLDP_MDI_POWER_CLASS4, "class4"},
+ { 0, NULL}
+};
+
+#define LLDP_AGGREGATION_CAPABILTIY (1 << 0)
+#define LLDP_AGGREGATION_STATUS (1 << 1)
+
+static const struct tok lldp_aggregation_values[] = {
+ { LLDP_AGGREGATION_CAPABILTIY, "supported"},
+ { LLDP_AGGREGATION_STATUS, "enabled"},
+ { 0, NULL}
+};
+
+/*
+ * DCBX protocol subtypes.
+ */
+#define LLDP_DCBX_SUBTYPE_1 1
+#define LLDP_DCBX_SUBTYPE_2 2
+
+static const struct tok lldp_dcbx_subtype_values[] = {
+ { LLDP_DCBX_SUBTYPE_1, "DCB Capability Exchange Protocol Rev 1" },
+ { LLDP_DCBX_SUBTYPE_2, "DCB Capability Exchange Protocol Rev 1.01" },
+ { 0, NULL}
+};
+
+#define LLDP_DCBX_CONTROL_TLV 1
+#define LLDP_DCBX_PRIORITY_GROUPS_TLV 2
+#define LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV 3
+#define LLDP_DCBX_APPLICATION_TLV 4
+
+/*
+ * Interface numbering subtypes.
+ */
+#define LLDP_INTF_NUMB_IFX_SUBTYPE 2
+#define LLDP_INTF_NUMB_SYSPORT_SUBTYPE 3
+
+static const struct tok lldp_intf_numb_subtype_values[] = {
+ { LLDP_INTF_NUMB_IFX_SUBTYPE, "Interface Index" },
+ { LLDP_INTF_NUMB_SYSPORT_SUBTYPE, "System Port Number" },
+ { 0, NULL}
+};
+
+#define LLDP_INTF_NUM_LEN 5
+
+/*
+ * Print IEEE 802.1 private extensions. (802.1AB annex E)
+ */
+static int
+lldp_private_8021_print(const u_char *tptr, u_int tlv_len)
+{
+ int subtype, hexdump = FALSE;
+ u_int sublen;
+
+ if (tlv_len < 4) {
+ return hexdump;
+ }
+ subtype = *(tptr+3);
+
+ printf("\n\t %s Subtype (%u)",
+ tok2str(lldp_8021_subtype_values, "unknown", subtype),
+ subtype);
+
+ switch (subtype) {
+ case LLDP_PRIVATE_8021_SUBTYPE_PORT_VLAN_ID:
+ if (tlv_len < 6) {
+ return hexdump;
+ }
+ printf("\n\t port vlan id (PVID): %u",
+ EXTRACT_16BITS(tptr+4));
+ break;
+ case LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_VLAN_ID:
+ if (tlv_len < 7) {
+ return hexdump;
+ }
+ printf("\n\t port and protocol vlan id (PPVID): %u, flags [%s] (0x%02x)",
+ EXTRACT_16BITS(tptr+5),
+ bittok2str(lldp_8021_port_protocol_id_values, "none", *(tptr+4)),
+ *(tptr+4));
+ break;
+ case LLDP_PRIVATE_8021_SUBTYPE_VLAN_NAME:
+ if (tlv_len < 6) {
+ return hexdump;
+ }
+ printf("\n\t vlan id (VID): %u",
+ EXTRACT_16BITS(tptr+4));
+ if (tlv_len < 7) {
+ return hexdump;
+ }
+ sublen = *(tptr+6);
+ if (tlv_len < 7+sublen) {
+ return hexdump;
+ }
+ printf("\n\t vlan name: ");
+ safeputs((const char *)tptr+7, sublen);
+ break;
+ case LLDP_PRIVATE_8021_SUBTYPE_PROTOCOL_IDENTITY:
+ if (tlv_len < 5) {
+ return hexdump;
+ }
+ sublen = *(tptr+4);
+ if (tlv_len < 5+sublen) {
+ return hexdump;
+ }
+ printf("\n\t protocol identity: ");
+ safeputs((const char *)tptr+5, sublen);
+ break;
+
+ default:
+ hexdump = TRUE;
+ break;
+ }
+
+ return hexdump;
+}
+
+/*
+ * Print IEEE 802.3 private extensions. (802.3bc)
+ */
+static int
+lldp_private_8023_print(const u_char *tptr, u_int tlv_len)
+{
+ int subtype, hexdump = FALSE;
+
+ if (tlv_len < 4) {
+ return hexdump;
+ }
+ subtype = *(tptr+3);
+
+ printf("\n\t %s Subtype (%u)",
+ tok2str(lldp_8023_subtype_values, "unknown", subtype),
+ subtype);
+
+ switch (subtype) {
+ case LLDP_PRIVATE_8023_SUBTYPE_MACPHY:
+ if (tlv_len < 9) {
+ return hexdump;
+ }
+ printf("\n\t autonegotiation [%s] (0x%02x)",
+ bittok2str(lldp_8023_autonegotiation_values, "none", *(tptr+4)),
+ *(tptr+4));
+ printf("\n\t PMD autoneg capability [%s] (0x%04x)",
+ bittok2str(lldp_pmd_capability_values,"unknown", EXTRACT_16BITS(tptr+5)),
+ EXTRACT_16BITS(tptr+5));
+ printf("\n\t MAU type %s (0x%04x)",
+ tok2str(lldp_mau_types_values, "unknown", EXTRACT_16BITS(tptr+7)),
+ EXTRACT_16BITS(tptr+7));
+ break;
+
+ case LLDP_PRIVATE_8023_SUBTYPE_MDIPOWER:
+ if (tlv_len < 7) {
+ return hexdump;
+ }
+ printf("\n\t MDI power support [%s], power pair %s, power class %s",
+ bittok2str(lldp_mdi_values, "none", *(tptr+4)),
+ tok2str(lldp_mdi_power_pairs_values, "unknown", *(tptr+5)),
+ tok2str(lldp_mdi_power_class_values, "unknown", *(tptr+6)));
+ break;
+
+ case LLDP_PRIVATE_8023_SUBTYPE_LINKAGGR:
+ if (tlv_len < 9) {
+ return hexdump;
+ }
+ printf("\n\t aggregation status [%s], aggregation port ID %u",
+ bittok2str(lldp_aggregation_values, "none", *(tptr+4)),
+ EXTRACT_32BITS(tptr+5));
+ break;
+
+ case LLDP_PRIVATE_8023_SUBTYPE_MTU:
+ printf("\n\t MTU size %u", EXTRACT_16BITS(tptr+4));
+ break;
+
+ default:
+ hexdump = TRUE;
+ break;
+ }
+
+ return hexdump;
+}
+
+/*
+ * Extract 34bits of latitude/longitude coordinates.
+ */
+static u_int64_t
+lldp_extract_latlon(const u_char *tptr)
+{
+ u_int64_t latlon;
+
+ latlon = *tptr & 0x3;
+ latlon = (latlon << 32) | EXTRACT_32BITS(tptr+1);
+
+ return latlon;
+}
+
+/*
+ * Print private TIA extensions.
+ */
+static int
+lldp_private_tia_print(const u_char *tptr, u_int tlv_len)
+{
+ int subtype, hexdump = FALSE;
+ u_int8_t location_format;
+ u_int16_t power_val;
+ u_int lci_len;
+ u_int8_t ca_type, ca_len;
+
+ if (tlv_len < 4) {
+ return hexdump;
+ }
+ subtype = *(tptr+3);
+
+ printf("\n\t %s Subtype (%u)",
+ tok2str(lldp_tia_subtype_values, "unknown", subtype),
+ subtype);
+
+ switch (subtype) {
+ case LLDP_PRIVATE_TIA_SUBTYPE_CAPABILITIES:
+ if (tlv_len < 7) {
+ return hexdump;
+ }
+ printf("\n\t Media capabilities [%s] (0x%04x)",
+ bittok2str(lldp_tia_capabilities_values, "none",
+ EXTRACT_16BITS(tptr+4)), EXTRACT_16BITS(tptr+4));
+ printf("\n\t Device type [%s] (0x%02x)",
+ tok2str(lldp_tia_device_type_values, "unknown", *(tptr+6)),
+ *(tptr+6));
+ break;
+
+ case LLDP_PRIVATE_TIA_SUBTYPE_NETWORK_POLICY:
+ if (tlv_len < 8) {
+ return hexdump;
+ }
+ printf("\n\t Application type [%s] (0x%02x)",
+ tok2str(lldp_tia_application_type_values, "none", *(tptr+4)),
+ *(tptr+4));
+ printf(", Flags [%s]", bittok2str(
+ lldp_tia_network_policy_bits_values, "none", *(tptr+5)));
+ printf("\n\t Vlan id %u",
+ LLDP_EXTRACT_NETWORK_POLICY_VLAN(EXTRACT_16BITS(tptr+5)));
+ printf(", L2 priority %u",
+ LLDP_EXTRACT_NETWORK_POLICY_L2_PRIORITY(EXTRACT_16BITS(tptr+6)));
+ printf(", DSCP value %u",
+ LLDP_EXTRACT_NETWORK_POLICY_DSCP(EXTRACT_16BITS(tptr+6)));
+ break;
+
+ case LLDP_PRIVATE_TIA_SUBTYPE_LOCAL_ID:
+ if (tlv_len < 5) {
+ return hexdump;
+ }
+ location_format = *(tptr+4);
+ printf("\n\t Location data format %s (0x%02x)",
+ tok2str(lldp_tia_location_data_format_values, "unknown", location_format),
+ location_format);
+
+ switch (location_format) {
+ case LLDP_TIA_LOCATION_DATA_FORMAT_COORDINATE_BASED:
+ if (tlv_len < 21) {
+ return hexdump;
+ }
+ printf("\n\t Latitude resolution %u, latitude value %" PRIu64,
+ (*(tptr+5)>>2), lldp_extract_latlon(tptr+5));
+ printf("\n\t Longitude resolution %u, longitude value %" PRIu64,
+ (*(tptr+10)>>2), lldp_extract_latlon(tptr+10));
+ printf("\n\t Altitude type %s (%u)",
+ tok2str(lldp_tia_location_altitude_type_values, "unknown",(*(tptr+15)>>4)),
+ (*(tptr+15)>>4));
+ printf("\n\t Altitude resolution %u, altitude value 0x%x",
+ (EXTRACT_16BITS(tptr+15)>>6)&0x3f,
+ ((EXTRACT_32BITS(tptr+16)&0x3fffffff)));
+ printf("\n\t Datum %s (0x%02x)",
+ tok2str(lldp_tia_location_datum_type_values, "unknown", *(tptr+20)),
+ *(tptr+20));
+ break;
+
+ case LLDP_TIA_LOCATION_DATA_FORMAT_CIVIC_ADDRESS:
+ if (tlv_len < 6) {
+ return hexdump;
+ }
+ lci_len = *(tptr+5);
+ if (lci_len < 3) {
+ return hexdump;
+ }
+ if (tlv_len < 7+lci_len) {
+ return hexdump;
+ }
+ printf("\n\t LCI length %u, LCI what %s (0x%02x), Country-code ",
+ lci_len,
+ tok2str(lldp_tia_location_lci_what_values, "unknown", *(tptr+6)),
+ *(tptr+6));
+
+ /* Country code */
+ safeputs((const char *)(tptr+7), 2);
+
+ lci_len = lci_len-3;
+ tptr = tptr + 9;
+
+ /* Decode each civic address element */
+ while (lci_len > 0) {
+ if (lci_len < 2) {
+ return hexdump;
+ }
+ ca_type = *(tptr);
+ ca_len = *(tptr+1);
+
+ tptr += 2;
+ lci_len -= 2;
+
+ printf("\n\t CA type \'%s\' (%u), length %u: ",
+ tok2str(lldp_tia_location_lci_catype_values, "unknown", ca_type),
+ ca_type, ca_len);
+
+ /* basic sanity check */
+ if ( ca_type == 0 || ca_len == 0) {
+ return hexdump;
+ }
+ if (lci_len < ca_len) {
+ return hexdump;
+ }
+
+ safeputs((const char *)tptr, ca_len);
+ tptr += ca_len;
+ lci_len -= ca_len;
+ }
+ break;
+
+ case LLDP_TIA_LOCATION_DATA_FORMAT_ECS_ELIN:
+ printf("\n\t ECS ELIN id ");
+ safeputs((const char *)tptr+5, tlv_len-5);
+ break;
+
+ default:
+ printf("\n\t Location ID ");
+ print_unknown_data(tptr+5, "\n\t ", tlv_len-5);
+ }
+ break;
+
+ case LLDP_PRIVATE_TIA_SUBTYPE_EXTENDED_POWER_MDI:
+ if (tlv_len < 7) {
+ return hexdump;
+ }
+ printf("\n\t Power type [%s]",
+ (*(tptr+4)&0xC0>>6) ? "PD device" : "PSE device");
+ printf(", Power source [%s]",
+ tok2str(lldp_tia_power_source_values, "none", (*(tptr+4)&0x30)>>4));
+ printf("\n\t Power priority [%s] (0x%02x)",
+ tok2str(lldp_tia_power_priority_values, "none", *(tptr+4)&0x0f),
+ *(tptr+4)&0x0f);
+ power_val = EXTRACT_16BITS(tptr+5);
+ if (power_val < LLDP_TIA_POWER_VAL_MAX) {
+ printf(", Power %.1f Watts", ((float)power_val)/10);
+ } else {
+ printf(", Power %u (Reserved)", power_val);
+ }
+ break;
+
+ case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_HARDWARE_REV:
+ case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_FIRMWARE_REV:
+ case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SOFTWARE_REV:
+ case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_SERIAL_NUMBER:
+ case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MANUFACTURER_NAME:
+ case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_MODEL_NAME:
+ case LLDP_PRIVATE_TIA_SUBTYPE_INVENTORY_ASSET_ID:
+ printf("\n\t %s ",
+ tok2str(lldp_tia_inventory_values, "unknown", subtype));
+ safeputs((const char *)tptr+4, tlv_len-4);
+ break;
+
+ default:
+ hexdump = TRUE;
+ break;
+ }
+
+ return hexdump;
+}
+
+/*
+ * Print DCBX Protocol fields (V 1.01).
+ */
+static int
+lldp_private_dcbx_print(const u_char *pptr, u_int len)
+{
+ int subtype, hexdump = FALSE;
+ u_int8_t tval;
+ u_int16_t tlv;
+ u_int32_t i, pgval, uval;
+ u_int tlen, tlv_type, tlv_len;
+ const u_char *tptr, *mptr;
+
+ if (len < 4) {
+ return hexdump;
+ }
+ subtype = *(pptr+3);
+
+ printf("\n\t %s Subtype (%u)",
+ tok2str(lldp_dcbx_subtype_values, "unknown", subtype),
+ subtype);
+
+ /* by passing old version */
+ if (subtype == LLDP_DCBX_SUBTYPE_1)
+ return TRUE;
+
+ tptr = pptr + 4;
+ tlen = len - 4;
+
+ while (tlen >= sizeof(tlv)) {
+
+ TCHECK2(*tptr, sizeof(tlv));
+
+ tlv = EXTRACT_16BITS(tptr);
+
+ tlv_type = LLDP_EXTRACT_TYPE(tlv);
+ tlv_len = LLDP_EXTRACT_LEN(tlv);
+ hexdump = FALSE;
+
+ tlen -= sizeof(tlv);
+ tptr += sizeof(tlv);
+
+ /* loop check */
+ if (!tlv_type || !tlv_len) {
+ break;
+ }
+
+ TCHECK2(*tptr, tlv_len);
+ if (tlen < tlv_len) {
+ goto trunc;
+ }
+
+ /* decode every tlv */
+ switch (tlv_type) {
+ case LLDP_DCBX_CONTROL_TLV:
+ if (tlv_len < 10) {
+ goto trunc;
+ }
+ printf("\n\t Control - Protocol Control (type 0x%x, length %d)",
+ LLDP_DCBX_CONTROL_TLV, tlv_len);
+ printf("\n\t Oper_Version: %d", *tptr);
+ printf("\n\t Max_Version: %d", *(tptr+1));
+ printf("\n\t Sequence Number: %d", EXTRACT_32BITS(tptr+2));
+ printf("\n\t Acknowledgement Number: %d",
+ EXTRACT_32BITS(tptr+6));
+ break;
+ case LLDP_DCBX_PRIORITY_GROUPS_TLV:
+ if (tlv_len < 17) {
+ goto trunc;
+ }
+ printf("\n\t Feature - Priority Group (type 0x%x, length %d)",
+ LLDP_DCBX_PRIORITY_GROUPS_TLV, tlv_len);
+ printf("\n\t Oper_Version: %d", *tptr);
+ printf("\n\t Max_Version: %d", *(tptr+1));
+ printf("\n\t Info block(0x%02X): ", *(tptr+2));
+ tval = *(tptr+2);
+ printf("Enable bit: %d, Willing bit: %d, Error Bit: %d",
+ (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0,
+ (tval & 0x20) ? 1 : 0);
+ printf("\n\t SubType: %d", *(tptr+3));
+ printf("\n\t Priority Allocation");
+
+ pgval = EXTRACT_32BITS(tptr+4);
+ for (i = 0; i <= 7; i++) {
+ tval = *(tptr+4+(i/2));
+ printf("\n\t PgId_%d: %d",
+ i, (pgval >> (28-4*i)) & 0xF);
+ }
+ printf("\n\t Priority Group Allocation");
+ for (i = 0; i <= 7; i++)
+ printf("\n\t Pg percentage[%d]: %d", i, *(tptr+8+i));
+ printf("\n\t NumTCsSupported: %d", *(tptr+8+8));
+ break;
+ case LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV:
+ if (tlv_len < 6) {
+ goto trunc;
+ }
+ printf("\n\t Feature - Priority Flow Control");
+ printf(" (type 0x%x, length %d)",
+ LLDP_DCBX_PRIORITY_FLOW_CONTROL_TLV, tlv_len);
+ printf("\n\t Oper_Version: %d", *tptr);
+ printf("\n\t Max_Version: %d", *(tptr+1));
+ printf("\n\t Info block(0x%02X): ", *(tptr+2));
+ tval = *(tptr+2);
+ printf("Enable bit: %d, Willing bit: %d, Error Bit: %d",
+ (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0,
+ (tval & 0x20) ? 1 : 0);
+ printf("\n\t SubType: %d", *(tptr+3));
+ tval = *(tptr+4);
+ printf("\n\t PFC Config (0x%02X)", *(tptr+4));
+ for (i = 0; i <= 7; i++)
+ printf("\n\t Priority Bit %d: %s",
+ i, (tval & (1 << i)) ? "Enabled" : "Disabled");
+ printf("\n\t NumTCPFCSupported: %d", *(tptr+5));
+ break;
+ case LLDP_DCBX_APPLICATION_TLV:
+ if (tlv_len < 4) {
+ goto trunc;
+ }
+ printf("\n\t Feature - Application (type 0x%x, length %d)",
+ LLDP_DCBX_APPLICATION_TLV, tlv_len);
+ printf("\n\t Oper_Version: %d", *tptr);
+ printf("\n\t Max_Version: %d", *(tptr+1));
+ printf("\n\t Info block(0x%02X): ", *(tptr+2));
+ tval = *(tptr+2);
+ printf("Enable bit: %d, Willing bit: %d, Error Bit: %d",
+ (tval & 0x80) ? 1 : 0, (tval & 0x40) ? 1 : 0,
+ (tval & 0x20) ? 1 : 0);
+ printf("\n\t SubType: %d", *(tptr+3));
+ tval = tlv_len - 4;
+ mptr = tptr + 4;
+ while (tval >= 6) {
+ printf("\n\t Application Value");
+ printf("\n\t Application Protocol ID: 0x%04x",
+ EXTRACT_16BITS(mptr));
+ uval = EXTRACT_24BITS(mptr+2);
+ printf("\n\t SF (0x%x) Application Protocol ID is %s",
+ (uval >> 22),
+ (uval >> 22) ? "Socket Number" : "L2 EtherType");
+ printf("\n\t OUI: 0x%06x", uval & 0x3fffff);
+ printf("\n\t User Priority Map: 0x%02x", *(mptr+5));
+ tval = tval - 6;
+ mptr = mptr + 6;
+ }
+ break;
+ default:
+ hexdump = TRUE;
+ break;
+ }
+
+ /* do we also want to see a hex dump ? */
+ if (vflag > 1 || (vflag && hexdump)) {
+ print_unknown_data(tptr,"\n\t ", tlv_len);
+ }
+
+ tlen -= tlv_len;
+ tptr += tlv_len;
+ }
+
+ trunc:
+ return hexdump;
+}
+
+static char *
+lldp_network_addr_print(const u_char *tptr, u_int len) {
+
+ u_int8_t af;
+ static char buf[BUFSIZE];
+ const char * (*pfunc)(const u_char *);
+
+ if (len < 1)
+ return NULL;
+ len--;
+ af = *tptr;
+ switch (af) {
+ case AFNUM_INET:
+ if (len < 4)
+ return NULL;
+ pfunc = getname;
+ break;
+#ifdef INET6
+ case AFNUM_INET6:
+ if (len < 16)
+ return NULL;
+ pfunc = getname6;
+ break;
+#endif
+ case AFNUM_802:
+ if (len < 6)
+ return NULL;
+ pfunc = etheraddr_string;
+ break;
+ default:
+ pfunc = NULL;
+ break;
+ }
+
+ if (!pfunc) {
+ snprintf(buf, sizeof(buf), "AFI %s (%u), no AF printer !",
+ tok2str(af_values, "Unknown", af), af);
+ } else {
+ snprintf(buf, sizeof(buf), "AFI %s (%u): %s",
+ tok2str(af_values, "Unknown", af), af, (*pfunc)(tptr+1));
+ }
+
+ return buf;
+}
+
+static int
+lldp_mgmt_addr_tlv_print(const u_char *pptr, u_int len) {
+
+ u_int8_t mgmt_addr_len, intf_num_subtype, oid_len;
+ const u_char *tptr;
+ u_int tlen;
+ char *mgmt_addr;
+
+ tlen = len;
+ tptr = pptr;
+
+ if (tlen < 1) {
+ return 0;
+ }
+ mgmt_addr_len = *tptr++;
+ tlen--;
+
+ if (tlen < mgmt_addr_len) {
+ return 0;
+ }
+
+ mgmt_addr = lldp_network_addr_print(tptr, mgmt_addr_len);
+ if (mgmt_addr == NULL) {
+ return 0;
+ }
+ printf("\n\t Management Address length %u, %s",
+ mgmt_addr_len, mgmt_addr);
+ tptr += mgmt_addr_len;
+ tlen -= mgmt_addr_len;
+
+ if (tlen < LLDP_INTF_NUM_LEN) {
+ return 0;
+ }
+
+ intf_num_subtype = *tptr;
+ printf("\n\t %s Interface Numbering (%u): %u",
+ tok2str(lldp_intf_numb_subtype_values, "Unknown", intf_num_subtype),
+ intf_num_subtype,
+ EXTRACT_32BITS(tptr+1));
+
+ tptr += LLDP_INTF_NUM_LEN;
+ tlen -= LLDP_INTF_NUM_LEN;
+
+ /*
+ * The OID is optional.
+ */
+ if (tlen) {
+ oid_len = *tptr;
+
+ if (tlen < oid_len) {
+ return 0;
+ }
+ if (oid_len) {
+ printf("\n\t OID length %u", oid_len);
+ safeputs((const char *)tptr+1, oid_len);
+ }
+ }
+
+ return 1;
+}
+
+void
+lldp_print(register const u_char *pptr, register u_int len) {
+
+ u_int8_t subtype;
+ u_int16_t tlv, cap, ena_cap;
+ u_int oui, tlen, hexdump, tlv_type, tlv_len;
+ const u_char *tptr;
+ char *network_addr;
+
+ tptr = pptr;
+ tlen = len;
+
+ printf("LLDP, length %u", len);
+
+ while (tlen >= sizeof(tlv)) {
+
+ TCHECK2(*tptr, sizeof(tlv));
+
+ tlv = EXTRACT_16BITS(tptr);
+
+ tlv_type = LLDP_EXTRACT_TYPE(tlv);
+ tlv_len = LLDP_EXTRACT_LEN(tlv);
+ hexdump = FALSE;
+
+ tlen -= sizeof(tlv);
+ tptr += sizeof(tlv);
+
+ if (vflag) {
+ printf("\n\t%s TLV (%u), length %u",
+ tok2str(lldp_tlv_values, "Unknown", tlv_type),
+ tlv_type, tlv_len);
+ }
+
+ /* infinite loop check */
+ if (!tlv_type || !tlv_len) {
+ break;
+ }
+
+ TCHECK2(*tptr, tlv_len);
+ if (tlen < tlv_len) {
+ goto trunc;
+ }
+
+ switch (tlv_type) {
+
+ case LLDP_CHASSIS_ID_TLV:
+ if (vflag) {
+ if (tlv_len < 2) {
+ goto trunc;
+ }
+ subtype = *tptr;
+ printf("\n\t Subtype %s (%u): ",
+ tok2str(lldp_chassis_subtype_values, "Unknown", subtype),
+ subtype);
+
+ switch (subtype) {
+ case LLDP_CHASSIS_MAC_ADDR_SUBTYPE:
+ if (tlv_len < 1+6) {
+ goto trunc;
+ }
+ printf("%s", etheraddr_string(tptr+1));
+ break;
+
+ case LLDP_CHASSIS_INTF_NAME_SUBTYPE: /* fall through */
+ case LLDP_CHASSIS_LOCAL_SUBTYPE:
+ case LLDP_CHASSIS_CHASSIS_COMP_SUBTYPE:
+ case LLDP_CHASSIS_INTF_ALIAS_SUBTYPE:
+ case LLDP_CHASSIS_PORT_COMP_SUBTYPE:
+ safeputs((const char *)tptr+1, tlv_len-1);
+ break;
+
+ case LLDP_CHASSIS_NETWORK_ADDR_SUBTYPE:
+ network_addr = lldp_network_addr_print(tptr+1, tlv_len-1);
+ if (network_addr == NULL) {
+ goto trunc;
+ }
+ printf("%s", network_addr);
+ break;
+
+ default:
+ hexdump = TRUE;
+ break;
+ }
+ }
+ break;
+
+ case LLDP_PORT_ID_TLV:
+ if (vflag) {
+ if (tlv_len < 2) {
+ goto trunc;
+ }
+ subtype = *tptr;
+ printf("\n\t Subtype %s (%u): ",
+ tok2str(lldp_port_subtype_values, "Unknown", subtype),
+ subtype);
+
+ switch (subtype) {
+ case LLDP_PORT_MAC_ADDR_SUBTYPE:
+ if (tlv_len < 1+6) {
+ goto trunc;
+ }
+ printf("%s", etheraddr_string(tptr+1));
+ break;
+
+ case LLDP_PORT_INTF_NAME_SUBTYPE: /* fall through */
+ case LLDP_PORT_LOCAL_SUBTYPE:
+ case LLDP_PORT_AGENT_CIRC_ID_SUBTYPE:
+ case LLDP_PORT_INTF_ALIAS_SUBTYPE:
+ case LLDP_PORT_PORT_COMP_SUBTYPE:
+ safeputs((const char *)tptr+1, tlv_len-1);
+ break;
+
+ case LLDP_PORT_NETWORK_ADDR_SUBTYPE:
+ network_addr = lldp_network_addr_print(tptr+1, tlv_len-1);
+ if (network_addr == NULL) {
+ goto trunc;
+ }
+ printf("%s", network_addr);
+ break;
+
+ default:
+ hexdump = TRUE;
+ break;
+ }
+ }
+ break;
+
+ case LLDP_TTL_TLV:
+ if (vflag) {
+ if (tlv_len < 2) {
+ goto trunc;
+ }
+ printf(": TTL %us", EXTRACT_16BITS(tptr));
+ }
+ break;
+
+ case LLDP_PORT_DESCR_TLV:
+ if (vflag) {
+ printf(": ");
+ safeputs((const char *)tptr, tlv_len);
+ }
+ break;
+
+ case LLDP_SYSTEM_NAME_TLV:
+ /*
+ * The system name is also print in non-verbose mode
+ * similar to the CDP printer.
+ */
+ printf(": ");
+ safeputs((const char *)tptr, tlv_len);
+ break;
+
+ case LLDP_SYSTEM_DESCR_TLV:
+ if (vflag) {
+ printf("\n\t ");
+ safeputs((const char *)tptr, tlv_len);
+ }
+ break;
+
+ case LLDP_SYSTEM_CAP_TLV:
+ if (vflag) {
+ /*
+ * XXX - IEEE Std 802.1AB-2009 says the first octet
+ * if a chassis ID subtype, with the system
+ * capabilities and enabled capabilities following
+ * it.
+ */
+ if (tlv_len < 4) {
+ goto trunc;
+ }
+ cap = EXTRACT_16BITS(tptr);
+ ena_cap = EXTRACT_16BITS(tptr+2);
+ printf("\n\t System Capabilities [%s] (0x%04x)",
+ bittok2str(lldp_cap_values, "none", cap), cap);
+ printf("\n\t Enabled Capabilities [%s] (0x%04x)",
+ bittok2str(lldp_cap_values, "none", ena_cap), ena_cap);
+ }
+ break;
+
+ case LLDP_MGMT_ADDR_TLV:
+ if (vflag) {
+ if (!lldp_mgmt_addr_tlv_print(tptr, tlv_len)) {
+ goto trunc;
+ }
+ }
+ break;
+
+ case LLDP_PRIVATE_TLV:
+ if (vflag) {
+ if (tlv_len < 3) {
+ goto trunc;
+ }
+ oui = EXTRACT_24BITS(tptr);
+ printf(": OUI %s (0x%06x)", tok2str(oui_values, "Unknown", oui), oui);
+
+ switch (oui) {
+ case OUI_IEEE_8021_PRIVATE:
+ hexdump = lldp_private_8021_print(tptr, tlv_len);
+ break;
+ case OUI_IEEE_8023_PRIVATE:
+ hexdump = lldp_private_8023_print(tptr, tlv_len);
+ break;
+ case OUI_TIA:
+ hexdump = lldp_private_tia_print(tptr, tlv_len);
+ break;
+ case OUI_DCBX:
+ hexdump = lldp_private_dcbx_print(tptr, tlv_len);
+ break;
+ default:
+ hexdump = TRUE;
+ break;
+ }
+ }
+ break;
+
+ default:
+ hexdump = TRUE;
+ break;
+ }
+
+ /* do we also want to see a hex dump ? */
+ if (vflag > 1 || (vflag && hexdump)) {
+ print_unknown_data(tptr,"\n\t ", tlv_len);
+ }
+
+ tlen -= tlv_len;
+ tptr += tlv_len;
+ }
+ return;
+ trunc:
+ printf("\n\t[|LLDP]");
+}
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-lmp.c b/freebsd/contrib/tcpdump/print-lmp.c
new file mode 100644
index 00000000..d6774409
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-lmp.c
@@ -0,0 +1,885 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Support for the Link Management Protocol as per rfc 4204.
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ * Support for LMP service discovery extensions (defined by UNI 1.0) added
+ * by Manu Pathak (mapathak@cisco.com), May 2005
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-lmp.c,v 1.11 2007-08-02 17:32:49 hannes Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+#include "gmpls.h"
+
+/*
+ * LMP common header
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Vers | (Reserved) | Flags | Msg Type |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | LMP Length | (Reserved) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+struct lmp_common_header {
+ u_int8_t version_res[2];
+ u_int8_t flags;
+ u_int8_t msg_type;
+ u_int8_t length[2];
+ u_int8_t reserved[2];
+};
+
+#define LMP_VERSION 1
+#define LMP_EXTRACT_VERSION(x) (((x)&0xf0)>>4)
+
+static const struct tok lmp_header_flag_values[] = {
+ { 0x01, "Control Channel Down"},
+ { 0x02, "LMP restart"},
+ { 0, NULL}
+};
+
+static const struct tok lmp_obj_te_link_flag_values[] = {
+ { 0x01, "Fault Management Supported"},
+ { 0x02, "Link Verification Supported"},
+ { 0, NULL}
+};
+
+static const struct tok lmp_obj_data_link_flag_values[] = {
+ { 0x01, "Data Link Port"},
+ { 0x02, "Allocated for user traffic"},
+ { 0x04, "Failed link"},
+ { 0, NULL}
+};
+
+static const struct tok lmp_obj_channel_status_values[] = {
+ { 1, "Signal Okay"},
+ { 2, "Signal Degraded"},
+ { 3, "Signal Fail"},
+ { 0, NULL}
+};
+
+static const struct tok lmp_obj_begin_verify_flag_values[] = {
+ { 0x0001, "Verify all links"},
+ { 0x0002, "Data link type"},
+ { 0, NULL}
+};
+
+static const struct tok lmp_obj_begin_verify_error_values[] = {
+ { 0x01, "Link Verification Procedure Not supported"},
+ { 0x02, "Unwilling to verify"},
+ { 0x04, "Unsupported verification transport mechanism"},
+ { 0x08, "Link-Id configuration error"},
+ { 0x10, "Unknown object c-type"},
+ { 0, NULL}
+};
+
+static const struct tok lmp_obj_link_summary_error_values[] = {
+ { 0x01, "Unacceptable non-negotiable LINK-SUMMARY parameters"},
+ { 0x02, "Renegotiate LINK-SUMMARY parameters"},
+ { 0x04, "Invalid TE-LINK Object"},
+ { 0x08, "Invalid DATA-LINK Object"},
+ { 0x10, "Unknown TE-LINK Object c-type"},
+ { 0x20, "Unknown DATA-LINK Object c-type"},
+ { 0, NULL}
+};
+
+/* Service Config Supported Protocols Flags */
+static const struct tok lmp_obj_service_config_sp_flag_values[] = {
+ { 0x01, "RSVP Supported"},
+ { 0x02, "LDP Supported"},
+ { 0, NULL}
+};
+
+/* Service Config Client Port Service Attribute Transparency Flags */
+static const struct tok lmp_obj_service_config_cpsa_tp_flag_values[] = {
+ { 0x01, "Path/VC Overhead Transparency Supported"},
+ { 0x02, "Line/MS Overhead Transparency Supported"},
+ { 0x04, "Section/RS Overhead Transparency Supported"},
+ { 0, NULL}
+};
+
+/* Service Config Client Port Service Attribute Contiguous Concatenation Types Flags */
+static const struct tok lmp_obj_service_config_cpsa_cct_flag_values[] = {
+ { 0x01, "Contiguous Concatenation Types Supported"},
+ { 0, NULL}
+};
+
+/* Service Config Network Service Attributes Transparency Flags */
+static const struct tok lmp_obj_service_config_nsa_transparency_flag_values[] = {
+ { 0x01, "Standard SOH/RSOH Transparency Supported"},
+ { 0x02, "Standard LOH/MSOH Transparency Supported"},
+ { 0, NULL}
+};
+
+/* Service Config Network Service Attributes TCM Monitoring Flags */
+static const struct tok lmp_obj_service_config_nsa_tcm_flag_values[] = {
+ { 0x01, "Transparent Tandem Connection Monitoring Supported"},
+ { 0, NULL}
+};
+
+/* Network Service Attributes Network Diversity Flags */
+static const struct tok lmp_obj_service_config_nsa_network_diversity_flag_values[] = {
+ { 0x01, "Node Diversity Supported"},
+ { 0x02, "Link Diversity Supported"},
+ { 0x04, "SRLG Diversity Supported"},
+ { 0, NULL}
+};
+
+#define LMP_MSGTYPE_CONFIG 1
+#define LMP_MSGTYPE_CONFIG_ACK 2
+#define LMP_MSGTYPE_CONFIG_NACK 3
+#define LMP_MSGTYPE_HELLO 4
+#define LMP_MSGTYPE_VERIFY_BEGIN 5
+#define LMP_MSGTYPE_VERIFY_BEGIN_ACK 6
+#define LMP_MSGTYPE_VERIFY_BEGIN_NACK 7
+#define LMP_MSGTYPE_VERIFY_END 8
+#define LMP_MSGTYPE_VERIFY_END_ACK 9
+#define LMP_MSGTYPE_TEST 10
+#define LMP_MSGTYPE_TEST_STATUS_SUCCESS 11
+#define LMP_MSGTYPE_TEST_STATUS_FAILURE 12
+#define LMP_MSGTYPE_TEST_STATUS_ACK 13
+#define LMP_MSGTYPE_LINK_SUMMARY 14
+#define LMP_MSGTYPE_LINK_SUMMARY_ACK 15
+#define LMP_MSGTYPE_LINK_SUMMARY_NACK 16
+#define LMP_MSGTYPE_CHANNEL_STATUS 17
+#define LMP_MSGTYPE_CHANNEL_STATUS_ACK 18
+#define LMP_MSGTYPE_CHANNEL_STATUS_REQ 19
+#define LMP_MSGTYPE_CHANNEL_STATUS_RESP 20
+/* LMP Service Discovery message types defined by UNI 1.0 */
+#define LMP_MSGTYPE_SERVICE_CONFIG 50
+#define LMP_MSGTYPE_SERVICE_CONFIG_ACK 51
+#define LMP_MSGTYPE_SERVICE_CONFIG_NACK 52
+
+static const struct tok lmp_msg_type_values[] = {
+ { LMP_MSGTYPE_CONFIG, "Config"},
+ { LMP_MSGTYPE_CONFIG_ACK, "Config ACK"},
+ { LMP_MSGTYPE_CONFIG_NACK, "Config NACK"},
+ { LMP_MSGTYPE_HELLO, "Hello"},
+ { LMP_MSGTYPE_VERIFY_BEGIN, "Begin Verify"},
+ { LMP_MSGTYPE_VERIFY_BEGIN_ACK, "Begin Verify ACK"},
+ { LMP_MSGTYPE_VERIFY_BEGIN_NACK, "Begin Verify NACK"},
+ { LMP_MSGTYPE_VERIFY_END, "End Verify"},
+ { LMP_MSGTYPE_VERIFY_END_ACK, "End Verify ACK"},
+ { LMP_MSGTYPE_TEST, "Test"},
+ { LMP_MSGTYPE_TEST_STATUS_SUCCESS, "Test Status Success"},
+ { LMP_MSGTYPE_TEST_STATUS_FAILURE, "Test Status Failure"},
+ { LMP_MSGTYPE_TEST_STATUS_ACK, "Test Status ACK"},
+ { LMP_MSGTYPE_LINK_SUMMARY, "Link Summary"},
+ { LMP_MSGTYPE_LINK_SUMMARY_ACK, "Link Summary ACK"},
+ { LMP_MSGTYPE_LINK_SUMMARY_NACK, "Link Summary NACK"},
+ { LMP_MSGTYPE_CHANNEL_STATUS, "Channel Status"},
+ { LMP_MSGTYPE_CHANNEL_STATUS_ACK, "Channel Status ACK"},
+ { LMP_MSGTYPE_CHANNEL_STATUS_REQ, "Channel Status Request"},
+ { LMP_MSGTYPE_CHANNEL_STATUS_RESP, "Channel Status Response"},
+ { LMP_MSGTYPE_SERVICE_CONFIG, "Service Config"},
+ { LMP_MSGTYPE_SERVICE_CONFIG_ACK, "Service Config ACK"},
+ { LMP_MSGTYPE_SERVICE_CONFIG_NACK, "Service Config NACK"},
+ { 0, NULL}
+};
+
+/*
+ * LMP object header
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |N| C-Type | Class | Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * // (object contents) //
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+struct lmp_object_header {
+ u_int8_t ctype;
+ u_int8_t class_num;
+ u_int8_t length[2];
+};
+
+#define LMP_OBJ_CC_ID 1
+#define LMP_OBJ_NODE_ID 2
+#define LMP_OBJ_LINK_ID 3
+#define LMP_OBJ_INTERFACE_ID 4
+#define LMP_OBJ_MESSAGE_ID 5
+#define LMP_OBJ_CONFIG 6
+#define LMP_OBJ_HELLO 7
+#define LMP_OBJ_VERIFY_BEGIN 8
+#define LMP_OBJ_VERIFY_BEGIN_ACK 9
+#define LMP_OBJ_VERIFY_ID 10
+#define LMP_OBJ_TE_LINK 11
+#define LMP_OBJ_DATA_LINK 12
+#define LMP_OBJ_CHANNEL_STATUS 13
+#define LMP_OBJ_CHANNEL_STATUS_REQ 14
+#define LMP_OBJ_ERROR_CODE 20
+
+#define LMP_OBJ_SERVICE_CONFIG 51 /* defined in UNI 1.0 */
+
+static const struct tok lmp_obj_values[] = {
+ { LMP_OBJ_CC_ID, "Control Channel ID" },
+ { LMP_OBJ_NODE_ID, "Node ID" },
+ { LMP_OBJ_LINK_ID, "Link ID" },
+ { LMP_OBJ_INTERFACE_ID, "Interface ID" },
+ { LMP_OBJ_MESSAGE_ID, "Message ID" },
+ { LMP_OBJ_CONFIG, "Configuration" },
+ { LMP_OBJ_HELLO, "Hello" },
+ { LMP_OBJ_VERIFY_BEGIN, "Verify Begin" },
+ { LMP_OBJ_VERIFY_BEGIN_ACK, "Verify Begin ACK" },
+ { LMP_OBJ_VERIFY_ID, "Verify ID" },
+ { LMP_OBJ_TE_LINK, "TE Link" },
+ { LMP_OBJ_DATA_LINK, "Data Link" },
+ { LMP_OBJ_CHANNEL_STATUS, "Channel Status" },
+ { LMP_OBJ_CHANNEL_STATUS_REQ, "Channel Status Request" },
+ { LMP_OBJ_ERROR_CODE, "Error Code" },
+ { LMP_OBJ_SERVICE_CONFIG, "Service Config" },
+
+ { 0, NULL}
+};
+
+#define INT_SWITCHING_TYPE_SUBOBJ 1
+#define WAVELENGTH_SUBOBJ 2
+
+static const struct tok lmp_data_link_subobj[] = {
+ { INT_SWITCHING_TYPE_SUBOBJ, "Interface Switching Type" },
+ { WAVELENGTH_SUBOBJ , "Wavelength" },
+ { 0, NULL}
+};
+
+#define LMP_CTYPE_IPV4 1
+#define LMP_CTYPE_IPV6 2
+
+#define LMP_CTYPE_LOC 1
+#define LMP_CTYPE_RMT 2
+#define LMP_CTYPE_UNMD 3
+
+#define LMP_CTYPE_IPV4_LOC 1
+#define LMP_CTYPE_IPV4_RMT 2
+#define LMP_CTYPE_IPV6_LOC 3
+#define LMP_CTYPE_IPV6_RMT 4
+#define LMP_CTYPE_UNMD_LOC 5
+#define LMP_CTYPE_UNMD_RMT 6
+
+#define LMP_CTYPE_1 1
+#define LMP_CTYPE_2 2
+
+#define LMP_CTYPE_HELLO_CONFIG 1
+#define LMP_CTYPE_HELLO 1
+
+#define LMP_CTYPE_BEGIN_VERIFY_ERROR 1
+#define LMP_CTYPE_LINK_SUMMARY_ERROR 2
+
+/* C-Types for Service Config Object */
+#define LMP_CTYPE_SERVICE_CONFIG_SP 1
+#define LMP_CTYPE_SERVICE_CONFIG_CPSA 2
+#define LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM 3
+#define LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY 4
+
+/*
+ * Different link types allowed in the Client Port Service Attributes
+ * subobject defined for LMP Service Discovery in the UNI 1.0 spec
+ */
+#define LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH 5 /* UNI 1.0 Sec 9.4.2 */
+#define LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET 6 /* UNI 1.0 Sec 9.4.2 */
+
+/*
+ * the ctypes are not globally unique so for
+ * translating it to strings we build a table based
+ * on objects offsetted by the ctype
+ */
+
+static const struct tok lmp_ctype_values[] = {
+ { 256*LMP_OBJ_CC_ID+LMP_CTYPE_LOC, "Local" },
+ { 256*LMP_OBJ_CC_ID+LMP_CTYPE_RMT, "Remote" },
+ { 256*LMP_OBJ_NODE_ID+LMP_CTYPE_LOC, "Local" },
+ { 256*LMP_OBJ_NODE_ID+LMP_CTYPE_RMT, "Remote" },
+ { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV4_LOC, "IPv4 Local" },
+ { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV4_RMT, "IPv4 Remote" },
+ { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV6_LOC, "IPv6 Local" },
+ { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_IPV6_RMT, "IPv6 Remote" },
+ { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_UNMD_LOC, "Unnumbered Local" },
+ { 256*LMP_OBJ_LINK_ID+LMP_CTYPE_UNMD_RMT, "Unnumbered Remote" },
+ { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV4_LOC, "IPv4 Local" },
+ { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV4_RMT, "IPv4 Remote" },
+ { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV6_LOC, "IPv6 Local" },
+ { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_IPV6_RMT, "IPv6 Remote" },
+ { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_UNMD_LOC, "Unnumbered Local" },
+ { 256*LMP_OBJ_INTERFACE_ID+LMP_CTYPE_UNMD_RMT, "Unnumbered Remote" },
+ { 256*LMP_OBJ_MESSAGE_ID+LMP_CTYPE_1, "1" },
+ { 256*LMP_OBJ_MESSAGE_ID+LMP_CTYPE_2, "2" },
+ { 256*LMP_OBJ_CONFIG+LMP_CTYPE_1, "1" },
+ { 256*LMP_OBJ_HELLO+LMP_CTYPE_1, "1" },
+ { 256*LMP_OBJ_VERIFY_BEGIN+LMP_CTYPE_1, "1" },
+ { 256*LMP_OBJ_VERIFY_BEGIN_ACK+LMP_CTYPE_1, "1" },
+ { 256*LMP_OBJ_VERIFY_ID+LMP_CTYPE_1, "1" },
+ { 256*LMP_OBJ_TE_LINK+LMP_CTYPE_IPV4, "IPv4" },
+ { 256*LMP_OBJ_TE_LINK+LMP_CTYPE_IPV6, "IPv6" },
+ { 256*LMP_OBJ_TE_LINK+LMP_CTYPE_UNMD, "Unnumbered" },
+ { 256*LMP_OBJ_DATA_LINK+LMP_CTYPE_IPV4, "IPv4" },
+ { 256*LMP_OBJ_DATA_LINK+LMP_CTYPE_IPV6, "IPv6" },
+ { 256*LMP_OBJ_DATA_LINK+LMP_CTYPE_UNMD, "Unnumbered" },
+ { 256*LMP_OBJ_CHANNEL_STATUS+LMP_CTYPE_IPV4, "IPv4" },
+ { 256*LMP_OBJ_CHANNEL_STATUS+LMP_CTYPE_IPV6, "IPv6" },
+ { 256*LMP_OBJ_CHANNEL_STATUS+LMP_CTYPE_UNMD, "Unnumbered" },
+ { 256*LMP_OBJ_CHANNEL_STATUS_REQ+LMP_CTYPE_IPV4, "IPv4" },
+ { 256*LMP_OBJ_CHANNEL_STATUS_REQ+LMP_CTYPE_IPV6, "IPv6" },
+ { 256*LMP_OBJ_CHANNEL_STATUS_REQ+LMP_CTYPE_UNMD, "Unnumbered" },
+ { 256*LMP_OBJ_ERROR_CODE+LMP_CTYPE_1, "1" },
+ { 256*LMP_OBJ_ERROR_CODE+LMP_CTYPE_2, "2" },
+ { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_SP, "1" },
+ { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_CPSA, "2" },
+ { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM, "3" },
+ { 256*LMP_OBJ_SERVICE_CONFIG+LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY, "4" },
+ { 0, NULL}
+};
+
+void
+lmp_print(register const u_char *pptr, register u_int len) {
+
+ const struct lmp_common_header *lmp_com_header;
+ const struct lmp_object_header *lmp_obj_header;
+ const u_char *tptr,*obj_tptr;
+ int tlen,lmp_obj_len,lmp_obj_ctype,obj_tlen;
+ int hexdump;
+ int offset,subobj_type,subobj_len,total_subobj_len;
+ int link_type;
+
+ union { /* int to float conversion buffer */
+ float f;
+ u_int32_t i;
+ } bw;
+
+ tptr=pptr;
+ lmp_com_header = (const struct lmp_common_header *)pptr;
+ TCHECK(*lmp_com_header);
+
+ /*
+ * Sanity checking of the header.
+ */
+ if (LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]) != LMP_VERSION) {
+ printf("LMP version %u packet not supported",
+ LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]));
+ return;
+ }
+
+ /* in non-verbose mode just lets print the basic Message Type*/
+ if (vflag < 1) {
+ printf("LMPv%u %s Message, length: %u",
+ LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]),
+ tok2str(lmp_msg_type_values, "unknown (%u)",lmp_com_header->msg_type),
+ len);
+ return;
+ }
+
+ /* ok they seem to want to know everything - lets fully decode it */
+
+ tlen=EXTRACT_16BITS(lmp_com_header->length);
+
+ printf("\n\tLMPv%u, msg-type: %s, Flags: [%s], length: %u",
+ LMP_EXTRACT_VERSION(lmp_com_header->version_res[0]),
+ tok2str(lmp_msg_type_values, "unknown, type: %u",lmp_com_header->msg_type),
+ bittok2str(lmp_header_flag_values,"none",lmp_com_header->flags),
+ tlen);
+
+ tptr+=sizeof(const struct lmp_common_header);
+ tlen-=sizeof(const struct lmp_common_header);
+
+ while(tlen>0) {
+ /* did we capture enough for fully decoding the object header ? */
+ if (!TTEST2(*tptr, sizeof(struct lmp_object_header)))
+ goto trunc;
+
+ lmp_obj_header = (const struct lmp_object_header *)tptr;
+ lmp_obj_len=EXTRACT_16BITS(lmp_obj_header->length);
+ lmp_obj_ctype=(lmp_obj_header->ctype)&0x7f;
+
+ if(lmp_obj_len % 4 || lmp_obj_len < 4)
+ return;
+
+ printf("\n\t %s Object (%u), Class-Type: %s (%u) Flags: [%snegotiable], length: %u",
+ tok2str(lmp_obj_values,
+ "Unknown",
+ lmp_obj_header->class_num),
+ lmp_obj_header->class_num,
+ tok2str(lmp_ctype_values,
+ "Unknown",
+ ((lmp_obj_header->class_num)<<8)+lmp_obj_ctype),
+ lmp_obj_ctype,
+ (lmp_obj_header->ctype)&0x80 ? "" : "non-",
+ lmp_obj_len);
+
+ obj_tptr=tptr+sizeof(struct lmp_object_header);
+ obj_tlen=lmp_obj_len-sizeof(struct lmp_object_header);
+
+ /* did we capture enough for fully decoding the object ? */
+ if (!TTEST2(*tptr, lmp_obj_len))
+ goto trunc;
+ hexdump=FALSE;
+
+ switch(lmp_obj_header->class_num) {
+
+ case LMP_OBJ_CC_ID:
+ switch(lmp_obj_ctype) {
+ case LMP_CTYPE_LOC:
+ case LMP_CTYPE_RMT:
+ printf("\n\t Control Channel ID: %u (0x%08x)",
+ EXTRACT_32BITS(obj_tptr),
+ EXTRACT_32BITS(obj_tptr));
+ break;
+
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case LMP_OBJ_LINK_ID:
+ case LMP_OBJ_INTERFACE_ID:
+ switch(lmp_obj_ctype) {
+ case LMP_CTYPE_IPV4_LOC:
+ case LMP_CTYPE_IPV4_RMT:
+ printf("\n\t IPv4 Link ID: %s (0x%08x)",
+ ipaddr_string(obj_tptr),
+ EXTRACT_32BITS(obj_tptr));
+ break;
+#ifdef INET6
+ case LMP_CTYPE_IPV6_LOC:
+ case LMP_CTYPE_IPV6_RMT:
+ printf("\n\t IPv6 Link ID: %s (0x%08x)",
+ ip6addr_string(obj_tptr),
+ EXTRACT_32BITS(obj_tptr));
+ break;
+#endif
+ case LMP_CTYPE_UNMD_LOC:
+ case LMP_CTYPE_UNMD_RMT:
+ printf("\n\t Link ID: %u (0x%08x)",
+ EXTRACT_32BITS(obj_tptr),
+ EXTRACT_32BITS(obj_tptr));
+ break;
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case LMP_OBJ_MESSAGE_ID:
+ switch(lmp_obj_ctype) {
+ case LMP_CTYPE_1:
+ printf("\n\t Message ID: %u (0x%08x)",
+ EXTRACT_32BITS(obj_tptr),
+ EXTRACT_32BITS(obj_tptr));
+ break;
+ case LMP_CTYPE_2:
+ printf("\n\t Message ID Ack: %u (0x%08x)",
+ EXTRACT_32BITS(obj_tptr),
+ EXTRACT_32BITS(obj_tptr));
+ break;
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case LMP_OBJ_NODE_ID:
+ switch(lmp_obj_ctype) {
+ case LMP_CTYPE_LOC:
+ case LMP_CTYPE_RMT:
+ printf("\n\t Node ID: %s (0x%08x)",
+ ipaddr_string(obj_tptr),
+ EXTRACT_32BITS(obj_tptr));
+ break;
+
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case LMP_OBJ_CONFIG:
+ switch(lmp_obj_ctype) {
+ case LMP_CTYPE_HELLO_CONFIG:
+ printf("\n\t Hello Interval: %u\n\t Hello Dead Interval: %u",
+ EXTRACT_16BITS(obj_tptr),
+ EXTRACT_16BITS(obj_tptr+2));
+ break;
+
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case LMP_OBJ_HELLO:
+ switch(lmp_obj_ctype) {
+ case LMP_CTYPE_HELLO:
+ printf("\n\t Tx Seq: %u, Rx Seq: %u",
+ EXTRACT_32BITS(obj_tptr),
+ EXTRACT_32BITS(obj_tptr+4));
+ break;
+
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case LMP_OBJ_TE_LINK:
+ printf("\n\t Flags: [%s]",
+ bittok2str(lmp_obj_te_link_flag_values,
+ "none",
+ EXTRACT_16BITS(obj_tptr)>>8));
+
+ switch(lmp_obj_ctype) {
+ case LMP_CTYPE_IPV4:
+ printf("\n\t Local Link-ID: %s (0x%08x) \
+ \n\t Remote Link-ID: %s (0x%08x)",
+ ipaddr_string(obj_tptr+4),
+ EXTRACT_32BITS(obj_tptr+4),
+ ipaddr_string(obj_tptr+8),
+ EXTRACT_32BITS(obj_tptr+8));
+ break;
+
+#ifdef INET6
+ case LMP_CTYPE_IPV6:
+#endif
+ case LMP_CTYPE_UNMD:
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case LMP_OBJ_DATA_LINK:
+ printf("\n\t Flags: [%s]",
+ bittok2str(lmp_obj_data_link_flag_values,
+ "none",
+ EXTRACT_16BITS(obj_tptr)>>8));
+
+ switch(lmp_obj_ctype) {
+ case LMP_CTYPE_IPV4:
+ case LMP_CTYPE_UNMD:
+ printf("\n\t Local Interface ID: %s (0x%08x) \
+ \n\t Remote Interface ID: %s (0x%08x)",
+ ipaddr_string(obj_tptr+4),
+ EXTRACT_32BITS(obj_tptr+4),
+ ipaddr_string(obj_tptr+8),
+ EXTRACT_32BITS(obj_tptr+8));
+
+ total_subobj_len = lmp_obj_len - 16;
+ offset = 12;
+ while (total_subobj_len > 0 && hexdump == FALSE ) {
+ subobj_type = EXTRACT_16BITS(obj_tptr+offset)>>8;
+ subobj_len = EXTRACT_16BITS(obj_tptr+offset)&0x00FF;
+ printf("\n\t Subobject, Type: %s (%u), Length: %u",
+ tok2str(lmp_data_link_subobj,
+ "Unknown",
+ subobj_type),
+ subobj_type,
+ subobj_len);
+ switch(subobj_type) {
+ case INT_SWITCHING_TYPE_SUBOBJ:
+ printf("\n\t Switching Type: %s (%u)",
+ tok2str(gmpls_switch_cap_values,
+ "Unknown",
+ EXTRACT_16BITS(obj_tptr+offset+2)>>8),
+ EXTRACT_16BITS(obj_tptr+offset+2)>>8);
+ printf("\n\t Encoding Type: %s (%u)",
+ tok2str(gmpls_encoding_values,
+ "Unknown",
+ EXTRACT_16BITS(obj_tptr+offset+2)&0x00FF),
+ EXTRACT_16BITS(obj_tptr+offset+2)&0x00FF);
+ bw.i = EXTRACT_32BITS(obj_tptr+offset+4);
+ printf("\n\t Min Reservable Bandwidth: %.3f Mbps",
+ bw.f*8/1000000);
+ bw.i = EXTRACT_32BITS(obj_tptr+offset+8);
+ printf("\n\t Max Reservable Bandwidth: %.3f Mbps",
+ bw.f*8/1000000);
+ break;
+ case WAVELENGTH_SUBOBJ:
+ printf("\n\t Wavelength: %u",
+ EXTRACT_32BITS(obj_tptr+offset+4));
+ break;
+ default:
+ /* Any Unknown Subobject ==> Exit loop */
+ hexdump=TRUE;
+ break;
+ }
+ total_subobj_len-=subobj_len;
+ offset+=subobj_len;
+ }
+
+ break;
+#ifdef INET6
+ case LMP_CTYPE_IPV6:
+#endif
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case LMP_OBJ_VERIFY_BEGIN:
+ switch(lmp_obj_ctype) {
+ case LMP_CTYPE_1:
+ printf("\n\t Flags: %s",
+ bittok2str(lmp_obj_begin_verify_flag_values,
+ "none",
+ EXTRACT_16BITS(obj_tptr)));
+ printf("\n\t Verify Interval: %u",
+ EXTRACT_16BITS(obj_tptr+2));
+ printf("\n\t Data links: %u",
+ EXTRACT_32BITS(obj_tptr+4));
+ printf("\n\t Encoding type: %s",
+ tok2str(gmpls_encoding_values, "Unknown", *(obj_tptr+8)));
+ printf("\n\t Verify Tranport Mechanism: %u (0x%x) %s",
+ EXTRACT_16BITS(obj_tptr+10),
+ EXTRACT_16BITS(obj_tptr+10),
+ EXTRACT_16BITS(obj_tptr+10)&8000 ? "(Payload test messages capable)" : "");
+ bw.i = EXTRACT_32BITS(obj_tptr+12);
+ printf("\n\t Transmission Rate: %.3f Mbps",bw.f*8/1000000);
+ printf("\n\t Wavelength: %u",
+ EXTRACT_32BITS(obj_tptr+16));
+ break;
+
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case LMP_OBJ_VERIFY_BEGIN_ACK:
+ switch(lmp_obj_ctype) {
+ case LMP_CTYPE_1:
+ printf("\n\t Verify Dead Interval: %u \
+ \n\t Verify Transport Response: %u",
+ EXTRACT_16BITS(obj_tptr),
+ EXTRACT_16BITS(obj_tptr+2));
+ break;
+
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case LMP_OBJ_VERIFY_ID:
+ switch(lmp_obj_ctype) {
+ case LMP_CTYPE_1:
+ printf("\n\t Verify ID: %u",
+ EXTRACT_32BITS(obj_tptr));
+ break;
+
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case LMP_OBJ_CHANNEL_STATUS:
+ switch(lmp_obj_ctype) {
+ case LMP_CTYPE_IPV4:
+ case LMP_CTYPE_UNMD:
+ offset = 0;
+ /* Decode pairs: <Interface_ID (4 bytes), Channel_status (4 bytes)> */
+ while (offset < (lmp_obj_len-(int)sizeof(struct lmp_object_header)) ) {
+ printf("\n\t Interface ID: %s (0x%08x)",
+ ipaddr_string(obj_tptr+offset),
+ EXTRACT_32BITS(obj_tptr+offset));
+
+ printf("\n\t\t Active: %s (%u)", (EXTRACT_32BITS(obj_tptr+offset+4)>>31) ?
+ "Allocated" : "Non-allocated",
+ (EXTRACT_32BITS(obj_tptr+offset+4)>>31));
+
+ printf("\n\t\t Direction: %s (%u)", (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1 ?
+ "Transmit" : "Receive",
+ (EXTRACT_32BITS(obj_tptr+offset+4)>>30)&0x1);
+
+ printf("\n\t\t Channel Status: %s (%u)",
+ tok2str(lmp_obj_channel_status_values,
+ "Unknown",
+ EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF),
+ EXTRACT_32BITS(obj_tptr+offset+4)&0x3FFFFFF);
+ offset+=8;
+ }
+ break;
+#ifdef INET6
+ case LMP_CTYPE_IPV6:
+#endif
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case LMP_OBJ_CHANNEL_STATUS_REQ:
+ switch(lmp_obj_ctype) {
+ case LMP_CTYPE_IPV4:
+ case LMP_CTYPE_UNMD:
+ offset = 0;
+ while (offset < (lmp_obj_len-(int)sizeof(struct lmp_object_header)) ) {
+ printf("\n\t Interface ID: %s (0x%08x)",
+ ipaddr_string(obj_tptr+offset),
+ EXTRACT_32BITS(obj_tptr+offset));
+ offset+=4;
+ }
+ break;
+#ifdef INET6
+ case LMP_CTYPE_IPV6:
+#endif
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case LMP_OBJ_ERROR_CODE:
+ switch(lmp_obj_ctype) {
+ case LMP_CTYPE_BEGIN_VERIFY_ERROR:
+ printf("\n\t Error Code: %s",
+ bittok2str(lmp_obj_begin_verify_error_values,
+ "none",
+ EXTRACT_32BITS(obj_tptr)));
+ break;
+
+ case LMP_CTYPE_LINK_SUMMARY_ERROR:
+ printf("\n\t Error Code: %s",
+ bittok2str(lmp_obj_link_summary_error_values,
+ "none",
+ EXTRACT_32BITS(obj_tptr)));
+ break;
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case LMP_OBJ_SERVICE_CONFIG:
+ switch (lmp_obj_ctype) {
+ case LMP_CTYPE_SERVICE_CONFIG_SP:
+
+ printf("\n\t Flags: %s",
+ bittok2str(lmp_obj_service_config_sp_flag_values,
+ "none",
+ EXTRACT_16BITS(obj_tptr)>>8));
+
+ printf("\n\t UNI Version: %u",
+ EXTRACT_16BITS(obj_tptr) & 0x00FF);
+
+ break;
+
+ case LMP_CTYPE_SERVICE_CONFIG_CPSA:
+
+ link_type = EXTRACT_16BITS(obj_tptr)>>8;
+
+ printf("\n\t Link Type: %s (%u)",
+ tok2str(lmp_sd_service_config_cpsa_link_type_values,
+ "Unknown", link_type),
+ link_type);
+
+ if (link_type == LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SDH) {
+ printf("\n\t Signal Type: %s (%u)",
+ tok2str(lmp_sd_service_config_cpsa_signal_type_sdh_values,
+ "Unknown",
+ EXTRACT_16BITS(obj_tptr) & 0x00FF),
+ EXTRACT_16BITS(obj_tptr) & 0x00FF);
+ }
+
+ if (link_type == LMP_SD_SERVICE_CONFIG_CPSA_LINK_TYPE_SONET) {
+ printf("\n\t Signal Type: %s (%u)",
+ tok2str(lmp_sd_service_config_cpsa_signal_type_sonet_values,
+ "Unknown",
+ EXTRACT_16BITS(obj_tptr) & 0x00FF),
+ EXTRACT_16BITS(obj_tptr) & 0x00FF);
+ }
+
+ printf("\n\t Transparency: %s",
+ bittok2str(lmp_obj_service_config_cpsa_tp_flag_values,
+ "none",
+ EXTRACT_16BITS(obj_tptr+2)>>8));
+
+ printf("\n\t Contiguous Concatenation Types: %s",
+ bittok2str(lmp_obj_service_config_cpsa_cct_flag_values,
+ "none",
+ EXTRACT_16BITS(obj_tptr+2)>>8 & 0x00FF));
+
+ printf("\n\t Minimum NCC: %u",
+ EXTRACT_16BITS(obj_tptr+4));
+
+ printf("\n\t Maximum NCC: %u",
+ EXTRACT_16BITS(obj_tptr+6));
+
+ printf("\n\t Minimum NVC:%u",
+ EXTRACT_16BITS(obj_tptr+8));
+
+ printf("\n\t Maximum NVC:%u",
+ EXTRACT_16BITS(obj_tptr+10));
+
+ printf("\n\t Local Interface ID: %s (0x%08x)",
+ ipaddr_string(obj_tptr+12),
+ EXTRACT_32BITS(obj_tptr+12));
+
+ break;
+
+ case LMP_CTYPE_SERVICE_CONFIG_TRANSPARENCY_TCM:
+
+ printf("\n\t Transparency Flags: %s",
+ bittok2str(
+ lmp_obj_service_config_nsa_transparency_flag_values,
+ "none",
+ EXTRACT_32BITS(obj_tptr)));
+
+ printf("\n\t TCM Monitoring Flags: %s",
+ bittok2str(
+ lmp_obj_service_config_nsa_tcm_flag_values,
+ "none",
+ EXTRACT_16BITS(obj_tptr+6) & 0x00FF));
+
+ break;
+
+ case LMP_CTYPE_SERVICE_CONFIG_NETWORK_DIVERSITY:
+
+ printf("\n\t Diversity: Flags: %s",
+ bittok2str(
+ lmp_obj_service_config_nsa_network_diversity_flag_values,
+ "none",
+ EXTRACT_16BITS(obj_tptr+2) & 0x00FF));
+ break;
+
+ default:
+ hexdump = TRUE;
+ };
+
+ break;
+
+ default:
+ if (vflag <= 1)
+ print_unknown_data(obj_tptr,"\n\t ",obj_tlen);
+ break;
+ }
+ /* do we want to see an additionally hexdump ? */
+ if (vflag > 1 || hexdump==TRUE)
+ print_unknown_data(tptr+sizeof(struct lmp_object_header),"\n\t ",
+ lmp_obj_len-sizeof(struct lmp_object_header));
+
+ tptr+=lmp_obj_len;
+ tlen-=lmp_obj_len;
+ }
+ return;
+trunc:
+ printf("\n\t\t packet exceeded snapshot");
+}
diff --git a/freebsd/contrib/tcpdump/print-lspping.c b/freebsd/contrib/tcpdump/print-lspping.c
new file mode 100644
index 00000000..aac0ca25
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-lspping.c
@@ -0,0 +1,898 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-lspping.c,v 1.20 2008-01-28 14:20:43 hannes Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+
+#include "bgp.h"
+#include "l2vpn.h"
+#include "oui.h"
+
+/*
+ * LSPPING common header
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Version Number | Must Be Zero |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Message Type | Reply mode | Return Code | Return Subcode|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Sender's Handle |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Sequence Number |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | TimeStamp Sent (seconds) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | TimeStamp Sent (microseconds) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | TimeStamp Received (seconds) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | TimeStamp Received (microseconds) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | TLVs ... |
+ * . .
+ * . .
+ * . .
+ */
+
+struct lspping_common_header {
+ u_int8_t version[2];
+ u_int8_t reserved[2];
+ u_int8_t msg_type;
+ u_int8_t reply_mode;
+ u_int8_t return_code;
+ u_int8_t return_subcode;
+ u_int8_t sender_handle[4];
+ u_int8_t seq_number[4];
+ u_int8_t ts_sent_sec[4];
+ u_int8_t ts_sent_usec[4];
+ u_int8_t ts_rcvd_sec[4];
+ u_int8_t ts_rcvd_usec[4];
+};
+
+#define LSPPING_VERSION 1
+
+static const struct tok lspping_msg_type_values[] = {
+ { 1, "MPLS Echo Request"},
+ { 2, "MPLS Echo Reply"},
+ { 0, NULL}
+};
+
+static const struct tok lspping_reply_mode_values[] = {
+ { 1, "Do not reply"},
+ { 2, "Reply via an IPv4/IPv6 UDP packet"},
+ { 3, "Reply via an IPv4/IPv6 UDP packet with Router Alert"},
+ { 4, "Reply via application level control channel"},
+ { 0, NULL}
+};
+
+static const struct tok lspping_return_code_values[] = {
+ { 0, "No return code or return code contained in the Error Code TLV"},
+ { 1, "Malformed echo request received"},
+ { 2, "One or more of the TLVs was not understood"},
+ { 3, "Replying router is an egress for the FEC at stack depth"},
+ { 4, "Replying router has no mapping for the FEC at stack depth"},
+ { 5, "Reserved"},
+ { 6, "Reserved"},
+ { 7, "Reserved"},
+ { 8, "Label switched at stack-depth"},
+ { 9, "Label switched but no MPLS forwarding at stack-depth"},
+ { 10, "Mapping for this FEC is not the given label at stack depth"},
+ { 11, "No label entry at stack-depth"},
+ { 12, "Protocol not associated with interface at FEC stack depth"},
+};
+
+
+/*
+ * LSPPING TLV header
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Type | Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Value |
+ * . .
+ * . .
+ * . .
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+struct lspping_tlv_header {
+ u_int8_t type[2];
+ u_int8_t length[2];
+};
+
+#define LSPPING_TLV_TARGET_FEC_STACK 1
+#define LSPPING_TLV_DOWNSTREAM_MAPPING 2
+#define LSPPING_TLV_PAD 3
+#define LSPPING_TLV_VENDOR_ENTERPRISE 5
+#define LSPPING_TLV_VENDOR_ENTERPRISE_LEN 4
+#define LSPPING_TLV_INTERFACE_LABEL_STACK 7
+#define LSPPING_TLV_ERROR_CODE 9
+#define LSPPING_TLV_REPLY_TOS_BYTE 10
+#define LSPPING_TLV_BFD_DISCRIMINATOR 15 /* draft-ietf-bfd-mpls-02 */
+#define LSPPING_TLV_BFD_DISCRIMINATOR_LEN 4
+#define LSPPING_TLV_VENDOR_PRIVATE 0xfc00
+
+static const struct tok lspping_tlv_values[] = {
+ { LSPPING_TLV_TARGET_FEC_STACK, "Target FEC Stack" },
+ { LSPPING_TLV_DOWNSTREAM_MAPPING, "Downstream Mapping" },
+ { LSPPING_TLV_PAD, "Pad" },
+ { LSPPING_TLV_ERROR_CODE, "Error Code" },
+ { LSPPING_TLV_VENDOR_ENTERPRISE, "Vendor Enterprise Code" },
+ { LSPPING_TLV_INTERFACE_LABEL_STACK, "Interface Label Stack" },
+ { LSPPING_TLV_REPLY_TOS_BYTE, "Reply TOS Byte" },
+ { LSPPING_TLV_BFD_DISCRIMINATOR, "BFD Discriminator" },
+ { LSPPING_TLV_VENDOR_PRIVATE, "Vendor Private Code" },
+ { 0, NULL}
+};
+
+#define LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4 1
+#define LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6 2
+#define LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4 3
+#define LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6 4
+#define LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4 6
+#define LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6 7
+#define LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT 8
+#define LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID_OLD 9
+#define LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID 10
+#define LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4 11
+#define LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6 12
+
+static const struct tok lspping_tlvtargetfec_subtlv_values[] = {
+ { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4, "LDP IPv4 prefix"},
+ { LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6, "LDP IPv6 prefix"},
+ { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4, "RSVP IPv4 Session Query"},
+ { LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6, "RSVP IPv6 Session Query"},
+ { 5, "Reserved"},
+ { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4, "VPN IPv4 prefix"},
+ { LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6, "VPN IPv6 prefix"},
+ { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT, "L2 VPN endpoint"},
+ { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID_OLD, "L2 circuit ID (old)"},
+ { LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID, "L2 circuit ID"},
+ { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4, "BGP labeled IPv4 prefix"},
+ { LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6, "BGP labeled IPv6 prefix"},
+ { 0, NULL}
+};
+
+/*
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | IPv4 prefix |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Prefix Length | Must Be Zero |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t {
+ u_int8_t prefix [4];
+ u_int8_t prefix_len;
+};
+
+/*
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | IPv6 prefix |
+ * | (16 octets) |
+ * | |
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Prefix Length | Must Be Zero |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t {
+ u_int8_t prefix [16];
+ u_int8_t prefix_len;
+};
+
+/*
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Sender identifier |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | IPv4 prefix |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Prefix Length | Must Be Zero |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t {
+ u_int8_t sender_id [4];
+ u_int8_t prefix [4];
+ u_int8_t prefix_len;
+};
+
+/*
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Sender identifier |
+ * | (16 octets) |
+ * | |
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | IPv6 prefix |
+ * | (16 octets) |
+ * | |
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Prefix Length | Must Be Zero |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t {
+ u_int8_t sender_id [16];
+ u_int8_t prefix [16];
+ u_int8_t prefix_len;
+};
+
+/*
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | IPv4 tunnel end point address |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Must Be Zero | Tunnel ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Extended Tunnel ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | IPv4 tunnel sender address |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Must Be Zero | LSP ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t {
+ u_int8_t tunnel_endpoint [4];
+ u_int8_t res[2];
+ u_int8_t tunnel_id[2];
+ u_int8_t extended_tunnel_id[4];
+ u_int8_t tunnel_sender [4];
+ u_int8_t res2[2];
+ u_int8_t lsp_id [2];
+};
+
+/*
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | IPv6 tunnel end point address |
+ * | |
+ * | |
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Must Be Zero | Tunnel ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Extended Tunnel ID |
+ * | |
+ * | |
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | IPv6 tunnel sender address |
+ * | |
+ * | |
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Must Be Zero | LSP ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t {
+ u_int8_t tunnel_endpoint [16];
+ u_int8_t res[2];
+ u_int8_t tunnel_id[2];
+ u_int8_t extended_tunnel_id[16];
+ u_int8_t tunnel_sender [16];
+ u_int8_t res2[2];
+ u_int8_t lsp_id [2];
+};
+
+/*
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Route Distinguisher |
+ * | (8 octets) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | IPv4 prefix |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Prefix Length | Must Be Zero |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t {
+ u_int8_t rd [8];
+ u_int8_t prefix [4];
+ u_int8_t prefix_len;
+};
+
+/*
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Route Distinguisher |
+ * | (8 octets) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | IPv6 prefix |
+ * | (16 octets) |
+ * | |
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Prefix Length | Must Be Zero |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t {
+ u_int8_t rd [8];
+ u_int8_t prefix [16];
+ u_int8_t prefix_len;
+};
+
+/*
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Route Distinguisher |
+ * | (8 octets) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Sender's CE ID | Receiver's CE ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Encapsulation Type | Must Be Zero |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 0 1 2 3
+ */
+struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t {
+ u_int8_t rd [8];
+ u_int8_t sender_ce_id [2];
+ u_int8_t receiver_ce_id [2];
+ u_int8_t encapsulation[2];
+};
+
+/*
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Remote PE Address |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | VC ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Encapsulation Type | Must Be Zero |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_old_t {
+ u_int8_t remote_pe_address [4];
+ u_int8_t vc_id [4];
+ u_int8_t encapsulation[2];
+};
+
+/*
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Sender's PE Address |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Remote PE Address |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | VC ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Encapsulation Type | Must Be Zero |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_t {
+ u_int8_t sender_pe_address [4];
+ u_int8_t remote_pe_address [4];
+ u_int8_t vc_id [4];
+ u_int8_t encapsulation[2];
+};
+
+/*
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | MTU | Address Type | Resvd (SBZ) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Downstream IP Address (4 or 16 octets) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Downstream Interface Address (4 or 16 octets) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Hash Key Type | Depth Limit | Multipath Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * . .
+ * . (Multipath Information) .
+ * . .
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Downstream Label | Protocol |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * . .
+ * . .
+ * . .
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Downstream Label | Protocol |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct lspping_tlv_downstream_map_ipv4_t {
+ u_int8_t mtu [2];
+ u_int8_t address_type;
+ u_int8_t res;
+ u_int8_t downstream_ip[4];
+ u_int8_t downstream_interface[4];
+};
+
+struct lspping_tlv_downstream_map_ipv6_t {
+ u_int8_t mtu [2];
+ u_int8_t address_type;
+ u_int8_t res;
+ u_int8_t downstream_ip[16];
+ u_int8_t downstream_interface[16];
+};
+
+struct lspping_tlv_downstream_map_info_t {
+ u_int8_t hash_key_type;
+ u_int8_t depth_limit;
+ u_int8_t multipath_length [2];
+};
+
+#define LSPPING_AFI_IPV4 1
+#define LSPPING_AFI_UNMB 2
+#define LSPPING_AFI_IPV6 3
+
+static const struct tok lspping_tlv_downstream_addr_values[] = {
+ { LSPPING_AFI_IPV4, "IPv4"},
+ { LSPPING_AFI_IPV6, "IPv6"},
+ { LSPPING_AFI_UNMB, "Unnumbered"},
+ { 0, NULL}
+};
+
+void
+lspping_print(register const u_char *pptr, register u_int len) {
+
+ const struct lspping_common_header *lspping_com_header;
+ const struct lspping_tlv_header *lspping_tlv_header;
+ const struct lspping_tlv_header *lspping_subtlv_header;
+ const u_char *tptr,*tlv_tptr,*subtlv_tptr;
+ int tlen,lspping_tlv_len,lspping_tlv_type,tlv_tlen;
+ int tlv_hexdump,subtlv_hexdump;
+ int lspping_subtlv_len,lspping_subtlv_type;
+ struct timeval timestamp;
+
+ union {
+ const struct lspping_tlv_downstream_map_ipv4_t *lspping_tlv_downstream_map_ipv4;
+ const struct lspping_tlv_downstream_map_ipv6_t *lspping_tlv_downstream_map_ipv6;
+ const struct lspping_tlv_downstream_map_info_t *lspping_tlv_downstream_map_info;
+ } tlv_ptr;
+
+ union {
+ const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *lspping_tlv_targetfec_subtlv_ldp_ipv4;
+ const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *lspping_tlv_targetfec_subtlv_ldp_ipv6;
+ const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *lspping_tlv_targetfec_subtlv_rsvp_ipv4;
+ const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *lspping_tlv_targetfec_subtlv_rsvp_ipv6;
+ const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv4;
+ const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *lspping_tlv_targetfec_subtlv_l3vpn_ipv6;
+ const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *lspping_tlv_targetfec_subtlv_l2vpn_endpt;
+ const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_old_t *lspping_tlv_targetfec_subtlv_l2vpn_vcid_old;
+ const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_t *lspping_tlv_targetfec_subtlv_l2vpn_vcid;
+ const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *lspping_tlv_targetfec_subtlv_bgp_ipv4;
+ const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *lspping_tlv_targetfec_subtlv_bgp_ipv6;
+ } subtlv_ptr;
+
+ tptr=pptr;
+ lspping_com_header = (const struct lspping_common_header *)pptr;
+ TCHECK(*lspping_com_header);
+
+ /*
+ * Sanity checking of the header.
+ */
+ if (EXTRACT_16BITS(&lspping_com_header->version[0]) != LSPPING_VERSION) {
+ printf("LSP-PING version %u packet not supported",
+ EXTRACT_16BITS(&lspping_com_header->version[0]));
+ return;
+ }
+
+ /* in non-verbose mode just lets print the basic Message Type*/
+ if (vflag < 1) {
+ printf("LSP-PINGv%u, %s, seq %u, length: %u",
+ EXTRACT_16BITS(&lspping_com_header->version[0]),
+ tok2str(lspping_msg_type_values, "unknown (%u)",lspping_com_header->msg_type),
+ EXTRACT_32BITS(lspping_com_header->seq_number),
+ len);
+ return;
+ }
+
+ /* ok they seem to want to know everything - lets fully decode it */
+
+ tlen=len;
+
+ printf("\n\tLSP-PINGv%u, msg-type: %s (%u), length: %u\n\t reply-mode: %s (%u)",
+ EXTRACT_16BITS(&lspping_com_header->version[0]),
+ tok2str(lspping_msg_type_values, "unknown",lspping_com_header->msg_type),
+ lspping_com_header->msg_type,
+ len,
+ tok2str(lspping_reply_mode_values, "unknown",lspping_com_header->reply_mode),
+ lspping_com_header->reply_mode);
+
+ /*
+ * the following return codes require that the subcode is attached
+ * at the end of the translated token output
+ */
+ if (lspping_com_header->return_code == 3 ||
+ lspping_com_header->return_code == 4 ||
+ lspping_com_header->return_code == 8 ||
+ lspping_com_header->return_code == 10 ||
+ lspping_com_header->return_code == 11 ||
+ lspping_com_header->return_code == 12 )
+ printf("\n\t Return Code: %s %u (%u)\n\t Return Subcode: (%u)",
+ tok2str(lspping_return_code_values, "unknown",lspping_com_header->return_code),
+ lspping_com_header->return_subcode,
+ lspping_com_header->return_code,
+ lspping_com_header->return_subcode);
+ else
+ printf("\n\t Return Code: %s (%u)\n\t Return Subcode: (%u)",
+ tok2str(lspping_return_code_values, "unknown",lspping_com_header->return_code),
+ lspping_com_header->return_code,
+ lspping_com_header->return_subcode);
+
+ printf("\n\t Sender Handle: 0x%08x, Sequence: %u",
+ EXTRACT_32BITS(lspping_com_header->sender_handle),
+ EXTRACT_32BITS(lspping_com_header->seq_number));
+
+ timestamp.tv_sec=EXTRACT_32BITS(lspping_com_header->ts_sent_sec);
+ timestamp.tv_usec=EXTRACT_32BITS(lspping_com_header->ts_sent_usec);
+ printf("\n\t Sender Timestamp: ");
+ ts_print(&timestamp);
+
+ timestamp.tv_sec=EXTRACT_32BITS(lspping_com_header->ts_rcvd_sec);
+ timestamp.tv_usec=EXTRACT_32BITS(lspping_com_header->ts_rcvd_usec);
+ printf("Receiver Timestamp: ");
+ if ((timestamp.tv_sec != 0) && (timestamp.tv_usec != 0))
+ ts_print(&timestamp);
+ else
+ printf("no timestamp");
+
+ tptr+=sizeof(const struct lspping_common_header);
+ tlen-=sizeof(const struct lspping_common_header);
+
+ while(tlen>(int)sizeof(struct lspping_tlv_header)) {
+
+ /* did we capture enough for fully decoding the tlv header ? */
+ if (!TTEST2(*tptr, sizeof(struct lspping_tlv_header)))
+ goto trunc;
+
+ lspping_tlv_header = (const struct lspping_tlv_header *)tptr;
+ lspping_tlv_type=EXTRACT_16BITS(lspping_tlv_header->type);
+ lspping_tlv_len=EXTRACT_16BITS(lspping_tlv_header->length);
+
+ /* some little sanity checking */
+ if (lspping_tlv_type == 0 || lspping_tlv_len == 0)
+ return;
+
+ if(lspping_tlv_len < 4) {
+ printf("\n\t ERROR: TLV %u bogus size %u",lspping_tlv_type,lspping_tlv_len);
+ return;
+ }
+
+ printf("\n\t %s TLV (%u), length: %u",
+ tok2str(lspping_tlv_values,
+ "Unknown",
+ lspping_tlv_type),
+ lspping_tlv_type,
+ lspping_tlv_len);
+
+ tlv_tptr=tptr+sizeof(struct lspping_tlv_header);
+ tlv_tlen=lspping_tlv_len; /* header not included -> no adjustment */
+
+ /* did we capture enough for fully decoding the tlv ? */
+ if (!TTEST2(*tptr, lspping_tlv_len))
+ goto trunc;
+ tlv_hexdump=FALSE;
+
+ switch(lspping_tlv_type) {
+ case LSPPING_TLV_TARGET_FEC_STACK:
+ while(tlv_tlen>(int)sizeof(struct lspping_tlv_header)) {
+
+ /* did we capture enough for fully decoding the subtlv header ? */
+ if (!TTEST2(*tptr, sizeof(struct lspping_tlv_header)))
+ goto trunc;
+ subtlv_hexdump=FALSE;
+
+ lspping_subtlv_header = (const struct lspping_tlv_header *)tlv_tptr;
+ lspping_subtlv_type=EXTRACT_16BITS(lspping_subtlv_header->type);
+ lspping_subtlv_len=EXTRACT_16BITS(lspping_subtlv_header->length);
+ subtlv_tptr=tlv_tptr+sizeof(struct lspping_tlv_header);
+
+ if (lspping_subtlv_len == 0)
+ break;
+
+ printf("\n\t %s subTLV (%u), length: %u",
+ tok2str(lspping_tlvtargetfec_subtlv_values,
+ "Unknown",
+ lspping_subtlv_type),
+ lspping_subtlv_type,
+ lspping_subtlv_len);
+
+ switch(lspping_subtlv_type) {
+
+ case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV4:
+ subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4 = \
+ (const struct lspping_tlv_targetfec_subtlv_ldp_ipv4_t *)subtlv_tptr;
+ printf("\n\t %s/%u",
+ ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix),
+ subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv4->prefix_len);
+ break;
+
+#ifdef INET6
+ case LSPPING_TLV_TARGETFEC_SUBTLV_LDP_IPV6:
+ subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6 = \
+ (const struct lspping_tlv_targetfec_subtlv_ldp_ipv6_t *)subtlv_tptr;
+ printf("\n\t %s/%u",
+ ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix),
+ subtlv_ptr.lspping_tlv_targetfec_subtlv_ldp_ipv6->prefix_len);
+ break;
+#endif
+
+ case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV4:
+ subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4 = \
+ (const struct lspping_tlv_targetfec_subtlv_bgp_ipv4_t *)subtlv_tptr;
+ printf("\n\t %s/%u, sender-id %s",
+ ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix),
+ subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->prefix_len,
+ ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv4->sender_id));
+ break;
+
+#ifdef INET6
+ case LSPPING_TLV_TARGETFEC_SUBTLV_BGP_IPV6:
+ subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6 = \
+ (const struct lspping_tlv_targetfec_subtlv_bgp_ipv6_t *)subtlv_tptr;
+ printf("\n\t %s/%u, sender-id %s",
+ ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix),
+ subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->prefix_len,
+ ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_bgp_ipv6->sender_id));
+ break;
+#endif
+
+ case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV4:
+ subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4 = \
+ (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv4_t *)subtlv_tptr;
+ printf("\n\t tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x" \
+ "\n\t tunnel-id 0x%04x, extended tunnel-id %s",
+ ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_endpoint),
+ ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_sender),
+ EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->lsp_id),
+ EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->tunnel_id),
+ ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv4->extended_tunnel_id));
+ break;
+
+#ifdef INET6
+ case LSPPING_TLV_TARGETFEC_SUBTLV_RSVP_IPV6:
+ subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6 = \
+ (const struct lspping_tlv_targetfec_subtlv_rsvp_ipv6_t *)subtlv_tptr;
+ printf("\n\t tunnel end-point %s, tunnel sender %s, lsp-id 0x%04x" \
+ "\n\t tunnel-id 0x%04x, extended tunnel-id %s",
+ ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_endpoint),
+ ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_sender),
+ EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->lsp_id),
+ EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->tunnel_id),
+ ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_rsvp_ipv6->extended_tunnel_id));
+ break;
+#endif
+
+ case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV4:
+ subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4 = \
+ (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv4_t *)subtlv_tptr;
+ printf("\n\t RD: %s, %s/%u",
+ bgp_vpn_rd_print(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->rd),
+ ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix),
+ subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv4->prefix_len);
+ break;
+
+#ifdef INET6
+ case LSPPING_TLV_TARGETFEC_SUBTLV_L3VPN_IPV6:
+ subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6 = \
+ (const struct lspping_tlv_targetfec_subtlv_l3vpn_ipv6_t *)subtlv_tptr;
+ printf("\n\t RD: %s, %s/%u",
+ bgp_vpn_rd_print(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->rd),
+ ip6addr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix),
+ subtlv_ptr.lspping_tlv_targetfec_subtlv_l3vpn_ipv6->prefix_len);
+ break;
+#endif
+
+ case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_ENDPT:
+ subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt = \
+ (const struct lspping_tlv_targetfec_subtlv_l2vpn_endpt_t *)subtlv_tptr;
+ printf("\n\t RD: %s, Sender CE-ID: %u, Receiver CE-ID: %u" \
+ "\n\t Encapsulation Type: %s (%u)",
+ bgp_vpn_rd_print(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->rd),
+ EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->sender_ce_id),
+ EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->receiver_ce_id),
+ tok2str(l2vpn_encaps_values,
+ "unknown",
+ EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation)),
+ EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_endpt->encapsulation));
+
+ break;
+
+ /* the old L2VPN VCID subTLV does not have support for the sender field */
+ case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID_OLD:
+ subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old = \
+ (const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_old_t *)subtlv_tptr;
+ printf("\n\t Remote PE: %s" \
+ "\n\t VC-ID: 0x%08x, Encapsulation Type: %s (%u)",
+ ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->remote_pe_address),
+ EXTRACT_32BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->vc_id),
+ tok2str(l2vpn_encaps_values,
+ "unknown",
+ EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->encapsulation)),
+ EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid_old->encapsulation));
+
+ break;
+
+ case LSPPING_TLV_TARGETFEC_SUBTLV_L2VPN_VCID:
+ subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid = \
+ (const struct lspping_tlv_targetfec_subtlv_l2vpn_vcid_t *)subtlv_tptr;
+ printf("\n\t Sender PE: %s, Remote PE: %s" \
+ "\n\t VC-ID: 0x%08x, Encapsulation Type: %s (%u)",
+ ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->sender_pe_address),
+ ipaddr_string(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->remote_pe_address),
+ EXTRACT_32BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->vc_id),
+ tok2str(l2vpn_encaps_values,
+ "unknown",
+ EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->encapsulation)),
+ EXTRACT_16BITS(subtlv_ptr.lspping_tlv_targetfec_subtlv_l2vpn_vcid->encapsulation));
+
+ break;
+
+ default:
+ subtlv_hexdump=TRUE; /* unknown subTLV just hexdump it */
+ break;
+ }
+ /* do we want to see an additionally subtlv hexdump ? */
+ if (vflag > 1 || subtlv_hexdump==TRUE)
+ print_unknown_data(tlv_tptr+sizeof(struct lspping_tlv_header), \
+ "\n\t ",
+ lspping_subtlv_len);
+
+ tlv_tptr+=lspping_subtlv_len;
+ tlv_tlen-=lspping_subtlv_len+sizeof(struct lspping_tlv_header);
+ }
+ break;
+
+ case LSPPING_TLV_DOWNSTREAM_MAPPING:
+ /* that strange thing with the downstream map TLV is that until now
+ * we do not know if its IPv4 or IPv6 , after we found the adress-type
+ * lets recast the tlv_tptr and move on */
+
+ tlv_ptr.lspping_tlv_downstream_map_ipv4= \
+ (const struct lspping_tlv_downstream_map_ipv4_t *)tlv_tptr;
+ tlv_ptr.lspping_tlv_downstream_map_ipv6= \
+ (const struct lspping_tlv_downstream_map_ipv6_t *)tlv_tptr;
+ printf("\n\t MTU: %u, Address-Type: %s (%u)",
+ EXTRACT_16BITS(tlv_ptr.lspping_tlv_downstream_map_ipv4->mtu),
+ tok2str(lspping_tlv_downstream_addr_values,
+ "unknown",
+ tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type),
+ tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type);
+
+ switch(tlv_ptr.lspping_tlv_downstream_map_ipv4->address_type) {
+
+ case LSPPING_AFI_IPV4:
+ printf("\n\t Downstream IP: %s" \
+ "\n\t Downstream Interface IP: %s",
+ ipaddr_string(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip),
+ ipaddr_string(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface));
+ tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
+ tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
+ break;
+#ifdef INET6
+ case LSPPING_AFI_IPV6:
+ printf("\n\t Downstream IP: %s" \
+ "\n\t Downstream Interface IP: %s",
+ ip6addr_string(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_ip),
+ ip6addr_string(tlv_ptr.lspping_tlv_downstream_map_ipv6->downstream_interface));
+ tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv6_t);
+ tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv6_t);
+ break;
+#endif
+ case LSPPING_AFI_UNMB:
+ printf("\n\t Downstream IP: %s" \
+ "\n\t Downstream Interface Index: 0x%08x",
+ ipaddr_string(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_ip),
+ EXTRACT_32BITS(tlv_ptr.lspping_tlv_downstream_map_ipv4->downstream_interface));
+ tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
+ tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_ipv4_t);
+ break;
+
+ default:
+ /* should not happen ! - no error message - tok2str() has barked already */
+ break;
+ }
+
+ tlv_ptr.lspping_tlv_downstream_map_info= \
+ (const struct lspping_tlv_downstream_map_info_t *)tlv_tptr;
+
+ /* FIXME add hash-key type, depth limit, multipath processing */
+
+
+ tlv_tptr+=sizeof(struct lspping_tlv_downstream_map_info_t);
+ tlv_tlen-=sizeof(struct lspping_tlv_downstream_map_info_t);
+
+ /* FIXME print downstream labels */
+
+
+ tlv_hexdump=TRUE; /* dump the TLV until code complete */
+
+ break;
+
+ case LSPPING_TLV_BFD_DISCRIMINATOR:
+ tptr += sizeof(struct lspping_tlv_header);
+ if (!TTEST2(*tptr, LSPPING_TLV_BFD_DISCRIMINATOR_LEN))
+ goto trunc;
+ printf("\n\t BFD Discriminator 0x%08x", EXTRACT_32BITS(tptr));
+ break;
+
+ case LSPPING_TLV_VENDOR_ENTERPRISE:
+ {
+ u_int32_t vendor_id;
+
+ if (!TTEST2(*tptr, LSPPING_TLV_VENDOR_ENTERPRISE_LEN))
+ goto trunc;
+ vendor_id = EXTRACT_32BITS(tlv_tptr);
+ printf("\n\t Vendor: %s (0x%04x)",
+ tok2str(smi_values, "Unknown", vendor_id),
+ vendor_id);
+ }
+ break;
+
+ /*
+ * FIXME those are the defined TLVs that lack a decoder
+ * you are welcome to contribute code ;-)
+ */
+ case LSPPING_TLV_PAD:
+ case LSPPING_TLV_ERROR_CODE:
+ case LSPPING_TLV_VENDOR_PRIVATE:
+
+ default:
+ if (vflag <= 1)
+ print_unknown_data(tlv_tptr,"\n\t ",tlv_tlen);
+ break;
+ }
+ /* do we want to see an additionally tlv hexdump ? */
+ if (vflag > 1 || tlv_hexdump==TRUE)
+ print_unknown_data(tptr+sizeof(struct lspping_tlv_header),"\n\t ",
+ lspping_tlv_len);
+
+
+ /* All TLVs are aligned to four octet boundary */
+ if (lspping_tlv_len % 4) {
+ lspping_tlv_len += (4 - lspping_tlv_len % 4);
+ }
+
+ tptr+=lspping_tlv_len+sizeof(struct lspping_tlv_header);
+ tlen-=lspping_tlv_len+sizeof(struct lspping_tlv_header);
+ }
+ return;
+trunc:
+ printf("\n\t\t packet exceeded snapshot");
+}
diff --git a/freebsd/contrib/tcpdump/print-lwapp.c b/freebsd/contrib/tcpdump/print-lwapp.c
new file mode 100644
index 00000000..fb76203f
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-lwapp.c
@@ -0,0 +1,361 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1998-2007 The TCPDUMP project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Support for the Light Weight Access Point Protocol as per draft-ohara-capwap-lwapp-04
+ *
+ * Original code by Carles Kishimoto <carles.kishimoto@gmail.com>
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+"@(#) $Header: /tcpdump/master/tcpdump/print-lwapp.c,v 1.1 2007-07-24 16:07:30 hannes Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+
+/*
+ * LWAPP transport (common) header
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |VER| RID |C|F|L| Frag ID | Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Status/WLANs | Payload... |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+struct lwapp_transport_header {
+ u_int8_t version;
+ u_int8_t frag_id;
+ u_int8_t length[2];
+ u_int16_t status;
+};
+
+/*
+ * LWAPP control header
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Message Type | Seq Num | Msg Element Length |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Session ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Msg Element [0..N] |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+struct lwapp_control_header {
+ u_int8_t msg_type;
+ u_int8_t seq_num;
+ u_int8_t len[2];
+ u_int8_t session_id[4];
+};
+
+#define LWAPP_VERSION 0
+#define LWAPP_EXTRACT_VERSION(x) (((x)&0xC0)>>6)
+#define LWAPP_EXTRACT_RID(x) (((x)&0x38)>>3)
+#define LWAPP_EXTRACT_CONTROL_BIT(x) (((x)&0x04)>>2)
+
+static const struct tok lwapp_header_bits_values[] = {
+ { 0x01, "Last Fragment Bit"},
+ { 0x02, "Fragment Bit"},
+ { 0x04, "Control Bit"},
+ { 0, NULL}
+};
+
+#define LWAPP_MSGTYPE_DISCOVERY_REQUEST 1
+#define LWAPP_MSGTYPE_DISCOVERY_RESPONSE 2
+#define LWAPP_MSGTYPE_JOIN_REQUEST 3
+#define LWAPP_MSGTYPE_JOIN_RESPONSE 4
+#define LWAPP_MSGTYPE_JOIN_ACK 5
+#define LWAPP_MSGTYPE_JOIN_CONFIRM 6
+#define LWAPP_MSGTYPE_CONFIGURE_REQUEST 10
+#define LWAPP_MSGTYPE_CONFIGURE_RESPONSE 11
+#define LWAPP_MSGTYPE_CONF_UPDATE_REQUEST 12
+#define LWAPP_MSGTYPE_CONF_UPDATE_RESPONSE 13
+#define LWAPP_MSGTYPE_WTP_EVENT_REQUEST 14
+#define LWAPP_MSGTYPE_WTP_EVENT_RESPONSE 15
+#define LWAPP_MSGTYPE_CHANGE_STATE_EVENT_REQUEST 16
+#define LWAPP_MSGTYPE_CHANGE_STATE_EVENT_RESPONSE 17
+#define LWAPP_MSGTYPE_ECHO_REQUEST 22
+#define LWAPP_MSGTYPE_ECHO_RESPONSE 23
+#define LWAPP_MSGTYPE_IMAGE_DATA_REQUEST 24
+#define LWAPP_MSGTYPE_IMAGE_DATA_RESPONSE 25
+#define LWAPP_MSGTYPE_RESET_REQUEST 26
+#define LWAPP_MSGTYPE_RESET_RESPONSE 27
+#define LWAPP_MSGTYPE_KEY_UPDATE_REQUEST 30
+#define LWAPP_MSGTYPE_KEY_UPDATE_RESPONSE 31
+#define LWAPP_MSGTYPE_PRIMARY_DISCOVERY_REQUEST 32
+#define LWAPP_MSGTYPE_PRIMARY_DISCOVERY_RESPONSE 33
+#define LWAPP_MSGTYPE_DATA_TRANSFER_REQUEST 34
+#define LWAPP_MSGTYPE_DATA_TRANSFER_RESPONSE 35
+#define LWAPP_MSGTYPE_CLEAR_CONFIG_INDICATION 36
+#define LWAPP_MSGTYPE_WLAN_CONFIG_REQUEST 37
+#define LWAPP_MSGTYPE_WLAN_CONFIG_RESPONSE 38
+#define LWAPP_MSGTYPE_MOBILE_CONFIG_REQUEST 39
+#define LWAPP_MSGTYPE_MOBILE_CONFIG_RESPONSE 40
+
+static const struct tok lwapp_msg_type_values[] = {
+ { LWAPP_MSGTYPE_DISCOVERY_REQUEST, "Discovery req"},
+ { LWAPP_MSGTYPE_DISCOVERY_RESPONSE, "Discovery resp"},
+ { LWAPP_MSGTYPE_JOIN_REQUEST, "Join req"},
+ { LWAPP_MSGTYPE_JOIN_RESPONSE, "Join resp"},
+ { LWAPP_MSGTYPE_JOIN_ACK, "Join ack"},
+ { LWAPP_MSGTYPE_JOIN_CONFIRM, "Join confirm"},
+ { LWAPP_MSGTYPE_CONFIGURE_REQUEST, "Configure req"},
+ { LWAPP_MSGTYPE_CONFIGURE_RESPONSE, "Configure resp"},
+ { LWAPP_MSGTYPE_CONF_UPDATE_REQUEST, "Update req"},
+ { LWAPP_MSGTYPE_CONF_UPDATE_RESPONSE, "Update resp"},
+ { LWAPP_MSGTYPE_WTP_EVENT_REQUEST, "WTP event req"},
+ { LWAPP_MSGTYPE_WTP_EVENT_RESPONSE, "WTP event resp"},
+ { LWAPP_MSGTYPE_CHANGE_STATE_EVENT_REQUEST, "Change state event req"},
+ { LWAPP_MSGTYPE_CHANGE_STATE_EVENT_RESPONSE, "Change state event resp"},
+ { LWAPP_MSGTYPE_ECHO_REQUEST, "Echo req"},
+ { LWAPP_MSGTYPE_ECHO_RESPONSE, "Echo resp"},
+ { LWAPP_MSGTYPE_IMAGE_DATA_REQUEST, "Image data req"},
+ { LWAPP_MSGTYPE_IMAGE_DATA_RESPONSE, "Image data resp"},
+ { LWAPP_MSGTYPE_RESET_REQUEST, "Channel status req"},
+ { LWAPP_MSGTYPE_RESET_RESPONSE, "Channel status resp"},
+ { LWAPP_MSGTYPE_KEY_UPDATE_REQUEST, "Key update req"},
+ { LWAPP_MSGTYPE_KEY_UPDATE_RESPONSE, "Key update resp"},
+ { LWAPP_MSGTYPE_PRIMARY_DISCOVERY_REQUEST, "Primary discovery req"},
+ { LWAPP_MSGTYPE_PRIMARY_DISCOVERY_RESPONSE, "Primary discovery resp"},
+ { LWAPP_MSGTYPE_DATA_TRANSFER_REQUEST, "Data transfer req"},
+ { LWAPP_MSGTYPE_DATA_TRANSFER_RESPONSE, "Data transfer resp"},
+ { LWAPP_MSGTYPE_CLEAR_CONFIG_INDICATION, "Clear config ind"},
+ { LWAPP_MSGTYPE_WLAN_CONFIG_REQUEST, "Wlan config req"},
+ { LWAPP_MSGTYPE_WLAN_CONFIG_RESPONSE, "Wlan config resp"},
+ { LWAPP_MSGTYPE_MOBILE_CONFIG_REQUEST, "Mobile config req"},
+ { LWAPP_MSGTYPE_MOBILE_CONFIG_RESPONSE, "Mobile config resp"},
+ { 0, NULL}
+};
+
+/*
+ * LWAPP message elements
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Type | Length | Value ... |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+struct lwapp_message_header {
+ u_int8_t type;
+ u_int8_t length[2];
+};
+
+void
+lwapp_control_print(const u_char *pptr, u_int len, int has_ap_ident) {
+
+ const struct lwapp_transport_header *lwapp_trans_header;
+ const struct lwapp_control_header *lwapp_control_header;
+ const u_char *tptr;
+ int tlen;
+ int msg_tlen;
+
+ tptr=pptr;
+
+ if (has_ap_ident) {
+ /* check if enough bytes for AP identity */
+ if (!TTEST2(*tptr, 6))
+ goto trunc;
+ lwapp_trans_header = (const struct lwapp_transport_header *)(pptr+6);
+ } else {
+ lwapp_trans_header = (const struct lwapp_transport_header *)pptr;
+ }
+ TCHECK(*lwapp_trans_header);
+
+ /*
+ * Sanity checking of the header.
+ */
+ if (LWAPP_EXTRACT_VERSION(lwapp_trans_header->version) != LWAPP_VERSION) {
+ printf("LWAPP version %u packet not supported",
+ LWAPP_EXTRACT_VERSION(lwapp_trans_header->version));
+ return;
+ }
+
+ /* non-verbose */
+ if (vflag < 1) {
+ printf("LWAPPv%u, %s frame, Flags [%s], length %u",
+ LWAPP_EXTRACT_VERSION(lwapp_trans_header->version),
+ LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data",
+ bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07),
+ len);
+ return;
+ }
+
+ /* ok they seem to want to know everything - lets fully decode it */
+ tlen=EXTRACT_16BITS(lwapp_trans_header->length);
+
+ printf("LWAPPv%u, %s frame, Radio-id %u, Flags [%s], Frag-id %u, length %u",
+ LWAPP_EXTRACT_VERSION(lwapp_trans_header->version),
+ LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data",
+ LWAPP_EXTRACT_RID(lwapp_trans_header->version),
+ bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07),
+ lwapp_trans_header->frag_id,
+ tlen);
+
+ if (has_ap_ident) {
+ printf("\n\tAP identity: %s",
+ etheraddr_string(tptr));
+ tptr+=sizeof(const struct lwapp_transport_header)+6;
+ } else {
+ tptr+=sizeof(const struct lwapp_transport_header);
+ }
+
+ while(tlen>0) {
+
+ /* did we capture enough for fully decoding the object header ? */
+ if (!TTEST2(*tptr, sizeof(struct lwapp_control_header)))
+ goto trunc;
+
+ lwapp_control_header = (const struct lwapp_control_header *)tptr;
+ msg_tlen = EXTRACT_16BITS(lwapp_control_header->len);
+
+ /* print message header */
+ printf("\n\t Msg type: %s (%u), Seqnum: %u, Msg len: %d, Session: 0x%08x",
+ tok2str(lwapp_msg_type_values,"Unknown",lwapp_control_header->msg_type),
+ lwapp_control_header->msg_type,
+ lwapp_control_header->seq_num,
+ msg_tlen,
+ EXTRACT_32BITS(lwapp_control_header->session_id));
+
+ /* did we capture enough for fully decoding the message */
+ if (!TTEST2(*tptr, msg_tlen))
+ goto trunc;
+
+ /* XXX - Decode sub messages for each message */
+ switch(lwapp_control_header->msg_type) {
+ case LWAPP_MSGTYPE_DISCOVERY_REQUEST:
+ case LWAPP_MSGTYPE_DISCOVERY_RESPONSE:
+ case LWAPP_MSGTYPE_JOIN_REQUEST:
+ case LWAPP_MSGTYPE_JOIN_RESPONSE:
+ case LWAPP_MSGTYPE_JOIN_ACK:
+ case LWAPP_MSGTYPE_JOIN_CONFIRM:
+ case LWAPP_MSGTYPE_CONFIGURE_REQUEST:
+ case LWAPP_MSGTYPE_CONFIGURE_RESPONSE:
+ case LWAPP_MSGTYPE_CONF_UPDATE_REQUEST:
+ case LWAPP_MSGTYPE_CONF_UPDATE_RESPONSE:
+ case LWAPP_MSGTYPE_WTP_EVENT_REQUEST:
+ case LWAPP_MSGTYPE_WTP_EVENT_RESPONSE:
+ case LWAPP_MSGTYPE_CHANGE_STATE_EVENT_REQUEST:
+ case LWAPP_MSGTYPE_CHANGE_STATE_EVENT_RESPONSE:
+ case LWAPP_MSGTYPE_ECHO_REQUEST:
+ case LWAPP_MSGTYPE_ECHO_RESPONSE:
+ case LWAPP_MSGTYPE_IMAGE_DATA_REQUEST:
+ case LWAPP_MSGTYPE_IMAGE_DATA_RESPONSE:
+ case LWAPP_MSGTYPE_RESET_REQUEST:
+ case LWAPP_MSGTYPE_RESET_RESPONSE:
+ case LWAPP_MSGTYPE_KEY_UPDATE_REQUEST:
+ case LWAPP_MSGTYPE_KEY_UPDATE_RESPONSE:
+ case LWAPP_MSGTYPE_PRIMARY_DISCOVERY_REQUEST:
+ case LWAPP_MSGTYPE_PRIMARY_DISCOVERY_RESPONSE:
+ case LWAPP_MSGTYPE_DATA_TRANSFER_REQUEST:
+ case LWAPP_MSGTYPE_DATA_TRANSFER_RESPONSE:
+ case LWAPP_MSGTYPE_CLEAR_CONFIG_INDICATION:
+ case LWAPP_MSGTYPE_WLAN_CONFIG_REQUEST:
+ case LWAPP_MSGTYPE_WLAN_CONFIG_RESPONSE:
+ case LWAPP_MSGTYPE_MOBILE_CONFIG_REQUEST:
+ case LWAPP_MSGTYPE_MOBILE_CONFIG_RESPONSE:
+ default:
+ break;
+ }
+
+ tptr += sizeof(struct lwapp_control_header) + msg_tlen;
+ tlen -= sizeof(struct lwapp_control_header) + msg_tlen;
+ }
+ return;
+
+ trunc:
+ printf("\n\t\t packet exceeded snapshot");
+}
+
+void
+lwapp_data_print(const u_char *pptr, u_int len) {
+
+ const struct lwapp_transport_header *lwapp_trans_header;
+ const u_char *tptr;
+ int tlen;
+
+ tptr=pptr;
+
+ /* check if enough bytes for AP identity */
+ if (!TTEST2(*tptr, 6))
+ goto trunc;
+ lwapp_trans_header = (const struct lwapp_transport_header *)pptr;
+ TCHECK(*lwapp_trans_header);
+
+ /*
+ * Sanity checking of the header.
+ */
+ if (LWAPP_EXTRACT_VERSION(lwapp_trans_header->version) != LWAPP_VERSION) {
+ printf("LWAPP version %u packet not supported",
+ LWAPP_EXTRACT_VERSION(lwapp_trans_header->version));
+ return;
+ }
+
+ /* non-verbose */
+ if (vflag < 1) {
+ printf("LWAPPv%u, %s frame, Flags [%s], length %u",
+ LWAPP_EXTRACT_VERSION(lwapp_trans_header->version),
+ LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data",
+ bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07),
+ len);
+ return;
+ }
+
+ /* ok they seem to want to know everything - lets fully decode it */
+ tlen=EXTRACT_16BITS(lwapp_trans_header->length);
+
+ printf("LWAPPv%u, %s frame, Radio-id %u, Flags [%s], Frag-id %u, length %u",
+ LWAPP_EXTRACT_VERSION(lwapp_trans_header->version),
+ LWAPP_EXTRACT_CONTROL_BIT(lwapp_trans_header->version) ? "Control" : "Data",
+ LWAPP_EXTRACT_RID(lwapp_trans_header->version),
+ bittok2str(lwapp_header_bits_values,"none",(lwapp_trans_header->version)&0x07),
+ lwapp_trans_header->frag_id,
+ tlen);
+
+ tptr+=sizeof(const struct lwapp_transport_header);
+ tlen-=sizeof(const struct lwapp_transport_header);
+
+ /* FIX - An IEEE 802.11 frame follows - hexdump for now */
+ print_unknown_data(tptr, "\n\t", tlen);
+
+ return;
+
+ trunc:
+ printf("\n\t\t packet exceeded snapshot");
+}
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-lwres.c b/freebsd/contrib/tcpdump/print-lwres.c
new file mode 100644
index 00000000..a68a67a4
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-lwres.c
@@ -0,0 +1,603 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2001 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-lwres.c,v 1.13 2004-03-24 01:54:29 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include "nameser.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h" /* must come after interface.h */
+
+/* BIND9 lib/lwres/include/lwres */
+typedef u_int32_t lwres_uint32_t;
+typedef u_int16_t lwres_uint16_t;
+typedef u_int8_t lwres_uint8_t;
+
+struct lwres_lwpacket {
+ lwres_uint32_t length;
+ lwres_uint16_t version;
+ lwres_uint16_t pktflags;
+ lwres_uint32_t serial;
+ lwres_uint32_t opcode;
+ lwres_uint32_t result;
+ lwres_uint32_t recvlength;
+ lwres_uint16_t authtype;
+ lwres_uint16_t authlength;
+};
+
+#define LWRES_LWPACKETFLAG_RESPONSE 0x0001U /* if set, pkt is a response */
+
+#define LWRES_LWPACKETVERSION_0 0
+
+#define LWRES_FLAG_TRUSTNOTREQUIRED 0x00000001U
+#define LWRES_FLAG_SECUREDATA 0x00000002U
+
+/*
+ * no-op
+ */
+#define LWRES_OPCODE_NOOP 0x00000000U
+
+typedef struct {
+ /* public */
+ lwres_uint16_t datalength;
+ /* data follows */
+} lwres_nooprequest_t;
+
+typedef struct {
+ /* public */
+ lwres_uint16_t datalength;
+ /* data follows */
+} lwres_noopresponse_t;
+
+/*
+ * get addresses by name
+ */
+#define LWRES_OPCODE_GETADDRSBYNAME 0x00010001U
+
+typedef struct lwres_addr lwres_addr_t;
+
+struct lwres_addr {
+ lwres_uint32_t family;
+ lwres_uint16_t length;
+ /* address folows */
+};
+
+typedef struct {
+ /* public */
+ lwres_uint32_t flags;
+ lwres_uint32_t addrtypes;
+ lwres_uint16_t namelen;
+ /* name follows */
+} lwres_gabnrequest_t;
+
+typedef struct {
+ /* public */
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ lwres_uint16_t naddrs;
+ lwres_uint16_t realnamelen;
+ /* aliases follows */
+ /* addrs follows */
+ /* realname follows */
+} lwres_gabnresponse_t;
+
+/*
+ * get name by address
+ */
+#define LWRES_OPCODE_GETNAMEBYADDR 0x00010002U
+typedef struct {
+ /* public */
+ lwres_uint32_t flags;
+ lwres_addr_t addr;
+ /* addr body follows */
+} lwres_gnbarequest_t;
+
+typedef struct {
+ /* public */
+ lwres_uint32_t flags;
+ lwres_uint16_t naliases;
+ lwres_uint16_t realnamelen;
+ /* aliases follows */
+ /* realname follows */
+} lwres_gnbaresponse_t;
+
+/*
+ * get rdata by name
+ */
+#define LWRES_OPCODE_GETRDATABYNAME 0x00010003U
+
+typedef struct {
+ /* public */
+ lwres_uint32_t flags;
+ lwres_uint16_t rdclass;
+ lwres_uint16_t rdtype;
+ lwres_uint16_t namelen;
+ /* name follows */
+} lwres_grbnrequest_t;
+
+typedef struct {
+ /* public */
+ lwres_uint32_t flags;
+ lwres_uint16_t rdclass;
+ lwres_uint16_t rdtype;
+ lwres_uint32_t ttl;
+ lwres_uint16_t nrdatas;
+ lwres_uint16_t nsigs;
+ /* realname here (len + name) */
+ /* rdata here (len + name) */
+ /* signatures here (len + name) */
+} lwres_grbnresponse_t;
+
+#define LWRDATA_VALIDATED 0x00000001
+
+#define LWRES_ADDRTYPE_V4 0x00000001U /* ipv4 */
+#define LWRES_ADDRTYPE_V6 0x00000002U /* ipv6 */
+
+#define LWRES_MAX_ALIASES 16 /* max # of aliases */
+#define LWRES_MAX_ADDRS 64 /* max # of addrs */
+
+struct tok opcode[] = {
+ { LWRES_OPCODE_NOOP, "noop", },
+ { LWRES_OPCODE_GETADDRSBYNAME, "getaddrsbyname", },
+ { LWRES_OPCODE_GETNAMEBYADDR, "getnamebyaddr", },
+ { LWRES_OPCODE_GETRDATABYNAME, "getrdatabyname", },
+ { 0, NULL, },
+};
+
+/* print-domain.c */
+extern struct tok ns_type2str[];
+extern struct tok ns_class2str[];
+
+static int lwres_printname(size_t, const char *);
+static int lwres_printnamelen(const char *);
+static int lwres_printbinlen(const char *);
+static int lwres_printaddr(lwres_addr_t *);
+
+static int
+lwres_printname(size_t l, const char *p0)
+{
+ const char *p;
+ size_t i;
+
+ p = p0;
+ /* + 1 for terminating \0 */
+ if (p + l + 1 > (const char *)snapend)
+ goto trunc;
+
+ printf(" ");
+ for (i = 0; i < l; i++)
+ safeputchar(*p++);
+ p++; /* skip terminating \0 */
+
+ return p - p0;
+
+ trunc:
+ return -1;
+}
+
+static int
+lwres_printnamelen(const char *p)
+{
+ u_int16_t l;
+ int advance;
+
+ if (p + 2 > (const char *)snapend)
+ goto trunc;
+ l = EXTRACT_16BITS(p);
+ advance = lwres_printname(l, p + 2);
+ if (advance < 0)
+ goto trunc;
+ return 2 + advance;
+
+ trunc:
+ return -1;
+}
+
+static int
+lwres_printbinlen(const char *p0)
+{
+ const char *p;
+ u_int16_t l;
+ int i;
+
+ p = p0;
+ if (p + 2 > (const char *)snapend)
+ goto trunc;
+ l = EXTRACT_16BITS(p);
+ if (p + 2 + l > (const char *)snapend)
+ goto trunc;
+ p += 2;
+ for (i = 0; i < l; i++)
+ printf("%02x", *p++);
+ return p - p0;
+
+ trunc:
+ return -1;
+}
+
+static int
+lwres_printaddr(lwres_addr_t *ap)
+{
+ u_int16_t l;
+ const char *p;
+ int i;
+
+ TCHECK(ap->length);
+ l = EXTRACT_16BITS(&ap->length);
+ /* XXX ap points to packed struct */
+ p = (const char *)&ap->length + sizeof(ap->length);
+ TCHECK2(*p, l);
+
+ switch (EXTRACT_32BITS(&ap->family)) {
+ case 1: /* IPv4 */
+ if (l < 4)
+ return -1;
+ printf(" %s", ipaddr_string(p));
+ p += sizeof(struct in_addr);
+ break;
+#ifdef INET6
+ case 2: /* IPv6 */
+ if (l < 16)
+ return -1;
+ printf(" %s", ip6addr_string(p));
+ p += sizeof(struct in6_addr);
+ break;
+#endif
+ default:
+ printf(" %u/", EXTRACT_32BITS(&ap->family));
+ for (i = 0; i < l; i++)
+ printf("%02x", *p++);
+ }
+
+ return p - (const char *)ap;
+
+ trunc:
+ return -1;
+}
+
+void
+lwres_print(register const u_char *bp, u_int length)
+{
+ const struct lwres_lwpacket *np;
+ u_int32_t v;
+ const char *s;
+ int response;
+ int advance;
+ int unsupported = 0;
+
+ np = (const struct lwres_lwpacket *)bp;
+ TCHECK(np->authlength);
+
+ printf(" lwres");
+ v = EXTRACT_16BITS(&np->version);
+ if (vflag || v != LWRES_LWPACKETVERSION_0)
+ printf(" v%u", v);
+ if (v != LWRES_LWPACKETVERSION_0) {
+ s = (const char *)np + EXTRACT_32BITS(&np->length);
+ goto tail;
+ }
+
+ response = EXTRACT_16BITS(&np->pktflags) & LWRES_LWPACKETFLAG_RESPONSE;
+
+ /* opcode and pktflags */
+ v = EXTRACT_32BITS(&np->opcode);
+ s = tok2str(opcode, "#0x%x", v);
+ printf(" %s%s", s, response ? "" : "?");
+
+ /* pktflags */
+ v = EXTRACT_16BITS(&np->pktflags);
+ if (v & ~LWRES_LWPACKETFLAG_RESPONSE)
+ printf("[0x%x]", v);
+
+ if (vflag > 1) {
+ printf(" ("); /*)*/
+ printf("serial:0x%x", EXTRACT_32BITS(&np->serial));
+ printf(" result:0x%x", EXTRACT_32BITS(&np->result));
+ printf(" recvlen:%u", EXTRACT_32BITS(&np->recvlength));
+ /* BIND910: not used */
+ if (vflag > 2) {
+ printf(" authtype:0x%x", EXTRACT_16BITS(&np->authtype));
+ printf(" authlen:%u", EXTRACT_16BITS(&np->authlength));
+ }
+ /*(*/
+ printf(")");
+ }
+
+ /* per-opcode content */
+ if (!response) {
+ /*
+ * queries
+ */
+ lwres_gabnrequest_t *gabn;
+ lwres_gnbarequest_t *gnba;
+ lwres_grbnrequest_t *grbn;
+ u_int32_t l;
+
+ gabn = NULL;
+ gnba = NULL;
+ grbn = NULL;
+
+ switch (EXTRACT_32BITS(&np->opcode)) {
+ case LWRES_OPCODE_NOOP:
+ break;
+ case LWRES_OPCODE_GETADDRSBYNAME:
+ gabn = (lwres_gabnrequest_t *)(np + 1);
+ TCHECK(gabn->namelen);
+ /* XXX gabn points to packed struct */
+ s = (const char *)&gabn->namelen +
+ sizeof(gabn->namelen);
+ l = EXTRACT_16BITS(&gabn->namelen);
+
+ /* BIND910: not used */
+ if (vflag > 2) {
+ printf(" flags:0x%x",
+ EXTRACT_32BITS(&gabn->flags));
+ }
+
+ v = EXTRACT_32BITS(&gabn->addrtypes);
+ switch (v & (LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6)) {
+ case LWRES_ADDRTYPE_V4:
+ printf(" IPv4");
+ break;
+ case LWRES_ADDRTYPE_V6:
+ printf(" IPv6");
+ break;
+ case LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6:
+ printf(" IPv4/6");
+ break;
+ }
+ if (v & ~(LWRES_ADDRTYPE_V4 | LWRES_ADDRTYPE_V6))
+ printf("[0x%x]", v);
+
+ advance = lwres_printname(l, s);
+ if (advance < 0)
+ goto trunc;
+ s += advance;
+ break;
+ case LWRES_OPCODE_GETNAMEBYADDR:
+ gnba = (lwres_gnbarequest_t *)(np + 1);
+ TCHECK(gnba->addr);
+
+ /* BIND910: not used */
+ if (vflag > 2) {
+ printf(" flags:0x%x",
+ EXTRACT_32BITS(&gnba->flags));
+ }
+
+ s = (const char *)&gnba->addr;
+
+ advance = lwres_printaddr(&gnba->addr);
+ if (advance < 0)
+ goto trunc;
+ s += advance;
+ break;
+ case LWRES_OPCODE_GETRDATABYNAME:
+ /* XXX no trace, not tested */
+ grbn = (lwres_grbnrequest_t *)(np + 1);
+ TCHECK(grbn->namelen);
+
+ /* BIND910: not used */
+ if (vflag > 2) {
+ printf(" flags:0x%x",
+ EXTRACT_32BITS(&grbn->flags));
+ }
+
+ printf(" %s", tok2str(ns_type2str, "Type%d",
+ EXTRACT_16BITS(&grbn->rdtype)));
+ if (EXTRACT_16BITS(&grbn->rdclass) != C_IN) {
+ printf(" %s", tok2str(ns_class2str, "Class%d",
+ EXTRACT_16BITS(&grbn->rdclass)));
+ }
+
+ /* XXX grbn points to packed struct */
+ s = (const char *)&grbn->namelen +
+ sizeof(grbn->namelen);
+ l = EXTRACT_16BITS(&grbn->namelen);
+
+ advance = lwres_printname(l, s);
+ if (advance < 0)
+ goto trunc;
+ s += advance;
+ break;
+ default:
+ unsupported++;
+ break;
+ }
+ } else {
+ /*
+ * responses
+ */
+ lwres_gabnresponse_t *gabn;
+ lwres_gnbaresponse_t *gnba;
+ lwres_grbnresponse_t *grbn;
+ u_int32_t l, na;
+ u_int32_t i;
+
+ gabn = NULL;
+ gnba = NULL;
+ grbn = NULL;
+
+ switch (EXTRACT_32BITS(&np->opcode)) {
+ case LWRES_OPCODE_NOOP:
+ break;
+ case LWRES_OPCODE_GETADDRSBYNAME:
+ gabn = (lwres_gabnresponse_t *)(np + 1);
+ TCHECK(gabn->realnamelen);
+ /* XXX gabn points to packed struct */
+ s = (const char *)&gabn->realnamelen +
+ sizeof(gabn->realnamelen);
+ l = EXTRACT_16BITS(&gabn->realnamelen);
+
+ /* BIND910: not used */
+ if (vflag > 2) {
+ printf(" flags:0x%x",
+ EXTRACT_32BITS(&gabn->flags));
+ }
+
+ printf(" %u/%u", EXTRACT_16BITS(&gabn->naliases),
+ EXTRACT_16BITS(&gabn->naddrs));
+
+ advance = lwres_printname(l, s);
+ if (advance < 0)
+ goto trunc;
+ s += advance;
+
+ /* aliases */
+ na = EXTRACT_16BITS(&gabn->naliases);
+ for (i = 0; i < na; i++) {
+ advance = lwres_printnamelen(s);
+ if (advance < 0)
+ goto trunc;
+ s += advance;
+ }
+
+ /* addrs */
+ na = EXTRACT_16BITS(&gabn->naddrs);
+ for (i = 0; i < na; i++) {
+ advance = lwres_printaddr((lwres_addr_t *)s);
+ if (advance < 0)
+ goto trunc;
+ s += advance;
+ }
+ break;
+ case LWRES_OPCODE_GETNAMEBYADDR:
+ gnba = (lwres_gnbaresponse_t *)(np + 1);
+ TCHECK(gnba->realnamelen);
+ /* XXX gnba points to packed struct */
+ s = (const char *)&gnba->realnamelen +
+ sizeof(gnba->realnamelen);
+ l = EXTRACT_16BITS(&gnba->realnamelen);
+
+ /* BIND910: not used */
+ if (vflag > 2) {
+ printf(" flags:0x%x",
+ EXTRACT_32BITS(&gnba->flags));
+ }
+
+ printf(" %u", EXTRACT_16BITS(&gnba->naliases));
+
+ advance = lwres_printname(l, s);
+ if (advance < 0)
+ goto trunc;
+ s += advance;
+
+ /* aliases */
+ na = EXTRACT_16BITS(&gnba->naliases);
+ for (i = 0; i < na; i++) {
+ advance = lwres_printnamelen(s);
+ if (advance < 0)
+ goto trunc;
+ s += advance;
+ }
+ break;
+ case LWRES_OPCODE_GETRDATABYNAME:
+ /* XXX no trace, not tested */
+ grbn = (lwres_grbnresponse_t *)(np + 1);
+ TCHECK(grbn->nsigs);
+
+ /* BIND910: not used */
+ if (vflag > 2) {
+ printf(" flags:0x%x",
+ EXTRACT_32BITS(&grbn->flags));
+ }
+
+ printf(" %s", tok2str(ns_type2str, "Type%d",
+ EXTRACT_16BITS(&grbn->rdtype)));
+ if (EXTRACT_16BITS(&grbn->rdclass) != C_IN) {
+ printf(" %s", tok2str(ns_class2str, "Class%d",
+ EXTRACT_16BITS(&grbn->rdclass)));
+ }
+ printf(" TTL ");
+ relts_print(EXTRACT_32BITS(&grbn->ttl));
+ printf(" %u/%u", EXTRACT_16BITS(&grbn->nrdatas),
+ EXTRACT_16BITS(&grbn->nsigs));
+
+ /* XXX grbn points to packed struct */
+ s = (const char *)&grbn->nsigs+ sizeof(grbn->nsigs);
+
+ advance = lwres_printnamelen(s);
+ if (advance < 0)
+ goto trunc;
+ s += advance;
+
+ /* rdatas */
+ na = EXTRACT_16BITS(&grbn->nrdatas);
+ for (i = 0; i < na; i++) {
+ /* XXX should decode resource data */
+ advance = lwres_printbinlen(s);
+ if (advance < 0)
+ goto trunc;
+ s += advance;
+ }
+
+ /* sigs */
+ na = EXTRACT_16BITS(&grbn->nsigs);
+ for (i = 0; i < na; i++) {
+ /* XXX how should we print it? */
+ advance = lwres_printbinlen(s);
+ if (advance < 0)
+ goto trunc;
+ s += advance;
+ }
+ break;
+ default:
+ unsupported++;
+ break;
+ }
+ }
+
+ tail:
+ /* length mismatch */
+ if (EXTRACT_32BITS(&np->length) != length) {
+ printf(" [len: %u != %u]", EXTRACT_32BITS(&np->length),
+ length);
+ }
+ if (!unsupported && s < (const char *)np + EXTRACT_32BITS(&np->length))
+ printf("[extra]");
+ return;
+
+ trunc:
+ printf("[|lwres]");
+ return;
+}
diff --git a/freebsd/contrib/tcpdump/print-mobile.c b/freebsd/contrib/tcpdump/print-mobile.c
new file mode 100644
index 00000000..b13ab43d
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-mobile.c
@@ -0,0 +1,114 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/* $NetBSD: print-mobile.c,v 1.2 1998/09/30 08:57:01 hwr Exp $ */
+
+/*
+ * (c) 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Heiko W.Rupp <hwr@pilhuhn.de>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-mobile.c,v 1.15 2004-03-24 01:58:14 guy Exp $";
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h" /* must come after interface.h */
+
+#define MOBILE_SIZE (8)
+
+struct mobile_ip {
+ u_int16_t proto;
+ u_int16_t hcheck;
+ u_int32_t odst;
+ u_int32_t osrc;
+};
+
+#define OSRC_PRES 0x0080 /* old source is present */
+
+/*
+ * Deencapsulate and print a mobile-tunneled IP datagram
+ */
+void
+mobile_print(const u_char *bp, u_int length)
+{
+ const u_char *cp = bp +8 ;
+ const struct mobile_ip *mob;
+ struct cksum_vec vec[1];
+ u_short proto,crc;
+ u_char osp =0; /* old source address present */
+
+ mob = (const struct mobile_ip *)bp;
+
+ if (length < MOBILE_SIZE || !TTEST(*mob)) {
+ fputs("[|mobile]", stdout);
+ return;
+ }
+ fputs("mobile: ", stdout);
+
+ proto = EXTRACT_16BITS(&mob->proto);
+ crc = EXTRACT_16BITS(&mob->hcheck);
+ if (proto & OSRC_PRES) {
+ osp=1;
+ cp +=4 ;
+ }
+
+ if (osp) {
+ fputs("[S] ",stdout);
+ if (vflag)
+ (void)printf("%s ",ipaddr_string(&mob->osrc));
+ } else {
+ fputs("[] ",stdout);
+ }
+ if (vflag) {
+ (void)printf("> %s ",ipaddr_string(&mob->odst));
+ (void)printf("(oproto=%d)",proto>>8);
+ }
+ vec[0].ptr = (const u_int8_t *)(void *)mob;
+ vec[0].len = osp ? 12 : 8;
+ if (in_cksum(vec, 1)!=0) {
+ (void)printf(" (bad checksum %d)",crc);
+ }
+
+ return;
+}
diff --git a/freebsd/contrib/tcpdump/print-mobility.c b/freebsd/contrib/tcpdump/print-mobility.c
new file mode 100644
index 00000000..3f564e79
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-mobility.c
@@ -0,0 +1,314 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2002 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-mobility.c,v 1.12 2005-04-20 22:21:00 guy Exp $";
+#endif
+
+#ifdef INET6
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+
+#include "ip6.h"
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h" /* must come after interface.h */
+
+/* Mobility header */
+struct ip6_mobility {
+ u_int8_t ip6m_pproto; /* following payload protocol (for PG) */
+ u_int8_t ip6m_len; /* length in units of 8 octets */
+ u_int8_t ip6m_type; /* message type */
+ u_int8_t reserved; /* reserved */
+ u_int16_t ip6m_cksum; /* sum of IPv6 pseudo-header and MH */
+ union {
+ u_int16_t ip6m_un_data16[1]; /* type-specific field */
+ u_int8_t ip6m_un_data8[2]; /* type-specific fiedl */
+ } ip6m_dataun;
+};
+
+#define ip6m_data16 ip6m_dataun.ip6m_un_data16
+#define ip6m_data8 ip6m_dataun.ip6m_un_data8
+
+#define IP6M_MINLEN 8
+
+/* message type */
+#define IP6M_BINDING_REQUEST 0 /* Binding Refresh Request */
+#define IP6M_HOME_TEST_INIT 1 /* Home Test Init */
+#define IP6M_CAREOF_TEST_INIT 2 /* Care-of Test Init */
+#define IP6M_HOME_TEST 3 /* Home Test */
+#define IP6M_CAREOF_TEST 4 /* Care-of Test */
+#define IP6M_BINDING_UPDATE 5 /* Binding Update */
+#define IP6M_BINDING_ACK 6 /* Binding Acknowledgement */
+#define IP6M_BINDING_ERROR 7 /* Binding Error */
+
+/* Mobility Header Options */
+#define IP6MOPT_MINLEN 2
+#define IP6MOPT_PAD1 0x0 /* Pad1 */
+#define IP6MOPT_PADN 0x1 /* PadN */
+#define IP6MOPT_REFRESH 0x2 /* Binding Refresh Advice */
+#define IP6MOPT_REFRESH_MINLEN 4
+#define IP6MOPT_ALTCOA 0x3 /* Alternate Care-of Address */
+#define IP6MOPT_ALTCOA_MINLEN 18
+#define IP6MOPT_NONCEID 0x4 /* Nonce Indices */
+#define IP6MOPT_NONCEID_MINLEN 6
+#define IP6MOPT_AUTH 0x5 /* Binding Authorization Data */
+#define IP6MOPT_AUTH_MINLEN 12
+
+static void
+mobility_opt_print(const u_char *bp, int len)
+{
+ int i;
+ int optlen;
+
+ for (i = 0; i < len; i += optlen) {
+ if (bp[i] == IP6MOPT_PAD1)
+ optlen = 1;
+ else {
+ if (i + 1 < len)
+ optlen = bp[i + 1] + 2;
+ else
+ goto trunc;
+ }
+ if (i + optlen > len)
+ goto trunc;
+
+ switch (bp[i]) {
+ case IP6MOPT_PAD1:
+ printf("(pad1)");
+ break;
+ case IP6MOPT_PADN:
+ if (len - i < IP6MOPT_MINLEN) {
+ printf("(padn: trunc)");
+ goto trunc;
+ }
+ printf("(padn)");
+ break;
+ case IP6MOPT_REFRESH:
+ if (len - i < IP6MOPT_REFRESH_MINLEN) {
+ printf("(refresh: trunc)");
+ goto trunc;
+ }
+ /* units of 4 secs */
+ printf("(refresh: %d)",
+ EXTRACT_16BITS(&bp[i+2]) << 2);
+ break;
+ case IP6MOPT_ALTCOA:
+ if (len - i < IP6MOPT_ALTCOA_MINLEN) {
+ printf("(altcoa: trunc)");
+ goto trunc;
+ }
+ printf("(alt-CoA: %s)", ip6addr_string(&bp[i+2]));
+ break;
+ case IP6MOPT_NONCEID:
+ if (len - i < IP6MOPT_NONCEID_MINLEN) {
+ printf("(ni: trunc)");
+ goto trunc;
+ }
+ printf("(ni: ho=0x%04x co=0x%04x)",
+ EXTRACT_16BITS(&bp[i+2]),
+ EXTRACT_16BITS(&bp[i+4]));
+ break;
+ case IP6MOPT_AUTH:
+ if (len - i < IP6MOPT_AUTH_MINLEN) {
+ printf("(auth: trunc)");
+ goto trunc;
+ }
+ printf("(auth)");
+ break;
+ default:
+ if (len - i < IP6MOPT_MINLEN) {
+ printf("(sopt_type %d: trunc)", bp[i]);
+ goto trunc;
+ }
+ printf("(type-0x%02x: len=%d)", bp[i], bp[i + 1]);
+ break;
+ }
+ }
+ return;
+
+trunc:
+ printf("[trunc] ");
+}
+
+/*
+ * Mobility Header
+ */
+int
+mobility_print(const u_char *bp, const u_char *bp2 _U_)
+{
+ const struct ip6_mobility *mh;
+ const u_char *ep;
+ int mhlen, hlen, type;
+
+ mh = (struct ip6_mobility *)bp;
+
+ /* 'ep' points to the end of available data. */
+ ep = snapend;
+
+ if (!TTEST(mh->ip6m_len)) {
+ /*
+ * There's not enough captured data to include the
+ * mobility header length.
+ *
+ * Our caller expects us to return the length, however,
+ * so return a value that will run to the end of the
+ * captured data.
+ *
+ * XXX - "ip6_print()" doesn't do anything with the
+ * returned length, however, as it breaks out of the
+ * header-processing loop.
+ */
+ mhlen = ep - bp;
+ goto trunc;
+ }
+ mhlen = (int)((mh->ip6m_len + 1) << 3);
+
+ /* XXX ip6m_cksum */
+
+ TCHECK(mh->ip6m_type);
+ type = mh->ip6m_type;
+ switch (type) {
+ case IP6M_BINDING_REQUEST:
+ printf("mobility: BRR");
+ hlen = IP6M_MINLEN;
+ break;
+ case IP6M_HOME_TEST_INIT:
+ case IP6M_CAREOF_TEST_INIT:
+ printf("mobility: %soTI",
+ type == IP6M_HOME_TEST_INIT ? "H" : "C");
+ hlen = IP6M_MINLEN;
+ if (vflag) {
+ TCHECK2(*mh, hlen + 8);
+ printf(" %s Init Cookie=%08x:%08x",
+ type == IP6M_HOME_TEST_INIT ? "Home" : "Care-of",
+ EXTRACT_32BITS(&bp[hlen]),
+ EXTRACT_32BITS(&bp[hlen + 4]));
+ }
+ hlen += 8;
+ break;
+ case IP6M_HOME_TEST:
+ case IP6M_CAREOF_TEST:
+ printf("mobility: %soT",
+ type == IP6M_HOME_TEST ? "H" : "C");
+ TCHECK(mh->ip6m_data16[0]);
+ printf(" nonce id=0x%x", EXTRACT_16BITS(&mh->ip6m_data16[0]));
+ hlen = IP6M_MINLEN;
+ if (vflag) {
+ TCHECK2(*mh, hlen + 8);
+ printf(" %s Init Cookie=%08x:%08x",
+ type == IP6M_HOME_TEST ? "Home" : "Care-of",
+ EXTRACT_32BITS(&bp[hlen]),
+ EXTRACT_32BITS(&bp[hlen + 4]));
+ }
+ hlen += 8;
+ if (vflag) {
+ TCHECK2(*mh, hlen + 8);
+ printf(" %s Keygen Token=%08x:%08x",
+ type == IP6M_HOME_TEST ? "Home" : "Care-of",
+ EXTRACT_32BITS(&bp[hlen]),
+ EXTRACT_32BITS(&bp[hlen + 4]));
+ }
+ hlen += 8;
+ break;
+ case IP6M_BINDING_UPDATE:
+ printf("mobility: BU");
+ TCHECK(mh->ip6m_data16[0]);
+ printf(" seq#=%d", EXTRACT_16BITS(&mh->ip6m_data16[0]));
+ hlen = IP6M_MINLEN;
+ TCHECK2(*mh, hlen + 1);
+ if (bp[hlen] & 0xf0)
+ printf(" ");
+ if (bp[hlen] & 0x80)
+ printf("A");
+ if (bp[hlen] & 0x40)
+ printf("H");
+ if (bp[hlen] & 0x20)
+ printf("L");
+ if (bp[hlen] & 0x10)
+ printf("K");
+ /* Reserved (4bits) */
+ hlen += 1;
+ /* Reserved (8bits) */
+ hlen += 1;
+ TCHECK2(*mh, hlen + 2);
+ /* units of 4 secs */
+ printf(" lifetime=%d", EXTRACT_16BITS(&bp[hlen]) << 2);
+ hlen += 2;
+ break;
+ case IP6M_BINDING_ACK:
+ printf("mobility: BA");
+ TCHECK(mh->ip6m_data8[0]);
+ printf(" status=%d", mh->ip6m_data8[0]);
+ if (mh->ip6m_data8[1] & 0x80)
+ printf(" K");
+ /* Reserved (7bits) */
+ hlen = IP6M_MINLEN;
+ TCHECK2(*mh, hlen + 2);
+ printf(" seq#=%d", EXTRACT_16BITS(&bp[hlen]));
+ hlen += 2;
+ TCHECK2(*mh, hlen + 2);
+ /* units of 4 secs */
+ printf(" lifetime=%d", EXTRACT_16BITS(&bp[hlen]) << 2);
+ hlen += 2;
+ break;
+ case IP6M_BINDING_ERROR:
+ printf("mobility: BE");
+ TCHECK(mh->ip6m_data8[0]);
+ printf(" status=%d", mh->ip6m_data8[0]);
+ /* Reserved */
+ hlen = IP6M_MINLEN;
+ TCHECK2(*mh, hlen + 16);
+ printf(" homeaddr %s", ip6addr_string(&bp[hlen]));
+ hlen += 16;
+ break;
+ default:
+ printf("mobility: type-#%d len=%d", type, mh->ip6m_len);
+ return(mhlen);
+ break;
+ }
+ if (vflag)
+ mobility_opt_print(&bp[hlen], mhlen - hlen);
+
+ return(mhlen);
+
+ trunc:
+ fputs("[|MOBILITY]", stdout);
+ return(mhlen);
+}
+#endif /* INET6 */
diff --git a/freebsd/contrib/tcpdump/print-mpcp.c b/freebsd/contrib/tcpdump/print-mpcp.c
new file mode 100644
index 00000000..f9ea1683
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-mpcp.c
@@ -0,0 +1,276 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1998-2006 The TCPDUMP project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * support for the IEEE MPCP protocol as per 802.3ah
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-mpcp.c,v 1.2 2006-02-10 17:24:55 hannes Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+#include "ether.h"
+
+#define MPCP_TIMESTAMP_LEN 4
+#define MPCP_TIMESTAMP_DURATION_LEN 2
+
+struct mpcp_common_header_t {
+ u_int8_t opcode[2];
+ u_int8_t timestamp[MPCP_TIMESTAMP_LEN];
+};
+
+#define MPCP_OPCODE_PAUSE 0x0001
+#define MPCP_OPCODE_GATE 0x0002
+#define MPCP_OPCODE_REPORT 0x0003
+#define MPCP_OPCODE_REG_REQ 0x0004
+#define MPCP_OPCODE_REG 0x0005
+#define MPCP_OPCODE_REG_ACK 0x0006
+
+static const struct tok mpcp_opcode_values[] = {
+ { MPCP_OPCODE_PAUSE, "Pause" },
+ { MPCP_OPCODE_GATE, "Gate" },
+ { MPCP_OPCODE_REPORT, "Report" },
+ { MPCP_OPCODE_REG_REQ, "Register Request" },
+ { MPCP_OPCODE_REG, "Register" },
+ { MPCP_OPCODE_REG_ACK, "Register ACK" },
+ { 0, NULL}
+};
+
+#define MPCP_GRANT_NUMBER_LEN 1
+#define MPCP_GRANT_NUMBER_MASK 0x7
+static const struct tok mpcp_grant_flag_values[] = {
+ { 0x08, "Discovery" },
+ { 0x10, "Force Grant #1" },
+ { 0x20, "Force Grant #2" },
+ { 0x40, "Force Grant #3" },
+ { 0x80, "Force Grant #4" },
+ { 0, NULL}
+};
+
+struct mpcp_grant_t {
+ u_int8_t starttime[MPCP_TIMESTAMP_LEN];
+ u_int8_t duration[MPCP_TIMESTAMP_DURATION_LEN];
+};
+
+struct mpcp_reg_req_t {
+ u_int8_t flags;
+ u_int8_t pending_grants;
+};
+
+
+static const struct tok mpcp_reg_req_flag_values[] = {
+ { 1, "Register" },
+ { 3, "De-Register" },
+ { 0, NULL}
+};
+
+struct mpcp_reg_t {
+ u_int8_t assigned_port[2];
+ u_int8_t flags;
+ u_int8_t sync_time[MPCP_TIMESTAMP_DURATION_LEN];
+ u_int8_t echoed_pending_grants;
+};
+
+static const struct tok mpcp_reg_flag_values[] = {
+ { 1, "Re-Register" },
+ { 2, "De-Register" },
+ { 3, "ACK" },
+ { 4, "NACK" },
+ { 0, NULL}
+};
+
+#define MPCP_REPORT_QUEUESETS_LEN 1
+#define MPCP_REPORT_REPORTBITMAP_LEN 1
+static const struct tok mpcp_report_bitmap_values[] = {
+ { 0x01, "Q0" },
+ { 0x02, "Q1" },
+ { 0x04, "Q2" },
+ { 0x08, "Q3" },
+ { 0x10, "Q4" },
+ { 0x20, "Q5" },
+ { 0x40, "Q6" },
+ { 0x80, "Q7" },
+ { 0, NULL}
+};
+
+struct mpcp_reg_ack_t {
+ u_int8_t flags;
+ u_int8_t echoed_assigned_port[2];
+ u_int8_t echoed_sync_time[MPCP_TIMESTAMP_DURATION_LEN];
+};
+
+static const struct tok mpcp_reg_ack_flag_values[] = {
+ { 0, "NACK" },
+ { 1, "ACK" },
+ { 0, NULL}
+};
+
+void
+mpcp_print(register const u_char *pptr, register u_int length) {
+
+ union {
+ const struct mpcp_common_header_t *common_header;
+ const struct mpcp_grant_t *grant;
+ const struct mpcp_reg_req_t *reg_req;
+ const struct mpcp_reg_t *reg;
+ const struct mpcp_reg_ack_t *reg_ack;
+ } mpcp;
+
+
+ const u_char *tptr;
+ u_int16_t opcode;
+ u_int8_t grant_numbers, grant;
+ u_int8_t queue_sets, queue_set, report_bitmap, report;
+
+ tptr=pptr;
+ mpcp.common_header = (const struct mpcp_common_header_t *)pptr;
+
+ if (!TTEST2(*tptr, sizeof(const struct mpcp_common_header_t)))
+ goto trunc;
+ opcode = EXTRACT_16BITS(mpcp.common_header->opcode);
+ printf("MPCP, Opcode %s", tok2str(mpcp_opcode_values, "Unknown (%u)", opcode));
+ if (opcode != MPCP_OPCODE_PAUSE) {
+ printf(", Timestamp %u ticks", EXTRACT_32BITS(mpcp.common_header->timestamp));
+ }
+ printf(", length %u", length);
+
+ if (!vflag)
+ return;
+
+ tptr += sizeof(const struct mpcp_common_header_t);
+
+ switch (opcode) {
+ case MPCP_OPCODE_PAUSE:
+ break;
+
+ case MPCP_OPCODE_GATE:
+ if (!TTEST2(*tptr, MPCP_GRANT_NUMBER_LEN))
+ goto trunc;
+ grant_numbers = *tptr & MPCP_GRANT_NUMBER_MASK;
+ printf("\n\tGrant Numbers %u, Flags [ %s ]",
+ grant_numbers,
+ bittok2str(mpcp_grant_flag_values,
+ "?",
+ *tptr &~ MPCP_GRANT_NUMBER_MASK));
+ tptr++;
+
+ for (grant = 1; grant <= grant_numbers; grant++) {
+ if (!TTEST2(*tptr, sizeof(const struct mpcp_grant_t)))
+ goto trunc;
+ mpcp.grant = (const struct mpcp_grant_t *)tptr;
+ printf("\n\tGrant #%u, Start-Time %u ticks, duration %u ticks",
+ grant,
+ EXTRACT_32BITS(mpcp.grant->starttime),
+ EXTRACT_16BITS(mpcp.grant->duration));
+ tptr += sizeof(const struct mpcp_grant_t);
+ }
+
+ if (!TTEST2(*tptr, MPCP_TIMESTAMP_DURATION_LEN))
+ goto trunc;
+ printf("\n\tSync-Time %u ticks", EXTRACT_16BITS(tptr));
+ break;
+
+
+ case MPCP_OPCODE_REPORT:
+ if (!TTEST2(*tptr, MPCP_REPORT_QUEUESETS_LEN))
+ goto trunc;
+ queue_sets = *tptr;
+ tptr+=MPCP_REPORT_QUEUESETS_LEN;
+ printf("\n\tTotal Queue-Sets %u", queue_sets);
+
+ for (queue_set = 1; queue_set < queue_sets; queue_set++) {
+ if (!TTEST2(*tptr, MPCP_REPORT_REPORTBITMAP_LEN))
+ goto trunc;
+ report_bitmap = *(tptr);
+ printf("\n\t Queue-Set #%u, Report-Bitmap [ %s ]",
+ queue_sets,
+ bittok2str(mpcp_report_bitmap_values, "Unknown", report_bitmap));
+ tptr++;
+
+ report=1;
+ while (report_bitmap != 0) {
+ if (report_bitmap & 1) {
+ if (!TTEST2(*tptr, MPCP_TIMESTAMP_DURATION_LEN))
+ goto trunc;
+ printf("\n\t Q%u Report, Duration %u ticks",
+ report,
+ EXTRACT_16BITS(tptr));
+ tptr+=MPCP_TIMESTAMP_DURATION_LEN;
+ }
+ report++;
+ report_bitmap = report_bitmap >> 1;
+ }
+ }
+ break;
+
+ case MPCP_OPCODE_REG_REQ:
+ if (!TTEST2(*tptr, sizeof(const struct mpcp_reg_req_t)))
+ goto trunc;
+ mpcp.reg_req = (const struct mpcp_reg_req_t *)tptr;
+ printf("\n\tFlags [ %s ], Pending-Grants %u",
+ bittok2str(mpcp_reg_req_flag_values, "Reserved", mpcp.reg_req->flags),
+ mpcp.reg_req->pending_grants);
+ break;
+
+ case MPCP_OPCODE_REG:
+ if (!TTEST2(*tptr, sizeof(const struct mpcp_reg_t)))
+ goto trunc;
+ mpcp.reg = (const struct mpcp_reg_t *)tptr;
+ printf("\n\tAssigned-Port %u, Flags [ %s ]" \
+ "\n\tSync-Time %u ticks, Echoed-Pending-Grants %u",
+ EXTRACT_16BITS(mpcp.reg->assigned_port),
+ bittok2str(mpcp_reg_flag_values, "Reserved", mpcp.reg->flags),
+ EXTRACT_16BITS(mpcp.reg->sync_time),
+ mpcp.reg->echoed_pending_grants);
+ break;
+
+ case MPCP_OPCODE_REG_ACK:
+ if (!TTEST2(*tptr, sizeof(const struct mpcp_reg_ack_t)))
+ goto trunc;
+ mpcp.reg_ack = (const struct mpcp_reg_ack_t *)tptr;
+ printf("\n\tEchoed-Assigned-Port %u, Flags [ %s ]" \
+ "\n\tEchoed-Sync-Time %u ticks",
+ EXTRACT_16BITS(mpcp.reg_ack->echoed_assigned_port),
+ bittok2str(mpcp_reg_ack_flag_values, "Reserved", mpcp.reg_ack->flags),
+ EXTRACT_16BITS(mpcp.reg_ack->echoed_sync_time));
+ break;
+
+ default:
+ /* unknown opcode - hexdump for now */
+ print_unknown_data(pptr, "\n\t", length);
+ break;
+ }
+
+ return;
+
+trunc:
+ printf("\n\t[|MPCP]");
+}
diff --git a/freebsd/contrib/tcpdump/print-mpls.c b/freebsd/contrib/tcpdump/print-mpls.c
new file mode 100644
index 00000000..3a755f77
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-mpls.c
@@ -0,0 +1,229 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2001 WIDE Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-mpls.c,v 1.14 2005-07-05 09:38:19 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "addrtoname.h"
+#include "interface.h"
+#include "extract.h" /* must come after interface.h */
+#include "mpls.h"
+
+static const char *mpls_labelname[] = {
+/*0*/ "IPv4 explicit NULL", "router alert", "IPv6 explicit NULL",
+ "implicit NULL", "rsvd",
+/*5*/ "rsvd", "rsvd", "rsvd", "rsvd", "rsvd",
+/*10*/ "rsvd", "rsvd", "rsvd", "rsvd", "rsvd",
+/*15*/ "rsvd",
+};
+
+enum mpls_packet_type {
+ PT_UNKNOWN,
+ PT_IPV4,
+ PT_IPV6,
+ PT_OSI
+};
+
+/*
+ * RFC3032: MPLS label stack encoding
+ */
+void
+mpls_print(const u_char *bp, u_int length)
+{
+ const u_char *p;
+ u_int32_t label_entry;
+ u_int16_t label_stack_depth = 0;
+ enum mpls_packet_type pt = PT_UNKNOWN;
+
+ p = bp;
+ printf("MPLS");
+ do {
+ TCHECK2(*p, sizeof(label_entry));
+ label_entry = EXTRACT_32BITS(p);
+ printf("%s(label %u",
+ (label_stack_depth && vflag) ? "\n\t" : " ",
+ MPLS_LABEL(label_entry));
+ label_stack_depth++;
+ if (vflag &&
+ MPLS_LABEL(label_entry) < sizeof(mpls_labelname) / sizeof(mpls_labelname[0]))
+ printf(" (%s)", mpls_labelname[MPLS_LABEL(label_entry)]);
+ printf(", exp %u", MPLS_EXP(label_entry));
+ if (MPLS_STACK(label_entry))
+ printf(", [S]");
+ printf(", ttl %u)", MPLS_TTL(label_entry));
+
+ p += sizeof(label_entry);
+ } while (!MPLS_STACK(label_entry));
+
+ /*
+ * Try to figure out the packet type.
+ */
+ switch (MPLS_LABEL(label_entry)) {
+
+ case 0: /* IPv4 explicit NULL label */
+ case 3: /* IPv4 implicit NULL label */
+ pt = PT_IPV4;
+ break;
+
+ case 2: /* IPv6 explicit NULL label */
+ pt = PT_IPV6;
+ break;
+
+ default:
+ /*
+ * Generally there's no indication of protocol in MPLS label
+ * encoding.
+ *
+ * However, draft-hsmit-isis-aal5mux-00.txt describes a
+ * technique for encapsulating IS-IS and IP traffic on the
+ * same ATM virtual circuit; you look at the first payload
+ * byte to determine the network layer protocol, based on
+ * the fact that
+ *
+ * 1) the first byte of an IP header is 0x45-0x4f
+ * for IPv4 and 0x60-0x6f for IPv6;
+ *
+ * 2) the first byte of an OSI CLNP packet is 0x81,
+ * the first byte of an OSI ES-IS packet is 0x82,
+ * and the first byte of an OSI IS-IS packet is
+ * 0x83;
+ *
+ * so the network layer protocol can be inferred from the
+ * first byte of the packet, if the protocol is one of the
+ * ones listed above.
+ *
+ * Cisco sends control-plane traffic MPLS-encapsulated in
+ * this fashion.
+ */
+ switch(*p) {
+
+ case 0x45:
+ case 0x46:
+ case 0x47:
+ case 0x48:
+ case 0x49:
+ case 0x4a:
+ case 0x4b:
+ case 0x4c:
+ case 0x4d:
+ case 0x4e:
+ case 0x4f:
+ pt = PT_IPV4;
+ break;
+
+ case 0x60:
+ case 0x61:
+ case 0x62:
+ case 0x63:
+ case 0x64:
+ case 0x65:
+ case 0x66:
+ case 0x67:
+ case 0x68:
+ case 0x69:
+ case 0x6a:
+ case 0x6b:
+ case 0x6c:
+ case 0x6d:
+ case 0x6e:
+ case 0x6f:
+ pt = PT_IPV6;
+ break;
+
+ case 0x81:
+ case 0x82:
+ case 0x83:
+ pt = PT_OSI;
+ break;
+
+ default:
+ /* ok bail out - we did not figure out what it is*/
+ break;
+ }
+ }
+
+ /*
+ * Print the payload.
+ */
+ if (pt == PT_UNKNOWN) {
+ if (!suppress_default_print)
+ default_print(p, length - (p - bp));
+ return;
+ }
+ if (vflag)
+ printf("\n\t");
+ else
+ printf(" ");
+ switch (pt) {
+
+ case PT_IPV4:
+ ip_print(gndo, p, length - (p - bp));
+ break;
+
+ case PT_IPV6:
+#ifdef INET6
+ ip6_print(gndo, p, length - (p - bp));
+#else
+ printf("IPv6, length: %u", length);
+#endif
+ break;
+
+ case PT_OSI:
+ isoclns_print(p, length - (p - bp), length - (p - bp));
+ break;
+
+ default:
+ break;
+ }
+ return;
+
+trunc:
+ printf("[|MPLS]");
+}
+
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-msdp.c b/freebsd/contrib/tcpdump/print-msdp.c
new file mode 100644
index 00000000..6269c2c2
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-msdp.c
@@ -0,0 +1,110 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 2001 William C. Fenner.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * The name of William C. Fenner may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ */
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-msdp.c,v 1.7 2005-04-06 21:32:41 mcr Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+#define MSDP_TYPE_MAX 7
+
+void
+msdp_print(const unsigned char *sp, u_int length)
+{
+ unsigned int type, len;
+
+ TCHECK2(*sp, 3);
+ /* See if we think we're at the beginning of a compound packet */
+ type = *sp;
+ len = EXTRACT_16BITS(sp + 1);
+ if (len > 1500 || len < 3 || type == 0 || type > MSDP_TYPE_MAX)
+ goto trunc; /* not really truncated, but still not decodable */
+ (void)printf(" msdp:");
+ while (length > 0) {
+ TCHECK2(*sp, 3);
+ type = *sp;
+ len = EXTRACT_16BITS(sp + 1);
+ if (len > 1400 || vflag)
+ printf(" [len %u]", len);
+ if (len < 3)
+ goto trunc;
+ sp += 3;
+ length -= 3;
+ switch (type) {
+ case 1: /* IPv4 Source-Active */
+ case 3: /* IPv4 Source-Active Response */
+ if (type == 1)
+ (void)printf(" SA");
+ else
+ (void)printf(" SA-Response");
+ TCHECK(*sp);
+ (void)printf(" %u entries", *sp);
+ if ((u_int)((*sp * 12) + 8) < len) {
+ (void)printf(" [w/data]");
+ if (vflag > 1) {
+ (void)printf(" ");
+ ip_print(gndo, sp + *sp * 12 + 8 - 3,
+ len - (*sp * 12 + 8));
+ }
+ }
+ break;
+ case 2:
+ (void)printf(" SA-Request");
+ TCHECK2(*sp, 5);
+ (void)printf(" for %s", ipaddr_string(sp + 1));
+ break;
+ case 4:
+ (void)printf(" Keepalive");
+ if (len != 3)
+ (void)printf("[len=%d] ", len);
+ break;
+ case 5:
+ (void)printf(" Notification");
+ break;
+ default:
+ (void)printf(" [type=%d len=%d]", type, len);
+ break;
+ }
+ sp += (len - 3);
+ length -= (len - 3);
+ }
+ return;
+trunc:
+ (void)printf(" [|msdp]");
+}
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-msnlb.c b/freebsd/contrib/tcpdump/print-msnlb.c
new file mode 100644
index 00000000..c0274a4f
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-msnlb.c
@@ -0,0 +1,68 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 2013 Romain Francoise <romain@orebokech.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "netdissect.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+struct msnlb_heartbeat_pkt {
+ u_int32_t unknown1;
+ u_int32_t unknown2;
+ u_int32_t host_prio; /* little-endian */
+ u_int32_t virtual_ip;
+ u_int32_t host_ip;
+ /* the protocol is undocumented so we ignore the rest */
+};
+
+void
+msnlb_print(netdissect_options *ndo, const u_char *bp, u_int length)
+{
+ const struct msnlb_heartbeat_pkt *hb;
+
+ hb = (struct msnlb_heartbeat_pkt *)bp;
+ ND_TCHECK(*hb);
+
+ ND_PRINT((ndo, "MS NLB heartbeat, host priority: %u,",
+ EXTRACT_LE_32BITS(&(hb->host_prio))));
+ ND_PRINT((ndo, " cluster IP: %s,", ipaddr_string(&(hb->virtual_ip))));
+ ND_PRINT((ndo, " host IP: %s", ipaddr_string(&(hb->host_ip))));
+ return;
+trunc:
+ ND_PRINT((ndo, "[|MS NLB]"));
+}
diff --git a/freebsd/contrib/tcpdump/print-netbios.c b/freebsd/contrib/tcpdump/print-netbios.c
new file mode 100644
index 00000000..fa32d146
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-netbios.c
@@ -0,0 +1,93 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Format and print NETBIOS packets.
+ * Contributed by Brad Parker (brad@fcr.com).
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-netbios.c,v 1.20 2003-11-16 09:36:29 guy Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "netbios.h"
+#include "extract.h"
+
+/*
+ * Print NETBIOS packets.
+ */
+void
+netbios_print(struct p8022Hdr *nb, u_int length)
+{
+ if (length < p8022Size) {
+ (void)printf(" truncated-netbios %d", length);
+ return;
+ }
+
+ if (nb->flags == UI) {
+ (void)printf("802.1 UI ");
+ } else {
+ (void)printf("802.1 CONN ");
+ }
+
+ if ((u_char *)(nb + 1) > snapend) {
+ printf(" [|netbios]");
+ return;
+ }
+
+/*
+ netbios_decode(nb, (u_char *)nb + p8022Size, length - p8022Size);
+*/
+}
+
+#ifdef never
+ (void)printf("%s.%d > ",
+ ipxaddr_string(EXTRACT_32BITS(ipx->srcNet), ipx->srcNode),
+ EXTRACT_16BITS(ipx->srcSkt));
+
+ (void)printf("%s.%d:",
+ ipxaddr_string(EXTRACT_32BITS(ipx->dstNet), ipx->dstNode),
+ EXTRACT_16BITS(ipx->dstSkt));
+
+ if ((u_char *)(ipx + 1) > snapend) {
+ printf(" [|ipx]");
+ return;
+ }
+
+ /* take length from ipx header */
+ length = EXTRACT_16BITS(&ipx->length);
+
+ ipx_decode(ipx, (u_char *)ipx + ipxSize, length - ipxSize);
+#endif
+
diff --git a/freebsd/contrib/tcpdump/print-nfs.c b/freebsd/contrib/tcpdump/print-nfs.c
new file mode 100644
index 00000000..34dbfa6c
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-nfs.c
@@ -0,0 +1,1855 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-nfs.c,v 1.111 2007-12-22 03:08:04 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <pcap.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+#include "nfs.h"
+#include "nfsfh.h"
+
+#include "ip.h"
+#ifdef INET6
+#include "ip6.h"
+#endif
+#include "rpc_auth.h"
+#include "rpc_msg.h"
+
+static void nfs_printfh(const u_int32_t *, const u_int);
+static int xid_map_enter(const struct sunrpc_msg *, const u_char *);
+static int32_t xid_map_find(const struct sunrpc_msg *, const u_char *,
+ u_int32_t *, u_int32_t *);
+static void interp_reply(const struct sunrpc_msg *, u_int32_t, u_int32_t, int);
+static const u_int32_t *parse_post_op_attr(const u_int32_t *, int);
+static void print_sattr3(const struct nfsv3_sattr *sa3, int verbose);
+static void print_nfsaddr(const u_char *, const char *, const char *);
+
+/*
+ * Mapping of old NFS Version 2 RPC numbers to generic numbers.
+ */
+u_int32_t nfsv3_procid[NFS_NPROCS] = {
+ NFSPROC_NULL,
+ NFSPROC_GETATTR,
+ NFSPROC_SETATTR,
+ NFSPROC_NOOP,
+ NFSPROC_LOOKUP,
+ NFSPROC_READLINK,
+ NFSPROC_READ,
+ NFSPROC_NOOP,
+ NFSPROC_WRITE,
+ NFSPROC_CREATE,
+ NFSPROC_REMOVE,
+ NFSPROC_RENAME,
+ NFSPROC_LINK,
+ NFSPROC_SYMLINK,
+ NFSPROC_MKDIR,
+ NFSPROC_RMDIR,
+ NFSPROC_READDIR,
+ NFSPROC_FSSTAT,
+ NFSPROC_NOOP,
+ NFSPROC_NOOP,
+ NFSPROC_NOOP,
+ NFSPROC_NOOP,
+ NFSPROC_NOOP,
+ NFSPROC_NOOP,
+ NFSPROC_NOOP,
+ NFSPROC_NOOP
+};
+
+/*
+ * NFS V2 and V3 status values.
+ *
+ * Some of these come from the RFCs for NFS V2 and V3, with the message
+ * strings taken from the FreeBSD C library "errlst.c".
+ *
+ * Others are errors that are not in the RFC but that I suspect some
+ * NFS servers could return; the values are FreeBSD errno values, as
+ * the first NFS server was the SunOS 2.0 one, and until 5.0 SunOS
+ * was primarily BSD-derived.
+ */
+static struct tok status2str[] = {
+ { 1, "Operation not permitted" }, /* EPERM */
+ { 2, "No such file or directory" }, /* ENOENT */
+ { 5, "Input/output error" }, /* EIO */
+ { 6, "Device not configured" }, /* ENXIO */
+ { 11, "Resource deadlock avoided" }, /* EDEADLK */
+ { 12, "Cannot allocate memory" }, /* ENOMEM */
+ { 13, "Permission denied" }, /* EACCES */
+ { 17, "File exists" }, /* EEXIST */
+ { 18, "Cross-device link" }, /* EXDEV */
+ { 19, "Operation not supported by device" }, /* ENODEV */
+ { 20, "Not a directory" }, /* ENOTDIR */
+ { 21, "Is a directory" }, /* EISDIR */
+ { 22, "Invalid argument" }, /* EINVAL */
+ { 26, "Text file busy" }, /* ETXTBSY */
+ { 27, "File too large" }, /* EFBIG */
+ { 28, "No space left on device" }, /* ENOSPC */
+ { 30, "Read-only file system" }, /* EROFS */
+ { 31, "Too many links" }, /* EMLINK */
+ { 45, "Operation not supported" }, /* EOPNOTSUPP */
+ { 62, "Too many levels of symbolic links" }, /* ELOOP */
+ { 63, "File name too long" }, /* ENAMETOOLONG */
+ { 66, "Directory not empty" }, /* ENOTEMPTY */
+ { 69, "Disc quota exceeded" }, /* EDQUOT */
+ { 70, "Stale NFS file handle" }, /* ESTALE */
+ { 71, "Too many levels of remote in path" }, /* EREMOTE */
+ { 99, "Write cache flushed to disk" }, /* NFSERR_WFLUSH (not used) */
+ { 10001, "Illegal NFS file handle" }, /* NFS3ERR_BADHANDLE */
+ { 10002, "Update synchronization mismatch" }, /* NFS3ERR_NOT_SYNC */
+ { 10003, "READDIR/READDIRPLUS cookie is stale" }, /* NFS3ERR_BAD_COOKIE */
+ { 10004, "Operation not supported" }, /* NFS3ERR_NOTSUPP */
+ { 10005, "Buffer or request is too small" }, /* NFS3ERR_TOOSMALL */
+ { 10006, "Unspecified error on server" }, /* NFS3ERR_SERVERFAULT */
+ { 10007, "Object of that type not supported" }, /* NFS3ERR_BADTYPE */
+ { 10008, "Request couldn't be completed in time" }, /* NFS3ERR_JUKEBOX */
+ { 0, NULL }
+};
+
+static struct tok nfsv3_writemodes[] = {
+ { 0, "unstable" },
+ { 1, "datasync" },
+ { 2, "filesync" },
+ { 0, NULL }
+};
+
+static struct tok type2str[] = {
+ { NFNON, "NON" },
+ { NFREG, "REG" },
+ { NFDIR, "DIR" },
+ { NFBLK, "BLK" },
+ { NFCHR, "CHR" },
+ { NFLNK, "LNK" },
+ { NFFIFO, "FIFO" },
+ { 0, NULL }
+};
+
+static void
+print_nfsaddr(const u_char *bp, const char *s, const char *d)
+{
+ struct ip *ip;
+#ifdef INET6
+ struct ip6_hdr *ip6;
+ char srcaddr[INET6_ADDRSTRLEN], dstaddr[INET6_ADDRSTRLEN];
+#else
+#ifndef INET_ADDRSTRLEN
+#define INET_ADDRSTRLEN 16
+#endif
+ char srcaddr[INET_ADDRSTRLEN], dstaddr[INET_ADDRSTRLEN];
+#endif
+
+ srcaddr[0] = dstaddr[0] = '\0';
+ switch (IP_V((struct ip *)bp)) {
+ case 4:
+ ip = (struct ip *)bp;
+ strlcpy(srcaddr, ipaddr_string(&ip->ip_src), sizeof(srcaddr));
+ strlcpy(dstaddr, ipaddr_string(&ip->ip_dst), sizeof(dstaddr));
+ break;
+#ifdef INET6
+ case 6:
+ ip6 = (struct ip6_hdr *)bp;
+ strlcpy(srcaddr, ip6addr_string(&ip6->ip6_src),
+ sizeof(srcaddr));
+ strlcpy(dstaddr, ip6addr_string(&ip6->ip6_dst),
+ sizeof(dstaddr));
+ break;
+#endif
+ default:
+ strlcpy(srcaddr, "?", sizeof(srcaddr));
+ strlcpy(dstaddr, "?", sizeof(dstaddr));
+ break;
+ }
+
+ (void)printf("%s.%s > %s.%s: ", srcaddr, s, dstaddr, d);
+}
+
+static const u_int32_t *
+parse_sattr3(const u_int32_t *dp, struct nfsv3_sattr *sa3)
+{
+ TCHECK(dp[0]);
+ sa3->sa_modeset = EXTRACT_32BITS(dp);
+ dp++;
+ if (sa3->sa_modeset) {
+ TCHECK(dp[0]);
+ sa3->sa_mode = EXTRACT_32BITS(dp);
+ dp++;
+ }
+
+ TCHECK(dp[0]);
+ sa3->sa_uidset = EXTRACT_32BITS(dp);
+ dp++;
+ if (sa3->sa_uidset) {
+ TCHECK(dp[0]);
+ sa3->sa_uid = EXTRACT_32BITS(dp);
+ dp++;
+ }
+
+ TCHECK(dp[0]);
+ sa3->sa_gidset = EXTRACT_32BITS(dp);
+ dp++;
+ if (sa3->sa_gidset) {
+ TCHECK(dp[0]);
+ sa3->sa_gid = EXTRACT_32BITS(dp);
+ dp++;
+ }
+
+ TCHECK(dp[0]);
+ sa3->sa_sizeset = EXTRACT_32BITS(dp);
+ dp++;
+ if (sa3->sa_sizeset) {
+ TCHECK(dp[0]);
+ sa3->sa_size = EXTRACT_32BITS(dp);
+ dp++;
+ }
+
+ TCHECK(dp[0]);
+ sa3->sa_atimetype = EXTRACT_32BITS(dp);
+ dp++;
+ if (sa3->sa_atimetype == NFSV3SATTRTIME_TOCLIENT) {
+ TCHECK(dp[1]);
+ sa3->sa_atime.nfsv3_sec = EXTRACT_32BITS(dp);
+ dp++;
+ sa3->sa_atime.nfsv3_nsec = EXTRACT_32BITS(dp);
+ dp++;
+ }
+
+ TCHECK(dp[0]);
+ sa3->sa_mtimetype = EXTRACT_32BITS(dp);
+ dp++;
+ if (sa3->sa_mtimetype == NFSV3SATTRTIME_TOCLIENT) {
+ TCHECK(dp[1]);
+ sa3->sa_mtime.nfsv3_sec = EXTRACT_32BITS(dp);
+ dp++;
+ sa3->sa_mtime.nfsv3_nsec = EXTRACT_32BITS(dp);
+ dp++;
+ }
+
+ return dp;
+trunc:
+ return NULL;
+}
+
+static int nfserr; /* true if we error rather than trunc */
+
+static void
+print_sattr3(const struct nfsv3_sattr *sa3, int verbose)
+{
+ if (sa3->sa_modeset)
+ printf(" mode %o", sa3->sa_mode);
+ if (sa3->sa_uidset)
+ printf(" uid %u", sa3->sa_uid);
+ if (sa3->sa_gidset)
+ printf(" gid %u", sa3->sa_gid);
+ if (verbose > 1) {
+ if (sa3->sa_atimetype == NFSV3SATTRTIME_TOCLIENT)
+ printf(" atime %u.%06u", sa3->sa_atime.nfsv3_sec,
+ sa3->sa_atime.nfsv3_nsec);
+ if (sa3->sa_mtimetype == NFSV3SATTRTIME_TOCLIENT)
+ printf(" mtime %u.%06u", sa3->sa_mtime.nfsv3_sec,
+ sa3->sa_mtime.nfsv3_nsec);
+ }
+}
+
+void
+nfsreply_print(register const u_char *bp, u_int length,
+ register const u_char *bp2)
+{
+ register const struct sunrpc_msg *rp;
+ u_int32_t proc, vers, reply_stat;
+ char srcid[20], dstid[20]; /*fits 32bit*/
+ enum sunrpc_reject_stat rstat;
+ u_int32_t rlow;
+ u_int32_t rhigh;
+ enum sunrpc_auth_stat rwhy;
+
+ nfserr = 0; /* assume no error */
+ rp = (const struct sunrpc_msg *)bp;
+
+ TCHECK(rp->rm_xid);
+ if (!nflag) {
+ strlcpy(srcid, "nfs", sizeof(srcid));
+ snprintf(dstid, sizeof(dstid), "%u",
+ EXTRACT_32BITS(&rp->rm_xid));
+ } else {
+ snprintf(srcid, sizeof(srcid), "%u", NFS_PORT);
+ snprintf(dstid, sizeof(dstid), "%u",
+ EXTRACT_32BITS(&rp->rm_xid));
+ }
+ print_nfsaddr(bp2, srcid, dstid);
+ TCHECK(rp->rm_reply.rp_stat);
+ reply_stat = EXTRACT_32BITS(&rp->rm_reply.rp_stat);
+ switch (reply_stat) {
+
+ case SUNRPC_MSG_ACCEPTED:
+ (void)printf("reply ok %u", length);
+ if (xid_map_find(rp, bp2, &proc, &vers) >= 0)
+ interp_reply(rp, proc, vers, length);
+ break;
+
+ case SUNRPC_MSG_DENIED:
+ (void)printf("reply ERR %u: ", length);
+ TCHECK(rp->rm_reply.rp_reject.rj_stat);
+ rstat = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_stat);
+ switch (rstat) {
+
+ case SUNRPC_RPC_MISMATCH:
+ TCHECK(rp->rm_reply.rp_reject.rj_vers.high);
+ rlow = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_vers.low);
+ rhigh = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_vers.high);
+ (void)printf("RPC Version mismatch (%u-%u)",
+ rlow, rhigh);
+ break;
+
+ case SUNRPC_AUTH_ERROR:
+ TCHECK(rp->rm_reply.rp_reject.rj_why);
+ rwhy = EXTRACT_32BITS(&rp->rm_reply.rp_reject.rj_why);
+ (void)printf("Auth ");
+ switch (rwhy) {
+
+ case SUNRPC_AUTH_OK:
+ (void)printf("OK");
+ break;
+
+ case SUNRPC_AUTH_BADCRED:
+ (void)printf("Bogus Credentials (seal broken)");
+ break;
+
+ case SUNRPC_AUTH_REJECTEDCRED:
+ (void)printf("Rejected Credentials (client should begin new session)");
+ break;
+
+ case SUNRPC_AUTH_BADVERF:
+ (void)printf("Bogus Verifier (seal broken)");
+ break;
+
+ case SUNRPC_AUTH_REJECTEDVERF:
+ (void)printf("Verifier expired or was replayed");
+ break;
+
+ case SUNRPC_AUTH_TOOWEAK:
+ (void)printf("Credentials are too weak");
+ break;
+
+ case SUNRPC_AUTH_INVALIDRESP:
+ (void)printf("Bogus response verifier");
+ break;
+
+ case SUNRPC_AUTH_FAILED:
+ (void)printf("Unknown failure");
+ break;
+
+ default:
+ (void)printf("Invalid failure code %u",
+ (unsigned int)rwhy);
+ break;
+ }
+ break;
+
+ default:
+ (void)printf("Unknown reason for rejecting rpc message %u",
+ (unsigned int)rstat);
+ break;
+ }
+ break;
+
+ default:
+ (void)printf("reply Unknown rpc response code=%u %u",
+ reply_stat, length);
+ break;
+ }
+ return;
+
+trunc:
+ if (!nfserr)
+ fputs(" [|nfs]", stdout);
+}
+
+/*
+ * Return a pointer to the first file handle in the packet.
+ * If the packet was truncated, return 0.
+ */
+static const u_int32_t *
+parsereq(register const struct sunrpc_msg *rp, register u_int length)
+{
+ register const u_int32_t *dp;
+ register u_int len;
+
+ /*
+ * find the start of the req data (if we captured it)
+ */
+ dp = (u_int32_t *)&rp->rm_call.cb_cred;
+ TCHECK(dp[1]);
+ len = EXTRACT_32BITS(&dp[1]);
+ if (len < length) {
+ dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp);
+ TCHECK(dp[1]);
+ len = EXTRACT_32BITS(&dp[1]);
+ if (len < length) {
+ dp += (len + (2 * sizeof(*dp) + 3)) / sizeof(*dp);
+ TCHECK2(dp[0], 0);
+ return (dp);
+ }
+ }
+trunc:
+ return (NULL);
+}
+
+/*
+ * Print out an NFS file handle and return a pointer to following word.
+ * If packet was truncated, return 0.
+ */
+static const u_int32_t *
+parsefh(register const u_int32_t *dp, int v3)
+{
+ u_int len;
+
+ if (v3) {
+ TCHECK(dp[0]);
+ len = EXTRACT_32BITS(dp) / 4;
+ dp++;
+ } else
+ len = NFSX_V2FH / 4;
+
+ if (TTEST2(*dp, len * sizeof(*dp))) {
+ nfs_printfh(dp, len);
+ return (dp + len);
+ }
+trunc:
+ return (NULL);
+}
+
+/*
+ * Print out a file name and return pointer to 32-bit word past it.
+ * If packet was truncated, return 0.
+ */
+static const u_int32_t *
+parsefn(register const u_int32_t *dp)
+{
+ register u_int32_t len;
+ register const u_char *cp;
+
+ /* Bail if we don't have the string length */
+ TCHECK(*dp);
+
+ /* Fetch string length; convert to host order */
+ len = *dp++;
+ NTOHL(len);
+
+ TCHECK2(*dp, ((len + 3) & ~3));
+
+ cp = (u_char *)dp;
+ /* Update 32-bit pointer (NFS filenames padded to 32-bit boundaries) */
+ dp += ((len + 3) & ~3) / sizeof(*dp);
+ putchar('"');
+ if (fn_printn(cp, len, snapend)) {
+ putchar('"');
+ goto trunc;
+ }
+ putchar('"');
+
+ return (dp);
+trunc:
+ return NULL;
+}
+
+/*
+ * Print out file handle and file name.
+ * Return pointer to 32-bit word past file name.
+ * If packet was truncated (or there was some other error), return 0.
+ */
+static const u_int32_t *
+parsefhn(register const u_int32_t *dp, int v3)
+{
+ dp = parsefh(dp, v3);
+ if (dp == NULL)
+ return (NULL);
+ putchar(' ');
+ return (parsefn(dp));
+}
+
+void
+nfsreq_print(register const u_char *bp, u_int length,
+ register const u_char *bp2)
+{
+ register const struct sunrpc_msg *rp;
+ register const u_int32_t *dp;
+ nfs_type type;
+ int v3;
+ u_int32_t proc;
+ u_int32_t access_flags;
+ struct nfsv3_sattr sa3;
+ char srcid[20], dstid[20]; /*fits 32bit*/
+
+ nfserr = 0; /* assume no error */
+ rp = (const struct sunrpc_msg *)bp;
+
+ TCHECK(rp->rm_xid);
+ if (!nflag) {
+ snprintf(srcid, sizeof(srcid), "%u",
+ EXTRACT_32BITS(&rp->rm_xid));
+ strlcpy(dstid, "nfs", sizeof(dstid));
+ } else {
+ snprintf(srcid, sizeof(srcid), "%u",
+ EXTRACT_32BITS(&rp->rm_xid));
+ snprintf(dstid, sizeof(dstid), "%u", NFS_PORT);
+ }
+ print_nfsaddr(bp2, srcid, dstid);
+ (void)printf("%d", length);
+
+ if (!xid_map_enter(rp, bp2)) /* record proc number for later on */
+ goto trunc;
+
+ v3 = (EXTRACT_32BITS(&rp->rm_call.cb_vers) == NFS_VER3);
+ proc = EXTRACT_32BITS(&rp->rm_call.cb_proc);
+
+ if (!v3 && proc < NFS_NPROCS)
+ proc = nfsv3_procid[proc];
+
+ switch (proc) {
+ case NFSPROC_NOOP:
+ printf(" nop");
+ return;
+ case NFSPROC_NULL:
+ printf(" null");
+ return;
+
+ case NFSPROC_GETATTR:
+ printf(" getattr");
+ if ((dp = parsereq(rp, length)) != NULL &&
+ parsefh(dp, v3) != NULL)
+ return;
+ break;
+
+ case NFSPROC_SETATTR:
+ printf(" setattr");
+ if ((dp = parsereq(rp, length)) != NULL &&
+ parsefh(dp, v3) != NULL)
+ return;
+ break;
+
+ case NFSPROC_LOOKUP:
+ printf(" lookup");
+ if ((dp = parsereq(rp, length)) != NULL &&
+ parsefhn(dp, v3) != NULL)
+ return;
+ break;
+
+ case NFSPROC_ACCESS:
+ printf(" access");
+ if ((dp = parsereq(rp, length)) != NULL &&
+ (dp = parsefh(dp, v3)) != NULL) {
+ TCHECK(dp[0]);
+ access_flags = EXTRACT_32BITS(&dp[0]);
+ if (access_flags & ~NFSV3ACCESS_FULL) {
+ /* NFSV3ACCESS definitions aren't up to date */
+ printf(" %04x", access_flags);
+ } else if ((access_flags & NFSV3ACCESS_FULL) == NFSV3ACCESS_FULL) {
+ printf(" NFS_ACCESS_FULL");
+ } else {
+ char separator = ' ';
+ if (access_flags & NFSV3ACCESS_READ) {
+ printf(" NFS_ACCESS_READ");
+ separator = '|';
+ }
+ if (access_flags & NFSV3ACCESS_LOOKUP) {
+ printf("%cNFS_ACCESS_LOOKUP", separator);
+ separator = '|';
+ }
+ if (access_flags & NFSV3ACCESS_MODIFY) {
+ printf("%cNFS_ACCESS_MODIFY", separator);
+ separator = '|';
+ }
+ if (access_flags & NFSV3ACCESS_EXTEND) {
+ printf("%cNFS_ACCESS_EXTEND", separator);
+ separator = '|';
+ }
+ if (access_flags & NFSV3ACCESS_DELETE) {
+ printf("%cNFS_ACCESS_DELETE", separator);
+ separator = '|';
+ }
+ if (access_flags & NFSV3ACCESS_EXECUTE)
+ printf("%cNFS_ACCESS_EXECUTE", separator);
+ }
+ return;
+ }
+ break;
+
+ case NFSPROC_READLINK:
+ printf(" readlink");
+ if ((dp = parsereq(rp, length)) != NULL &&
+ parsefh(dp, v3) != NULL)
+ return;
+ break;
+
+ case NFSPROC_READ:
+ printf(" read");
+ if ((dp = parsereq(rp, length)) != NULL &&
+ (dp = parsefh(dp, v3)) != NULL) {
+ if (v3) {
+ TCHECK(dp[2]);
+ printf(" %u bytes @ %" PRIu64,
+ EXTRACT_32BITS(&dp[2]),
+ EXTRACT_64BITS(&dp[0]));
+ } else {
+ TCHECK(dp[1]);
+ printf(" %u bytes @ %u",
+ EXTRACT_32BITS(&dp[1]),
+ EXTRACT_32BITS(&dp[0]));
+ }
+ return;
+ }
+ break;
+
+ case NFSPROC_WRITE:
+ printf(" write");
+ if ((dp = parsereq(rp, length)) != NULL &&
+ (dp = parsefh(dp, v3)) != NULL) {
+ if (v3) {
+ TCHECK(dp[2]);
+ printf(" %u (%u) bytes @ %" PRIu64,
+ EXTRACT_32BITS(&dp[4]),
+ EXTRACT_32BITS(&dp[2]),
+ EXTRACT_64BITS(&dp[0]));
+ if (vflag) {
+ dp += 3;
+ TCHECK(dp[0]);
+ printf(" <%s>",
+ tok2str(nfsv3_writemodes,
+ NULL, EXTRACT_32BITS(dp)));
+ }
+ } else {
+ TCHECK(dp[3]);
+ printf(" %u (%u) bytes @ %u (%u)",
+ EXTRACT_32BITS(&dp[3]),
+ EXTRACT_32BITS(&dp[2]),
+ EXTRACT_32BITS(&dp[1]),
+ EXTRACT_32BITS(&dp[0]));
+ }
+ return;
+ }
+ break;
+
+ case NFSPROC_CREATE:
+ printf(" create");
+ if ((dp = parsereq(rp, length)) != NULL &&
+ parsefhn(dp, v3) != NULL)
+ return;
+ break;
+
+ case NFSPROC_MKDIR:
+ printf(" mkdir");
+ if ((dp = parsereq(rp, length)) != 0 && parsefhn(dp, v3) != 0)
+ return;
+ break;
+
+ case NFSPROC_SYMLINK:
+ printf(" symlink");
+ if ((dp = parsereq(rp, length)) != 0 &&
+ (dp = parsefhn(dp, v3)) != 0) {
+ fputs(" ->", stdout);
+ if (v3 && (dp = parse_sattr3(dp, &sa3)) == 0)
+ break;
+ if (parsefn(dp) == 0)
+ break;
+ if (v3 && vflag)
+ print_sattr3(&sa3, vflag);
+ return;
+ }
+ break;
+
+ case NFSPROC_MKNOD:
+ printf(" mknod");
+ if ((dp = parsereq(rp, length)) != 0 &&
+ (dp = parsefhn(dp, v3)) != 0) {
+ TCHECK(*dp);
+ type = (nfs_type)EXTRACT_32BITS(dp);
+ dp++;
+ if ((dp = parse_sattr3(dp, &sa3)) == 0)
+ break;
+ printf(" %s", tok2str(type2str, "unk-ft %d", type));
+ if (vflag && (type == NFCHR || type == NFBLK)) {
+ TCHECK(dp[1]);
+ printf(" %u/%u",
+ EXTRACT_32BITS(&dp[0]),
+ EXTRACT_32BITS(&dp[1]));
+ dp += 2;
+ }
+ if (vflag)
+ print_sattr3(&sa3, vflag);
+ return;
+ }
+ break;
+
+ case NFSPROC_REMOVE:
+ printf(" remove");
+ if ((dp = parsereq(rp, length)) != NULL &&
+ parsefhn(dp, v3) != NULL)
+ return;
+ break;
+
+ case NFSPROC_RMDIR:
+ printf(" rmdir");
+ if ((dp = parsereq(rp, length)) != NULL &&
+ parsefhn(dp, v3) != NULL)
+ return;
+ break;
+
+ case NFSPROC_RENAME:
+ printf(" rename");
+ if ((dp = parsereq(rp, length)) != NULL &&
+ (dp = parsefhn(dp, v3)) != NULL) {
+ fputs(" ->", stdout);
+ if (parsefhn(dp, v3) != NULL)
+ return;
+ }
+ break;
+
+ case NFSPROC_LINK:
+ printf(" link");
+ if ((dp = parsereq(rp, length)) != NULL &&
+ (dp = parsefh(dp, v3)) != NULL) {
+ fputs(" ->", stdout);
+ if (parsefhn(dp, v3) != NULL)
+ return;
+ }
+ break;
+
+ case NFSPROC_READDIR:
+ printf(" readdir");
+ if ((dp = parsereq(rp, length)) != NULL &&
+ (dp = parsefh(dp, v3)) != NULL) {
+ if (v3) {
+ TCHECK(dp[4]);
+ /*
+ * We shouldn't really try to interpret the
+ * offset cookie here.
+ */
+ printf(" %u bytes @ %" PRId64,
+ EXTRACT_32BITS(&dp[4]),
+ EXTRACT_64BITS(&dp[0]));
+ if (vflag)
+ printf(" verf %08x%08x", dp[2],
+ dp[3]);
+ } else {
+ TCHECK(dp[1]);
+ /*
+ * Print the offset as signed, since -1 is
+ * common, but offsets > 2^31 aren't.
+ */
+ printf(" %u bytes @ %d",
+ EXTRACT_32BITS(&dp[1]),
+ EXTRACT_32BITS(&dp[0]));
+ }
+ return;
+ }
+ break;
+
+ case NFSPROC_READDIRPLUS:
+ printf(" readdirplus");
+ if ((dp = parsereq(rp, length)) != NULL &&
+ (dp = parsefh(dp, v3)) != NULL) {
+ TCHECK(dp[4]);
+ /*
+ * We don't try to interpret the offset
+ * cookie here.
+ */
+ printf(" %u bytes @ %" PRId64,
+ EXTRACT_32BITS(&dp[4]),
+ EXTRACT_64BITS(&dp[0]));
+ if (vflag) {
+ TCHECK(dp[5]);
+ printf(" max %u verf %08x%08x",
+ EXTRACT_32BITS(&dp[5]), dp[2], dp[3]);
+ }
+ return;
+ }
+ break;
+
+ case NFSPROC_FSSTAT:
+ printf(" fsstat");
+ if ((dp = parsereq(rp, length)) != NULL &&
+ parsefh(dp, v3) != NULL)
+ return;
+ break;
+
+ case NFSPROC_FSINFO:
+ printf(" fsinfo");
+ if ((dp = parsereq(rp, length)) != NULL &&
+ parsefh(dp, v3) != NULL)
+ return;
+ break;
+
+ case NFSPROC_PATHCONF:
+ printf(" pathconf");
+ if ((dp = parsereq(rp, length)) != NULL &&
+ parsefh(dp, v3) != NULL)
+ return;
+ break;
+
+ case NFSPROC_COMMIT:
+ printf(" commit");
+ if ((dp = parsereq(rp, length)) != NULL &&
+ (dp = parsefh(dp, v3)) != NULL) {
+ TCHECK(dp[2]);
+ printf(" %u bytes @ %" PRIu64,
+ EXTRACT_32BITS(&dp[2]),
+ EXTRACT_64BITS(&dp[0]));
+ return;
+ }
+ break;
+
+ default:
+ printf(" proc-%u", EXTRACT_32BITS(&rp->rm_call.cb_proc));
+ return;
+ }
+
+trunc:
+ if (!nfserr)
+ fputs(" [|nfs]", stdout);
+}
+
+/*
+ * Print out an NFS file handle.
+ * We assume packet was not truncated before the end of the
+ * file handle pointed to by dp.
+ *
+ * Note: new version (using portable file-handle parser) doesn't produce
+ * generation number. It probably could be made to do that, with some
+ * additional hacking on the parser code.
+ */
+static void
+nfs_printfh(register const u_int32_t *dp, const u_int len)
+{
+ my_fsid fsid;
+ ino_t ino;
+ const char *sfsname = NULL;
+ char *spacep;
+
+ if (uflag) {
+ u_int i;
+ char const *sep = "";
+
+ printf(" fh[");
+ for (i=0; i<len; i++) {
+ (void)printf("%s%x", sep, dp[i]);
+ sep = ":";
+ }
+ printf("]");
+ return;
+ }
+
+ Parse_fh((const u_char *)dp, len, &fsid, &ino, NULL, &sfsname, 0);
+
+ if (sfsname) {
+ /* file system ID is ASCII, not numeric, for this server OS */
+ static char temp[NFSX_V3FHMAX+1];
+
+ /* Make sure string is null-terminated */
+ strncpy(temp, sfsname, NFSX_V3FHMAX);
+ temp[sizeof(temp) - 1] = '\0';
+ /* Remove trailing spaces */
+ spacep = strchr(temp, ' ');
+ if (spacep)
+ *spacep = '\0';
+
+ (void)printf(" fh %s/", temp);
+ } else {
+ (void)printf(" fh %d,%d/",
+ fsid.Fsid_dev.Major, fsid.Fsid_dev.Minor);
+ }
+
+ if(fsid.Fsid_dev.Minor == 257)
+ /* Print the undecoded handle */
+ (void)printf("%s", fsid.Opaque_Handle);
+ else
+ (void)printf("%ld", (long) ino);
+}
+
+/*
+ * Maintain a small cache of recent client.XID.server/proc pairs, to allow
+ * us to match up replies with requests and thus to know how to parse
+ * the reply.
+ */
+
+struct xid_map_entry {
+ u_int32_t xid; /* transaction ID (net order) */
+ int ipver; /* IP version (4 or 6) */
+#ifdef INET6
+ struct in6_addr client; /* client IP address (net order) */
+ struct in6_addr server; /* server IP address (net order) */
+#else
+ struct in_addr client; /* client IP address (net order) */
+ struct in_addr server; /* server IP address (net order) */
+#endif
+ u_int32_t proc; /* call proc number (host order) */
+ u_int32_t vers; /* program version (host order) */
+};
+
+/*
+ * Map entries are kept in an array that we manage as a ring;
+ * new entries are always added at the tail of the ring. Initially,
+ * all the entries are zero and hence don't match anything.
+ */
+
+#define XIDMAPSIZE 64
+
+struct xid_map_entry xid_map[XIDMAPSIZE];
+
+int xid_map_next = 0;
+int xid_map_hint = 0;
+
+static int
+xid_map_enter(const struct sunrpc_msg *rp, const u_char *bp)
+{
+ struct ip *ip = NULL;
+#ifdef INET6
+ struct ip6_hdr *ip6 = NULL;
+#endif
+ struct xid_map_entry *xmep;
+
+ if (!TTEST(rp->rm_call.cb_vers))
+ return (0);
+ switch (IP_V((struct ip *)bp)) {
+ case 4:
+ ip = (struct ip *)bp;
+ break;
+#ifdef INET6
+ case 6:
+ ip6 = (struct ip6_hdr *)bp;
+ break;
+#endif
+ default:
+ return (1);
+ }
+
+ xmep = &xid_map[xid_map_next];
+
+ if (++xid_map_next >= XIDMAPSIZE)
+ xid_map_next = 0;
+
+ xmep->xid = rp->rm_xid;
+ if (ip) {
+ xmep->ipver = 4;
+ memcpy(&xmep->client, &ip->ip_src, sizeof(ip->ip_src));
+ memcpy(&xmep->server, &ip->ip_dst, sizeof(ip->ip_dst));
+ }
+#ifdef INET6
+ else if (ip6) {
+ xmep->ipver = 6;
+ memcpy(&xmep->client, &ip6->ip6_src, sizeof(ip6->ip6_src));
+ memcpy(&xmep->server, &ip6->ip6_dst, sizeof(ip6->ip6_dst));
+ }
+#endif
+ xmep->proc = EXTRACT_32BITS(&rp->rm_call.cb_proc);
+ xmep->vers = EXTRACT_32BITS(&rp->rm_call.cb_vers);
+ return (1);
+}
+
+/*
+ * Returns 0 and puts NFSPROC_xxx in proc return and
+ * version in vers return, or returns -1 on failure
+ */
+static int32_t
+xid_map_find(const struct sunrpc_msg *rp, const u_char *bp, u_int32_t *proc,
+ u_int32_t *vers)
+{
+ int i;
+ struct xid_map_entry *xmep;
+ u_int32_t xid = rp->rm_xid;
+ struct ip *ip = (struct ip *)bp;
+#ifdef INET6
+ struct ip6_hdr *ip6 = (struct ip6_hdr *)bp;
+#endif
+ int cmp;
+
+ /* Start searching from where we last left off */
+ i = xid_map_hint;
+ do {
+ xmep = &xid_map[i];
+ cmp = 1;
+ if (xmep->ipver != IP_V(ip) || xmep->xid != xid)
+ goto nextitem;
+ switch (xmep->ipver) {
+ case 4:
+ if (memcmp(&ip->ip_src, &xmep->server,
+ sizeof(ip->ip_src)) != 0 ||
+ memcmp(&ip->ip_dst, &xmep->client,
+ sizeof(ip->ip_dst)) != 0) {
+ cmp = 0;
+ }
+ break;
+#ifdef INET6
+ case 6:
+ if (memcmp(&ip6->ip6_src, &xmep->server,
+ sizeof(ip6->ip6_src)) != 0 ||
+ memcmp(&ip6->ip6_dst, &xmep->client,
+ sizeof(ip6->ip6_dst)) != 0) {
+ cmp = 0;
+ }
+ break;
+#endif
+ default:
+ cmp = 0;
+ break;
+ }
+ if (cmp) {
+ /* match */
+ xid_map_hint = i;
+ *proc = xmep->proc;
+ *vers = xmep->vers;
+ return 0;
+ }
+ nextitem:
+ if (++i >= XIDMAPSIZE)
+ i = 0;
+ } while (i != xid_map_hint);
+
+ /* search failed */
+ return (-1);
+}
+
+/*
+ * Routines for parsing reply packets
+ */
+
+/*
+ * Return a pointer to the beginning of the actual results.
+ * If the packet was truncated, return 0.
+ */
+static const u_int32_t *
+parserep(register const struct sunrpc_msg *rp, register u_int length)
+{
+ register const u_int32_t *dp;
+ u_int len;
+ enum sunrpc_accept_stat astat;
+
+ /*
+ * Portability note:
+ * Here we find the address of the ar_verf credentials.
+ * Originally, this calculation was
+ * dp = (u_int32_t *)&rp->rm_reply.rp_acpt.ar_verf
+ * On the wire, the rp_acpt field starts immediately after
+ * the (32 bit) rp_stat field. However, rp_acpt (which is a
+ * "struct accepted_reply") contains a "struct opaque_auth",
+ * whose internal representation contains a pointer, so on a
+ * 64-bit machine the compiler inserts 32 bits of padding
+ * before rp->rm_reply.rp_acpt.ar_verf. So, we cannot use
+ * the internal representation to parse the on-the-wire
+ * representation. Instead, we skip past the rp_stat field,
+ * which is an "enum" and so occupies one 32-bit word.
+ */
+ dp = ((const u_int32_t *)&rp->rm_reply) + 1;
+ TCHECK(dp[1]);
+ len = EXTRACT_32BITS(&dp[1]);
+ if (len >= length)
+ return (NULL);
+ /*
+ * skip past the ar_verf credentials.
+ */
+ dp += (len + (2*sizeof(u_int32_t) + 3)) / sizeof(u_int32_t);
+ TCHECK2(dp[0], 0);
+
+ /*
+ * now we can check the ar_stat field
+ */
+ astat = (enum sunrpc_accept_stat) EXTRACT_32BITS(dp);
+ switch (astat) {
+
+ case SUNRPC_SUCCESS:
+ break;
+
+ case SUNRPC_PROG_UNAVAIL:
+ printf(" PROG_UNAVAIL");
+ nfserr = 1; /* suppress trunc string */
+ return (NULL);
+
+ case SUNRPC_PROG_MISMATCH:
+ printf(" PROG_MISMATCH");
+ nfserr = 1; /* suppress trunc string */
+ return (NULL);
+
+ case SUNRPC_PROC_UNAVAIL:
+ printf(" PROC_UNAVAIL");
+ nfserr = 1; /* suppress trunc string */
+ return (NULL);
+
+ case SUNRPC_GARBAGE_ARGS:
+ printf(" GARBAGE_ARGS");
+ nfserr = 1; /* suppress trunc string */
+ return (NULL);
+
+ case SUNRPC_SYSTEM_ERR:
+ printf(" SYSTEM_ERR");
+ nfserr = 1; /* suppress trunc string */
+ return (NULL);
+
+ default:
+ printf(" ar_stat %d", astat);
+ nfserr = 1; /* suppress trunc string */
+ return (NULL);
+ }
+ /* successful return */
+ TCHECK2(*dp, sizeof(astat));
+ return ((u_int32_t *) (sizeof(astat) + ((char *)dp)));
+trunc:
+ return (0);
+}
+
+static const u_int32_t *
+parsestatus(const u_int32_t *dp, int *er)
+{
+ int errnum;
+
+ TCHECK(dp[0]);
+
+ errnum = EXTRACT_32BITS(&dp[0]);
+ if (er)
+ *er = errnum;
+ if (errnum != 0) {
+ if (!qflag)
+ printf(" ERROR: %s",
+ tok2str(status2str, "unk %d", errnum));
+ nfserr = 1;
+ }
+ return (dp + 1);
+trunc:
+ return NULL;
+}
+
+static const u_int32_t *
+parsefattr(const u_int32_t *dp, int verbose, int v3)
+{
+ const struct nfs_fattr *fap;
+
+ fap = (const struct nfs_fattr *)dp;
+ TCHECK(fap->fa_gid);
+ if (verbose) {
+ printf(" %s %o ids %d/%d",
+ tok2str(type2str, "unk-ft %d ",
+ EXTRACT_32BITS(&fap->fa_type)),
+ EXTRACT_32BITS(&fap->fa_mode),
+ EXTRACT_32BITS(&fap->fa_uid),
+ EXTRACT_32BITS(&fap->fa_gid));
+ if (v3) {
+ TCHECK(fap->fa3_size);
+ printf(" sz %" PRIu64,
+ EXTRACT_64BITS((u_int32_t *)&fap->fa3_size));
+ } else {
+ TCHECK(fap->fa2_size);
+ printf(" sz %d", EXTRACT_32BITS(&fap->fa2_size));
+ }
+ }
+ /* print lots more stuff */
+ if (verbose > 1) {
+ if (v3) {
+ TCHECK(fap->fa3_ctime);
+ printf(" nlink %d rdev %d/%d",
+ EXTRACT_32BITS(&fap->fa_nlink),
+ EXTRACT_32BITS(&fap->fa3_rdev.specdata1),
+ EXTRACT_32BITS(&fap->fa3_rdev.specdata2));
+ printf(" fsid %" PRIx64,
+ EXTRACT_64BITS((u_int32_t *)&fap->fa3_fsid));
+ printf(" fileid %" PRIx64,
+ EXTRACT_64BITS((u_int32_t *)&fap->fa3_fileid));
+ printf(" a/m/ctime %u.%06u",
+ EXTRACT_32BITS(&fap->fa3_atime.nfsv3_sec),
+ EXTRACT_32BITS(&fap->fa3_atime.nfsv3_nsec));
+ printf(" %u.%06u",
+ EXTRACT_32BITS(&fap->fa3_mtime.nfsv3_sec),
+ EXTRACT_32BITS(&fap->fa3_mtime.nfsv3_nsec));
+ printf(" %u.%06u",
+ EXTRACT_32BITS(&fap->fa3_ctime.nfsv3_sec),
+ EXTRACT_32BITS(&fap->fa3_ctime.nfsv3_nsec));
+ } else {
+ TCHECK(fap->fa2_ctime);
+ printf(" nlink %d rdev %x fsid %x nodeid %x a/m/ctime",
+ EXTRACT_32BITS(&fap->fa_nlink),
+ EXTRACT_32BITS(&fap->fa2_rdev),
+ EXTRACT_32BITS(&fap->fa2_fsid),
+ EXTRACT_32BITS(&fap->fa2_fileid));
+ printf(" %u.%06u",
+ EXTRACT_32BITS(&fap->fa2_atime.nfsv2_sec),
+ EXTRACT_32BITS(&fap->fa2_atime.nfsv2_usec));
+ printf(" %u.%06u",
+ EXTRACT_32BITS(&fap->fa2_mtime.nfsv2_sec),
+ EXTRACT_32BITS(&fap->fa2_mtime.nfsv2_usec));
+ printf(" %u.%06u",
+ EXTRACT_32BITS(&fap->fa2_ctime.nfsv2_sec),
+ EXTRACT_32BITS(&fap->fa2_ctime.nfsv2_usec));
+ }
+ }
+ return ((const u_int32_t *)((unsigned char *)dp +
+ (v3 ? NFSX_V3FATTR : NFSX_V2FATTR)));
+trunc:
+ return (NULL);
+}
+
+static int
+parseattrstat(const u_int32_t *dp, int verbose, int v3)
+{
+ int er;
+
+ dp = parsestatus(dp, &er);
+ if (dp == NULL)
+ return (0);
+ if (er)
+ return (1);
+
+ return (parsefattr(dp, verbose, v3) != NULL);
+}
+
+static int
+parsediropres(const u_int32_t *dp)
+{
+ int er;
+
+ if (!(dp = parsestatus(dp, &er)))
+ return (0);
+ if (er)
+ return (1);
+
+ dp = parsefh(dp, 0);
+ if (dp == NULL)
+ return (0);
+
+ return (parsefattr(dp, vflag, 0) != NULL);
+}
+
+static int
+parselinkres(const u_int32_t *dp, int v3)
+{
+ int er;
+
+ dp = parsestatus(dp, &er);
+ if (dp == NULL)
+ return(0);
+ if (er)
+ return(1);
+ if (v3 && !(dp = parse_post_op_attr(dp, vflag)))
+ return (0);
+ putchar(' ');
+ return (parsefn(dp) != NULL);
+}
+
+static int
+parsestatfs(const u_int32_t *dp, int v3)
+{
+ const struct nfs_statfs *sfsp;
+ int er;
+
+ dp = parsestatus(dp, &er);
+ if (dp == NULL)
+ return (0);
+ if (!v3 && er)
+ return (1);
+
+ if (qflag)
+ return(1);
+
+ if (v3) {
+ if (vflag)
+ printf(" POST:");
+ if (!(dp = parse_post_op_attr(dp, vflag)))
+ return (0);
+ }
+
+ TCHECK2(*dp, (v3 ? NFSX_V3STATFS : NFSX_V2STATFS));
+
+ sfsp = (const struct nfs_statfs *)dp;
+
+ if (v3) {
+ printf(" tbytes %" PRIu64 " fbytes %" PRIu64 " abytes %" PRIu64,
+ EXTRACT_64BITS((u_int32_t *)&sfsp->sf_tbytes),
+ EXTRACT_64BITS((u_int32_t *)&sfsp->sf_fbytes),
+ EXTRACT_64BITS((u_int32_t *)&sfsp->sf_abytes));
+ if (vflag) {
+ printf(" tfiles %" PRIu64 " ffiles %" PRIu64 " afiles %" PRIu64 " invar %u",
+ EXTRACT_64BITS((u_int32_t *)&sfsp->sf_tfiles),
+ EXTRACT_64BITS((u_int32_t *)&sfsp->sf_ffiles),
+ EXTRACT_64BITS((u_int32_t *)&sfsp->sf_afiles),
+ EXTRACT_32BITS(&sfsp->sf_invarsec));
+ }
+ } else {
+ printf(" tsize %d bsize %d blocks %d bfree %d bavail %d",
+ EXTRACT_32BITS(&sfsp->sf_tsize),
+ EXTRACT_32BITS(&sfsp->sf_bsize),
+ EXTRACT_32BITS(&sfsp->sf_blocks),
+ EXTRACT_32BITS(&sfsp->sf_bfree),
+ EXTRACT_32BITS(&sfsp->sf_bavail));
+ }
+
+ return (1);
+trunc:
+ return (0);
+}
+
+static int
+parserddires(const u_int32_t *dp)
+{
+ int er;
+
+ dp = parsestatus(dp, &er);
+ if (dp == NULL)
+ return (0);
+ if (er)
+ return (1);
+ if (qflag)
+ return (1);
+
+ TCHECK(dp[2]);
+ printf(" offset %x size %d ",
+ EXTRACT_32BITS(&dp[0]), EXTRACT_32BITS(&dp[1]));
+ if (dp[2] != 0)
+ printf(" eof");
+
+ return (1);
+trunc:
+ return (0);
+}
+
+static const u_int32_t *
+parse_wcc_attr(const u_int32_t *dp)
+{
+ printf(" sz %" PRIu64, EXTRACT_64BITS(&dp[0]));
+ printf(" mtime %u.%06u ctime %u.%06u",
+ EXTRACT_32BITS(&dp[2]), EXTRACT_32BITS(&dp[3]),
+ EXTRACT_32BITS(&dp[4]), EXTRACT_32BITS(&dp[5]));
+ return (dp + 6);
+}
+
+/*
+ * Pre operation attributes. Print only if vflag > 1.
+ */
+static const u_int32_t *
+parse_pre_op_attr(const u_int32_t *dp, int verbose)
+{
+ TCHECK(dp[0]);
+ if (!EXTRACT_32BITS(&dp[0]))
+ return (dp + 1);
+ dp++;
+ TCHECK2(*dp, 24);
+ if (verbose > 1) {
+ return parse_wcc_attr(dp);
+ } else {
+ /* If not verbose enough, just skip over wcc_attr */
+ return (dp + 6);
+ }
+trunc:
+ return (NULL);
+}
+
+/*
+ * Post operation attributes are printed if vflag >= 1
+ */
+static const u_int32_t *
+parse_post_op_attr(const u_int32_t *dp, int verbose)
+{
+ TCHECK(dp[0]);
+ if (!EXTRACT_32BITS(&dp[0]))
+ return (dp + 1);
+ dp++;
+ if (verbose) {
+ return parsefattr(dp, verbose, 1);
+ } else
+ return (dp + (NFSX_V3FATTR / sizeof (u_int32_t)));
+trunc:
+ return (NULL);
+}
+
+static const u_int32_t *
+parse_wcc_data(const u_int32_t *dp, int verbose)
+{
+ if (verbose > 1)
+ printf(" PRE:");
+ if (!(dp = parse_pre_op_attr(dp, verbose)))
+ return (0);
+
+ if (verbose)
+ printf(" POST:");
+ return parse_post_op_attr(dp, verbose);
+}
+
+static const u_int32_t *
+parsecreateopres(const u_int32_t *dp, int verbose)
+{
+ int er;
+
+ if (!(dp = parsestatus(dp, &er)))
+ return (0);
+ if (er)
+ dp = parse_wcc_data(dp, verbose);
+ else {
+ TCHECK(dp[0]);
+ if (!EXTRACT_32BITS(&dp[0]))
+ return (dp + 1);
+ dp++;
+ if (!(dp = parsefh(dp, 1)))
+ return (0);
+ if (verbose) {
+ if (!(dp = parse_post_op_attr(dp, verbose)))
+ return (0);
+ if (vflag > 1) {
+ printf(" dir attr:");
+ dp = parse_wcc_data(dp, verbose);
+ }
+ }
+ }
+ return (dp);
+trunc:
+ return (NULL);
+}
+
+static int
+parsewccres(const u_int32_t *dp, int verbose)
+{
+ int er;
+
+ if (!(dp = parsestatus(dp, &er)))
+ return (0);
+ return parse_wcc_data(dp, verbose) != 0;
+}
+
+static const u_int32_t *
+parsev3rddirres(const u_int32_t *dp, int verbose)
+{
+ int er;
+
+ if (!(dp = parsestatus(dp, &er)))
+ return (0);
+ if (vflag)
+ printf(" POST:");
+ if (!(dp = parse_post_op_attr(dp, verbose)))
+ return (0);
+ if (er)
+ return dp;
+ if (vflag) {
+ TCHECK(dp[1]);
+ printf(" verf %08x%08x", dp[0], dp[1]);
+ dp += 2;
+ }
+ return dp;
+trunc:
+ return (NULL);
+}
+
+static int
+parsefsinfo(const u_int32_t *dp)
+{
+ struct nfsv3_fsinfo *sfp;
+ int er;
+
+ if (!(dp = parsestatus(dp, &er)))
+ return (0);
+ if (vflag)
+ printf(" POST:");
+ if (!(dp = parse_post_op_attr(dp, vflag)))
+ return (0);
+ if (er)
+ return (1);
+
+ sfp = (struct nfsv3_fsinfo *)dp;
+ TCHECK(*sfp);
+ printf(" rtmax %u rtpref %u wtmax %u wtpref %u dtpref %u",
+ EXTRACT_32BITS(&sfp->fs_rtmax),
+ EXTRACT_32BITS(&sfp->fs_rtpref),
+ EXTRACT_32BITS(&sfp->fs_wtmax),
+ EXTRACT_32BITS(&sfp->fs_wtpref),
+ EXTRACT_32BITS(&sfp->fs_dtpref));
+ if (vflag) {
+ printf(" rtmult %u wtmult %u maxfsz %" PRIu64,
+ EXTRACT_32BITS(&sfp->fs_rtmult),
+ EXTRACT_32BITS(&sfp->fs_wtmult),
+ EXTRACT_64BITS((u_int32_t *)&sfp->fs_maxfilesize));
+ printf(" delta %u.%06u ",
+ EXTRACT_32BITS(&sfp->fs_timedelta.nfsv3_sec),
+ EXTRACT_32BITS(&sfp->fs_timedelta.nfsv3_nsec));
+ }
+ return (1);
+trunc:
+ return (0);
+}
+
+static int
+parsepathconf(const u_int32_t *dp)
+{
+ int er;
+ struct nfsv3_pathconf *spp;
+
+ if (!(dp = parsestatus(dp, &er)))
+ return (0);
+ if (vflag)
+ printf(" POST:");
+ if (!(dp = parse_post_op_attr(dp, vflag)))
+ return (0);
+ if (er)
+ return (1);
+
+ spp = (struct nfsv3_pathconf *)dp;
+ TCHECK(*spp);
+
+ printf(" linkmax %u namemax %u %s %s %s %s",
+ EXTRACT_32BITS(&spp->pc_linkmax),
+ EXTRACT_32BITS(&spp->pc_namemax),
+ EXTRACT_32BITS(&spp->pc_notrunc) ? "notrunc" : "",
+ EXTRACT_32BITS(&spp->pc_chownrestricted) ? "chownres" : "",
+ EXTRACT_32BITS(&spp->pc_caseinsensitive) ? "igncase" : "",
+ EXTRACT_32BITS(&spp->pc_casepreserving) ? "keepcase" : "");
+ return (1);
+trunc:
+ return (0);
+}
+
+static void
+interp_reply(const struct sunrpc_msg *rp, u_int32_t proc, u_int32_t vers, int length)
+{
+ register const u_int32_t *dp;
+ register int v3;
+ int er;
+
+ v3 = (vers == NFS_VER3);
+
+ if (!v3 && proc < NFS_NPROCS)
+ proc = nfsv3_procid[proc];
+
+ switch (proc) {
+
+ case NFSPROC_NOOP:
+ printf(" nop");
+ return;
+
+ case NFSPROC_NULL:
+ printf(" null");
+ return;
+
+ case NFSPROC_GETATTR:
+ printf(" getattr");
+ dp = parserep(rp, length);
+ if (dp != NULL && parseattrstat(dp, !qflag, v3) != 0)
+ return;
+ break;
+
+ case NFSPROC_SETATTR:
+ printf(" setattr");
+ if (!(dp = parserep(rp, length)))
+ return;
+ if (v3) {
+ if (parsewccres(dp, vflag))
+ return;
+ } else {
+ if (parseattrstat(dp, !qflag, 0) != 0)
+ return;
+ }
+ break;
+
+ case NFSPROC_LOOKUP:
+ printf(" lookup");
+ if (!(dp = parserep(rp, length)))
+ break;
+ if (v3) {
+ if (!(dp = parsestatus(dp, &er)))
+ break;
+ if (er) {
+ if (vflag > 1) {
+ printf(" post dattr:");
+ dp = parse_post_op_attr(dp, vflag);
+ }
+ } else {
+ if (!(dp = parsefh(dp, v3)))
+ break;
+ if ((dp = parse_post_op_attr(dp, vflag)) &&
+ vflag > 1) {
+ printf(" post dattr:");
+ dp = parse_post_op_attr(dp, vflag);
+ }
+ }
+ if (dp)
+ return;
+ } else {
+ if (parsediropres(dp) != 0)
+ return;
+ }
+ break;
+
+ case NFSPROC_ACCESS:
+ printf(" access");
+ if (!(dp = parserep(rp, length)))
+ break;
+ if (!(dp = parsestatus(dp, &er)))
+ break;
+ if (vflag)
+ printf(" attr:");
+ if (!(dp = parse_post_op_attr(dp, vflag)))
+ break;
+ if (!er)
+ printf(" c %04x", EXTRACT_32BITS(&dp[0]));
+ return;
+
+ case NFSPROC_READLINK:
+ printf(" readlink");
+ dp = parserep(rp, length);
+ if (dp != NULL && parselinkres(dp, v3) != 0)
+ return;
+ break;
+
+ case NFSPROC_READ:
+ printf(" read");
+ if (!(dp = parserep(rp, length)))
+ break;
+ if (v3) {
+ if (!(dp = parsestatus(dp, &er)))
+ break;
+ if (!(dp = parse_post_op_attr(dp, vflag)))
+ break;
+ if (er)
+ return;
+ if (vflag) {
+ TCHECK(dp[1]);
+ printf(" %u bytes", EXTRACT_32BITS(&dp[0]));
+ if (EXTRACT_32BITS(&dp[1]))
+ printf(" EOF");
+ }
+ return;
+ } else {
+ if (parseattrstat(dp, vflag, 0) != 0)
+ return;
+ }
+ break;
+
+ case NFSPROC_WRITE:
+ printf(" write");
+ if (!(dp = parserep(rp, length)))
+ break;
+ if (v3) {
+ if (!(dp = parsestatus(dp, &er)))
+ break;
+ if (!(dp = parse_wcc_data(dp, vflag)))
+ break;
+ if (er)
+ return;
+ if (vflag) {
+ TCHECK(dp[0]);
+ printf(" %u bytes", EXTRACT_32BITS(&dp[0]));
+ if (vflag > 1) {
+ TCHECK(dp[1]);
+ printf(" <%s>",
+ tok2str(nfsv3_writemodes,
+ NULL, EXTRACT_32BITS(&dp[1])));
+ }
+ return;
+ }
+ } else {
+ if (parseattrstat(dp, vflag, v3) != 0)
+ return;
+ }
+ break;
+
+ case NFSPROC_CREATE:
+ printf(" create");
+ if (!(dp = parserep(rp, length)))
+ break;
+ if (v3) {
+ if (parsecreateopres(dp, vflag) != 0)
+ return;
+ } else {
+ if (parsediropres(dp) != 0)
+ return;
+ }
+ break;
+
+ case NFSPROC_MKDIR:
+ printf(" mkdir");
+ if (!(dp = parserep(rp, length)))
+ break;
+ if (v3) {
+ if (parsecreateopres(dp, vflag) != 0)
+ return;
+ } else {
+ if (parsediropres(dp) != 0)
+ return;
+ }
+ break;
+
+ case NFSPROC_SYMLINK:
+ printf(" symlink");
+ if (!(dp = parserep(rp, length)))
+ break;
+ if (v3) {
+ if (parsecreateopres(dp, vflag) != 0)
+ return;
+ } else {
+ if (parsestatus(dp, &er) != 0)
+ return;
+ }
+ break;
+
+ case NFSPROC_MKNOD:
+ printf(" mknod");
+ if (!(dp = parserep(rp, length)))
+ break;
+ if (parsecreateopres(dp, vflag) != 0)
+ return;
+ break;
+
+ case NFSPROC_REMOVE:
+ printf(" remove");
+ if (!(dp = parserep(rp, length)))
+ break;
+ if (v3) {
+ if (parsewccres(dp, vflag))
+ return;
+ } else {
+ if (parsestatus(dp, &er) != 0)
+ return;
+ }
+ break;
+
+ case NFSPROC_RMDIR:
+ printf(" rmdir");
+ if (!(dp = parserep(rp, length)))
+ break;
+ if (v3) {
+ if (parsewccres(dp, vflag))
+ return;
+ } else {
+ if (parsestatus(dp, &er) != 0)
+ return;
+ }
+ break;
+
+ case NFSPROC_RENAME:
+ printf(" rename");
+ if (!(dp = parserep(rp, length)))
+ break;
+ if (v3) {
+ if (!(dp = parsestatus(dp, &er)))
+ break;
+ if (vflag) {
+ printf(" from:");
+ if (!(dp = parse_wcc_data(dp, vflag)))
+ break;
+ printf(" to:");
+ if (!(dp = parse_wcc_data(dp, vflag)))
+ break;
+ }
+ return;
+ } else {
+ if (parsestatus(dp, &er) != 0)
+ return;
+ }
+ break;
+
+ case NFSPROC_LINK:
+ printf(" link");
+ if (!(dp = parserep(rp, length)))
+ break;
+ if (v3) {
+ if (!(dp = parsestatus(dp, &er)))
+ break;
+ if (vflag) {
+ printf(" file POST:");
+ if (!(dp = parse_post_op_attr(dp, vflag)))
+ break;
+ printf(" dir:");
+ if (!(dp = parse_wcc_data(dp, vflag)))
+ break;
+ return;
+ }
+ } else {
+ if (parsestatus(dp, &er) != 0)
+ return;
+ }
+ break;
+
+ case NFSPROC_READDIR:
+ printf(" readdir");
+ if (!(dp = parserep(rp, length)))
+ break;
+ if (v3) {
+ if (parsev3rddirres(dp, vflag))
+ return;
+ } else {
+ if (parserddires(dp) != 0)
+ return;
+ }
+ break;
+
+ case NFSPROC_READDIRPLUS:
+ printf(" readdirplus");
+ if (!(dp = parserep(rp, length)))
+ break;
+ if (parsev3rddirres(dp, vflag))
+ return;
+ break;
+
+ case NFSPROC_FSSTAT:
+ printf(" fsstat");
+ dp = parserep(rp, length);
+ if (dp != NULL && parsestatfs(dp, v3) != 0)
+ return;
+ break;
+
+ case NFSPROC_FSINFO:
+ printf(" fsinfo");
+ dp = parserep(rp, length);
+ if (dp != NULL && parsefsinfo(dp) != 0)
+ return;
+ break;
+
+ case NFSPROC_PATHCONF:
+ printf(" pathconf");
+ dp = parserep(rp, length);
+ if (dp != NULL && parsepathconf(dp) != 0)
+ return;
+ break;
+
+ case NFSPROC_COMMIT:
+ printf(" commit");
+ dp = parserep(rp, length);
+ if (dp != NULL && parsewccres(dp, vflag) != 0)
+ return;
+ break;
+
+ default:
+ printf(" proc-%u", proc);
+ return;
+ }
+trunc:
+ if (!nfserr)
+ fputs(" [|nfs]", stdout);
+}
diff --git a/freebsd/contrib/tcpdump/print-ntp.c b/freebsd/contrib/tcpdump/print-ntp.c
new file mode 100644
index 00000000..9c37de1d
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-ntp.c
@@ -0,0 +1,312 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Format and print ntp packets.
+ * By Jeffrey Mogul/DECWRL
+ * loosely based on print-bootp.c
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ntp.c,v 1.43 2007-11-30 13:45:10 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+#ifdef HAVE_STRFTIME
+#include <time.h>
+#endif
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+#ifdef MODEMASK
+#undef MODEMASK /* Solaris sucks */
+#endif
+#include "ntp.h"
+
+static void p_sfix(const struct s_fixedpt *);
+static void p_ntp_time(const struct l_fixedpt *);
+static void p_ntp_delta(const struct l_fixedpt *, const struct l_fixedpt *);
+
+static struct tok ntp_mode_values[] = {
+ { MODE_UNSPEC, "unspecified" },
+ { MODE_SYM_ACT, "symmetric active" },
+ { MODE_SYM_PAS, "symmetric passive" },
+ { MODE_CLIENT, "Client" },
+ { MODE_SERVER, "Server" },
+ { MODE_BROADCAST, "Broadcast" },
+ { MODE_RES1, "Reserved" },
+ { MODE_RES2, "Reserved" },
+ { 0, NULL }
+};
+
+static struct tok ntp_leapind_values[] = {
+ { NO_WARNING, "" },
+ { PLUS_SEC, "+1s" },
+ { MINUS_SEC, "-1s" },
+ { ALARM, "clock unsynchronized" },
+ { 0, NULL }
+};
+
+static struct tok ntp_stratum_values[] = {
+ { UNSPECIFIED, "unspecified" },
+ { PRIM_REF, "primary reference" },
+ { 0, NULL }
+};
+
+/*
+ * Print ntp requests
+ */
+void
+ntp_print(register const u_char *cp, u_int length)
+{
+ register const struct ntpdata *bp;
+ int mode, version, leapind;
+
+ bp = (struct ntpdata *)cp;
+
+ TCHECK(bp->status);
+
+ version = (int)(bp->status & VERSIONMASK) >> 3;
+ printf("NTPv%d", version);
+
+ mode = bp->status & MODEMASK;
+ if (!vflag) {
+ printf (", %s, length %u",
+ tok2str(ntp_mode_values, "Unknown mode", mode),
+ length);
+ return;
+ }
+
+ printf (", length %u\n\t%s",
+ length,
+ tok2str(ntp_mode_values, "Unknown mode", mode));
+
+ leapind = bp->status & LEAPMASK;
+ printf (", Leap indicator: %s (%u)",
+ tok2str(ntp_leapind_values, "Unknown", leapind),
+ leapind);
+
+ TCHECK(bp->stratum);
+ printf(", Stratum %u (%s)",
+ bp->stratum,
+ tok2str(ntp_stratum_values, (bp->stratum >=2 && bp->stratum<=15) ? "secondary reference" : "reserved", bp->stratum));
+
+ TCHECK(bp->ppoll);
+ printf(", poll %u (%us)", bp->ppoll, 1 << bp->ppoll);
+
+ /* Can't TCHECK bp->precision bitfield so bp->distance + 0 instead */
+ TCHECK2(bp->root_delay, 0);
+ printf(", precision %d", bp->precision);
+
+ TCHECK(bp->root_delay);
+ fputs("\n\tRoot Delay: ", stdout);
+ p_sfix(&bp->root_delay);
+
+ TCHECK(bp->root_dispersion);
+ fputs(", Root dispersion: ", stdout);
+ p_sfix(&bp->root_dispersion);
+
+ TCHECK(bp->refid);
+ fputs(", Reference-ID: ", stdout);
+ /* Interpretation depends on stratum */
+ switch (bp->stratum) {
+
+ case UNSPECIFIED:
+ printf("(unspec)");
+ break;
+
+ case PRIM_REF:
+ if (fn_printn((u_char *)&(bp->refid), 4, snapend))
+ goto trunc;
+ break;
+
+ case INFO_QUERY:
+ printf("%s INFO_QUERY", ipaddr_string(&(bp->refid)));
+ /* this doesn't have more content */
+ return;
+
+ case INFO_REPLY:
+ printf("%s INFO_REPLY", ipaddr_string(&(bp->refid)));
+ /* this is too complex to be worth printing */
+ return;
+
+ default:
+ printf("%s", ipaddr_string(&(bp->refid)));
+ break;
+ }
+
+ TCHECK(bp->ref_timestamp);
+ fputs("\n\t Reference Timestamp: ", stdout);
+ p_ntp_time(&(bp->ref_timestamp));
+
+ TCHECK(bp->org_timestamp);
+ fputs("\n\t Originator Timestamp: ", stdout);
+ p_ntp_time(&(bp->org_timestamp));
+
+ TCHECK(bp->rec_timestamp);
+ fputs("\n\t Receive Timestamp: ", stdout);
+ p_ntp_time(&(bp->rec_timestamp));
+
+ TCHECK(bp->xmt_timestamp);
+ fputs("\n\t Transmit Timestamp: ", stdout);
+ p_ntp_time(&(bp->xmt_timestamp));
+
+ fputs("\n\t Originator - Receive Timestamp: ", stdout);
+ p_ntp_delta(&(bp->org_timestamp), &(bp->rec_timestamp));
+
+ fputs("\n\t Originator - Transmit Timestamp: ", stdout);
+ p_ntp_delta(&(bp->org_timestamp), &(bp->xmt_timestamp));
+
+ if ( (sizeof(struct ntpdata) - length) == 16) { /* Optional: key-id */
+ TCHECK(bp->key_id);
+ printf("\n\tKey id: %u", bp->key_id);
+ } else if ( (sizeof(struct ntpdata) - length) == 0) { /* Optional: key-id + authentication */
+ TCHECK(bp->key_id);
+ printf("\n\tKey id: %u", bp->key_id);
+ TCHECK2(bp->message_digest, sizeof (bp->message_digest));
+ printf("\n\tAuthentication: %08x%08x%08x%08x",
+ EXTRACT_32BITS(bp->message_digest),
+ EXTRACT_32BITS(bp->message_digest + 4),
+ EXTRACT_32BITS(bp->message_digest + 8),
+ EXTRACT_32BITS(bp->message_digest + 12));
+ }
+ return;
+
+trunc:
+ fputs(" [|ntp]", stdout);
+}
+
+static void
+p_sfix(register const struct s_fixedpt *sfp)
+{
+ register int i;
+ register int f;
+ register float ff;
+
+ i = EXTRACT_16BITS(&sfp->int_part);
+ f = EXTRACT_16BITS(&sfp->fraction);
+ ff = f / 65536.0; /* shift radix point by 16 bits */
+ f = ff * 1000000.0; /* Treat fraction as parts per million */
+ printf("%d.%06d", i, f);
+}
+
+#define FMAXINT (4294967296.0) /* floating point rep. of MAXINT */
+
+static void
+p_ntp_time(register const struct l_fixedpt *lfp)
+{
+ register int32_t i;
+ register u_int32_t uf;
+ register u_int32_t f;
+ register float ff;
+
+ i = EXTRACT_32BITS(&lfp->int_part);
+ uf = EXTRACT_32BITS(&lfp->fraction);
+ ff = uf;
+ if (ff < 0.0) /* some compilers are buggy */
+ ff += FMAXINT;
+ ff = ff / FMAXINT; /* shift radix point by 32 bits */
+ f = ff * 1000000000.0; /* treat fraction as parts per billion */
+ printf("%u.%09d", i, f);
+
+#ifdef HAVE_STRFTIME
+ /*
+ * print the time in human-readable format.
+ */
+ if (i) {
+ time_t seconds = i - JAN_1970;
+ struct tm *tm;
+ char time_buf[128];
+
+ tm = localtime(&seconds);
+ strftime(time_buf, sizeof (time_buf), "%Y/%m/%d %H:%M:%S", tm);
+ printf (" (%s)", time_buf);
+ }
+#endif
+}
+
+/* Prints time difference between *lfp and *olfp */
+static void
+p_ntp_delta(register const struct l_fixedpt *olfp,
+ register const struct l_fixedpt *lfp)
+{
+ register int32_t i;
+ register u_int32_t u, uf;
+ register u_int32_t ou, ouf;
+ register u_int32_t f;
+ register float ff;
+ int signbit;
+
+ u = EXTRACT_32BITS(&lfp->int_part);
+ ou = EXTRACT_32BITS(&olfp->int_part);
+ uf = EXTRACT_32BITS(&lfp->fraction);
+ ouf = EXTRACT_32BITS(&olfp->fraction);
+ if (ou == 0 && ouf == 0) {
+ p_ntp_time(lfp);
+ return;
+ }
+
+ i = u - ou;
+
+ if (i > 0) { /* new is definitely greater than old */
+ signbit = 0;
+ f = uf - ouf;
+ if (ouf > uf) /* must borrow from high-order bits */
+ i -= 1;
+ } else if (i < 0) { /* new is definitely less than old */
+ signbit = 1;
+ f = ouf - uf;
+ if (uf > ouf) /* must carry into the high-order bits */
+ i += 1;
+ i = -i;
+ } else { /* int_part is zero */
+ if (uf > ouf) {
+ signbit = 0;
+ f = uf - ouf;
+ } else {
+ signbit = 1;
+ f = ouf - uf;
+ }
+ }
+
+ ff = f;
+ if (ff < 0.0) /* some compilers are buggy */
+ ff += FMAXINT;
+ ff = ff / FMAXINT; /* shift radix point by 32 bits */
+ f = ff * 1000000000.0; /* treat fraction as parts per billion */
+ if (signbit)
+ putchar('-');
+ else
+ putchar('+');
+ printf("%d.%09d", i, f);
+}
+
diff --git a/freebsd/contrib/tcpdump/print-null.c b/freebsd/contrib/tcpdump/print-null.c
new file mode 100644
index 00000000..ac727077
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-null.c
@@ -0,0 +1,164 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1991, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-null.c,v 1.57 2006-03-23 14:58:44 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <pcap.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+#include "ip.h"
+#ifdef INET6
+#include "ip6.h"
+#endif
+#include "af.h"
+
+/*
+ * The DLT_NULL packet header is 4 bytes long. It contains a host-byte-order
+ * 32-bit integer that specifies the family, e.g. AF_INET.
+ *
+ * Note here that "host" refers to the host on which the packets were
+ * captured; that isn't necessarily *this* host.
+ *
+ * The OpenBSD DLT_LOOP packet header is the same, except that the integer
+ * is in network byte order.
+ */
+#define NULL_HDRLEN 4
+
+/*
+ * Byte-swap a 32-bit number.
+ * ("htonl()" or "ntohl()" won't work - we want to byte-swap even on
+ * big-endian platforms.)
+ */
+#define SWAPLONG(y) \
+((((y)&0xff)<<24) | (((y)&0xff00)<<8) | (((y)&0xff0000)>>8) | (((y)>>24)&0xff))
+
+static inline void
+null_hdr_print(u_int family, u_int length)
+{
+ if (!qflag) {
+ (void)printf("AF %s (%u)",
+ tok2str(bsd_af_values,"Unknown",family),family);
+ } else {
+ (void)printf("%s",
+ tok2str(bsd_af_values,"Unknown AF %u",family));
+ }
+
+ (void)printf(", length %u: ", length);
+}
+
+/*
+ * This is the top level routine of the printer. 'p' points
+ * to the ether header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ */
+u_int
+null_if_print(const struct pcap_pkthdr *h, const u_char *p)
+{
+ u_int length = h->len;
+ u_int caplen = h->caplen;
+ u_int family;
+
+ if (caplen < NULL_HDRLEN) {
+ printf("[|null]");
+ return (NULL_HDRLEN);
+ }
+
+ memcpy((char *)&family, (char *)p, sizeof(family));
+
+ /*
+ * This isn't necessarily in our host byte order; if this is
+ * a DLT_LOOP capture, it's in network byte order, and if
+ * this is a DLT_NULL capture from a machine with the opposite
+ * byte-order, it's in the opposite byte order from ours.
+ *
+ * If the upper 16 bits aren't all zero, assume it's byte-swapped.
+ */
+ if ((family & 0xFFFF0000) != 0)
+ family = SWAPLONG(family);
+
+ if (eflag)
+ null_hdr_print(family, length);
+
+ length -= NULL_HDRLEN;
+ caplen -= NULL_HDRLEN;
+ p += NULL_HDRLEN;
+
+ switch (family) {
+
+ case BSD_AFNUM_INET:
+ ip_print(gndo, p, length);
+ break;
+
+#ifdef INET6
+ case BSD_AFNUM_INET6_BSD:
+ case BSD_AFNUM_INET6_FREEBSD:
+ case BSD_AFNUM_INET6_DARWIN:
+ ip6_print(gndo, p, length);
+ break;
+#endif
+
+ case BSD_AFNUM_ISO:
+ isoclns_print(p, length, caplen);
+ break;
+
+ case BSD_AFNUM_APPLETALK:
+ atalk_print(p, length);
+ break;
+
+ case BSD_AFNUM_IPX:
+ ipx_print(p, length);
+ break;
+
+ default:
+ /* unknown AF_ value */
+ if (!eflag)
+ null_hdr_print(family, length + NULL_HDRLEN);
+ if (!suppress_default_print)
+ default_print(p, caplen);
+ }
+
+ return (NULL_HDRLEN);
+}
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-olsr.c b/freebsd/contrib/tcpdump/print-olsr.c
new file mode 100644
index 00000000..962c4d0e
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-olsr.c
@@ -0,0 +1,628 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1998-2007 The TCPDUMP project
+ * Copyright (c) 2009 Florian Forster
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Optimized Link State Protocl (OLSR) as per rfc3626
+ *
+ * Original code by Hannes Gredler <hannes@juniper.net>
+ * IPv6 additions by Florian Forster <octo at verplant.org>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+#include "ip.h"
+
+/*
+ * RFC 3626 common header
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Packet Length | Packet Sequence Number |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Message Type | Vtime | Message Size |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Originator Address |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Time To Live | Hop Count | Message Sequence Number |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * : MESSAGE :
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Message Type | Vtime | Message Size |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Originator Address |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Time To Live | Hop Count | Message Sequence Number |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | |
+ * : MESSAGE :
+ * | |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * : :
+ */
+
+struct olsr_common {
+ u_int8_t packet_len[2];
+ u_int8_t packet_seq[2];
+};
+
+#define OLSR_HELLO_MSG 1 /* rfc3626 */
+#define OLSR_TC_MSG 2 /* rfc3626 */
+#define OLSR_MID_MSG 3 /* rfc3626 */
+#define OLSR_HNA_MSG 4 /* rfc3626 */
+#define OLSR_POWERINFO_MSG 128
+#define OLSR_NAMESERVICE_MSG 130
+#define OLSR_HELLO_LQ_MSG 201 /* LQ extensions olsr.org */
+#define OLSR_TC_LQ_MSG 202 /* LQ extensions olsr.org */
+
+static struct tok olsr_msg_values[] = {
+ { OLSR_HELLO_MSG, "Hello" },
+ { OLSR_TC_MSG, "TC" },
+ { OLSR_MID_MSG, "MID" },
+ { OLSR_HNA_MSG, "HNA" },
+ { OLSR_POWERINFO_MSG, "Powerinfo" },
+ { OLSR_NAMESERVICE_MSG, "Nameservice" },
+ { OLSR_HELLO_LQ_MSG, "Hello-LQ" },
+ { OLSR_TC_LQ_MSG, "TC-LQ" },
+ { 0, NULL}
+};
+
+struct olsr_msg4 {
+ u_int8_t msg_type;
+ u_int8_t vtime;
+ u_int8_t msg_len[2];
+ u_int8_t originator[4];
+ u_int8_t ttl;
+ u_int8_t hopcount;
+ u_int8_t msg_seq[2];
+};
+
+struct olsr_msg6 {
+ u_int8_t msg_type;
+ u_int8_t vtime;
+ u_int8_t msg_len[2];
+ u_int8_t originator[16];
+ u_int8_t ttl;
+ u_int8_t hopcount;
+ u_int8_t msg_seq[2];
+};
+
+struct olsr_hello {
+ u_int8_t res[2];
+ u_int8_t htime;
+ u_int8_t will;
+};
+
+struct olsr_hello_link {
+ u_int8_t link_code;
+ u_int8_t res;
+ u_int8_t len[2];
+};
+
+struct olsr_tc {
+ u_int8_t ans_seq[2];
+ u_int8_t res[2];
+};
+
+struct olsr_hna4 {
+ u_int8_t network[4];
+ u_int8_t mask[4];
+};
+
+struct olsr_hna6 {
+ u_int8_t network[16];
+ u_int8_t mask[16];
+};
+
+
+#define OLSR_EXTRACT_LINK_TYPE(link_code) (link_code & 0x3)
+#define OLSR_EXTRACT_NEIGHBOR_TYPE(link_code) (link_code >> 2)
+
+static struct tok olsr_link_type_values[] = {
+ { 0, "Unspecified" },
+ { 1, "Asymmetric" },
+ { 2, "Symmetric" },
+ { 3, "Lost" },
+ { 0, NULL}
+};
+
+static struct tok olsr_neighbor_type_values[] = {
+ { 0, "Not-Neighbor" },
+ { 1, "Symmetric" },
+ { 2, "Symmetric-MPR" },
+ { 0, NULL}
+};
+
+struct olsr_lq_neighbor4 {
+ u_int8_t neighbor[4];
+ u_int8_t link_quality;
+ u_int8_t neighbor_link_quality;
+ u_int8_t res[2];
+};
+
+struct olsr_lq_neighbor6 {
+ u_int8_t neighbor[16];
+ u_int8_t link_quality;
+ u_int8_t neighbor_link_quality;
+ u_int8_t res[2];
+};
+
+/*
+ * macro to convert the 8-bit mantissa/exponent to a double float
+ * taken from olsr.org.
+ */
+#define VTIME_SCALE_FACTOR 0.0625
+#define ME_TO_DOUBLE(me) \
+ (double)(VTIME_SCALE_FACTOR*(1+(double)(me>>4)/16)*(double)(1<<(me&0x0F)))
+
+/*
+ * print a neighbor list with LQ extensions.
+ */
+static void
+olsr_print_lq_neighbor4 (const u_char *msg_data, u_int hello_len)
+{
+ struct olsr_lq_neighbor4 *lq_neighbor;
+
+ while (hello_len >= sizeof(struct olsr_lq_neighbor4)) {
+
+ lq_neighbor = (struct olsr_lq_neighbor4 *)msg_data;
+
+ printf("\n\t neighbor %s, link-quality %.2lf%%"
+ ", neighbor-link-quality %.2lf%%",
+ ipaddr_string(lq_neighbor->neighbor),
+ ((double)lq_neighbor->link_quality/2.55),
+ ((double)lq_neighbor->neighbor_link_quality/2.55));
+
+ msg_data += sizeof(struct olsr_lq_neighbor4);
+ hello_len -= sizeof(struct olsr_lq_neighbor4);
+ }
+}
+
+#if INET6
+static void
+olsr_print_lq_neighbor6 (const u_char *msg_data, u_int hello_len)
+{
+ struct olsr_lq_neighbor6 *lq_neighbor;
+
+ while (hello_len >= sizeof(struct olsr_lq_neighbor6)) {
+
+ lq_neighbor = (struct olsr_lq_neighbor6 *)msg_data;
+
+ printf("\n\t neighbor %s, link-quality %.2lf%%"
+ ", neighbor-link-quality %.2lf%%",
+ ip6addr_string(lq_neighbor->neighbor),
+ ((double)lq_neighbor->link_quality/2.55),
+ ((double)lq_neighbor->neighbor_link_quality/2.55));
+
+ msg_data += sizeof(struct olsr_lq_neighbor6);
+ hello_len -= sizeof(struct olsr_lq_neighbor6);
+ }
+}
+#endif /* INET6 */
+
+/*
+ * print a neighbor list.
+ */
+static void
+olsr_print_neighbor (const u_char *msg_data, u_int hello_len)
+{
+ int neighbor;
+
+ printf("\n\t neighbor\n\t\t");
+ neighbor = 1;
+
+ while (hello_len >= sizeof(struct in_addr)) {
+
+ /* print 4 neighbors per line */
+
+ printf("%s%s", ipaddr_string(msg_data),
+ neighbor % 4 == 0 ? "\n\t\t" : " ");
+
+ msg_data += sizeof(struct in_addr);
+ hello_len -= sizeof(struct in_addr);
+ }
+}
+
+
+void
+olsr_print (const u_char *pptr, u_int length, int is_ipv6)
+{
+ union {
+ const struct olsr_common *common;
+ const struct olsr_msg4 *msg4;
+ const struct olsr_msg6 *msg6;
+ const struct olsr_hello *hello;
+ const struct olsr_hello_link *hello_link;
+ const struct olsr_tc *tc;
+ const struct olsr_hna4 *hna;
+ } ptr;
+
+ u_int msg_type, msg_len, msg_tlen, hello_len;
+ u_int16_t name_entry_type, name_entry_len;
+ u_int name_entry_padding;
+ u_int8_t link_type, neighbor_type;
+ const u_char *tptr, *msg_data;
+
+ tptr = pptr;
+
+ if (length < sizeof(struct olsr_common)) {
+ goto trunc;
+ }
+
+ if (!TTEST2(*tptr, sizeof(struct olsr_common))) {
+ goto trunc;
+ }
+
+ ptr.common = (struct olsr_common *)tptr;
+ length = MIN(length, EXTRACT_16BITS(ptr.common->packet_len));
+
+ printf("OLSRv%i, seq 0x%04x, length %u",
+ (is_ipv6 == 0) ? 4 : 6,
+ EXTRACT_16BITS(ptr.common->packet_seq),
+ length);
+
+ tptr += sizeof(struct olsr_common);
+
+ /*
+ * In non-verbose mode, just print version.
+ */
+ if (vflag < 1) {
+ return;
+ }
+
+ while (tptr < (pptr+length)) {
+ union
+ {
+ struct olsr_msg4 *v4;
+ struct olsr_msg6 *v6;
+ } msgptr;
+ int msg_len_valid = 0;
+
+ if (!TTEST2(*tptr, sizeof(struct olsr_msg4)))
+ goto trunc;
+
+#if INET6
+ if (is_ipv6)
+ {
+ msgptr.v6 = (struct olsr_msg6 *) tptr;
+ msg_type = msgptr.v6->msg_type;
+ msg_len = EXTRACT_16BITS(msgptr.v6->msg_len);
+ if ((msg_len >= sizeof (struct olsr_msg6))
+ && (msg_len <= length))
+ msg_len_valid = 1;
+
+ /* infinite loop check */
+ if (msg_type == 0 || msg_len == 0) {
+ return;
+ }
+
+ printf("\n\t%s Message (%#04x), originator %s, ttl %u, hop %u"
+ "\n\t vtime %.3lfs, msg-seq 0x%04x, length %u%s",
+ tok2str(olsr_msg_values, "Unknown", msg_type),
+ msg_type, ip6addr_string(msgptr.v6->originator),
+ msgptr.v6->ttl,
+ msgptr.v6->hopcount,
+ ME_TO_DOUBLE(msgptr.v6->vtime),
+ EXTRACT_16BITS(msgptr.v6->msg_seq),
+ msg_len, (msg_len_valid == 0) ? " (invalid)" : "");
+
+ msg_tlen = msg_len - sizeof(struct olsr_msg6);
+ msg_data = tptr + sizeof(struct olsr_msg6);
+ }
+ else /* (!is_ipv6) */
+#endif /* INET6 */
+ {
+ msgptr.v4 = (struct olsr_msg4 *) tptr;
+ msg_type = msgptr.v4->msg_type;
+ msg_len = EXTRACT_16BITS(msgptr.v4->msg_len);
+ if ((msg_len >= sizeof (struct olsr_msg4))
+ && (msg_len <= length))
+ msg_len_valid = 1;
+
+ /* infinite loop check */
+ if (msg_type == 0 || msg_len == 0) {
+ return;
+ }
+
+ printf("\n\t%s Message (%#04x), originator %s, ttl %u, hop %u"
+ "\n\t vtime %.3lfs, msg-seq 0x%04x, length %u%s",
+ tok2str(olsr_msg_values, "Unknown", msg_type),
+ msg_type, ipaddr_string(msgptr.v4->originator),
+ msgptr.v4->ttl,
+ msgptr.v4->hopcount,
+ ME_TO_DOUBLE(msgptr.v4->vtime),
+ EXTRACT_16BITS(msgptr.v4->msg_seq),
+ msg_len, (msg_len_valid == 0) ? " (invalid)" : "");
+
+ msg_tlen = msg_len - sizeof(struct olsr_msg4);
+ msg_data = tptr + sizeof(struct olsr_msg4);
+ }
+
+ switch (msg_type) {
+ case OLSR_HELLO_MSG:
+ case OLSR_HELLO_LQ_MSG:
+ if (!TTEST2(*msg_data, sizeof(struct olsr_hello)))
+ goto trunc;
+
+ ptr.hello = (struct olsr_hello *)msg_data;
+ printf("\n\t hello-time %.3lfs, MPR willingness %u",
+ ME_TO_DOUBLE(ptr.hello->htime), ptr.hello->will);
+ msg_data += sizeof(struct olsr_hello);
+ msg_tlen -= sizeof(struct olsr_hello);
+
+ while (msg_tlen >= sizeof(struct olsr_hello_link)) {
+ int hello_len_valid = 0;
+
+ /*
+ * link-type.
+ */
+ if (!TTEST2(*msg_data, sizeof(struct olsr_hello_link)))
+ goto trunc;
+
+ ptr.hello_link = (struct olsr_hello_link *)msg_data;
+
+ hello_len = EXTRACT_16BITS(ptr.hello_link->len);
+ link_type = OLSR_EXTRACT_LINK_TYPE(ptr.hello_link->link_code);
+ neighbor_type = OLSR_EXTRACT_NEIGHBOR_TYPE(ptr.hello_link->link_code);
+
+ if ((hello_len <= msg_tlen)
+ && (hello_len >= sizeof(struct olsr_hello_link)))
+ hello_len_valid = 1;
+
+ printf("\n\t link-type %s, neighbor-type %s, len %u%s",
+ tok2str(olsr_link_type_values, "Unknown", link_type),
+ tok2str(olsr_neighbor_type_values, "Unknown", neighbor_type),
+ hello_len,
+ (hello_len_valid == 0) ? " (invalid)" : "");
+
+ if (hello_len_valid == 0)
+ break;
+
+ msg_data += sizeof(struct olsr_hello_link);
+ msg_tlen -= sizeof(struct olsr_hello_link);
+ hello_len -= sizeof(struct olsr_hello_link);
+
+ if (msg_type == OLSR_HELLO_MSG) {
+ olsr_print_neighbor(msg_data, hello_len);
+ } else {
+#if INET6
+ if (is_ipv6)
+ olsr_print_lq_neighbor6(msg_data, hello_len);
+ else
+#endif
+ olsr_print_lq_neighbor4(msg_data, hello_len);
+ }
+
+ msg_data += hello_len;
+ msg_tlen -= hello_len;
+ }
+ break;
+
+ case OLSR_TC_MSG:
+ case OLSR_TC_LQ_MSG:
+ if (!TTEST2(*msg_data, sizeof(struct olsr_tc)))
+ goto trunc;
+
+ ptr.tc = (struct olsr_tc *)msg_data;
+ printf("\n\t advertised neighbor seq 0x%04x",
+ EXTRACT_16BITS(ptr.tc->ans_seq));
+ msg_data += sizeof(struct olsr_tc);
+ msg_tlen -= sizeof(struct olsr_tc);
+
+ if (msg_type == OLSR_TC_MSG) {
+ olsr_print_neighbor(msg_data, msg_tlen);
+ } else {
+#if INET6
+ if (is_ipv6)
+ olsr_print_lq_neighbor6(msg_data, msg_tlen);
+ else
+#endif
+ olsr_print_lq_neighbor4(msg_data, msg_tlen);
+ }
+ break;
+
+ case OLSR_MID_MSG:
+ {
+ size_t addr_size = sizeof(struct in_addr);
+
+#if INET6
+ if (is_ipv6)
+ addr_size = sizeof(struct in6_addr);
+#endif
+
+ while (msg_tlen >= addr_size) {
+ if (!TTEST2(*msg_data, addr_size))
+ goto trunc;
+
+ printf("\n\t interface address %s",
+#if INET6
+ is_ipv6 ? ip6addr_string(msg_data) :
+#endif
+ ipaddr_string(msg_data));
+ msg_data += addr_size;
+ msg_tlen -= addr_size;
+ }
+ break;
+ }
+
+ case OLSR_HNA_MSG:
+ printf("\n\t Advertised networks (total %u)",
+ (unsigned int) (msg_tlen / sizeof(struct olsr_hna6)));
+#if INET6
+ if (is_ipv6)
+ {
+ int i = 0;
+ while (msg_tlen >= sizeof(struct olsr_hna6)) {
+ struct olsr_hna6 *hna6;
+
+ if (!TTEST2(*msg_data, sizeof(struct olsr_hna6)))
+ goto trunc;
+
+ hna6 = (struct olsr_hna6 *)msg_data;
+
+ printf("\n\t #%i: %s/%u",
+ i, ip6addr_string(hna6->network),
+ mask62plen (hna6->mask));
+
+ msg_data += sizeof(struct olsr_hna6);
+ msg_tlen -= sizeof(struct olsr_hna6);
+ }
+ }
+ else
+#endif
+ {
+ int col = 0;
+ while (msg_tlen >= sizeof(struct olsr_hna4)) {
+ if (!TTEST2(*msg_data, sizeof(struct olsr_hna4)))
+ goto trunc;
+
+ ptr.hna = (struct olsr_hna4 *)msg_data;
+
+ /* print 4 prefixes per line */
+ if (col == 0)
+ printf ("\n\t ");
+ else
+ printf (", ");
+
+ printf("%s/%u",
+ ipaddr_string(ptr.hna->network),
+ mask2plen(EXTRACT_32BITS(ptr.hna->mask)));
+
+ msg_data += sizeof(struct olsr_hna4);
+ msg_tlen -= sizeof(struct olsr_hna4);
+
+ col = (col + 1) % 4;
+ }
+ }
+ break;
+
+ case OLSR_NAMESERVICE_MSG:
+ {
+ u_int name_entries = EXTRACT_16BITS(msg_data+2);
+ u_int addr_size = 4;
+ int name_entries_valid = 0;
+ u_int i;
+
+ if (is_ipv6)
+ addr_size = 16;
+
+ if ((name_entries > 0)
+ && ((name_entries * (4 + addr_size)) <= msg_tlen))
+ name_entries_valid = 1;
+
+ if (msg_tlen < 4)
+ goto trunc;
+ if (!TTEST2(*msg_data, 4))
+ goto trunc;
+
+ printf("\n\t Version %u, Entries %u%s",
+ EXTRACT_16BITS(msg_data),
+ name_entries, (name_entries_valid == 0) ? " (invalid)" : "");
+
+ if (name_entries_valid == 0)
+ break;
+
+ msg_data += 4;
+ msg_tlen -= 4;
+
+ for (i = 0; i < name_entries; i++) {
+ int name_entry_len_valid = 0;
+
+ if (msg_tlen < 4)
+ break;
+ if (!TTEST2(*msg_data, 4))
+ goto trunc;
+
+ name_entry_type = EXTRACT_16BITS(msg_data);
+ name_entry_len = EXTRACT_16BITS(msg_data+2);
+
+ msg_data += 4;
+ msg_tlen -= 4;
+
+ if ((name_entry_len > 0) && ((addr_size + name_entry_len) <= msg_tlen))
+ name_entry_len_valid = 1;
+
+ printf("\n\t #%u: type %#06x, length %u%s",
+ (unsigned int) i, name_entry_type,
+ name_entry_len, (name_entry_len_valid == 0) ? " (invalid)" : "");
+
+ if (name_entry_len_valid == 0)
+ break;
+
+ /* 32-bit alignment */
+ name_entry_padding = 0;
+ if (name_entry_len%4 != 0)
+ name_entry_padding = 4-(name_entry_len%4);
+
+ if (msg_tlen < addr_size + name_entry_len + name_entry_padding)
+ goto trunc;
+
+ if (!TTEST2(*msg_data, addr_size + name_entry_len + name_entry_padding))
+ goto trunc;
+
+#if INET6
+ if (is_ipv6)
+ printf(", address %s, name \"",
+ ip6addr_string(msg_data));
+ else
+#endif
+ printf(", address %s, name \"",
+ ipaddr_string(msg_data));
+ fn_printn(msg_data + addr_size, name_entry_len, NULL);
+ printf("\"");
+
+ msg_data += addr_size + name_entry_len + name_entry_padding;
+ msg_tlen -= addr_size + name_entry_len + name_entry_padding;
+ } /* for (i = 0; i < name_entries; i++) */
+ break;
+ } /* case OLSR_NAMESERVICE_MSG */
+
+ /*
+ * FIXME those are the defined messages that lack a decoder
+ * you are welcome to contribute code ;-)
+ */
+ case OLSR_POWERINFO_MSG:
+ default:
+ print_unknown_data(msg_data, "\n\t ", msg_tlen);
+ break;
+ } /* switch (msg_type) */
+ tptr += msg_len;
+ } /* while (tptr < (pptr+length)) */
+
+ return;
+
+ trunc:
+ printf("[|olsr]");
+}
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-ospf.c b/freebsd/contrib/tcpdump/print-ospf.c
new file mode 100644
index 00000000..769a29f0
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-ospf.c
@@ -0,0 +1,1159 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ospf.c,v 1.66 2007-10-08 07:53:21 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+#include "gmpls.h"
+
+#include "ospf.h"
+
+#include "ip.h"
+
+static struct tok ospf_option_values[] = {
+ { OSPF_OPTION_T, "MultiTopology" }, /* draft-ietf-ospf-mt-09 */
+ { OSPF_OPTION_E, "External" },
+ { OSPF_OPTION_MC, "Multicast" },
+ { OSPF_OPTION_NP, "NSSA" },
+ { OSPF_OPTION_L, "LLS" },
+ { OSPF_OPTION_DC, "Demand Circuit" },
+ { OSPF_OPTION_O, "Opaque" },
+ { OSPF_OPTION_DN, "Up/Down" },
+ { 0, NULL }
+};
+
+static struct tok ospf_authtype_values[] = {
+ { OSPF_AUTH_NONE, "none" },
+ { OSPF_AUTH_SIMPLE, "simple" },
+ { OSPF_AUTH_MD5, "MD5" },
+ { 0, NULL }
+};
+
+static struct tok ospf_rla_flag_values[] = {
+ { RLA_FLAG_B, "ABR" },
+ { RLA_FLAG_E, "ASBR" },
+ { RLA_FLAG_W1, "Virtual" },
+ { RLA_FLAG_W2, "W2" },
+ { 0, NULL }
+};
+
+static struct tok type2str[] = {
+ { OSPF_TYPE_UMD, "UMD" },
+ { OSPF_TYPE_HELLO, "Hello" },
+ { OSPF_TYPE_DD, "Database Description" },
+ { OSPF_TYPE_LS_REQ, "LS-Request" },
+ { OSPF_TYPE_LS_UPDATE, "LS-Update" },
+ { OSPF_TYPE_LS_ACK, "LS-Ack" },
+ { 0, NULL }
+};
+
+static struct tok lsa_values[] = {
+ { LS_TYPE_ROUTER, "Router" },
+ { LS_TYPE_NETWORK, "Network" },
+ { LS_TYPE_SUM_IP, "Summary" },
+ { LS_TYPE_SUM_ABR, "ASBR Summary" },
+ { LS_TYPE_ASE, "External" },
+ { LS_TYPE_GROUP, "Multicast Group" },
+ { LS_TYPE_NSSA, "NSSA" },
+ { LS_TYPE_OPAQUE_LL, "Link Local Opaque" },
+ { LS_TYPE_OPAQUE_AL, "Area Local Opaque" },
+ { LS_TYPE_OPAQUE_DW, "Domain Wide Opaque" },
+ { 0, NULL }
+};
+
+static struct tok ospf_dd_flag_values[] = {
+ { OSPF_DB_INIT, "Init" },
+ { OSPF_DB_MORE, "More" },
+ { OSPF_DB_MASTER, "Master" },
+ { OSPF_DB_RESYNC, "OOBResync" },
+ { 0, NULL }
+};
+
+static struct tok lsa_opaque_values[] = {
+ { LS_OPAQUE_TYPE_TE, "Traffic Engineering" },
+ { LS_OPAQUE_TYPE_GRACE, "Graceful restart" },
+ { LS_OPAQUE_TYPE_RI, "Router Information" },
+ { 0, NULL }
+};
+
+static struct tok lsa_opaque_te_tlv_values[] = {
+ { LS_OPAQUE_TE_TLV_ROUTER, "Router Address" },
+ { LS_OPAQUE_TE_TLV_LINK, "Link" },
+ { 0, NULL }
+};
+
+static struct tok lsa_opaque_te_link_tlv_subtlv_values[] = {
+ { LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE, "Link Type" },
+ { LS_OPAQUE_TE_LINK_SUBTLV_LINK_ID, "Link ID" },
+ { LS_OPAQUE_TE_LINK_SUBTLV_LOCAL_IP, "Local Interface IP address" },
+ { LS_OPAQUE_TE_LINK_SUBTLV_REMOTE_IP, "Remote Interface IP address" },
+ { LS_OPAQUE_TE_LINK_SUBTLV_TE_METRIC, "Traffic Engineering Metric" },
+ { LS_OPAQUE_TE_LINK_SUBTLV_MAX_BW, "Maximum Bandwidth" },
+ { LS_OPAQUE_TE_LINK_SUBTLV_MAX_RES_BW, "Maximum Reservable Bandwidth" },
+ { LS_OPAQUE_TE_LINK_SUBTLV_UNRES_BW, "Unreserved Bandwidth" },
+ { LS_OPAQUE_TE_LINK_SUBTLV_ADMIN_GROUP, "Administrative Group" },
+ { LS_OPAQUE_TE_LINK_SUBTLV_LINK_LOCAL_REMOTE_ID, "Link Local/Remote Identifier" },
+ { LS_OPAQUE_TE_LINK_SUBTLV_LINK_PROTECTION_TYPE, "Link Protection Type" },
+ { LS_OPAQUE_TE_LINK_SUBTLV_INTF_SW_CAP_DESCR, "Interface Switching Capability" },
+ { LS_OPAQUE_TE_LINK_SUBTLV_SHARED_RISK_GROUP, "Shared Risk Link Group" },
+ { LS_OPAQUE_TE_LINK_SUBTLV_BW_CONSTRAINTS, "Bandwidth Constraints" },
+ { 0, NULL }
+};
+
+static struct tok lsa_opaque_grace_tlv_values[] = {
+ { LS_OPAQUE_GRACE_TLV_PERIOD, "Grace Period" },
+ { LS_OPAQUE_GRACE_TLV_REASON, "Graceful restart Reason" },
+ { LS_OPAQUE_GRACE_TLV_INT_ADDRESS, "IPv4 interface address" },
+ { 0, NULL }
+};
+
+static struct tok lsa_opaque_grace_tlv_reason_values[] = {
+ { LS_OPAQUE_GRACE_TLV_REASON_UNKNOWN, "Unknown" },
+ { LS_OPAQUE_GRACE_TLV_REASON_SW_RESTART, "Software Restart" },
+ { LS_OPAQUE_GRACE_TLV_REASON_SW_UPGRADE, "Software Reload/Upgrade" },
+ { LS_OPAQUE_GRACE_TLV_REASON_CP_SWITCH, "Control Processor Switch" },
+ { 0, NULL }
+};
+
+static struct tok lsa_opaque_te_tlv_link_type_sub_tlv_values[] = {
+ { LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_PTP, "Point-to-point" },
+ { LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE_MA, "Multi-Access" },
+ { 0, NULL }
+};
+
+static struct tok lsa_opaque_ri_tlv_values[] = {
+ { LS_OPAQUE_RI_TLV_CAP, "Router Capabilities" },
+ { 0, NULL }
+};
+
+static struct tok lsa_opaque_ri_tlv_cap_values[] = {
+ { 1, "Reserved" },
+ { 2, "Reserved" },
+ { 4, "Reserved" },
+ { 8, "Reserved" },
+ { 16, "graceful restart capable" },
+ { 32, "graceful restart helper" },
+ { 64, "Stub router support" },
+ { 128, "Traffic engineering" },
+ { 256, "p2p over LAN" },
+ { 512, "path computation server" },
+ { 0, NULL }
+};
+
+static struct tok ospf_lls_tlv_values[] = {
+ { OSPF_LLS_EO, "Extended Options" },
+ { OSPF_LLS_MD5, "MD5 Authentication" },
+ { 0, NULL }
+};
+
+static struct tok ospf_lls_eo_options[] = {
+ { OSPF_LLS_EO_LR, "LSDB resync" },
+ { OSPF_LLS_EO_RS, "Restart" },
+ { 0, NULL }
+};
+
+static char tstr[] = " [|ospf2]";
+
+#ifdef WIN32
+#define inline __inline
+#endif /* WIN32 */
+
+static int ospf_print_lshdr(const struct lsa_hdr *);
+static const u_char *ospf_print_lsa(const struct lsa *);
+static int ospf_decode_v2(const struct ospfhdr *, const u_char *);
+static int ospf_decode_lls(const struct ospfhdr *, register u_int);
+
+int
+ospf_print_grace_lsa (const u_int8_t *tptr, u_int ls_length) {
+
+ u_int tlv_type, tlv_length;
+
+
+ while (ls_length > 0) {
+ TCHECK2(*tptr, 4);
+ if (ls_length < 4) {
+ printf("\n\t Remaining LS length %u < 4", ls_length);
+ return -1;
+ }
+ tlv_type = EXTRACT_16BITS(tptr);
+ tlv_length = EXTRACT_16BITS(tptr+2);
+ tptr+=4;
+ ls_length-=4;
+
+ printf("\n\t %s TLV (%u), length %u, value: ",
+ tok2str(lsa_opaque_grace_tlv_values,"unknown",tlv_type),
+ tlv_type,
+ tlv_length);
+
+ if (tlv_length > ls_length) {
+ printf("\n\t Bogus length %u > %u", tlv_length,
+ ls_length);
+ return -1;
+ }
+
+ /* Infinite loop protection. */
+ if (tlv_type == 0 || tlv_length ==0) {
+ return -1;
+ }
+
+ TCHECK2(*tptr, tlv_length);
+ switch(tlv_type) {
+
+ case LS_OPAQUE_GRACE_TLV_PERIOD:
+ if (tlv_length != 4) {
+ printf("\n\t Bogus length %u != 4", tlv_length);
+ return -1;
+ }
+ printf("%us",EXTRACT_32BITS(tptr));
+ break;
+
+ case LS_OPAQUE_GRACE_TLV_REASON:
+ if (tlv_length != 1) {
+ printf("\n\t Bogus length %u != 1", tlv_length);
+ return -1;
+ }
+ printf("%s (%u)",
+ tok2str(lsa_opaque_grace_tlv_reason_values, "Unknown", *tptr),
+ *tptr);
+ break;
+
+ case LS_OPAQUE_GRACE_TLV_INT_ADDRESS:
+ if (tlv_length != 4) {
+ printf("\n\t Bogus length %u != 4", tlv_length);
+ return -1;
+ }
+ printf("%s", ipaddr_string(tptr));
+ break;
+
+ default:
+ if (vflag <= 1) {
+ if(!print_unknown_data(tptr,"\n\t ",tlv_length))
+ return -1;
+ }
+ break;
+
+ }
+ /* in OSPF everything has to be 32-bit aligned, including TLVs */
+ if (tlv_length%4 != 0)
+ tlv_length+=4-(tlv_length%4);
+ ls_length-=tlv_length;
+ tptr+=tlv_length;
+ }
+
+ return 0;
+trunc:
+ return -1;
+}
+
+int
+ospf_print_te_lsa (const u_int8_t *tptr, u_int ls_length) {
+
+ u_int tlv_type, tlv_length, subtlv_type, subtlv_length;
+ u_int priority_level, te_class, count_srlg;
+ union { /* int to float conversion buffer for several subTLVs */
+ float f;
+ u_int32_t i;
+ } bw;
+
+ while (ls_length != 0) {
+ TCHECK2(*tptr, 4);
+ if (ls_length < 4) {
+ printf("\n\t Remaining LS length %u < 4", ls_length);
+ return -1;
+ }
+ tlv_type = EXTRACT_16BITS(tptr);
+ tlv_length = EXTRACT_16BITS(tptr+2);
+ tptr+=4;
+ ls_length-=4;
+
+ printf("\n\t %s TLV (%u), length: %u",
+ tok2str(lsa_opaque_te_tlv_values,"unknown",tlv_type),
+ tlv_type,
+ tlv_length);
+
+ if (tlv_length > ls_length) {
+ printf("\n\t Bogus length %u > %u", tlv_length,
+ ls_length);
+ return -1;
+ }
+
+ /* Infinite loop protection. */
+ if (tlv_type == 0 || tlv_length ==0) {
+ return -1;
+ }
+
+ switch(tlv_type) {
+ case LS_OPAQUE_TE_TLV_LINK:
+ while (tlv_length >= sizeof(subtlv_type) + sizeof(subtlv_length)) {
+ if (tlv_length < 4) {
+ printf("\n\t Remaining TLV length %u < 4",
+ tlv_length);
+ return -1;
+ }
+ TCHECK2(*tptr, 4);
+ subtlv_type = EXTRACT_16BITS(tptr);
+ subtlv_length = EXTRACT_16BITS(tptr+2);
+ tptr+=4;
+ tlv_length-=4;
+
+ printf("\n\t %s subTLV (%u), length: %u",
+ tok2str(lsa_opaque_te_link_tlv_subtlv_values,"unknown",subtlv_type),
+ subtlv_type,
+ subtlv_length);
+
+ TCHECK2(*tptr, subtlv_length);
+ switch(subtlv_type) {
+ case LS_OPAQUE_TE_LINK_SUBTLV_ADMIN_GROUP:
+ printf(", 0x%08x", EXTRACT_32BITS(tptr));
+ break;
+ case LS_OPAQUE_TE_LINK_SUBTLV_LINK_ID:
+ case LS_OPAQUE_TE_LINK_SUBTLV_LINK_LOCAL_REMOTE_ID:
+ printf(", %s (0x%08x)",
+ ipaddr_string(tptr),
+ EXTRACT_32BITS(tptr));
+ if (subtlv_length == 8) /* rfc4203 */
+ printf(", %s (0x%08x)",
+ ipaddr_string(tptr+4),
+ EXTRACT_32BITS(tptr+4));
+ break;
+ case LS_OPAQUE_TE_LINK_SUBTLV_LOCAL_IP:
+ case LS_OPAQUE_TE_LINK_SUBTLV_REMOTE_IP:
+ printf(", %s", ipaddr_string(tptr));
+ break;
+ case LS_OPAQUE_TE_LINK_SUBTLV_MAX_BW:
+ case LS_OPAQUE_TE_LINK_SUBTLV_MAX_RES_BW:
+ bw.i = EXTRACT_32BITS(tptr);
+ printf(", %.3f Mbps", bw.f*8/1000000 );
+ break;
+ case LS_OPAQUE_TE_LINK_SUBTLV_UNRES_BW:
+ for (te_class = 0; te_class < 8; te_class++) {
+ bw.i = EXTRACT_32BITS(tptr+te_class*4);
+ printf("\n\t\tTE-Class %u: %.3f Mbps",
+ te_class,
+ bw.f*8/1000000 );
+ }
+ break;
+ case LS_OPAQUE_TE_LINK_SUBTLV_BW_CONSTRAINTS:
+ printf("\n\t\tBandwidth Constraints Model ID: %s (%u)",
+ tok2str(diffserv_te_bc_values, "unknown", *tptr),
+ *tptr);
+ /* decode BCs until the subTLV ends */
+ for (te_class = 0; te_class < (subtlv_length-4)/4; te_class++) {
+ bw.i = EXTRACT_32BITS(tptr+4+te_class*4);
+ printf("\n\t\t Bandwidth constraint CT%u: %.3f Mbps",
+ te_class,
+ bw.f*8/1000000 );
+ }
+ break;
+ case LS_OPAQUE_TE_LINK_SUBTLV_TE_METRIC:
+ printf(", Metric %u", EXTRACT_32BITS(tptr));
+ break;
+ case LS_OPAQUE_TE_LINK_SUBTLV_LINK_PROTECTION_TYPE:
+ printf(", %s, Priority %u",
+ bittok2str(gmpls_link_prot_values, "none", *tptr),
+ *(tptr+1));
+ break;
+ case LS_OPAQUE_TE_LINK_SUBTLV_INTF_SW_CAP_DESCR:
+ printf("\n\t\tInterface Switching Capability: %s",
+ tok2str(gmpls_switch_cap_values, "Unknown", *(tptr)));
+ printf("\n\t\tLSP Encoding: %s\n\t\tMax LSP Bandwidth:",
+ tok2str(gmpls_encoding_values, "Unknown", *(tptr+1)));
+ for (priority_level = 0; priority_level < 8; priority_level++) {
+ bw.i = EXTRACT_32BITS(tptr+4+(priority_level*4));
+ printf("\n\t\t priority level %d: %.3f Mbps",
+ priority_level,
+ bw.f*8/1000000 );
+ }
+ break;
+ case LS_OPAQUE_TE_LINK_SUBTLV_LINK_TYPE:
+ printf(", %s (%u)",
+ tok2str(lsa_opaque_te_tlv_link_type_sub_tlv_values,"unknown",*tptr),
+ *tptr);
+ break;
+
+ case LS_OPAQUE_TE_LINK_SUBTLV_SHARED_RISK_GROUP:
+ count_srlg = subtlv_length / 4;
+ if (count_srlg != 0)
+ printf("\n\t\t Shared risk group: ");
+ while (count_srlg > 0) {
+ bw.i = EXTRACT_32BITS(tptr);
+ printf("%d",bw.i);
+ tptr+=4;
+ count_srlg--;
+ if (count_srlg > 0)
+ printf(", ");
+ }
+ break;
+
+ default:
+ if (vflag <= 1) {
+ if(!print_unknown_data(tptr,"\n\t\t",subtlv_length))
+ return -1;
+ }
+ break;
+ }
+ /* in OSPF everything has to be 32-bit aligned, including subTLVs */
+ if (subtlv_length%4 != 0)
+ subtlv_length+=4-(subtlv_length%4);
+
+ tlv_length-=subtlv_length;
+ tptr+=subtlv_length;
+
+ }
+ break;
+
+ case LS_OPAQUE_TE_TLV_ROUTER:
+ if (tlv_length < 4) {
+ printf("\n\t TLV length %u < 4", tlv_length);
+ return -1;
+ }
+ TCHECK2(*tptr, 4);
+ printf(", %s", ipaddr_string(tptr));
+ break;
+
+ default:
+ if (vflag <= 1) {
+ if(!print_unknown_data(tptr,"\n\t ",tlv_length))
+ return -1;
+ }
+ break;
+ }
+ /* in OSPF everything has to be 32-bit aligned, including TLVs */
+ if (tlv_length%4 != 0)
+ tlv_length+=4-(tlv_length%4);
+ ls_length-=tlv_length;
+ tptr+=tlv_length;
+ }
+ return 0;
+trunc:
+ return -1;
+}
+
+
+static int
+ospf_print_lshdr(register const struct lsa_hdr *lshp)
+{
+ u_int ls_length;
+
+ TCHECK(lshp->ls_length);
+ ls_length = EXTRACT_16BITS(&lshp->ls_length);
+ if (ls_length < sizeof(struct lsa_hdr)) {
+ printf("\n\t Bogus length %u < header (%lu)", ls_length,
+ (unsigned long)sizeof(struct lsa_hdr));
+ return(-1);
+ }
+
+ TCHECK(lshp->ls_seq); /* XXX - ls_length check checked this */
+ printf("\n\t Advertising Router %s, seq 0x%08x, age %us, length %u",
+ ipaddr_string(&lshp->ls_router),
+ EXTRACT_32BITS(&lshp->ls_seq),
+ EXTRACT_16BITS(&lshp->ls_age),
+ ls_length-(u_int)sizeof(struct lsa_hdr));
+
+ TCHECK(lshp->ls_type); /* XXX - ls_length check checked this */
+ switch (lshp->ls_type) {
+ /* the LSA header for opaque LSAs was slightly changed */
+ case LS_TYPE_OPAQUE_LL:
+ case LS_TYPE_OPAQUE_AL:
+ case LS_TYPE_OPAQUE_DW:
+ printf("\n\t %s LSA (%d), Opaque-Type %s LSA (%u), Opaque-ID %u",
+ tok2str(lsa_values,"unknown",lshp->ls_type),
+ lshp->ls_type,
+
+ tok2str(lsa_opaque_values,
+ "unknown",
+ *(&lshp->un_lsa_id.opaque_field.opaque_type)),
+ *(&lshp->un_lsa_id.opaque_field.opaque_type),
+ EXTRACT_24BITS(&lshp->un_lsa_id.opaque_field.opaque_id)
+
+ );
+ break;
+
+ /* all other LSA types use regular style LSA headers */
+ default:
+ printf("\n\t %s LSA (%d), LSA-ID: %s",
+ tok2str(lsa_values,"unknown",lshp->ls_type),
+ lshp->ls_type,
+ ipaddr_string(&lshp->un_lsa_id.lsa_id));
+ break;
+ }
+
+ TCHECK(lshp->ls_options); /* XXX - ls_length check checked this */
+ printf("\n\t Options: [%s]", bittok2str(ospf_option_values,"none",lshp->ls_options));
+
+ return (ls_length);
+trunc:
+ return (-1);
+}
+
+/* draft-ietf-ospf-mt-09 */
+static struct tok ospf_topology_values[] = {
+ { 0, "default " },
+ { 1, "multicast " },
+ { 2, "management " },
+ { 0, NULL }
+};
+
+/*
+ * Print all the per-topology metrics.
+ */
+static void
+ospf_print_tos_metrics(const union un_tos *tos)
+{
+ int metric_count;
+ int toscount;
+
+ toscount = tos->link.link_tos_count+1;
+ metric_count = 0;
+
+ /*
+ * All but the first metric contain a valid topology id.
+ */
+ while (toscount) {
+ printf("\n\t\ttopology %s(%u), metric %u",
+ tok2str(ospf_topology_values, "",
+ metric_count ? tos->metrics.tos_type : 0),
+ metric_count ? tos->metrics.tos_type : 0,
+ EXTRACT_16BITS(&tos->metrics.tos_metric));
+ metric_count++;
+ tos++;
+ toscount--;
+ }
+}
+
+/*
+ * Print a single link state advertisement. If truncated or if LSA length
+ * field is less than the length of the LSA header, return NULl, else
+ * return pointer to data past end of LSA.
+ */
+static const u_int8_t *
+ospf_print_lsa(register const struct lsa *lsap)
+{
+ register const u_int8_t *ls_end;
+ register const struct rlalink *rlp;
+ register const struct in_addr *ap;
+ register const struct aslametric *almp;
+ register const struct mcla *mcp;
+ register const u_int32_t *lp;
+ register int j, tlv_type, tlv_length, topology;
+ register int ls_length;
+ const u_int8_t *tptr;
+
+ tptr = (u_int8_t *)lsap->lsa_un.un_unknown; /* squelch compiler warnings */
+ ls_length = ospf_print_lshdr(&lsap->ls_hdr);
+ if (ls_length == -1)
+ return(NULL);
+ ls_end = (u_int8_t *)lsap + ls_length;
+ ls_length -= sizeof(struct lsa_hdr);
+
+ switch (lsap->ls_hdr.ls_type) {
+
+ case LS_TYPE_ROUTER:
+ TCHECK(lsap->lsa_un.un_rla.rla_flags);
+ printf("\n\t Router LSA Options: [%s]", bittok2str(ospf_rla_flag_values,"none",lsap->lsa_un.un_rla.rla_flags));
+
+ TCHECK(lsap->lsa_un.un_rla.rla_count);
+ j = EXTRACT_16BITS(&lsap->lsa_un.un_rla.rla_count);
+ TCHECK(lsap->lsa_un.un_rla.rla_link);
+ rlp = lsap->lsa_un.un_rla.rla_link;
+ while (j--) {
+ TCHECK(*rlp);
+ switch (rlp->un_tos.link.link_type) {
+
+ case RLA_TYPE_VIRTUAL:
+ printf("\n\t Virtual Link: Neighbor Router-ID: %s, Interface Address: %s",
+ ipaddr_string(&rlp->link_id),
+ ipaddr_string(&rlp->link_data));
+ break;
+
+ case RLA_TYPE_ROUTER:
+ printf("\n\t Neighbor Router-ID: %s, Interface Address: %s",
+ ipaddr_string(&rlp->link_id),
+ ipaddr_string(&rlp->link_data));
+ break;
+
+ case RLA_TYPE_TRANSIT:
+ printf("\n\t Neighbor Network-ID: %s, Interface Address: %s",
+ ipaddr_string(&rlp->link_id),
+ ipaddr_string(&rlp->link_data));
+ break;
+
+ case RLA_TYPE_STUB:
+ printf("\n\t Stub Network: %s, Mask: %s",
+ ipaddr_string(&rlp->link_id),
+ ipaddr_string(&rlp->link_data));
+ break;
+
+ default:
+ printf("\n\t Unknown Router Link Type (%u)",
+ rlp->un_tos.link.link_type);
+ return (ls_end);
+ }
+
+ ospf_print_tos_metrics(&rlp->un_tos);
+
+ rlp = (struct rlalink *)((u_char *)(rlp + 1) +
+ ((rlp->un_tos.link.link_tos_count) * sizeof(union un_tos)));
+ }
+ break;
+
+ case LS_TYPE_NETWORK:
+ TCHECK(lsap->lsa_un.un_nla.nla_mask);
+ printf("\n\t Mask %s\n\t Connected Routers:",
+ ipaddr_string(&lsap->lsa_un.un_nla.nla_mask));
+ ap = lsap->lsa_un.un_nla.nla_router;
+ while ((u_char *)ap < ls_end) {
+ TCHECK(*ap);
+ printf("\n\t %s", ipaddr_string(ap));
+ ++ap;
+ }
+ break;
+
+ case LS_TYPE_SUM_IP:
+ TCHECK(lsap->lsa_un.un_nla.nla_mask);
+ printf("\n\t Mask %s",
+ ipaddr_string(&lsap->lsa_un.un_sla.sla_mask));
+ TCHECK(lsap->lsa_un.un_sla.sla_tosmetric);
+ lp = lsap->lsa_un.un_sla.sla_tosmetric;
+ while ((u_char *)lp < ls_end) {
+ register u_int32_t ul;
+
+ TCHECK(*lp);
+ ul = EXTRACT_32BITS(lp);
+ topology = (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS;
+ printf("\n\t\ttopology %s(%u) metric %d",
+ tok2str(ospf_topology_values, "", topology),
+ topology,
+ ul & SLA_MASK_METRIC);
+ ++lp;
+ }
+ break;
+
+ case LS_TYPE_SUM_ABR:
+ TCHECK(lsap->lsa_un.un_sla.sla_tosmetric);
+ lp = lsap->lsa_un.un_sla.sla_tosmetric;
+ while ((u_char *)lp < ls_end) {
+ register u_int32_t ul;
+
+ TCHECK(*lp);
+ ul = EXTRACT_32BITS(lp);
+ topology = (ul & SLA_MASK_TOS) >> SLA_SHIFT_TOS;
+ printf("\n\t\ttopology %s(%u) metric %d",
+ tok2str(ospf_topology_values, "", topology),
+ topology,
+ ul & SLA_MASK_METRIC);
+ ++lp;
+ }
+ break;
+
+ case LS_TYPE_ASE:
+ case LS_TYPE_NSSA: /* fall through - those LSAs share the same format */
+ TCHECK(lsap->lsa_un.un_nla.nla_mask);
+ printf("\n\t Mask %s",
+ ipaddr_string(&lsap->lsa_un.un_asla.asla_mask));
+
+ TCHECK(lsap->lsa_un.un_sla.sla_tosmetric);
+ almp = lsap->lsa_un.un_asla.asla_metric;
+ while ((u_char *)almp < ls_end) {
+ register u_int32_t ul;
+
+ TCHECK(almp->asla_tosmetric);
+ ul = EXTRACT_32BITS(&almp->asla_tosmetric);
+ topology = ((ul & ASLA_MASK_TOS) >> ASLA_SHIFT_TOS);
+ printf("\n\t\ttopology %s(%u), type %d, metric",
+ tok2str(ospf_topology_values, "", topology),
+ topology,
+ (ul & ASLA_FLAG_EXTERNAL) ? 2 : 1);
+ if ((ul & ASLA_MASK_METRIC)==0xffffff)
+ printf(" infinite");
+ else
+ printf(" %d", (ul & ASLA_MASK_METRIC));
+
+ TCHECK(almp->asla_forward);
+ if (almp->asla_forward.s_addr) {
+ printf(", forward %s",
+ ipaddr_string(&almp->asla_forward));
+ }
+ TCHECK(almp->asla_tag);
+ if (almp->asla_tag.s_addr) {
+ printf(", tag %s",
+ ipaddr_string(&almp->asla_tag));
+ }
+ ++almp;
+ }
+ break;
+
+ case LS_TYPE_GROUP:
+ /* Multicast extensions as of 23 July 1991 */
+ mcp = lsap->lsa_un.un_mcla;
+ while ((u_char *)mcp < ls_end) {
+ TCHECK(mcp->mcla_vid);
+ switch (EXTRACT_32BITS(&mcp->mcla_vtype)) {
+
+ case MCLA_VERTEX_ROUTER:
+ printf("\n\t Router Router-ID %s",
+ ipaddr_string(&mcp->mcla_vid));
+ break;
+
+ case MCLA_VERTEX_NETWORK:
+ printf("\n\t Network Designated Router %s",
+ ipaddr_string(&mcp->mcla_vid));
+ break;
+
+ default:
+ printf("\n\t unknown VertexType (%u)",
+ EXTRACT_32BITS(&mcp->mcla_vtype));
+ break;
+ }
+ ++mcp;
+ }
+ break;
+
+ case LS_TYPE_OPAQUE_LL: /* fall through */
+ case LS_TYPE_OPAQUE_AL:
+ case LS_TYPE_OPAQUE_DW:
+
+ switch (*(&lsap->ls_hdr.un_lsa_id.opaque_field.opaque_type)) {
+ case LS_OPAQUE_TYPE_RI:
+ tptr = (u_int8_t *)(&lsap->lsa_un.un_ri_tlv.type);
+
+ while (ls_length != 0) {
+ TCHECK2(*tptr, 4);
+ if (ls_length < 4) {
+ printf("\n\t Remaining LS length %u < 4", ls_length);
+ return(ls_end);
+ }
+ tlv_type = EXTRACT_16BITS(tptr);
+ tlv_length = EXTRACT_16BITS(tptr+2);
+ tptr+=4;
+ ls_length-=4;
+
+ printf("\n\t %s TLV (%u), length: %u, value: ",
+ tok2str(lsa_opaque_ri_tlv_values,"unknown",tlv_type),
+ tlv_type,
+ tlv_length);
+
+ if (tlv_length > ls_length) {
+ printf("\n\t Bogus length %u > %u", tlv_length,
+ ls_length);
+ return(ls_end);
+ }
+ TCHECK2(*tptr, tlv_length);
+ switch(tlv_type) {
+
+ case LS_OPAQUE_RI_TLV_CAP:
+ if (tlv_length != 4) {
+ printf("\n\t Bogus length %u != 4", tlv_length);
+ return(ls_end);
+ }
+ printf("Capabilities: %s",
+ bittok2str(lsa_opaque_ri_tlv_cap_values, "Unknown", EXTRACT_32BITS(tptr)));
+ break;
+ default:
+ if (vflag <= 1) {
+ if(!print_unknown_data(tptr,"\n\t ",tlv_length))
+ return(ls_end);
+ }
+ break;
+
+ }
+ tptr+=tlv_length;
+ ls_length-=tlv_length;
+ }
+ break;
+
+ case LS_OPAQUE_TYPE_GRACE:
+ if (ospf_print_grace_lsa((u_int8_t *)(&lsap->lsa_un.un_grace_tlv.type),
+ ls_length) == -1) {
+ return(ls_end);
+ }
+ break;
+
+ case LS_OPAQUE_TYPE_TE:
+ if (ospf_print_te_lsa((u_int8_t *)(&lsap->lsa_un.un_te_lsa_tlv.type),
+ ls_length) == -1) {
+ return(ls_end);
+ }
+ break;
+
+ default:
+ if (vflag <= 1) {
+ if(!print_unknown_data((u_int8_t *)lsap->lsa_un.un_unknown,
+ "\n\t ", ls_length))
+ return(ls_end);
+ }
+ break;
+ }
+ }
+
+ /* do we want to see an additionally hexdump ? */
+ if (vflag> 1)
+ if(!print_unknown_data((u_int8_t *)lsap->lsa_un.un_unknown,
+ "\n\t ", ls_length)) {
+ return(ls_end);
+ }
+
+ return (ls_end);
+trunc:
+ return (NULL);
+}
+
+static int
+ospf_decode_lls(register const struct ospfhdr *op,
+ register u_int length)
+{
+ register const u_char *dptr;
+ register const u_char *dataend;
+ register u_int length2;
+ register u_int16_t lls_type, lls_len;
+ register u_int32_t lls_flags;
+
+ switch (op->ospf_type) {
+
+ case OSPF_TYPE_HELLO:
+ if (!(op->ospf_hello.hello_options & OSPF_OPTION_L))
+ return (0);
+ break;
+
+ case OSPF_TYPE_DD:
+ if (!(op->ospf_db.db_options & OSPF_OPTION_L))
+ return (0);
+ break;
+
+ default:
+ return (0);
+ }
+
+ /* dig deeper if LLS data is available; see RFC4813 */
+ length2 = EXTRACT_16BITS(&op->ospf_len);
+ dptr = (u_char *)op + length2;
+ dataend = (u_char *)op + length;
+
+ if (EXTRACT_16BITS(&op->ospf_authtype) == OSPF_AUTH_MD5) {
+ dptr = dptr + op->ospf_authdata[3];
+ length2 += op->ospf_authdata[3];
+ }
+ if (length2 >= length) {
+ printf("\n\t[LLS truncated]");
+ return (1);
+ }
+ TCHECK2(*dptr, 2);
+ printf("\n\t LLS: checksum: 0x%04x", (u_int)EXTRACT_16BITS(dptr));
+
+ dptr += 2;
+ TCHECK2(*dptr, 2);
+ length2 = EXTRACT_16BITS(dptr);
+ printf(", length: %u", length2);
+
+ dptr += 2;
+ TCHECK(*dptr);
+ while (dptr < dataend) {
+ TCHECK2(*dptr, 2);
+ lls_type = EXTRACT_16BITS(dptr);
+ printf("\n\t %s (%u)",
+ tok2str(ospf_lls_tlv_values,"Unknown TLV",lls_type),
+ lls_type);
+ dptr += 2;
+ TCHECK2(*dptr, 2);
+ lls_len = EXTRACT_16BITS(dptr);
+ printf(", length: %u", lls_len);
+ dptr += 2;
+ switch (lls_type) {
+
+ case OSPF_LLS_EO:
+ if (lls_len != 4) {
+ printf(" [should be 4]");
+ lls_len = 4;
+ }
+ TCHECK2(*dptr, 4);
+ lls_flags = EXTRACT_32BITS(dptr);
+ printf("\n\t Options: 0x%08x [%s]", lls_flags,
+ bittok2str(ospf_lls_eo_options,"?",lls_flags));
+
+ break;
+
+ case OSPF_LLS_MD5:
+ if (lls_len != 20) {
+ printf(" [should be 20]");
+ lls_len = 20;
+ }
+ TCHECK2(*dptr, 4);
+ printf("\n\t Sequence number: 0x%08x", EXTRACT_32BITS(dptr));
+ break;
+ }
+
+ dptr += lls_len;
+ }
+
+ return (0);
+trunc:
+ return (1);
+}
+
+static int
+ospf_decode_v2(register const struct ospfhdr *op,
+ register const u_char *dataend)
+{
+ register const struct in_addr *ap;
+ register const struct lsr *lsrp;
+ register const struct lsa_hdr *lshp;
+ register const struct lsa *lsap;
+ register u_int32_t lsa_count,lsa_count_max;
+
+ switch (op->ospf_type) {
+
+ case OSPF_TYPE_UMD:
+ /*
+ * Rob Coltun's special monitoring packets;
+ * do nothing
+ */
+ break;
+
+ case OSPF_TYPE_HELLO:
+ printf("\n\tOptions [%s]",
+ bittok2str(ospf_option_values,"none",op->ospf_hello.hello_options));
+
+ TCHECK(op->ospf_hello.hello_deadint);
+ printf("\n\t Hello Timer %us, Dead Timer %us, Mask %s, Priority %u",
+ EXTRACT_16BITS(&op->ospf_hello.hello_helloint),
+ EXTRACT_32BITS(&op->ospf_hello.hello_deadint),
+ ipaddr_string(&op->ospf_hello.hello_mask),
+ op->ospf_hello.hello_priority);
+
+ TCHECK(op->ospf_hello.hello_dr);
+ if (op->ospf_hello.hello_dr.s_addr != 0)
+ printf("\n\t Designated Router %s",
+ ipaddr_string(&op->ospf_hello.hello_dr));
+
+ TCHECK(op->ospf_hello.hello_bdr);
+ if (op->ospf_hello.hello_bdr.s_addr != 0)
+ printf(", Backup Designated Router %s",
+ ipaddr_string(&op->ospf_hello.hello_bdr));
+
+ ap = op->ospf_hello.hello_neighbor;
+ if ((u_char *)ap < dataend)
+ printf("\n\t Neighbor List:");
+ while ((u_char *)ap < dataend) {
+ TCHECK(*ap);
+ printf("\n\t %s", ipaddr_string(ap));
+ ++ap;
+ }
+ break; /* HELLO */
+
+ case OSPF_TYPE_DD:
+ TCHECK(op->ospf_db.db_options);
+ printf("\n\tOptions [%s]",
+ bittok2str(ospf_option_values,"none",op->ospf_db.db_options));
+ TCHECK(op->ospf_db.db_flags);
+ printf(", DD Flags [%s]",
+ bittok2str(ospf_dd_flag_values,"none",op->ospf_db.db_flags));
+ TCHECK(op->ospf_db.db_ifmtu);
+ if (op->ospf_db.db_ifmtu) {
+ printf(", MTU: %u", EXTRACT_16BITS(&op->ospf_db.db_ifmtu));
+ }
+ TCHECK(op->ospf_db.db_seq);
+ printf(", Sequence: 0x%08x", EXTRACT_32BITS(&op->ospf_db.db_seq));
+
+ /* Print all the LS adv's */
+ lshp = op->ospf_db.db_lshdr;
+ while (((u_char *)lshp < dataend) && ospf_print_lshdr(lshp) != -1) {
+ ++lshp;
+ }
+ break;
+
+ case OSPF_TYPE_LS_REQ:
+ lsrp = op->ospf_lsr;
+ while ((u_char *)lsrp < dataend) {
+ TCHECK(*lsrp);
+
+ printf("\n\t Advertising Router: %s, %s LSA (%u)",
+ ipaddr_string(&lsrp->ls_router),
+ tok2str(lsa_values,"unknown",EXTRACT_32BITS(lsrp->ls_type)),
+ EXTRACT_32BITS(&lsrp->ls_type));
+
+ switch (EXTRACT_32BITS(lsrp->ls_type)) {
+ /* the LSA header for opaque LSAs was slightly changed */
+ case LS_TYPE_OPAQUE_LL:
+ case LS_TYPE_OPAQUE_AL:
+ case LS_TYPE_OPAQUE_DW:
+ printf(", Opaque-Type: %s LSA (%u), Opaque-ID: %u",
+ tok2str(lsa_opaque_values, "unknown",lsrp->un_ls_stateid.opaque_field.opaque_type),
+ lsrp->un_ls_stateid.opaque_field.opaque_type,
+ EXTRACT_24BITS(&lsrp->un_ls_stateid.opaque_field.opaque_id));
+ break;
+ default:
+ printf(", LSA-ID: %s",
+ ipaddr_string(&lsrp->un_ls_stateid.ls_stateid));
+ break;
+ }
+
+ ++lsrp;
+ }
+ break;
+
+ case OSPF_TYPE_LS_UPDATE:
+ lsap = op->ospf_lsu.lsu_lsa;
+ TCHECK(op->ospf_lsu.lsu_count);
+ lsa_count_max = EXTRACT_32BITS(&op->ospf_lsu.lsu_count);
+ printf(", %d LSA%s",lsa_count_max, PLURAL_SUFFIX(lsa_count_max));
+ for (lsa_count=1;lsa_count <= lsa_count_max;lsa_count++) {
+ printf("\n\t LSA #%u",lsa_count);
+ lsap = (const struct lsa *)ospf_print_lsa(lsap);
+ if (lsap == NULL)
+ goto trunc;
+ }
+ break;
+
+ case OSPF_TYPE_LS_ACK:
+ lshp = op->ospf_lsa.lsa_lshdr;
+ while (ospf_print_lshdr(lshp) != -1) {
+ ++lshp;
+ }
+ break;
+
+ default:
+ break;
+ }
+ return (0);
+trunc:
+ return (1);
+}
+
+void
+ospf_print(register const u_char *bp, register u_int length,
+ const u_char *bp2 _U_)
+{
+ register const struct ospfhdr *op;
+ register const u_char *dataend;
+ register const char *cp;
+
+ op = (struct ospfhdr *)bp;
+
+ /* XXX Before we do anything else, strip off the MD5 trailer */
+ TCHECK(op->ospf_authtype);
+ if (EXTRACT_16BITS(&op->ospf_authtype) == OSPF_AUTH_MD5) {
+ length -= OSPF_AUTH_MD5_LEN;
+ snapend -= OSPF_AUTH_MD5_LEN;
+ }
+
+ /* If the type is valid translate it, or just print the type */
+ /* value. If it's not valid, say so and return */
+ TCHECK(op->ospf_type);
+ cp = tok2str(type2str, "unknown LS-type", op->ospf_type);
+ printf("OSPFv%u, %s, length %u",
+ op->ospf_version,
+ cp,
+ length);
+ if (*cp == 'u')
+ return;
+
+ if(!vflag) { /* non verbose - so lets bail out here */
+ return;
+ }
+
+ TCHECK(op->ospf_len);
+ if (length != EXTRACT_16BITS(&op->ospf_len)) {
+ printf(" [len %d]", EXTRACT_16BITS(&op->ospf_len));
+ }
+
+ if (length > EXTRACT_16BITS(&op->ospf_len)) {
+ dataend = bp + EXTRACT_16BITS(&op->ospf_len);
+ } else {
+ dataend = bp + length;
+ }
+
+ TCHECK(op->ospf_routerid);
+ printf("\n\tRouter-ID %s", ipaddr_string(&op->ospf_routerid));
+
+ TCHECK(op->ospf_areaid);
+ if (op->ospf_areaid.s_addr != 0)
+ printf(", Area %s", ipaddr_string(&op->ospf_areaid));
+ else
+ printf(", Backbone Area");
+
+ if (vflag) {
+ /* Print authentication data (should we really do this?) */
+ TCHECK2(op->ospf_authdata[0], sizeof(op->ospf_authdata));
+
+ printf(", Authentication Type: %s (%u)",
+ tok2str(ospf_authtype_values,"unknown",EXTRACT_16BITS(&op->ospf_authtype)),
+ EXTRACT_16BITS(&op->ospf_authtype));
+
+ switch (EXTRACT_16BITS(&op->ospf_authtype)) {
+
+ case OSPF_AUTH_NONE:
+ break;
+
+ case OSPF_AUTH_SIMPLE:
+ printf("\n\tSimple text password: ");
+ safeputs((const char *)op->ospf_authdata, OSPF_AUTH_SIMPLE_LEN);
+ break;
+
+ case OSPF_AUTH_MD5:
+ printf("\n\tKey-ID: %u, Auth-Length: %u, Crypto Sequence Number: 0x%08x",
+ *((op->ospf_authdata)+2),
+ *((op->ospf_authdata)+3),
+ EXTRACT_32BITS((op->ospf_authdata)+4));
+ break;
+
+ default:
+ return;
+ }
+ }
+ /* Do rest according to version. */
+ switch (op->ospf_version) {
+
+ case 2:
+ /* ospf version 2 */
+ if (ospf_decode_v2(op, dataend))
+ goto trunc;
+ if (length > EXTRACT_16BITS(&op->ospf_len)) {
+ if (ospf_decode_lls(op, length))
+ goto trunc;
+ }
+ break;
+
+ default:
+ printf(" ospf [version %d]", op->ospf_version);
+ break;
+ } /* end switch on version */
+
+ return;
+trunc:
+ fputs(tstr, stdout);
+}
diff --git a/freebsd/contrib/tcpdump/print-ospf6.c b/freebsd/contrib/tcpdump/print-ospf6.c
new file mode 100644
index 00000000..419cf705
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-ospf6.c
@@ -0,0 +1,646 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * OSPF support contributed by Jeffrey Honig (jch@mitchell.cit.cornell.edu)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ospf6.c,v 1.15 2006-09-13 06:31:11 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+#include "ospf.h"
+#include "ospf6.h"
+
+static const struct tok ospf6_option_values[] = {
+ { OSPF6_OPTION_V6, "V6" },
+ { OSPF6_OPTION_E, "External" },
+ { OSPF6_OPTION_MC, "Multicast" },
+ { OSPF6_OPTION_N, "NSSA" },
+ { OSPF6_OPTION_R, "Router" },
+ { OSPF6_OPTION_DC, "Demand Circuit" },
+ { 0, NULL }
+};
+
+static const struct tok ospf6_rla_flag_values[] = {
+ { RLA_FLAG_B, "ABR" },
+ { RLA_FLAG_E, "External" },
+ { RLA_FLAG_V, "Virtual-Link Endpoint" },
+ { RLA_FLAG_W, "Wildcard Receiver" },
+ { RLA_FLAG_N, "NSSA Translator" },
+ { 0, NULL }
+};
+
+static const struct tok ospf6_asla_flag_values[] = {
+ { ASLA_FLAG_EXTERNAL, "External Type 2" },
+ { ASLA_FLAG_FWDADDR, "Fforwarding" },
+ { ASLA_FLAG_ROUTETAG, "Tag" },
+ { 0, NULL }
+};
+
+static struct tok ospf6_type_values[] = {
+ { OSPF_TYPE_HELLO, "Hello" },
+ { OSPF_TYPE_DD, "Database Description" },
+ { OSPF_TYPE_LS_REQ, "LS-Request" },
+ { OSPF_TYPE_LS_UPDATE, "LS-Update" },
+ { OSPF_TYPE_LS_ACK, "LS-Ack" },
+ { 0, NULL }
+};
+
+static struct tok ospf6_lsa_values[] = {
+ { LS_TYPE_ROUTER, "Router" },
+ { LS_TYPE_NETWORK, "Network" },
+ { LS_TYPE_INTER_AP, "Inter-Area Prefix" },
+ { LS_TYPE_INTER_AR, "Inter-Area Router" },
+ { LS_TYPE_ASE, "External" },
+ { LS_TYPE_GROUP, "Multicast Group" },
+ { LS_TYPE_NSSA, "NSSA" },
+ { LS_TYPE_LINK, "Link" },
+ { LS_TYPE_INTRA_AP, "Intra-Area Prefix" },
+ { LS_TYPE_INTRA_ATE, "Intra-Area TE" },
+ { LS_TYPE_GRACE, "Grace" },
+ { 0, NULL }
+};
+
+static struct tok ospf6_ls_scope_values[] = {
+ { LS_SCOPE_LINKLOCAL, "Link Local" },
+ { LS_SCOPE_AREA, "Area Local" },
+ { LS_SCOPE_AS, "Domain Wide" },
+ { 0, NULL }
+};
+
+static struct tok ospf6_dd_flag_values[] = {
+ { OSPF6_DB_INIT, "Init" },
+ { OSPF6_DB_MORE, "More" },
+ { OSPF6_DB_MASTER, "Master" },
+ { 0, NULL }
+};
+
+static struct tok ospf6_lsa_prefix_option_values[] = {
+ { LSA_PREFIX_OPT_NU, "No Unicast" },
+ { LSA_PREFIX_OPT_LA, "Local address" },
+ { LSA_PREFIX_OPT_MC, "Multicast" },
+ { LSA_PREFIX_OPT_P, "Propagate" },
+ { LSA_PREFIX_OPT_DN, "Down" },
+ { 0, NULL }
+};
+
+static char tstr[] = " [|ospf3]";
+
+#ifdef WIN32
+#define inline __inline
+#endif /* WIN32 */
+
+/* Forwards */
+static void ospf6_print_ls_type(u_int, const rtrid_t *);
+static int ospf6_print_lshdr(const struct lsa6_hdr *);
+static int ospf6_print_lsa(const struct lsa6 *);
+static int ospf6_decode_v3(const struct ospf6hdr *, const u_char *);
+
+
+static void
+ospf6_print_ls_type(register u_int ls_type, register const rtrid_t *ls_stateid)
+{
+ printf("\n\t %s LSA (%d), %s Scope%s, LSA-ID %s",
+ tok2str(ospf6_lsa_values, "Unknown", ls_type & LS_TYPE_MASK),
+ ls_type & LS_TYPE_MASK,
+ tok2str(ospf6_ls_scope_values, "Unknown", ls_type & LS_SCOPE_MASK),
+ ls_type &0x8000 ? ", transitive" : "", /* U-bit */
+ ipaddr_string(ls_stateid));
+}
+
+static int
+ospf6_print_lshdr(register const struct lsa6_hdr *lshp)
+{
+
+ TCHECK(lshp->ls_type);
+ TCHECK(lshp->ls_seq);
+
+ printf("\n\t Advertising Router %s, seq 0x%08x, age %us, length %u",
+ ipaddr_string(&lshp->ls_router),
+ EXTRACT_32BITS(&lshp->ls_seq),
+ EXTRACT_16BITS(&lshp->ls_age),
+ EXTRACT_16BITS(&lshp->ls_length)-(u_int)sizeof(struct lsa6_hdr));
+
+ ospf6_print_ls_type(EXTRACT_16BITS(&lshp->ls_type), &lshp->ls_stateid);
+
+ return (0);
+trunc:
+ return (1);
+}
+
+static int
+ospf6_print_lsaprefix(const u_int8_t *tptr, u_int lsa_length)
+{
+ const struct lsa6_prefix *lsapp = (struct lsa6_prefix *)tptr;
+ u_int wordlen;
+ struct in6_addr prefix;
+
+ if (lsa_length < sizeof (*lsapp) - 4)
+ goto trunc;
+ lsa_length -= sizeof (*lsapp) - 4;
+ TCHECK2(*lsapp, sizeof (*lsapp) - 4);
+ wordlen = (lsapp->lsa_p_len + 31) / 32;
+ if (wordlen * 4 > sizeof(struct in6_addr)) {
+ printf(" bogus prefixlen /%d", lsapp->lsa_p_len);
+ goto trunc;
+ }
+ if (lsa_length < wordlen * 4)
+ goto trunc;
+ lsa_length -= wordlen * 4;
+ TCHECK2(lsapp->lsa_p_prefix, wordlen * 4);
+ memset(&prefix, 0, sizeof(prefix));
+ memcpy(&prefix, lsapp->lsa_p_prefix, wordlen * 4);
+ printf("\n\t\t%s/%d", ip6addr_string(&prefix),
+ lsapp->lsa_p_len);
+ if (lsapp->lsa_p_opt) {
+ printf(", Options [%s]",
+ bittok2str(ospf6_lsa_prefix_option_values,
+ "none", lsapp->lsa_p_opt));
+ }
+ printf(", metric %u", EXTRACT_16BITS(&lsapp->lsa_p_metric));
+ return sizeof(*lsapp) - 4 + wordlen * 4;
+
+trunc:
+ return -1;
+}
+
+
+/*
+ * Print a single link state advertisement. If truncated return 1, else 0.
+ */
+static int
+ospf6_print_lsa(register const struct lsa6 *lsap)
+{
+ register const struct rlalink6 *rlp;
+#if 0
+ register const struct tos_metric *tosp;
+#endif
+ register const rtrid_t *ap;
+#if 0
+ register const struct aslametric *almp;
+ register const struct mcla *mcp;
+#endif
+ register const struct llsa *llsap;
+ register const struct lsa6_prefix *lsapp;
+#if 0
+ register const u_int32_t *lp;
+#endif
+ register u_int prefixes;
+ register int bytelen;
+ register u_int length, lsa_length;
+ u_int32_t flags32;
+ const u_int8_t *tptr;
+
+ if (ospf6_print_lshdr(&lsap->ls_hdr))
+ return (1);
+ TCHECK(lsap->ls_hdr.ls_length);
+ length = EXTRACT_16BITS(&lsap->ls_hdr.ls_length);
+
+ /*
+ * The LSA length includes the length of the header;
+ * it must have a value that's at least that length.
+ * If it does, find the length of what follows the
+ * header.
+ */
+ if (length < sizeof(struct lsa6_hdr))
+ return (1);
+ lsa_length = length - sizeof(struct lsa6_hdr);
+ tptr = (u_int8_t *)lsap+sizeof(struct lsa6_hdr);
+
+ switch (EXTRACT_16BITS(&lsap->ls_hdr.ls_type)) {
+ case LS_TYPE_ROUTER | LS_SCOPE_AREA:
+ if (lsa_length < sizeof (lsap->lsa_un.un_rla.rla_options))
+ return (1);
+ lsa_length -= sizeof (lsap->lsa_un.un_rla.rla_options);
+ TCHECK(lsap->lsa_un.un_rla.rla_options);
+ printf("\n\t Options [%s]",
+ bittok2str(ospf6_option_values, "none",
+ EXTRACT_32BITS(&lsap->lsa_un.un_rla.rla_options)));
+ printf(", RLA-Flags [%s]",
+ bittok2str(ospf6_rla_flag_values, "none",
+ lsap->lsa_un.un_rla.rla_flags));
+
+ rlp = lsap->lsa_un.un_rla.rla_link;
+ while (lsa_length != 0) {
+ if (lsa_length < sizeof (*rlp))
+ return (1);
+ lsa_length -= sizeof (*rlp);
+ TCHECK(*rlp);
+ switch (rlp->link_type) {
+
+ case RLA_TYPE_VIRTUAL:
+ printf("\n\t Virtual Link: Neighbor Router-ID %s"
+ "\n\t Neighbor Interface-ID %s, Interface %s",
+ ipaddr_string(&rlp->link_nrtid),
+ ipaddr_string(&rlp->link_nifid),
+ ipaddr_string(&rlp->link_ifid));
+ break;
+
+ case RLA_TYPE_ROUTER:
+ printf("\n\t Neighbor Router-ID %s"
+ "\n\t Neighbor Interface-ID %s, Interface %s",
+ ipaddr_string(&rlp->link_nrtid),
+ ipaddr_string(&rlp->link_nifid),
+ ipaddr_string(&rlp->link_ifid));
+ break;
+
+ case RLA_TYPE_TRANSIT:
+ printf("\n\t Neighbor Network-ID %s"
+ "\n\t Neighbor Interface-ID %s, Interface %s",
+ ipaddr_string(&rlp->link_nrtid),
+ ipaddr_string(&rlp->link_nifid),
+ ipaddr_string(&rlp->link_ifid));
+ break;
+
+ default:
+ printf("\n\t Unknown Router Links Type 0x%02x",
+ rlp->link_type);
+ return (0);
+ }
+ printf(", metric %d", EXTRACT_16BITS(&rlp->link_metric));
+ rlp++;
+ }
+ break;
+
+ case LS_TYPE_NETWORK | LS_SCOPE_AREA:
+ if (lsa_length < sizeof (lsap->lsa_un.un_nla.nla_options))
+ return (1);
+ lsa_length -= sizeof (lsap->lsa_un.un_nla.nla_options);
+ TCHECK(lsap->lsa_un.un_nla.nla_options);
+ printf("\n\t Options [%s]",
+ bittok2str(ospf6_option_values, "none",
+ EXTRACT_32BITS(&lsap->lsa_un.un_nla.nla_options)));
+
+ printf("\n\t Connected Routers:");
+ ap = lsap->lsa_un.un_nla.nla_router;
+ while (lsa_length != 0) {
+ if (lsa_length < sizeof (*ap))
+ return (1);
+ lsa_length -= sizeof (*ap);
+ TCHECK(*ap);
+ printf("\n\t\t%s", ipaddr_string(ap));
+ ++ap;
+ }
+ break;
+
+ case LS_TYPE_INTER_AP | LS_SCOPE_AREA:
+ if (lsa_length < sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric))
+ return (1);
+ lsa_length -= sizeof (lsap->lsa_un.un_inter_ap.inter_ap_metric);
+ TCHECK(lsap->lsa_un.un_inter_ap.inter_ap_metric);
+ printf(", metric %u",
+ EXTRACT_32BITS(&lsap->lsa_un.un_inter_ap.inter_ap_metric) & SLA_MASK_METRIC);
+
+ tptr = (u_int8_t *)lsap->lsa_un.un_inter_ap.inter_ap_prefix;
+ while (lsa_length != 0) {
+ bytelen = ospf6_print_lsaprefix(tptr, lsa_length);
+ if (bytelen < 0)
+ goto trunc;
+ lsa_length -= bytelen;
+ tptr += bytelen;
+ }
+ break;
+
+ case LS_TYPE_ASE | LS_SCOPE_AS:
+ if (lsa_length < sizeof (lsap->lsa_un.un_asla.asla_metric))
+ return (1);
+ lsa_length -= sizeof (lsap->lsa_un.un_asla.asla_metric);
+ TCHECK(lsap->lsa_un.un_asla.asla_metric);
+ flags32 = EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric);
+ printf("\n\t Flags [%s]",
+ bittok2str(ospf6_asla_flag_values, "none", flags32));
+ printf(" metric %u",
+ EXTRACT_32BITS(&lsap->lsa_un.un_asla.asla_metric) &
+ ASLA_MASK_METRIC);
+
+ tptr = (u_int8_t *)lsap->lsa_un.un_asla.asla_prefix;
+ lsapp = (struct lsa6_prefix *)tptr;
+ bytelen = ospf6_print_lsaprefix(tptr, lsa_length);
+ if (bytelen < 0)
+ goto trunc;
+ lsa_length -= bytelen;
+ tptr += bytelen;
+
+ if ((flags32 & ASLA_FLAG_FWDADDR) != 0) {
+ struct in6_addr *fwdaddr6;
+
+ fwdaddr6 = (struct in6_addr *)tptr;
+ if (lsa_length < sizeof (*fwdaddr6))
+ return (1);
+ lsa_length -= sizeof (*fwdaddr6);
+ TCHECK(*fwdaddr6);
+ printf(" forward %s",
+ ip6addr_string(fwdaddr6));
+ tptr += sizeof(*fwdaddr6);
+ }
+
+ if ((flags32 & ASLA_FLAG_ROUTETAG) != 0) {
+ if (lsa_length < sizeof (u_int32_t))
+ return (1);
+ lsa_length -= sizeof (u_int32_t);
+ TCHECK(*(u_int32_t *)tptr);
+ printf(" tag %s",
+ ipaddr_string((u_int32_t *)tptr));
+ tptr += sizeof(u_int32_t);
+ }
+
+ if (lsapp->lsa_p_metric) {
+ if (lsa_length < sizeof (u_int32_t))
+ return (1);
+ lsa_length -= sizeof (u_int32_t);
+ TCHECK(*(u_int32_t *)tptr);
+ printf(" RefLSID: %s",
+ ipaddr_string((u_int32_t *)tptr));
+ tptr += sizeof(u_int32_t);
+ }
+ break;
+
+ case LS_TYPE_LINK:
+ /* Link LSA */
+ llsap = &lsap->lsa_un.un_llsa;
+ if (lsa_length < sizeof (llsap->llsa_priandopt))
+ return (1);
+ lsa_length -= sizeof (llsap->llsa_priandopt);
+ TCHECK(llsap->llsa_priandopt);
+ printf("\n\t Options [%s]",
+ bittok2str(ospf6_option_values, "none",
+ EXTRACT_32BITS(&llsap->llsa_options)));
+
+ if (lsa_length < sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix))
+ return (1);
+ lsa_length -= sizeof (llsap->llsa_lladdr) + sizeof (llsap->llsa_nprefix);
+ prefixes = EXTRACT_32BITS(&llsap->llsa_nprefix);
+ printf("\n\t Priority %d, Link-local address %s, Prefixes %d:",
+ llsap->llsa_priority,
+ ip6addr_string(&llsap->llsa_lladdr),
+ prefixes);
+
+ tptr = (u_int8_t *)llsap->llsa_prefix;
+ while (prefixes > 0) {
+ bytelen = ospf6_print_lsaprefix(tptr, lsa_length);
+ if (bytelen < 0)
+ goto trunc;
+ prefixes--;
+ lsa_length -= bytelen;
+ tptr += bytelen;
+ }
+ break;
+
+ case LS_TYPE_INTRA_AP | LS_SCOPE_AREA:
+ /* Intra-Area-Prefix LSA */
+ if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid))
+ return (1);
+ lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_rtid);
+ TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_rtid);
+ ospf6_print_ls_type(
+ EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_lstype),
+ &lsap->lsa_un.un_intra_ap.intra_ap_lsid);
+
+ if (lsa_length < sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix))
+ return (1);
+ lsa_length -= sizeof (lsap->lsa_un.un_intra_ap.intra_ap_nprefix);
+ TCHECK(lsap->lsa_un.un_intra_ap.intra_ap_nprefix);
+ prefixes = EXTRACT_16BITS(&lsap->lsa_un.un_intra_ap.intra_ap_nprefix);
+ printf("\n\t Prefixes %d:", prefixes);
+
+ tptr = (u_int8_t *)lsap->lsa_un.un_intra_ap.intra_ap_prefix;
+ while (prefixes > 0) {
+ bytelen = ospf6_print_lsaprefix(tptr, lsa_length);
+ if (bytelen < 0)
+ goto trunc;
+ prefixes--;
+ lsa_length -= bytelen;
+ tptr += bytelen;
+ }
+ break;
+
+ case LS_TYPE_GRACE | LS_SCOPE_LINKLOCAL:
+ if (ospf_print_grace_lsa(tptr, lsa_length) == -1) {
+ return 1;
+ }
+ break;
+
+ case LS_TYPE_INTRA_ATE | LS_SCOPE_LINKLOCAL:
+ if (ospf_print_te_lsa(tptr, lsa_length) == -1) {
+ return 1;
+ }
+ break;
+
+ default:
+ if(!print_unknown_data(tptr,
+ "\n\t ",
+ lsa_length)) {
+ return (1);
+ }
+ break;
+ }
+
+ return (0);
+trunc:
+ return (1);
+}
+
+static int
+ospf6_decode_v3(register const struct ospf6hdr *op,
+ register const u_char *dataend)
+{
+ register const rtrid_t *ap;
+ register const struct lsr6 *lsrp;
+ register const struct lsa6_hdr *lshp;
+ register const struct lsa6 *lsap;
+ register int i;
+
+ switch (op->ospf6_type) {
+
+ case OSPF_TYPE_HELLO:
+ printf("\n\tOptions [%s]",
+ bittok2str(ospf6_option_values, "none",
+ EXTRACT_32BITS(&op->ospf6_hello.hello_options)));
+
+ TCHECK(op->ospf6_hello.hello_deadint);
+ printf("\n\t Hello Timer %us, Dead Timer %us, Interface-ID %s, Priority %u",
+ EXTRACT_16BITS(&op->ospf6_hello.hello_helloint),
+ EXTRACT_16BITS(&op->ospf6_hello.hello_deadint),
+ ipaddr_string(&op->ospf6_hello.hello_ifid),
+ op->ospf6_hello.hello_priority);
+
+ TCHECK(op->ospf6_hello.hello_dr);
+ if (op->ospf6_hello.hello_dr != 0)
+ printf("\n\t Designated Router %s",
+ ipaddr_string(&op->ospf6_hello.hello_dr));
+ TCHECK(op->ospf6_hello.hello_bdr);
+ if (op->ospf6_hello.hello_bdr != 0)
+ printf(", Backup Designated Router %s",
+ ipaddr_string(&op->ospf6_hello.hello_bdr));
+ if (vflag) {
+ printf("\n\t Neighbor List:");
+ ap = op->ospf6_hello.hello_neighbor;
+ while ((u_char *)ap < dataend) {
+ TCHECK(*ap);
+ printf("\n\t %s", ipaddr_string(ap));
+ ++ap;
+ }
+ }
+ break; /* HELLO */
+
+ case OSPF_TYPE_DD:
+ TCHECK(op->ospf6_db.db_options);
+ printf("\n\tOptions [%s]",
+ bittok2str(ospf6_option_values, "none",
+ EXTRACT_32BITS(&op->ospf6_db.db_options)));
+ TCHECK(op->ospf6_db.db_flags);
+ printf(", DD Flags [%s]",
+ bittok2str(ospf6_dd_flag_values,"none",op->ospf6_db.db_flags));
+
+ TCHECK(op->ospf6_db.db_seq);
+ printf(", MTU %u, DD-Sequence 0x%08x",
+ EXTRACT_16BITS(&op->ospf6_db.db_mtu),
+ EXTRACT_32BITS(&op->ospf6_db.db_seq));
+
+ /* Print all the LS adv's */
+ lshp = op->ospf6_db.db_lshdr;
+ while (!ospf6_print_lshdr(lshp)) {
+ ++lshp;
+ }
+ break;
+
+ case OSPF_TYPE_LS_REQ:
+ if (vflag) {
+ lsrp = op->ospf6_lsr;
+ while ((u_char *)lsrp < dataend) {
+ TCHECK(*lsrp);
+ printf("\n\t Advertising Router %s",
+ ipaddr_string(&lsrp->ls_router));
+ ospf6_print_ls_type(EXTRACT_16BITS(&lsrp->ls_type),
+ &lsrp->ls_stateid);
+ ++lsrp;
+ }
+ }
+ break;
+
+ case OSPF_TYPE_LS_UPDATE:
+ if (vflag) {
+ lsap = op->ospf6_lsu.lsu_lsa;
+ TCHECK(op->ospf6_lsu.lsu_count);
+ i = EXTRACT_32BITS(&op->ospf6_lsu.lsu_count);
+ while (i--) {
+ if (ospf6_print_lsa(lsap))
+ goto trunc;
+ lsap = (struct lsa6 *)((u_char *)lsap +
+ EXTRACT_16BITS(&lsap->ls_hdr.ls_length));
+ }
+ }
+ break;
+
+
+ case OSPF_TYPE_LS_ACK:
+ if (vflag) {
+ lshp = op->ospf6_lsa.lsa_lshdr;
+
+ while (!ospf6_print_lshdr(lshp)) {
+ ++lshp;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ return (0);
+trunc:
+ return (1);
+}
+
+void
+ospf6_print(register const u_char *bp, register u_int length)
+{
+ register const struct ospf6hdr *op;
+ register const u_char *dataend;
+ register const char *cp;
+
+ op = (struct ospf6hdr *)bp;
+
+ /* If the type is valid translate it, or just print the type */
+ /* value. If it's not valid, say so and return */
+ TCHECK(op->ospf6_type);
+ cp = tok2str(ospf6_type_values, "unknown LS-type", op->ospf6_type);
+ printf("OSPFv%u, %s, length %d", op->ospf6_version, cp, length);
+ if (*cp == 'u') {
+ return;
+ }
+
+ if(!vflag) { /* non verbose - so lets bail out here */
+ return;
+ }
+
+ TCHECK(op->ospf6_len);
+ if (length != EXTRACT_16BITS(&op->ospf6_len)) {
+ printf(" [len %d]", EXTRACT_16BITS(&op->ospf6_len));
+ return;
+ }
+ dataend = bp + length;
+
+ /* Print the routerid if it is not the same as the source */
+ TCHECK(op->ospf6_routerid);
+ printf("\n\tRouter-ID %s", ipaddr_string(&op->ospf6_routerid));
+
+ TCHECK(op->ospf6_areaid);
+ if (op->ospf6_areaid != 0)
+ printf(", Area %s", ipaddr_string(&op->ospf6_areaid));
+ else
+ printf(", Backbone Area");
+ TCHECK(op->ospf6_instanceid);
+ if (op->ospf6_instanceid)
+ printf(", Instance %u", op->ospf6_instanceid);
+
+ /* Do rest according to version. */
+ switch (op->ospf6_version) {
+
+ case 3:
+ /* ospf version 3 */
+ if (ospf6_decode_v3(op, dataend))
+ goto trunc;
+ break;
+
+ default:
+ printf(" ospf [version %d]", op->ospf6_version);
+ break;
+ } /* end switch on version */
+
+ return;
+trunc:
+ fputs(tstr, stdout);
+}
diff --git a/freebsd/contrib/tcpdump/print-otv.c b/freebsd/contrib/tcpdump/print-otv.c
new file mode 100644
index 00000000..12da24c8
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-otv.c
@@ -0,0 +1,81 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Francesco Fondelli (francesco dot fondelli, gmail dot com)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+
+#include "udp.h"
+
+/*
+ * OTV header, draft-hasmit-otv-04
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |R|R|R|R|I|R|R|R| Overlay ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Instance ID | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+void
+otv_print(const u_char *bp, u_int len)
+{
+ u_int8_t flags;
+ u_int32_t overlay_id;
+ u_int32_t instance_id;
+
+ if (len < 8) {
+ printf("[|OTV]");
+ return;
+ }
+
+ flags = *bp;
+ bp += 1;
+
+ overlay_id = EXTRACT_24BITS(bp);
+ bp += 3;
+
+ instance_id = EXTRACT_24BITS(bp);
+ bp += 4;
+
+ printf("OTV, ");
+
+ fputs("flags [", stdout);
+ if (flags & 0x08)
+ fputs("I", stdout);
+ else
+ fputs(".", stdout);
+ fputs("] ", stdout);
+
+ printf("(0x%02x), ", flags);
+ printf("overlay %u, ", overlay_id);
+ printf("instance %u\n", instance_id);
+
+ ether_print(gndo, bp, len - 8, len - 8, NULL, NULL);
+ return;
+}
diff --git a/freebsd/contrib/tcpdump/print-pflog.c b/freebsd/contrib/tcpdump/print-pflog.c
new file mode 100644
index 00000000..5f67fb0e
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-pflog.c
@@ -0,0 +1,190 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-pflog.c,v 1.16 2007-09-12 19:36:18 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef HAVE_NET_PFVAR_H
+#error "No pf headers available"
+#endif
+#include <rtems/bsd/sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/pfvar.h>
+#include <net/if_pflog.h>
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <pcap.h>
+
+#include "extract.h"
+#include "interface.h"
+#include "addrtoname.h"
+
+static struct tok pf_reasons[] = {
+ { 0, "0(match)" },
+ { 1, "1(bad-offset)" },
+ { 2, "2(fragment)" },
+ { 3, "3(short)" },
+ { 4, "4(normalize)" },
+ { 5, "5(memory)" },
+ { 6, "6(bad-timestamp)" },
+ { 7, "7(congestion)" },
+ { 8, "8(ip-option)" },
+ { 9, "9(proto-cksum)" },
+ { 10, "10(state-mismatch)" },
+ { 11, "11(state-insert)" },
+ { 12, "12(state-limit)" },
+ { 13, "13(src-limit)" },
+ { 14, "14(synproxy)" },
+ { 0, NULL }
+};
+
+static struct tok pf_actions[] = {
+ { PF_PASS, "pass" },
+ { PF_DROP, "block" },
+ { PF_SCRUB, "scrub" },
+ { PF_NAT, "nat" },
+ { PF_NONAT, "nat" },
+ { PF_BINAT, "binat" },
+ { PF_NOBINAT, "binat" },
+ { PF_RDR, "rdr" },
+ { PF_NORDR, "rdr" },
+ { PF_SYNPROXY_DROP, "synproxy-drop" },
+ { 0, NULL }
+};
+
+static struct tok pf_directions[] = {
+ { PF_INOUT, "in/out" },
+ { PF_IN, "in" },
+ { PF_OUT, "out" },
+ { 0, NULL }
+};
+
+/* For reading capture files on other systems */
+#define OPENBSD_AF_INET 2
+#define OPENBSD_AF_INET6 24
+
+static void
+pflog_print(const struct pfloghdr *hdr)
+{
+ u_int32_t rulenr, subrulenr;
+
+ rulenr = EXTRACT_32BITS(&hdr->rulenr);
+ subrulenr = EXTRACT_32BITS(&hdr->subrulenr);
+ if (subrulenr == (u_int32_t)-1)
+ printf("rule %u/", rulenr);
+ else
+ printf("rule %u.%s.%u/", rulenr, hdr->ruleset, subrulenr);
+
+ printf("%s: %s %s on %s: ",
+ tok2str(pf_reasons, "unkn(%u)", hdr->reason),
+ tok2str(pf_actions, "unkn(%u)", hdr->action),
+ tok2str(pf_directions, "unkn(%u)", hdr->dir),
+ hdr->ifname);
+}
+
+u_int
+pflog_if_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ u_int length = h->len;
+ u_int hdrlen;
+ u_int caplen = h->caplen;
+ const struct pfloghdr *hdr;
+ u_int8_t af;
+
+ /* check length */
+ if (caplen < sizeof(u_int8_t)) {
+ printf("[|pflog]");
+ return (caplen);
+ }
+
+#define MIN_PFLOG_HDRLEN 45
+ hdr = (struct pfloghdr *)p;
+ if (hdr->length < MIN_PFLOG_HDRLEN) {
+ printf("[pflog: invalid header length!]");
+ return (hdr->length); /* XXX: not really */
+ }
+ hdrlen = BPF_WORDALIGN(hdr->length);
+
+ if (caplen < hdrlen) {
+ printf("[|pflog]");
+ return (hdrlen); /* XXX: true? */
+ }
+
+ /* print what we know */
+ hdr = (struct pfloghdr *)p;
+ TCHECK(*hdr);
+ if (eflag)
+ pflog_print(hdr);
+
+ /* skip to the real packet */
+ af = hdr->af;
+ length -= hdrlen;
+ caplen -= hdrlen;
+ p += hdrlen;
+ switch (af) {
+
+ case AF_INET:
+#if OPENBSD_AF_INET != AF_INET
+ case OPENBSD_AF_INET: /* XXX: read pcap files */
+#endif
+ ip_print(gndo, p, length);
+ break;
+
+#ifdef INET6
+ case AF_INET6:
+#if OPENBSD_AF_INET6 != AF_INET6
+ case OPENBSD_AF_INET6: /* XXX: read pcap files */
+#endif
+ ip6_print(gndo, p, length);
+ break;
+#endif
+
+ default:
+ /* address family not handled, print raw packet */
+ if (!eflag)
+ pflog_print(hdr);
+ if (!suppress_default_print)
+ default_print(p, caplen);
+ }
+
+ return (hdrlen);
+trunc:
+ printf("[|pflog]");
+ return (hdrlen);
+}
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-pfsync.c b/freebsd/contrib/tcpdump/print-pfsync.c
new file mode 100644
index 00000000..fc71f732
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-pfsync.c
@@ -0,0 +1,453 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 2012 Gleb Smirnoff <glebius@FreeBSD.org>
+ * Copyright (c) 2002 Michael Shalayeff
+ * Copyright (c) 2001 Daniel Hartmeier
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $OpenBSD: print-pfsync.c,v 1.38 2012/09/19 13:50:36 mikeb Exp $
+ * $OpenBSD: pf_print_state.c,v 1.11 2012/07/08 17:48:37 lteo Exp $
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <sys/endian.h>
+#include <net/if.h>
+#define TCPSTATES
+#include <net/pfvar.h> /* XXX */
+#include <net/if_pfsync.h>
+#include <netinet/ip.h>
+#include <netinet/tcp_fsm.h>
+
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+static void pfsync_print(struct pfsync_header *, const u_char *, u_int);
+static void print_src_dst(const struct pfsync_state_peer *,
+ const struct pfsync_state_peer *, uint8_t);
+static void print_state(struct pfsync_state *);
+
+#ifdef notyet
+void
+pfsync_if_print(u_char *user, const struct pcap_pkthdr *h,
+ register const u_char *p)
+{
+ u_int caplen = h->caplen;
+
+ ts_print(&h->ts);
+
+ if (caplen < PFSYNC_HDRLEN) {
+ printf("[|pfsync]");
+ goto out;
+ }
+
+ pfsync_print((struct pfsync_header *)p,
+ p + sizeof(struct pfsync_header),
+ caplen - sizeof(struct pfsync_header));
+out:
+ if (xflag) {
+ default_print((const u_char *)p, caplen);
+ }
+ putchar('\n');
+}
+#endif /* notyet */
+
+void
+pfsync_ip_print(const u_char *bp, u_int len)
+{
+ struct pfsync_header *hdr = (struct pfsync_header *)bp;
+
+ if (len < PFSYNC_HDRLEN)
+ printf("[|pfsync]");
+ else
+ pfsync_print(hdr, bp + sizeof(struct pfsync_header),
+ len - sizeof(struct pfsync_header));
+}
+
+struct pfsync_actions {
+ const char *name;
+ size_t len;
+ void (*print)(const void *);
+};
+
+static void pfsync_print_clr(const void *);
+static void pfsync_print_state(const void *);
+static void pfsync_print_ins_ack(const void *);
+static void pfsync_print_upd_c(const void *);
+static void pfsync_print_upd_req(const void *);
+static void pfsync_print_del_c(const void *);
+static void pfsync_print_bus(const void *);
+static void pfsync_print_tdb(const void *);
+
+struct pfsync_actions actions[] = {
+ { "clear all", sizeof(struct pfsync_clr), pfsync_print_clr },
+ { "insert", sizeof(struct pfsync_state), pfsync_print_state },
+ { "insert ack", sizeof(struct pfsync_ins_ack), pfsync_print_ins_ack },
+ { "update", sizeof(struct pfsync_ins_ack), pfsync_print_state },
+ { "update compressed", sizeof(struct pfsync_upd_c),
+ pfsync_print_upd_c },
+ { "request uncompressed", sizeof(struct pfsync_upd_req),
+ pfsync_print_upd_req },
+ { "delete", sizeof(struct pfsync_state), pfsync_print_state },
+ { "delete compressed", sizeof(struct pfsync_del_c),
+ pfsync_print_del_c },
+ { "frag insert", 0, NULL },
+ { "frag delete", 0, NULL },
+ { "bulk update status", sizeof(struct pfsync_bus),
+ pfsync_print_bus },
+ { "tdb", 0, pfsync_print_tdb },
+ { "eof", 0, NULL },
+};
+
+static void
+pfsync_print(struct pfsync_header *hdr, const u_char *bp, u_int len)
+{
+ struct pfsync_subheader *subh;
+ int count, plen, i;
+ u_int alen;
+
+ plen = ntohs(hdr->len);
+
+ printf("PFSYNCv%d len %d", hdr->version, plen);
+
+ if (hdr->version != PFSYNC_VERSION)
+ return;
+
+ plen -= sizeof(*hdr);
+
+ while (plen > 0) {
+ if (len < sizeof(*subh))
+ break;
+
+ subh = (struct pfsync_subheader *)bp;
+ bp += sizeof(*subh);
+ len -= sizeof(*subh);
+ plen -= sizeof(*subh);
+
+ if (subh->action >= PFSYNC_ACT_MAX) {
+ printf("\n act UNKNOWN id %d", subh->action);
+ return;
+ }
+
+ count = ntohs(subh->count);
+ printf("\n %s count %d", actions[subh->action].name, count);
+ alen = actions[subh->action].len;
+
+ if (subh->action == PFSYNC_ACT_EOF)
+ return;
+
+ if (actions[subh->action].print == NULL) {
+ printf("\n unimplemented action %hhu", subh->action);
+ return;
+ }
+
+ for (i = 0; i < count; i++) {
+ if (len < alen) {
+ len = 0;
+ break;
+ }
+
+ if (vflag)
+ actions[subh->action].print(bp);
+
+ bp += alen;
+ len -= alen;
+ plen -= alen;
+ }
+ }
+
+ if (plen > 0) {
+ printf("\n ...");
+ return;
+ }
+ if (plen < 0) {
+ printf("\n invalid header length");
+ return;
+ }
+ if (len > 0)
+ printf("\n invalid packet length");
+}
+
+static void
+pfsync_print_clr(const void *bp)
+{
+ const struct pfsync_clr *clr = bp;
+
+ printf("\n\tcreatorid: %08x", htonl(clr->creatorid));
+ if (clr->ifname[0] != '\0')
+ printf(" interface: %s", clr->ifname);
+}
+
+static void
+pfsync_print_state(const void *bp)
+{
+ struct pfsync_state *st = (struct pfsync_state *)bp;
+
+ putchar('\n');
+ print_state(st);
+}
+
+static void
+pfsync_print_ins_ack(const void *bp)
+{
+ const struct pfsync_ins_ack *iack = bp;
+
+ printf("\n\tid: %016jx creatorid: %08x", (uintmax_t )be64toh(iack->id),
+ ntohl(iack->creatorid));
+}
+
+static void
+pfsync_print_upd_c(const void *bp)
+{
+ const struct pfsync_upd_c *u = bp;
+
+ printf("\n\tid: %016jx creatorid: %08x", (uintmax_t )be64toh(u->id),
+ ntohl(u->creatorid));
+ if (vflag > 2) {
+ printf("\n\tTCP? :");
+ print_src_dst(&u->src, &u->dst, IPPROTO_TCP);
+ }
+}
+
+static void
+pfsync_print_upd_req(const void *bp)
+{
+ const struct pfsync_upd_req *ur = bp;
+
+ printf("\n\tid: %016jx creatorid: %08x", (uintmax_t )be64toh(ur->id),
+ ntohl(ur->creatorid));
+}
+
+static void
+pfsync_print_del_c(const void *bp)
+{
+ const struct pfsync_del_c *d = bp;
+
+ printf("\n\tid: %016jx creatorid: %08x", (uintmax_t )be64toh(d->id),
+ ntohl(d->creatorid));
+}
+
+static void
+pfsync_print_bus(const void *bp)
+{
+ const struct pfsync_bus *b = bp;
+ uint32_t endtime;
+ int min, sec;
+ const char *status;
+
+ endtime = ntohl(b->endtime);
+ sec = endtime % 60;
+ endtime /= 60;
+ min = endtime % 60;
+ endtime /= 60;
+
+ switch (b->status) {
+ case PFSYNC_BUS_START:
+ status = "start";
+ break;
+ case PFSYNC_BUS_END:
+ status = "end";
+ break;
+ default:
+ status = "UNKNOWN";
+ break;
+ }
+
+ printf("\n\tcreatorid: %08x age: %.2u:%.2u:%.2u status: %s",
+ htonl(b->creatorid), endtime, min, sec, status);
+}
+
+static void
+pfsync_print_tdb(const void *bp)
+{
+ const struct pfsync_tdb *t = bp;
+
+ printf("\n\tspi: 0x%08x rpl: %ju cur_bytes: %ju",
+ ntohl(t->spi), (uintmax_t )be64toh(t->rpl),
+ (uintmax_t )be64toh(t->cur_bytes));
+}
+
+static void
+print_host(struct pf_addr *addr, uint16_t port, sa_family_t af,
+ const char *proto)
+{
+ char buf[48];
+
+ if (inet_ntop(af, addr, buf, sizeof(buf)) == NULL)
+ printf("?");
+ else
+ printf("%s", buf);
+
+ if (port)
+ printf(".%hu", ntohs(port));
+}
+
+static void
+print_seq(const struct pfsync_state_peer *p)
+{
+ if (p->seqdiff)
+ printf("[%u + %u](+%u)", ntohl(p->seqlo),
+ ntohl(p->seqhi) - ntohl(p->seqlo), ntohl(p->seqdiff));
+ else
+ printf("[%u + %u]", ntohl(p->seqlo),
+ ntohl(p->seqhi) - ntohl(p->seqlo));
+}
+
+static void
+print_src_dst(const struct pfsync_state_peer *src,
+ const struct pfsync_state_peer *dst, uint8_t proto)
+{
+
+ if (proto == IPPROTO_TCP) {
+ if (src->state <= TCPS_TIME_WAIT &&
+ dst->state <= TCPS_TIME_WAIT)
+ printf(" %s:%s", tcpstates[src->state],
+ tcpstates[dst->state]);
+ else if (src->state == PF_TCPS_PROXY_SRC ||
+ dst->state == PF_TCPS_PROXY_SRC)
+ printf(" PROXY:SRC");
+ else if (src->state == PF_TCPS_PROXY_DST ||
+ dst->state == PF_TCPS_PROXY_DST)
+ printf(" PROXY:DST");
+ else
+ printf(" <BAD STATE LEVELS %u:%u>",
+ src->state, dst->state);
+ if (vflag > 1) {
+ printf("\n\t");
+ print_seq(src);
+ if (src->wscale && dst->wscale)
+ printf(" wscale %u",
+ src->wscale & PF_WSCALE_MASK);
+ printf(" ");
+ print_seq(dst);
+ if (src->wscale && dst->wscale)
+ printf(" wscale %u",
+ dst->wscale & PF_WSCALE_MASK);
+ }
+ } else if (proto == IPPROTO_UDP && src->state < PFUDPS_NSTATES &&
+ dst->state < PFUDPS_NSTATES) {
+ const char *states[] = PFUDPS_NAMES;
+
+ printf(" %s:%s", states[src->state], states[dst->state]);
+ } else if (proto != IPPROTO_ICMP && src->state < PFOTHERS_NSTATES &&
+ dst->state < PFOTHERS_NSTATES) {
+ /* XXX ICMP doesn't really have state levels */
+ const char *states[] = PFOTHERS_NAMES;
+
+ printf(" %s:%s", states[src->state], states[dst->state]);
+ } else {
+ printf(" %u:%u", src->state, dst->state);
+ }
+}
+
+static void
+print_state(struct pfsync_state *s)
+{
+ struct pfsync_state_peer *src, *dst;
+ struct pfsync_state_key *sk, *nk;
+ int min, sec;
+
+ if (s->direction == PF_OUT) {
+ src = &s->src;
+ dst = &s->dst;
+ sk = &s->key[PF_SK_STACK];
+ nk = &s->key[PF_SK_WIRE];
+ if (s->proto == IPPROTO_ICMP || s->proto == IPPROTO_ICMPV6)
+ sk->port[0] = nk->port[0];
+ } else {
+ src = &s->dst;
+ dst = &s->src;
+ sk = &s->key[PF_SK_WIRE];
+ nk = &s->key[PF_SK_STACK];
+ if (s->proto == IPPROTO_ICMP || s->proto == IPPROTO_ICMPV6)
+ sk->port[1] = nk->port[1];
+ }
+ printf("\t%s ", s->ifname);
+ printf("proto %u ", s->proto);
+
+ print_host(&nk->addr[1], nk->port[1], s->af, NULL);
+ if (PF_ANEQ(&nk->addr[1], &sk->addr[1], s->af) ||
+ nk->port[1] != sk->port[1]) {
+ printf(" (");
+ print_host(&sk->addr[1], sk->port[1], s->af, NULL);
+ printf(")");
+ }
+ if (s->direction == PF_OUT)
+ printf(" -> ");
+ else
+ printf(" <- ");
+ print_host(&nk->addr[0], nk->port[0], s->af, NULL);
+ if (PF_ANEQ(&nk->addr[0], &sk->addr[0], s->af) ||
+ nk->port[0] != sk->port[0]) {
+ printf(" (");
+ print_host(&sk->addr[0], sk->port[0], s->af, NULL);
+ printf(")");
+ }
+
+ print_src_dst(src, dst, s->proto);
+
+ if (vflag > 1) {
+ uint64_t packets[2];
+ uint64_t bytes[2];
+ uint32_t creation = ntohl(s->creation);
+ uint32_t expire = ntohl(s->expire);
+
+ sec = creation % 60;
+ creation /= 60;
+ min = creation % 60;
+ creation /= 60;
+ printf("\n\tage %.2u:%.2u:%.2u", creation, min, sec);
+ sec = expire % 60;
+ expire /= 60;
+ min = expire % 60;
+ expire /= 60;
+ printf(", expires in %.2u:%.2u:%.2u", expire, min, sec);
+
+ bcopy(s->packets[0], &packets[0], sizeof(uint64_t));
+ bcopy(s->packets[1], &packets[1], sizeof(uint64_t));
+ bcopy(s->bytes[0], &bytes[0], sizeof(uint64_t));
+ bcopy(s->bytes[1], &bytes[1], sizeof(uint64_t));
+ printf(", %ju:%ju pkts, %ju:%ju bytes",
+ be64toh(packets[0]), be64toh(packets[1]),
+ be64toh(bytes[0]), be64toh(bytes[1]));
+ if (s->anchor != ntohl(-1))
+ printf(", anchor %u", ntohl(s->anchor));
+ if (s->rule != ntohl(-1))
+ printf(", rule %u", ntohl(s->rule));
+ }
+ if (vflag > 1) {
+ uint64_t id;
+
+ bcopy(&s->id, &id, sizeof(uint64_t));
+ printf("\n\tid: %016jx creatorid: %08x",
+ (uintmax_t )be64toh(id), ntohl(s->creatorid));
+ }
+}
diff --git a/freebsd/contrib/tcpdump/print-pgm.c b/freebsd/contrib/tcpdump/print-pgm.c
new file mode 100644
index 00000000..065cffc8
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-pgm.c
@@ -0,0 +1,849 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Andy Heffernan (ahh@juniper.net)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-pgm.c,v 1.5 2005-06-07 22:05:58 guy Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+
+#include "ip.h"
+#ifdef INET6
+#include "ip6.h"
+#endif
+#include "ipproto.h"
+
+/*
+ * PGM header (RFC 3208)
+ */
+struct pgm_header {
+ u_int16_t pgm_sport;
+ u_int16_t pgm_dport;
+ u_int8_t pgm_type;
+ u_int8_t pgm_options;
+ u_int16_t pgm_sum;
+ u_int8_t pgm_gsid[6];
+ u_int16_t pgm_length;
+};
+
+struct pgm_spm {
+ u_int32_t pgms_seq;
+ u_int32_t pgms_trailseq;
+ u_int32_t pgms_leadseq;
+ u_int16_t pgms_nla_afi;
+ u_int16_t pgms_reserved;
+ /* ... u_int8_t pgms_nla[0]; */
+ /* ... options */
+};
+
+struct pgm_nak {
+ u_int32_t pgmn_seq;
+ u_int16_t pgmn_source_afi;
+ u_int16_t pgmn_reserved;
+ /* ... u_int8_t pgmn_source[0]; */
+ /* ... u_int16_t pgmn_group_afi */
+ /* ... u_int16_t pgmn_reserved2; */
+ /* ... u_int8_t pgmn_group[0]; */
+ /* ... options */
+};
+
+struct pgm_ack {
+ u_int32_t pgma_rx_max_seq;
+ u_int32_t pgma_bitmap;
+ /* ... options */
+};
+
+struct pgm_poll {
+ u_int32_t pgmp_seq;
+ u_int16_t pgmp_round;
+ u_int16_t pgmp_reserved;
+ /* ... options */
+};
+
+struct pgm_polr {
+ u_int32_t pgmp_seq;
+ u_int16_t pgmp_round;
+ u_int16_t pgmp_subtype;
+ u_int16_t pgmp_nla_afi;
+ u_int16_t pgmp_reserved;
+ /* ... u_int8_t pgmp_nla[0]; */
+ /* ... options */
+};
+
+struct pgm_data {
+ u_int32_t pgmd_seq;
+ u_int32_t pgmd_trailseq;
+ /* ... options */
+};
+
+typedef enum _pgm_type {
+ PGM_SPM = 0, /* source path message */
+ PGM_POLL = 1, /* POLL Request */
+ PGM_POLR = 2, /* POLL Response */
+ PGM_ODATA = 4, /* original data */
+ PGM_RDATA = 5, /* repair data */
+ PGM_NAK = 8, /* NAK */
+ PGM_NULLNAK = 9, /* Null NAK */
+ PGM_NCF = 10, /* NAK Confirmation */
+ PGM_ACK = 11, /* ACK for congestion control */
+ PGM_SPMR = 12, /* SPM request */
+ PGM_MAX = 255
+} pgm_type;
+
+#define PGM_OPT_BIT_PRESENT 0x01
+#define PGM_OPT_BIT_NETWORK 0x02
+#define PGM_OPT_BIT_VAR_PKTLEN 0x40
+#define PGM_OPT_BIT_PARITY 0x80
+
+#define PGM_OPT_LENGTH 0x00
+#define PGM_OPT_FRAGMENT 0x01
+#define PGM_OPT_NAK_LIST 0x02
+#define PGM_OPT_JOIN 0x03
+#define PGM_OPT_NAK_BO_IVL 0x04
+#define PGM_OPT_NAK_BO_RNG 0x05
+
+#define PGM_OPT_REDIRECT 0x07
+#define PGM_OPT_PARITY_PRM 0x08
+#define PGM_OPT_PARITY_GRP 0x09
+#define PGM_OPT_CURR_TGSIZE 0x0A
+#define PGM_OPT_NBR_UNREACH 0x0B
+#define PGM_OPT_PATH_NLA 0x0C
+
+#define PGM_OPT_SYN 0x0D
+#define PGM_OPT_FIN 0x0E
+#define PGM_OPT_RST 0x0F
+#define PGM_OPT_CR 0x10
+#define PGM_OPT_CRQST 0x11
+
+#define PGM_OPT_PGMCC_DATA 0x12
+#define PGM_OPT_PGMCC_FEEDBACK 0x13
+
+#define PGM_OPT_MASK 0x7f
+
+#define PGM_OPT_END 0x80 /* end of options marker */
+
+#define PGM_MIN_OPT_LEN 4
+
+#ifndef AFI_IP
+#define AFI_IP 1
+#define AFI_IP6 2
+#endif
+
+void
+pgm_print(register const u_char *bp, register u_int length,
+ register const u_char *bp2)
+{
+ register const struct pgm_header *pgm;
+ register const struct ip *ip;
+ register char ch;
+ u_int16_t sport, dport;
+ int addr_size;
+ const void *nla;
+ int nla_af;
+#ifdef INET6
+ char nla_buf[INET6_ADDRSTRLEN];
+ register const struct ip6_hdr *ip6;
+#else
+ char nla_buf[INET_ADDRSTRLEN];
+#endif
+ u_int8_t opt_type, opt_len, flags1, flags2;
+ u_int32_t seq, opts_len, len, offset;
+
+ pgm = (struct pgm_header *)bp;
+ ip = (struct ip *)bp2;
+#ifdef INET6
+ if (IP_V(ip) == 6)
+ ip6 = (struct ip6_hdr *)bp2;
+ else
+ ip6 = NULL;
+#else /* INET6 */
+ if (IP_V(ip) == 6) {
+ (void)printf("Can't handle IPv6");
+ return;
+ }
+#endif /* INET6 */
+ ch = '\0';
+ if (!TTEST(pgm->pgm_dport)) {
+#ifdef INET6
+ if (ip6) {
+ (void)printf("%s > %s: [|pgm]",
+ ip6addr_string(&ip6->ip6_src),
+ ip6addr_string(&ip6->ip6_dst));
+ return;
+ } else
+#endif /* INET6 */
+ {
+ (void)printf("%s > %s: [|pgm]",
+ ipaddr_string(&ip->ip_src),
+ ipaddr_string(&ip->ip_dst));
+ return;
+ }
+ }
+
+ sport = EXTRACT_16BITS(&pgm->pgm_sport);
+ dport = EXTRACT_16BITS(&pgm->pgm_dport);
+
+#ifdef INET6
+ if (ip6) {
+ if (ip6->ip6_nxt == IPPROTO_PGM) {
+ (void)printf("%s.%s > %s.%s: ",
+ ip6addr_string(&ip6->ip6_src),
+ tcpport_string(sport),
+ ip6addr_string(&ip6->ip6_dst),
+ tcpport_string(dport));
+ } else {
+ (void)printf("%s > %s: ",
+ tcpport_string(sport), tcpport_string(dport));
+ }
+ } else
+#endif /*INET6*/
+ {
+ if (ip->ip_p == IPPROTO_PGM) {
+ (void)printf("%s.%s > %s.%s: ",
+ ipaddr_string(&ip->ip_src),
+ tcpport_string(sport),
+ ipaddr_string(&ip->ip_dst),
+ tcpport_string(dport));
+ } else {
+ (void)printf("%s > %s: ",
+ tcpport_string(sport), tcpport_string(dport));
+ }
+ }
+
+ TCHECK(*pgm);
+
+ (void)printf("PGM, length %u", pgm->pgm_length);
+
+ if (!vflag)
+ return;
+
+ if (length > pgm->pgm_length)
+ length = pgm->pgm_length;
+
+ (void)printf(" 0x%02x%02x%02x%02x%02x%02x ",
+ pgm->pgm_gsid[0],
+ pgm->pgm_gsid[1],
+ pgm->pgm_gsid[2],
+ pgm->pgm_gsid[3],
+ pgm->pgm_gsid[4],
+ pgm->pgm_gsid[5]);
+ switch (pgm->pgm_type) {
+ case PGM_SPM: {
+ struct pgm_spm *spm;
+
+ spm = (struct pgm_spm *)(pgm + 1);
+ TCHECK(*spm);
+
+ switch (EXTRACT_16BITS(&spm->pgms_nla_afi)) {
+ case AFI_IP:
+ addr_size = sizeof(struct in_addr);
+ nla_af = AF_INET;
+ break;
+#ifdef INET6
+ case AFI_IP6:
+ addr_size = sizeof(struct in6_addr);
+ nla_af = AF_INET6;
+ break;
+#endif
+ default:
+ goto trunc;
+ break;
+ }
+ bp = (u_char *) (spm + 1);
+ TCHECK2(*bp, addr_size);
+ nla = bp;
+ bp += addr_size;
+
+ inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf));
+ (void)printf("SPM seq %u trail %u lead %u nla %s",
+ EXTRACT_32BITS(&spm->pgms_seq),
+ EXTRACT_32BITS(&spm->pgms_trailseq),
+ EXTRACT_32BITS(&spm->pgms_leadseq),
+ nla_buf);
+ break;
+ }
+
+ case PGM_POLL: {
+ struct pgm_poll *poll;
+
+ poll = (struct pgm_poll *)(pgm + 1);
+ TCHECK(*poll);
+ (void)printf("POLL seq %u round %u",
+ EXTRACT_32BITS(&poll->pgmp_seq),
+ EXTRACT_16BITS(&poll->pgmp_round));
+ bp = (u_char *) (poll + 1);
+ break;
+ }
+ case PGM_POLR: {
+ struct pgm_polr *polr;
+ u_int32_t ivl, rnd, mask;
+
+ polr = (struct pgm_polr *)(pgm + 1);
+ TCHECK(*polr);
+
+ switch (EXTRACT_16BITS(&polr->pgmp_nla_afi)) {
+ case AFI_IP:
+ addr_size = sizeof(struct in_addr);
+ nla_af = AF_INET;
+ break;
+#ifdef INET6
+ case AFI_IP6:
+ addr_size = sizeof(struct in6_addr);
+ nla_af = AF_INET6;
+ break;
+#endif
+ default:
+ goto trunc;
+ break;
+ }
+ bp = (u_char *) (polr + 1);
+ TCHECK2(*bp, addr_size);
+ nla = bp;
+ bp += addr_size;
+
+ inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf));
+
+ TCHECK2(*bp, sizeof(u_int32_t));
+ ivl = EXTRACT_32BITS(bp);
+ bp += sizeof(u_int32_t);
+
+ TCHECK2(*bp, sizeof(u_int32_t));
+ rnd = EXTRACT_32BITS(bp);
+ bp += sizeof(u_int32_t);
+
+ TCHECK2(*bp, sizeof(u_int32_t));
+ mask = EXTRACT_32BITS(bp);
+ bp += sizeof(u_int32_t);
+
+ (void)printf("POLR seq %u round %u nla %s ivl %u rnd 0x%08x "
+ "mask 0x%08x", EXTRACT_32BITS(&polr->pgmp_seq),
+ EXTRACT_16BITS(&polr->pgmp_round), nla_buf, ivl, rnd, mask);
+ break;
+ }
+ case PGM_ODATA: {
+ struct pgm_data *odata;
+
+ odata = (struct pgm_data *)(pgm + 1);
+ TCHECK(*odata);
+ (void)printf("ODATA trail %u seq %u",
+ EXTRACT_32BITS(&odata->pgmd_trailseq),
+ EXTRACT_32BITS(&odata->pgmd_seq));
+ bp = (u_char *) (odata + 1);
+ break;
+ }
+
+ case PGM_RDATA: {
+ struct pgm_data *rdata;
+
+ rdata = (struct pgm_data *)(pgm + 1);
+ TCHECK(*rdata);
+ (void)printf("RDATA trail %u seq %u",
+ EXTRACT_32BITS(&rdata->pgmd_trailseq),
+ EXTRACT_32BITS(&rdata->pgmd_seq));
+ bp = (u_char *) (rdata + 1);
+ break;
+ }
+
+ case PGM_NAK:
+ case PGM_NULLNAK:
+ case PGM_NCF: {
+ struct pgm_nak *nak;
+ const void *source, *group;
+ int source_af, group_af;
+#ifdef INET6
+ char source_buf[INET6_ADDRSTRLEN], group_buf[INET6_ADDRSTRLEN];
+#else
+ char source_buf[INET_ADDRSTRLEN], group_buf[INET_ADDRSTRLEN];
+#endif
+
+ nak = (struct pgm_nak *)(pgm + 1);
+ TCHECK(*nak);
+
+ /*
+ * Skip past the source, saving info along the way
+ * and stopping if we don't have enough.
+ */
+ switch (EXTRACT_16BITS(&nak->pgmn_source_afi)) {
+ case AFI_IP:
+ addr_size = sizeof(struct in_addr);
+ source_af = AF_INET;
+ break;
+#ifdef INET6
+ case AFI_IP6:
+ addr_size = sizeof(struct in6_addr);
+ source_af = AF_INET6;
+ break;
+#endif
+ default:
+ goto trunc;
+ break;
+ }
+ bp = (u_char *) (nak + 1);
+ TCHECK2(*bp, addr_size);
+ source = bp;
+ bp += addr_size;
+
+ /*
+ * Skip past the group, saving info along the way
+ * and stopping if we don't have enough.
+ */
+ switch (EXTRACT_16BITS(bp)) {
+ case AFI_IP:
+ addr_size = sizeof(struct in_addr);
+ group_af = AF_INET;
+ break;
+#ifdef INET6
+ case AFI_IP6:
+ addr_size = sizeof(struct in6_addr);
+ group_af = AF_INET6;
+ break;
+#endif
+ default:
+ goto trunc;
+ break;
+ }
+ bp += (2 * sizeof(u_int16_t));
+ TCHECK2(*bp, addr_size);
+ group = bp;
+ bp += addr_size;
+
+ /*
+ * Options decoding can go here.
+ */
+ inet_ntop(source_af, source, source_buf, sizeof(source_buf));
+ inet_ntop(group_af, group, group_buf, sizeof(group_buf));
+ switch (pgm->pgm_type) {
+ case PGM_NAK:
+ (void)printf("NAK ");
+ break;
+ case PGM_NULLNAK:
+ (void)printf("NNAK ");
+ break;
+ case PGM_NCF:
+ (void)printf("NCF ");
+ break;
+ default:
+ break;
+ }
+ (void)printf("(%s -> %s), seq %u",
+ source_buf, group_buf, EXTRACT_32BITS(&nak->pgmn_seq));
+ break;
+ }
+
+ case PGM_ACK: {
+ struct pgm_ack *ack;
+
+ ack = (struct pgm_ack *)(pgm + 1);
+ TCHECK(*ack);
+ (void)printf("ACK seq %u",
+ EXTRACT_32BITS(&ack->pgma_rx_max_seq));
+ bp = (u_char *) (ack + 1);
+ break;
+ }
+
+ case PGM_SPMR:
+ (void)printf("SPMR");
+ break;
+
+ default:
+ (void)printf("UNKNOWN type %0x02x", pgm->pgm_type);
+ break;
+
+ }
+ if (pgm->pgm_options & PGM_OPT_BIT_PRESENT) {
+
+ /*
+ * make sure there's enough for the first option header
+ */
+ if (!TTEST2(*bp, PGM_MIN_OPT_LEN)) {
+ (void)printf("[|OPT]");
+ return;
+ }
+
+ /*
+ * That option header MUST be an OPT_LENGTH option
+ * (see the first paragraph of section 9.1 in RFC 3208).
+ */
+ opt_type = *bp++;
+ if ((opt_type & PGM_OPT_MASK) != PGM_OPT_LENGTH) {
+ (void)printf("[First option bad, should be PGM_OPT_LENGTH, is %u]", opt_type & PGM_OPT_MASK);
+ return;
+ }
+ opt_len = *bp++;
+ if (opt_len != 4) {
+ (void)printf("[Bad OPT_LENGTH option, length %u != 4]", opt_len);
+ return;
+ }
+ opts_len = EXTRACT_16BITS(bp);
+ if (opts_len < 4) {
+ (void)printf("[Bad total option length %u < 4]", opts_len);
+ return;
+ }
+ bp += sizeof(u_int16_t);
+ (void)printf(" OPTS LEN %d", opts_len);
+ opts_len -= 4;
+
+ while (opts_len) {
+ if (opts_len < PGM_MIN_OPT_LEN) {
+ (void)printf("[Total option length leaves no room for final option]");
+ return;
+ }
+ opt_type = *bp++;
+ opt_len = *bp++;
+ if (opt_len < PGM_MIN_OPT_LEN) {
+ (void)printf("[Bad option, length %u < %u]", opt_len,
+ PGM_MIN_OPT_LEN);
+ break;
+ }
+ if (opts_len < opt_len) {
+ (void)printf("[Total option length leaves no room for final option]");
+ return;
+ }
+ if (!TTEST2(*bp, opt_len - 2)) {
+ (void)printf(" [|OPT]");
+ return;
+ }
+
+ switch (opt_type & PGM_OPT_MASK) {
+ case PGM_OPT_LENGTH:
+ if (opt_len != 4) {
+ (void)printf("[Bad OPT_LENGTH option, length %u != 4]", opt_len);
+ return;
+ }
+ (void)printf(" OPTS LEN (extra?) %d", EXTRACT_16BITS(bp));
+ bp += sizeof(u_int16_t);
+ opts_len -= 4;
+ break;
+
+ case PGM_OPT_FRAGMENT:
+ if (opt_len != 16) {
+ (void)printf("[Bad OPT_FRAGMENT option, length %u != 16]", opt_len);
+ return;
+ }
+ flags1 = *bp++;
+ flags2 = *bp++;
+ seq = EXTRACT_32BITS(bp);
+ bp += sizeof(u_int32_t);
+ offset = EXTRACT_32BITS(bp);
+ bp += sizeof(u_int32_t);
+ len = EXTRACT_32BITS(bp);
+ bp += sizeof(u_int32_t);
+ (void)printf(" FRAG seq %u off %u len %u", seq, offset, len);
+ opts_len -= 16;
+ break;
+
+ case PGM_OPT_NAK_LIST:
+ flags1 = *bp++;
+ flags2 = *bp++;
+ opt_len -= sizeof(u_int32_t); /* option header */
+ (void)printf(" NAK LIST");
+ while (opt_len) {
+ if (opt_len < sizeof(u_int32_t)) {
+ (void)printf("[Option length not a multiple of 4]");
+ return;
+ }
+ TCHECK2(*bp, sizeof(u_int32_t));
+ (void)printf(" %u", EXTRACT_32BITS(bp));
+ bp += sizeof(u_int32_t);
+ opt_len -= sizeof(u_int32_t);
+ opts_len -= sizeof(u_int32_t);
+ }
+ break;
+
+ case PGM_OPT_JOIN:
+ if (opt_len != 8) {
+ (void)printf("[Bad OPT_JOIN option, length %u != 8]", opt_len);
+ return;
+ }
+ flags1 = *bp++;
+ flags2 = *bp++;
+ seq = EXTRACT_32BITS(bp);
+ bp += sizeof(u_int32_t);
+ (void)printf(" JOIN %u", seq);
+ opts_len -= 8;
+ break;
+
+ case PGM_OPT_NAK_BO_IVL:
+ if (opt_len != 12) {
+ (void)printf("[Bad OPT_NAK_BO_IVL option, length %u != 12]", opt_len);
+ return;
+ }
+ flags1 = *bp++;
+ flags2 = *bp++;
+ offset = EXTRACT_32BITS(bp);
+ bp += sizeof(u_int32_t);
+ seq = EXTRACT_32BITS(bp);
+ bp += sizeof(u_int32_t);
+ (void)printf(" BACKOFF ivl %u ivlseq %u", offset, seq);
+ opts_len -= 12;
+ break;
+
+ case PGM_OPT_NAK_BO_RNG:
+ if (opt_len != 12) {
+ (void)printf("[Bad OPT_NAK_BO_RNG option, length %u != 12]", opt_len);
+ return;
+ }
+ flags1 = *bp++;
+ flags2 = *bp++;
+ offset = EXTRACT_32BITS(bp);
+ bp += sizeof(u_int32_t);
+ seq = EXTRACT_32BITS(bp);
+ bp += sizeof(u_int32_t);
+ (void)printf(" BACKOFF max %u min %u", offset, seq);
+ opts_len -= 12;
+ break;
+
+ case PGM_OPT_REDIRECT:
+ flags1 = *bp++;
+ flags2 = *bp++;
+ switch (EXTRACT_16BITS(bp)) {
+ case AFI_IP:
+ addr_size = sizeof(struct in_addr);
+ nla_af = AF_INET;
+ break;
+#ifdef INET6
+ case AFI_IP6:
+ addr_size = sizeof(struct in6_addr);
+ nla_af = AF_INET6;
+ break;
+#endif
+ default:
+ goto trunc;
+ break;
+ }
+ bp += (2 * sizeof(u_int16_t));
+ if (opt_len != 4 + addr_size) {
+ (void)printf("[Bad OPT_REDIRECT option, length %u != 4 + address size]", opt_len);
+ return;
+ }
+ TCHECK2(*bp, addr_size);
+ nla = bp;
+ bp += addr_size;
+
+ inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf));
+ (void)printf(" REDIRECT %s", (char *)nla);
+ opts_len -= 4 + addr_size;
+ break;
+
+ case PGM_OPT_PARITY_PRM:
+ if (opt_len != 8) {
+ (void)printf("[Bad OPT_PARITY_PRM option, length %u != 8]", opt_len);
+ return;
+ }
+ flags1 = *bp++;
+ flags2 = *bp++;
+ len = EXTRACT_32BITS(bp);
+ bp += sizeof(u_int32_t);
+ (void)printf(" PARITY MAXTGS %u", len);
+ opts_len -= 8;
+ break;
+
+ case PGM_OPT_PARITY_GRP:
+ if (opt_len != 8) {
+ (void)printf("[Bad OPT_PARITY_GRP option, length %u != 8]", opt_len);
+ return;
+ }
+ flags1 = *bp++;
+ flags2 = *bp++;
+ seq = EXTRACT_32BITS(bp);
+ bp += sizeof(u_int32_t);
+ (void)printf(" PARITY GROUP %u", seq);
+ opts_len -= 8;
+ break;
+
+ case PGM_OPT_CURR_TGSIZE:
+ if (opt_len != 8) {
+ (void)printf("[Bad OPT_CURR_TGSIZE option, length %u != 8]", opt_len);
+ return;
+ }
+ flags1 = *bp++;
+ flags2 = *bp++;
+ len = EXTRACT_32BITS(bp);
+ bp += sizeof(u_int32_t);
+ (void)printf(" PARITY ATGS %u", len);
+ opts_len -= 8;
+ break;
+
+ case PGM_OPT_NBR_UNREACH:
+ if (opt_len != 4) {
+ (void)printf("[Bad OPT_NBR_UNREACH option, length %u != 4]", opt_len);
+ return;
+ }
+ flags1 = *bp++;
+ flags2 = *bp++;
+ (void)printf(" NBR_UNREACH");
+ opts_len -= 4;
+ break;
+
+ case PGM_OPT_PATH_NLA:
+ (void)printf(" PATH_NLA [%d]", opt_len);
+ bp += opt_len;
+ opts_len -= opt_len;
+ break;
+
+ case PGM_OPT_SYN:
+ if (opt_len != 4) {
+ (void)printf("[Bad OPT_SYN option, length %u != 4]", opt_len);
+ return;
+ }
+ flags1 = *bp++;
+ flags2 = *bp++;
+ (void)printf(" SYN");
+ opts_len -= 4;
+ break;
+
+ case PGM_OPT_FIN:
+ if (opt_len != 4) {
+ (void)printf("[Bad OPT_FIN option, length %u != 4]", opt_len);
+ return;
+ }
+ flags1 = *bp++;
+ flags2 = *bp++;
+ (void)printf(" FIN");
+ opts_len -= 4;
+ break;
+
+ case PGM_OPT_RST:
+ if (opt_len != 4) {
+ (void)printf("[Bad OPT_RST option, length %u != 4]", opt_len);
+ return;
+ }
+ flags1 = *bp++;
+ flags2 = *bp++;
+ (void)printf(" RST");
+ opts_len -= 4;
+ break;
+
+ case PGM_OPT_CR:
+ (void)printf(" CR");
+ bp += opt_len;
+ opts_len -= opt_len;
+ break;
+
+ case PGM_OPT_CRQST:
+ if (opt_len != 4) {
+ (void)printf("[Bad OPT_CRQST option, length %u != 4]", opt_len);
+ return;
+ }
+ flags1 = *bp++;
+ flags2 = *bp++;
+ (void)printf(" CRQST");
+ opts_len -= 4;
+ break;
+
+ case PGM_OPT_PGMCC_DATA:
+ flags1 = *bp++;
+ flags2 = *bp++;
+ offset = EXTRACT_32BITS(bp);
+ bp += sizeof(u_int32_t);
+ switch (EXTRACT_16BITS(bp)) {
+ case AFI_IP:
+ addr_size = sizeof(struct in_addr);
+ nla_af = AF_INET;
+ break;
+#ifdef INET6
+ case AFI_IP6:
+ addr_size = sizeof(struct in6_addr);
+ nla_af = AF_INET6;
+ break;
+#endif
+ default:
+ goto trunc;
+ break;
+ }
+ bp += (2 * sizeof(u_int16_t));
+ if (opt_len != 12 + addr_size) {
+ (void)printf("[Bad OPT_PGMCC_DATA option, length %u != 12 + address size]", opt_len);
+ return;
+ }
+ TCHECK2(*bp, addr_size);
+ nla = bp;
+ bp += addr_size;
+
+ inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf));
+ (void)printf(" PGMCC DATA %u %s", offset, (char*)nla);
+ opts_len -= 16;
+ break;
+
+ case PGM_OPT_PGMCC_FEEDBACK:
+ flags1 = *bp++;
+ flags2 = *bp++;
+ offset = EXTRACT_32BITS(bp);
+ bp += sizeof(u_int32_t);
+ switch (EXTRACT_16BITS(bp)) {
+ case AFI_IP:
+ addr_size = sizeof(struct in_addr);
+ nla_af = AF_INET;
+ break;
+#ifdef INET6
+ case AFI_IP6:
+ addr_size = sizeof(struct in6_addr);
+ nla_af = AF_INET6;
+ break;
+#endif
+ default:
+ goto trunc;
+ break;
+ }
+ bp += (2 * sizeof(u_int16_t));
+ if (opt_len != 12 + addr_size) {
+ (void)printf("[Bad OPT_PGMCC_FEEDBACK option, length %u != 12 + address size]", opt_len);
+ return;
+ }
+ TCHECK2(*bp, addr_size);
+ nla = bp;
+ bp += addr_size;
+
+ inet_ntop(nla_af, nla, nla_buf, sizeof(nla_buf));
+ (void)printf(" PGMCC FEEDBACK %u %s", offset, (char*)nla);
+ opts_len -= 16;
+ break;
+
+ default:
+ (void)printf(" OPT_%02X [%d] ", opt_type, opt_len);
+ bp += opt_len;
+ opts_len -= opt_len;
+ break;
+ }
+
+ if (opt_type & PGM_OPT_END)
+ break;
+ }
+ }
+
+ (void)printf(" [%u]", EXTRACT_16BITS(&pgm->pgm_length));
+
+ return;
+
+trunc:
+ fputs("[|pgm]", stdout);
+ if (ch != '\0')
+ putchar('>');
+}
diff --git a/freebsd/contrib/tcpdump/print-pim.c b/freebsd/contrib/tcpdump/print-pim.c
new file mode 100644
index 00000000..32a549c6
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-pim.c
@@ -0,0 +1,1097 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-pim.c,v 1.49 2006-02-13 01:31:35 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+#include "ip.h"
+
+#define PIMV2_TYPE_HELLO 0
+#define PIMV2_TYPE_REGISTER 1
+#define PIMV2_TYPE_REGISTER_STOP 2
+#define PIMV2_TYPE_JOIN_PRUNE 3
+#define PIMV2_TYPE_BOOTSTRAP 4
+#define PIMV2_TYPE_ASSERT 5
+#define PIMV2_TYPE_GRAFT 6
+#define PIMV2_TYPE_GRAFT_ACK 7
+#define PIMV2_TYPE_CANDIDATE_RP 8
+#define PIMV2_TYPE_PRUNE_REFRESH 9
+
+static struct tok pimv2_type_values[] = {
+ { PIMV2_TYPE_HELLO, "Hello" },
+ { PIMV2_TYPE_REGISTER, "Register" },
+ { PIMV2_TYPE_REGISTER_STOP, "Register Stop" },
+ { PIMV2_TYPE_JOIN_PRUNE, "Join / Prune" },
+ { PIMV2_TYPE_BOOTSTRAP, "Bootstrap" },
+ { PIMV2_TYPE_ASSERT, "Assert" },
+ { PIMV2_TYPE_GRAFT, "Graft" },
+ { PIMV2_TYPE_GRAFT_ACK, "Graft Acknowledgement" },
+ { PIMV2_TYPE_CANDIDATE_RP, "Candidate RP Advertisement" },
+ { PIMV2_TYPE_PRUNE_REFRESH, "Prune Refresh" },
+ { 0, NULL}
+};
+
+#define PIMV2_HELLO_OPTION_HOLDTIME 1
+#define PIMV2_HELLO_OPTION_LANPRUNEDELAY 2
+#define PIMV2_HELLO_OPTION_DR_PRIORITY_OLD 18
+#define PIMV2_HELLO_OPTION_DR_PRIORITY 19
+#define PIMV2_HELLO_OPTION_GENID 20
+#define PIMV2_HELLO_OPTION_REFRESH_CAP 21
+#define PIMV2_HELLO_OPTION_BIDIR_CAP 22
+#define PIMV2_HELLO_OPTION_ADDRESS_LIST 24
+#define PIMV2_HELLO_OPTION_ADDRESS_LIST_OLD 65001
+
+static struct tok pimv2_hello_option_values[] = {
+ { PIMV2_HELLO_OPTION_HOLDTIME, "Hold Time" },
+ { PIMV2_HELLO_OPTION_LANPRUNEDELAY, "LAN Prune Delay" },
+ { PIMV2_HELLO_OPTION_DR_PRIORITY_OLD, "DR Priority (Old)" },
+ { PIMV2_HELLO_OPTION_DR_PRIORITY, "DR Priority" },
+ { PIMV2_HELLO_OPTION_GENID, "Generation ID" },
+ { PIMV2_HELLO_OPTION_REFRESH_CAP, "State Refresh Capability" },
+ { PIMV2_HELLO_OPTION_BIDIR_CAP, "Bi-Directional Capability" },
+ { PIMV2_HELLO_OPTION_ADDRESS_LIST, "Address List" },
+ { PIMV2_HELLO_OPTION_ADDRESS_LIST_OLD, "Address List (Old)" },
+ { 0, NULL}
+};
+
+#define PIMV2_REGISTER_FLAG_LEN 4
+#define PIMV2_REGISTER_FLAG_BORDER 0x80000000
+#define PIMV2_REGISTER_FLAG_NULL 0x40000000
+
+static struct tok pimv2_register_flag_values[] = {
+ { PIMV2_REGISTER_FLAG_BORDER, "Border" },
+ { PIMV2_REGISTER_FLAG_NULL, "Null" },
+ { 0, NULL}
+};
+
+/*
+ * XXX: We consider a case where IPv6 is not ready yet for portability,
+ * but PIM dependent defintions should be independent of IPv6...
+ */
+
+struct pim {
+ u_int8_t pim_typever;
+ /* upper 4bit: PIM version number; 2 for PIMv2 */
+ /* lower 4bit: the PIM message type, currently they are:
+ * Hello, Register, Register-Stop, Join/Prune,
+ * Bootstrap, Assert, Graft (PIM-DM only),
+ * Graft-Ack (PIM-DM only), C-RP-Adv
+ */
+#define PIM_VER(x) (((x) & 0xf0) >> 4)
+#define PIM_TYPE(x) ((x) & 0x0f)
+ u_char pim_rsv; /* Reserved */
+ u_short pim_cksum; /* IP style check sum */
+};
+
+static void pimv2_print(register const u_char *bp, register u_int len, u_int cksum);
+
+static void
+pimv1_join_prune_print(register const u_char *bp, register u_int len)
+{
+ int maddrlen, addrlen, ngroups, njoin, nprune;
+ int njp;
+
+ /* If it's a single group and a single source, use 1-line output. */
+ if (TTEST2(bp[0], 30) && bp[11] == 1 &&
+ ((njoin = EXTRACT_16BITS(&bp[20])) + EXTRACT_16BITS(&bp[22])) == 1) {
+ int hold;
+
+ (void)printf(" RPF %s ", ipaddr_string(bp));
+ hold = EXTRACT_16BITS(&bp[6]);
+ if (hold != 180) {
+ (void)printf("Hold ");
+ relts_print(hold);
+ }
+ (void)printf("%s (%s/%d, %s", njoin ? "Join" : "Prune",
+ ipaddr_string(&bp[26]), bp[25] & 0x3f,
+ ipaddr_string(&bp[12]));
+ if (EXTRACT_32BITS(&bp[16]) != 0xffffffff)
+ (void)printf("/%s", ipaddr_string(&bp[16]));
+ (void)printf(") %s%s %s",
+ (bp[24] & 0x01) ? "Sparse" : "Dense",
+ (bp[25] & 0x80) ? " WC" : "",
+ (bp[25] & 0x40) ? "RP" : "SPT");
+ return;
+ }
+
+ TCHECK2(bp[0], sizeof(struct in_addr));
+ if (vflag > 1)
+ (void)printf("\n");
+ (void)printf(" Upstream Nbr: %s", ipaddr_string(bp));
+ TCHECK2(bp[6], 2);
+ if (vflag > 1)
+ (void)printf("\n");
+ (void)printf(" Hold time: ");
+ relts_print(EXTRACT_16BITS(&bp[6]));
+ if (vflag < 2)
+ return;
+ bp += 8;
+ len -= 8;
+
+ TCHECK2(bp[0], 4);
+ maddrlen = bp[1];
+ addrlen = bp[2];
+ ngroups = bp[3];
+ bp += 4;
+ len -= 4;
+ while (ngroups--) {
+ /*
+ * XXX - does the address have length "addrlen" and the
+ * mask length "maddrlen"?
+ */
+ TCHECK2(bp[0], sizeof(struct in_addr));
+ (void)printf("\n\tGroup: %s", ipaddr_string(bp));
+ TCHECK2(bp[4], sizeof(struct in_addr));
+ if (EXTRACT_32BITS(&bp[4]) != 0xffffffff)
+ (void)printf("/%s", ipaddr_string(&bp[4]));
+ TCHECK2(bp[8], 4);
+ njoin = EXTRACT_16BITS(&bp[8]);
+ nprune = EXTRACT_16BITS(&bp[10]);
+ (void)printf(" joined: %d pruned: %d", njoin, nprune);
+ bp += 12;
+ len -= 12;
+ for (njp = 0; njp < (njoin + nprune); njp++) {
+ const char *type;
+
+ if (njp < njoin)
+ type = "Join ";
+ else
+ type = "Prune";
+ TCHECK2(bp[0], 6);
+ (void)printf("\n\t%s %s%s%s%s/%d", type,
+ (bp[0] & 0x01) ? "Sparse " : "Dense ",
+ (bp[1] & 0x80) ? "WC " : "",
+ (bp[1] & 0x40) ? "RP " : "SPT ",
+ ipaddr_string(&bp[2]), bp[1] & 0x3f);
+ bp += 6;
+ len -= 6;
+ }
+ }
+ return;
+trunc:
+ (void)printf("[|pim]");
+ return;
+}
+
+void
+pimv1_print(register const u_char *bp, register u_int len)
+{
+ register const u_char *ep;
+ register u_char type;
+
+ ep = (const u_char *)snapend;
+ if (bp >= ep)
+ return;
+
+ TCHECK(bp[1]);
+ type = bp[1];
+
+ switch (type) {
+ case 0:
+ (void)printf(" Query");
+ if (TTEST(bp[8])) {
+ switch (bp[8] >> 4) {
+ case 0:
+ (void)printf(" Dense-mode");
+ break;
+ case 1:
+ (void)printf(" Sparse-mode");
+ break;
+ case 2:
+ (void)printf(" Sparse-Dense-mode");
+ break;
+ default:
+ (void)printf(" mode-%d", bp[8] >> 4);
+ break;
+ }
+ }
+ if (vflag) {
+ TCHECK2(bp[10],2);
+ (void)printf(" (Hold-time ");
+ relts_print(EXTRACT_16BITS(&bp[10]));
+ (void)printf(")");
+ }
+ break;
+
+ case 1:
+ (void)printf(" Register");
+ TCHECK2(bp[8], 20); /* ip header */
+ (void)printf(" for %s > %s", ipaddr_string(&bp[20]),
+ ipaddr_string(&bp[24]));
+ break;
+ case 2:
+ (void)printf(" Register-Stop");
+ TCHECK2(bp[12], sizeof(struct in_addr));
+ (void)printf(" for %s > %s", ipaddr_string(&bp[8]),
+ ipaddr_string(&bp[12]));
+ break;
+ case 3:
+ (void)printf(" Join/Prune");
+ if (vflag)
+ pimv1_join_prune_print(&bp[8], len - 8);
+ break;
+ case 4:
+ (void)printf(" RP-reachable");
+ if (vflag) {
+ TCHECK2(bp[22], 2);
+ (void)printf(" group %s",
+ ipaddr_string(&bp[8]));
+ if (EXTRACT_32BITS(&bp[12]) != 0xffffffff)
+ (void)printf("/%s", ipaddr_string(&bp[12]));
+ (void)printf(" RP %s hold ", ipaddr_string(&bp[16]));
+ relts_print(EXTRACT_16BITS(&bp[22]));
+ }
+ break;
+ case 5:
+ (void)printf(" Assert");
+ TCHECK2(bp[16], sizeof(struct in_addr));
+ (void)printf(" for %s > %s", ipaddr_string(&bp[16]),
+ ipaddr_string(&bp[8]));
+ if (EXTRACT_32BITS(&bp[12]) != 0xffffffff)
+ (void)printf("/%s", ipaddr_string(&bp[12]));
+ TCHECK2(bp[24], 4);
+ (void)printf(" %s pref %d metric %d",
+ (bp[20] & 0x80) ? "RP-tree" : "SPT",
+ EXTRACT_32BITS(&bp[20]) & 0x7fffffff,
+ EXTRACT_32BITS(&bp[24]));
+ break;
+ case 6:
+ (void)printf(" Graft");
+ if (vflag)
+ pimv1_join_prune_print(&bp[8], len - 8);
+ break;
+ case 7:
+ (void)printf(" Graft-ACK");
+ if (vflag)
+ pimv1_join_prune_print(&bp[8], len - 8);
+ break;
+ case 8:
+ (void)printf(" Mode");
+ break;
+ default:
+ (void)printf(" [type %d]", type);
+ break;
+ }
+ if ((bp[4] >> 4) != 1)
+ (void)printf(" [v%d]", bp[4] >> 4);
+ return;
+
+trunc:
+ (void)printf("[|pim]");
+ return;
+}
+
+/*
+ * auto-RP is a cisco protocol, documented at
+ * ftp://ftpeng.cisco.com/ipmulticast/specs/pim-autorp-spec01.txt
+ *
+ * This implements version 1+, dated Sept 9, 1998.
+ */
+void
+cisco_autorp_print(register const u_char *bp, register u_int len)
+{
+ int type;
+ int numrps;
+ int hold;
+
+ TCHECK(bp[0]);
+ (void)printf(" auto-rp ");
+ type = bp[0];
+ switch (type) {
+ case 0x11:
+ (void)printf("candidate-advert");
+ break;
+ case 0x12:
+ (void)printf("mapping");
+ break;
+ default:
+ (void)printf("type-0x%02x", type);
+ break;
+ }
+
+ TCHECK(bp[1]);
+ numrps = bp[1];
+
+ TCHECK2(bp[2], 2);
+ (void)printf(" Hold ");
+ hold = EXTRACT_16BITS(&bp[2]);
+ if (hold)
+ relts_print(EXTRACT_16BITS(&bp[2]));
+ else
+ printf("FOREVER");
+
+ /* Next 4 bytes are reserved. */
+
+ bp += 8; len -= 8;
+
+ /*XXX skip unless -v? */
+
+ /*
+ * Rest of packet:
+ * numrps entries of the form:
+ * 32 bits: RP
+ * 6 bits: reserved
+ * 2 bits: PIM version supported, bit 0 is "supports v1", 1 is "v2".
+ * 8 bits: # of entries for this RP
+ * each entry: 7 bits: reserved, 1 bit: negative,
+ * 8 bits: mask 32 bits: source
+ * lather, rinse, repeat.
+ */
+ while (numrps--) {
+ int nentries;
+ char s;
+
+ TCHECK2(bp[0], 4);
+ (void)printf(" RP %s", ipaddr_string(bp));
+ TCHECK(bp[4]);
+ switch (bp[4] & 0x3) {
+ case 0: printf(" PIMv?");
+ break;
+ case 1: printf(" PIMv1");
+ break;
+ case 2: printf(" PIMv2");
+ break;
+ case 3: printf(" PIMv1+2");
+ break;
+ }
+ if (bp[4] & 0xfc)
+ (void)printf(" [rsvd=0x%02x]", bp[4] & 0xfc);
+ TCHECK(bp[5]);
+ nentries = bp[5];
+ bp += 6; len -= 6;
+ s = ' ';
+ for (; nentries; nentries--) {
+ TCHECK2(bp[0], 6);
+ (void)printf("%c%s%s/%d", s, bp[0] & 1 ? "!" : "",
+ ipaddr_string(&bp[2]), bp[1]);
+ if (bp[0] & 0x02) {
+ (void)printf(" bidir");
+ }
+ if (bp[0] & 0xfc) {
+ (void)printf("[rsvd=0x%02x]", bp[0] & 0xfc);
+ }
+ s = ',';
+ bp += 6; len -= 6;
+ }
+ }
+ return;
+
+trunc:
+ (void)printf("[|autorp]");
+ return;
+}
+
+void
+pim_print(register const u_char *bp, register u_int len, u_int cksum)
+{
+ register const u_char *ep;
+ register struct pim *pim = (struct pim *)bp;
+
+ ep = (const u_char *)snapend;
+ if (bp >= ep)
+ return;
+#ifdef notyet /* currently we see only version and type */
+ TCHECK(pim->pim_rsv);
+#endif
+
+ switch (PIM_VER(pim->pim_typever)) {
+ case 2:
+ if (!vflag) {
+ printf("PIMv%u, %s, length %u",
+ PIM_VER(pim->pim_typever),
+ tok2str(pimv2_type_values,"Unknown Type",PIM_TYPE(pim->pim_typever)),
+ len);
+ return;
+ } else {
+ printf("PIMv%u, length %u\n\t%s",
+ PIM_VER(pim->pim_typever),
+ len,
+ tok2str(pimv2_type_values,"Unknown Type",PIM_TYPE(pim->pim_typever)));
+ pimv2_print(bp, len, cksum);
+ }
+ break;
+ default:
+ printf("PIMv%u, length %u",
+ PIM_VER(pim->pim_typever),
+ len);
+ break;
+ }
+ return;
+}
+
+/*
+ * PIMv2 uses encoded address representations.
+ *
+ * The last PIM-SM I-D before RFC2117 was published specified the
+ * following representation for unicast addresses. However, RFC2117
+ * specified no encoding for unicast addresses with the unicast
+ * address length specified in the header. Therefore, we have to
+ * guess which encoding is being used (Cisco's PIMv2 implementation
+ * uses the non-RFC encoding). RFC2117 turns a previously "Reserved"
+ * field into a 'unicast-address-length-in-bytes' field. We guess
+ * that it's the draft encoding if this reserved field is zero.
+ *
+ * RFC2362 goes back to the encoded format, and calls the addr length
+ * field "reserved" again.
+ *
+ * The first byte is the address family, from:
+ *
+ * 0 Reserved
+ * 1 IP (IP version 4)
+ * 2 IP6 (IP version 6)
+ * 3 NSAP
+ * 4 HDLC (8-bit multidrop)
+ * 5 BBN 1822
+ * 6 802 (includes all 802 media plus Ethernet "canonical format")
+ * 7 E.163
+ * 8 E.164 (SMDS, Frame Relay, ATM)
+ * 9 F.69 (Telex)
+ * 10 X.121 (X.25, Frame Relay)
+ * 11 IPX
+ * 12 Appletalk
+ * 13 Decnet IV
+ * 14 Banyan Vines
+ * 15 E.164 with NSAP format subaddress
+ *
+ * In addition, the second byte is an "Encoding". 0 is the default
+ * encoding for the address family, and no other encodings are currently
+ * specified.
+ *
+ */
+
+static int pimv2_addr_len;
+
+enum pimv2_addrtype {
+ pimv2_unicast, pimv2_group, pimv2_source
+};
+
+/* 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Addr Family | Encoding Type | Unicast Address |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+++++++
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Addr Family | Encoding Type | Reserved | Mask Len |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Group multicast Address |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Addr Family | Encoding Type | Rsrvd |S|W|R| Mask Len |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Source Address |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+static int
+pimv2_addr_print(const u_char *bp, enum pimv2_addrtype at, int silent)
+{
+ int af;
+ int len, hdrlen;
+
+ TCHECK(bp[0]);
+
+ if (pimv2_addr_len == 0) {
+ TCHECK(bp[1]);
+ switch (bp[0]) {
+ case 1:
+ af = AF_INET;
+ len = sizeof(struct in_addr);
+ break;
+#ifdef INET6
+ case 2:
+ af = AF_INET6;
+ len = sizeof(struct in6_addr);
+ break;
+#endif
+ default:
+ return -1;
+ }
+ if (bp[1] != 0)
+ return -1;
+ hdrlen = 2;
+ } else {
+ switch (pimv2_addr_len) {
+ case sizeof(struct in_addr):
+ af = AF_INET;
+ break;
+#ifdef INET6
+ case sizeof(struct in6_addr):
+ af = AF_INET6;
+ break;
+#endif
+ default:
+ return -1;
+ break;
+ }
+ len = pimv2_addr_len;
+ hdrlen = 0;
+ }
+
+ bp += hdrlen;
+ switch (at) {
+ case pimv2_unicast:
+ TCHECK2(bp[0], len);
+ if (af == AF_INET) {
+ if (!silent)
+ (void)printf("%s", ipaddr_string(bp));
+ }
+#ifdef INET6
+ else if (af == AF_INET6) {
+ if (!silent)
+ (void)printf("%s", ip6addr_string(bp));
+ }
+#endif
+ return hdrlen + len;
+ case pimv2_group:
+ case pimv2_source:
+ TCHECK2(bp[0], len + 2);
+ if (af == AF_INET) {
+ if (!silent) {
+ (void)printf("%s", ipaddr_string(bp + 2));
+ if (bp[1] != 32)
+ (void)printf("/%u", bp[1]);
+ }
+ }
+#ifdef INET6
+ else if (af == AF_INET6) {
+ if (!silent) {
+ (void)printf("%s", ip6addr_string(bp + 2));
+ if (bp[1] != 128)
+ (void)printf("/%u", bp[1]);
+ }
+ }
+#endif
+ if (bp[0] && !silent) {
+ if (at == pimv2_group) {
+ (void)printf("(0x%02x)", bp[0]);
+ } else {
+ (void)printf("(%s%s%s",
+ bp[0] & 0x04 ? "S" : "",
+ bp[0] & 0x02 ? "W" : "",
+ bp[0] & 0x01 ? "R" : "");
+ if (bp[0] & 0xf8) {
+ (void) printf("+0x%02x", bp[0] & 0xf8);
+ }
+ (void)printf(")");
+ }
+ }
+ return hdrlen + 2 + len;
+ default:
+ return -1;
+ }
+trunc:
+ return -1;
+}
+
+static void
+pimv2_print(register const u_char *bp, register u_int len, u_int cksum)
+{
+ register const u_char *ep;
+ register struct pim *pim = (struct pim *)bp;
+ int advance;
+
+ ep = (const u_char *)snapend;
+ if (bp >= ep)
+ return;
+ if (ep > bp + len)
+ ep = bp + len;
+ TCHECK(pim->pim_rsv);
+ pimv2_addr_len = pim->pim_rsv;
+ if (pimv2_addr_len != 0)
+ (void)printf(", RFC2117-encoding");
+
+ printf(", cksum 0x%04x ", EXTRACT_16BITS(&pim->pim_cksum));
+ if (EXTRACT_16BITS(&pim->pim_cksum) == 0) {
+ printf("(unverified)");
+ } else {
+ printf("(%scorrect)", TTEST2(bp[0], len) && cksum ? "in" : "" );
+ }
+
+ switch (PIM_TYPE(pim->pim_typever)) {
+ case PIMV2_TYPE_HELLO:
+ {
+ u_int16_t otype, olen;
+ bp += 4;
+ while (bp < ep) {
+ TCHECK2(bp[0], 4);
+ otype = EXTRACT_16BITS(&bp[0]);
+ olen = EXTRACT_16BITS(&bp[2]);
+ TCHECK2(bp[0], 4 + olen);
+
+ printf("\n\t %s Option (%u), length %u, Value: ",
+ tok2str( pimv2_hello_option_values,"Unknown",otype),
+ otype,
+ olen);
+ bp += 4;
+
+ switch (otype) {
+ case PIMV2_HELLO_OPTION_HOLDTIME:
+ relts_print(EXTRACT_16BITS(bp));
+ break;
+
+ case PIMV2_HELLO_OPTION_LANPRUNEDELAY:
+ if (olen != 4) {
+ (void)printf("ERROR: Option Length != 4 Bytes (%u)", olen);
+ } else {
+ char t_bit;
+ u_int16_t lan_delay, override_interval;
+ lan_delay = EXTRACT_16BITS(bp);
+ override_interval = EXTRACT_16BITS(bp+2);
+ t_bit = (lan_delay & 0x8000)? 1 : 0;
+ lan_delay &= ~0x8000;
+ (void)printf("\n\t T-bit=%d, LAN delay %dms, Override interval %dms",
+ t_bit, lan_delay, override_interval);
+ }
+ break;
+
+ case PIMV2_HELLO_OPTION_DR_PRIORITY_OLD:
+ case PIMV2_HELLO_OPTION_DR_PRIORITY:
+ switch (olen) {
+ case 0:
+ printf("Bi-Directional Capability (Old)");
+ break;
+ case 4:
+ printf("%u", EXTRACT_32BITS(bp));
+ break;
+ default:
+ printf("ERROR: Option Length != 4 Bytes (%u)", olen);
+ break;
+ }
+ break;
+
+ case PIMV2_HELLO_OPTION_GENID:
+ (void)printf("0x%08x", EXTRACT_32BITS(bp));
+ break;
+
+ case PIMV2_HELLO_OPTION_REFRESH_CAP:
+ (void)printf("v%d", *bp);
+ if (*(bp+1) != 0) {
+ (void)printf(", interval ");
+ relts_print(*(bp+1));
+ }
+ if (EXTRACT_16BITS(bp+2) != 0) {
+ (void)printf(" ?0x%04x?", EXTRACT_16BITS(bp+2));
+ }
+ break;
+
+ case PIMV2_HELLO_OPTION_BIDIR_CAP:
+ break;
+
+ case PIMV2_HELLO_OPTION_ADDRESS_LIST_OLD:
+ case PIMV2_HELLO_OPTION_ADDRESS_LIST:
+ if (vflag > 1) {
+ const u_char *ptr = bp;
+ while (ptr < (bp+olen)) {
+ int advance;
+
+ printf("\n\t ");
+ advance = pimv2_addr_print(ptr, pimv2_unicast, 0);
+ if (advance < 0) {
+ printf("...");
+ break;
+ }
+ ptr += advance;
+ }
+ }
+ break;
+ default:
+ if (vflag <= 1)
+ print_unknown_data(bp,"\n\t ",olen);
+ break;
+ }
+ /* do we want to see an additionally hexdump ? */
+ if (vflag> 1)
+ print_unknown_data(bp,"\n\t ",olen);
+ bp += olen;
+ }
+ break;
+ }
+
+ case PIMV2_TYPE_REGISTER:
+ {
+ struct ip *ip;
+
+ if (!TTEST2(*(bp+4), PIMV2_REGISTER_FLAG_LEN))
+ goto trunc;
+
+ printf(", Flags [ %s ]\n\t",
+ tok2str(pimv2_register_flag_values,
+ "none",
+ EXTRACT_32BITS(bp+4)));
+
+ bp += 8; len -= 8;
+ /* encapsulated multicast packet */
+ ip = (struct ip *)bp;
+ switch (IP_V(ip)) {
+ case 0: /* Null header */
+ (void)printf("IP-Null-header %s > %s",
+ ipaddr_string(&ip->ip_src),
+ ipaddr_string(&ip->ip_dst));
+ break;
+
+ case 4: /* IPv4 */
+ ip_print(gndo, bp, len);
+ break;
+#ifdef INET6
+ case 6: /* IPv6 */
+ ip6_print(gndo, bp, len);
+ break;
+#endif
+ default:
+ (void)printf("IP ver %d", IP_V(ip));
+ break;
+ }
+ break;
+ }
+
+ case PIMV2_TYPE_REGISTER_STOP:
+ bp += 4; len -= 4;
+ if (bp >= ep)
+ break;
+ (void)printf(" group=");
+ if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) {
+ (void)printf("...");
+ break;
+ }
+ bp += advance; len -= advance;
+ if (bp >= ep)
+ break;
+ (void)printf(" source=");
+ if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) {
+ (void)printf("...");
+ break;
+ }
+ bp += advance; len -= advance;
+ break;
+
+ case PIMV2_TYPE_JOIN_PRUNE:
+ case PIMV2_TYPE_GRAFT:
+ case PIMV2_TYPE_GRAFT_ACK:
+
+
+ /*
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |PIM Ver| Type | Addr length | Checksum |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Unicast-Upstream Neighbor Address |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Reserved | Num groups | Holdtime |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Encoded-Multicast Group Address-1 |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Number of Joined Sources | Number of Pruned Sources |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Encoded-Joined Source Address-1 |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | . |
+ * | . |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Encoded-Joined Source Address-n |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Encoded-Pruned Source Address-1 |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | . |
+ * | . |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Encoded-Pruned Source Address-n |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | . |
+ * | . |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Encoded-Multicast Group Address-n |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+ {
+ u_int8_t ngroup;
+ u_int16_t holdtime;
+ u_int16_t njoin;
+ u_int16_t nprune;
+ int i, j;
+
+ bp += 4; len -= 4;
+ if (PIM_TYPE(pim->pim_typever) != 7) { /*not for Graft-ACK*/
+ if (bp >= ep)
+ break;
+ (void)printf(", upstream-neighbor: ");
+ if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) {
+ (void)printf("...");
+ break;
+ }
+ bp += advance; len -= advance;
+ }
+ if (bp + 4 > ep)
+ break;
+ ngroup = bp[1];
+ holdtime = EXTRACT_16BITS(&bp[2]);
+ (void)printf("\n\t %u group(s)", ngroup);
+ if (PIM_TYPE(pim->pim_typever) != 7) { /*not for Graft-ACK*/
+ (void)printf(", holdtime: ");
+ if (holdtime == 0xffff)
+ (void)printf("infinite");
+ else
+ relts_print(holdtime);
+ }
+ bp += 4; len -= 4;
+ for (i = 0; i < ngroup; i++) {
+ if (bp >= ep)
+ goto jp_done;
+ (void)printf("\n\t group #%u: ", i+1);
+ if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) {
+ (void)printf("...)");
+ goto jp_done;
+ }
+ bp += advance; len -= advance;
+ if (bp + 4 > ep) {
+ (void)printf("...)");
+ goto jp_done;
+ }
+ njoin = EXTRACT_16BITS(&bp[0]);
+ nprune = EXTRACT_16BITS(&bp[2]);
+ (void)printf(", joined sources: %u, pruned sources: %u", njoin,nprune);
+ bp += 4; len -= 4;
+ for (j = 0; j < njoin; j++) {
+ (void)printf("\n\t joined source #%u: ",j+1);
+ if ((advance = pimv2_addr_print(bp, pimv2_source, 0)) < 0) {
+ (void)printf("...)");
+ goto jp_done;
+ }
+ bp += advance; len -= advance;
+ }
+ for (j = 0; j < nprune; j++) {
+ (void)printf("\n\t pruned source #%u: ",j+1);
+ if ((advance = pimv2_addr_print(bp, pimv2_source, 0)) < 0) {
+ (void)printf("...)");
+ goto jp_done;
+ }
+ bp += advance; len -= advance;
+ }
+ }
+ jp_done:
+ break;
+ }
+
+ case PIMV2_TYPE_BOOTSTRAP:
+ {
+ int i, j, frpcnt;
+ bp += 4;
+
+ /* Fragment Tag, Hash Mask len, and BSR-priority */
+ if (bp + sizeof(u_int16_t) >= ep) break;
+ (void)printf(" tag=%x", EXTRACT_16BITS(bp));
+ bp += sizeof(u_int16_t);
+ if (bp >= ep) break;
+ (void)printf(" hashmlen=%d", bp[0]);
+ if (bp + 1 >= ep) break;
+ (void)printf(" BSRprio=%d", bp[1]);
+ bp += 2;
+
+ /* Encoded-Unicast-BSR-Address */
+ if (bp >= ep) break;
+ (void)printf(" BSR=");
+ if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) {
+ (void)printf("...");
+ break;
+ }
+ bp += advance;
+
+ for (i = 0; bp < ep; i++) {
+ /* Encoded-Group Address */
+ (void)printf(" (group%d: ", i);
+ if ((advance = pimv2_addr_print(bp, pimv2_group, 0))
+ < 0) {
+ (void)printf("...)");
+ goto bs_done;
+ }
+ bp += advance;
+
+ /* RP-Count, Frag RP-Cnt, and rsvd */
+ if (bp >= ep) {
+ (void)printf("...)");
+ goto bs_done;
+ }
+ (void)printf(" RPcnt=%d", bp[0]);
+ if (bp + 1 >= ep) {
+ (void)printf("...)");
+ goto bs_done;
+ }
+ (void)printf(" FRPcnt=%d", frpcnt = bp[1]);
+ bp += 4;
+
+ for (j = 0; j < frpcnt && bp < ep; j++) {
+ /* each RP info */
+ (void)printf(" RP%d=", j);
+ if ((advance = pimv2_addr_print(bp,
+ pimv2_unicast,
+ 0)) < 0) {
+ (void)printf("...)");
+ goto bs_done;
+ }
+ bp += advance;
+
+ if (bp + 1 >= ep) {
+ (void)printf("...)");
+ goto bs_done;
+ }
+ (void)printf(",holdtime=");
+ relts_print(EXTRACT_16BITS(bp));
+ if (bp + 2 >= ep) {
+ (void)printf("...)");
+ goto bs_done;
+ }
+ (void)printf(",prio=%d", bp[2]);
+ bp += 4;
+ }
+ (void)printf(")");
+ }
+ bs_done:
+ break;
+ }
+ case PIMV2_TYPE_ASSERT:
+ bp += 4; len -= 4;
+ if (bp >= ep)
+ break;
+ (void)printf(" group=");
+ if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) {
+ (void)printf("...");
+ break;
+ }
+ bp += advance; len -= advance;
+ if (bp >= ep)
+ break;
+ (void)printf(" src=");
+ if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) {
+ (void)printf("...");
+ break;
+ }
+ bp += advance; len -= advance;
+ if (bp + 8 > ep)
+ break;
+ if (bp[0] & 0x80)
+ (void)printf(" RPT");
+ (void)printf(" pref=%u", EXTRACT_32BITS(&bp[0]) & 0x7fffffff);
+ (void)printf(" metric=%u", EXTRACT_32BITS(&bp[4]));
+ break;
+
+ case PIMV2_TYPE_CANDIDATE_RP:
+ {
+ int i, pfxcnt;
+ bp += 4;
+
+ /* Prefix-Cnt, Priority, and Holdtime */
+ if (bp >= ep) break;
+ (void)printf(" prefix-cnt=%d", bp[0]);
+ pfxcnt = bp[0];
+ if (bp + 1 >= ep) break;
+ (void)printf(" prio=%d", bp[1]);
+ if (bp + 3 >= ep) break;
+ (void)printf(" holdtime=");
+ relts_print(EXTRACT_16BITS(&bp[2]));
+ bp += 4;
+
+ /* Encoded-Unicast-RP-Address */
+ if (bp >= ep) break;
+ (void)printf(" RP=");
+ if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) {
+ (void)printf("...");
+ break;
+ }
+ bp += advance;
+
+ /* Encoded-Group Addresses */
+ for (i = 0; i < pfxcnt && bp < ep; i++) {
+ (void)printf(" Group%d=", i);
+ if ((advance = pimv2_addr_print(bp, pimv2_group, 0))
+ < 0) {
+ (void)printf("...");
+ break;
+ }
+ bp += advance;
+ }
+ break;
+ }
+
+ case PIMV2_TYPE_PRUNE_REFRESH:
+ (void)printf(" src=");
+ if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) {
+ (void)printf("...");
+ break;
+ }
+ bp += advance;
+ (void)printf(" grp=");
+ if ((advance = pimv2_addr_print(bp, pimv2_group, 0)) < 0) {
+ (void)printf("...");
+ break;
+ }
+ bp += advance;
+ (void)printf(" forwarder=");
+ if ((advance = pimv2_addr_print(bp, pimv2_unicast, 0)) < 0) {
+ (void)printf("...");
+ break;
+ }
+ bp += advance;
+ TCHECK2(bp[0], 2);
+ (void)printf(" TUNR ");
+ relts_print(EXTRACT_16BITS(bp));
+ break;
+
+
+ default:
+ (void)printf(" [type %d]", PIM_TYPE(pim->pim_typever));
+ break;
+ }
+
+ return;
+
+trunc:
+ (void)printf("[|pim]");
+}
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-ppi.c b/freebsd/contrib/tcpdump/print-ppi.c
new file mode 100644
index 00000000..b78d8730
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-ppi.c
@@ -0,0 +1,106 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Oracle
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <pcap.h>
+
+#include "netdissect.h"
+#include "interface.h"
+#include "extract.h"
+#include "ppi.h"
+
+#ifdef DLT_PPI
+
+static inline void
+ppi_header_print(struct netdissect_options *ndo, const u_char *bp, u_int length)
+{
+ const ppi_header_t *hdr;
+ u_int32_t dlt;
+ u_int16_t len;
+
+ hdr = (const ppi_header_t *)bp;
+
+ len = EXTRACT_16BITS(&hdr->ppi_len);
+ dlt = EXTRACT_32BITS(&hdr->ppi_dlt);
+
+ if (!ndo->ndo_qflag) {
+ ND_PRINT((ndo,", V.%d DLT %s (%d) len %d", hdr->ppi_ver,
+ pcap_datalink_val_to_name(dlt), dlt,
+ len));
+ } else {
+ ND_PRINT((ndo,", %s", pcap_datalink_val_to_name(dlt)));
+ }
+
+ ND_PRINT((ndo, ", length %u: ", length));
+}
+
+static void
+ppi_print(struct netdissect_options *ndo,
+ const struct pcap_pkthdr *h, const u_char *p)
+{
+ if_ndo_printer ndo_printer;
+ if_printer printer;
+ ppi_header_t *hdr;
+ u_int caplen = h->caplen;
+ u_int length = h->len;
+ u_int32_t dlt;
+
+ if (caplen < sizeof(ppi_header_t)) {
+ ND_PRINT((ndo, "[|ppi]"));
+ return;
+ }
+ hdr = (ppi_header_t *)p;
+ dlt = EXTRACT_32BITS(&hdr->ppi_dlt);
+
+ if (ndo->ndo_eflag)
+ ppi_header_print(ndo, p, length);
+
+ length -= sizeof(ppi_header_t);
+ caplen -= sizeof(ppi_header_t);
+ p += sizeof(ppi_header_t);
+
+ if ((printer = lookup_printer(dlt)) != NULL) {
+ printer(h, p);
+ } else if ((ndo_printer = lookup_ndo_printer(dlt)) != NULL) {
+ ndo_printer(ndo, h, p);
+ } else {
+ if (!ndo->ndo_eflag)
+ ppi_header_print(ndo, (u_char *)hdr,
+ length + sizeof(ppi_header_t));
+
+ if (!ndo->ndo_suppress_default_print)
+ ndo->ndo_default_print(ndo, p, caplen);
+ }
+}
+
+/*
+ * This is the top level routine of the printer. 'p' points
+ * to the ether header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ */
+u_int
+ppi_if_print(struct netdissect_options *ndo,
+ const struct pcap_pkthdr *h, const u_char *p)
+{
+ ppi_print(ndo, h, p);
+
+ return (sizeof(ppi_header_t));
+}
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */
+
+#endif /* DLT_PPI */
diff --git a/freebsd/contrib/tcpdump/print-ppp.c b/freebsd/contrib/tcpdump/print-ppp.c
new file mode 100644
index 00000000..23eb21a2
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-ppp.c
@@ -0,0 +1,1761 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Extensively modified by Motonori Shindo (mshindo@mshindo.net) for more
+ * complete PPP support.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * TODO:
+ * o resolve XXX as much as possible
+ * o MP support
+ * o BAP support
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ppp.c,v 1.114 2005-12-05 11:35:58 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#ifdef __bsdi__
+#include <net/slcompress.h>
+#include <net/if_ppp.h>
+#endif
+
+#include <pcap.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+#include "ppp.h"
+#include "chdlc.h"
+#include "ethertype.h"
+#include "oui.h"
+
+/*
+ * The following constatns are defined by IANA. Please refer to
+ * http://www.isi.edu/in-notes/iana/assignments/ppp-numbers
+ * for the up-to-date information.
+ */
+
+/* Protocol Codes defined in ppp.h */
+
+struct tok ppptype2str[] = {
+ { PPP_IP, "IP" },
+ { PPP_OSI, "OSI" },
+ { PPP_NS, "NS" },
+ { PPP_DECNET, "DECNET" },
+ { PPP_APPLE, "APPLE" },
+ { PPP_IPX, "IPX" },
+ { PPP_VJC, "VJC IP" },
+ { PPP_VJNC, "VJNC IP" },
+ { PPP_BRPDU, "BRPDU" },
+ { PPP_STII, "STII" },
+ { PPP_VINES, "VINES" },
+ { PPP_MPLS_UCAST, "MPLS" },
+ { PPP_MPLS_MCAST, "MPLS" },
+ { PPP_COMP, "Compressed"},
+ { PPP_ML, "MLPPP"},
+ { PPP_IPV6, "IP6"},
+
+ { PPP_HELLO, "HELLO" },
+ { PPP_LUXCOM, "LUXCOM" },
+ { PPP_SNS, "SNS" },
+ { PPP_IPCP, "IPCP" },
+ { PPP_OSICP, "OSICP" },
+ { PPP_NSCP, "NSCP" },
+ { PPP_DECNETCP, "DECNETCP" },
+ { PPP_APPLECP, "APPLECP" },
+ { PPP_IPXCP, "IPXCP" },
+ { PPP_STIICP, "STIICP" },
+ { PPP_VINESCP, "VINESCP" },
+ { PPP_IPV6CP, "IP6CP" },
+ { PPP_MPLSCP, "MPLSCP" },
+
+ { PPP_LCP, "LCP" },
+ { PPP_PAP, "PAP" },
+ { PPP_LQM, "LQM" },
+ { PPP_CHAP, "CHAP" },
+ { PPP_EAP, "EAP" },
+ { PPP_SPAP, "SPAP" },
+ { PPP_SPAP_OLD, "Old-SPAP" },
+ { PPP_BACP, "BACP" },
+ { PPP_BAP, "BAP" },
+ { PPP_MPCP, "MLPPP-CP" },
+ { 0, NULL }
+};
+
+/* Control Protocols (LCP/IPCP/CCP etc.) Codes defined in RFC 1661 */
+
+#define CPCODES_VEXT 0 /* Vendor-Specific (RFC2153) */
+#define CPCODES_CONF_REQ 1 /* Configure-Request */
+#define CPCODES_CONF_ACK 2 /* Configure-Ack */
+#define CPCODES_CONF_NAK 3 /* Configure-Nak */
+#define CPCODES_CONF_REJ 4 /* Configure-Reject */
+#define CPCODES_TERM_REQ 5 /* Terminate-Request */
+#define CPCODES_TERM_ACK 6 /* Terminate-Ack */
+#define CPCODES_CODE_REJ 7 /* Code-Reject */
+#define CPCODES_PROT_REJ 8 /* Protocol-Reject (LCP only) */
+#define CPCODES_ECHO_REQ 9 /* Echo-Request (LCP only) */
+#define CPCODES_ECHO_RPL 10 /* Echo-Reply (LCP only) */
+#define CPCODES_DISC_REQ 11 /* Discard-Request (LCP only) */
+#define CPCODES_ID 12 /* Identification (LCP only) RFC1570 */
+#define CPCODES_TIME_REM 13 /* Time-Remaining (LCP only) RFC1570 */
+#define CPCODES_RESET_REQ 14 /* Reset-Request (CCP only) RFC1962 */
+#define CPCODES_RESET_REP 15 /* Reset-Reply (CCP only) */
+
+struct tok cpcodes[] = {
+ {CPCODES_VEXT, "Vendor-Extension"}, /* RFC2153 */
+ {CPCODES_CONF_REQ, "Conf-Request"},
+ {CPCODES_CONF_ACK, "Conf-Ack"},
+ {CPCODES_CONF_NAK, "Conf-Nack"},
+ {CPCODES_CONF_REJ, "Conf-Reject"},
+ {CPCODES_TERM_REQ, "Term-Request"},
+ {CPCODES_TERM_ACK, "Term-Ack"},
+ {CPCODES_CODE_REJ, "Code-Reject"},
+ {CPCODES_PROT_REJ, "Prot-Reject"},
+ {CPCODES_ECHO_REQ, "Echo-Request"},
+ {CPCODES_ECHO_RPL, "Echo-Reply"},
+ {CPCODES_DISC_REQ, "Disc-Req"},
+ {CPCODES_ID, "Ident"}, /* RFC1570 */
+ {CPCODES_TIME_REM, "Time-Rem"}, /* RFC1570 */
+ {CPCODES_RESET_REQ, "Reset-Req"}, /* RFC1962 */
+ {CPCODES_RESET_REP, "Reset-Ack"}, /* RFC1962 */
+ {0, NULL}
+};
+
+/* LCP Config Options */
+
+#define LCPOPT_VEXT 0
+#define LCPOPT_MRU 1
+#define LCPOPT_ACCM 2
+#define LCPOPT_AP 3
+#define LCPOPT_QP 4
+#define LCPOPT_MN 5
+#define LCPOPT_DEP6 6
+#define LCPOPT_PFC 7
+#define LCPOPT_ACFC 8
+#define LCPOPT_FCSALT 9
+#define LCPOPT_SDP 10
+#define LCPOPT_NUMMODE 11
+#define LCPOPT_DEP12 12
+#define LCPOPT_CBACK 13
+#define LCPOPT_DEP14 14
+#define LCPOPT_DEP15 15
+#define LCPOPT_DEP16 16
+#define LCPOPT_MLMRRU 17
+#define LCPOPT_MLSSNHF 18
+#define LCPOPT_MLED 19
+#define LCPOPT_PROP 20
+#define LCPOPT_DCEID 21
+#define LCPOPT_MPP 22
+#define LCPOPT_LD 23
+#define LCPOPT_LCPAOPT 24
+#define LCPOPT_COBS 25
+#define LCPOPT_PE 26
+#define LCPOPT_MLHF 27
+#define LCPOPT_I18N 28
+#define LCPOPT_SDLOS 29
+#define LCPOPT_PPPMUX 30
+
+#define LCPOPT_MIN LCPOPT_VEXT
+#define LCPOPT_MAX LCPOPT_PPPMUX
+
+static const char *lcpconfopts[] = {
+ "Vend-Ext", /* (0) */
+ "MRU", /* (1) */
+ "ACCM", /* (2) */
+ "Auth-Prot", /* (3) */
+ "Qual-Prot", /* (4) */
+ "Magic-Num", /* (5) */
+ "deprecated(6)", /* used to be a Quality Protocol */
+ "PFC", /* (7) */
+ "ACFC", /* (8) */
+ "FCS-Alt", /* (9) */
+ "SDP", /* (10) */
+ "Num-Mode", /* (11) */
+ "deprecated(12)", /* used to be a Multi-Link-Procedure*/
+ "Call-Back", /* (13) */
+ "deprecated(14)", /* used to be a Connect-Time */
+ "deprecated(15)", /* used to be a Compund-Frames */
+ "deprecated(16)", /* used to be a Nominal-Data-Encap */
+ "MRRU", /* (17) */
+ "12-Bit seq #", /* (18) */
+ "End-Disc", /* (19) */
+ "Proprietary", /* (20) */
+ "DCE-Id", /* (21) */
+ "MP+", /* (22) */
+ "Link-Disc", /* (23) */
+ "LCP-Auth-Opt", /* (24) */
+ "COBS", /* (25) */
+ "Prefix-elision", /* (26) */
+ "Multilink-header-Form",/* (27) */
+ "I18N", /* (28) */
+ "SDL-over-SONET/SDH", /* (29) */
+ "PPP-Muxing", /* (30) */
+};
+
+/* ECP - to be supported */
+
+/* CCP Config Options */
+
+#define CCPOPT_OUI 0 /* RFC1962 */
+#define CCPOPT_PRED1 1 /* RFC1962 */
+#define CCPOPT_PRED2 2 /* RFC1962 */
+#define CCPOPT_PJUMP 3 /* RFC1962 */
+/* 4-15 unassigned */
+#define CCPOPT_HPPPC 16 /* RFC1962 */
+#define CCPOPT_STACLZS 17 /* RFC1974 */
+#define CCPOPT_MPPC 18 /* RFC2118 */
+#define CCPOPT_GFZA 19 /* RFC1962 */
+#define CCPOPT_V42BIS 20 /* RFC1962 */
+#define CCPOPT_BSDCOMP 21 /* RFC1977 */
+/* 22 unassigned */
+#define CCPOPT_LZSDCP 23 /* RFC1967 */
+#define CCPOPT_MVRCA 24 /* RFC1975 */
+#define CCPOPT_DEC 25 /* RFC1976 */
+#define CCPOPT_DEFLATE 26 /* RFC1979 */
+/* 27-254 unassigned */
+#define CCPOPT_RESV 255 /* RFC1962 */
+
+const struct tok ccpconfopts_values[] = {
+ { CCPOPT_OUI, "OUI" },
+ { CCPOPT_PRED1, "Pred-1" },
+ { CCPOPT_PRED2, "Pred-2" },
+ { CCPOPT_PJUMP, "Puddle" },
+ { CCPOPT_HPPPC, "HP-PPC" },
+ { CCPOPT_STACLZS, "Stac-LZS" },
+ { CCPOPT_MPPC, "MPPC" },
+ { CCPOPT_GFZA, "Gand-FZA" },
+ { CCPOPT_V42BIS, "V.42bis" },
+ { CCPOPT_BSDCOMP, "BSD-Comp" },
+ { CCPOPT_LZSDCP, "LZS-DCP" },
+ { CCPOPT_MVRCA, "MVRCA" },
+ { CCPOPT_DEC, "DEC" },
+ { CCPOPT_DEFLATE, "Deflate" },
+ { CCPOPT_RESV, "Reserved"},
+ {0, NULL}
+};
+
+/* BACP Config Options */
+
+#define BACPOPT_FPEER 1 /* RFC2125 */
+
+const struct tok bacconfopts_values[] = {
+ { BACPOPT_FPEER, "Favored-Peer" },
+ {0, NULL}
+};
+
+
+/* SDCP - to be supported */
+
+/* IPCP Config Options */
+#define IPCPOPT_2ADDR 1 /* RFC1172, RFC1332 (deprecated) */
+#define IPCPOPT_IPCOMP 2 /* RFC1332 */
+#define IPCPOPT_ADDR 3 /* RFC1332 */
+#define IPCPOPT_MOBILE4 4 /* RFC2290 */
+#define IPCPOPT_PRIDNS 129 /* RFC1877 */
+#define IPCPOPT_PRINBNS 130 /* RFC1877 */
+#define IPCPOPT_SECDNS 131 /* RFC1877 */
+#define IPCPOPT_SECNBNS 132 /* RFC1877 */
+
+struct tok ipcpopt_values[] = {
+ { IPCPOPT_2ADDR, "IP-Addrs" },
+ { IPCPOPT_IPCOMP, "IP-Comp" },
+ { IPCPOPT_ADDR, "IP-Addr" },
+ { IPCPOPT_MOBILE4, "Home-Addr" },
+ { IPCPOPT_PRIDNS, "Pri-DNS" },
+ { IPCPOPT_PRINBNS, "Pri-NBNS" },
+ { IPCPOPT_SECDNS, "Sec-DNS" },
+ { IPCPOPT_SECNBNS, "Sec-NBNS" },
+ { 0, NULL }
+};
+
+#define IPCPOPT_IPCOMP_HDRCOMP 0x61 /* rfc3544 */
+#define IPCPOPT_IPCOMP_MINLEN 14
+
+struct tok ipcpopt_compproto_values[] = {
+ { PPP_VJC, "VJ-Comp" },
+ { IPCPOPT_IPCOMP_HDRCOMP, "IP Header Compression" },
+ { 0, NULL }
+};
+
+struct tok ipcpopt_compproto_subopt_values[] = {
+ { 1, "RTP-Compression" },
+ { 2, "Enhanced RTP-Compression" },
+ { 0, NULL }
+};
+
+/* IP6CP Config Options */
+#define IP6CP_IFID 1
+
+struct tok ip6cpopt_values[] = {
+ { IP6CP_IFID, "Interface-ID" },
+ { 0, NULL }
+};
+
+/* ATCP - to be supported */
+/* OSINLCP - to be supported */
+/* BVCP - to be supported */
+/* BCP - to be supported */
+/* IPXCP - to be supported */
+/* MPLSCP - to be supported */
+
+/* Auth Algorithms */
+
+/* 0-4 Reserved (RFC1994) */
+#define AUTHALG_CHAPMD5 5 /* RFC1994 */
+#define AUTHALG_MSCHAP1 128 /* RFC2433 */
+#define AUTHALG_MSCHAP2 129 /* RFC2795 */
+
+struct tok authalg_values[] = {
+ { AUTHALG_CHAPMD5, "MD5" },
+ { AUTHALG_MSCHAP1, "MS-CHAPv1" },
+ { AUTHALG_MSCHAP2, "MS-CHAPv2" },
+ { 0, NULL }
+};
+
+/* FCS Alternatives - to be supported */
+
+/* Multilink Endpoint Discriminator (RFC1717) */
+#define MEDCLASS_NULL 0 /* Null Class */
+#define MEDCLASS_LOCAL 1 /* Locally Assigned */
+#define MEDCLASS_IPV4 2 /* Internet Protocol (IPv4) */
+#define MEDCLASS_MAC 3 /* IEEE 802.1 global MAC address */
+#define MEDCLASS_MNB 4 /* PPP Magic Number Block */
+#define MEDCLASS_PSNDN 5 /* Public Switched Network Director Number */
+
+/* PPP LCP Callback */
+#define CALLBACK_AUTH 0 /* Location determined by user auth */
+#define CALLBACK_DSTR 1 /* Dialing string */
+#define CALLBACK_LID 2 /* Location identifier */
+#define CALLBACK_E164 3 /* E.164 number */
+#define CALLBACK_X500 4 /* X.500 distinguished name */
+#define CALLBACK_CBCP 6 /* Location is determined during CBCP nego */
+
+struct tok ppp_callback_values[] = {
+ { CALLBACK_AUTH, "UserAuth" },
+ { CALLBACK_DSTR, "DialString" },
+ { CALLBACK_LID, "LocalID" },
+ { CALLBACK_E164, "E.164" },
+ { CALLBACK_X500, "X.500" },
+ { CALLBACK_CBCP, "CBCP" },
+ { 0, NULL }
+};
+
+/* CHAP */
+
+#define CHAP_CHAL 1
+#define CHAP_RESP 2
+#define CHAP_SUCC 3
+#define CHAP_FAIL 4
+
+struct tok chapcode_values[] = {
+ { CHAP_CHAL, "Challenge" },
+ { CHAP_RESP, "Response" },
+ { CHAP_SUCC, "Success" },
+ { CHAP_FAIL, "Fail" },
+ { 0, NULL}
+};
+
+/* PAP */
+
+#define PAP_AREQ 1
+#define PAP_AACK 2
+#define PAP_ANAK 3
+
+struct tok papcode_values[] = {
+ { PAP_AREQ, "Auth-Req" },
+ { PAP_AACK, "Auth-ACK" },
+ { PAP_ANAK, "Auth-NACK" },
+ { 0, NULL }
+};
+
+/* BAP */
+#define BAP_CALLREQ 1
+#define BAP_CALLRES 2
+#define BAP_CBREQ 3
+#define BAP_CBRES 4
+#define BAP_LDQREQ 5
+#define BAP_LDQRES 6
+#define BAP_CSIND 7
+#define BAP_CSRES 8
+
+static void handle_ctrl_proto (u_int proto,const u_char *p, int length);
+static void handle_chap (const u_char *p, int length);
+static void handle_pap (const u_char *p, int length);
+static void handle_bap (const u_char *p, int length);
+static void handle_mlppp(const u_char *p, int length);
+static int print_lcp_config_options (const u_char *p, int);
+static int print_ipcp_config_options (const u_char *p, int);
+static int print_ip6cp_config_options (const u_char *p, int);
+static int print_ccp_config_options (const u_char *p, int);
+static int print_bacp_config_options (const u_char *p, int);
+static void handle_ppp (u_int proto, const u_char *p, int length);
+static void ppp_hdlc(const u_char *p, int length);
+
+/* generic Control Protocol (e.g. LCP, IPCP, CCP, etc.) handler */
+static void
+handle_ctrl_proto(u_int proto, const u_char *pptr, int length)
+{
+ const char *typestr;
+ u_int code, len;
+ int (*pfunc)(const u_char *, int);
+ int x, j;
+ const u_char *tptr;
+
+ tptr=pptr;
+
+ typestr = tok2str(ppptype2str, "unknown ctrl-proto (0x%04x)", proto);
+ printf("%s, ",typestr);
+
+ if (length < 4) /* FIXME weak boundary checking */
+ goto trunc;
+ TCHECK2(*tptr, 2);
+
+ code = *tptr++;
+
+ printf("%s (0x%02x), id %u, length %u",
+ tok2str(cpcodes, "Unknown Opcode",code),
+ code,
+ *tptr++, /* ID */
+ length+2);
+
+ if (!vflag)
+ return;
+
+ if (length <= 4)
+ return; /* there may be a NULL confreq etc. */
+
+ TCHECK2(*tptr, 2);
+ len = EXTRACT_16BITS(tptr);
+ tptr += 2;
+
+ printf("\n\tencoded length %u (=Option(s) length %u)",len,len-4);
+
+ if (vflag>1)
+ print_unknown_data(pptr-2,"\n\t",6);
+
+
+ switch (code) {
+ case CPCODES_VEXT:
+ if (length < 11)
+ break;
+ TCHECK2(*tptr, 4);
+ printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr));
+ tptr += 4;
+ TCHECK2(*tptr, 3);
+ printf(" Vendor: %s (%u)",
+ tok2str(oui_values,"Unknown",EXTRACT_24BITS(tptr)),
+ EXTRACT_24BITS(tptr));
+ /* XXX: need to decode Kind and Value(s)? */
+ break;
+ case CPCODES_CONF_REQ:
+ case CPCODES_CONF_ACK:
+ case CPCODES_CONF_NAK:
+ case CPCODES_CONF_REJ:
+ x = len - 4; /* Code(1), Identifier(1) and Length(2) */
+ do {
+ switch (proto) {
+ case PPP_LCP:
+ pfunc = print_lcp_config_options;
+ break;
+ case PPP_IPCP:
+ pfunc = print_ipcp_config_options;
+ break;
+ case PPP_IPV6CP:
+ pfunc = print_ip6cp_config_options;
+ break;
+ case PPP_CCP:
+ pfunc = print_ccp_config_options;
+ break;
+ case PPP_BACP:
+ pfunc = print_bacp_config_options;
+ break;
+ default:
+ /*
+ * No print routine for the options for
+ * this protocol.
+ */
+ pfunc = NULL;
+ break;
+ }
+
+ if (pfunc == NULL) /* catch the above null pointer if unknown CP */
+ break;
+
+ if ((j = (*pfunc)(tptr, len)) == 0)
+ break;
+ x -= j;
+ tptr += j;
+ } while (x > 0);
+ break;
+
+ case CPCODES_TERM_REQ:
+ case CPCODES_TERM_ACK:
+ /* XXX: need to decode Data? */
+ break;
+ case CPCODES_CODE_REJ:
+ /* XXX: need to decode Rejected-Packet? */
+ break;
+ case CPCODES_PROT_REJ:
+ if (length < 6)
+ break;
+ TCHECK2(*tptr, 2);
+ printf("\n\t Rejected %s Protocol (0x%04x)",
+ tok2str(ppptype2str,"unknown", EXTRACT_16BITS(tptr)),
+ EXTRACT_16BITS(tptr));
+ /* XXX: need to decode Rejected-Information? - hexdump for now */
+ if (len > 6) {
+ printf("\n\t Rejected Packet");
+ print_unknown_data(tptr+2,"\n\t ",len-2);
+ }
+ break;
+ case CPCODES_ECHO_REQ:
+ case CPCODES_ECHO_RPL:
+ case CPCODES_DISC_REQ:
+ if (length < 8)
+ break;
+ TCHECK2(*tptr, 4);
+ printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr));
+ /* XXX: need to decode Data? - hexdump for now */
+ if (len > 8) {
+ printf("\n\t -----trailing data-----");
+ TCHECK2(tptr[4], len-8);
+ print_unknown_data(tptr+4,"\n\t ",len-8);
+ }
+ break;
+ case CPCODES_ID:
+ if (length < 8)
+ break;
+ TCHECK2(*tptr, 4);
+ printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr));
+ /* RFC 1661 says this is intended to be human readable */
+ if (len > 8) {
+ printf("\n\t Message\n\t ");
+ fn_printn(tptr+4,len-4,snapend);
+ }
+ break;
+ case CPCODES_TIME_REM:
+ if (length < 12)
+ break;
+ TCHECK2(*tptr, 4);
+ printf("\n\t Magic-Num 0x%08x", EXTRACT_32BITS(tptr));
+ TCHECK2(*(tptr + 4), 4);
+ printf(", Seconds-Remaining %us", EXTRACT_32BITS(tptr + 4));
+ /* XXX: need to decode Message? */
+ break;
+ default:
+ /* XXX this is dirty but we do not get the
+ * original pointer passed to the begin
+ * the PPP packet */
+ if (vflag <= 1)
+ print_unknown_data(pptr-2,"\n\t ",length+2);
+ break;
+ }
+ return;
+
+trunc:
+ printf("[|%s]", typestr);
+}
+
+/* LCP config options */
+static int
+print_lcp_config_options(const u_char *p, int length)
+{
+ int len, opt;
+
+ if (length < 2)
+ return 0;
+ TCHECK2(*p, 2);
+ len = p[1];
+ opt = p[0];
+ if (length < len)
+ return 0;
+ if (len < 2) {
+ if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX))
+ printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)", lcpconfopts[opt],opt,len);
+ else
+ printf("\n\tunknown LCP option 0x%02x", opt);
+ return 0;
+ }
+ if ((opt >= LCPOPT_MIN) && (opt <= LCPOPT_MAX))
+ printf("\n\t %s Option (0x%02x), length %u: ", lcpconfopts[opt],opt,len);
+ else {
+ printf("\n\tunknown LCP option 0x%02x", opt);
+ return len;
+ }
+
+ switch (opt) {
+ case LCPOPT_VEXT:
+ if (len >= 6) {
+ TCHECK2(*(p + 2), 3);
+ printf("Vendor: %s (%u)",
+ tok2str(oui_values,"Unknown",EXTRACT_24BITS(p+2)),
+ EXTRACT_24BITS(p+2));
+#if 0
+ TCHECK(p[5]);
+ printf(", kind: 0x%02x", p[5]);
+ printf(", Value: 0x")
+ for (i = 0; i < len - 6; i++) {
+ TCHECK(p[6 + i]);
+ printf("%02x", p[6 + i]);
+ }
+#endif
+ }
+ break;
+ case LCPOPT_MRU:
+ if (len == 4) {
+ TCHECK2(*(p + 2), 2);
+ printf("%u", EXTRACT_16BITS(p + 2));
+ }
+ break;
+ case LCPOPT_ACCM:
+ if (len == 6) {
+ TCHECK2(*(p + 2), 4);
+ printf("0x%08x", EXTRACT_32BITS(p + 2));
+ }
+ break;
+ case LCPOPT_AP:
+ if (len >= 4) {
+ TCHECK2(*(p + 2), 2);
+ printf("%s", tok2str(ppptype2str,"Unknown Auth Proto (0x04x)",EXTRACT_16BITS(p+2)));
+
+ switch (EXTRACT_16BITS(p+2)) {
+ case PPP_CHAP:
+ TCHECK(p[4]);
+ printf(", %s",tok2str(authalg_values,"Unknown Auth Alg %u",p[4]));
+ break;
+ case PPP_PAP: /* fall through */
+ case PPP_EAP:
+ case PPP_SPAP:
+ case PPP_SPAP_OLD:
+ break;
+ default:
+ print_unknown_data(p,"\n\t",len);
+ }
+ }
+ break;
+ case LCPOPT_QP:
+ if (len >= 4) {
+ TCHECK2(*(p + 2), 2);
+ if (EXTRACT_16BITS(p+2) == PPP_LQM)
+ printf(" LQR");
+ else
+ printf(" unknown");
+ }
+ break;
+ case LCPOPT_MN:
+ if (len == 6) {
+ TCHECK2(*(p + 2), 4);
+ printf("0x%08x", EXTRACT_32BITS(p + 2));
+ }
+ break;
+ case LCPOPT_PFC:
+ break;
+ case LCPOPT_ACFC:
+ break;
+ case LCPOPT_LD:
+ if (len == 4) {
+ TCHECK2(*(p + 2), 2);
+ printf("0x%04x", EXTRACT_16BITS(p + 2));
+ }
+ break;
+ case LCPOPT_CBACK:
+ if (len < 3)
+ break;
+ TCHECK(p[2]);
+ printf("Callback Operation %s (%u)",
+ tok2str(ppp_callback_values,"Unknown",p[2]),
+ p[2]);
+ break;
+ case LCPOPT_MLMRRU:
+ if (len == 4) {
+ TCHECK2(*(p + 2), 2);
+ printf("%u", EXTRACT_16BITS(p + 2));
+ }
+ break;
+ case LCPOPT_MLED:
+ if (len < 3)
+ break;
+ TCHECK(p[2]);
+ switch (p[2]) { /* class */
+ case MEDCLASS_NULL:
+ printf("Null");
+ break;
+ case MEDCLASS_LOCAL:
+ printf("Local"); /* XXX */
+ break;
+ case MEDCLASS_IPV4:
+ if (len != 7)
+ break;
+ TCHECK2(*(p + 3), 4);
+ printf("IPv4 %s", ipaddr_string(p + 3));
+ break;
+ case MEDCLASS_MAC:
+ if (len != 9)
+ break;
+ TCHECK(p[8]);
+ printf("MAC %02x:%02x:%02x:%02x:%02x:%02x",
+ p[3], p[4], p[5], p[6], p[7], p[8]);
+ break;
+ case MEDCLASS_MNB:
+ printf("Magic-Num-Block"); /* XXX */
+ break;
+ case MEDCLASS_PSNDN:
+ printf("PSNDN"); /* XXX */
+ break;
+ }
+ break;
+
+/* XXX: to be supported */
+#if 0
+ case LCPOPT_DEP6:
+ case LCPOPT_FCSALT:
+ case LCPOPT_SDP:
+ case LCPOPT_NUMMODE:
+ case LCPOPT_DEP12:
+ case LCPOPT_DEP14:
+ case LCPOPT_DEP15:
+ case LCPOPT_DEP16:
+ case LCPOPT_MLSSNHF:
+ case LCPOPT_PROP:
+ case LCPOPT_DCEID:
+ case LCPOPT_MPP:
+ case LCPOPT_LCPAOPT:
+ case LCPOPT_COBS:
+ case LCPOPT_PE:
+ case LCPOPT_MLHF:
+ case LCPOPT_I18N:
+ case LCPOPT_SDLOS:
+ case LCPOPT_PPPMUX:
+ break;
+#endif
+ default:
+ if(vflag<2)
+ print_unknown_data(&p[2],"\n\t ",len-2);
+ break;
+ }
+
+ if (vflag>1)
+ print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */
+
+ return len;
+
+trunc:
+ printf("[|lcp]");
+ return 0;
+}
+
+/* ML-PPP*/
+struct tok ppp_ml_flag_values[] = {
+ { 0x80, "begin" },
+ { 0x40, "end" },
+ { 0, NULL }
+};
+
+static void
+handle_mlppp(const u_char *p, int length) {
+
+ if (!eflag)
+ printf("MLPPP, ");
+
+ printf("seq 0x%03x, Flags [%s], length %u",
+ (EXTRACT_16BITS(p))&0x0fff, /* only support 12-Bit sequence space for now */
+ bittok2str(ppp_ml_flag_values, "none", *p & 0xc0),
+ length);
+
+ return;
+}
+
+/* CHAP */
+static void
+handle_chap(const u_char *p, int length)
+{
+ u_int code, len;
+ int val_size, name_size, msg_size;
+ const u_char *p0;
+ int i;
+
+ p0 = p;
+ if (length < 1) {
+ printf("[|chap]");
+ return;
+ } else if (length < 4) {
+ TCHECK(*p);
+ printf("[|chap 0x%02x]", *p);
+ return;
+ }
+
+ TCHECK(*p);
+ code = *p;
+ printf("CHAP, %s (0x%02x)",
+ tok2str(chapcode_values,"unknown",code),
+ code);
+ p++;
+
+ TCHECK(*p);
+ printf(", id %u", *p); /* ID */
+ p++;
+
+ TCHECK2(*p, 2);
+ len = EXTRACT_16BITS(p);
+ p += 2;
+
+ /*
+ * Note that this is a generic CHAP decoding routine. Since we
+ * don't know which flavor of CHAP (i.e. CHAP-MD5, MS-CHAPv1,
+ * MS-CHAPv2) is used at this point, we can't decode packet
+ * specifically to each algorithms. Instead, we simply decode
+ * the GCD (Gratest Common Denominator) for all algorithms.
+ */
+ switch (code) {
+ case CHAP_CHAL:
+ case CHAP_RESP:
+ if (length - (p - p0) < 1)
+ return;
+ TCHECK(*p);
+ val_size = *p; /* value size */
+ p++;
+ if (length - (p - p0) < val_size)
+ return;
+ printf(", Value ");
+ for (i = 0; i < val_size; i++) {
+ TCHECK(*p);
+ printf("%02x", *p++);
+ }
+ name_size = len - (p - p0);
+ printf(", Name ");
+ for (i = 0; i < name_size; i++) {
+ TCHECK(*p);
+ safeputchar(*p++);
+ }
+ break;
+ case CHAP_SUCC:
+ case CHAP_FAIL:
+ msg_size = len - (p - p0);
+ printf(", Msg ");
+ for (i = 0; i< msg_size; i++) {
+ TCHECK(*p);
+ safeputchar(*p++);
+ }
+ break;
+ }
+ return;
+
+trunc:
+ printf("[|chap]");
+}
+
+/* PAP (see RFC 1334) */
+static void
+handle_pap(const u_char *p, int length)
+{
+ u_int code, len;
+ int peerid_len, passwd_len, msg_len;
+ const u_char *p0;
+ int i;
+
+ p0 = p;
+ if (length < 1) {
+ printf("[|pap]");
+ return;
+ } else if (length < 4) {
+ TCHECK(*p);
+ printf("[|pap 0x%02x]", *p);
+ return;
+ }
+
+ TCHECK(*p);
+ code = *p;
+ printf("PAP, %s (0x%02x)",
+ tok2str(papcode_values,"unknown",code),
+ code);
+ p++;
+
+ TCHECK(*p);
+ printf(", id %u", *p); /* ID */
+ p++;
+
+ TCHECK2(*p, 2);
+ len = EXTRACT_16BITS(p);
+ p += 2;
+
+ if ((int)len > length) {
+ printf(", length %u > packet size", len);
+ return;
+ }
+ length = len;
+ if (length < (p - p0)) {
+ printf(", length %u < PAP header length", length);
+ return;
+ }
+
+ switch (code) {
+ case PAP_AREQ:
+ if (length - (p - p0) < 1)
+ return;
+ TCHECK(*p);
+ peerid_len = *p; /* Peer-ID Length */
+ p++;
+ if (length - (p - p0) < peerid_len)
+ return;
+ printf(", Peer ");
+ for (i = 0; i < peerid_len; i++) {
+ TCHECK(*p);
+ safeputchar(*p++);
+ }
+
+ if (length - (p - p0) < 1)
+ return;
+ TCHECK(*p);
+ passwd_len = *p; /* Password Length */
+ p++;
+ if (length - (p - p0) < passwd_len)
+ return;
+ printf(", Name ");
+ for (i = 0; i < passwd_len; i++) {
+ TCHECK(*p);
+ safeputchar(*p++);
+ }
+ break;
+ case PAP_AACK:
+ case PAP_ANAK:
+ if (length - (p - p0) < 1)
+ return;
+ TCHECK(*p);
+ msg_len = *p; /* Msg-Length */
+ p++;
+ if (length - (p - p0) < msg_len)
+ return;
+ printf(", Msg ");
+ for (i = 0; i< msg_len; i++) {
+ TCHECK(*p);
+ safeputchar(*p++);
+ }
+ break;
+ }
+ return;
+
+trunc:
+ printf("[|pap]");
+}
+
+/* BAP */
+static void
+handle_bap(const u_char *p _U_, int length _U_)
+{
+ /* XXX: to be supported!! */
+}
+
+
+/* IPCP config options */
+static int
+print_ipcp_config_options(const u_char *p, int length)
+{
+ int len, opt;
+ u_int compproto, ipcomp_subopttotallen, ipcomp_subopt, ipcomp_suboptlen;
+
+ if (length < 2)
+ return 0;
+ TCHECK2(*p, 2);
+ len = p[1];
+ opt = p[0];
+ if (length < len)
+ return 0;
+ if (len < 2) {
+ printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)",
+ tok2str(ipcpopt_values,"unknown",opt),
+ opt,
+ len);
+ return 0;
+ }
+
+ printf("\n\t %s Option (0x%02x), length %u: ",
+ tok2str(ipcpopt_values,"unknown",opt),
+ opt,
+ len);
+
+ switch (opt) {
+ case IPCPOPT_2ADDR: /* deprecated */
+ if (len != 10)
+ goto invlen;
+ TCHECK2(*(p + 6), 4);
+ printf("src %s, dst %s",
+ ipaddr_string(p + 2),
+ ipaddr_string(p + 6));
+ break;
+ case IPCPOPT_IPCOMP:
+ if (len < 4)
+ goto invlen;
+ TCHECK2(*(p + 2), 2);
+ compproto = EXTRACT_16BITS(p+2);
+
+ printf("%s (0x%02x):",
+ tok2str(ipcpopt_compproto_values,"Unknown",compproto),
+ compproto);
+
+ switch (compproto) {
+ case PPP_VJC:
+ /* XXX: VJ-Comp parameters should be decoded */
+ break;
+ case IPCPOPT_IPCOMP_HDRCOMP:
+ if (len < IPCPOPT_IPCOMP_MINLEN)
+ goto invlen;
+
+ TCHECK2(*(p + 2), IPCPOPT_IPCOMP_MINLEN);
+ printf("\n\t TCP Space %u, non-TCP Space %u" \
+ ", maxPeriod %u, maxTime %u, maxHdr %u",
+ EXTRACT_16BITS(p+4),
+ EXTRACT_16BITS(p+6),
+ EXTRACT_16BITS(p+8),
+ EXTRACT_16BITS(p+10),
+ EXTRACT_16BITS(p+12));
+
+ /* suboptions present ? */
+ if (len > IPCPOPT_IPCOMP_MINLEN) {
+ ipcomp_subopttotallen = len - IPCPOPT_IPCOMP_MINLEN;
+ p += IPCPOPT_IPCOMP_MINLEN;
+
+ printf("\n\t Suboptions, length %u", ipcomp_subopttotallen);
+
+ while (ipcomp_subopttotallen >= 2) {
+ TCHECK2(*p, 2);
+ ipcomp_subopt = *p;
+ ipcomp_suboptlen = *(p+1);
+
+ /* sanity check */
+ if (ipcomp_subopt == 0 ||
+ ipcomp_suboptlen == 0 )
+ break;
+
+ /* XXX: just display the suboptions for now */
+ printf("\n\t\t%s Suboption #%u, length %u",
+ tok2str(ipcpopt_compproto_subopt_values,
+ "Unknown",
+ ipcomp_subopt),
+ ipcomp_subopt,
+ ipcomp_suboptlen);
+
+ ipcomp_subopttotallen -= ipcomp_suboptlen;
+ p += ipcomp_suboptlen;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case IPCPOPT_ADDR: /* those options share the same format - fall through */
+ case IPCPOPT_MOBILE4:
+ case IPCPOPT_PRIDNS:
+ case IPCPOPT_PRINBNS:
+ case IPCPOPT_SECDNS:
+ case IPCPOPT_SECNBNS:
+ if (len != 6)
+ goto invlen;
+ TCHECK2(*(p + 2), 4);
+ printf("%s", ipaddr_string(p + 2));
+ break;
+ default:
+ if(vflag<2)
+ print_unknown_data(&p[2],"\n\t ",len-2);
+ break;
+ }
+ if (vflag>1)
+ print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */
+ return len;
+
+invlen:
+ printf(", invalid-length-%d", opt);
+ return 0;
+
+trunc:
+ printf("[|ipcp]");
+ return 0;
+}
+
+/* IP6CP config options */
+static int
+print_ip6cp_config_options(const u_char *p, int length)
+{
+ int len, opt;
+
+ if (length < 2)
+ return 0;
+ TCHECK2(*p, 2);
+ len = p[1];
+ opt = p[0];
+ if (length < len)
+ return 0;
+ if (len < 2) {
+ printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)",
+ tok2str(ip6cpopt_values,"unknown",opt),
+ opt,
+ len);
+ return 0;
+ }
+
+ printf("\n\t %s Option (0x%02x), length %u: ",
+ tok2str(ip6cpopt_values,"unknown",opt),
+ opt,
+ len);
+
+ switch (opt) {
+ case IP6CP_IFID:
+ if (len != 10)
+ goto invlen;
+ TCHECK2(*(p + 2), 8);
+ printf("%04x:%04x:%04x:%04x",
+ EXTRACT_16BITS(p + 2),
+ EXTRACT_16BITS(p + 4),
+ EXTRACT_16BITS(p + 6),
+ EXTRACT_16BITS(p + 8));
+ break;
+ default:
+ if(vflag<2)
+ print_unknown_data(&p[2],"\n\t ",len-2);
+ break;
+ }
+ if (vflag>1)
+ print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */
+
+ return len;
+
+invlen:
+ printf(", invalid-length-%d", opt);
+ return 0;
+
+trunc:
+ printf("[|ip6cp]");
+ return 0;
+}
+
+
+/* CCP config options */
+static int
+print_ccp_config_options(const u_char *p, int length)
+{
+ int len, opt;
+
+ if (length < 2)
+ return 0;
+ TCHECK2(*p, 2);
+ len = p[1];
+ opt = p[0];
+ if (length < len)
+ return 0;
+ if (len < 2) {
+ printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)",
+ tok2str(ccpconfopts_values, "Unknown", opt),
+ opt,
+ len);
+ return 0;
+ }
+
+ printf("\n\t %s Option (0x%02x), length %u:",
+ tok2str(ccpconfopts_values, "Unknown", opt),
+ opt,
+ len);
+
+ switch (opt) {
+ /* fall through --> default: nothing supported yet */
+ case CCPOPT_OUI:
+ case CCPOPT_PRED1:
+ case CCPOPT_PRED2:
+ case CCPOPT_PJUMP:
+ case CCPOPT_HPPPC:
+ case CCPOPT_STACLZS:
+ case CCPOPT_MPPC:
+ case CCPOPT_GFZA:
+ case CCPOPT_V42BIS:
+ case CCPOPT_BSDCOMP:
+ case CCPOPT_LZSDCP:
+ case CCPOPT_MVRCA:
+ case CCPOPT_DEC:
+ case CCPOPT_DEFLATE:
+ case CCPOPT_RESV:
+ default:
+ if(vflag<2)
+ print_unknown_data(&p[2],"\n\t ",len-2);
+ break;
+ }
+ if (vflag>1)
+ print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */
+
+ return len;
+
+trunc:
+ printf("[|ccp]");
+ return 0;
+}
+
+/* BACP config options */
+static int
+print_bacp_config_options(const u_char *p, int length)
+{
+ int len, opt;
+
+ if (length < 2)
+ return 0;
+ TCHECK2(*p, 2);
+ len = p[1];
+ opt = p[0];
+ if (length < len)
+ return 0;
+ if (len < 2) {
+ printf("\n\t %s Option (0x%02x), length %u (bogus, should be >= 2)",
+ tok2str(bacconfopts_values, "Unknown", opt),
+ opt,
+ len);
+ return 0;
+ }
+
+ printf("\n\t %s Option (0x%02x), length %u:",
+ tok2str(bacconfopts_values, "Unknown", opt),
+ opt,
+ len);
+
+ switch (opt) {
+ case BACPOPT_FPEER:
+ TCHECK2(*(p + 2), 4);
+ printf(", Magic-Num 0x%08x", EXTRACT_32BITS(p + 2));
+ break;
+ default:
+ if(vflag<2)
+ print_unknown_data(&p[2],"\n\t ",len-2);
+ break;
+ }
+ if (vflag>1)
+ print_unknown_data(&p[2],"\n\t ",len-2); /* exclude TLV header */
+
+ return len;
+
+trunc:
+ printf("[|bacp]");
+ return 0;
+}
+
+
+static void
+ppp_hdlc(const u_char *p, int length)
+{
+ u_char *b, *s, *t, c;
+ int i, proto;
+ const void *se;
+
+ b = (u_int8_t *)malloc(length);
+ if (b == NULL)
+ return;
+
+ /*
+ * Unescape all the data into a temporary, private, buffer.
+ * Do this so that we dont overwrite the original packet
+ * contents.
+ */
+ for (s = (u_char *)p, t = b, i = length; i > 0; i--) {
+ c = *s++;
+ if (c == 0x7d) {
+ if (i > 1) {
+ i--;
+ c = *s++ ^ 0x20;
+ } else
+ continue;
+ }
+ *t++ = c;
+ }
+
+ se = snapend;
+ snapend = t;
+
+ /* now lets guess about the payload codepoint format */
+ proto = *b; /* start with a one-octet codepoint guess */
+
+ switch (proto) {
+ case PPP_IP:
+ ip_print(gndo, b+1, t - b - 1);
+ goto cleanup;
+#ifdef INET6
+ case PPP_IPV6:
+ ip6_print(gndo, b+1, t - b - 1);
+ goto cleanup;
+#endif
+ default: /* no luck - try next guess */
+ break;
+ }
+
+ proto = EXTRACT_16BITS(b); /* next guess - load two octets */
+
+ switch (proto) {
+ case (PPP_ADDRESS << 8 | PPP_CONTROL): /* looks like a PPP frame */
+ proto = EXTRACT_16BITS(b+2); /* load the PPP proto-id */
+ handle_ppp(proto, b+4, t - b - 4);
+ break;
+ default: /* last guess - proto must be a PPP proto-id */
+ handle_ppp(proto, b+2, t - b - 2);
+ break;
+ }
+
+cleanup:
+ snapend = se;
+ free(b);
+ return;
+}
+
+
+/* PPP */
+static void
+handle_ppp(u_int proto, const u_char *p, int length)
+{
+ if ((proto & 0xff00) == 0x7e00) {/* is this an escape code ? */
+ ppp_hdlc(p-1, length);
+ return;
+ }
+
+ switch (proto) {
+ case PPP_LCP: /* fall through */
+ case PPP_IPCP:
+ case PPP_OSICP:
+ case PPP_MPLSCP:
+ case PPP_IPV6CP:
+ case PPP_CCP:
+ case PPP_BACP:
+ handle_ctrl_proto(proto, p, length);
+ break;
+ case PPP_ML:
+ handle_mlppp(p, length);
+ break;
+ case PPP_CHAP:
+ handle_chap(p, length);
+ break;
+ case PPP_PAP:
+ handle_pap(p, length);
+ break;
+ case PPP_BAP: /* XXX: not yet completed */
+ handle_bap(p, length);
+ break;
+ case ETHERTYPE_IP: /*XXX*/
+ case PPP_VJNC:
+ case PPP_IP:
+ ip_print(gndo, p, length);
+ break;
+#ifdef INET6
+ case ETHERTYPE_IPV6: /*XXX*/
+ case PPP_IPV6:
+ ip6_print(gndo, p, length);
+ break;
+#endif
+ case ETHERTYPE_IPX: /*XXX*/
+ case PPP_IPX:
+ ipx_print(p, length);
+ break;
+ case PPP_OSI:
+ isoclns_print(p, length, length);
+ break;
+ case PPP_MPLS_UCAST:
+ case PPP_MPLS_MCAST:
+ mpls_print(p, length);
+ break;
+ case PPP_COMP:
+ printf("compressed PPP data");
+ break;
+ default:
+ printf("%s ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", proto));
+ print_unknown_data(p,"\n\t",length);
+ break;
+ }
+}
+
+/* Standard PPP printer */
+u_int
+ppp_print(register const u_char *p, u_int length)
+{
+ u_int proto,ppp_header;
+ u_int olen = length; /* _o_riginal length */
+ u_int hdr_len = 0;
+
+ /*
+ * Here, we assume that p points to the Address and Control
+ * field (if they present).
+ */
+ if (length < 2)
+ goto trunc;
+ TCHECK2(*p, 2);
+ ppp_header = EXTRACT_16BITS(p);
+
+ switch(ppp_header) {
+ case (PPP_WITHDIRECTION_IN << 8 | PPP_CONTROL):
+ if (eflag) printf("In ");
+ p += 2;
+ length -= 2;
+ hdr_len += 2;
+ break;
+ case (PPP_WITHDIRECTION_OUT << 8 | PPP_CONTROL):
+ if (eflag) printf("Out ");
+ p += 2;
+ length -= 2;
+ hdr_len += 2;
+ break;
+ case (PPP_ADDRESS << 8 | PPP_CONTROL):
+ p += 2; /* ACFC not used */
+ length -= 2;
+ hdr_len += 2;
+ break;
+
+ default:
+ break;
+ }
+
+ if (length < 2)
+ goto trunc;
+ TCHECK(*p);
+ if (*p % 2) {
+ proto = *p; /* PFC is used */
+ p++;
+ length--;
+ hdr_len++;
+ } else {
+ TCHECK2(*p, 2);
+ proto = EXTRACT_16BITS(p);
+ p += 2;
+ length -= 2;
+ hdr_len += 2;
+ }
+
+ if (eflag)
+ printf("%s (0x%04x), length %u: ",
+ tok2str(ppptype2str, "unknown", proto),
+ proto,
+ olen);
+
+ handle_ppp(proto, p, length);
+ return (hdr_len);
+trunc:
+ printf("[|ppp]");
+ return (0);
+}
+
+
+/* PPP I/F printer */
+u_int
+ppp_if_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ register u_int length = h->len;
+ register u_int caplen = h->caplen;
+
+ if (caplen < PPP_HDRLEN) {
+ printf("[|ppp]");
+ return (caplen);
+ }
+
+#if 0
+ /*
+ * XXX: seems to assume that there are 2 octets prepended to an
+ * actual PPP frame. The 1st octet looks like Input/Output flag
+ * while 2nd octet is unknown, at least to me
+ * (mshindo@mshindo.net).
+ *
+ * That was what the original tcpdump code did.
+ *
+ * FreeBSD's "if_ppp.c" *does* set the first octet to 1 for outbound
+ * packets and 0 for inbound packets - but only if the
+ * protocol field has the 0x8000 bit set (i.e., it's a network
+ * control protocol); it does so before running the packet through
+ * "bpf_filter" to see if it should be discarded, and to see
+ * if we should update the time we sent the most recent packet...
+ *
+ * ...but it puts the original address field back after doing
+ * so.
+ *
+ * NetBSD's "if_ppp.c" doesn't set the first octet in that fashion.
+ *
+ * I don't know if any PPP implementation handed up to a BPF
+ * device packets with the first octet being 1 for outbound and
+ * 0 for inbound packets, so I (guy@alum.mit.edu) don't know
+ * whether that ever needs to be checked or not.
+ *
+ * Note that NetBSD has a DLT_PPP_SERIAL, which it uses for PPP,
+ * and its tcpdump appears to assume that the frame always
+ * begins with an address field and a control field, and that
+ * the address field might be 0x0f or 0x8f, for Cisco
+ * point-to-point with HDLC framing as per section 4.3.1 of RFC
+ * 1547, as well as 0xff, for PPP in HDLC-like framing as per
+ * RFC 1662.
+ *
+ * (Is the Cisco framing in question what DLT_C_HDLC, in
+ * BSD/OS, is?)
+ */
+ if (eflag)
+ printf("%c %4d %02x ", p[0] ? 'O' : 'I', length, p[1]);
+#endif
+
+ ppp_print(p, length);
+
+ return (0);
+}
+
+/*
+ * PPP I/F printer to use if we know that RFC 1662-style PPP in HDLC-like
+ * framing, or Cisco PPP with HDLC framing as per section 4.3.1 of RFC 1547,
+ * is being used (i.e., we don't check for PPP_ADDRESS and PPP_CONTROL,
+ * discard them *if* those are the first two octets, and parse the remaining
+ * packet as a PPP packet, as "ppp_print()" does).
+ *
+ * This handles, for example, DLT_PPP_SERIAL in NetBSD.
+ */
+u_int
+ppp_hdlc_if_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ register u_int length = h->len;
+ register u_int caplen = h->caplen;
+ u_int proto;
+ u_int hdrlen = 0;
+
+ if (caplen < 2) {
+ printf("[|ppp]");
+ return (caplen);
+ }
+
+ switch (p[0]) {
+
+ case PPP_ADDRESS:
+ if (caplen < 4) {
+ printf("[|ppp]");
+ return (caplen);
+ }
+
+ if (eflag)
+ printf("%02x %02x %d ", p[0], p[1], length);
+ p += 2;
+ length -= 2;
+ hdrlen += 2;
+
+ proto = EXTRACT_16BITS(p);
+ p += 2;
+ length -= 2;
+ hdrlen += 2;
+ printf("%s: ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", proto));
+
+ handle_ppp(proto, p, length);
+ break;
+
+ case CHDLC_UNICAST:
+ case CHDLC_BCAST:
+ return (chdlc_if_print(h, p));
+
+ default:
+ if (eflag)
+ printf("%02x %02x %d ", p[0], p[1], length);
+ p += 2;
+ length -= 2;
+ hdrlen += 2;
+
+ /*
+ * XXX - NetBSD's "ppp_netbsd_serial_if_print()" treats
+ * the next two octets as an Ethernet type; does that
+ * ever happen?
+ */
+ printf("unknown addr %02x; ctrl %02x", p[0], p[1]);
+ break;
+ }
+
+ return (hdrlen);
+}
+
+#define PPP_BSDI_HDRLEN 24
+
+/* BSD/OS specific PPP printer */
+u_int
+ppp_bsdos_if_print(const struct pcap_pkthdr *h _U_, register const u_char *p _U_)
+{
+ register int hdrlength;
+#ifdef __bsdi__
+ register u_int length = h->len;
+ register u_int caplen = h->caplen;
+ u_int16_t ptype;
+ const u_char *q;
+ int i;
+
+ if (caplen < PPP_BSDI_HDRLEN) {
+ printf("[|ppp]");
+ return (caplen)
+ }
+
+ hdrlength = 0;
+
+#if 0
+ if (p[0] == PPP_ADDRESS && p[1] == PPP_CONTROL) {
+ if (eflag)
+ printf("%02x %02x ", p[0], p[1]);
+ p += 2;
+ hdrlength = 2;
+ }
+
+ if (eflag)
+ printf("%d ", length);
+ /* Retrieve the protocol type */
+ if (*p & 01) {
+ /* Compressed protocol field */
+ ptype = *p;
+ if (eflag)
+ printf("%02x ", ptype);
+ p++;
+ hdrlength += 1;
+ } else {
+ /* Un-compressed protocol field */
+ ptype = EXTRACT_16BITS(p);
+ if (eflag)
+ printf("%04x ", ptype);
+ p += 2;
+ hdrlength += 2;
+ }
+#else
+ ptype = 0; /*XXX*/
+ if (eflag)
+ printf("%c ", p[SLC_DIR] ? 'O' : 'I');
+ if (p[SLC_LLHL]) {
+ /* link level header */
+ struct ppp_header *ph;
+
+ q = p + SLC_BPFHDRLEN;
+ ph = (struct ppp_header *)q;
+ if (ph->phdr_addr == PPP_ADDRESS
+ && ph->phdr_ctl == PPP_CONTROL) {
+ if (eflag)
+ printf("%02x %02x ", q[0], q[1]);
+ ptype = EXTRACT_16BITS(&ph->phdr_type);
+ if (eflag && (ptype == PPP_VJC || ptype == PPP_VJNC)) {
+ printf("%s ", tok2str(ppptype2str,
+ "proto-#%d", ptype));
+ }
+ } else {
+ if (eflag) {
+ printf("LLH=[");
+ for (i = 0; i < p[SLC_LLHL]; i++)
+ printf("%02x", q[i]);
+ printf("] ");
+ }
+ }
+ }
+ if (eflag)
+ printf("%d ", length);
+ if (p[SLC_CHL]) {
+ q = p + SLC_BPFHDRLEN + p[SLC_LLHL];
+
+ switch (ptype) {
+ case PPP_VJC:
+ ptype = vjc_print(q, ptype);
+ hdrlength = PPP_BSDI_HDRLEN;
+ p += hdrlength;
+ switch (ptype) {
+ case PPP_IP:
+ ip_print(gndo, p, length);
+ break;
+#ifdef INET6
+ case PPP_IPV6:
+ ip6_print(gndo, p, length);
+ break;
+#endif
+ case PPP_MPLS_UCAST:
+ case PPP_MPLS_MCAST:
+ mpls_print(p, length);
+ break;
+ }
+ goto printx;
+ case PPP_VJNC:
+ ptype = vjc_print(q, ptype);
+ hdrlength = PPP_BSDI_HDRLEN;
+ p += hdrlength;
+ switch (ptype) {
+ case PPP_IP:
+ ip_print(gndo, p, length);
+ break;
+#ifdef INET6
+ case PPP_IPV6:
+ ip6_print(gndo, p, length);
+ break;
+#endif
+ case PPP_MPLS_UCAST:
+ case PPP_MPLS_MCAST:
+ mpls_print(p, length);
+ break;
+ }
+ goto printx;
+ default:
+ if (eflag) {
+ printf("CH=[");
+ for (i = 0; i < p[SLC_LLHL]; i++)
+ printf("%02x", q[i]);
+ printf("] ");
+ }
+ break;
+ }
+ }
+
+ hdrlength = PPP_BSDI_HDRLEN;
+#endif
+
+ length -= hdrlength;
+ p += hdrlength;
+
+ switch (ptype) {
+ case PPP_IP:
+ ip_print(p, length);
+ break;
+#ifdef INET6
+ case PPP_IPV6:
+ ip6_print(gndo, p, length);
+ break;
+#endif
+ case PPP_MPLS_UCAST:
+ case PPP_MPLS_MCAST:
+ mpls_print(gndo, p, length);
+ break;
+ default:
+ printf("%s ", tok2str(ppptype2str, "unknown PPP protocol (0x%04x)", ptype));
+ }
+
+printx:
+#else /* __bsdi */
+ hdrlength = 0;
+#endif /* __bsdi__ */
+ return (hdrlength);
+}
+
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-pppoe.c b/freebsd/contrib/tcpdump/print-pppoe.c
new file mode 100644
index 00000000..af12682f
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-pppoe.c
@@ -0,0 +1,213 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Greg Stark <gsstark@mit.edu>
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+"@(#) $Header: /tcpdump/master/tcpdump/print-pppoe.c,v 1.31 2005-04-26 19:48:38 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ppp.h"
+#include "ethertype.h"
+#include "ether.h"
+#include "extract.h" /* must come after interface.h */
+
+/* Codes */
+enum {
+ PPPOE_PADI = 0x09,
+ PPPOE_PADO = 0x07,
+ PPPOE_PADR = 0x19,
+ PPPOE_PADS = 0x65,
+ PPPOE_PADT = 0xa7
+};
+
+static struct tok pppoecode2str[] = {
+ { PPPOE_PADI, "PADI" },
+ { PPPOE_PADO, "PADO" },
+ { PPPOE_PADR, "PADR" },
+ { PPPOE_PADS, "PADS" },
+ { PPPOE_PADT, "PADT" },
+ { 0, "" }, /* PPP Data */
+ { 0, NULL }
+};
+
+/* Tags */
+enum {
+ PPPOE_EOL = 0,
+ PPPOE_SERVICE_NAME = 0x0101,
+ PPPOE_AC_NAME = 0x0102,
+ PPPOE_HOST_UNIQ = 0x0103,
+ PPPOE_AC_COOKIE = 0x0104,
+ PPPOE_VENDOR = 0x0105,
+ PPPOE_RELAY_SID = 0x0110,
+ PPPOE_MAX_PAYLOAD = 0x0120,
+ PPPOE_SERVICE_NAME_ERROR = 0x0201,
+ PPPOE_AC_SYSTEM_ERROR = 0x0202,
+ PPPOE_GENERIC_ERROR = 0x0203
+};
+
+static struct tok pppoetag2str[] = {
+ { PPPOE_EOL, "EOL" },
+ { PPPOE_SERVICE_NAME, "Service-Name" },
+ { PPPOE_AC_NAME, "AC-Name" },
+ { PPPOE_HOST_UNIQ, "Host-Uniq" },
+ { PPPOE_AC_COOKIE, "AC-Cookie" },
+ { PPPOE_VENDOR, "Vendor-Specific" },
+ { PPPOE_RELAY_SID, "Relay-Session-ID" },
+ { PPPOE_MAX_PAYLOAD, "PPP-Max-Payload" },
+ { PPPOE_SERVICE_NAME_ERROR, "Service-Name-Error" },
+ { PPPOE_AC_SYSTEM_ERROR, "AC-System-Error" },
+ { PPPOE_GENERIC_ERROR, "Generic-Error" },
+ { 0, NULL }
+};
+
+#define PPPOE_HDRLEN 6
+#define MAXTAGPRINT 80
+
+u_int
+pppoe_if_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ return (pppoe_print(p, h->len));
+}
+
+u_int
+pppoe_print(register const u_char *bp, u_int length)
+{
+ u_int16_t pppoe_ver, pppoe_type, pppoe_code, pppoe_sessionid;
+ u_int pppoe_length;
+ const u_char *pppoe_packet, *pppoe_payload;
+
+ if (length < PPPOE_HDRLEN) {
+ (void)printf("truncated-pppoe %u", length);
+ return (length);
+ }
+ length -= PPPOE_HDRLEN;
+ pppoe_packet = bp;
+ TCHECK2(*pppoe_packet, PPPOE_HDRLEN);
+ pppoe_ver = (pppoe_packet[0] & 0xF0) >> 4;
+ pppoe_type = (pppoe_packet[0] & 0x0F);
+ pppoe_code = pppoe_packet[1];
+ pppoe_sessionid = EXTRACT_16BITS(pppoe_packet + 2);
+ pppoe_length = EXTRACT_16BITS(pppoe_packet + 4);
+ pppoe_payload = pppoe_packet + PPPOE_HDRLEN;
+
+ if (pppoe_ver != 1) {
+ printf(" [ver %d]",pppoe_ver);
+ }
+ if (pppoe_type != 1) {
+ printf(" [type %d]",pppoe_type);
+ }
+
+ printf("PPPoE %s", tok2str(pppoecode2str, "PAD-%x", pppoe_code));
+ if (pppoe_code == PPPOE_PADI && pppoe_length > 1484 - PPPOE_HDRLEN) {
+ printf(" [len %u!]",pppoe_length);
+ }
+ if (pppoe_length > length) {
+ printf(" [len %u > %u!]", pppoe_length, length);
+ pppoe_length = length;
+ }
+ if (pppoe_sessionid) {
+ printf(" [ses 0x%x]", pppoe_sessionid);
+ }
+
+ if (pppoe_code) {
+ /* PPP session packets don't contain tags */
+ u_short tag_type = 0xffff, tag_len;
+ const u_char *p = pppoe_payload;
+
+ /*
+ * loop invariant:
+ * p points to current tag,
+ * tag_type is previous tag or 0xffff for first iteration
+ */
+ while (tag_type && p < pppoe_payload + pppoe_length) {
+ TCHECK2(*p, 4);
+ tag_type = EXTRACT_16BITS(p);
+ tag_len = EXTRACT_16BITS(p + 2);
+ p += 4;
+ /* p points to tag_value */
+
+ if (tag_len) {
+ unsigned isascii = 0, isgarbage = 0;
+ const u_char *v;
+ char tag_str[MAXTAGPRINT];
+ unsigned tag_str_len = 0;
+
+ /* TODO print UTF-8 decoded text */
+ TCHECK2(*p, tag_len);
+ for (v = p; v < p + tag_len && tag_str_len < MAXTAGPRINT-1; v++)
+ if (*v >= 32 && *v < 127) {
+ tag_str[tag_str_len++] = *v;
+ isascii++;
+ } else {
+ tag_str[tag_str_len++] = '.';
+ isgarbage++;
+ }
+ tag_str[tag_str_len] = 0;
+
+ if (isascii > isgarbage) {
+ printf(" [%s \"%*.*s\"]",
+ tok2str(pppoetag2str, "TAG-0x%x", tag_type),
+ (int)tag_str_len,
+ (int)tag_str_len,
+ tag_str);
+ } else {
+ /* Print hex, not fast to abuse printf but this doesn't get used much */
+ printf(" [%s 0x", tok2str(pppoetag2str, "TAG-0x%x", tag_type));
+ for (v=p; v<p+tag_len; v++) {
+ printf("%02X", *v);
+ }
+ printf("]");
+ }
+
+
+ } else
+ printf(" [%s]", tok2str(pppoetag2str,
+ "TAG-0x%x", tag_type));
+
+ p += tag_len;
+ /* p points to next tag */
+ }
+ return (0);
+ } else {
+ /* PPPoE data */
+ printf(" ");
+ return (PPPOE_HDRLEN + ppp_print(pppoe_payload, pppoe_length));
+ }
+
+trunc:
+ printf("[|pppoe]");
+ return (PPPOE_HDRLEN);
+}
diff --git a/freebsd/contrib/tcpdump/print-pptp.c b/freebsd/contrib/tcpdump/print-pptp.c
new file mode 100644
index 00000000..27eb7c72
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-pptp.c
@@ -0,0 +1,1062 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1991, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * PPTP support contributed by Motonori Shindo (mshindo@mshindo.net)
+ */
+
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-pptp.c,v 1.12 2006-06-23 02:03:09 hannes Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "extract.h"
+
+static char tstr[] = " [|pptp]";
+
+#define PPTP_MSG_TYPE_CTRL 1 /* Control Message */
+#define PPTP_MSG_TYPE_MGMT 2 /* Management Message (currently not used */
+#define PPTP_MAGIC_COOKIE 0x1a2b3c4d /* for sanity check */
+
+#define PPTP_CTRL_MSG_TYPE_SCCRQ 1
+#define PPTP_CTRL_MSG_TYPE_SCCRP 2
+#define PPTP_CTRL_MSG_TYPE_StopCCRQ 3
+#define PPTP_CTRL_MSG_TYPE_StopCCRP 4
+#define PPTP_CTRL_MSG_TYPE_ECHORQ 5
+#define PPTP_CTRL_MSG_TYPE_ECHORP 6
+#define PPTP_CTRL_MSG_TYPE_OCRQ 7
+#define PPTP_CTRL_MSG_TYPE_OCRP 8
+#define PPTP_CTRL_MSG_TYPE_ICRQ 9
+#define PPTP_CTRL_MSG_TYPE_ICRP 10
+#define PPTP_CTRL_MSG_TYPE_ICCN 11
+#define PPTP_CTRL_MSG_TYPE_CCRQ 12
+#define PPTP_CTRL_MSG_TYPE_CDN 13
+#define PPTP_CTRL_MSG_TYPE_WEN 14
+#define PPTP_CTRL_MSG_TYPE_SLI 15
+
+#define PPTP_FRAMING_CAP_ASYNC_MASK 0x00000001 /* Aynchronous */
+#define PPTP_FRAMING_CAP_SYNC_MASK 0x00000002 /* Synchronous */
+
+#define PPTP_BEARER_CAP_ANALOG_MASK 0x00000001 /* Analog */
+#define PPTP_BEARER_CAP_DIGITAL_MASK 0x00000002 /* Digital */
+
+static const char *pptp_message_type_string[] = {
+ "NOT_DEFINED", /* 0 Not defined in the RFC2637 */
+ "SCCRQ", /* 1 Start-Control-Connection-Request */
+ "SCCRP", /* 2 Start-Control-Connection-Reply */
+ "StopCCRQ", /* 3 Stop-Control-Connection-Request */
+ "StopCCRP", /* 4 Stop-Control-Connection-Reply */
+ "ECHORQ", /* 5 Echo Request */
+ "ECHORP", /* 6 Echo Reply */
+
+ "OCRQ", /* 7 Outgoing-Call-Request */
+ "OCRP", /* 8 Outgoing-Call-Reply */
+ "ICRQ", /* 9 Incoming-Call-Request */
+ "ICRP", /* 10 Incoming-Call-Reply */
+ "ICCN", /* 11 Incoming-Call-Connected */
+ "CCRQ", /* 12 Call-Clear-Request */
+ "CDN", /* 13 Call-Disconnect-Notify */
+
+ "WEN", /* 14 WAN-Error-Notify */
+
+ "SLI" /* 15 Set-Link-Info */
+#define PPTP_MAX_MSGTYPE_INDEX 16
+};
+
+/* common for all PPTP control messages */
+struct pptp_hdr {
+ u_int16_t length;
+ u_int16_t msg_type;
+ u_int32_t magic_cookie;
+ u_int16_t ctrl_msg_type;
+ u_int16_t reserved0;
+};
+
+struct pptp_msg_sccrq {
+ u_int16_t proto_ver;
+ u_int16_t reserved1;
+ u_int32_t framing_cap;
+ u_int32_t bearer_cap;
+ u_int16_t max_channel;
+ u_int16_t firm_rev;
+ u_char hostname[64];
+ u_char vendor[64];
+};
+
+struct pptp_msg_sccrp {
+ u_int16_t proto_ver;
+ u_int8_t result_code;
+ u_int8_t err_code;
+ u_int32_t framing_cap;
+ u_int32_t bearer_cap;
+ u_int16_t max_channel;
+ u_int16_t firm_rev;
+ u_char hostname[64];
+ u_char vendor[64];
+};
+
+struct pptp_msg_stopccrq {
+ u_int8_t reason;
+ u_int8_t reserved1;
+ u_int16_t reserved2;
+};
+
+struct pptp_msg_stopccrp {
+ u_int8_t result_code;
+ u_int8_t err_code;
+ u_int16_t reserved1;
+};
+
+struct pptp_msg_echorq {
+ u_int32_t id;
+};
+
+struct pptp_msg_echorp {
+ u_int32_t id;
+ u_int8_t result_code;
+ u_int8_t err_code;
+ u_int16_t reserved1;
+};
+
+struct pptp_msg_ocrq {
+ u_int16_t call_id;
+ u_int16_t call_ser;
+ u_int32_t min_bps;
+ u_int32_t max_bps;
+ u_int32_t bearer_type;
+ u_int32_t framing_type;
+ u_int16_t recv_winsiz;
+ u_int16_t pkt_proc_delay;
+ u_int16_t phone_no_len;
+ u_int16_t reserved1;
+ u_char phone_no[64];
+ u_char subaddr[64];
+};
+
+struct pptp_msg_ocrp {
+ u_int16_t call_id;
+ u_int16_t peer_call_id;
+ u_int8_t result_code;
+ u_int8_t err_code;
+ u_int16_t cause_code;
+ u_int32_t conn_speed;
+ u_int16_t recv_winsiz;
+ u_int16_t pkt_proc_delay;
+ u_int32_t phy_chan_id;
+};
+
+struct pptp_msg_icrq {
+ u_int16_t call_id;
+ u_int16_t call_ser;
+ u_int32_t bearer_type;
+ u_int32_t phy_chan_id;
+ u_int16_t dialed_no_len;
+ u_int16_t dialing_no_len;
+ u_char dialed_no[64]; /* DNIS */
+ u_char dialing_no[64]; /* CLID */
+ u_char subaddr[64];
+};
+
+struct pptp_msg_icrp {
+ u_int16_t call_id;
+ u_int16_t peer_call_id;
+ u_int8_t result_code;
+ u_int8_t err_code;
+ u_int16_t recv_winsiz;
+ u_int16_t pkt_proc_delay;
+ u_int16_t reserved1;
+};
+
+struct pptp_msg_iccn {
+ u_int16_t peer_call_id;
+ u_int16_t reserved1;
+ u_int32_t conn_speed;
+ u_int16_t recv_winsiz;
+ u_int16_t pkt_proc_delay;
+ u_int32_t framing_type;
+};
+
+struct pptp_msg_ccrq {
+ u_int16_t call_id;
+ u_int16_t reserved1;
+};
+
+struct pptp_msg_cdn {
+ u_int16_t call_id;
+ u_int8_t result_code;
+ u_int8_t err_code;
+ u_int16_t cause_code;
+ u_int16_t reserved1;
+ u_char call_stats[128];
+};
+
+struct pptp_msg_wen {
+ u_int16_t peer_call_id;
+ u_int16_t reserved1;
+ u_int32_t crc_err;
+ u_int32_t framing_err;
+ u_int32_t hardware_overrun;
+ u_int32_t buffer_overrun;
+ u_int32_t timeout_err;
+ u_int32_t align_err;
+};
+
+struct pptp_msg_sli {
+ u_int16_t peer_call_id;
+ u_int16_t reserved1;
+ u_int32_t send_accm;
+ u_int32_t recv_accm;
+};
+
+/* attributes that appear more than once in above messages:
+
+ Number of
+ occurence attributes
+ --------------------------------------
+ 2 u_int32_t bearer_cap;
+ 2 u_int32_t bearer_type;
+ 6 u_int16_t call_id;
+ 2 u_int16_t call_ser;
+ 2 u_int16_t cause_code;
+ 2 u_int32_t conn_speed;
+ 6 u_int8_t err_code;
+ 2 u_int16_t firm_rev;
+ 2 u_int32_t framing_cap;
+ 2 u_int32_t framing_type;
+ 2 u_char hostname[64];
+ 2 u_int32_t id;
+ 2 u_int16_t max_channel;
+ 5 u_int16_t peer_call_id;
+ 2 u_int32_t phy_chan_id;
+ 4 u_int16_t pkt_proc_delay;
+ 2 u_int16_t proto_ver;
+ 4 u_int16_t recv_winsiz;
+ 2 u_int8_t reserved1;
+ 9 u_int16_t reserved1;
+ 6 u_int8_t result_code;
+ 2 u_char subaddr[64];
+ 2 u_char vendor[64];
+
+ so I will prepare print out functions for these attributes (except for
+ reserved*).
+*/
+
+/******************************************/
+/* Attribute-specific print out functions */
+/******************************************/
+
+/* In these attribute-specific print-out functions, it't not necessary
+ to do TCHECK because they are already checked in the caller of
+ these functions. */
+
+static void
+pptp_bearer_cap_print(const u_int32_t *bearer_cap)
+{
+ printf(" BEARER_CAP(");
+ if (EXTRACT_32BITS(bearer_cap) & PPTP_BEARER_CAP_DIGITAL_MASK) {
+ printf("D");
+ }
+ if (EXTRACT_32BITS(bearer_cap) & PPTP_BEARER_CAP_ANALOG_MASK) {
+ printf("A");
+ }
+ printf(")");
+}
+
+static void
+pptp_bearer_type_print(const u_int32_t *bearer_type)
+{
+ printf(" BEARER_TYPE(");
+ switch (EXTRACT_32BITS(bearer_type)) {
+ case 1:
+ printf("A"); /* Analog */
+ break;
+ case 2:
+ printf("D"); /* Digital */
+ break;
+ case 3:
+ printf("Any");
+ break;
+ default:
+ printf("?");
+ break;
+ }
+ printf(")");
+}
+
+static void
+pptp_call_id_print(const u_int16_t *call_id)
+{
+ printf(" CALL_ID(%u)", EXTRACT_16BITS(call_id));
+}
+
+static void
+pptp_call_ser_print(const u_int16_t *call_ser)
+{
+ printf(" CALL_SER_NUM(%u)", EXTRACT_16BITS(call_ser));
+}
+
+static void
+pptp_cause_code_print(const u_int16_t *cause_code)
+{
+ printf(" CAUSE_CODE(%u)", EXTRACT_16BITS(cause_code));
+}
+
+static void
+pptp_conn_speed_print(const u_int32_t *conn_speed)
+{
+ printf(" CONN_SPEED(%u)", EXTRACT_32BITS(conn_speed));
+}
+
+static void
+pptp_err_code_print(const u_int8_t *err_code)
+{
+ printf(" ERR_CODE(%u", *err_code);
+ if (vflag) {
+ switch (*err_code) {
+ case 0:
+ printf(":None");
+ break;
+ case 1:
+ printf(":Not-Connected");
+ break;
+ case 2:
+ printf(":Bad-Format");
+ break;
+ case 3:
+ printf(":Bad-Valude");
+ break;
+ case 4:
+ printf(":No-Resource");
+ break;
+ case 5:
+ printf(":Bad-Call-ID");
+ break;
+ case 6:
+ printf(":PAC-Error");
+ break;
+ default:
+ printf(":?");
+ break;
+ }
+ }
+ printf(")");
+}
+
+static void
+pptp_firm_rev_print(const u_int16_t *firm_rev)
+{
+ printf(" FIRM_REV(%u)", EXTRACT_16BITS(firm_rev));
+}
+
+static void
+pptp_framing_cap_print(const u_int32_t *framing_cap)
+{
+ printf(" FRAME_CAP(");
+ if (EXTRACT_32BITS(framing_cap) & PPTP_FRAMING_CAP_ASYNC_MASK) {
+ printf("A"); /* Async */
+ }
+ if (EXTRACT_32BITS(framing_cap) & PPTP_FRAMING_CAP_SYNC_MASK) {
+ printf("S"); /* Sync */
+ }
+ printf(")");
+}
+
+static void
+pptp_framing_type_print(const u_int32_t *framing_type)
+{
+ printf(" FRAME_TYPE(");
+ switch (EXTRACT_32BITS(framing_type)) {
+ case 1:
+ printf("A"); /* Async */
+ break;
+ case 2:
+ printf("S"); /* Sync */
+ break;
+ case 3:
+ printf("E"); /* Either */
+ break;
+ default:
+ printf("?");
+ break;
+ }
+ printf(")");
+}
+
+static void
+pptp_hostname_print(const u_char *hostname)
+{
+ printf(" HOSTNAME(%.64s)", hostname);
+}
+
+static void
+pptp_id_print(const u_int32_t *id)
+{
+ printf(" ID(%u)", EXTRACT_32BITS(id));
+}
+
+static void
+pptp_max_channel_print(const u_int16_t *max_channel)
+{
+ printf(" MAX_CHAN(%u)", EXTRACT_16BITS(max_channel));
+}
+
+static void
+pptp_peer_call_id_print(const u_int16_t *peer_call_id)
+{
+ printf(" PEER_CALL_ID(%u)", EXTRACT_16BITS(peer_call_id));
+}
+
+static void
+pptp_phy_chan_id_print(const u_int32_t *phy_chan_id)
+{
+ printf(" PHY_CHAN_ID(%u)", EXTRACT_32BITS(phy_chan_id));
+}
+
+static void
+pptp_pkt_proc_delay_print(const u_int16_t *pkt_proc_delay)
+{
+ printf(" PROC_DELAY(%u)", EXTRACT_16BITS(pkt_proc_delay));
+}
+
+static void
+pptp_proto_ver_print(const u_int16_t *proto_ver)
+{
+ printf(" PROTO_VER(%u.%u)", /* Version.Revision */
+ EXTRACT_16BITS(proto_ver) >> 8,
+ EXTRACT_16BITS(proto_ver) & 0xff);
+}
+
+static void
+pptp_recv_winsiz_print(const u_int16_t *recv_winsiz)
+{
+ printf(" RECV_WIN(%u)", EXTRACT_16BITS(recv_winsiz));
+}
+
+static void
+pptp_result_code_print(const u_int8_t *result_code, int ctrl_msg_type)
+{
+ printf(" RESULT_CODE(%u", *result_code);
+ if (vflag) {
+ switch (ctrl_msg_type) {
+ case PPTP_CTRL_MSG_TYPE_SCCRP:
+ switch (*result_code) {
+ case 1:
+ printf(":Successful channel establishment");
+ break;
+ case 2:
+ printf(":General error");
+ break;
+ case 3:
+ printf(":Command channel already exists");
+ break;
+ case 4:
+ printf(":Requester is not authorized to establish a command channel");
+ break;
+ case 5:
+ printf(":The protocol version of the requester is not supported");
+ break;
+ default:
+ printf(":?");
+ break;
+ }
+ break;
+ case PPTP_CTRL_MSG_TYPE_StopCCRP:
+ case PPTP_CTRL_MSG_TYPE_ECHORP:
+ switch (*result_code) {
+ case 1:
+ printf(":OK");
+ break;
+ case 2:
+ printf(":General Error");
+ break;
+ default:
+ printf(":?");
+ break;
+ }
+ break;
+ case PPTP_CTRL_MSG_TYPE_OCRP:
+ switch (*result_code) {
+ case 1:
+ printf(":Connected");
+ break;
+ case 2:
+ printf(":General Error");
+ break;
+ case 3:
+ printf(":No Carrier");
+ break;
+ case 4:
+ printf(":Busy");
+ break;
+ case 5:
+ printf(":No Dial Tone");
+ break;
+ case 6:
+ printf(":Time-out");
+ break;
+ case 7:
+ printf(":Do Not Accept");
+ break;
+ default:
+ printf(":?");
+ break;
+ }
+ break;
+ case PPTP_CTRL_MSG_TYPE_ICRP:
+ switch (*result_code) {
+ case 1:
+ printf(":Connect");
+ break;
+ case 2:
+ printf(":General Error");
+ break;
+ case 3:
+ printf(":Do Not Accept");
+ break;
+ default:
+ printf(":?");
+ break;
+ }
+ break;
+ case PPTP_CTRL_MSG_TYPE_CDN:
+ switch (*result_code) {
+ case 1:
+ printf(":Lost Carrier");
+ break;
+ case 2:
+ printf(":General Error");
+ break;
+ case 3:
+ printf(":Admin Shutdown");
+ break;
+ case 4:
+ printf(":Request");
+ default:
+ printf(":?");
+ break;
+ break;
+ }
+ default:
+ /* assertion error */
+ break;
+ }
+ }
+ printf(")");
+}
+
+static void
+pptp_subaddr_print(const u_char *subaddr)
+{
+ printf(" SUB_ADDR(%.64s)", subaddr);
+}
+
+static void
+pptp_vendor_print(const u_char *vendor)
+{
+ printf(" VENDOR(%.64s)", vendor);
+}
+
+/************************************/
+/* PPTP message print out functions */
+/************************************/
+static void
+pptp_sccrq_print(const u_char *dat)
+{
+ struct pptp_msg_sccrq *ptr = (struct pptp_msg_sccrq *)dat;
+
+ TCHECK(ptr->proto_ver);
+ pptp_proto_ver_print(&ptr->proto_ver);
+ TCHECK(ptr->reserved1);
+ TCHECK(ptr->framing_cap);
+ pptp_framing_cap_print(&ptr->framing_cap);
+ TCHECK(ptr->bearer_cap);
+ pptp_bearer_cap_print(&ptr->bearer_cap);
+ TCHECK(ptr->max_channel);
+ pptp_max_channel_print(&ptr->max_channel);
+ TCHECK(ptr->firm_rev);
+ pptp_firm_rev_print(&ptr->firm_rev);
+ TCHECK(ptr->hostname);
+ pptp_hostname_print(&ptr->hostname[0]);
+ TCHECK(ptr->vendor);
+ pptp_vendor_print(&ptr->vendor[0]);
+
+ return;
+
+trunc:
+ printf("%s", tstr);
+}
+
+static void
+pptp_sccrp_print(const u_char *dat)
+{
+ struct pptp_msg_sccrp *ptr = (struct pptp_msg_sccrp *)dat;
+
+ TCHECK(ptr->proto_ver);
+ pptp_proto_ver_print(&ptr->proto_ver);
+ TCHECK(ptr->result_code);
+ pptp_result_code_print(&ptr->result_code, PPTP_CTRL_MSG_TYPE_SCCRP);
+ TCHECK(ptr->err_code);
+ pptp_err_code_print(&ptr->err_code);
+ TCHECK(ptr->framing_cap);
+ pptp_framing_cap_print(&ptr->framing_cap);
+ TCHECK(ptr->bearer_cap);
+ pptp_bearer_cap_print(&ptr->bearer_cap);
+ TCHECK(ptr->max_channel);
+ pptp_max_channel_print(&ptr->max_channel);
+ TCHECK(ptr->firm_rev);
+ pptp_firm_rev_print(&ptr->firm_rev);
+ TCHECK(ptr->hostname);
+ pptp_hostname_print(&ptr->hostname[0]);
+ TCHECK(ptr->vendor);
+ pptp_vendor_print(&ptr->vendor[0]);
+
+ return;
+
+trunc:
+ printf("%s", tstr);
+}
+
+static void
+pptp_stopccrq_print(const u_char *dat)
+{
+ struct pptp_msg_stopccrq *ptr = (struct pptp_msg_stopccrq *)dat;
+
+ TCHECK(ptr->reason);
+ printf(" REASON(%u", ptr->reason);
+ if (vflag) {
+ switch (ptr->reason) {
+ case 1:
+ printf(":None");
+ break;
+ case 2:
+ printf(":Stop-Protocol");
+ break;
+ case 3:
+ printf(":Stop-Local-Shutdown");
+ break;
+ default:
+ printf(":?");
+ break;
+ }
+ }
+ printf(")");
+ TCHECK(ptr->reserved1);
+ TCHECK(ptr->reserved2);
+
+ return;
+
+trunc:
+ printf("%s", tstr);
+}
+
+static void
+pptp_stopccrp_print(const u_char *dat)
+{
+ struct pptp_msg_stopccrp *ptr = (struct pptp_msg_stopccrp *)dat;
+
+ TCHECK(ptr->result_code);
+ pptp_result_code_print(&ptr->result_code, PPTP_CTRL_MSG_TYPE_StopCCRP);
+ TCHECK(ptr->err_code);
+ pptp_err_code_print(&ptr->err_code);
+ TCHECK(ptr->reserved1);
+
+ return;
+
+trunc:
+ printf("%s", tstr);
+}
+
+static void
+pptp_echorq_print(const u_char *dat)
+{
+ struct pptp_msg_echorq *ptr = (struct pptp_msg_echorq *)dat;
+
+ TCHECK(ptr->id);
+ pptp_id_print(&ptr->id);
+
+ return;
+
+trunc:
+ printf("%s", tstr);
+}
+
+static void
+pptp_echorp_print(const u_char *dat)
+{
+ struct pptp_msg_echorp *ptr = (struct pptp_msg_echorp *)dat;
+
+ TCHECK(ptr->id);
+ pptp_id_print(&ptr->id);
+ TCHECK(ptr->result_code);
+ pptp_result_code_print(&ptr->result_code, PPTP_CTRL_MSG_TYPE_ECHORP);
+ TCHECK(ptr->err_code);
+ pptp_err_code_print(&ptr->err_code);
+ TCHECK(ptr->reserved1);
+
+ return;
+
+trunc:
+ printf("%s", tstr);
+}
+
+static void
+pptp_ocrq_print(const u_char *dat)
+{
+ struct pptp_msg_ocrq *ptr = (struct pptp_msg_ocrq *)dat;
+
+ TCHECK(ptr->call_id);
+ pptp_call_id_print(&ptr->call_id);
+ TCHECK(ptr->call_ser);
+ pptp_call_ser_print(&ptr->call_ser);
+ TCHECK(ptr->min_bps);
+ printf(" MIN_BPS(%u)", EXTRACT_32BITS(&ptr->min_bps));
+ TCHECK(ptr->max_bps);
+ printf(" MAX_BPS(%u)", EXTRACT_32BITS(&ptr->max_bps));
+ TCHECK(ptr->bearer_type);
+ pptp_bearer_type_print(&ptr->bearer_type);
+ TCHECK(ptr->framing_type);
+ pptp_framing_type_print(&ptr->framing_type);
+ TCHECK(ptr->recv_winsiz);
+ pptp_recv_winsiz_print(&ptr->recv_winsiz);
+ TCHECK(ptr->pkt_proc_delay);
+ pptp_pkt_proc_delay_print(&ptr->pkt_proc_delay);
+ TCHECK(ptr->phone_no_len);
+ printf(" PHONE_NO_LEN(%u)", EXTRACT_16BITS(&ptr->phone_no_len));
+ TCHECK(ptr->reserved1);
+ TCHECK(ptr->phone_no);
+ printf(" PHONE_NO(%.64s)", ptr->phone_no);
+ TCHECK(ptr->subaddr);
+ pptp_subaddr_print(&ptr->subaddr[0]);
+
+ return;
+
+trunc:
+ printf("%s", tstr);
+}
+
+static void
+pptp_ocrp_print(const u_char *dat)
+{
+ struct pptp_msg_ocrp *ptr = (struct pptp_msg_ocrp *)dat;
+
+ TCHECK(ptr->call_id);
+ pptp_call_id_print(&ptr->call_id);
+ TCHECK(ptr->peer_call_id);
+ pptp_peer_call_id_print(&ptr->peer_call_id);
+ TCHECK(ptr->result_code);
+ pptp_result_code_print(&ptr->result_code, PPTP_CTRL_MSG_TYPE_OCRP);
+ TCHECK(ptr->err_code);
+ pptp_err_code_print(&ptr->err_code);
+ TCHECK(ptr->cause_code);
+ pptp_cause_code_print(&ptr->cause_code);
+ TCHECK(ptr->conn_speed);
+ pptp_conn_speed_print(&ptr->conn_speed);
+ TCHECK(ptr->recv_winsiz);
+ pptp_recv_winsiz_print(&ptr->recv_winsiz);
+ TCHECK(ptr->pkt_proc_delay);
+ pptp_pkt_proc_delay_print(&ptr->pkt_proc_delay);
+ TCHECK(ptr->phy_chan_id);
+ pptp_phy_chan_id_print(&ptr->phy_chan_id);
+
+ return;
+
+trunc:
+ printf("%s", tstr);
+}
+
+static void
+pptp_icrq_print(const u_char *dat)
+{
+ struct pptp_msg_icrq *ptr = (struct pptp_msg_icrq *)dat;
+
+ TCHECK(ptr->call_id);
+ pptp_call_id_print(&ptr->call_id);
+ TCHECK(ptr->call_ser);
+ pptp_call_ser_print(&ptr->call_ser);
+ TCHECK(ptr->bearer_type);
+ pptp_bearer_type_print(&ptr->bearer_type);
+ TCHECK(ptr->phy_chan_id);
+ pptp_phy_chan_id_print(&ptr->phy_chan_id);
+ TCHECK(ptr->dialed_no_len);
+ printf(" DIALED_NO_LEN(%u)", EXTRACT_16BITS(&ptr->dialed_no_len));
+ TCHECK(ptr->dialing_no_len);
+ printf(" DIALING_NO_LEN(%u)", EXTRACT_16BITS(&ptr->dialing_no_len));
+ TCHECK(ptr->dialed_no);
+ printf(" DIALED_NO(%.64s)", ptr->dialed_no);
+ TCHECK(ptr->dialing_no);
+ printf(" DIALING_NO(%.64s)", ptr->dialing_no);
+ TCHECK(ptr->subaddr);
+ pptp_subaddr_print(&ptr->subaddr[0]);
+
+ return;
+
+trunc:
+ printf("%s", tstr);
+}
+
+static void
+pptp_icrp_print(const u_char *dat)
+{
+ struct pptp_msg_icrp *ptr = (struct pptp_msg_icrp *)dat;
+
+ TCHECK(ptr->call_id);
+ pptp_call_id_print(&ptr->call_id);
+ TCHECK(ptr->peer_call_id);
+ pptp_peer_call_id_print(&ptr->peer_call_id);
+ TCHECK(ptr->result_code);
+ pptp_result_code_print(&ptr->result_code, PPTP_CTRL_MSG_TYPE_ICRP);
+ TCHECK(ptr->err_code);
+ pptp_err_code_print(&ptr->err_code);
+ TCHECK(ptr->recv_winsiz);
+ pptp_recv_winsiz_print(&ptr->recv_winsiz);
+ TCHECK(ptr->pkt_proc_delay);
+ pptp_pkt_proc_delay_print(&ptr->pkt_proc_delay);
+ TCHECK(ptr->reserved1);
+
+ return;
+
+trunc:
+ printf("%s", tstr);
+}
+
+static void
+pptp_iccn_print(const u_char *dat)
+{
+ struct pptp_msg_iccn *ptr = (struct pptp_msg_iccn *)dat;
+
+ TCHECK(ptr->peer_call_id);
+ pptp_peer_call_id_print(&ptr->peer_call_id);
+ TCHECK(ptr->reserved1);
+ TCHECK(ptr->conn_speed);
+ pptp_conn_speed_print(&ptr->conn_speed);
+ TCHECK(ptr->recv_winsiz);
+ pptp_recv_winsiz_print(&ptr->recv_winsiz);
+ TCHECK(ptr->pkt_proc_delay);
+ pptp_pkt_proc_delay_print(&ptr->pkt_proc_delay);
+ TCHECK(ptr->framing_type);
+ pptp_framing_type_print(&ptr->framing_type);
+
+ return;
+
+trunc:
+ printf("%s", tstr);
+}
+
+static void
+pptp_ccrq_print(const u_char *dat)
+{
+ struct pptp_msg_ccrq *ptr = (struct pptp_msg_ccrq *)dat;
+
+ TCHECK(ptr->call_id);
+ pptp_call_id_print(&ptr->call_id);
+ TCHECK(ptr->reserved1);
+
+ return;
+
+trunc:
+ printf("%s", tstr);
+}
+
+static void
+pptp_cdn_print(const u_char *dat)
+{
+ struct pptp_msg_cdn *ptr = (struct pptp_msg_cdn *)dat;
+
+ TCHECK(ptr->call_id);
+ pptp_call_id_print(&ptr->call_id);
+ TCHECK(ptr->result_code);
+ pptp_result_code_print(&ptr->result_code, PPTP_CTRL_MSG_TYPE_CDN);
+ TCHECK(ptr->err_code);
+ pptp_err_code_print(&ptr->err_code);
+ TCHECK(ptr->cause_code);
+ pptp_cause_code_print(&ptr->cause_code);
+ TCHECK(ptr->reserved1);
+ TCHECK(ptr->call_stats);
+ printf(" CALL_STATS(%.128s)", ptr->call_stats);
+
+ return;
+
+trunc:
+ printf("%s", tstr);
+}
+
+static void
+pptp_wen_print(const u_char *dat)
+{
+ struct pptp_msg_wen *ptr = (struct pptp_msg_wen *)dat;
+
+ TCHECK(ptr->peer_call_id);
+ pptp_peer_call_id_print(&ptr->peer_call_id);
+ TCHECK(ptr->reserved1);
+ TCHECK(ptr->crc_err);
+ printf(" CRC_ERR(%u)", EXTRACT_32BITS(&ptr->crc_err));
+ TCHECK(ptr->framing_err);
+ printf(" FRAMING_ERR(%u)", EXTRACT_32BITS(&ptr->framing_err));
+ TCHECK(ptr->hardware_overrun);
+ printf(" HARDWARE_OVERRUN(%u)", EXTRACT_32BITS(&ptr->hardware_overrun));
+ TCHECK(ptr->buffer_overrun);
+ printf(" BUFFER_OVERRUN(%u)", EXTRACT_32BITS(&ptr->buffer_overrun));
+ TCHECK(ptr->timeout_err);
+ printf(" TIMEOUT_ERR(%u)", EXTRACT_32BITS(&ptr->timeout_err));
+ TCHECK(ptr->align_err);
+ printf(" ALIGN_ERR(%u)", EXTRACT_32BITS(&ptr->align_err));
+
+ return;
+
+trunc:
+ printf("%s", tstr);
+}
+
+static void
+pptp_sli_print(const u_char *dat)
+{
+ struct pptp_msg_sli *ptr = (struct pptp_msg_sli *)dat;
+
+ TCHECK(ptr->peer_call_id);
+ pptp_peer_call_id_print(&ptr->peer_call_id);
+ TCHECK(ptr->reserved1);
+ TCHECK(ptr->send_accm);
+ printf(" SEND_ACCM(0x%08x)", EXTRACT_32BITS(&ptr->send_accm));
+ TCHECK(ptr->recv_accm);
+ printf(" RECV_ACCM(0x%08x)", EXTRACT_32BITS(&ptr->recv_accm));
+
+ return;
+
+trunc:
+ printf("%s", tstr);
+}
+
+void
+pptp_print(const u_char *dat)
+{
+ const struct pptp_hdr *hdr;
+ u_int32_t mc;
+ u_int16_t ctrl_msg_type;
+
+ printf(": pptp");
+
+ hdr = (struct pptp_hdr *)dat;
+
+ TCHECK(hdr->length);
+ if (vflag) {
+ printf(" Length=%u", EXTRACT_16BITS(&hdr->length));
+ }
+ TCHECK(hdr->msg_type);
+ if (vflag) {
+ switch(EXTRACT_16BITS(&hdr->msg_type)) {
+ case PPTP_MSG_TYPE_CTRL:
+ printf(" CTRL-MSG");
+ break;
+ case PPTP_MSG_TYPE_MGMT:
+ printf(" MGMT-MSG");
+ break;
+ default:
+ printf(" UNKNOWN-MSG-TYPE");
+ break;
+ }
+ }
+
+ TCHECK(hdr->magic_cookie);
+ mc = EXTRACT_32BITS(&hdr->magic_cookie);
+ if (mc != PPTP_MAGIC_COOKIE) {
+ printf(" UNEXPECTED Magic-Cookie!!(%08x)", mc);
+ }
+ if (vflag || mc != PPTP_MAGIC_COOKIE) {
+ printf(" Magic-Cookie=%08x", mc);
+ }
+ TCHECK(hdr->ctrl_msg_type);
+ ctrl_msg_type = EXTRACT_16BITS(&hdr->ctrl_msg_type);
+ if (ctrl_msg_type < PPTP_MAX_MSGTYPE_INDEX) {
+ printf(" CTRL_MSGTYPE=%s",
+ pptp_message_type_string[ctrl_msg_type]);
+ } else {
+ printf(" UNKNOWN_CTRL_MSGTYPE(%u)", ctrl_msg_type);
+ }
+ TCHECK(hdr->reserved0);
+
+ dat += 12;
+
+ switch(ctrl_msg_type) {
+ case PPTP_CTRL_MSG_TYPE_SCCRQ:
+ pptp_sccrq_print(dat);
+ break;
+ case PPTP_CTRL_MSG_TYPE_SCCRP:
+ pptp_sccrp_print(dat);
+ break;
+ case PPTP_CTRL_MSG_TYPE_StopCCRQ:
+ pptp_stopccrq_print(dat);
+ break;
+ case PPTP_CTRL_MSG_TYPE_StopCCRP:
+ pptp_stopccrp_print(dat);
+ break;
+ case PPTP_CTRL_MSG_TYPE_ECHORQ:
+ pptp_echorq_print(dat);
+ break;
+ case PPTP_CTRL_MSG_TYPE_ECHORP:
+ pptp_echorp_print(dat);
+ break;
+ case PPTP_CTRL_MSG_TYPE_OCRQ:
+ pptp_ocrq_print(dat);
+ break;
+ case PPTP_CTRL_MSG_TYPE_OCRP:
+ pptp_ocrp_print(dat);
+ break;
+ case PPTP_CTRL_MSG_TYPE_ICRQ:
+ pptp_icrq_print(dat);
+ break;
+ case PPTP_CTRL_MSG_TYPE_ICRP:
+ pptp_icrp_print(dat);
+ break;
+ case PPTP_CTRL_MSG_TYPE_ICCN:
+ pptp_iccn_print(dat);
+ break;
+ case PPTP_CTRL_MSG_TYPE_CCRQ:
+ pptp_ccrq_print(dat);
+ break;
+ case PPTP_CTRL_MSG_TYPE_CDN:
+ pptp_cdn_print(dat);
+ break;
+ case PPTP_CTRL_MSG_TYPE_WEN:
+ pptp_wen_print(dat);
+ break;
+ case PPTP_CTRL_MSG_TYPE_SLI:
+ pptp_sli_print(dat);
+ break;
+ default:
+ /* do nothing */
+ break;
+ }
+
+ return;
+
+trunc:
+ printf("%s", tstr);
+}
diff --git a/freebsd/contrib/tcpdump/print-radius.c b/freebsd/contrib/tcpdump/print-radius.c
new file mode 100644
index 00000000..3ae0a4b1
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-radius.c
@@ -0,0 +1,939 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) 2000 Alfredo Andres Omella. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. The names of the authors may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+/*
+ * Radius printer routines as specified on:
+ *
+ * RFC 2865:
+ * "Remote Authentication Dial In User Service (RADIUS)"
+ *
+ * RFC 2866:
+ * "RADIUS Accounting"
+ *
+ * RFC 2867:
+ * "RADIUS Accounting Modifications for Tunnel Protocol Support"
+ *
+ * RFC 2868:
+ * "RADIUS Attributes for Tunnel Protocol Support"
+ *
+ * RFC 2869:
+ * "RADIUS Extensions"
+ *
+ * Alfredo Andres Omella (aandres@s21sec.com) v0.1 2000/09/15
+ *
+ * TODO: Among other things to print ok MacIntosh and Vendor values
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "$Id: print-radius.c,v 1.28 2005-09-26 01:01:55 guy Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <string.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+#include "oui.h"
+
+#define TAM_SIZE(x) (sizeof(x)/sizeof(x[0]) )
+
+#define PRINT_HEX(bytes_len, ptr_data) \
+ while(bytes_len) \
+ { \
+ printf("%02X", *ptr_data ); \
+ ptr_data++; \
+ bytes_len--; \
+ }
+
+
+/* Radius packet codes */
+#define RADCMD_ACCESS_REQ 1 /* Access-Request */
+#define RADCMD_ACCESS_ACC 2 /* Access-Accept */
+#define RADCMD_ACCESS_REJ 3 /* Access-Reject */
+#define RADCMD_ACCOUN_REQ 4 /* Accounting-Request */
+#define RADCMD_ACCOUN_RES 5 /* Accounting-Response */
+#define RADCMD_ACCESS_CHA 11 /* Access-Challenge */
+#define RADCMD_STATUS_SER 12 /* Status-Server */
+#define RADCMD_STATUS_CLI 13 /* Status-Client */
+#define RADCMD_RESERVED 255 /* Reserved */
+
+static struct tok radius_command_values[] = {
+ { RADCMD_ACCESS_REQ, "Access Request" },
+ { RADCMD_ACCESS_ACC, "Access Accept" },
+ { RADCMD_ACCESS_REJ, "Access Reject" },
+ { RADCMD_ACCOUN_REQ, "Accounting Request" },
+ { RADCMD_ACCOUN_RES, "Accounting Response" },
+ { RADCMD_ACCESS_CHA, "Access Challenge" },
+ { RADCMD_STATUS_SER, "Status Server" },
+ { RADCMD_STATUS_CLI, "Status Client" },
+ { RADCMD_RESERVED, "Reserved" },
+ { 0, NULL}
+};
+
+/********************************/
+/* Begin Radius Attribute types */
+/********************************/
+#define SERV_TYPE 6
+#define FRM_IPADDR 8
+#define LOG_IPHOST 14
+#define LOG_SERVICE 15
+#define FRM_IPX 23
+#define SESSION_TIMEOUT 27
+#define IDLE_TIMEOUT 28
+#define FRM_ATALK_LINK 37
+#define FRM_ATALK_NETWORK 38
+
+#define ACCT_DELAY 41
+#define ACCT_SESSION_TIME 46
+
+#define TUNNEL_TYPE 64
+#define TUNNEL_MEDIUM 65
+#define TUNNEL_CLIENT_END 66
+#define TUNNEL_SERVER_END 67
+#define TUNNEL_PASS 69
+
+#define ARAP_PASS 70
+#define ARAP_FEATURES 71
+
+#define TUNNEL_PRIV_GROUP 81
+#define TUNNEL_ASSIGN_ID 82
+#define TUNNEL_PREFERENCE 83
+
+#define ARAP_CHALLENGE_RESP 84
+#define ACCT_INT_INTERVAL 85
+
+#define TUNNEL_CLIENT_AUTH 90
+#define TUNNEL_SERVER_AUTH 91
+/********************************/
+/* End Radius Attribute types */
+/********************************/
+
+
+static void print_attr_string(register u_char *, u_int, u_short );
+static void print_attr_num(register u_char *, u_int, u_short );
+static void print_vendor_attr(register u_char *, u_int, u_short );
+static void print_attr_address(register u_char *, u_int, u_short);
+static void print_attr_time(register u_char *, u_int, u_short);
+static void print_attr_strange(register u_char *, u_int, u_short);
+
+
+struct radius_hdr { u_int8_t code; /* Radius packet code */
+ u_int8_t id; /* Radius packet id */
+ u_int16_t len; /* Radius total length */
+ u_int8_t auth[16]; /* Authenticator */
+ };
+
+#define MIN_RADIUS_LEN 20
+
+struct radius_attr { u_int8_t type; /* Attribute type */
+ u_int8_t len; /* Attribute length */
+ };
+
+
+/* Service-Type Attribute standard values */
+static const char *serv_type[]={ NULL,
+ "Login",
+ "Framed",
+ "Callback Login",
+ "Callback Framed",
+ "Outbound",
+ "Administrative",
+ "NAS Prompt",
+ "Authenticate Only",
+ "Callback NAS Prompt",
+ "Call Check",
+ "Callback Administrative",
+ };
+
+/* Framed-Protocol Attribute standard values */
+static const char *frm_proto[]={ NULL,
+ "PPP",
+ "SLIP",
+ "ARAP",
+ "Gandalf proprietary",
+ "Xylogics IPX/SLIP",
+ "X.75 Synchronous",
+ };
+
+/* Framed-Routing Attribute standard values */
+static const char *frm_routing[]={ "None",
+ "Send",
+ "Listen",
+ "Send&Listen",
+ };
+
+/* Framed-Compression Attribute standard values */
+static const char *frm_comp[]={ "None",
+ "VJ TCP/IP",
+ "IPX",
+ "Stac-LZS",
+ };
+
+/* Login-Service Attribute standard values */
+static const char *login_serv[]={ "Telnet",
+ "Rlogin",
+ "TCP Clear",
+ "PortMaster(proprietary)",
+ "LAT",
+ "X.25-PAD",
+ "X.25-T3POS",
+ "Unassigned",
+ "TCP Clear Quiet",
+ };
+
+
+/* Termination-Action Attribute standard values */
+static const char *term_action[]={ "Default",
+ "RADIUS-Request",
+ };
+
+/* NAS-Port-Type Attribute standard values */
+static const char *nas_port_type[]={ "Async",
+ "Sync",
+ "ISDN Sync",
+ "ISDN Async V.120",
+ "ISDN Async V.110",
+ "Virtual",
+ "PIAFS",
+ "HDLC Clear Channel",
+ "X.25",
+ "X.75",
+ "G.3 Fax",
+ "SDSL",
+ "ADSL-CAP",
+ "ADSL-DMT",
+ "ISDN-DSL",
+ "Ethernet",
+ "xDSL",
+ "Cable",
+ "Wireless - Other",
+ "Wireless - IEEE 802.11",
+ };
+
+/* Acct-Status-Type Accounting Attribute standard values */
+static const char *acct_status[]={ NULL,
+ "Start",
+ "Stop",
+ "Interim-Update",
+ "Unassigned",
+ "Unassigned",
+ "Unassigned",
+ "Accounting-On",
+ "Accounting-Off",
+ "Tunnel-Start",
+ "Tunnel-Stop",
+ "Tunnel-Reject",
+ "Tunnel-Link-Start",
+ "Tunnel-Link-Stop",
+ "Tunnel-Link-Reject",
+ "Failed",
+ };
+
+/* Acct-Authentic Accounting Attribute standard values */
+static const char *acct_auth[]={ NULL,
+ "RADIUS",
+ "Local",
+ "Remote",
+ };
+
+/* Acct-Terminate-Cause Accounting Attribute standard values */
+static const char *acct_term[]={ NULL,
+ "User Request",
+ "Lost Carrier",
+ "Lost Service",
+ "Idle Timeout",
+ "Session Timeout",
+ "Admin Reset",
+ "Admin Reboot",
+ "Port Error",
+ "NAS Error",
+ "NAS Request",
+ "NAS Reboot",
+ "Port Unneeded",
+ "Port Preempted",
+ "Port Suspended",
+ "Service Unavailable",
+ "Callback",
+ "User Error",
+ "Host Request",
+ };
+
+/* Tunnel-Type Attribute standard values */
+static const char *tunnel_type[]={ NULL,
+ "PPTP",
+ "L2F",
+ "L2TP",
+ "ATMP",
+ "VTP",
+ "AH",
+ "IP-IP",
+ "MIN-IP-IP",
+ "ESP",
+ "GRE",
+ "DVS",
+ "IP-in-IP Tunneling",
+ };
+
+/* Tunnel-Medium-Type Attribute standard values */
+static const char *tunnel_medium[]={ NULL,
+ "IPv4",
+ "IPv6",
+ "NSAP",
+ "HDLC",
+ "BBN 1822",
+ "802",
+ "E.163",
+ "E.164",
+ "F.69",
+ "X.121",
+ "IPX",
+ "Appletalk",
+ "Decnet IV",
+ "Banyan Vines",
+ "E.164 with NSAP subaddress",
+ };
+
+/* ARAP-Zone-Access Attribute standard values */
+static const char *arap_zone[]={ NULL,
+ "Only access to dfl zone",
+ "Use zone filter inc.",
+ "Not used",
+ "Use zone filter exc.",
+ };
+
+static const char *prompt[]={ "No Echo",
+ "Echo",
+ };
+
+
+struct attrtype { const char *name; /* Attribute name */
+ const char **subtypes; /* Standard Values (if any) */
+ u_char siz_subtypes; /* Size of total standard values */
+ u_char first_subtype; /* First standard value is 0 or 1 */
+ void (*print_func)(register u_char *, u_int, u_short );
+ } attr_type[]=
+ {
+ { NULL, NULL, 0, 0, NULL },
+ { "Username", NULL, 0, 0, print_attr_string },
+ { "Password", NULL, 0, 0, NULL },
+ { "CHAP Password", NULL, 0, 0, NULL },
+ { "NAS IP Address", NULL, 0, 0, print_attr_address },
+ { "NAS Port", NULL, 0, 0, print_attr_num },
+ { "Service Type", serv_type, TAM_SIZE(serv_type)-1, 1, print_attr_num },
+ { "Framed Protocol", frm_proto, TAM_SIZE(frm_proto)-1, 1, print_attr_num },
+ { "Framed IP Address", NULL, 0, 0, print_attr_address },
+ { "Framed IP Network", NULL, 0, 0, print_attr_address },
+ { "Framed Routing", frm_routing, TAM_SIZE(frm_routing), 0, print_attr_num },
+ { "Filter ID", NULL, 0, 0, print_attr_string },
+ { "Framed MTU", NULL, 0, 0, print_attr_num },
+ { "Framed Compression", frm_comp, TAM_SIZE(frm_comp), 0, print_attr_num },
+ { "Login IP Host", NULL, 0, 0, print_attr_address },
+ { "Login Service", login_serv, TAM_SIZE(login_serv), 0, print_attr_num },
+ { "Login TCP Port", NULL, 0, 0, print_attr_num },
+ { "Unassigned", NULL, 0, 0, NULL }, /*17*/
+ { "Reply", NULL, 0, 0, print_attr_string },
+ { "Callback-number", NULL, 0, 0, print_attr_string },
+ { "Callback-ID", NULL, 0, 0, print_attr_string },
+ { "Unassigned", NULL, 0, 0, NULL }, /*21*/
+ { "Framed Route", NULL, 0, 0, print_attr_string },
+ { "Framed IPX Network", NULL, 0, 0, print_attr_num },
+ { "State", NULL, 0, 0, print_attr_string },
+ { "Class", NULL, 0, 0, print_attr_string },
+ { "Vendor Specific", NULL, 0, 0, print_vendor_attr },
+ { "Session Timeout", NULL, 0, 0, print_attr_num },
+ { "Idle Timeout", NULL, 0, 0, print_attr_num },
+ { "Termination Action", term_action, TAM_SIZE(term_action), 0, print_attr_num },
+ { "Called Station", NULL, 0, 0, print_attr_string },
+ { "Calling Station", NULL, 0, 0, print_attr_string },
+ { "NAS ID", NULL, 0, 0, print_attr_string },
+ { "Proxy State", NULL, 0, 0, print_attr_string },
+ { "Login LAT Service", NULL, 0, 0, print_attr_string },
+ { "Login LAT Node", NULL, 0, 0, print_attr_string },
+ { "Login LAT Group", NULL, 0, 0, print_attr_string },
+ { "Framed Appletalk Link", NULL, 0, 0, print_attr_num },
+ { "Framed Appltalk Net", NULL, 0, 0, print_attr_num },
+ { "Framed Appletalk Zone", NULL, 0, 0, print_attr_string },
+ { "Accounting Status", acct_status, TAM_SIZE(acct_status)-1, 1, print_attr_num },
+ { "Accounting Delay", NULL, 0, 0, print_attr_num },
+ { "Accounting Input Octets", NULL, 0, 0, print_attr_num },
+ { "Accounting Output Octets", NULL, 0, 0, print_attr_num },
+ { "Accounting Session ID", NULL, 0, 0, print_attr_string },
+ { "Accounting Authentication", acct_auth, TAM_SIZE(acct_auth)-1, 1, print_attr_num },
+ { "Accounting Session Time", NULL, 0, 0, print_attr_num },
+ { "Accounting Input Packets", NULL, 0, 0, print_attr_num },
+ { "Accounting Output Packets", NULL, 0, 0, print_attr_num },
+ { "Accounting Termination Cause", acct_term, TAM_SIZE(acct_term)-1, 1, print_attr_num },
+ { "Accounting Multilink Session ID", NULL, 0, 0, print_attr_string },
+ { "Accounting Link Count", NULL, 0, 0, print_attr_num },
+ { "Accounting Input Giga", NULL, 0, 0, print_attr_num },
+ { "Accounting Output Giga", NULL, 0, 0, print_attr_num },
+ { "Unassigned", NULL, 0, 0, NULL }, /*54*/
+ { "Event Timestamp", NULL, 0, 0, print_attr_time },
+ { "Unassigned", NULL, 0, 0, NULL }, /*56*/
+ { "Unassigned", NULL, 0, 0, NULL }, /*57*/
+ { "Unassigned", NULL, 0, 0, NULL }, /*58*/
+ { "Unassigned", NULL, 0, 0, NULL }, /*59*/
+ { "CHAP challenge", NULL, 0, 0, print_attr_string },
+ { "NAS Port Type", nas_port_type, TAM_SIZE(nas_port_type), 0, print_attr_num },
+ { "Port Limit", NULL, 0, 0, print_attr_num },
+ { "Login LAT Port", NULL, 0, 0, print_attr_string }, /*63*/
+ { "Tunnel Type", tunnel_type, TAM_SIZE(tunnel_type)-1, 1, print_attr_num },
+ { "Tunnel Medium", tunnel_medium, TAM_SIZE(tunnel_medium)-1, 1, print_attr_num },
+ { "Tunnel Client End", NULL, 0, 0, print_attr_string },
+ { "Tunnel Server End", NULL, 0, 0, print_attr_string },
+ { "Accounting Tunnel connect", NULL, 0, 0, print_attr_string },
+ { "Tunnel Password", NULL, 0, 0, print_attr_string },
+ { "ARAP Password", NULL, 0, 0, print_attr_strange },
+ { "ARAP Feature", NULL, 0, 0, print_attr_strange },
+ { "ARAP Zone Acces", arap_zone, TAM_SIZE(arap_zone)-1, 1, print_attr_num }, /*72*/
+ { "ARAP Security", NULL, 0, 0, print_attr_string },
+ { "ARAP Security Data", NULL, 0, 0, print_attr_string },
+ { "Password Retry", NULL, 0, 0, print_attr_num },
+ { "Prompt", prompt, TAM_SIZE(prompt), 0, print_attr_num },
+ { "Connect Info", NULL, 0, 0, print_attr_string },
+ { "Config Token", NULL, 0, 0, print_attr_string },
+ { "EAP Message", NULL, 0, 0, print_attr_string },
+ { "Message Authentication", NULL, 0, 0, print_attr_string }, /*80*/
+ { "Tunnel Private Group", NULL, 0, 0, print_attr_string },
+ { "Tunnel Assigned ID", NULL, 0, 0, print_attr_string },
+ { "Tunnel Preference", NULL, 0, 0, print_attr_num },
+ { "ARAP Challenge Response", NULL, 0, 0, print_attr_strange },
+ { "Accounting Interim Interval", NULL, 0, 0, print_attr_num },
+ { "Accounting Tunnel packets lost", NULL, 0, 0, print_attr_num }, /*86*/
+ { "NAS Port ID", NULL, 0, 0, print_attr_string },
+ { "Framed Pool", NULL, 0, 0, print_attr_string },
+ { "Unassigned", NULL, 0, 0, NULL },
+ { "Tunnel Client Authentication ID", NULL, 0, 0, print_attr_string },
+ { "Tunnel Server Authentication ID", NULL, 0, 0, print_attr_string },
+ { "Unassigned", NULL, 0, 0, NULL }, /*92*/
+ { "Unassigned", NULL, 0, 0, NULL } /*93*/
+ };
+
+
+/*****************************/
+/* Print an attribute string */
+/* value pointed by 'data' */
+/* and 'length' size. */
+/*****************************/
+/* Returns nothing. */
+/*****************************/
+static void
+print_attr_string(register u_char *data, u_int length, u_short attr_code )
+{
+ register u_int i;
+
+ TCHECK2(data[0],length);
+
+ switch(attr_code)
+ {
+ case TUNNEL_PASS:
+ if (length < 3)
+ {
+ printf(" [|radius]");
+ return;
+ }
+ if (*data && (*data <=0x1F) )
+ printf("Tag %u, ",*data);
+ data++;
+ length--;
+ printf("Salt %u ",EXTRACT_16BITS(data) );
+ data+=2;
+ length-=2;
+ break;
+ case TUNNEL_CLIENT_END:
+ case TUNNEL_SERVER_END:
+ case TUNNEL_PRIV_GROUP:
+ case TUNNEL_ASSIGN_ID:
+ case TUNNEL_CLIENT_AUTH:
+ case TUNNEL_SERVER_AUTH:
+ if (*data <= 0x1F)
+ {
+ if (length < 1)
+ {
+ printf(" [|radius]");
+ return;
+ }
+ printf("Tag %u",*data);
+ data++;
+ length--;
+ }
+ break;
+ }
+
+ for (i=0; *data && i < length ; i++, data++)
+ printf("%c",(*data < 32 || *data > 128) ? '.' : *data );
+
+ return;
+
+ trunc:
+ printf(" [|radius]");
+}
+
+/*
+ * print vendor specific attributes
+ */
+
+static void
+print_vendor_attr(register u_char *data, u_int length, u_short attr_code _U_)
+{
+ u_int idx;
+ u_int vendor_id;
+ u_int vendor_type;
+ u_int vendor_length;
+
+ if (length < 4)
+ goto trunc;
+ TCHECK2(*data, 4);
+ vendor_id = EXTRACT_32BITS(data);
+ data+=4;
+ length-=4;
+
+ printf("Vendor: %s (%u)",
+ tok2str(smi_values,"Unknown",vendor_id),
+ vendor_id);
+
+ while (length >= 2) {
+ TCHECK2(*data, 2);
+
+ vendor_type = *(data);
+ vendor_length = *(data+1);
+
+ if (vendor_length < 2)
+ {
+ printf("\n\t Vendor Attribute: %u, Length: %u (bogus, must be >= 2)",
+ vendor_type,
+ vendor_length);
+ return;
+ }
+ if (vendor_length > length)
+ {
+ printf("\n\t Vendor Attribute: %u, Length: %u (bogus, goes past end of vendor-specific attribute)",
+ vendor_type,
+ vendor_length);
+ return;
+ }
+ data+=2;
+ vendor_length-=2;
+ length-=2;
+ TCHECK2(*data, vendor_length);
+
+ printf("\n\t Vendor Attribute: %u, Length: %u, Value: ",
+ vendor_type,
+ vendor_length);
+ for (idx = 0; idx < vendor_length ; idx++, data++)
+ printf("%c",(*data < 32 || *data > 128) ? '.' : *data );
+ length-=vendor_length;
+ }
+ return;
+
+ trunc:
+ printf(" [|radius]");
+}
+
+
+
+/******************************/
+/* Print an attribute numeric */
+/* value pointed by 'data' */
+/* and 'length' size. */
+/******************************/
+/* Returns nothing. */
+/******************************/
+static void
+print_attr_num(register u_char *data, u_int length, u_short attr_code )
+{
+ u_int8_t tag;
+ u_int32_t timeout;
+
+ if (length != 4)
+ {
+ printf("ERROR: length %u != 4", length);
+ return;
+ }
+
+ TCHECK2(data[0],4);
+ /* This attribute has standard values */
+ if (attr_type[attr_code].siz_subtypes)
+ {
+ static const char **table;
+ u_int32_t data_value;
+ table = attr_type[attr_code].subtypes;
+
+ if ( (attr_code == TUNNEL_TYPE) || (attr_code == TUNNEL_MEDIUM) )
+ {
+ if (!*data)
+ printf("Tag[Unused]");
+ else
+ printf("Tag[%d]", *data);
+ data++;
+ data_value = EXTRACT_24BITS(data);
+ }
+ else
+ {
+ data_value = EXTRACT_32BITS(data);
+ }
+ if ( data_value <= (u_int32_t)(attr_type[attr_code].siz_subtypes - 1 +
+ attr_type[attr_code].first_subtype) &&
+ data_value >= attr_type[attr_code].first_subtype )
+ printf("%s",table[data_value]);
+ else
+ printf("#%u",data_value);
+ }
+ else
+ {
+ switch(attr_code) /* Be aware of special cases... */
+ {
+ case FRM_IPX:
+ if (EXTRACT_32BITS( data) == 0xFFFFFFFE )
+ printf("NAS Select");
+ else
+ printf("%d",EXTRACT_32BITS( data) );
+ break;
+
+ case SESSION_TIMEOUT:
+ case IDLE_TIMEOUT:
+ case ACCT_DELAY:
+ case ACCT_SESSION_TIME:
+ case ACCT_INT_INTERVAL:
+ timeout = EXTRACT_32BITS( data);
+ if ( timeout < 60 )
+ printf( "%02d secs", timeout);
+ else
+ {
+ if ( timeout < 3600 )
+ printf( "%02d:%02d min",
+ timeout / 60, timeout % 60);
+ else
+ printf( "%02d:%02d:%02d hours",
+ timeout / 3600, (timeout % 3600) / 60,
+ timeout % 60);
+ }
+ break;
+
+ case FRM_ATALK_LINK:
+ if (EXTRACT_32BITS(data) )
+ printf("%d",EXTRACT_32BITS(data) );
+ else
+ printf("Unnumbered" );
+ break;
+
+ case FRM_ATALK_NETWORK:
+ if (EXTRACT_32BITS(data) )
+ printf("%d",EXTRACT_32BITS(data) );
+ else
+ printf("NAS assigned" );
+ break;
+
+ case TUNNEL_PREFERENCE:
+ tag = *data;
+ data++;
+ if (tag == 0)
+ printf("Tag (Unused) %d",EXTRACT_24BITS(data) );
+ else
+ printf("Tag (%d) %d", tag, EXTRACT_24BITS(data) );
+ break;
+
+ default:
+ printf("%d",EXTRACT_32BITS( data) );
+ break;
+
+ } /* switch */
+
+ } /* if-else */
+
+ return;
+
+ trunc:
+ printf(" [|radius]");
+}
+
+
+/*****************************/
+/* Print an attribute IPv4 */
+/* address value pointed by */
+/* 'data' and 'length' size. */
+/*****************************/
+/* Returns nothing. */
+/*****************************/
+static void
+print_attr_address(register u_char *data, u_int length, u_short attr_code )
+{
+ if (length != 4)
+ {
+ printf("ERROR: length %u != 4", length);
+ return;
+ }
+
+ TCHECK2(data[0],4);
+
+ switch(attr_code)
+ {
+ case FRM_IPADDR:
+ case LOG_IPHOST:
+ if (EXTRACT_32BITS(data) == 0xFFFFFFFF )
+ printf("User Selected");
+ else
+ if (EXTRACT_32BITS(data) == 0xFFFFFFFE )
+ printf("NAS Select");
+ else
+ printf("%s",ipaddr_string(data));
+ break;
+
+ default:
+ printf("%s",ipaddr_string(data) );
+ break;
+ }
+
+ return;
+
+ trunc:
+ printf(" [|radius]");
+}
+
+
+/*************************************/
+/* Print an attribute of 'secs since */
+/* January 1, 1970 00:00 UTC' value */
+/* pointed by 'data' and 'length' */
+/* size. */
+/*************************************/
+/* Returns nothing. */
+/*************************************/
+static void print_attr_time(register u_char *data, u_int length, u_short attr_code _U_)
+{
+ time_t attr_time;
+ char string[26];
+
+ if (length != 4)
+ {
+ printf("ERROR: length %u != 4", length);
+ return;
+ }
+
+ TCHECK2(data[0],4);
+
+ attr_time = EXTRACT_32BITS(data);
+ strlcpy(string, ctime(&attr_time), sizeof(string));
+ /* Get rid of the newline */
+ string[24] = '\0';
+ printf("%.24s", string);
+ return;
+
+ trunc:
+ printf(" [|radius]");
+}
+
+
+/***********************************/
+/* Print an attribute of 'strange' */
+/* data format pointed by 'data' */
+/* and 'length' size. */
+/***********************************/
+/* Returns nothing. */
+/***********************************/
+static void print_attr_strange(register u_char *data, u_int length, u_short attr_code)
+{
+ u_short len_data;
+
+ switch(attr_code)
+ {
+ case ARAP_PASS:
+ if (length != 16)
+ {
+ printf("ERROR: length %u != 16", length);
+ return;
+ }
+ printf("User_challenge (");
+ TCHECK2(data[0],8);
+ len_data = 8;
+ PRINT_HEX(len_data, data);
+ printf(") User_resp(");
+ TCHECK2(data[0],8);
+ len_data = 8;
+ PRINT_HEX(len_data, data);
+ printf(")");
+ break;
+
+ case ARAP_FEATURES:
+ if (length != 14)
+ {
+ printf("ERROR: length %u != 14", length);
+ return;
+ }
+ TCHECK2(data[0],1);
+ if (*data)
+ printf("User can change password");
+ else
+ printf("User cannot change password");
+ data++;
+ TCHECK2(data[0],1);
+ printf(", Min password length: %d",*data);
+ data++;
+ printf(", created at: ");
+ TCHECK2(data[0],4);
+ len_data = 4;
+ PRINT_HEX(len_data, data);
+ printf(", expires in: ");
+ TCHECK2(data[0],4);
+ len_data = 4;
+ PRINT_HEX(len_data, data);
+ printf(", Current Time: ");
+ TCHECK2(data[0],4);
+ len_data = 4;
+ PRINT_HEX(len_data, data);
+ break;
+
+ case ARAP_CHALLENGE_RESP:
+ if (length < 8)
+ {
+ printf("ERROR: length %u != 8", length);
+ return;
+ }
+ TCHECK2(data[0],8);
+ len_data = 8;
+ PRINT_HEX(len_data, data);
+ break;
+ }
+ return;
+
+ trunc:
+ printf(" [|radius]");
+}
+
+
+
+static void
+radius_attrs_print(register const u_char *attr, u_int length)
+{
+ register const struct radius_attr *rad_attr = (struct radius_attr *)attr;
+ const char *attr_string;
+
+ while (length > 0)
+ {
+ if (length < 2)
+ goto trunc;
+ TCHECK(*rad_attr);
+
+ if (rad_attr->type > 0 && rad_attr->type < TAM_SIZE(attr_type))
+ attr_string = attr_type[rad_attr->type].name;
+ else
+ attr_string = "Unknown";
+ if (rad_attr->len < 2)
+ {
+ printf("\n\t %s Attribute (%u), length: %u (bogus, must be >= 2)",
+ attr_string,
+ rad_attr->type,
+ rad_attr->len);
+ return;
+ }
+ if (rad_attr->len > length)
+ {
+ printf("\n\t %s Attribute (%u), length: %u (bogus, goes past end of packet)",
+ attr_string,
+ rad_attr->type,
+ rad_attr->len);
+ return;
+ }
+ printf("\n\t %s Attribute (%u), length: %u, Value: ",
+ attr_string,
+ rad_attr->type,
+ rad_attr->len);
+
+ if (rad_attr->type < TAM_SIZE(attr_type))
+ {
+ if (rad_attr->len > 2)
+ {
+ if ( attr_type[rad_attr->type].print_func )
+ (*attr_type[rad_attr->type].print_func)(
+ ((u_char *)(rad_attr+1)),
+ rad_attr->len - 2, rad_attr->type);
+ }
+ }
+ /* do we also want to see a hex dump ? */
+ if (vflag> 1)
+ print_unknown_data((u_char *)rad_attr+2,"\n\t ",(rad_attr->len)-2);
+
+ length-=(rad_attr->len);
+ rad_attr = (struct radius_attr *)( ((char *)(rad_attr))+rad_attr->len);
+ }
+ return;
+
+trunc:
+ printf(" [|radius]");
+}
+
+
+void
+radius_print(const u_char *dat, u_int length)
+{
+ register const struct radius_hdr *rad;
+ u_int len, auth_idx;
+
+ TCHECK2(*dat, MIN_RADIUS_LEN);
+ rad = (struct radius_hdr *)dat;
+ len = EXTRACT_16BITS(&rad->len);
+
+ if (len < MIN_RADIUS_LEN)
+ {
+ printf(" [|radius]");
+ return;
+ }
+
+ if (len > length)
+ len = length;
+
+ if (vflag < 1) {
+ printf("RADIUS, %s (%u), id: 0x%02x length: %u",
+ tok2str(radius_command_values,"Unknown Command",rad->code),
+ rad->code,
+ rad->id,
+ len);
+ return;
+ }
+ else {
+ printf("RADIUS, length: %u\n\t%s (%u), id: 0x%02x, Authenticator: ",
+ len,
+ tok2str(radius_command_values,"Unknown Command",rad->code),
+ rad->code,
+ rad->id);
+
+ for(auth_idx=0; auth_idx < 16; auth_idx++)
+ printf("%02x", rad->auth[auth_idx] );
+ }
+
+ if (len > MIN_RADIUS_LEN)
+ radius_attrs_print( dat + MIN_RADIUS_LEN, len - MIN_RADIUS_LEN);
+ return;
+
+trunc:
+ printf(" [|radius]");
+}
diff --git a/freebsd/contrib/tcpdump/print-raw.c b/freebsd/contrib/tcpdump/print-raw.c
new file mode 100644
index 00000000..ec257de6
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-raw.c
@@ -0,0 +1,55 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-raw.c,v 1.41 2003-11-16 09:36:34 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <pcap.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "addrtoname.h"
+#include "interface.h"
+
+/*
+ * The DLT_RAW packet has no header. It contains a raw IP packet.
+ */
+
+u_int
+raw_if_print(const struct pcap_pkthdr *h, const u_char *p)
+{
+ if (eflag)
+ printf("ip: ");
+
+ ipN_print(p, h->len);
+
+ return (0);
+}
diff --git a/freebsd/contrib/tcpdump/print-rip.c b/freebsd/contrib/tcpdump/print-rip.c
new file mode 100644
index 00000000..8d6aced0
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-rip.c
@@ -0,0 +1,274 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1989, 1990, 1991, 1993, 1994, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-rip.c,v 1.59 2006-03-23 14:58:44 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h" /* must come after interface.h */
+
+#include "af.h"
+
+struct rip {
+ u_int8_t rip_cmd; /* request/response */
+ u_int8_t rip_vers; /* protocol version # */
+ u_int8_t unused[2]; /* unused */
+};
+
+#define RIPCMD_REQUEST 1 /* want info */
+#define RIPCMD_RESPONSE 2 /* responding to request */
+#define RIPCMD_TRACEON 3 /* turn tracing on */
+#define RIPCMD_TRACEOFF 4 /* turn it off */
+#define RIPCMD_POLL 5 /* want info from everybody */
+#define RIPCMD_POLLENTRY 6 /* poll for entry */
+
+static const struct tok rip_cmd_values[] = {
+ { RIPCMD_REQUEST, "Request" },
+ { RIPCMD_RESPONSE, "Response" },
+ { RIPCMD_TRACEON, "Trace on" },
+ { RIPCMD_TRACEOFF, "Trace off" },
+ { RIPCMD_POLL, "Poll" },
+ { RIPCMD_POLLENTRY, "Poll Entry" },
+ { 0, NULL}
+};
+
+#define RIP_AUTHLEN 16
+#define RIP_ROUTELEN 20
+
+/*
+ * rfc 1723
+ *
+ * 0 1 2 3 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Command (1) | Version (1) | unused |
+ * +---------------+---------------+-------------------------------+
+ * | Address Family Identifier (2) | Route Tag (2) |
+ * +-------------------------------+-------------------------------+
+ * | IP Address (4) |
+ * +---------------------------------------------------------------+
+ * | Subnet Mask (4) |
+ * +---------------------------------------------------------------+
+ * | Next Hop (4) |
+ * +---------------------------------------------------------------+
+ * | Metric (4) |
+ * +---------------------------------------------------------------+
+ *
+ */
+
+struct rip_netinfo {
+ u_int16_t rip_family;
+ u_int16_t rip_tag;
+ u_int32_t rip_dest;
+ u_int32_t rip_dest_mask;
+ u_int32_t rip_router;
+ u_int32_t rip_metric; /* cost of route */
+};
+
+static void
+rip_entry_print_v1(register const struct rip_netinfo *ni)
+{
+ register u_short family;
+
+ /* RFC 1058 */
+ family = EXTRACT_16BITS(&ni->rip_family);
+ if (family != BSD_AFNUM_INET && family != 0) {
+ printf("\n\t AFI %s, ", tok2str(bsd_af_values, "Unknown (%u)", family));
+ print_unknown_data((u_int8_t *)&ni->rip_family,"\n\t ",RIP_ROUTELEN);
+ return;
+ }
+ if (EXTRACT_16BITS(&ni->rip_tag) ||
+ EXTRACT_32BITS(&ni->rip_dest_mask) ||
+ EXTRACT_32BITS(&ni->rip_router)) {
+ /* MBZ fields not zero */
+ print_unknown_data((u_int8_t *)&ni->rip_family,"\n\t ",RIP_ROUTELEN);
+ return;
+ }
+ if (family == 0) {
+ printf("\n\t AFI 0, %s, metric: %u",
+ ipaddr_string(&ni->rip_dest),
+ EXTRACT_32BITS(&ni->rip_metric));
+ return;
+ } /* BSD_AFNUM_INET */
+ printf("\n\t %s, metric: %u",
+ ipaddr_string(&ni->rip_dest),
+ EXTRACT_32BITS(&ni->rip_metric));
+}
+
+static unsigned
+rip_entry_print_v2(register const struct rip_netinfo *ni, const unsigned remaining)
+{
+ register u_short family;
+
+ family = EXTRACT_16BITS(&ni->rip_family);
+ if (family == 0xFFFF) { /* variable-sized authentication structures */
+ u_int16_t auth_type = EXTRACT_16BITS(&ni->rip_tag);
+ if (auth_type == 2) {
+ register u_char *p = (u_char *)&ni->rip_dest;
+ u_int i = 0;
+ printf("\n\t Simple Text Authentication data: ");
+ for (; i < RIP_AUTHLEN; p++, i++)
+ putchar (isprint(*p) ? *p : '.');
+ } else if (auth_type == 3) {
+ printf("\n\t Auth header:");
+ printf(" Packet Len %u,", EXTRACT_16BITS((u_int8_t *)ni + 4));
+ printf(" Key-ID %u,", *((u_int8_t *)ni + 6));
+ printf(" Auth Data Len %u,", *((u_int8_t *)ni + 7));
+ printf(" SeqNo %u,", EXTRACT_32BITS(&ni->rip_dest_mask));
+ printf(" MBZ %u,", EXTRACT_32BITS(&ni->rip_router));
+ printf(" MBZ %u", EXTRACT_32BITS(&ni->rip_metric));
+ } else if (auth_type == 1) {
+ printf("\n\t Auth trailer:");
+ print_unknown_data((u_int8_t *)&ni->rip_dest,"\n\t ",remaining);
+ return remaining; /* AT spans till the packet end */
+ } else {
+ printf("\n\t Unknown (%u) Authentication data:",
+ EXTRACT_16BITS(&ni->rip_tag));
+ print_unknown_data((u_int8_t *)&ni->rip_dest,"\n\t ",remaining);
+ }
+ } else if (family != BSD_AFNUM_INET && family != 0) {
+ printf("\n\t AFI %s", tok2str(bsd_af_values, "Unknown (%u)", family));
+ print_unknown_data((u_int8_t *)&ni->rip_tag,"\n\t ",RIP_ROUTELEN-2);
+ } else { /* BSD_AFNUM_INET or AFI 0 */
+ printf("\n\t AFI %s, %15s/%-2d, tag 0x%04x, metric: %u, next-hop: ",
+ tok2str(bsd_af_values, "%u", family),
+ ipaddr_string(&ni->rip_dest),
+ mask2plen(EXTRACT_32BITS(&ni->rip_dest_mask)),
+ EXTRACT_16BITS(&ni->rip_tag),
+ EXTRACT_32BITS(&ni->rip_metric));
+ if (EXTRACT_32BITS(&ni->rip_router))
+ printf("%s", ipaddr_string(&ni->rip_router));
+ else
+ printf("self");
+ }
+ return sizeof (*ni);
+}
+
+void
+rip_print(const u_char *dat, u_int length)
+{
+ register const struct rip *rp;
+ register const struct rip_netinfo *ni;
+ register u_int i, j;
+
+ if (snapend < dat) {
+ printf(" [|rip]");
+ return;
+ }
+ i = snapend - dat;
+ if (i > length)
+ i = length;
+ if (i < sizeof(*rp)) {
+ printf(" [|rip]");
+ return;
+ }
+ i -= sizeof(*rp);
+
+ rp = (struct rip *)dat;
+
+ printf("%sRIPv%u",
+ (vflag >= 1) ? "\n\t" : "",
+ rp->rip_vers);
+
+ switch (rp->rip_vers) {
+ case 0:
+ /*
+ * RFC 1058.
+ *
+ * XXX - RFC 1058 says
+ *
+ * 0 Datagrams whose version number is zero are to be ignored.
+ * These are from a previous version of the protocol, whose
+ * packet format was machine-specific.
+ *
+ * so perhaps we should just dump the packet, in hex.
+ */
+ print_unknown_data((u_int8_t *)&rp->rip_cmd,"\n\t",length);
+ break;
+ default:
+ /* dump version and lets see if we know the commands name*/
+ printf(", %s, length: %u",
+ tok2str(rip_cmd_values,
+ "unknown command (%u)",
+ rp->rip_cmd),
+ length);
+
+ if (vflag < 1)
+ return;
+
+ switch (rp->rip_cmd) {
+ case RIPCMD_REQUEST:
+ case RIPCMD_RESPONSE:
+ j = length / sizeof(*ni);
+ printf(", routes: %u%s", j, rp->rip_vers == 2 ? " or less" : "");
+ ni = (struct rip_netinfo *)(rp + 1);
+ for (; i >= sizeof(*ni); ++ni) {
+ if (rp->rip_vers == 1)
+ {
+ rip_entry_print_v1(ni);
+ i -= sizeof(*ni);
+ }
+ else if (rp->rip_vers == 2)
+ i -= rip_entry_print_v2(ni, i);
+ else
+ break;
+ }
+ if (i)
+ printf("[|rip]");
+ break;
+
+ case RIPCMD_TRACEOFF:
+ case RIPCMD_POLL:
+ case RIPCMD_POLLENTRY:
+ break;
+
+ case RIPCMD_TRACEON:
+ /* fall through */
+ default:
+ if (vflag <= 1) {
+ if(!print_unknown_data((u_int8_t *)rp,"\n\t",length))
+ return;
+ }
+ break;
+ }
+ /* do we want to see an additionally hexdump ? */
+ if (vflag> 1) {
+ if(!print_unknown_data((u_int8_t *)rp,"\n\t",length))
+ return;
+ }
+ }
+}
+
+
diff --git a/freebsd/contrib/tcpdump/print-ripng.c b/freebsd/contrib/tcpdump/print-ripng.c
new file mode 100644
index 00000000..7ce8e977
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-ripng.c
@@ -0,0 +1,130 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1989, 1990, 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-ripng.c,v 1.18 2005-01-04 00:15:54 guy Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef INET6
+
+#include <tcpdump-stdinc.h>
+#include <stdio.h>
+
+#include "route6d.h"
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+#if !defined(IN6_IS_ADDR_UNSPECIFIED) && !defined(_MSC_VER) /* MSVC inline */
+static int IN6_IS_ADDR_UNSPECIFIED(const struct in6_addr *addr)
+{
+ static const struct in6_addr in6addr_any; /* :: */
+ return (memcmp(addr, &in6addr_any, sizeof(*addr)) == 0);
+}
+#endif
+
+static int
+rip6_entry_print(register const struct netinfo6 *ni, int metric)
+{
+ int l;
+ l = printf("%s/%d", ip6addr_string(&ni->rip6_dest), ni->rip6_plen);
+ if (ni->rip6_tag)
+ l += printf(" [%d]", EXTRACT_16BITS(&ni->rip6_tag));
+ if (metric)
+ l += printf(" (%d)", ni->rip6_metric);
+ return l;
+}
+
+void
+ripng_print(const u_char *dat, unsigned int length)
+{
+ register const struct rip6 *rp = (struct rip6 *)dat;
+ register const struct netinfo6 *ni;
+ register u_int amt;
+ register u_int i;
+ int j;
+ int trunc;
+
+ if (snapend < dat)
+ return;
+ amt = snapend - dat;
+ i = min(length, amt);
+ if (i < (sizeof(struct rip6) - sizeof(struct netinfo6)))
+ return;
+ i -= (sizeof(struct rip6) - sizeof(struct netinfo6));
+
+ switch (rp->rip6_cmd) {
+
+ case RIP6_REQUEST:
+ j = length / sizeof(*ni);
+ if (j == 1
+ && rp->rip6_nets->rip6_metric == HOPCNT_INFINITY6
+ && IN6_IS_ADDR_UNSPECIFIED(&rp->rip6_nets->rip6_dest)) {
+ printf(" ripng-req dump");
+ break;
+ }
+ if (j * sizeof(*ni) != length - 4)
+ printf(" ripng-req %d[%u]:", j, length);
+ else
+ printf(" ripng-req %d:", j);
+ trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i);
+ for (ni = rp->rip6_nets; i >= sizeof(*ni);
+ i -= sizeof(*ni), ++ni) {
+ if (vflag > 1)
+ printf("\n\t");
+ else
+ printf(" ");
+ rip6_entry_print(ni, 0);
+ }
+ break;
+ case RIP6_RESPONSE:
+ j = length / sizeof(*ni);
+ if (j * sizeof(*ni) != length - 4)
+ printf(" ripng-resp %d[%u]:", j, length);
+ else
+ printf(" ripng-resp %d:", j);
+ trunc = ((i / sizeof(*ni)) * sizeof(*ni) != i);
+ for (ni = rp->rip6_nets; i >= sizeof(*ni);
+ i -= sizeof(*ni), ++ni) {
+ if (vflag > 1)
+ printf("\n\t");
+ else
+ printf(" ");
+ rip6_entry_print(ni, ni->rip6_metric);
+ }
+ if (trunc)
+ printf("[|ripng]");
+ break;
+ default:
+ printf(" ripng-%d ?? %u", rp->rip6_cmd, length);
+ break;
+ }
+ if (rp->rip6_vers != RIP6_VERSION)
+ printf(" [vers %d]", rp->rip6_vers);
+}
+#endif /* INET6 */
diff --git a/freebsd/contrib/tcpdump/print-rpki-rtr.c b/freebsd/contrib/tcpdump/print-rpki-rtr.c
new file mode 100644
index 00000000..42c3ac1b
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-rpki-rtr.c
@@ -0,0 +1,370 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1998-2011 The TCPDUMP project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * support for the The RPKI/Router Protocol as RFC6810
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+"@(#) $Header: /tcpdump/master/tcpdump/print-rpki_rtr.c,v 1.10 2008-03-20 09:30:56 hannes Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+
+/*
+ * RPKI/Router PDU header
+ *
+ * Here's what the PDU header looks like.
+ * The length does include the version and length fields.
+ */
+typedef struct rpki_rtr_pdu_ {
+ u_char version; /* Version number */
+ u_char pdu_type; /* PDU type */
+ union {
+ u_char session_id[2]; /* Session id */
+ u_char error_code[2]; /* Error code */
+ } u;
+ u_char length[4];
+} rpki_rtr_pdu;
+#define RPKI_RTR_PDU_OVERHEAD (offsetof(rpki_rtr_pdu, rpki_rtr_pdu_msg))
+
+/*
+ * IPv4 Prefix PDU.
+ */
+typedef struct rpki_rtr_pdu_ipv4_prefix_ {
+ rpki_rtr_pdu pdu_header;
+ u_char flags;
+ u_char prefix_length;
+ u_char max_length;
+ u_char zero;
+ u_char prefix[4];
+ u_char as[4];
+} rpki_rtr_pdu_ipv4_prefix;
+
+/*
+ * IPv6 Prefix PDU.
+ */
+typedef struct rpki_rtr_pdu_ipv6_prefix_ {
+ rpki_rtr_pdu pdu_header;
+ u_char flags;
+ u_char prefix_length;
+ u_char max_length;
+ u_char zero;
+ u_char prefix[16];
+ u_char as[4];
+} rpki_rtr_pdu_ipv6_prefix;
+
+/*
+ * Error report PDU.
+ */
+typedef struct rpki_rtr_pdu_error_report_ {
+ rpki_rtr_pdu pdu_header;
+ u_char encapsulated_pdu_length[4]; /* Encapsulated PDU length */
+} rpki_rtr_pdu_error_report;
+
+/*
+ * PDU type codes
+ */
+#define RPKI_RTR_SERIAL_NOTIFY_PDU 0
+#define RPKI_RTR_SERIAL_QUERY_PDU 1
+#define RPKI_RTR_RESET_QUERY_PDU 2
+#define RPKI_RTR_CACHE_RESPONSE_PDU 3
+#define RPKI_RTR_IPV4_PREFIX_PDU 4
+#define RPKI_RTR_IPV6_PREFIX_PDU 6
+#define RPKI_RTR_END_OF_DATA_PDU 7
+#define RPKI_RTR_CACHE_RESET_PDU 8
+#define RPKI_RTR_ERROR_REPORT_PDU 10
+
+static const struct tok rpki_rtr_pdu_values[] = {
+ { RPKI_RTR_SERIAL_NOTIFY_PDU, "Serial Notify" },
+ { RPKI_RTR_SERIAL_QUERY_PDU, "Serial Query" },
+ { RPKI_RTR_RESET_QUERY_PDU, "Reset Query" },
+ { RPKI_RTR_CACHE_RESPONSE_PDU, "Cache Response" },
+ { RPKI_RTR_IPV4_PREFIX_PDU, "IPV4 Prefix" },
+ { RPKI_RTR_IPV6_PREFIX_PDU, "IPV6 Prefix" },
+ { RPKI_RTR_END_OF_DATA_PDU, "End of Data" },
+ { RPKI_RTR_CACHE_RESET_PDU, "Cache Reset" },
+ { RPKI_RTR_ERROR_REPORT_PDU, "Error Report" },
+ { 0, NULL}
+};
+
+static const struct tok rpki_rtr_error_codes[] = {
+ { 0, "Corrupt Data" },
+ { 1, "Internal Error" },
+ { 2, "No Data Available" },
+ { 3, "Invalid Request" },
+ { 4, "Unsupported Protocol Version" },
+ { 5, "Unsupported PDU Type" },
+ { 6, "Withdrawal of Unknown Record" },
+ { 7, "Duplicate Announcement Received" },
+ { 0, NULL}
+};
+
+/*
+ * Build a identation string for a given identation level.
+ * XXX this should be really in util.c
+ */
+static char *
+indent_string (u_int indent)
+{
+ static char buf[20];
+ u_int idx;
+
+ idx = 0;
+ buf[idx] = '\0';
+
+ /*
+ * Does the static buffer fit ?
+ */
+ if (sizeof(buf) < ((indent/8) + (indent %8) + 2)) {
+ return buf;
+ }
+
+ /*
+ * Heading newline.
+ */
+ buf[idx] = '\n';
+ idx++;
+
+ while (indent >= 8) {
+ buf[idx] = '\t';
+ idx++;
+ indent -= 8;
+ }
+
+ while (indent > 0) {
+ buf[idx] = ' ';
+ idx++;
+ indent--;
+ }
+
+ /*
+ * Trailing zero.
+ */
+ buf[idx] = '\0';
+
+ return buf;
+}
+
+/*
+ * Print a single PDU.
+ */
+static void
+rpki_rtr_pdu_print (const u_char *tptr, u_int indent)
+{
+ const rpki_rtr_pdu *pdu_header;
+ u_int pdu_type, pdu_len, hexdump;
+ const u_char *msg;
+
+ pdu_header = (rpki_rtr_pdu *)tptr;
+ pdu_type = pdu_header->pdu_type;
+ pdu_len = EXTRACT_32BITS(pdu_header->length);
+ hexdump = FALSE;
+
+ printf("%sRPKI-RTRv%u, %s PDU (%u), length: %u",
+ indent_string(8),
+ pdu_header->version,
+ tok2str(rpki_rtr_pdu_values, "Unknown", pdu_type),
+ pdu_type, pdu_len);
+
+ switch (pdu_type) {
+
+ /*
+ * The following PDUs share the message format.
+ */
+ case RPKI_RTR_SERIAL_NOTIFY_PDU:
+ case RPKI_RTR_SERIAL_QUERY_PDU:
+ case RPKI_RTR_END_OF_DATA_PDU:
+ msg = (const u_char *)(pdu_header + 1);
+ printf("%sSession ID: 0x%04x, Serial: %u",
+ indent_string(indent+2),
+ EXTRACT_16BITS(pdu_header->u.session_id),
+ EXTRACT_32BITS(msg));
+ break;
+
+ /*
+ * The following PDUs share the message format.
+ */
+ case RPKI_RTR_RESET_QUERY_PDU:
+ case RPKI_RTR_CACHE_RESET_PDU:
+
+ /*
+ * Zero payload PDUs.
+ */
+ break;
+
+ case RPKI_RTR_CACHE_RESPONSE_PDU:
+ printf("%sSession ID: 0x%04x",
+ indent_string(indent+2),
+ EXTRACT_16BITS(pdu_header->u.session_id));
+ break;
+
+ case RPKI_RTR_IPV4_PREFIX_PDU:
+ {
+ rpki_rtr_pdu_ipv4_prefix *pdu;
+
+ pdu = (rpki_rtr_pdu_ipv4_prefix *)tptr;
+ printf("%sIPv4 Prefix %s/%u-%u, origin-as %u, flags 0x%02x",
+ indent_string(indent+2),
+ ipaddr_string(pdu->prefix),
+ pdu->prefix_length, pdu->max_length,
+ EXTRACT_32BITS(pdu->as), pdu->flags);
+ }
+ break;
+
+#ifdef INET6
+ case RPKI_RTR_IPV6_PREFIX_PDU:
+ {
+ rpki_rtr_pdu_ipv6_prefix *pdu;
+
+ pdu = (rpki_rtr_pdu_ipv6_prefix *)tptr;
+ printf("%sIPv6 Prefix %s/%u-%u, origin-as %u, flags 0x%02x",
+ indent_string(indent+2),
+ ip6addr_string(pdu->prefix),
+ pdu->prefix_length, pdu->max_length,
+ EXTRACT_32BITS(pdu->as), pdu->flags);
+ }
+ break;
+#endif
+
+ case RPKI_RTR_ERROR_REPORT_PDU:
+ {
+ rpki_rtr_pdu_error_report *pdu;
+ u_int encapsulated_pdu_length, text_length, tlen, error_code;
+ u_char buf[80];
+
+ pdu = (rpki_rtr_pdu_error_report *)tptr;
+ encapsulated_pdu_length = EXTRACT_32BITS(pdu->encapsulated_pdu_length);
+ tlen = pdu_len;
+
+ error_code = EXTRACT_16BITS(pdu->pdu_header.u.error_code);
+ printf("%sError code: %s (%u), Encapsulated PDU length: %u",
+ indent_string(indent+2),
+ tok2str(rpki_rtr_error_codes, "Unknown", error_code),
+ error_code, encapsulated_pdu_length);
+
+ tptr += sizeof(*pdu);
+ tlen -= sizeof(*pdu);
+
+ /*
+ * Recurse if there is an encapsulated PDU.
+ */
+ if (encapsulated_pdu_length &&
+ (encapsulated_pdu_length <= tlen)) {
+ printf("%s-----encapsulated PDU-----", indent_string(indent+4));
+ rpki_rtr_pdu_print(tptr, indent+2);
+ }
+
+ tptr += encapsulated_pdu_length;
+ tlen -= encapsulated_pdu_length;
+
+ /*
+ * Extract, trail-zero and print the Error message.
+ */
+ text_length = 0;
+ if (tlen > 4) {
+ text_length = EXTRACT_32BITS(tptr);
+ tptr += 4;
+ tlen -= 4;
+ }
+ if (text_length && (text_length <= tlen )) {
+ memcpy(buf, tptr, MIN(sizeof(buf)-1, text_length));
+ buf[text_length] = '\0';
+ printf("%sError text: %s", indent_string(indent+2), buf);
+ }
+ }
+ break;
+
+ default:
+
+ /*
+ * Unknown data, please hexdump.
+ */
+ hexdump = TRUE;
+ }
+
+ /* do we also want to see a hex dump ? */
+ if (vflag > 1 || (vflag && hexdump)) {
+ print_unknown_data(tptr,"\n\t ", pdu_len);
+ }
+}
+
+void
+rpki_rtr_print(register const u_char *pptr, register u_int len) {
+
+ u_int tlen, pdu_type, pdu_len;
+ const u_char *tptr;
+ const rpki_rtr_pdu *pdu_header;
+
+ tptr = pptr;
+ tlen = len;
+
+ if (!vflag) {
+ printf(", RPKI-RTR");
+ return;
+ }
+
+ while (tlen >= sizeof(rpki_rtr_pdu)) {
+
+ TCHECK2(*tptr, sizeof(rpki_rtr_pdu));
+
+ pdu_header = (rpki_rtr_pdu *)tptr;
+ pdu_type = pdu_header->pdu_type;
+ pdu_len = EXTRACT_32BITS(pdu_header->length);
+
+ /* infinite loop check */
+ if (!pdu_type || !pdu_len) {
+ break;
+ }
+
+ TCHECK2(*tptr, pdu_len);
+ if (tlen < pdu_len) {
+ goto trunc;
+ }
+
+ /*
+ * Print the PDU.
+ */
+ rpki_rtr_pdu_print(tptr, 8);
+
+ tlen -= pdu_len;
+ tptr += pdu_len;
+ }
+ return;
+ trunc:
+ printf("\n\t[|RPKI-RTR]");
+}
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-rrcp.c b/freebsd/contrib/tcpdump/print-rrcp.c
new file mode 100644
index 00000000..57ed68ef
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-rrcp.c
@@ -0,0 +1,145 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 2007 - Andrey "nording" Chernyak <andrew@nording.ru>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Format and print Realtek Remote Control Protocol (RRCP)
+ * and Realtek Echo Protocol (RRCP-REP) packets.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-rrcp.c,v 1.2 2008-04-11 17:21:34 gianluca Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "netdissect.h"
+#include "addrtoname.h"
+#include "extract.h"
+#include "ether.h"
+
+#ifndef ETH_ALEN
+#define ETH_ALEN 6
+#endif
+
+#define RRCP_OPCODE_MASK 0x7F /* 0x00 = hello, 0x01 = get, 0x02 = set */
+#define RRCP_ISREPLY 0x80 /* 0 = request to switch, 0x80 = reply from switch */
+
+#define RRCP_PROTO_OFFSET 0 /* proto - 1 byte, must be 1 */
+#define RRCP_OPCODE_ISREPLY_OFFSET 1 /* opcode and isreply flag - 1 byte */
+#define RRCP_AUTHKEY_OFFSET 2 /* authorization key - 2 bytes, 0x2379 by default */
+
+/* most packets */
+#define RRCP_REG_ADDR_OFFSET 4 /* register address - 2 bytes */
+#define RRCP_REG_DATA_OFFSET 6 /* register data - 4 bytes */
+#define RRCP_COOKIE1_OFFSET 10 /* 4 bytes */
+#define RRCP_COOKIE2_OFFSET 14 /* 4 bytes */
+
+/* hello reply packets */
+#define RRCP_DOWNLINK_PORT_OFFSET 4 /* 1 byte */
+#define RRCP_UPLINK_PORT_OFFSET 5 /* 1 byte */
+#define RRCP_UPLINK_MAC_OFFSET 6 /* 6 byte MAC address */
+#define RRCP_CHIP_ID_OFFSET 12 /* 2 bytes */
+#define RRCP_VENDOR_ID_OFFSET 14 /* 4 bytes */
+
+static const struct tok proto_values[] = {
+ { 1, "RRCP" },
+ { 2, "RRCP-REP" },
+ { 0, NULL }
+};
+
+static const struct tok opcode_values[] = {
+ { 0, "hello" },
+ { 1, "get" },
+ { 2, "set" },
+ { 0, NULL }
+};
+
+/*
+ * Print RRCP requests
+ */
+void
+rrcp_print(netdissect_options *ndo,
+ register const u_char *cp,
+ u_int length _U_)
+{
+ const u_char *rrcp;
+ u_int8_t rrcp_proto;
+ u_int8_t rrcp_opcode;
+ register const struct ether_header *ep;
+ char proto_str[16];
+ char opcode_str[32];
+
+ ep = (const struct ether_header *)cp;
+ rrcp = cp + ETHER_HDRLEN;
+
+ ND_TCHECK(*(rrcp + RRCP_PROTO_OFFSET));
+ rrcp_proto = *(rrcp + RRCP_PROTO_OFFSET);
+ ND_TCHECK(*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET));
+ rrcp_opcode = (*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_OPCODE_MASK;
+ ND_PRINT((ndo, "%s > %s, %s %s",
+ etheraddr_string(ESRC(ep)),
+ etheraddr_string(EDST(ep)),
+ tok2strbuf(proto_values,"RRCP-0x%02x",rrcp_proto,proto_str,sizeof(proto_str)),
+ ((*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY) ? "reply" : "query"));
+ if (rrcp_proto==1){
+ ND_PRINT((ndo, ": %s",
+ tok2strbuf(opcode_values,"unknown opcode (0x%02x)",rrcp_opcode,opcode_str,sizeof(opcode_str))));
+ }
+ if (rrcp_opcode==1 || rrcp_opcode==2){
+ ND_TCHECK2(*(rrcp + RRCP_REG_ADDR_OFFSET), 6);
+ ND_PRINT((ndo, " addr=0x%04x, data=0x%08x",
+ EXTRACT_LE_16BITS(rrcp + RRCP_REG_ADDR_OFFSET),
+ EXTRACT_LE_32BITS(rrcp + RRCP_REG_DATA_OFFSET)));
+ }
+ if (rrcp_proto==1){
+ ND_TCHECK2(*(rrcp + RRCP_AUTHKEY_OFFSET), 2);
+ ND_PRINT((ndo, ", auth=0x%04x",
+ EXTRACT_16BITS(rrcp + RRCP_AUTHKEY_OFFSET)));
+ }
+ if (rrcp_proto==1 && rrcp_opcode==0 &&
+ ((*(rrcp + RRCP_OPCODE_ISREPLY_OFFSET)) & RRCP_ISREPLY)){
+ ND_TCHECK2(*(rrcp + RRCP_VENDOR_ID_OFFSET), 4);
+ ND_PRINT((ndo, " downlink_port=%d, uplink_port=%d, uplink_mac=%s, vendor_id=%08x ,chip_id=%04x ",
+ *(rrcp + RRCP_DOWNLINK_PORT_OFFSET),
+ *(rrcp + RRCP_UPLINK_PORT_OFFSET),
+ etheraddr_string(rrcp + RRCP_UPLINK_MAC_OFFSET),
+ EXTRACT_32BITS(rrcp + RRCP_VENDOR_ID_OFFSET),
+ EXTRACT_16BITS(rrcp + RRCP_CHIP_ID_OFFSET)));
+ }else if (rrcp_opcode==1 || rrcp_opcode==2 || rrcp_proto==2){
+ ND_TCHECK2(*(rrcp + RRCP_COOKIE2_OFFSET), 4);
+ ND_PRINT((ndo, ", cookie=0x%08x%08x ",
+ EXTRACT_32BITS(rrcp + RRCP_COOKIE2_OFFSET),
+ EXTRACT_32BITS(rrcp + RRCP_COOKIE1_OFFSET)));
+ }
+ if (!ndo->ndo_vflag)
+ return;
+ return;
+
+trunc:
+ ND_PRINT((ndo, "[|rrcp]"));
+}
diff --git a/freebsd/contrib/tcpdump/print-rsvp.c b/freebsd/contrib/tcpdump/print-rsvp.c
new file mode 100644
index 00000000..009ef0c5
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-rsvp.c
@@ -0,0 +1,1946 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1998-2007 The TCPDUMP project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-rsvp.c,v 1.50 2008-08-16 11:36:20 hannes Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+#include "gmpls.h"
+#include "af.h"
+#include "signature.h"
+
+/*
+ * RFC 2205 common header
+ *
+ * 0 1 2 3
+ * +-------------+-------------+-------------+-------------+
+ * | Vers | Flags| Msg Type | RSVP Checksum |
+ * +-------------+-------------+-------------+-------------+
+ * | Send_TTL | (Reserved) | RSVP Length |
+ * +-------------+-------------+-------------+-------------+
+ *
+ */
+
+struct rsvp_common_header {
+ u_int8_t version_flags;
+ u_int8_t msg_type;
+ u_int8_t checksum[2];
+ u_int8_t ttl;
+ u_int8_t reserved;
+ u_int8_t length[2];
+};
+
+/*
+ * RFC2205 object header
+ *
+ *
+ * 0 1 2 3
+ * +-------------+-------------+-------------+-------------+
+ * | Length (bytes) | Class-Num | C-Type |
+ * +-------------+-------------+-------------+-------------+
+ * | |
+ * // (Object contents) //
+ * | |
+ * +-------------+-------------+-------------+-------------+
+ */
+
+struct rsvp_object_header {
+ u_int8_t length[2];
+ u_int8_t class_num;
+ u_int8_t ctype;
+};
+
+#define RSVP_VERSION 1
+#define RSVP_EXTRACT_VERSION(x) (((x)&0xf0)>>4)
+#define RSVP_EXTRACT_FLAGS(x) ((x)&0x0f)
+
+#define RSVP_MSGTYPE_PATH 1
+#define RSVP_MSGTYPE_RESV 2
+#define RSVP_MSGTYPE_PATHERR 3
+#define RSVP_MSGTYPE_RESVERR 4
+#define RSVP_MSGTYPE_PATHTEAR 5
+#define RSVP_MSGTYPE_RESVTEAR 6
+#define RSVP_MSGTYPE_RESVCONF 7
+#define RSVP_MSGTYPE_AGGREGATE 12
+#define RSVP_MSGTYPE_ACK 13
+#define RSVP_MSGTYPE_HELLO_OLD 14 /* ancient Hellos */
+#define RSVP_MSGTYPE_SREFRESH 15
+#define RSVP_MSGTYPE_HELLO 20
+
+static const struct tok rsvp_msg_type_values[] = {
+ { RSVP_MSGTYPE_PATH, "Path" },
+ { RSVP_MSGTYPE_RESV, "Resv" },
+ { RSVP_MSGTYPE_PATHERR, "PathErr" },
+ { RSVP_MSGTYPE_RESVERR, "ResvErr" },
+ { RSVP_MSGTYPE_PATHTEAR, "PathTear" },
+ { RSVP_MSGTYPE_RESVTEAR, "ResvTear" },
+ { RSVP_MSGTYPE_RESVCONF, "ResvConf" },
+ { RSVP_MSGTYPE_AGGREGATE, "Aggregate" },
+ { RSVP_MSGTYPE_ACK, "Acknowledgement" },
+ { RSVP_MSGTYPE_HELLO_OLD, "Hello (Old)" },
+ { RSVP_MSGTYPE_SREFRESH, "Refresh" },
+ { RSVP_MSGTYPE_HELLO, "Hello" },
+ { 0, NULL}
+};
+
+static const struct tok rsvp_header_flag_values[] = {
+ { 0x01, "Refresh reduction capable" }, /* rfc2961 */
+ { 0, NULL}
+};
+
+#define RSVP_OBJ_SESSION 1 /* rfc2205 */
+#define RSVP_OBJ_RSVP_HOP 3 /* rfc2205, rfc3473 */
+#define RSVP_OBJ_INTEGRITY 4 /* rfc2747 */
+#define RSVP_OBJ_TIME_VALUES 5 /* rfc2205 */
+#define RSVP_OBJ_ERROR_SPEC 6
+#define RSVP_OBJ_SCOPE 7
+#define RSVP_OBJ_STYLE 8 /* rfc2205 */
+#define RSVP_OBJ_FLOWSPEC 9 /* rfc2215 */
+#define RSVP_OBJ_FILTERSPEC 10 /* rfc2215 */
+#define RSVP_OBJ_SENDER_TEMPLATE 11
+#define RSVP_OBJ_SENDER_TSPEC 12 /* rfc2215 */
+#define RSVP_OBJ_ADSPEC 13 /* rfc2215 */
+#define RSVP_OBJ_POLICY_DATA 14
+#define RSVP_OBJ_CONFIRM 15 /* rfc2205 */
+#define RSVP_OBJ_LABEL 16 /* rfc3209 */
+#define RSVP_OBJ_LABEL_REQ 19 /* rfc3209 */
+#define RSVP_OBJ_ERO 20 /* rfc3209 */
+#define RSVP_OBJ_RRO 21 /* rfc3209 */
+#define RSVP_OBJ_HELLO 22 /* rfc3209 */
+#define RSVP_OBJ_MESSAGE_ID 23 /* rfc2961 */
+#define RSVP_OBJ_MESSAGE_ID_ACK 24 /* rfc2961 */
+#define RSVP_OBJ_MESSAGE_ID_LIST 25 /* rfc2961 */
+#define RSVP_OBJ_RECOVERY_LABEL 34 /* rfc3473 */
+#define RSVP_OBJ_UPSTREAM_LABEL 35 /* rfc3473 */
+#define RSVP_OBJ_LABEL_SET 36 /* rfc3473 */
+#define RSVP_OBJ_PROTECTION 37 /* rfc3473 */
+#define RSVP_OBJ_S2L 50 /* rfc4875 */
+#define RSVP_OBJ_DETOUR 63 /* draft-ietf-mpls-rsvp-lsp-fastreroute-07 */
+#define RSVP_OBJ_CLASSTYPE 66 /* rfc4124 */
+#define RSVP_OBJ_CLASSTYPE_OLD 125 /* draft-ietf-tewg-diff-te-proto-07 */
+#define RSVP_OBJ_SUGGESTED_LABEL 129 /* rfc3473 */
+#define RSVP_OBJ_ACCEPT_LABEL_SET 130 /* rfc3473 */
+#define RSVP_OBJ_RESTART_CAPABILITY 131 /* rfc3473 */
+#define RSVP_OBJ_NOTIFY_REQ 195 /* rfc3473 */
+#define RSVP_OBJ_ADMIN_STATUS 196 /* rfc3473 */
+#define RSVP_OBJ_PROPERTIES 204 /* juniper proprietary */
+#define RSVP_OBJ_FASTREROUTE 205 /* draft-ietf-mpls-rsvp-lsp-fastreroute-07 */
+#define RSVP_OBJ_SESSION_ATTRIBUTE 207 /* rfc3209 */
+#define RSVP_OBJ_GENERALIZED_UNI 229 /* OIF RSVP extensions UNI 1.0 Signaling, Rel. 2 */
+#define RSVP_OBJ_CALL_ID 230 /* rfc3474 */
+#define RSVP_OBJ_CALL_OPS 236 /* rfc3474 */
+
+static const struct tok rsvp_obj_values[] = {
+ { RSVP_OBJ_SESSION, "Session" },
+ { RSVP_OBJ_RSVP_HOP, "RSVP Hop" },
+ { RSVP_OBJ_INTEGRITY, "Integrity" },
+ { RSVP_OBJ_TIME_VALUES, "Time Values" },
+ { RSVP_OBJ_ERROR_SPEC, "Error Spec" },
+ { RSVP_OBJ_SCOPE, "Scope" },
+ { RSVP_OBJ_STYLE, "Style" },
+ { RSVP_OBJ_FLOWSPEC, "Flowspec" },
+ { RSVP_OBJ_FILTERSPEC, "FilterSpec" },
+ { RSVP_OBJ_SENDER_TEMPLATE, "Sender Template" },
+ { RSVP_OBJ_SENDER_TSPEC, "Sender TSpec" },
+ { RSVP_OBJ_ADSPEC, "Adspec" },
+ { RSVP_OBJ_POLICY_DATA, "Policy Data" },
+ { RSVP_OBJ_CONFIRM, "Confirm" },
+ { RSVP_OBJ_LABEL, "Label" },
+ { RSVP_OBJ_LABEL_REQ, "Label Request" },
+ { RSVP_OBJ_ERO, "ERO" },
+ { RSVP_OBJ_RRO, "RRO" },
+ { RSVP_OBJ_HELLO, "Hello" },
+ { RSVP_OBJ_MESSAGE_ID, "Message ID" },
+ { RSVP_OBJ_MESSAGE_ID_ACK, "Message ID Ack" },
+ { RSVP_OBJ_MESSAGE_ID_LIST, "Message ID List" },
+ { RSVP_OBJ_RECOVERY_LABEL, "Recovery Label" },
+ { RSVP_OBJ_UPSTREAM_LABEL, "Upstream Label" },
+ { RSVP_OBJ_LABEL_SET, "Label Set" },
+ { RSVP_OBJ_ACCEPT_LABEL_SET, "Acceptable Label Set" },
+ { RSVP_OBJ_DETOUR, "Detour" },
+ { RSVP_OBJ_CLASSTYPE, "Class Type" },
+ { RSVP_OBJ_CLASSTYPE_OLD, "Class Type (old)" },
+ { RSVP_OBJ_SUGGESTED_LABEL, "Suggested Label" },
+ { RSVP_OBJ_PROPERTIES, "Properties" },
+ { RSVP_OBJ_FASTREROUTE, "Fast Re-Route" },
+ { RSVP_OBJ_SESSION_ATTRIBUTE, "Session Attribute" },
+ { RSVP_OBJ_GENERALIZED_UNI, "Generalized UNI" },
+ { RSVP_OBJ_CALL_ID, "Call-ID" },
+ { RSVP_OBJ_CALL_OPS, "Call Capability" },
+ { RSVP_OBJ_RESTART_CAPABILITY, "Restart Capability" },
+ { RSVP_OBJ_NOTIFY_REQ, "Notify Request" },
+ { RSVP_OBJ_PROTECTION, "Protection" },
+ { RSVP_OBJ_ADMIN_STATUS, "Administrative Status" },
+ { RSVP_OBJ_S2L, "Sub-LSP to LSP" },
+ { 0, NULL}
+};
+
+#define RSVP_CTYPE_IPV4 1
+#define RSVP_CTYPE_IPV6 2
+#define RSVP_CTYPE_TUNNEL_IPV4 7
+#define RSVP_CTYPE_TUNNEL_IPV6 8
+#define RSVP_CTYPE_UNI_IPV4 11 /* OIF RSVP extensions UNI 1.0 Signaling Rel. 2 */
+#define RSVP_CTYPE_1 1
+#define RSVP_CTYPE_2 2
+#define RSVP_CTYPE_3 3
+#define RSVP_CTYPE_4 4
+#define RSVP_CTYPE_12 12
+#define RSVP_CTYPE_13 13
+#define RSVP_CTYPE_14 14
+
+/*
+ * the ctypes are not globally unique so for
+ * translating it to strings we build a table based
+ * on objects offsetted by the ctype
+ */
+
+static const struct tok rsvp_ctype_values[] = {
+ { 256*RSVP_OBJ_RSVP_HOP+RSVP_CTYPE_IPV4, "IPv4" },
+ { 256*RSVP_OBJ_RSVP_HOP+RSVP_CTYPE_IPV6, "IPv6" },
+ { 256*RSVP_OBJ_RSVP_HOP+RSVP_CTYPE_3, "IPv4 plus opt. TLVs" },
+ { 256*RSVP_OBJ_RSVP_HOP+RSVP_CTYPE_4, "IPv6 plus opt. TLVs" },
+ { 256*RSVP_OBJ_NOTIFY_REQ+RSVP_CTYPE_IPV4, "IPv4" },
+ { 256*RSVP_OBJ_NOTIFY_REQ+RSVP_CTYPE_IPV6, "IPv6" },
+ { 256*RSVP_OBJ_CONFIRM+RSVP_CTYPE_IPV4, "IPv4" },
+ { 256*RSVP_OBJ_CONFIRM+RSVP_CTYPE_IPV6, "IPv6" },
+ { 256*RSVP_OBJ_TIME_VALUES+RSVP_CTYPE_1, "1" },
+ { 256*RSVP_OBJ_FLOWSPEC+RSVP_CTYPE_1, "obsolete" },
+ { 256*RSVP_OBJ_FLOWSPEC+RSVP_CTYPE_2, "IntServ" },
+ { 256*RSVP_OBJ_SENDER_TSPEC+RSVP_CTYPE_2, "IntServ" },
+ { 256*RSVP_OBJ_ADSPEC+RSVP_CTYPE_2, "IntServ" },
+ { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_IPV4, "IPv4" },
+ { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_IPV6, "IPv6" },
+ { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_3, "IPv6 Flow-label" },
+ { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" },
+ { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_12, "IPv4 P2MP LSP Tunnel" },
+ { 256*RSVP_OBJ_FILTERSPEC+RSVP_CTYPE_13, "IPv6 P2MP LSP Tunnel" },
+ { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_IPV4, "IPv4" },
+ { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_IPV6, "IPv6" },
+ { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" },
+ { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_UNI_IPV4, "UNI IPv4" },
+ { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_13, "IPv4 P2MP LSP Tunnel" },
+ { 256*RSVP_OBJ_SESSION+RSVP_CTYPE_14, "IPv6 P2MP LSP Tunnel" },
+ { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_IPV4, "IPv4" },
+ { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_IPV6, "IPv6" },
+ { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" },
+ { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_12, "IPv4 P2MP LSP Tunnel" },
+ { 256*RSVP_OBJ_SENDER_TEMPLATE+RSVP_CTYPE_13, "IPv6 P2MP LSP Tunnel" },
+ { 256*RSVP_OBJ_MESSAGE_ID+RSVP_CTYPE_1, "1" },
+ { 256*RSVP_OBJ_MESSAGE_ID_ACK+RSVP_CTYPE_1, "Message id ack" },
+ { 256*RSVP_OBJ_MESSAGE_ID_ACK+RSVP_CTYPE_2, "Message id nack" },
+ { 256*RSVP_OBJ_MESSAGE_ID_LIST+RSVP_CTYPE_1, "1" },
+ { 256*RSVP_OBJ_STYLE+RSVP_CTYPE_1, "1" },
+ { 256*RSVP_OBJ_HELLO+RSVP_CTYPE_1, "Hello Request" },
+ { 256*RSVP_OBJ_HELLO+RSVP_CTYPE_2, "Hello Ack" },
+ { 256*RSVP_OBJ_LABEL_REQ+RSVP_CTYPE_1, "without label range" },
+ { 256*RSVP_OBJ_LABEL_REQ+RSVP_CTYPE_2, "with ATM label range" },
+ { 256*RSVP_OBJ_LABEL_REQ+RSVP_CTYPE_3, "with FR label range" },
+ { 256*RSVP_OBJ_LABEL_REQ+RSVP_CTYPE_4, "Generalized Label" },
+ { 256*RSVP_OBJ_LABEL+RSVP_CTYPE_1, "Label" },
+ { 256*RSVP_OBJ_LABEL+RSVP_CTYPE_2, "Generalized Label" },
+ { 256*RSVP_OBJ_LABEL+RSVP_CTYPE_3, "Waveband Switching" },
+ { 256*RSVP_OBJ_SUGGESTED_LABEL+RSVP_CTYPE_1, "Label" },
+ { 256*RSVP_OBJ_SUGGESTED_LABEL+RSVP_CTYPE_2, "Generalized Label" },
+ { 256*RSVP_OBJ_SUGGESTED_LABEL+RSVP_CTYPE_3, "Waveband Switching" },
+ { 256*RSVP_OBJ_UPSTREAM_LABEL+RSVP_CTYPE_1, "Label" },
+ { 256*RSVP_OBJ_UPSTREAM_LABEL+RSVP_CTYPE_2, "Generalized Label" },
+ { 256*RSVP_OBJ_UPSTREAM_LABEL+RSVP_CTYPE_3, "Waveband Switching" },
+ { 256*RSVP_OBJ_RECOVERY_LABEL+RSVP_CTYPE_1, "Label" },
+ { 256*RSVP_OBJ_RECOVERY_LABEL+RSVP_CTYPE_2, "Generalized Label" },
+ { 256*RSVP_OBJ_RECOVERY_LABEL+RSVP_CTYPE_3, "Waveband Switching" },
+ { 256*RSVP_OBJ_ERO+RSVP_CTYPE_IPV4, "IPv4" },
+ { 256*RSVP_OBJ_RRO+RSVP_CTYPE_IPV4, "IPv4" },
+ { 256*RSVP_OBJ_ERROR_SPEC+RSVP_CTYPE_IPV4, "IPv4" },
+ { 256*RSVP_OBJ_ERROR_SPEC+RSVP_CTYPE_IPV6, "IPv6" },
+ { 256*RSVP_OBJ_ERROR_SPEC+RSVP_CTYPE_3, "IPv4 plus opt. TLVs" },
+ { 256*RSVP_OBJ_ERROR_SPEC+RSVP_CTYPE_4, "IPv6 plus opt. TLVs" },
+ { 256*RSVP_OBJ_RESTART_CAPABILITY+RSVP_CTYPE_1, "IPv4" },
+ { 256*RSVP_OBJ_SESSION_ATTRIBUTE+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" },
+ { 256*RSVP_OBJ_FASTREROUTE+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" }, /* old style*/
+ { 256*RSVP_OBJ_FASTREROUTE+RSVP_CTYPE_1, "1" }, /* new style */
+ { 256*RSVP_OBJ_DETOUR+RSVP_CTYPE_TUNNEL_IPV4, "Tunnel IPv4" },
+ { 256*RSVP_OBJ_PROPERTIES+RSVP_CTYPE_1, "1" },
+ { 256*RSVP_OBJ_ADMIN_STATUS+RSVP_CTYPE_1, "1" },
+ { 256*RSVP_OBJ_CLASSTYPE+RSVP_CTYPE_1, "1" },
+ { 256*RSVP_OBJ_CLASSTYPE_OLD+RSVP_CTYPE_1, "1" },
+ { 256*RSVP_OBJ_LABEL_SET+RSVP_CTYPE_1, "1" },
+ { 256*RSVP_OBJ_GENERALIZED_UNI+RSVP_CTYPE_1, "1" },
+ { 256*RSVP_OBJ_S2L+RSVP_CTYPE_IPV4, "IPv4 sub-LSP" },
+ { 256*RSVP_OBJ_S2L+RSVP_CTYPE_IPV6, "IPv6 sub-LSP" },
+ { 0, NULL}
+};
+
+struct rsvp_obj_integrity_t {
+ u_int8_t flags;
+ u_int8_t res;
+ u_int8_t key_id[6];
+ u_int8_t sequence[8];
+ u_int8_t digest[16];
+};
+
+static const struct tok rsvp_obj_integrity_flag_values[] = {
+ { 0x80, "Handshake" },
+ { 0, NULL}
+};
+
+struct rsvp_obj_frr_t {
+ u_int8_t setup_prio;
+ u_int8_t hold_prio;
+ u_int8_t hop_limit;
+ u_int8_t flags;
+ u_int8_t bandwidth[4];
+ u_int8_t include_any[4];
+ u_int8_t exclude_any[4];
+ u_int8_t include_all[4];
+};
+
+
+#define RSVP_OBJ_XRO_MASK_SUBOBJ(x) ((x)&0x7f)
+#define RSVP_OBJ_XRO_MASK_LOOSE(x) ((x)&0x80)
+
+#define RSVP_OBJ_XRO_RES 0
+#define RSVP_OBJ_XRO_IPV4 1
+#define RSVP_OBJ_XRO_IPV6 2
+#define RSVP_OBJ_XRO_LABEL 3
+#define RSVP_OBJ_XRO_ASN 32
+#define RSVP_OBJ_XRO_MPLS 64
+
+static const struct tok rsvp_obj_xro_values[] = {
+ { RSVP_OBJ_XRO_RES, "Reserved" },
+ { RSVP_OBJ_XRO_IPV4, "IPv4 prefix" },
+ { RSVP_OBJ_XRO_IPV6, "IPv6 prefix" },
+ { RSVP_OBJ_XRO_LABEL, "Label" },
+ { RSVP_OBJ_XRO_ASN, "Autonomous system number" },
+ { RSVP_OBJ_XRO_MPLS, "MPLS label switched path termination" },
+ { 0, NULL}
+};
+
+/* draft-ietf-mpls-rsvp-lsp-fastreroute-07.txt */
+static const struct tok rsvp_obj_rro_flag_values[] = {
+ { 0x01, "Local protection available" },
+ { 0x02, "Local protection in use" },
+ { 0x04, "Bandwidth protection" },
+ { 0x08, "Node protection" },
+ { 0, NULL}
+};
+
+/* RFC3209 */
+static const struct tok rsvp_obj_rro_label_flag_values[] = {
+ { 0x01, "Global" },
+ { 0, NULL}
+};
+
+static const struct tok rsvp_resstyle_values[] = {
+ { 17, "Wildcard Filter" },
+ { 10, "Fixed Filter" },
+ { 18, "Shared Explicit" },
+ { 0, NULL}
+};
+
+#define RSVP_OBJ_INTSERV_GUARANTEED_SERV 2
+#define RSVP_OBJ_INTSERV_CONTROLLED_LOAD 5
+
+static const struct tok rsvp_intserv_service_type_values[] = {
+ { 1, "Default/Global Information" },
+ { RSVP_OBJ_INTSERV_GUARANTEED_SERV, "Guaranteed Service" },
+ { RSVP_OBJ_INTSERV_CONTROLLED_LOAD, "Controlled Load" },
+ { 0, NULL}
+};
+
+static const struct tok rsvp_intserv_parameter_id_values[] = {
+ { 4, "IS hop cnt" },
+ { 6, "Path b/w estimate" },
+ { 8, "Minimum path latency" },
+ { 10, "Composed MTU" },
+ { 127, "Token Bucket TSpec" },
+ { 130, "Guaranteed Service RSpec" },
+ { 133, "End-to-end composed value for C" },
+ { 134, "End-to-end composed value for D" },
+ { 135, "Since-last-reshaping point composed C" },
+ { 136, "Since-last-reshaping point composed D" },
+ { 0, NULL}
+};
+
+static struct tok rsvp_session_attribute_flag_values[] = {
+ { 0x01, "Local Protection" },
+ { 0x02, "Label Recording" },
+ { 0x04, "SE Style" },
+ { 0x08, "Bandwidth protection" }, /* RFC4090 */
+ { 0x10, "Node protection" }, /* RFC4090 */
+ { 0, NULL}
+};
+
+static struct tok rsvp_obj_prop_tlv_values[] = {
+ { 0x01, "Cos" },
+ { 0x02, "Metric 1" },
+ { 0x04, "Metric 2" },
+ { 0x08, "CCC Status" },
+ { 0x10, "Path Type" },
+ { 0, NULL}
+};
+
+#define RSVP_OBJ_ERROR_SPEC_CODE_ROUTING 24
+#define RSVP_OBJ_ERROR_SPEC_CODE_NOTIFY 25
+#define RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE 28
+#define RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE_OLD 125
+
+static struct tok rsvp_obj_error_code_values[] = {
+ { RSVP_OBJ_ERROR_SPEC_CODE_ROUTING, "Routing Problem" },
+ { RSVP_OBJ_ERROR_SPEC_CODE_NOTIFY, "Notify Error" },
+ { RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE, "Diffserv TE Error" },
+ { RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE_OLD, "Diffserv TE Error (Old)" },
+ { 0, NULL}
+};
+
+static struct tok rsvp_obj_error_code_routing_values[] = {
+ { 1, "Bad EXPLICIT_ROUTE object" },
+ { 2, "Bad strict node" },
+ { 3, "Bad loose node" },
+ { 4, "Bad initial subobject" },
+ { 5, "No route available toward destination" },
+ { 6, "Unacceptable label value" },
+ { 7, "RRO indicated routing loops" },
+ { 8, "non-RSVP-capable router in the path" },
+ { 9, "MPLS label allocation failure" },
+ { 10, "Unsupported L3PID" },
+ { 0, NULL}
+};
+
+static struct tok rsvp_obj_error_code_diffserv_te_values[] = {
+ { 1, "Unexpected CT object" },
+ { 2, "Unsupported CT" },
+ { 3, "Invalid CT value" },
+ { 4, "CT/setup priority do not form a configured TE-Class" },
+ { 5, "CT/holding priority do not form a configured TE-Class" },
+ { 6, "CT/setup priority and CT/holding priority do not form a configured TE-Class" },
+ { 7, "Inconsistency between signaled PSC and signaled CT" },
+ { 8, "Inconsistency between signaled PHBs and signaled CT" },
+ { 0, NULL}
+};
+
+/* rfc3473 / rfc 3471 */
+static const struct tok rsvp_obj_admin_status_flag_values[] = {
+ { 0x80000000, "Reflect" },
+ { 0x00000004, "Testing" },
+ { 0x00000002, "Admin-down" },
+ { 0x00000001, "Delete-in-progress" },
+ { 0, NULL}
+};
+
+/* label set actions - rfc3471 */
+#define LABEL_SET_INCLUSIVE_LIST 0
+#define LABEL_SET_EXCLUSIVE_LIST 1
+#define LABEL_SET_INCLUSIVE_RANGE 2
+#define LABEL_SET_EXCLUSIVE_RANGE 3
+
+static const struct tok rsvp_obj_label_set_action_values[] = {
+ { LABEL_SET_INCLUSIVE_LIST, "Inclusive list" },
+ { LABEL_SET_EXCLUSIVE_LIST, "Exclusive list" },
+ { LABEL_SET_INCLUSIVE_RANGE, "Inclusive range" },
+ { LABEL_SET_EXCLUSIVE_RANGE, "Exclusive range" },
+ { 0, NULL}
+};
+
+/* OIF RSVP extensions UNI 1.0 Signaling, release 2 */
+#define RSVP_GEN_UNI_SUBOBJ_SOURCE_TNA_ADDRESS 1
+#define RSVP_GEN_UNI_SUBOBJ_DESTINATION_TNA_ADDRESS 2
+#define RSVP_GEN_UNI_SUBOBJ_DIVERSITY 3
+#define RSVP_GEN_UNI_SUBOBJ_EGRESS_LABEL 4
+#define RSVP_GEN_UNI_SUBOBJ_SERVICE_LEVEL 5
+
+static const struct tok rsvp_obj_generalized_uni_values[] = {
+ { RSVP_GEN_UNI_SUBOBJ_SOURCE_TNA_ADDRESS, "Source TNA address" },
+ { RSVP_GEN_UNI_SUBOBJ_DESTINATION_TNA_ADDRESS, "Destination TNA address" },
+ { RSVP_GEN_UNI_SUBOBJ_DIVERSITY, "Diversity" },
+ { RSVP_GEN_UNI_SUBOBJ_EGRESS_LABEL, "Egress label" },
+ { RSVP_GEN_UNI_SUBOBJ_SERVICE_LEVEL, "Service level" },
+ { 0, NULL}
+};
+
+static int rsvp_intserv_print(const u_char *, u_short);
+
+/*
+ * this is a dissector for all the intserv defined
+ * specs as defined per rfc2215
+ * it is called from various rsvp objects;
+ * returns the amount of bytes being processed
+ */
+static int
+rsvp_intserv_print(const u_char *tptr, u_short obj_tlen) {
+
+ int parameter_id,parameter_length;
+ union {
+ float f;
+ u_int32_t i;
+ } bw;
+
+ if (obj_tlen < 4)
+ return 0;
+ parameter_id = *(tptr);
+ parameter_length = EXTRACT_16BITS(tptr+2)<<2; /* convert wordcount to bytecount */
+
+ printf("\n\t Parameter ID: %s (%u), length: %u, Flags: [0x%02x]",
+ tok2str(rsvp_intserv_parameter_id_values,"unknown",parameter_id),
+ parameter_id,
+ parameter_length,
+ *(tptr+1));
+
+ if (obj_tlen < parameter_length+4)
+ return 0;
+ switch(parameter_id) { /* parameter_id */
+
+ case 4:
+ /*
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | 4 (e) | (f) | 1 (g) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | IS hop cnt (32-bit unsigned integer) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+ if (parameter_length == 4)
+ printf("\n\t\tIS hop count: %u", EXTRACT_32BITS(tptr+4));
+ break;
+
+ case 6:
+ /*
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | 6 (h) | (i) | 1 (j) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Path b/w estimate (32-bit IEEE floating point number) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+ if (parameter_length == 4) {
+ bw.i = EXTRACT_32BITS(tptr+4);
+ printf("\n\t\tPath b/w estimate: %.10g Mbps", bw.f/125000);
+ }
+ break;
+
+ case 8:
+ /*
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | 8 (k) | (l) | 1 (m) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Minimum path latency (32-bit integer) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+ if (parameter_length == 4) {
+ printf("\n\t\tMinimum path latency: ");
+ if (EXTRACT_32BITS(tptr+4) == 0xffffffff)
+ printf("don't care");
+ else
+ printf("%u", EXTRACT_32BITS(tptr+4));
+ }
+ break;
+
+ case 10:
+
+ /*
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | 10 (n) | (o) | 1 (p) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Composed MTU (32-bit unsigned integer) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+ if (parameter_length == 4)
+ printf("\n\t\tComposed MTU: %u bytes", EXTRACT_32BITS(tptr+4));
+ break;
+ case 127:
+ /*
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | 127 (e) | 0 (f) | 5 (g) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Token Bucket Rate [r] (32-bit IEEE floating point number) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Token Bucket Size [b] (32-bit IEEE floating point number) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Peak Data Rate [p] (32-bit IEEE floating point number) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Minimum Policed Unit [m] (32-bit integer) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Maximum Packet Size [M] (32-bit integer) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+ if (parameter_length == 20) {
+ bw.i = EXTRACT_32BITS(tptr+4);
+ printf("\n\t\tToken Bucket Rate: %.10g Mbps", bw.f/125000);
+ bw.i = EXTRACT_32BITS(tptr+8);
+ printf("\n\t\tToken Bucket Size: %.10g bytes", bw.f);
+ bw.i = EXTRACT_32BITS(tptr+12);
+ printf("\n\t\tPeak Data Rate: %.10g Mbps", bw.f/125000);
+ printf("\n\t\tMinimum Policed Unit: %u bytes", EXTRACT_32BITS(tptr+16));
+ printf("\n\t\tMaximum Packet Size: %u bytes", EXTRACT_32BITS(tptr+20));
+ }
+ break;
+
+ case 130:
+ /*
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | 130 (h) | 0 (i) | 2 (j) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Rate [R] (32-bit IEEE floating point number) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Slack Term [S] (32-bit integer) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+ if (parameter_length == 8) {
+ bw.i = EXTRACT_32BITS(tptr+4);
+ printf("\n\t\tRate: %.10g Mbps", bw.f/125000);
+ printf("\n\t\tSlack Term: %u", EXTRACT_32BITS(tptr+8));
+ }
+ break;
+
+ case 133:
+ case 134:
+ case 135:
+ case 136:
+ if (parameter_length == 4)
+ printf("\n\t\tValue: %u", EXTRACT_32BITS(tptr+4));
+ break;
+
+ default:
+ if (vflag <= 1)
+ print_unknown_data(tptr+4,"\n\t\t",parameter_length);
+ }
+ return (parameter_length+4); /* header length 4 bytes */
+}
+
+static int
+rsvp_obj_print (const u_char *pptr
+#ifndef HAVE_LIBCRYPTO
+_U_
+#endif
+, u_int plen
+#ifndef HAVE_LIBCRYPTO
+_U_
+#endif
+, const u_char *tptr,
+ const char *ident, u_int tlen) {
+
+ const struct rsvp_object_header *rsvp_obj_header;
+ const u_char *obj_tptr;
+ union {
+ const struct rsvp_obj_integrity_t *rsvp_obj_integrity;
+ const struct rsvp_obj_frr_t *rsvp_obj_frr;
+ } obj_ptr;
+
+ u_short rsvp_obj_len,rsvp_obj_ctype,obj_tlen,intserv_serv_tlen;
+ int hexdump,processed,padbytes,error_code,error_value,i,sigcheck;
+ union {
+ float f;
+ u_int32_t i;
+ } bw;
+ u_int8_t namelen;
+
+ u_int action, subchannel;
+
+ while(tlen>=sizeof(struct rsvp_object_header)) {
+ /* did we capture enough for fully decoding the object header ? */
+ if (!TTEST2(*tptr, sizeof(struct rsvp_object_header)))
+ goto trunc;
+
+ rsvp_obj_header = (const struct rsvp_object_header *)tptr;
+ rsvp_obj_len=EXTRACT_16BITS(rsvp_obj_header->length);
+ rsvp_obj_ctype=rsvp_obj_header->ctype;
+
+ if(rsvp_obj_len % 4) {
+ printf("%sERROR: object header size %u not a multiple of 4", ident, rsvp_obj_len);
+ return -1;
+ }
+ if(rsvp_obj_len < sizeof(struct rsvp_object_header)) {
+ printf("%sERROR: object header too short %u < %lu", ident, rsvp_obj_len,
+ (unsigned long)sizeof(const struct rsvp_object_header));
+ return -1;
+ }
+
+ printf("%s%s Object (%u) Flags: [%s",
+ ident,
+ tok2str(rsvp_obj_values,
+ "Unknown",
+ rsvp_obj_header->class_num),
+ rsvp_obj_header->class_num,
+ ((rsvp_obj_header->class_num)&0x80) ? "ignore" : "reject");
+
+ if (rsvp_obj_header->class_num > 128)
+ printf(" %s",
+ ((rsvp_obj_header->class_num)&0x40) ? "and forward" : "silently");
+
+ printf(" if unknown], Class-Type: %s (%u), length: %u",
+ tok2str(rsvp_ctype_values,
+ "Unknown",
+ ((rsvp_obj_header->class_num)<<8)+rsvp_obj_ctype),
+ rsvp_obj_ctype,
+ rsvp_obj_len);
+
+ if(tlen < rsvp_obj_len) {
+ printf("%sERROR: object goes past end of objects TLV", ident);
+ return -1;
+ }
+
+ obj_tptr=tptr+sizeof(struct rsvp_object_header);
+ obj_tlen=rsvp_obj_len-sizeof(struct rsvp_object_header);
+
+ /* did we capture enough for fully decoding the object ? */
+ if (!TTEST2(*tptr, rsvp_obj_len))
+ return -1;
+ hexdump=FALSE;
+
+ switch(rsvp_obj_header->class_num) {
+ case RSVP_OBJ_SESSION:
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_IPV4:
+ if (obj_tlen < 8)
+ return -1;
+ printf("%s IPv4 DestAddress: %s, Protocol ID: 0x%02x",
+ ident,
+ ipaddr_string(obj_tptr),
+ *(obj_tptr+sizeof(struct in_addr)));
+ printf("%s Flags: [0x%02x], DestPort %u",
+ ident,
+ *(obj_tptr+5),
+ EXTRACT_16BITS(obj_tptr+6));
+ obj_tlen-=8;
+ obj_tptr+=8;
+ break;
+#ifdef INET6
+ case RSVP_CTYPE_IPV6:
+ if (obj_tlen < 20)
+ return -1;
+ printf("%s IPv6 DestAddress: %s, Protocol ID: 0x%02x",
+ ident,
+ ip6addr_string(obj_tptr),
+ *(obj_tptr+sizeof(struct in6_addr)));
+ printf("%s Flags: [0x%02x], DestPort %u",
+ ident,
+ *(obj_tptr+sizeof(struct in6_addr)+1),
+ EXTRACT_16BITS(obj_tptr+sizeof(struct in6_addr)+2));
+ obj_tlen-=20;
+ obj_tptr+=20;
+ break;
+
+ case RSVP_CTYPE_TUNNEL_IPV6:
+ if (obj_tlen < 36)
+ return -1;
+ printf("%s IPv6 Tunnel EndPoint: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s",
+ ident,
+ ip6addr_string(obj_tptr),
+ EXTRACT_16BITS(obj_tptr+18),
+ ip6addr_string(obj_tptr+20));
+ obj_tlen-=36;
+ obj_tptr+=36;
+ break;
+
+ case RSVP_CTYPE_14: /* IPv6 p2mp LSP Tunnel */
+ if (obj_tlen < 26)
+ return -1;
+ printf("%s IPv6 P2MP LSP ID: 0x%08x, Tunnel ID: 0x%04x, Extended Tunnel ID: %s",
+ ident,
+ EXTRACT_32BITS(obj_tptr),
+ EXTRACT_16BITS(obj_tptr+6),
+ ip6addr_string(obj_tptr+8));
+ obj_tlen-=26;
+ obj_tptr+=26;
+ break;
+#endif
+ case RSVP_CTYPE_13: /* IPv4 p2mp LSP Tunnel */
+ if (obj_tlen < 12)
+ return -1;
+ printf("%s IPv4 P2MP LSP ID: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s",
+ ident,
+ ipaddr_string(obj_tptr),
+ EXTRACT_16BITS(obj_tptr+6),
+ ipaddr_string(obj_tptr+8));
+ obj_tlen-=12;
+ obj_tptr+=12;
+ break;
+ case RSVP_CTYPE_TUNNEL_IPV4:
+ case RSVP_CTYPE_UNI_IPV4:
+ if (obj_tlen < 12)
+ return -1;
+ printf("%s IPv4 Tunnel EndPoint: %s, Tunnel ID: 0x%04x, Extended Tunnel ID: %s",
+ ident,
+ ipaddr_string(obj_tptr),
+ EXTRACT_16BITS(obj_tptr+6),
+ ipaddr_string(obj_tptr+8));
+ obj_tlen-=12;
+ obj_tptr+=12;
+ break;
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_OBJ_CONFIRM:
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_IPV4:
+ if (obj_tlen < sizeof(struct in_addr))
+ return -1;
+ printf("%s IPv4 Receiver Address: %s",
+ ident,
+ ipaddr_string(obj_tptr));
+ obj_tlen-=sizeof(struct in_addr);
+ obj_tptr+=sizeof(struct in_addr);
+ break;
+#ifdef INET6
+ case RSVP_CTYPE_IPV6:
+ if (obj_tlen < sizeof(struct in6_addr))
+ return -1;
+ printf("%s IPv6 Receiver Address: %s",
+ ident,
+ ip6addr_string(obj_tptr));
+ obj_tlen-=sizeof(struct in6_addr);
+ obj_tptr+=sizeof(struct in6_addr);
+ break;
+#endif
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_OBJ_NOTIFY_REQ:
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_IPV4:
+ if (obj_tlen < sizeof(struct in_addr))
+ return -1;
+ printf("%s IPv4 Notify Node Address: %s",
+ ident,
+ ipaddr_string(obj_tptr));
+ obj_tlen-=sizeof(struct in_addr);
+ obj_tptr+=sizeof(struct in_addr);
+ break;
+#ifdef INET6
+ case RSVP_CTYPE_IPV6:
+ if (obj_tlen < sizeof(struct in6_addr))
+ return-1;
+ printf("%s IPv6 Notify Node Address: %s",
+ ident,
+ ip6addr_string(obj_tptr));
+ obj_tlen-=sizeof(struct in6_addr);
+ obj_tptr+=sizeof(struct in6_addr);
+ break;
+#endif
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_OBJ_SUGGESTED_LABEL: /* fall through */
+ case RSVP_OBJ_UPSTREAM_LABEL: /* fall through */
+ case RSVP_OBJ_RECOVERY_LABEL: /* fall through */
+ case RSVP_OBJ_LABEL:
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_1:
+ while(obj_tlen >= 4 ) {
+ printf("%s Label: %u", ident, EXTRACT_32BITS(obj_tptr));
+ obj_tlen-=4;
+ obj_tptr+=4;
+ }
+ break;
+ case RSVP_CTYPE_2:
+ if (obj_tlen < 4)
+ return-1;
+ printf("%s Generalized Label: %u",
+ ident,
+ EXTRACT_32BITS(obj_tptr));
+ obj_tlen-=4;
+ obj_tptr+=4;
+ break;
+ case RSVP_CTYPE_3:
+ if (obj_tlen < 12)
+ return-1;
+ printf("%s Waveband ID: %u%s Start Label: %u, Stop Label: %u",
+ ident,
+ EXTRACT_32BITS(obj_tptr),
+ ident,
+ EXTRACT_32BITS(obj_tptr+4),
+ EXTRACT_32BITS(obj_tptr+8));
+ obj_tlen-=12;
+ obj_tptr+=12;
+ break;
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_OBJ_STYLE:
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_1:
+ if (obj_tlen < 4)
+ return-1;
+ printf("%s Reservation Style: %s, Flags: [0x%02x]",
+ ident,
+ tok2str(rsvp_resstyle_values,
+ "Unknown",
+ EXTRACT_24BITS(obj_tptr+1)),
+ *(obj_tptr));
+ obj_tlen-=4;
+ obj_tptr+=4;
+ break;
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_OBJ_SENDER_TEMPLATE:
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_IPV4:
+ if (obj_tlen < 8)
+ return-1;
+ printf("%s Source Address: %s, Source Port: %u",
+ ident,
+ ipaddr_string(obj_tptr),
+ EXTRACT_16BITS(obj_tptr+6));
+ obj_tlen-=8;
+ obj_tptr+=8;
+ break;
+#ifdef INET6
+ case RSVP_CTYPE_IPV6:
+ if (obj_tlen < 20)
+ return-1;
+ printf("%s Source Address: %s, Source Port: %u",
+ ident,
+ ip6addr_string(obj_tptr),
+ EXTRACT_16BITS(obj_tptr+18));
+ obj_tlen-=20;
+ obj_tptr+=20;
+ break;
+ case RSVP_CTYPE_13: /* IPv6 p2mp LSP tunnel */
+ if (obj_tlen < 40)
+ return-1;
+ printf("%s IPv6 Tunnel Sender Address: %s, LSP ID: 0x%04x"
+ "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x",
+ ident,
+ ip6addr_string(obj_tptr),
+ EXTRACT_16BITS(obj_tptr+18),
+ ident,
+ ip6addr_string(obj_tptr+20),
+ EXTRACT_16BITS(obj_tptr+38));
+ obj_tlen-=40;
+ obj_tptr+=40;
+ break;
+#endif
+ case RSVP_CTYPE_TUNNEL_IPV4:
+ if (obj_tlen < 8)
+ return-1;
+ printf("%s IPv4 Tunnel Sender Address: %s, LSP-ID: 0x%04x",
+ ident,
+ ipaddr_string(obj_tptr),
+ EXTRACT_16BITS(obj_tptr+6));
+ obj_tlen-=8;
+ obj_tptr+=8;
+ break;
+ case RSVP_CTYPE_12: /* IPv4 p2mp LSP tunnel */
+ if (obj_tlen < 16)
+ return-1;
+ printf("%s IPv4 Tunnel Sender Address: %s, LSP ID: 0x%04x"
+ "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x",
+ ident,
+ ipaddr_string(obj_tptr),
+ EXTRACT_16BITS(obj_tptr+6),
+ ident,
+ ipaddr_string(obj_tptr+8),
+ EXTRACT_16BITS(obj_tptr+12));
+ obj_tlen-=16;
+ obj_tptr+=16;
+ break;
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_OBJ_LABEL_REQ:
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_1:
+ while(obj_tlen >= 4 ) {
+ printf("%s L3 Protocol ID: %s",
+ ident,
+ tok2str(ethertype_values,
+ "Unknown Protocol (0x%04x)",
+ EXTRACT_16BITS(obj_tptr+2)));
+ obj_tlen-=4;
+ obj_tptr+=4;
+ }
+ break;
+ case RSVP_CTYPE_2:
+ if (obj_tlen < 12)
+ return-1;
+ printf("%s L3 Protocol ID: %s",
+ ident,
+ tok2str(ethertype_values,
+ "Unknown Protocol (0x%04x)",
+ EXTRACT_16BITS(obj_tptr+2)));
+ printf(",%s merge capability",((*(obj_tptr+4))&0x80) ? "no" : "" );
+ printf("%s Minimum VPI/VCI: %u/%u",
+ ident,
+ (EXTRACT_16BITS(obj_tptr+4))&0xfff,
+ (EXTRACT_16BITS(obj_tptr+6))&0xfff);
+ printf("%s Maximum VPI/VCI: %u/%u",
+ ident,
+ (EXTRACT_16BITS(obj_tptr+8))&0xfff,
+ (EXTRACT_16BITS(obj_tptr+10))&0xfff);
+ obj_tlen-=12;
+ obj_tptr+=12;
+ break;
+ case RSVP_CTYPE_3:
+ if (obj_tlen < 12)
+ return-1;
+ printf("%s L3 Protocol ID: %s",
+ ident,
+ tok2str(ethertype_values,
+ "Unknown Protocol (0x%04x)",
+ EXTRACT_16BITS(obj_tptr+2)));
+ printf("%s Minimum/Maximum DLCI: %u/%u, %s%s bit DLCI",
+ ident,
+ (EXTRACT_32BITS(obj_tptr+4))&0x7fffff,
+ (EXTRACT_32BITS(obj_tptr+8))&0x7fffff,
+ (((EXTRACT_16BITS(obj_tptr+4)>>7)&3) == 0 ) ? "10" : "",
+ (((EXTRACT_16BITS(obj_tptr+4)>>7)&3) == 2 ) ? "23" : "");
+ obj_tlen-=12;
+ obj_tptr+=12;
+ break;
+ case RSVP_CTYPE_4:
+ if (obj_tlen < 4)
+ return-1;
+ printf("%s LSP Encoding Type: %s (%u)",
+ ident,
+ tok2str(gmpls_encoding_values,
+ "Unknown",
+ *obj_tptr),
+ *obj_tptr);
+ printf("%s Switching Type: %s (%u), Payload ID: %s (0x%04x)",
+ ident,
+ tok2str(gmpls_switch_cap_values,
+ "Unknown",
+ *(obj_tptr+1)),
+ *(obj_tptr+1),
+ tok2str(gmpls_payload_values,
+ "Unknown",
+ EXTRACT_16BITS(obj_tptr+2)),
+ EXTRACT_16BITS(obj_tptr+2));
+ obj_tlen-=4;
+ obj_tptr+=4;
+ break;
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_OBJ_RRO:
+ case RSVP_OBJ_ERO:
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_IPV4:
+ while(obj_tlen >= 4 ) {
+ printf("%s Subobject Type: %s, length %u",
+ ident,
+ tok2str(rsvp_obj_xro_values,
+ "Unknown %u",
+ RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)),
+ *(obj_tptr+1));
+
+ if (*(obj_tptr+1) == 0) { /* prevent infinite loops */
+ printf("%s ERROR: zero length ERO subtype",ident);
+ break;
+ }
+
+ switch(RSVP_OBJ_XRO_MASK_SUBOBJ(*obj_tptr)) {
+ case RSVP_OBJ_XRO_IPV4:
+ printf(", %s, %s/%u, Flags: [%s]",
+ RSVP_OBJ_XRO_MASK_LOOSE(*obj_tptr) ? "Loose" : "Strict",
+ ipaddr_string(obj_tptr+2),
+ *(obj_tptr+6),
+ bittok2str(rsvp_obj_rro_flag_values,
+ "none",
+ *(obj_tptr+7))); /* rfc3209 says that this field is rsvd. */
+ break;
+ case RSVP_OBJ_XRO_LABEL:
+ printf(", Flags: [%s] (%#x), Class-Type: %s (%u), %u",
+ bittok2str(rsvp_obj_rro_label_flag_values,
+ "none",
+ *(obj_tptr+2)),
+ *(obj_tptr+2),
+ tok2str(rsvp_ctype_values,
+ "Unknown",
+ *(obj_tptr+3) + 256*RSVP_OBJ_RRO),
+ *(obj_tptr+3),
+ EXTRACT_32BITS(obj_tptr+4));
+ }
+ obj_tlen-=*(obj_tptr+1);
+ obj_tptr+=*(obj_tptr+1);
+ }
+ break;
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_OBJ_HELLO:
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_1:
+ case RSVP_CTYPE_2:
+ if (obj_tlen < 8)
+ return-1;
+ printf("%s Source Instance: 0x%08x, Destination Instance: 0x%08x",
+ ident,
+ EXTRACT_32BITS(obj_tptr),
+ EXTRACT_32BITS(obj_tptr+4));
+ obj_tlen-=8;
+ obj_tptr+=8;
+ break;
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_OBJ_RESTART_CAPABILITY:
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_1:
+ if (obj_tlen < 8)
+ return-1;
+ printf("%s Restart Time: %ums, Recovery Time: %ums",
+ ident,
+ EXTRACT_32BITS(obj_tptr),
+ EXTRACT_32BITS(obj_tptr+4));
+ obj_tlen-=8;
+ obj_tptr+=8;
+ break;
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_OBJ_SESSION_ATTRIBUTE:
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_TUNNEL_IPV4:
+ if (obj_tlen < 4)
+ return-1;
+ namelen = *(obj_tptr+3);
+ if (obj_tlen < 4+namelen)
+ return-1;
+ printf("%s Session Name: ", ident);
+ for (i = 0; i < namelen; i++)
+ safeputchar(*(obj_tptr+4+i));
+ printf("%s Setup Priority: %u, Holding Priority: %u, Flags: [%s] (%#x)",
+ ident,
+ (int)*obj_tptr,
+ (int)*(obj_tptr+1),
+ bittok2str(rsvp_session_attribute_flag_values,
+ "none",
+ *(obj_tptr+2)),
+ *(obj_tptr+2));
+ obj_tlen-=4+*(obj_tptr+3);
+ obj_tptr+=4+*(obj_tptr+3);
+ break;
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_OBJ_GENERALIZED_UNI:
+ switch(rsvp_obj_ctype) {
+ int subobj_type,af,subobj_len,total_subobj_len;
+
+ case RSVP_CTYPE_1:
+
+ if (obj_tlen < 4)
+ return-1;
+
+ /* read variable length subobjects */
+ total_subobj_len = obj_tlen;
+ while(total_subobj_len > 0) {
+ subobj_len = EXTRACT_16BITS(obj_tptr);
+ subobj_type = (EXTRACT_16BITS(obj_tptr+2))>>8;
+ af = (EXTRACT_16BITS(obj_tptr+2))&0x00FF;
+
+ printf("%s Subobject Type: %s (%u), AF: %s (%u), length: %u",
+ ident,
+ tok2str(rsvp_obj_generalized_uni_values, "Unknown", subobj_type),
+ subobj_type,
+ tok2str(af_values, "Unknown", af), af,
+ subobj_len);
+
+ switch(subobj_type) {
+ case RSVP_GEN_UNI_SUBOBJ_SOURCE_TNA_ADDRESS:
+ case RSVP_GEN_UNI_SUBOBJ_DESTINATION_TNA_ADDRESS:
+
+ switch(af) {
+ case AFNUM_INET:
+ if (subobj_len < 8)
+ return -1;
+ printf("%s UNI IPv4 TNA address: %s",
+ ident, ipaddr_string(obj_tptr+4));
+ break;
+#ifdef INET6
+ case AFNUM_INET6:
+ if (subobj_len < 20)
+ return -1;
+ printf("%s UNI IPv6 TNA address: %s",
+ ident, ip6addr_string(obj_tptr+4));
+ break;
+#endif
+ case AFNUM_NSAP:
+ if (subobj_len) {
+ /* unless we have a TLV parser lets just hexdump */
+ hexdump=TRUE;
+ }
+ break;
+ }
+ break;
+
+ case RSVP_GEN_UNI_SUBOBJ_DIVERSITY:
+ if (subobj_len) {
+ /* unless we have a TLV parser lets just hexdump */
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_GEN_UNI_SUBOBJ_EGRESS_LABEL:
+ if (subobj_len < 16) {
+ return -1;
+ }
+
+ printf("%s U-bit: %x, Label type: %u, Logical port id: %u, Label: %u",
+ ident,
+ ((EXTRACT_32BITS(obj_tptr+4))>>31),
+ ((EXTRACT_32BITS(obj_tptr+4))&0xFF),
+ EXTRACT_32BITS(obj_tptr+8),
+ EXTRACT_32BITS(obj_tptr+12));
+ break;
+
+ case RSVP_GEN_UNI_SUBOBJ_SERVICE_LEVEL:
+ if (subobj_len < 8) {
+ return -1;
+ }
+
+ printf("%s Service level: %u",
+ ident, (EXTRACT_32BITS(obj_tptr+4))>>24);
+ break;
+
+ default:
+ hexdump=TRUE;
+ break;
+ }
+ total_subobj_len-=subobj_len;
+ obj_tptr+=subobj_len;
+ obj_tlen+=subobj_len;
+ }
+
+ if (total_subobj_len) {
+ /* unless we have a TLV parser lets just hexdump */
+ hexdump=TRUE;
+ }
+ break;
+
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_OBJ_RSVP_HOP:
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_3: /* fall through - FIXME add TLV parser */
+ case RSVP_CTYPE_IPV4:
+ if (obj_tlen < 8)
+ return-1;
+ printf("%s Previous/Next Interface: %s, Logical Interface Handle: 0x%08x",
+ ident,
+ ipaddr_string(obj_tptr),
+ EXTRACT_32BITS(obj_tptr+4));
+ obj_tlen-=8;
+ obj_tptr+=8;
+ if (obj_tlen)
+ hexdump=TRUE; /* unless we have a TLV parser lets just hexdump */
+ break;
+#ifdef INET6
+ case RSVP_CTYPE_4: /* fall through - FIXME add TLV parser */
+ case RSVP_CTYPE_IPV6:
+ if (obj_tlen < 20)
+ return-1;
+ printf("%s Previous/Next Interface: %s, Logical Interface Handle: 0x%08x",
+ ident,
+ ip6addr_string(obj_tptr),
+ EXTRACT_32BITS(obj_tptr+16));
+ obj_tlen-=20;
+ obj_tptr+=20;
+ hexdump=TRUE; /* unless we have a TLV parser lets just hexdump */
+ break;
+#endif
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_OBJ_TIME_VALUES:
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_1:
+ if (obj_tlen < 4)
+ return-1;
+ printf("%s Refresh Period: %ums",
+ ident,
+ EXTRACT_32BITS(obj_tptr));
+ obj_tlen-=4;
+ obj_tptr+=4;
+ break;
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ /* those three objects do share the same semantics */
+ case RSVP_OBJ_SENDER_TSPEC:
+ case RSVP_OBJ_ADSPEC:
+ case RSVP_OBJ_FLOWSPEC:
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_2:
+ if (obj_tlen < 4)
+ return-1;
+ printf("%s Msg-Version: %u, length: %u",
+ ident,
+ (*obj_tptr & 0xf0) >> 4,
+ EXTRACT_16BITS(obj_tptr+2)<<2);
+ obj_tptr+=4; /* get to the start of the service header */
+ obj_tlen-=4;
+
+ while (obj_tlen >= 4) {
+ intserv_serv_tlen=EXTRACT_16BITS(obj_tptr+2)<<2;
+ printf("%s Service Type: %s (%u), break bit %s set, Service length: %u",
+ ident,
+ tok2str(rsvp_intserv_service_type_values,"unknown",*(obj_tptr)),
+ *(obj_tptr),
+ (*(obj_tptr+1)&0x80) ? "" : "not",
+ intserv_serv_tlen);
+
+ obj_tptr+=4; /* get to the start of the parameter list */
+ obj_tlen-=4;
+
+ while (intserv_serv_tlen>=4) {
+ processed = rsvp_intserv_print(obj_tptr, obj_tlen);
+ if (processed == 0)
+ break;
+ obj_tlen-=processed;
+ intserv_serv_tlen-=processed;
+ obj_tptr+=processed;
+ }
+ }
+ break;
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_OBJ_FILTERSPEC:
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_IPV4:
+ if (obj_tlen < 8)
+ return-1;
+ printf("%s Source Address: %s, Source Port: %u",
+ ident,
+ ipaddr_string(obj_tptr),
+ EXTRACT_16BITS(obj_tptr+6));
+ obj_tlen-=8;
+ obj_tptr+=8;
+ break;
+#ifdef INET6
+ case RSVP_CTYPE_IPV6:
+ if (obj_tlen < 20)
+ return-1;
+ printf("%s Source Address: %s, Source Port: %u",
+ ident,
+ ip6addr_string(obj_tptr),
+ EXTRACT_16BITS(obj_tptr+18));
+ obj_tlen-=20;
+ obj_tptr+=20;
+ break;
+ case RSVP_CTYPE_3:
+ if (obj_tlen < 20)
+ return-1;
+ printf("%s Source Address: %s, Flow Label: %u",
+ ident,
+ ip6addr_string(obj_tptr),
+ EXTRACT_24BITS(obj_tptr+17));
+ obj_tlen-=20;
+ obj_tptr+=20;
+ break;
+ case RSVP_CTYPE_TUNNEL_IPV6:
+ if (obj_tlen < 20)
+ return-1;
+ printf("%s Source Address: %s, LSP-ID: 0x%04x",
+ ident,
+ ipaddr_string(obj_tptr),
+ EXTRACT_16BITS(obj_tptr+18));
+ obj_tlen-=20;
+ obj_tptr+=20;
+ break;
+ case RSVP_CTYPE_13: /* IPv6 p2mp LSP tunnel */
+ if (obj_tlen < 40)
+ return-1;
+ printf("%s IPv6 Tunnel Sender Address: %s, LSP ID: 0x%04x"
+ "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x",
+ ident,
+ ip6addr_string(obj_tptr),
+ EXTRACT_16BITS(obj_tptr+18),
+ ident,
+ ip6addr_string(obj_tptr+20),
+ EXTRACT_16BITS(obj_tptr+38));
+ obj_tlen-=40;
+ obj_tptr+=40;
+ break;
+#endif
+ case RSVP_CTYPE_TUNNEL_IPV4:
+ if (obj_tlen < 8)
+ return-1;
+ printf("%s Source Address: %s, LSP-ID: 0x%04x",
+ ident,
+ ipaddr_string(obj_tptr),
+ EXTRACT_16BITS(obj_tptr+6));
+ obj_tlen-=8;
+ obj_tptr+=8;
+ break;
+ case RSVP_CTYPE_12: /* IPv4 p2mp LSP tunnel */
+ if (obj_tlen < 16)
+ return-1;
+ printf("%s IPv4 Tunnel Sender Address: %s, LSP ID: 0x%04x"
+ "%s Sub-Group Originator ID: %s, Sub-Group ID: 0x%04x",
+ ident,
+ ipaddr_string(obj_tptr),
+ EXTRACT_16BITS(obj_tptr+6),
+ ident,
+ ipaddr_string(obj_tptr+8),
+ EXTRACT_16BITS(obj_tptr+12));
+ obj_tlen-=16;
+ obj_tptr+=16;
+ break;
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_OBJ_FASTREROUTE:
+ /* the differences between c-type 1 and 7 are minor */
+ obj_ptr.rsvp_obj_frr = (const struct rsvp_obj_frr_t *)obj_tptr;
+ bw.i = EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->bandwidth);
+
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_1: /* new style */
+ if (obj_tlen < sizeof(struct rsvp_obj_frr_t))
+ return-1;
+ printf("%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps",
+ ident,
+ (int)obj_ptr.rsvp_obj_frr->setup_prio,
+ (int)obj_ptr.rsvp_obj_frr->hold_prio,
+ (int)obj_ptr.rsvp_obj_frr->hop_limit,
+ bw.f*8/1000000);
+ printf("%s Include-any: 0x%08x, Exclude-any: 0x%08x, Include-all: 0x%08x",
+ ident,
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_any),
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->exclude_any),
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_all));
+ obj_tlen-=sizeof(struct rsvp_obj_frr_t);
+ obj_tptr+=sizeof(struct rsvp_obj_frr_t);
+ break;
+
+ case RSVP_CTYPE_TUNNEL_IPV4: /* old style */
+ if (obj_tlen < 16)
+ return-1;
+ printf("%s Setup Priority: %u, Holding Priority: %u, Hop-limit: %u, Bandwidth: %.10g Mbps",
+ ident,
+ (int)obj_ptr.rsvp_obj_frr->setup_prio,
+ (int)obj_ptr.rsvp_obj_frr->hold_prio,
+ (int)obj_ptr.rsvp_obj_frr->hop_limit,
+ bw.f*8/1000000);
+ printf("%s Include Colors: 0x%08x, Exclude Colors: 0x%08x",
+ ident,
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->include_any),
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_frr->exclude_any));
+ obj_tlen-=16;
+ obj_tptr+=16;
+ break;
+
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_OBJ_DETOUR:
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_TUNNEL_IPV4:
+ while(obj_tlen >= 8) {
+ printf("%s PLR-ID: %s, Avoid-Node-ID: %s",
+ ident,
+ ipaddr_string(obj_tptr),
+ ipaddr_string(obj_tptr+4));
+ obj_tlen-=8;
+ obj_tptr+=8;
+ }
+ break;
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_OBJ_CLASSTYPE:
+ case RSVP_OBJ_CLASSTYPE_OLD: /* fall through */
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_1:
+ printf("%s CT: %u",
+ ident,
+ EXTRACT_32BITS(obj_tptr)&0x7);
+ obj_tlen-=4;
+ obj_tptr+=4;
+ break;
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_OBJ_ERROR_SPEC:
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_3: /* fall through - FIXME add TLV parser */
+ case RSVP_CTYPE_IPV4:
+ if (obj_tlen < 8)
+ return-1;
+ error_code=*(obj_tptr+5);
+ error_value=EXTRACT_16BITS(obj_tptr+6);
+ printf("%s Error Node Address: %s, Flags: [0x%02x]%s Error Code: %s (%u)",
+ ident,
+ ipaddr_string(obj_tptr),
+ *(obj_tptr+4),
+ ident,
+ tok2str(rsvp_obj_error_code_values,"unknown",error_code),
+ error_code);
+ switch (error_code) {
+ case RSVP_OBJ_ERROR_SPEC_CODE_ROUTING:
+ printf(", Error Value: %s (%u)",
+ tok2str(rsvp_obj_error_code_routing_values,"unknown",error_value),
+ error_value);
+ break;
+ case RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE: /* fall through */
+ case RSVP_OBJ_ERROR_SPEC_CODE_DIFFSERV_TE_OLD:
+ printf(", Error Value: %s (%u)",
+ tok2str(rsvp_obj_error_code_diffserv_te_values,"unknown",error_value),
+ error_value);
+ break;
+ default:
+ printf(", Unknown Error Value (%u)", error_value);
+ break;
+ }
+ obj_tlen-=8;
+ obj_tptr+=8;
+ break;
+#ifdef INET6
+ case RSVP_CTYPE_4: /* fall through - FIXME add TLV parser */
+ case RSVP_CTYPE_IPV6:
+ if (obj_tlen < 20)
+ return-1;
+ error_code=*(obj_tptr+17);
+ error_value=EXTRACT_16BITS(obj_tptr+18);
+ printf("%s Error Node Address: %s, Flags: [0x%02x]%s Error Code: %s (%u)",
+ ident,
+ ip6addr_string(obj_tptr),
+ *(obj_tptr+16),
+ ident,
+ tok2str(rsvp_obj_error_code_values,"unknown",error_code),
+ error_code);
+
+ switch (error_code) {
+ case RSVP_OBJ_ERROR_SPEC_CODE_ROUTING:
+ printf(", Error Value: %s (%u)",
+ tok2str(rsvp_obj_error_code_routing_values,"unknown",error_value),
+ error_value);
+ break;
+ default:
+ break;
+ }
+ obj_tlen-=20;
+ obj_tptr+=20;
+ break;
+#endif
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_OBJ_PROPERTIES:
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_1:
+ if (obj_tlen < 4)
+ return-1;
+ padbytes = EXTRACT_16BITS(obj_tptr+2);
+ printf("%s TLV count: %u, padding bytes: %u",
+ ident,
+ EXTRACT_16BITS(obj_tptr),
+ padbytes);
+ obj_tlen-=4;
+ obj_tptr+=4;
+ /* loop through as long there is anything longer than the TLV header (2) */
+ while(obj_tlen >= 2 + padbytes) {
+ printf("%s %s TLV (0x%02x), length: %u", /* length includes header */
+ ident,
+ tok2str(rsvp_obj_prop_tlv_values,"unknown",*obj_tptr),
+ *obj_tptr,
+ *(obj_tptr+1));
+ if (obj_tlen < *(obj_tptr+1))
+ return-1;
+ if (*(obj_tptr+1) < 2)
+ return -1;
+ print_unknown_data(obj_tptr+2,"\n\t\t",*(obj_tptr+1)-2);
+ obj_tlen-=*(obj_tptr+1);
+ obj_tptr+=*(obj_tptr+1);
+ }
+ break;
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_OBJ_MESSAGE_ID: /* fall through */
+ case RSVP_OBJ_MESSAGE_ID_ACK: /* fall through */
+ case RSVP_OBJ_MESSAGE_ID_LIST:
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_1:
+ case RSVP_CTYPE_2:
+ if (obj_tlen < 8)
+ return-1;
+ printf("%s Flags [0x%02x], epoch: %u",
+ ident,
+ *obj_tptr,
+ EXTRACT_24BITS(obj_tptr+1));
+ obj_tlen-=4;
+ obj_tptr+=4;
+ /* loop through as long there are no messages left */
+ while(obj_tlen >= 4) {
+ printf("%s Message-ID 0x%08x (%u)",
+ ident,
+ EXTRACT_32BITS(obj_tptr),
+ EXTRACT_32BITS(obj_tptr));
+ obj_tlen-=4;
+ obj_tptr+=4;
+ }
+ break;
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_OBJ_INTEGRITY:
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_1:
+ if (obj_tlen < sizeof(struct rsvp_obj_integrity_t))
+ return-1;
+ obj_ptr.rsvp_obj_integrity = (const struct rsvp_obj_integrity_t *)obj_tptr;
+ printf("%s Key-ID 0x%04x%08x, Sequence 0x%08x%08x, Flags [%s]",
+ ident,
+ EXTRACT_16BITS(obj_ptr.rsvp_obj_integrity->key_id),
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->key_id+2),
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->sequence),
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->sequence+4),
+ bittok2str(rsvp_obj_integrity_flag_values,
+ "none",
+ obj_ptr.rsvp_obj_integrity->flags));
+ printf("%s MD5-sum 0x%08x%08x%08x%08x ",
+ ident,
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest),
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+4),
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+8),
+ EXTRACT_32BITS(obj_ptr.rsvp_obj_integrity->digest+12));
+
+#ifdef HAVE_LIBCRYPTO
+ sigcheck = signature_verify(pptr, plen, (unsigned char *)obj_ptr.\
+ rsvp_obj_integrity->digest);
+#else
+ sigcheck = CANT_CHECK_SIGNATURE;
+#endif
+ printf(" (%s)", tok2str(signature_check_values, "Unknown", sigcheck));
+
+ obj_tlen+=sizeof(struct rsvp_obj_integrity_t);
+ obj_tptr+=sizeof(struct rsvp_obj_integrity_t);
+ break;
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_OBJ_ADMIN_STATUS:
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_1:
+ if (obj_tlen < 4)
+ return-1;
+ printf("%s Flags [%s]", ident,
+ bittok2str(rsvp_obj_admin_status_flag_values, "none",
+ EXTRACT_32BITS(obj_tptr)));
+ obj_tlen-=4;
+ obj_tptr+=4;
+ break;
+ default:
+ hexdump=TRUE;
+ }
+ break;
+
+ case RSVP_OBJ_LABEL_SET:
+ switch(rsvp_obj_ctype) {
+ case RSVP_CTYPE_1:
+ if (obj_tlen < 4)
+ return-1;
+ action = (EXTRACT_16BITS(obj_tptr)>>8);
+
+ printf("%s Action: %s (%u), Label type: %u", ident,
+ tok2str(rsvp_obj_label_set_action_values, "Unknown", action),
+ action, ((EXTRACT_32BITS(obj_tptr) & 0x7F)));
+
+ switch (action) {
+ case LABEL_SET_INCLUSIVE_RANGE:
+ case LABEL_SET_EXCLUSIVE_RANGE: /* fall through */
+
+ /* only a couple of subchannels are expected */
+ if (obj_tlen < 12)
+ return -1;
+ printf("%s Start range: %u, End range: %u", ident,
+ EXTRACT_32BITS(obj_tptr+4),
+ EXTRACT_32BITS(obj_tptr+8));
+ obj_tlen-=12;
+ obj_tptr+=12;
+ break;
+
+ default:
+ obj_tlen-=4;
+ obj_tptr+=4;
+ subchannel = 1;
+ while(obj_tlen >= 4 ) {
+ printf("%s Subchannel #%u: %u", ident, subchannel,
+ EXTRACT_32BITS(obj_tptr));
+ obj_tptr+=4;
+ obj_tlen-=4;
+ subchannel++;
+ }
+ break;
+ }
+ break;
+ default:
+ hexdump=TRUE;
+ }
+
+ case RSVP_OBJ_S2L:
+ switch (rsvp_obj_ctype) {
+ case RSVP_CTYPE_IPV4:
+ if (obj_tlen < 4)
+ return-1;
+ printf("%s Sub-LSP destination address: %s",
+ ident, ipaddr_string(obj_tptr));
+
+ obj_tlen-=4;
+ obj_tptr+=4;
+ break;
+#ifdef INET6
+ case RSVP_CTYPE_IPV6:
+ if (obj_tlen < 16)
+ return-1;
+ printf("%s Sub-LSP destination address: %s",
+ ident, ip6addr_string(obj_tptr));
+
+ obj_tlen-=16;
+ obj_tptr+=16;
+ break;
+#endif
+ default:
+ hexdump=TRUE;
+ }
+
+ /*
+ * FIXME those are the defined objects that lack a decoder
+ * you are welcome to contribute code ;-)
+ */
+
+ case RSVP_OBJ_SCOPE:
+ case RSVP_OBJ_POLICY_DATA:
+ case RSVP_OBJ_ACCEPT_LABEL_SET:
+ case RSVP_OBJ_PROTECTION:
+ default:
+ if (vflag <= 1)
+ print_unknown_data(obj_tptr,"\n\t ",obj_tlen); /* FIXME indentation */
+ break;
+ }
+ /* do we also want to see a hex dump ? */
+ if (vflag > 1 || hexdump==TRUE)
+ print_unknown_data(tptr+sizeof(struct rsvp_object_header),"\n\t ", /* FIXME indentation */
+ rsvp_obj_len-sizeof(struct rsvp_object_header));
+
+ tptr+=rsvp_obj_len;
+ tlen-=rsvp_obj_len;
+ }
+ return 0;
+trunc:
+ printf("\n\t\t packet exceeded snapshot");
+ return -1;
+}
+
+
+void
+rsvp_print(register const u_char *pptr, register u_int len) {
+
+ struct rsvp_common_header *rsvp_com_header;
+ const u_char *tptr,*subtptr;
+ u_short plen, tlen, subtlen;
+
+ tptr=pptr;
+
+ rsvp_com_header = (struct rsvp_common_header *)pptr;
+ TCHECK(*rsvp_com_header);
+
+ /*
+ * Sanity checking of the header.
+ */
+ if (RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags) != RSVP_VERSION) {
+ printf("ERROR: RSVP version %u packet not supported",
+ RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags));
+ return;
+ }
+
+ /* in non-verbose mode just lets print the basic Message Type*/
+ if (vflag < 1) {
+ printf("RSVPv%u %s Message, length: %u",
+ RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags),
+ tok2str(rsvp_msg_type_values, "unknown (%u)",rsvp_com_header->msg_type),
+ len);
+ return;
+ }
+
+ /* ok they seem to want to know everything - lets fully decode it */
+
+ plen = tlen = EXTRACT_16BITS(rsvp_com_header->length);
+
+ printf("\n\tRSVPv%u %s Message (%u), Flags: [%s], length: %u, ttl: %u, checksum: 0x%04x",
+ RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags),
+ tok2str(rsvp_msg_type_values, "unknown, type: %u",rsvp_com_header->msg_type),
+ rsvp_com_header->msg_type,
+ bittok2str(rsvp_header_flag_values,"none",RSVP_EXTRACT_FLAGS(rsvp_com_header->version_flags)),
+ tlen,
+ rsvp_com_header->ttl,
+ EXTRACT_16BITS(rsvp_com_header->checksum));
+
+ /*
+ * Clear checksum prior to signature verification.
+ */
+ rsvp_com_header->checksum[0] = 0;
+ rsvp_com_header->checksum[1] = 0;
+
+ if (tlen < sizeof(const struct rsvp_common_header)) {
+ printf("ERROR: common header too short %u < %lu", tlen,
+ (unsigned long)sizeof(const struct rsvp_common_header));
+ return;
+ }
+
+ tptr+=sizeof(const struct rsvp_common_header);
+ tlen-=sizeof(const struct rsvp_common_header);
+
+ switch(rsvp_com_header->msg_type) {
+
+ case RSVP_MSGTYPE_AGGREGATE:
+ while(tlen > 0) {
+ subtptr=tptr;
+ rsvp_com_header = (struct rsvp_common_header *)subtptr;
+ TCHECK(*rsvp_com_header);
+
+ /*
+ * Sanity checking of the header.
+ */
+ if (RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags) != RSVP_VERSION) {
+ printf("ERROR: RSVP version %u packet not supported",
+ RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags));
+ return;
+ }
+ subtlen=EXTRACT_16BITS(rsvp_com_header->length);
+
+ printf("\n\t RSVPv%u %s Message (%u), Flags: [%s], length: %u, ttl: %u, checksum: 0x%04x",
+ RSVP_EXTRACT_VERSION(rsvp_com_header->version_flags),
+ tok2str(rsvp_msg_type_values, "unknown, type: %u",rsvp_com_header->msg_type),
+ rsvp_com_header->msg_type,
+ bittok2str(rsvp_header_flag_values,"none",RSVP_EXTRACT_FLAGS(rsvp_com_header->version_flags)),
+ subtlen,
+ rsvp_com_header->ttl,
+ EXTRACT_16BITS(rsvp_com_header->checksum));
+
+ /*
+ * Clear checksum prior to signature verification.
+ */
+ rsvp_com_header->checksum[0] = 0;
+ rsvp_com_header->checksum[1] = 0;
+
+ if (subtlen < sizeof(const struct rsvp_common_header)) {
+ printf("ERROR: common header too short %u < %lu", subtlen,
+ (unsigned long)sizeof(const struct rsvp_common_header));
+ return;
+ }
+
+ if (tlen < subtlen) {
+ printf("ERROR: common header too large %u > %u", subtlen,
+ tlen);
+ return;
+ }
+
+ subtptr+=sizeof(const struct rsvp_common_header);
+ subtlen-=sizeof(const struct rsvp_common_header);
+
+ if (rsvp_obj_print(pptr, plen, subtptr,"\n\t ", subtlen) == -1)
+ return;
+
+ tptr+=subtlen+sizeof(const struct rsvp_common_header);
+ tlen-=subtlen+sizeof(const struct rsvp_common_header);
+ }
+
+ break;
+
+ case RSVP_MSGTYPE_PATH:
+ case RSVP_MSGTYPE_RESV:
+ case RSVP_MSGTYPE_PATHERR:
+ case RSVP_MSGTYPE_RESVERR:
+ case RSVP_MSGTYPE_PATHTEAR:
+ case RSVP_MSGTYPE_RESVTEAR:
+ case RSVP_MSGTYPE_RESVCONF:
+ case RSVP_MSGTYPE_HELLO_OLD:
+ case RSVP_MSGTYPE_HELLO:
+ case RSVP_MSGTYPE_ACK:
+ case RSVP_MSGTYPE_SREFRESH:
+ if (rsvp_obj_print(pptr, plen, tptr,"\n\t ", tlen) == -1)
+ return;
+ break;
+
+ default:
+ print_unknown_data(tptr,"\n\t ",tlen);
+ break;
+ }
+
+ return;
+trunc:
+ printf("\n\t\t packet exceeded snapshot");
+}
diff --git a/freebsd/contrib/tcpdump/print-rt6.c b/freebsd/contrib/tcpdump/print-rt6.c
new file mode 100644
index 00000000..c9501c92
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-rt6.c
@@ -0,0 +1,107 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-rt6.c,v 1.27 2005-04-20 22:34:57 guy Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef INET6
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+
+#include "ip6.h"
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+int
+rt6_print(register const u_char *bp, const u_char *bp2 _U_)
+{
+ register const struct ip6_rthdr *dp;
+ register const struct ip6_rthdr0 *dp0;
+ register const u_char *ep;
+ int i, len;
+ register const struct in6_addr *addr;
+
+ dp = (struct ip6_rthdr *)bp;
+ len = dp->ip6r_len;
+
+ /* 'ep' points to the end of available data. */
+ ep = snapend;
+
+ TCHECK(dp->ip6r_segleft);
+
+ printf("srcrt (len=%d", dp->ip6r_len); /*)*/
+ printf(", type=%d", dp->ip6r_type);
+ printf(", segleft=%d", dp->ip6r_segleft);
+
+ switch (dp->ip6r_type) {
+#ifndef IPV6_RTHDR_TYPE_0
+#define IPV6_RTHDR_TYPE_0 0
+#endif
+#ifndef IPV6_RTHDR_TYPE_2
+#define IPV6_RTHDR_TYPE_2 2
+#endif
+ case IPV6_RTHDR_TYPE_0:
+ case IPV6_RTHDR_TYPE_2: /* Mobile IPv6 ID-20 */
+ dp0 = (struct ip6_rthdr0 *)dp;
+
+ TCHECK(dp0->ip6r0_reserved);
+ if (dp0->ip6r0_reserved || vflag) {
+ printf(", rsv=0x%0x",
+ EXTRACT_32BITS(&dp0->ip6r0_reserved));
+ }
+
+ if (len % 2 == 1)
+ goto trunc;
+ len >>= 1;
+ addr = &dp0->ip6r0_addr[0];
+ for (i = 0; i < len; i++) {
+ if ((u_char *)(addr + 1) > ep)
+ goto trunc;
+
+ printf(", [%d]%s", i, ip6addr_string(addr));
+ addr++;
+ }
+ /*(*/
+ printf(") ");
+ return((dp0->ip6r0_len + 1) << 3);
+ break;
+ default:
+ goto trunc;
+ break;
+ }
+
+ trunc:
+ fputs("[|srcrt]", stdout);
+ return -1;
+}
+#endif /* INET6 */
diff --git a/freebsd/contrib/tcpdump/print-rx.c b/freebsd/contrib/tcpdump/print-rx.c
new file mode 100644
index 00000000..26ed1c63
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-rx.c
@@ -0,0 +1,2800 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright: (c) 2000 United States Government as represented by the
+ * Secretary of the Navy. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. The names of the authors may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+/*
+ * This code unmangles RX packets. RX is the mutant form of RPC that AFS
+ * uses to communicate between clients and servers.
+ *
+ * In this code, I mainly concern myself with decoding the AFS calls, not
+ * with the guts of RX, per se.
+ *
+ * Bah. If I never look at rx_packet.h again, it will be too soon.
+ *
+ * Ken Hornstein <kenh@cmf.nrl.navy.mil>
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-rx.c,v 1.42 2008-07-01 07:44:50 guy Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tcpdump-stdinc.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+#include "rx.h"
+
+#include "ip.h"
+
+static struct tok rx_types[] = {
+ { RX_PACKET_TYPE_DATA, "data" },
+ { RX_PACKET_TYPE_ACK, "ack" },
+ { RX_PACKET_TYPE_BUSY, "busy" },
+ { RX_PACKET_TYPE_ABORT, "abort" },
+ { RX_PACKET_TYPE_ACKALL, "ackall" },
+ { RX_PACKET_TYPE_CHALLENGE, "challenge" },
+ { RX_PACKET_TYPE_RESPONSE, "response" },
+ { RX_PACKET_TYPE_DEBUG, "debug" },
+ { RX_PACKET_TYPE_PARAMS, "params" },
+ { RX_PACKET_TYPE_VERSION, "version" },
+ { 0, NULL },
+};
+
+static struct double_tok {
+ int flag; /* Rx flag */
+ int packetType; /* Packet type */
+ const char *s; /* Flag string */
+} rx_flags[] = {
+ { RX_CLIENT_INITIATED, 0, "client-init" },
+ { RX_REQUEST_ACK, 0, "req-ack" },
+ { RX_LAST_PACKET, 0, "last-pckt" },
+ { RX_MORE_PACKETS, 0, "more-pckts" },
+ { RX_FREE_PACKET, 0, "free-pckt" },
+ { RX_SLOW_START_OK, RX_PACKET_TYPE_ACK, "slow-start" },
+ { RX_JUMBO_PACKET, RX_PACKET_TYPE_DATA, "jumbogram" }
+};
+
+static struct tok fs_req[] = {
+ { 130, "fetch-data" },
+ { 131, "fetch-acl" },
+ { 132, "fetch-status" },
+ { 133, "store-data" },
+ { 134, "store-acl" },
+ { 135, "store-status" },
+ { 136, "remove-file" },
+ { 137, "create-file" },
+ { 138, "rename" },
+ { 139, "symlink" },
+ { 140, "link" },
+ { 141, "makedir" },
+ { 142, "rmdir" },
+ { 143, "oldsetlock" },
+ { 144, "oldextlock" },
+ { 145, "oldrellock" },
+ { 146, "get-stats" },
+ { 147, "give-cbs" },
+ { 148, "get-vlinfo" },
+ { 149, "get-vlstats" },
+ { 150, "set-vlstats" },
+ { 151, "get-rootvl" },
+ { 152, "check-token" },
+ { 153, "get-time" },
+ { 154, "nget-vlinfo" },
+ { 155, "bulk-stat" },
+ { 156, "setlock" },
+ { 157, "extlock" },
+ { 158, "rellock" },
+ { 159, "xstat-ver" },
+ { 160, "get-xstat" },
+ { 161, "dfs-lookup" },
+ { 162, "dfs-flushcps" },
+ { 163, "dfs-symlink" },
+ { 220, "residency" },
+ { 65536, "inline-bulk-status" },
+ { 65537, "fetch-data-64" },
+ { 65538, "store-data-64" },
+ { 65539, "give-up-all-cbs" },
+ { 65540, "get-caps" },
+ { 65541, "cb-rx-conn-addr" },
+ { 0, NULL },
+};
+
+static struct tok cb_req[] = {
+ { 204, "callback" },
+ { 205, "initcb" },
+ { 206, "probe" },
+ { 207, "getlock" },
+ { 208, "getce" },
+ { 209, "xstatver" },
+ { 210, "getxstat" },
+ { 211, "initcb2" },
+ { 212, "whoareyou" },
+ { 213, "initcb3" },
+ { 214, "probeuuid" },
+ { 215, "getsrvprefs" },
+ { 216, "getcellservdb" },
+ { 217, "getlocalcell" },
+ { 218, "getcacheconf" },
+ { 65536, "getce64" },
+ { 65537, "getcellbynum" },
+ { 65538, "tellmeaboutyourself" },
+ { 0, NULL },
+};
+
+static struct tok pt_req[] = {
+ { 500, "new-user" },
+ { 501, "where-is-it" },
+ { 502, "dump-entry" },
+ { 503, "add-to-group" },
+ { 504, "name-to-id" },
+ { 505, "id-to-name" },
+ { 506, "delete" },
+ { 507, "remove-from-group" },
+ { 508, "get-cps" },
+ { 509, "new-entry" },
+ { 510, "list-max" },
+ { 511, "set-max" },
+ { 512, "list-entry" },
+ { 513, "change-entry" },
+ { 514, "list-elements" },
+ { 515, "same-mbr-of" },
+ { 516, "set-fld-sentry" },
+ { 517, "list-owned" },
+ { 518, "get-cps2" },
+ { 519, "get-host-cps" },
+ { 520, "update-entry" },
+ { 521, "list-entries" },
+ { 530, "list-super-groups" },
+ { 0, NULL },
+};
+
+static struct tok vldb_req[] = {
+ { 501, "create-entry" },
+ { 502, "delete-entry" },
+ { 503, "get-entry-by-id" },
+ { 504, "get-entry-by-name" },
+ { 505, "get-new-volume-id" },
+ { 506, "replace-entry" },
+ { 507, "update-entry" },
+ { 508, "setlock" },
+ { 509, "releaselock" },
+ { 510, "list-entry" },
+ { 511, "list-attrib" },
+ { 512, "linked-list" },
+ { 513, "get-stats" },
+ { 514, "probe" },
+ { 515, "get-addrs" },
+ { 516, "change-addr" },
+ { 517, "create-entry-n" },
+ { 518, "get-entry-by-id-n" },
+ { 519, "get-entry-by-name-n" },
+ { 520, "replace-entry-n" },
+ { 521, "list-entry-n" },
+ { 522, "list-attrib-n" },
+ { 523, "linked-list-n" },
+ { 524, "update-entry-by-name" },
+ { 525, "create-entry-u" },
+ { 526, "get-entry-by-id-u" },
+ { 527, "get-entry-by-name-u" },
+ { 528, "replace-entry-u" },
+ { 529, "list-entry-u" },
+ { 530, "list-attrib-u" },
+ { 531, "linked-list-u" },
+ { 532, "regaddr" },
+ { 533, "get-addrs-u" },
+ { 534, "list-attrib-n2" },
+ { 0, NULL },
+};
+
+static struct tok kauth_req[] = {
+ { 1, "auth-old" },
+ { 21, "authenticate" },
+ { 22, "authenticate-v2" },
+ { 2, "change-pw" },
+ { 3, "get-ticket-old" },
+ { 23, "get-ticket" },
+ { 4, "set-pw" },
+ { 5, "set-fields" },
+ { 6, "create-user" },
+ { 7, "delete-user" },
+ { 8, "get-entry" },
+ { 9, "list-entry" },
+ { 10, "get-stats" },
+ { 11, "debug" },
+ { 12, "get-pw" },
+ { 13, "get-random-key" },
+ { 14, "unlock" },
+ { 15, "lock-status" },
+ { 0, NULL },
+};
+
+static struct tok vol_req[] = {
+ { 100, "create-volume" },
+ { 101, "delete-volume" },
+ { 102, "restore" },
+ { 103, "forward" },
+ { 104, "end-trans" },
+ { 105, "clone" },
+ { 106, "set-flags" },
+ { 107, "get-flags" },
+ { 108, "trans-create" },
+ { 109, "dump" },
+ { 110, "get-nth-volume" },
+ { 111, "set-forwarding" },
+ { 112, "get-name" },
+ { 113, "get-status" },
+ { 114, "sig-restore" },
+ { 115, "list-partitions" },
+ { 116, "list-volumes" },
+ { 117, "set-id-types" },
+ { 118, "monitor" },
+ { 119, "partition-info" },
+ { 120, "reclone" },
+ { 121, "list-one-volume" },
+ { 122, "nuke" },
+ { 123, "set-date" },
+ { 124, "x-list-volumes" },
+ { 125, "x-list-one-volume" },
+ { 126, "set-info" },
+ { 127, "x-list-partitions" },
+ { 128, "forward-multiple" },
+ { 65536, "convert-ro" },
+ { 65537, "get-size" },
+ { 65538, "dump-v2" },
+ { 0, NULL },
+};
+
+static struct tok bos_req[] = {
+ { 80, "create-bnode" },
+ { 81, "delete-bnode" },
+ { 82, "set-status" },
+ { 83, "get-status" },
+ { 84, "enumerate-instance" },
+ { 85, "get-instance-info" },
+ { 86, "get-instance-parm" },
+ { 87, "add-superuser" },
+ { 88, "delete-superuser" },
+ { 89, "list-superusers" },
+ { 90, "list-keys" },
+ { 91, "add-key" },
+ { 92, "delete-key" },
+ { 93, "set-cell-name" },
+ { 94, "get-cell-name" },
+ { 95, "get-cell-host" },
+ { 96, "add-cell-host" },
+ { 97, "delete-cell-host" },
+ { 98, "set-t-status" },
+ { 99, "shutdown-all" },
+ { 100, "restart-all" },
+ { 101, "startup-all" },
+ { 102, "set-noauth-flag" },
+ { 103, "re-bozo" },
+ { 104, "restart" },
+ { 105, "start-bozo-install" },
+ { 106, "uninstall" },
+ { 107, "get-dates" },
+ { 108, "exec" },
+ { 109, "prune" },
+ { 110, "set-restart-time" },
+ { 111, "get-restart-time" },
+ { 112, "start-bozo-log" },
+ { 113, "wait-all" },
+ { 114, "get-instance-strings" },
+ { 115, "get-restricted" },
+ { 116, "set-restricted" },
+ { 0, NULL },
+};
+
+static struct tok ubik_req[] = {
+ { 10000, "vote-beacon" },
+ { 10001, "vote-debug-old" },
+ { 10002, "vote-sdebug-old" },
+ { 10003, "vote-getsyncsite" },
+ { 10004, "vote-debug" },
+ { 10005, "vote-sdebug" },
+ { 10006, "vote-xdebug" },
+ { 10007, "vote-xsdebug" },
+ { 20000, "disk-begin" },
+ { 20001, "disk-commit" },
+ { 20002, "disk-lock" },
+ { 20003, "disk-write" },
+ { 20004, "disk-getversion" },
+ { 20005, "disk-getfile" },
+ { 20006, "disk-sendfile" },
+ { 20007, "disk-abort" },
+ { 20008, "disk-releaselocks" },
+ { 20009, "disk-truncate" },
+ { 20010, "disk-probe" },
+ { 20011, "disk-writev" },
+ { 20012, "disk-interfaceaddr" },
+ { 20013, "disk-setversion" },
+ { 0, NULL },
+};
+
+#define VOTE_LOW 10000
+#define VOTE_HIGH 10007
+#define DISK_LOW 20000
+#define DISK_HIGH 20013
+
+static struct tok cb_types[] = {
+ { 1, "exclusive" },
+ { 2, "shared" },
+ { 3, "dropped" },
+ { 0, NULL },
+};
+
+static struct tok ubik_lock_types[] = {
+ { 1, "read" },
+ { 2, "write" },
+ { 3, "wait" },
+ { 0, NULL },
+};
+
+static const char *voltype[] = { "read-write", "read-only", "backup" };
+
+static struct tok afs_fs_errors[] = {
+ { 101, "salvage volume" },
+ { 102, "no such vnode" },
+ { 103, "no such volume" },
+ { 104, "volume exist" },
+ { 105, "no service" },
+ { 106, "volume offline" },
+ { 107, "voline online" },
+ { 108, "diskfull" },
+ { 109, "diskquota exceeded" },
+ { 110, "volume busy" },
+ { 111, "volume moved" },
+ { 112, "AFS IO error" },
+ { -100, "restarting fileserver" },
+ { 0, NULL }
+};
+
+/*
+ * Reasons for acknowledging a packet
+ */
+
+static struct tok rx_ack_reasons[] = {
+ { 1, "ack requested" },
+ { 2, "duplicate packet" },
+ { 3, "out of sequence" },
+ { 4, "exceeds window" },
+ { 5, "no buffer space" },
+ { 6, "ping" },
+ { 7, "ping response" },
+ { 8, "delay" },
+ { 9, "idle" },
+ { 0, NULL },
+};
+
+/*
+ * Cache entries we keep around so we can figure out the RX opcode
+ * numbers for replies. This allows us to make sense of RX reply packets.
+ */
+
+struct rx_cache_entry {
+ u_int32_t callnum; /* Call number (net order) */
+ struct in_addr client; /* client IP address (net order) */
+ struct in_addr server; /* server IP address (net order) */
+ int dport; /* server port (host order) */
+ u_short serviceId; /* Service identifier (net order) */
+ u_int32_t opcode; /* RX opcode (host order) */
+};
+
+#define RX_CACHE_SIZE 64
+
+static struct rx_cache_entry rx_cache[RX_CACHE_SIZE];
+
+static int rx_cache_next = 0;
+static int rx_cache_hint = 0;
+static void rx_cache_insert(const u_char *, const struct ip *, int);
+static int rx_cache_find(const struct rx_header *, const struct ip *,
+ int, int32_t *);
+
+static void fs_print(const u_char *, int);
+static void fs_reply_print(const u_char *, int, int32_t);
+static void acl_print(u_char *, int, u_char *);
+static void cb_print(const u_char *, int);
+static void cb_reply_print(const u_char *, int, int32_t);
+static void prot_print(const u_char *, int);
+static void prot_reply_print(const u_char *, int, int32_t);
+static void vldb_print(const u_char *, int);
+static void vldb_reply_print(const u_char *, int, int32_t);
+static void kauth_print(const u_char *, int);
+static void kauth_reply_print(const u_char *, int, int32_t);
+static void vol_print(const u_char *, int);
+static void vol_reply_print(const u_char *, int, int32_t);
+static void bos_print(const u_char *, int);
+static void bos_reply_print(const u_char *, int, int32_t);
+static void ubik_print(const u_char *);
+static void ubik_reply_print(const u_char *, int, int32_t);
+
+static void rx_ack_print(const u_char *, int);
+
+static int is_ubik(u_int32_t);
+
+/*
+ * Handle the rx-level packet. See if we know what port it's going to so
+ * we can peek at the afs call inside
+ */
+
+void
+rx_print(register const u_char *bp, int length, int sport, int dport,
+ u_char *bp2)
+{
+ register struct rx_header *rxh;
+ int i;
+ int32_t opcode;
+
+ if (snapend - bp < (int)sizeof (struct rx_header)) {
+ printf(" [|rx] (%d)", length);
+ return;
+ }
+
+ rxh = (struct rx_header *) bp;
+
+ printf(" rx %s", tok2str(rx_types, "type %d", rxh->type));
+
+ if (vflag) {
+ int firstflag = 0;
+
+ if (vflag > 1)
+ printf(" cid %08x call# %d",
+ (int) EXTRACT_32BITS(&rxh->cid),
+ (int) EXTRACT_32BITS(&rxh->callNumber));
+
+ printf(" seq %d ser %d",
+ (int) EXTRACT_32BITS(&rxh->seq),
+ (int) EXTRACT_32BITS(&rxh->serial));
+
+ if (vflag > 2)
+ printf(" secindex %d serviceid %hu",
+ (int) rxh->securityIndex,
+ EXTRACT_16BITS(&rxh->serviceId));
+
+ if (vflag > 1)
+ for (i = 0; i < NUM_RX_FLAGS; i++) {
+ if (rxh->flags & rx_flags[i].flag &&
+ (!rx_flags[i].packetType ||
+ rxh->type == rx_flags[i].packetType)) {
+ if (!firstflag) {
+ firstflag = 1;
+ printf(" ");
+ } else {
+ printf(",");
+ }
+ printf("<%s>", rx_flags[i].s);
+ }
+ }
+ }
+
+ /*
+ * Try to handle AFS calls that we know about. Check the destination
+ * port and make sure it's a data packet. Also, make sure the
+ * seq number is 1 (because otherwise it's a continuation packet,
+ * and we can't interpret that). Also, seems that reply packets
+ * do not have the client-init flag set, so we check for that
+ * as well.
+ */
+
+ if (rxh->type == RX_PACKET_TYPE_DATA &&
+ EXTRACT_32BITS(&rxh->seq) == 1 &&
+ rxh->flags & RX_CLIENT_INITIATED) {
+
+ /*
+ * Insert this call into the call cache table, so we
+ * have a chance to print out replies
+ */
+
+ rx_cache_insert(bp, (const struct ip *) bp2, dport);
+
+ switch (dport) {
+ case FS_RX_PORT: /* AFS file service */
+ fs_print(bp, length);
+ break;
+ case CB_RX_PORT: /* AFS callback service */
+ cb_print(bp, length);
+ break;
+ case PROT_RX_PORT: /* AFS protection service */
+ prot_print(bp, length);
+ break;
+ case VLDB_RX_PORT: /* AFS VLDB service */
+ vldb_print(bp, length);
+ break;
+ case KAUTH_RX_PORT: /* AFS Kerberos auth service */
+ kauth_print(bp, length);
+ break;
+ case VOL_RX_PORT: /* AFS Volume service */
+ vol_print(bp, length);
+ break;
+ case BOS_RX_PORT: /* AFS BOS service */
+ bos_print(bp, length);
+ break;
+ default:
+ ;
+ }
+
+ /*
+ * If it's a reply (client-init is _not_ set, but seq is one)
+ * then look it up in the cache. If we find it, call the reply
+ * printing functions Note that we handle abort packets here,
+ * because printing out the return code can be useful at times.
+ */
+
+ } else if (((rxh->type == RX_PACKET_TYPE_DATA &&
+ EXTRACT_32BITS(&rxh->seq) == 1) ||
+ rxh->type == RX_PACKET_TYPE_ABORT) &&
+ (rxh->flags & RX_CLIENT_INITIATED) == 0 &&
+ rx_cache_find(rxh, (const struct ip *) bp2,
+ sport, &opcode)) {
+
+ switch (sport) {
+ case FS_RX_PORT: /* AFS file service */
+ fs_reply_print(bp, length, opcode);
+ break;
+ case CB_RX_PORT: /* AFS callback service */
+ cb_reply_print(bp, length, opcode);
+ break;
+ case PROT_RX_PORT: /* AFS PT service */
+ prot_reply_print(bp, length, opcode);
+ break;
+ case VLDB_RX_PORT: /* AFS VLDB service */
+ vldb_reply_print(bp, length, opcode);
+ break;
+ case KAUTH_RX_PORT: /* AFS Kerberos auth service */
+ kauth_reply_print(bp, length, opcode);
+ break;
+ case VOL_RX_PORT: /* AFS Volume service */
+ vol_reply_print(bp, length, opcode);
+ break;
+ case BOS_RX_PORT: /* AFS BOS service */
+ bos_reply_print(bp, length, opcode);
+ break;
+ default:
+ ;
+ }
+
+ /*
+ * If it's an RX ack packet, then use the appropriate ack decoding
+ * function (there isn't any service-specific information in the
+ * ack packet, so we can use one for all AFS services)
+ */
+
+ } else if (rxh->type == RX_PACKET_TYPE_ACK)
+ rx_ack_print(bp, length);
+
+
+ printf(" (%d)", length);
+}
+
+/*
+ * Insert an entry into the cache. Taken from print-nfs.c
+ */
+
+static void
+rx_cache_insert(const u_char *bp, const struct ip *ip, int dport)
+{
+ struct rx_cache_entry *rxent;
+ const struct rx_header *rxh = (const struct rx_header *) bp;
+
+ if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t)))
+ return;
+
+ rxent = &rx_cache[rx_cache_next];
+
+ if (++rx_cache_next >= RX_CACHE_SIZE)
+ rx_cache_next = 0;
+
+ rxent->callnum = rxh->callNumber;
+ rxent->client = ip->ip_src;
+ rxent->server = ip->ip_dst;
+ rxent->dport = dport;
+ rxent->serviceId = rxh->serviceId;
+ rxent->opcode = EXTRACT_32BITS(bp + sizeof(struct rx_header));
+}
+
+/*
+ * Lookup an entry in the cache. Also taken from print-nfs.c
+ *
+ * Note that because this is a reply, we're looking at the _source_
+ * port.
+ */
+
+static int
+rx_cache_find(const struct rx_header *rxh, const struct ip *ip, int sport,
+ int32_t *opcode)
+{
+ int i;
+ struct rx_cache_entry *rxent;
+ u_int32_t clip = ip->ip_dst.s_addr;
+ u_int32_t sip = ip->ip_src.s_addr;
+
+ /* Start the search where we last left off */
+
+ i = rx_cache_hint;
+ do {
+ rxent = &rx_cache[i];
+ if (rxent->callnum == rxh->callNumber &&
+ rxent->client.s_addr == clip &&
+ rxent->server.s_addr == sip &&
+ rxent->serviceId == rxh->serviceId &&
+ rxent->dport == sport) {
+
+ /* We got a match! */
+
+ rx_cache_hint = i;
+ *opcode = rxent->opcode;
+ return(1);
+ }
+ if (++i > RX_CACHE_SIZE)
+ i = 0;
+ } while (i != rx_cache_hint);
+
+ /* Our search failed */
+ return(0);
+}
+
+/*
+ * These extrememly grody macros handle the printing of various AFS stuff.
+ */
+
+#define FIDOUT() { unsigned long n1, n2, n3; \
+ TCHECK2(bp[0], sizeof(int32_t) * 3); \
+ n1 = EXTRACT_32BITS(bp); \
+ bp += sizeof(int32_t); \
+ n2 = EXTRACT_32BITS(bp); \
+ bp += sizeof(int32_t); \
+ n3 = EXTRACT_32BITS(bp); \
+ bp += sizeof(int32_t); \
+ printf(" fid %d/%d/%d", (int) n1, (int) n2, (int) n3); \
+ }
+
+#define STROUT(MAX) { unsigned int i; \
+ TCHECK2(bp[0], sizeof(int32_t)); \
+ i = EXTRACT_32BITS(bp); \
+ if (i > (MAX)) \
+ goto trunc; \
+ bp += sizeof(int32_t); \
+ printf(" \""); \
+ if (fn_printn(bp, i, snapend)) \
+ goto trunc; \
+ printf("\""); \
+ bp += ((i + sizeof(int32_t) - 1) / sizeof(int32_t)) * sizeof(int32_t); \
+ }
+
+#define INTOUT() { int i; \
+ TCHECK2(bp[0], sizeof(int32_t)); \
+ i = (int) EXTRACT_32BITS(bp); \
+ bp += sizeof(int32_t); \
+ printf(" %d", i); \
+ }
+
+#define UINTOUT() { unsigned long i; \
+ TCHECK2(bp[0], sizeof(int32_t)); \
+ i = EXTRACT_32BITS(bp); \
+ bp += sizeof(int32_t); \
+ printf(" %lu", i); \
+ }
+
+#define UINT64OUT() { u_int64_t i; \
+ TCHECK2(bp[0], sizeof(u_int64_t)); \
+ i = EXTRACT_64BITS(bp); \
+ bp += sizeof(u_int64_t); \
+ printf(" %" PRIu64, i); \
+ }
+
+#define DATEOUT() { time_t t; struct tm *tm; char str[256]; \
+ TCHECK2(bp[0], sizeof(int32_t)); \
+ t = (time_t) EXTRACT_32BITS(bp); \
+ bp += sizeof(int32_t); \
+ tm = localtime(&t); \
+ strftime(str, 256, "%Y/%m/%d %T", tm); \
+ printf(" %s", str); \
+ }
+
+#define STOREATTROUT() { unsigned long mask, i; \
+ TCHECK2(bp[0], (sizeof(int32_t)*6)); \
+ mask = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \
+ if (mask) printf (" StoreStatus"); \
+ if (mask & 1) { printf(" date"); DATEOUT(); } \
+ else bp += sizeof(int32_t); \
+ i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \
+ if (mask & 2) printf(" owner %lu", i); \
+ i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \
+ if (mask & 4) printf(" group %lu", i); \
+ i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \
+ if (mask & 8) printf(" mode %lo", i & 07777); \
+ i = EXTRACT_32BITS(bp); bp += sizeof(int32_t); \
+ if (mask & 16) printf(" segsize %lu", i); \
+ /* undocumented in 3.3 docu */ \
+ if (mask & 1024) printf(" fsync"); \
+ }
+
+#define UBIK_VERSIONOUT() {int32_t epoch; int32_t counter; \
+ TCHECK2(bp[0], sizeof(int32_t) * 2); \
+ epoch = EXTRACT_32BITS(bp); \
+ bp += sizeof(int32_t); \
+ counter = EXTRACT_32BITS(bp); \
+ bp += sizeof(int32_t); \
+ printf(" %d.%d", epoch, counter); \
+ }
+
+#define AFSUUIDOUT() {u_int32_t temp; int i; \
+ TCHECK2(bp[0], 11*sizeof(u_int32_t)); \
+ temp = EXTRACT_32BITS(bp); \
+ bp += sizeof(u_int32_t); \
+ printf(" %08x", temp); \
+ temp = EXTRACT_32BITS(bp); \
+ bp += sizeof(u_int32_t); \
+ printf("%04x", temp); \
+ temp = EXTRACT_32BITS(bp); \
+ bp += sizeof(u_int32_t); \
+ printf("%04x", temp); \
+ for (i = 0; i < 8; i++) { \
+ temp = EXTRACT_32BITS(bp); \
+ bp += sizeof(u_int32_t); \
+ printf("%02x", (unsigned char) temp); \
+ } \
+ }
+
+/*
+ * This is the sickest one of all
+ */
+
+#define VECOUT(MAX) { u_char *sp; \
+ u_char s[AFSNAMEMAX]; \
+ int k; \
+ if ((MAX) + 1 > sizeof(s)) \
+ goto trunc; \
+ TCHECK2(bp[0], (MAX) * sizeof(int32_t)); \
+ sp = s; \
+ for (k = 0; k < (MAX); k++) { \
+ *sp++ = (u_char) EXTRACT_32BITS(bp); \
+ bp += sizeof(int32_t); \
+ } \
+ s[(MAX)] = '\0'; \
+ printf(" \""); \
+ fn_print(s, NULL); \
+ printf("\""); \
+ }
+
+#define DESTSERVEROUT() { unsigned long n1, n2, n3; \
+ TCHECK2(bp[0], sizeof(int32_t) * 3); \
+ n1 = EXTRACT_32BITS(bp); \
+ bp += sizeof(int32_t); \
+ n2 = EXTRACT_32BITS(bp); \
+ bp += sizeof(int32_t); \
+ n3 = EXTRACT_32BITS(bp); \
+ bp += sizeof(int32_t); \
+ printf(" server %d:%d:%d", (int) n1, (int) n2, (int) n3); \
+ }
+
+/*
+ * Handle calls to the AFS file service (fs)
+ */
+
+static void
+fs_print(register const u_char *bp, int length)
+{
+ int fs_op;
+ unsigned long i;
+
+ if (length <= (int)sizeof(struct rx_header))
+ return;
+
+ if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) {
+ goto trunc;
+ }
+
+ /*
+ * Print out the afs call we're invoking. The table used here was
+ * gleaned from fsint/afsint.xg
+ */
+
+ fs_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
+
+ printf(" fs call %s", tok2str(fs_req, "op#%d", fs_op));
+
+ /*
+ * Print out arguments to some of the AFS calls. This stuff is
+ * all from afsint.xg
+ */
+
+ bp += sizeof(struct rx_header) + 4;
+
+ /*
+ * Sigh. This is gross. Ritchie forgive me.
+ */
+
+ switch (fs_op) {
+ case 130: /* Fetch data */
+ FIDOUT();
+ printf(" offset");
+ UINTOUT();
+ printf(" length");
+ UINTOUT();
+ break;
+ case 131: /* Fetch ACL */
+ case 132: /* Fetch Status */
+ case 143: /* Old set lock */
+ case 144: /* Old extend lock */
+ case 145: /* Old release lock */
+ case 156: /* Set lock */
+ case 157: /* Extend lock */
+ case 158: /* Release lock */
+ FIDOUT();
+ break;
+ case 135: /* Store status */
+ FIDOUT();
+ STOREATTROUT();
+ break;
+ case 133: /* Store data */
+ FIDOUT();
+ STOREATTROUT();
+ printf(" offset");
+ UINTOUT();
+ printf(" length");
+ UINTOUT();
+ printf(" flen");
+ UINTOUT();
+ break;
+ case 134: /* Store ACL */
+ {
+ char a[AFSOPAQUEMAX+1];
+ FIDOUT();
+ TCHECK2(bp[0], 4);
+ i = EXTRACT_32BITS(bp);
+ bp += sizeof(int32_t);
+ TCHECK2(bp[0], i);
+ i = min(AFSOPAQUEMAX, i);
+ strncpy(a, (char *) bp, i);
+ a[i] = '\0';
+ acl_print((u_char *) a, sizeof(a), (u_char *) a + i);
+ break;
+ }
+ case 137: /* Create file */
+ case 141: /* MakeDir */
+ FIDOUT();
+ STROUT(AFSNAMEMAX);
+ STOREATTROUT();
+ break;
+ case 136: /* Remove file */
+ case 142: /* Remove directory */
+ FIDOUT();
+ STROUT(AFSNAMEMAX);
+ break;
+ case 138: /* Rename file */
+ printf(" old");
+ FIDOUT();
+ STROUT(AFSNAMEMAX);
+ printf(" new");
+ FIDOUT();
+ STROUT(AFSNAMEMAX);
+ break;
+ case 139: /* Symlink */
+ FIDOUT();
+ STROUT(AFSNAMEMAX);
+ printf(" link to");
+ STROUT(AFSNAMEMAX);
+ break;
+ case 140: /* Link */
+ FIDOUT();
+ STROUT(AFSNAMEMAX);
+ printf(" link to");
+ FIDOUT();
+ break;
+ case 148: /* Get volume info */
+ STROUT(AFSNAMEMAX);
+ break;
+ case 149: /* Get volume stats */
+ case 150: /* Set volume stats */
+ printf(" volid");
+ UINTOUT();
+ break;
+ case 154: /* New get volume info */
+ printf(" volname");
+ STROUT(AFSNAMEMAX);
+ break;
+ case 155: /* Bulk stat */
+ case 65536: /* Inline bulk stat */
+ {
+ unsigned long j;
+ TCHECK2(bp[0], 4);
+ j = EXTRACT_32BITS(bp);
+ bp += sizeof(int32_t);
+
+ for (i = 0; i < j; i++) {
+ FIDOUT();
+ if (i != j - 1)
+ printf(",");
+ }
+ if (j == 0)
+ printf(" <none!>");
+ }
+ case 65537: /* Fetch data 64 */
+ FIDOUT();
+ printf(" offset");
+ UINT64OUT();
+ printf(" length");
+ UINT64OUT();
+ break;
+ case 65538: /* Store data 64 */
+ FIDOUT();
+ STOREATTROUT();
+ printf(" offset");
+ UINT64OUT();
+ printf(" length");
+ UINT64OUT();
+ printf(" flen");
+ UINT64OUT();
+ break;
+ case 65541: /* CallBack rx conn address */
+ printf(" addr");
+ UINTOUT();
+ default:
+ ;
+ }
+
+ return;
+
+trunc:
+ printf(" [|fs]");
+}
+
+/*
+ * Handle replies to the AFS file service
+ */
+
+static void
+fs_reply_print(register const u_char *bp, int length, int32_t opcode)
+{
+ unsigned long i;
+ struct rx_header *rxh;
+
+ if (length <= (int)sizeof(struct rx_header))
+ return;
+
+ rxh = (struct rx_header *) bp;
+
+ /*
+ * Print out the afs call we're invoking. The table used here was
+ * gleaned from fsint/afsint.xg
+ */
+
+ printf(" fs reply %s", tok2str(fs_req, "op#%d", opcode));
+
+ bp += sizeof(struct rx_header);
+
+ /*
+ * If it was a data packet, interpret the response
+ */
+
+ if (rxh->type == RX_PACKET_TYPE_DATA) {
+ switch (opcode) {
+ case 131: /* Fetch ACL */
+ {
+ char a[AFSOPAQUEMAX+1];
+ TCHECK2(bp[0], 4);
+ i = EXTRACT_32BITS(bp);
+ bp += sizeof(int32_t);
+ TCHECK2(bp[0], i);
+ i = min(AFSOPAQUEMAX, i);
+ strncpy(a, (char *) bp, i);
+ a[i] = '\0';
+ acl_print((u_char *) a, sizeof(a), (u_char *) a + i);
+ break;
+ }
+ case 137: /* Create file */
+ case 141: /* MakeDir */
+ printf(" new");
+ FIDOUT();
+ break;
+ case 151: /* Get root volume */
+ printf(" root volume");
+ STROUT(AFSNAMEMAX);
+ break;
+ case 153: /* Get time */
+ DATEOUT();
+ break;
+ default:
+ ;
+ }
+ } else if (rxh->type == RX_PACKET_TYPE_ABORT) {
+ int i;
+
+ /*
+ * Otherwise, just print out the return code
+ */
+ TCHECK2(bp[0], sizeof(int32_t));
+ i = (int) EXTRACT_32BITS(bp);
+ bp += sizeof(int32_t);
+
+ printf(" error %s", tok2str(afs_fs_errors, "#%d", i));
+ } else {
+ printf(" strange fs reply of type %d", rxh->type);
+ }
+
+ return;
+
+trunc:
+ printf(" [|fs]");
+}
+
+/*
+ * Print out an AFS ACL string. An AFS ACL is a string that has the
+ * following format:
+ *
+ * <positive> <negative>
+ * <uid1> <aclbits1>
+ * ....
+ *
+ * "positive" and "negative" are integers which contain the number of
+ * positive and negative ACL's in the string. The uid/aclbits pair are
+ * ASCII strings containing the UID/PTS record and and a ascii number
+ * representing a logical OR of all the ACL permission bits
+ */
+
+static void
+acl_print(u_char *s, int maxsize, u_char *end)
+{
+ int pos, neg, acl;
+ int n, i;
+ char *user;
+ char fmt[1024];
+
+ if ((user = (char *)malloc(maxsize)) == NULL)
+ return;
+
+ if (sscanf((char *) s, "%d %d\n%n", &pos, &neg, &n) != 2)
+ goto finish;
+
+ s += n;
+
+ if (s > end)
+ goto finish;
+
+ /*
+ * This wacky order preserves the order used by the "fs" command
+ */
+
+#define ACLOUT(acl) \
+ if (acl & PRSFS_READ) \
+ printf("r"); \
+ if (acl & PRSFS_LOOKUP) \
+ printf("l"); \
+ if (acl & PRSFS_INSERT) \
+ printf("i"); \
+ if (acl & PRSFS_DELETE) \
+ printf("d"); \
+ if (acl & PRSFS_WRITE) \
+ printf("w"); \
+ if (acl & PRSFS_LOCK) \
+ printf("k"); \
+ if (acl & PRSFS_ADMINISTER) \
+ printf("a");
+
+ for (i = 0; i < pos; i++) {
+ snprintf(fmt, sizeof(fmt), "%%%ds %%d\n%%n", maxsize - 1);
+ if (sscanf((char *) s, fmt, user, &acl, &n) != 2)
+ goto finish;
+ s += n;
+ printf(" +{");
+ fn_print((u_char *)user, NULL);
+ printf(" ");
+ ACLOUT(acl);
+ printf("}");
+ if (s > end)
+ goto finish;
+ }
+
+ for (i = 0; i < neg; i++) {
+ snprintf(fmt, sizeof(fmt), "%%%ds %%d\n%%n", maxsize - 1);
+ if (sscanf((char *) s, fmt, user, &acl, &n) != 2)
+ goto finish;
+ s += n;
+ printf(" -{");
+ fn_print((u_char *)user, NULL);
+ printf(" ");
+ ACLOUT(acl);
+ printf("}");
+ if (s > end)
+ goto finish;
+ }
+
+finish:
+ free(user);
+ return;
+}
+
+#undef ACLOUT
+
+/*
+ * Handle calls to the AFS callback service
+ */
+
+static void
+cb_print(register const u_char *bp, int length)
+{
+ int cb_op;
+ unsigned long i;
+
+ if (length <= (int)sizeof(struct rx_header))
+ return;
+
+ if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) {
+ goto trunc;
+ }
+
+ /*
+ * Print out the afs call we're invoking. The table used here was
+ * gleaned from fsint/afscbint.xg
+ */
+
+ cb_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
+
+ printf(" cb call %s", tok2str(cb_req, "op#%d", cb_op));
+
+ bp += sizeof(struct rx_header) + 4;
+
+ /*
+ * Print out the afs call we're invoking. The table used here was
+ * gleaned from fsint/afscbint.xg
+ */
+
+ switch (cb_op) {
+ case 204: /* Callback */
+ {
+ unsigned long j, t;
+ TCHECK2(bp[0], 4);
+ j = EXTRACT_32BITS(bp);
+ bp += sizeof(int32_t);
+
+ for (i = 0; i < j; i++) {
+ FIDOUT();
+ if (i != j - 1)
+ printf(",");
+ }
+
+ if (j == 0)
+ printf(" <none!>");
+
+ j = EXTRACT_32BITS(bp);
+ bp += sizeof(int32_t);
+
+ if (j != 0)
+ printf(";");
+
+ for (i = 0; i < j; i++) {
+ printf(" ver");
+ INTOUT();
+ printf(" expires");
+ DATEOUT();
+ TCHECK2(bp[0], 4);
+ t = EXTRACT_32BITS(bp);
+ bp += sizeof(int32_t);
+ tok2str(cb_types, "type %d", t);
+ }
+ }
+ case 214: {
+ printf(" afsuuid");
+ AFSUUIDOUT();
+ break;
+ }
+ default:
+ ;
+ }
+
+ return;
+
+trunc:
+ printf(" [|cb]");
+}
+
+/*
+ * Handle replies to the AFS Callback Service
+ */
+
+static void
+cb_reply_print(register const u_char *bp, int length, int32_t opcode)
+{
+ struct rx_header *rxh;
+
+ if (length <= (int)sizeof(struct rx_header))
+ return;
+
+ rxh = (struct rx_header *) bp;
+
+ /*
+ * Print out the afs call we're invoking. The table used here was
+ * gleaned from fsint/afscbint.xg
+ */
+
+ printf(" cb reply %s", tok2str(cb_req, "op#%d", opcode));
+
+ bp += sizeof(struct rx_header);
+
+ /*
+ * If it was a data packet, interpret the response.
+ */
+
+ if (rxh->type == RX_PACKET_TYPE_DATA)
+ switch (opcode) {
+ case 213: /* InitCallBackState3 */
+ AFSUUIDOUT();
+ break;
+ default:
+ ;
+ }
+ else {
+ /*
+ * Otherwise, just print out the return code
+ */
+ printf(" errcode");
+ INTOUT();
+ }
+
+ return;
+
+trunc:
+ printf(" [|cb]");
+}
+
+/*
+ * Handle calls to the AFS protection database server
+ */
+
+static void
+prot_print(register const u_char *bp, int length)
+{
+ unsigned long i;
+ int pt_op;
+
+ if (length <= (int)sizeof(struct rx_header))
+ return;
+
+ if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) {
+ goto trunc;
+ }
+
+ /*
+ * Print out the afs call we're invoking. The table used here was
+ * gleaned from ptserver/ptint.xg
+ */
+
+ pt_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
+
+ printf(" pt");
+
+ if (is_ubik(pt_op)) {
+ ubik_print(bp);
+ return;
+ }
+
+ printf(" call %s", tok2str(pt_req, "op#%d", pt_op));
+
+ /*
+ * Decode some of the arguments to the PT calls
+ */
+
+ bp += sizeof(struct rx_header) + 4;
+
+ switch (pt_op) {
+ case 500: /* I New User */
+ STROUT(PRNAMEMAX);
+ printf(" id");
+ INTOUT();
+ printf(" oldid");
+ INTOUT();
+ break;
+ case 501: /* Where is it */
+ case 506: /* Delete */
+ case 508: /* Get CPS */
+ case 512: /* List entry */
+ case 514: /* List elements */
+ case 517: /* List owned */
+ case 518: /* Get CPS2 */
+ case 519: /* Get host CPS */
+ case 530: /* List super groups */
+ printf(" id");
+ INTOUT();
+ break;
+ case 502: /* Dump entry */
+ printf(" pos");
+ INTOUT();
+ break;
+ case 503: /* Add to group */
+ case 507: /* Remove from group */
+ case 515: /* Is a member of? */
+ printf(" uid");
+ INTOUT();
+ printf(" gid");
+ INTOUT();
+ break;
+ case 504: /* Name to ID */
+ {
+ unsigned long j;
+ TCHECK2(bp[0], 4);
+ j = EXTRACT_32BITS(bp);
+ bp += sizeof(int32_t);
+
+ /*
+ * Who designed this chicken-shit protocol?
+ *
+ * Each character is stored as a 32-bit
+ * integer!
+ */
+
+ for (i = 0; i < j; i++) {
+ VECOUT(PRNAMEMAX);
+ }
+ if (j == 0)
+ printf(" <none!>");
+ }
+ break;
+ case 505: /* Id to name */
+ {
+ unsigned long j;
+ printf(" ids:");
+ TCHECK2(bp[0], 4);
+ i = EXTRACT_32BITS(bp);
+ bp += sizeof(int32_t);
+ for (j = 0; j < i; j++)
+ INTOUT();
+ if (j == 0)
+ printf(" <none!>");
+ }
+ break;
+ case 509: /* New entry */
+ STROUT(PRNAMEMAX);
+ printf(" flag");
+ INTOUT();
+ printf(" oid");
+ INTOUT();
+ break;
+ case 511: /* Set max */
+ printf(" id");
+ INTOUT();
+ printf(" gflag");
+ INTOUT();
+ break;
+ case 513: /* Change entry */
+ printf(" id");
+ INTOUT();
+ STROUT(PRNAMEMAX);
+ printf(" oldid");
+ INTOUT();
+ printf(" newid");
+ INTOUT();
+ break;
+ case 520: /* Update entry */
+ printf(" id");
+ INTOUT();
+ STROUT(PRNAMEMAX);
+ break;
+ default:
+ ;
+ }
+
+
+ return;
+
+trunc:
+ printf(" [|pt]");
+}
+
+/*
+ * Handle replies to the AFS protection service
+ */
+
+static void
+prot_reply_print(register const u_char *bp, int length, int32_t opcode)
+{
+ struct rx_header *rxh;
+ unsigned long i;
+
+ if (length < (int)sizeof(struct rx_header))
+ return;
+
+ rxh = (struct rx_header *) bp;
+
+ /*
+ * Print out the afs call we're invoking. The table used here was
+ * gleaned from ptserver/ptint.xg. Check to see if it's a
+ * Ubik call, however.
+ */
+
+ printf(" pt");
+
+ if (is_ubik(opcode)) {
+ ubik_reply_print(bp, length, opcode);
+ return;
+ }
+
+ printf(" reply %s", tok2str(pt_req, "op#%d", opcode));
+
+ bp += sizeof(struct rx_header);
+
+ /*
+ * If it was a data packet, interpret the response
+ */
+
+ if (rxh->type == RX_PACKET_TYPE_DATA)
+ switch (opcode) {
+ case 504: /* Name to ID */
+ {
+ unsigned long j;
+ printf(" ids:");
+ TCHECK2(bp[0], 4);
+ i = EXTRACT_32BITS(bp);
+ bp += sizeof(int32_t);
+ for (j = 0; j < i; j++)
+ INTOUT();
+ if (j == 0)
+ printf(" <none!>");
+ }
+ break;
+ case 505: /* ID to name */
+ {
+ unsigned long j;
+ TCHECK2(bp[0], 4);
+ j = EXTRACT_32BITS(bp);
+ bp += sizeof(int32_t);
+
+ /*
+ * Who designed this chicken-shit protocol?
+ *
+ * Each character is stored as a 32-bit
+ * integer!
+ */
+
+ for (i = 0; i < j; i++) {
+ VECOUT(PRNAMEMAX);
+ }
+ if (j == 0)
+ printf(" <none!>");
+ }
+ break;
+ case 508: /* Get CPS */
+ case 514: /* List elements */
+ case 517: /* List owned */
+ case 518: /* Get CPS2 */
+ case 519: /* Get host CPS */
+ {
+ unsigned long j;
+ TCHECK2(bp[0], 4);
+ j = EXTRACT_32BITS(bp);
+ bp += sizeof(int32_t);
+ for (i = 0; i < j; i++) {
+ INTOUT();
+ }
+ if (j == 0)
+ printf(" <none!>");
+ }
+ break;
+ case 510: /* List max */
+ printf(" maxuid");
+ INTOUT();
+ printf(" maxgid");
+ INTOUT();
+ break;
+ default:
+ ;
+ }
+ else {
+ /*
+ * Otherwise, just print out the return code
+ */
+ printf(" errcode");
+ INTOUT();
+ }
+
+ return;
+
+trunc:
+ printf(" [|pt]");
+}
+
+/*
+ * Handle calls to the AFS volume location database service
+ */
+
+static void
+vldb_print(register const u_char *bp, int length)
+{
+ int vldb_op;
+ unsigned long i;
+
+ if (length <= (int)sizeof(struct rx_header))
+ return;
+
+ if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) {
+ goto trunc;
+ }
+
+ /*
+ * Print out the afs call we're invoking. The table used here was
+ * gleaned from vlserver/vldbint.xg
+ */
+
+ vldb_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
+
+ printf(" vldb");
+
+ if (is_ubik(vldb_op)) {
+ ubik_print(bp);
+ return;
+ }
+ printf(" call %s", tok2str(vldb_req, "op#%d", vldb_op));
+
+ /*
+ * Decode some of the arguments to the VLDB calls
+ */
+
+ bp += sizeof(struct rx_header) + 4;
+
+ switch (vldb_op) {
+ case 501: /* Create new volume */
+ case 517: /* Create entry N */
+ VECOUT(VLNAMEMAX);
+ break;
+ case 502: /* Delete entry */
+ case 503: /* Get entry by ID */
+ case 507: /* Update entry */
+ case 508: /* Set lock */
+ case 509: /* Release lock */
+ case 518: /* Get entry by ID N */
+ printf(" volid");
+ INTOUT();
+ TCHECK2(bp[0], sizeof(int32_t));
+ i = EXTRACT_32BITS(bp);
+ bp += sizeof(int32_t);
+ if (i <= 2)
+ printf(" type %s", voltype[i]);
+ break;
+ case 504: /* Get entry by name */
+ case 519: /* Get entry by name N */
+ case 524: /* Update entry by name */
+ case 527: /* Get entry by name U */
+ STROUT(VLNAMEMAX);
+ break;
+ case 505: /* Get new vol id */
+ printf(" bump");
+ INTOUT();
+ break;
+ case 506: /* Replace entry */
+ case 520: /* Replace entry N */
+ printf(" volid");
+ INTOUT();
+ TCHECK2(bp[0], sizeof(int32_t));
+ i = EXTRACT_32BITS(bp);
+ bp += sizeof(int32_t);
+ if (i <= 2)
+ printf(" type %s", voltype[i]);
+ VECOUT(VLNAMEMAX);
+ break;
+ case 510: /* List entry */
+ case 521: /* List entry N */
+ printf(" index");
+ INTOUT();
+ break;
+ default:
+ ;
+ }
+
+ return;
+
+trunc:
+ printf(" [|vldb]");
+}
+
+/*
+ * Handle replies to the AFS volume location database service
+ */
+
+static void
+vldb_reply_print(register const u_char *bp, int length, int32_t opcode)
+{
+ struct rx_header *rxh;
+ unsigned long i;
+
+ if (length < (int)sizeof(struct rx_header))
+ return;
+
+ rxh = (struct rx_header *) bp;
+
+ /*
+ * Print out the afs call we're invoking. The table used here was
+ * gleaned from vlserver/vldbint.xg. Check to see if it's a
+ * Ubik call, however.
+ */
+
+ printf(" vldb");
+
+ if (is_ubik(opcode)) {
+ ubik_reply_print(bp, length, opcode);
+ return;
+ }
+
+ printf(" reply %s", tok2str(vldb_req, "op#%d", opcode));
+
+ bp += sizeof(struct rx_header);
+
+ /*
+ * If it was a data packet, interpret the response
+ */
+
+ if (rxh->type == RX_PACKET_TYPE_DATA)
+ switch (opcode) {
+ case 510: /* List entry */
+ printf(" count");
+ INTOUT();
+ printf(" nextindex");
+ INTOUT();
+ case 503: /* Get entry by id */
+ case 504: /* Get entry by name */
+ { unsigned long nservers, j;
+ VECOUT(VLNAMEMAX);
+ TCHECK2(bp[0], sizeof(int32_t));
+ bp += sizeof(int32_t);
+ printf(" numservers");
+ TCHECK2(bp[0], sizeof(int32_t));
+ nservers = EXTRACT_32BITS(bp);
+ bp += sizeof(int32_t);
+ printf(" %lu", nservers);
+ printf(" servers");
+ for (i = 0; i < 8; i++) {
+ TCHECK2(bp[0], sizeof(int32_t));
+ if (i < nservers)
+ printf(" %s",
+ intoa(((struct in_addr *) bp)->s_addr));
+ bp += sizeof(int32_t);
+ }
+ printf(" partitions");
+ for (i = 0; i < 8; i++) {
+ TCHECK2(bp[0], sizeof(int32_t));
+ j = EXTRACT_32BITS(bp);
+ if (i < nservers && j <= 26)
+ printf(" %c", 'a' + (int)j);
+ else if (i < nservers)
+ printf(" %lu", j);
+ bp += sizeof(int32_t);
+ }
+ TCHECK2(bp[0], 8 * sizeof(int32_t));
+ bp += 8 * sizeof(int32_t);
+ printf(" rwvol");
+ UINTOUT();
+ printf(" rovol");
+ UINTOUT();
+ printf(" backup");
+ UINTOUT();
+ }
+ break;
+ case 505: /* Get new volume ID */
+ printf(" newvol");
+ UINTOUT();
+ break;
+ case 521: /* List entry */
+ case 529: /* List entry U */
+ printf(" count");
+ INTOUT();
+ printf(" nextindex");
+ INTOUT();
+ case 518: /* Get entry by ID N */
+ case 519: /* Get entry by name N */
+ { unsigned long nservers, j;
+ VECOUT(VLNAMEMAX);
+ printf(" numservers");
+ TCHECK2(bp[0], sizeof(int32_t));
+ nservers = EXTRACT_32BITS(bp);
+ bp += sizeof(int32_t);
+ printf(" %lu", nservers);
+ printf(" servers");
+ for (i = 0; i < 13; i++) {
+ TCHECK2(bp[0], sizeof(int32_t));
+ if (i < nservers)
+ printf(" %s",
+ intoa(((struct in_addr *) bp)->s_addr));
+ bp += sizeof(int32_t);
+ }
+ printf(" partitions");
+ for (i = 0; i < 13; i++) {
+ TCHECK2(bp[0], sizeof(int32_t));
+ j = EXTRACT_32BITS(bp);
+ if (i < nservers && j <= 26)
+ printf(" %c", 'a' + (int)j);
+ else if (i < nservers)
+ printf(" %lu", j);
+ bp += sizeof(int32_t);
+ }
+ TCHECK2(bp[0], 13 * sizeof(int32_t));
+ bp += 13 * sizeof(int32_t);
+ printf(" rwvol");
+ UINTOUT();
+ printf(" rovol");
+ UINTOUT();
+ printf(" backup");
+ UINTOUT();
+ }
+ break;
+ case 526: /* Get entry by ID U */
+ case 527: /* Get entry by name U */
+ { unsigned long nservers, j;
+ VECOUT(VLNAMEMAX);
+ printf(" numservers");
+ TCHECK2(bp[0], sizeof(int32_t));
+ nservers = EXTRACT_32BITS(bp);
+ bp += sizeof(int32_t);
+ printf(" %lu", nservers);
+ printf(" servers");
+ for (i = 0; i < 13; i++) {
+ if (i < nservers) {
+ printf(" afsuuid");
+ AFSUUIDOUT();
+ } else {
+ TCHECK2(bp[0], 44);
+ bp += 44;
+ }
+ }
+ TCHECK2(bp[0], 4 * 13);
+ bp += 4 * 13;
+ printf(" partitions");
+ for (i = 0; i < 13; i++) {
+ TCHECK2(bp[0], sizeof(int32_t));
+ j = EXTRACT_32BITS(bp);
+ if (i < nservers && j <= 26)
+ printf(" %c", 'a' + (int)j);
+ else if (i < nservers)
+ printf(" %lu", j);
+ bp += sizeof(int32_t);
+ }
+ TCHECK2(bp[0], 13 * sizeof(int32_t));
+ bp += 13 * sizeof(int32_t);
+ printf(" rwvol");
+ UINTOUT();
+ printf(" rovol");
+ UINTOUT();
+ printf(" backup");
+ UINTOUT();
+ }
+ default:
+ ;
+ }
+
+ else {
+ /*
+ * Otherwise, just print out the return code
+ */
+ printf(" errcode");
+ INTOUT();
+ }
+
+ return;
+
+trunc:
+ printf(" [|vldb]");
+}
+
+/*
+ * Handle calls to the AFS Kerberos Authentication service
+ */
+
+static void
+kauth_print(register const u_char *bp, int length)
+{
+ int kauth_op;
+
+ if (length <= (int)sizeof(struct rx_header))
+ return;
+
+ if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) {
+ goto trunc;
+ }
+
+ /*
+ * Print out the afs call we're invoking. The table used here was
+ * gleaned from kauth/kauth.rg
+ */
+
+ kauth_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
+
+ printf(" kauth");
+
+ if (is_ubik(kauth_op)) {
+ ubik_print(bp);
+ return;
+ }
+
+
+ printf(" call %s", tok2str(kauth_req, "op#%d", kauth_op));
+
+ /*
+ * Decode some of the arguments to the KA calls
+ */
+
+ bp += sizeof(struct rx_header) + 4;
+
+ switch (kauth_op) {
+ case 1: /* Authenticate old */;
+ case 21: /* Authenticate */
+ case 22: /* Authenticate-V2 */
+ case 2: /* Change PW */
+ case 5: /* Set fields */
+ case 6: /* Create user */
+ case 7: /* Delete user */
+ case 8: /* Get entry */
+ case 14: /* Unlock */
+ case 15: /* Lock status */
+ printf(" principal");
+ STROUT(KANAMEMAX);
+ STROUT(KANAMEMAX);
+ break;
+ case 3: /* GetTicket-old */
+ case 23: /* GetTicket */
+ {
+ int i;
+ printf(" kvno");
+ INTOUT();
+ printf(" domain");
+ STROUT(KANAMEMAX);
+ TCHECK2(bp[0], sizeof(int32_t));
+ i = (int) EXTRACT_32BITS(bp);
+ bp += sizeof(int32_t);
+ TCHECK2(bp[0], i);
+ bp += i;
+ printf(" principal");
+ STROUT(KANAMEMAX);
+ STROUT(KANAMEMAX);
+ break;
+ }
+ case 4: /* Set Password */
+ printf(" principal");
+ STROUT(KANAMEMAX);
+ STROUT(KANAMEMAX);
+ printf(" kvno");
+ INTOUT();
+ break;
+ case 12: /* Get password */
+ printf(" name");
+ STROUT(KANAMEMAX);
+ break;
+ default:
+ ;
+ }
+
+ return;
+
+trunc:
+ printf(" [|kauth]");
+}
+
+/*
+ * Handle replies to the AFS Kerberos Authentication Service
+ */
+
+static void
+kauth_reply_print(register const u_char *bp, int length, int32_t opcode)
+{
+ struct rx_header *rxh;
+
+ if (length <= (int)sizeof(struct rx_header))
+ return;
+
+ rxh = (struct rx_header *) bp;
+
+ /*
+ * Print out the afs call we're invoking. The table used here was
+ * gleaned from kauth/kauth.rg
+ */
+
+ printf(" kauth");
+
+ if (is_ubik(opcode)) {
+ ubik_reply_print(bp, length, opcode);
+ return;
+ }
+
+ printf(" reply %s", tok2str(kauth_req, "op#%d", opcode));
+
+ bp += sizeof(struct rx_header);
+
+ /*
+ * If it was a data packet, interpret the response.
+ */
+
+ if (rxh->type == RX_PACKET_TYPE_DATA)
+ /* Well, no, not really. Leave this for later */
+ ;
+ else {
+ /*
+ * Otherwise, just print out the return code
+ */
+ printf(" errcode");
+ INTOUT();
+ }
+
+ return;
+
+trunc:
+ printf(" [|kauth]");
+}
+
+/*
+ * Handle calls to the AFS Volume location service
+ */
+
+static void
+vol_print(register const u_char *bp, int length)
+{
+ int vol_op;
+
+ if (length <= (int)sizeof(struct rx_header))
+ return;
+
+ if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) {
+ goto trunc;
+ }
+
+ /*
+ * Print out the afs call we're invoking. The table used here was
+ * gleaned from volser/volint.xg
+ */
+
+ vol_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
+
+ printf(" vol call %s", tok2str(vol_req, "op#%d", vol_op));
+
+ bp += sizeof(struct rx_header) + 4;
+
+ switch (vol_op) {
+ case 100: /* Create volume */
+ printf(" partition");
+ UINTOUT();
+ printf(" name");
+ STROUT(AFSNAMEMAX);
+ printf(" type");
+ UINTOUT();
+ printf(" parent");
+ UINTOUT();
+ break;
+ case 101: /* Delete volume */
+ case 107: /* Get flags */
+ printf(" trans");
+ UINTOUT();
+ break;
+ case 102: /* Restore */
+ printf(" totrans");
+ UINTOUT();
+ printf(" flags");
+ UINTOUT();
+ break;
+ case 103: /* Forward */
+ printf(" fromtrans");
+ UINTOUT();
+ printf(" fromdate");
+ DATEOUT();
+ DESTSERVEROUT();
+ printf(" desttrans");
+ INTOUT();
+ break;
+ case 104: /* End trans */
+ printf(" trans");
+ UINTOUT();
+ break;
+ case 105: /* Clone */
+ printf(" trans");
+ UINTOUT();
+ printf(" purgevol");
+ UINTOUT();
+ printf(" newtype");
+ UINTOUT();
+ printf(" newname");
+ STROUT(AFSNAMEMAX);
+ break;
+ case 106: /* Set flags */
+ printf(" trans");
+ UINTOUT();
+ printf(" flags");
+ UINTOUT();
+ break;
+ case 108: /* Trans create */
+ printf(" vol");
+ UINTOUT();
+ printf(" partition");
+ UINTOUT();
+ printf(" flags");
+ UINTOUT();
+ break;
+ case 109: /* Dump */
+ case 655537: /* Get size */
+ printf(" fromtrans");
+ UINTOUT();
+ printf(" fromdate");
+ DATEOUT();
+ break;
+ case 110: /* Get n-th volume */
+ printf(" index");
+ UINTOUT();
+ break;
+ case 111: /* Set forwarding */
+ printf(" tid");
+ UINTOUT();
+ printf(" newsite");
+ UINTOUT();
+ break;
+ case 112: /* Get name */
+ case 113: /* Get status */
+ printf(" tid");
+ break;
+ case 114: /* Signal restore */
+ printf(" name");
+ STROUT(AFSNAMEMAX);
+ printf(" type");
+ UINTOUT();
+ printf(" pid");
+ UINTOUT();
+ printf(" cloneid");
+ UINTOUT();
+ break;
+ case 116: /* List volumes */
+ printf(" partition");
+ UINTOUT();
+ printf(" flags");
+ UINTOUT();
+ break;
+ case 117: /* Set id types */
+ printf(" tid");
+ UINTOUT();
+ printf(" name");
+ STROUT(AFSNAMEMAX);
+ printf(" type");
+ UINTOUT();
+ printf(" pid");
+ UINTOUT();
+ printf(" clone");
+ UINTOUT();
+ printf(" backup");
+ UINTOUT();
+ break;
+ case 119: /* Partition info */
+ printf(" name");
+ STROUT(AFSNAMEMAX);
+ break;
+ case 120: /* Reclone */
+ printf(" tid");
+ UINTOUT();
+ break;
+ case 121: /* List one volume */
+ case 122: /* Nuke volume */
+ case 124: /* Extended List volumes */
+ case 125: /* Extended List one volume */
+ case 65536: /* Convert RO to RW volume */
+ printf(" partid");
+ UINTOUT();
+ printf(" volid");
+ UINTOUT();
+ break;
+ case 123: /* Set date */
+ printf(" tid");
+ UINTOUT();
+ printf(" date");
+ DATEOUT();
+ break;
+ case 126: /* Set info */
+ printf(" tid");
+ UINTOUT();
+ break;
+ case 128: /* Forward multiple */
+ printf(" fromtrans");
+ UINTOUT();
+ printf(" fromdate");
+ DATEOUT();
+ {
+ unsigned long i, j;
+ TCHECK2(bp[0], 4);
+ j = EXTRACT_32BITS(bp);
+ bp += sizeof(int32_t);
+ for (i = 0; i < j; i++) {
+ DESTSERVEROUT();
+ if (i != j - 1)
+ printf(",");
+ }
+ if (j == 0)
+ printf(" <none!>");
+ }
+ break;
+ case 65538: /* Dump version 2 */
+ printf(" fromtrans");
+ UINTOUT();
+ printf(" fromdate");
+ DATEOUT();
+ printf(" flags");
+ UINTOUT();
+ break;
+ default:
+ ;
+ }
+ return;
+
+trunc:
+ printf(" [|vol]");
+}
+
+/*
+ * Handle replies to the AFS Volume Service
+ */
+
+static void
+vol_reply_print(register const u_char *bp, int length, int32_t opcode)
+{
+ struct rx_header *rxh;
+
+ if (length <= (int)sizeof(struct rx_header))
+ return;
+
+ rxh = (struct rx_header *) bp;
+
+ /*
+ * Print out the afs call we're invoking. The table used here was
+ * gleaned from volser/volint.xg
+ */
+
+ printf(" vol reply %s", tok2str(vol_req, "op#%d", opcode));
+
+ bp += sizeof(struct rx_header);
+
+ /*
+ * If it was a data packet, interpret the response.
+ */
+
+ if (rxh->type == RX_PACKET_TYPE_DATA) {
+ switch (opcode) {
+ case 100: /* Create volume */
+ printf(" volid");
+ UINTOUT();
+ printf(" trans");
+ UINTOUT();
+ break;
+ case 104: /* End transaction */
+ UINTOUT();
+ break;
+ case 105: /* Clone */
+ printf(" newvol");
+ UINTOUT();
+ break;
+ case 107: /* Get flags */
+ UINTOUT();
+ break;
+ case 108: /* Transaction create */
+ printf(" trans");
+ UINTOUT();
+ break;
+ case 110: /* Get n-th volume */
+ printf(" volume");
+ UINTOUT();
+ printf(" partition");
+ UINTOUT();
+ break;
+ case 112: /* Get name */
+ STROUT(AFSNAMEMAX);
+ break;
+ case 113: /* Get status */
+ printf(" volid");
+ UINTOUT();
+ printf(" nextuniq");
+ UINTOUT();
+ printf(" type");
+ UINTOUT();
+ printf(" parentid");
+ UINTOUT();
+ printf(" clone");
+ UINTOUT();
+ printf(" backup");
+ UINTOUT();
+ printf(" restore");
+ UINTOUT();
+ printf(" maxquota");
+ UINTOUT();
+ printf(" minquota");
+ UINTOUT();
+ printf(" owner");
+ UINTOUT();
+ printf(" create");
+ DATEOUT();
+ printf(" access");
+ DATEOUT();
+ printf(" update");
+ DATEOUT();
+ printf(" expire");
+ DATEOUT();
+ printf(" backup");
+ DATEOUT();
+ printf(" copy");
+ DATEOUT();
+ break;
+ case 115: /* Old list partitions */
+ break;
+ case 116: /* List volumes */
+ case 121: /* List one volume */
+ {
+ unsigned long i, j;
+ TCHECK2(bp[0], 4);
+ j = EXTRACT_32BITS(bp);
+ bp += sizeof(int32_t);
+ for (i = 0; i < j; i++) {
+ printf(" name");
+ VECOUT(32);
+ printf(" volid");
+ UINTOUT();
+ printf(" type");
+ bp += sizeof(int32_t) * 21;
+ if (i != j - 1)
+ printf(",");
+ }
+ if (j == 0)
+ printf(" <none!>");
+ }
+ break;
+
+
+ default:
+ ;
+ }
+ } else {
+ /*
+ * Otherwise, just print out the return code
+ */
+ printf(" errcode");
+ INTOUT();
+ }
+
+ return;
+
+trunc:
+ printf(" [|vol]");
+}
+
+/*
+ * Handle calls to the AFS BOS service
+ */
+
+static void
+bos_print(register const u_char *bp, int length)
+{
+ int bos_op;
+
+ if (length <= (int)sizeof(struct rx_header))
+ return;
+
+ if (snapend - bp + 1 <= (int)(sizeof(struct rx_header) + sizeof(int32_t))) {
+ goto trunc;
+ }
+
+ /*
+ * Print out the afs call we're invoking. The table used here was
+ * gleaned from bozo/bosint.xg
+ */
+
+ bos_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
+
+ printf(" bos call %s", tok2str(bos_req, "op#%d", bos_op));
+
+ /*
+ * Decode some of the arguments to the BOS calls
+ */
+
+ bp += sizeof(struct rx_header) + 4;
+
+ switch (bos_op) {
+ case 80: /* Create B node */
+ printf(" type");
+ STROUT(BOSNAMEMAX);
+ printf(" instance");
+ STROUT(BOSNAMEMAX);
+ break;
+ case 81: /* Delete B node */
+ case 83: /* Get status */
+ case 85: /* Get instance info */
+ case 87: /* Add super user */
+ case 88: /* Delete super user */
+ case 93: /* Set cell name */
+ case 96: /* Add cell host */
+ case 97: /* Delete cell host */
+ case 104: /* Restart */
+ case 106: /* Uninstall */
+ case 108: /* Exec */
+ case 112: /* Getlog */
+ case 114: /* Get instance strings */
+ STROUT(BOSNAMEMAX);
+ break;
+ case 82: /* Set status */
+ case 98: /* Set T status */
+ STROUT(BOSNAMEMAX);
+ printf(" status");
+ INTOUT();
+ break;
+ case 86: /* Get instance parm */
+ STROUT(BOSNAMEMAX);
+ printf(" num");
+ INTOUT();
+ break;
+ case 84: /* Enumerate instance */
+ case 89: /* List super users */
+ case 90: /* List keys */
+ case 91: /* Add key */
+ case 92: /* Delete key */
+ case 95: /* Get cell host */
+ INTOUT();
+ break;
+ case 105: /* Install */
+ STROUT(BOSNAMEMAX);
+ printf(" size");
+ INTOUT();
+ printf(" flags");
+ INTOUT();
+ printf(" date");
+ INTOUT();
+ break;
+ default:
+ ;
+ }
+
+ return;
+
+trunc:
+ printf(" [|bos]");
+}
+
+/*
+ * Handle replies to the AFS BOS Service
+ */
+
+static void
+bos_reply_print(register const u_char *bp, int length, int32_t opcode)
+{
+ struct rx_header *rxh;
+
+ if (length <= (int)sizeof(struct rx_header))
+ return;
+
+ rxh = (struct rx_header *) bp;
+
+ /*
+ * Print out the afs call we're invoking. The table used here was
+ * gleaned from volser/volint.xg
+ */
+
+ printf(" bos reply %s", tok2str(bos_req, "op#%d", opcode));
+
+ bp += sizeof(struct rx_header);
+
+ /*
+ * If it was a data packet, interpret the response.
+ */
+
+ if (rxh->type == RX_PACKET_TYPE_DATA)
+ /* Well, no, not really. Leave this for later */
+ ;
+ else {
+ /*
+ * Otherwise, just print out the return code
+ */
+ printf(" errcode");
+ INTOUT();
+ }
+
+ return;
+
+trunc:
+ printf(" [|bos]");
+}
+
+/*
+ * Check to see if this is a Ubik opcode.
+ */
+
+static int
+is_ubik(u_int32_t opcode)
+{
+ if ((opcode >= VOTE_LOW && opcode <= VOTE_HIGH) ||
+ (opcode >= DISK_LOW && opcode <= DISK_HIGH))
+ return(1);
+ else
+ return(0);
+}
+
+/*
+ * Handle Ubik opcodes to any one of the replicated database services
+ */
+
+static void
+ubik_print(register const u_char *bp)
+{
+ int ubik_op;
+ int32_t temp;
+
+ /*
+ * Print out the afs call we're invoking. The table used here was
+ * gleaned from ubik/ubik_int.xg
+ */
+
+ ubik_op = EXTRACT_32BITS(bp + sizeof(struct rx_header));
+
+ printf(" ubik call %s", tok2str(ubik_req, "op#%d", ubik_op));
+
+ /*
+ * Decode some of the arguments to the Ubik calls
+ */
+
+ bp += sizeof(struct rx_header) + 4;
+
+ switch (ubik_op) {
+ case 10000: /* Beacon */
+ TCHECK2(bp[0], 4);
+ temp = EXTRACT_32BITS(bp);
+ bp += sizeof(int32_t);
+ printf(" syncsite %s", temp ? "yes" : "no");
+ printf(" votestart");
+ DATEOUT();
+ printf(" dbversion");
+ UBIK_VERSIONOUT();
+ printf(" tid");
+ UBIK_VERSIONOUT();
+ break;
+ case 10003: /* Get sync site */
+ printf(" site");
+ UINTOUT();
+ break;
+ case 20000: /* Begin */
+ case 20001: /* Commit */
+ case 20007: /* Abort */
+ case 20008: /* Release locks */
+ case 20010: /* Writev */
+ printf(" tid");
+ UBIK_VERSIONOUT();
+ break;
+ case 20002: /* Lock */
+ printf(" tid");
+ UBIK_VERSIONOUT();
+ printf(" file");
+ INTOUT();
+ printf(" pos");
+ INTOUT();
+ printf(" length");
+ INTOUT();
+ temp = EXTRACT_32BITS(bp);
+ bp += sizeof(int32_t);
+ tok2str(ubik_lock_types, "type %d", temp);
+ break;
+ case 20003: /* Write */
+ printf(" tid");
+ UBIK_VERSIONOUT();
+ printf(" file");
+ INTOUT();
+ printf(" pos");
+ INTOUT();
+ break;
+ case 20005: /* Get file */
+ printf(" file");
+ INTOUT();
+ break;
+ case 20006: /* Send file */
+ printf(" file");
+ INTOUT();
+ printf(" length");
+ INTOUT();
+ printf(" dbversion");
+ UBIK_VERSIONOUT();
+ break;
+ case 20009: /* Truncate */
+ printf(" tid");
+ UBIK_VERSIONOUT();
+ printf(" file");
+ INTOUT();
+ printf(" length");
+ INTOUT();
+ break;
+ case 20012: /* Set version */
+ printf(" tid");
+ UBIK_VERSIONOUT();
+ printf(" oldversion");
+ UBIK_VERSIONOUT();
+ printf(" newversion");
+ UBIK_VERSIONOUT();
+ break;
+ default:
+ ;
+ }
+
+ return;
+
+trunc:
+ printf(" [|ubik]");
+}
+
+/*
+ * Handle Ubik replies to any one of the replicated database services
+ */
+
+static void
+ubik_reply_print(register const u_char *bp, int length, int32_t opcode)
+{
+ struct rx_header *rxh;
+
+ if (length < (int)sizeof(struct rx_header))
+ return;
+
+ rxh = (struct rx_header *) bp;
+
+ /*
+ * Print out the ubik call we're invoking. This table was gleaned
+ * from ubik/ubik_int.xg
+ */
+
+ printf(" ubik reply %s", tok2str(ubik_req, "op#%d", opcode));
+
+ bp += sizeof(struct rx_header);
+
+ /*
+ * If it was a data packet, print out the arguments to the Ubik calls
+ */
+
+ if (rxh->type == RX_PACKET_TYPE_DATA)
+ switch (opcode) {
+ case 10000: /* Beacon */
+ printf(" vote no");
+ break;
+ case 20004: /* Get version */
+ printf(" dbversion");
+ UBIK_VERSIONOUT();
+ break;
+ default:
+ ;
+ }
+
+ /*
+ * Otherwise, print out "yes" it it was a beacon packet (because
+ * that's how yes votes are returned, go figure), otherwise
+ * just print out the error code.
+ */
+
+ else
+ switch (opcode) {
+ case 10000: /* Beacon */
+ printf(" vote yes until");
+ DATEOUT();
+ break;
+ default:
+ printf(" errcode");
+ INTOUT();
+ }
+
+ return;
+
+trunc:
+ printf(" [|ubik]");
+}
+
+/*
+ * Handle RX ACK packets.
+ */
+
+static void
+rx_ack_print(register const u_char *bp, int length)
+{
+ struct rx_ackPacket *rxa;
+ int i, start, last;
+ u_int32_t firstPacket;
+
+ if (length < (int)sizeof(struct rx_header))
+ return;
+
+ bp += sizeof(struct rx_header);
+
+ /*
+ * This may seem a little odd .... the rx_ackPacket structure
+ * contains an array of individual packet acknowledgements
+ * (used for selective ack/nack), but since it's variable in size,
+ * we don't want to truncate based on the size of the whole
+ * rx_ackPacket structure.
+ */
+
+ TCHECK2(bp[0], sizeof(struct rx_ackPacket) - RX_MAXACKS);
+
+ rxa = (struct rx_ackPacket *) bp;
+ bp += (sizeof(struct rx_ackPacket) - RX_MAXACKS);
+
+ /*
+ * Print out a few useful things from the ack packet structure
+ */
+
+ if (vflag > 2)
+ printf(" bufspace %d maxskew %d",
+ (int) EXTRACT_16BITS(&rxa->bufferSpace),
+ (int) EXTRACT_16BITS(&rxa->maxSkew));
+
+ firstPacket = EXTRACT_32BITS(&rxa->firstPacket);
+ printf(" first %d serial %d reason %s",
+ firstPacket, EXTRACT_32BITS(&rxa->serial),
+ tok2str(rx_ack_reasons, "#%d", (int) rxa->reason));
+
+ /*
+ * Okay, now we print out the ack array. The way _this_ works
+ * is that we start at "first", and step through the ack array.
+ * If we have a contiguous range of acks/nacks, try to
+ * collapse them into a range.
+ *
+ * If you're really clever, you might have noticed that this
+ * doesn't seem quite correct. Specifically, due to structure
+ * padding, sizeof(struct rx_ackPacket) - RX_MAXACKS won't actually
+ * yield the start of the ack array (because RX_MAXACKS is 255
+ * and the structure will likely get padded to a 2 or 4 byte
+ * boundary). However, this is the way it's implemented inside
+ * of AFS - the start of the extra fields are at
+ * sizeof(struct rx_ackPacket) - RX_MAXACKS + nAcks, which _isn't_
+ * the exact start of the ack array. Sigh. That's why we aren't
+ * using bp, but instead use rxa->acks[]. But nAcks gets added
+ * to bp after this, so bp ends up at the right spot. Go figure.
+ */
+
+ if (rxa->nAcks != 0) {
+
+ TCHECK2(bp[0], rxa->nAcks);
+
+ /*
+ * Sigh, this is gross, but it seems to work to collapse
+ * ranges correctly.
+ */
+
+ for (i = 0, start = last = -2; i < rxa->nAcks; i++)
+ if (rxa->acks[i] == RX_ACK_TYPE_ACK) {
+
+ /*
+ * I figured this deserved _some_ explanation.
+ * First, print "acked" and the packet seq
+ * number if this is the first time we've
+ * seen an acked packet.
+ */
+
+ if (last == -2) {
+ printf(" acked %d",
+ firstPacket + i);
+ start = i;
+ }
+
+ /*
+ * Otherwise, if the there is a skip in
+ * the range (such as an nacked packet in
+ * the middle of some acked packets),
+ * then print the current packet number
+ * seperated from the last number by
+ * a comma.
+ */
+
+ else if (last != i - 1) {
+ printf(",%d", firstPacket + i);
+ start = i;
+ }
+
+ /*
+ * We always set last to the value of
+ * the last ack we saw. Conversely, start
+ * is set to the value of the first ack
+ * we saw in a range.
+ */
+
+ last = i;
+
+ /*
+ * Okay, this bit a code gets executed when
+ * we hit a nack ... in _this_ case we
+ * want to print out the range of packets
+ * that were acked, so we need to print
+ * the _previous_ packet number seperated
+ * from the first by a dash (-). Since we
+ * already printed the first packet above,
+ * just print the final packet. Don't
+ * do this if there will be a single-length
+ * range.
+ */
+ } else if (last == i - 1 && start != last)
+ printf("-%d", firstPacket + i - 1);
+
+ /*
+ * So, what's going on here? We ran off the end of the
+ * ack list, and if we got a range we need to finish it up.
+ * So we need to determine if the last packet in the list
+ * was an ack (if so, then last will be set to it) and
+ * we need to see if the last range didn't start with the
+ * last packet (because if it _did_, then that would mean
+ * that the packet number has already been printed and
+ * we don't need to print it again).
+ */
+
+ if (last == i - 1 && start != last)
+ printf("-%d", firstPacket + i - 1);
+
+ /*
+ * Same as above, just without comments
+ */
+
+ for (i = 0, start = last = -2; i < rxa->nAcks; i++)
+ if (rxa->acks[i] == RX_ACK_TYPE_NACK) {
+ if (last == -2) {
+ printf(" nacked %d",
+ firstPacket + i);
+ start = i;
+ } else if (last != i - 1) {
+ printf(",%d", firstPacket + i);
+ start = i;
+ }
+ last = i;
+ } else if (last == i - 1 && start != last)
+ printf("-%d", firstPacket + i - 1);
+
+ if (last == i - 1 && start != last)
+ printf("-%d", firstPacket + i - 1);
+
+ bp += rxa->nAcks;
+ }
+
+
+ /*
+ * These are optional fields; depending on your version of AFS,
+ * you may or may not see them
+ */
+
+#define TRUNCRET(n) if (snapend - bp + 1 <= n) return;
+
+ if (vflag > 1) {
+ TRUNCRET(4);
+ printf(" ifmtu");
+ INTOUT();
+
+ TRUNCRET(4);
+ printf(" maxmtu");
+ INTOUT();
+
+ TRUNCRET(4);
+ printf(" rwind");
+ INTOUT();
+
+ TRUNCRET(4);
+ printf(" maxpackets");
+ INTOUT();
+ }
+
+ return;
+
+trunc:
+ printf(" [|ack]");
+}
+#undef TRUNCRET
diff --git a/freebsd/contrib/tcpdump/print-sctp.c b/freebsd/contrib/tcpdump/print-sctp.c
new file mode 100644
index 00000000..afd3f7d2
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-sctp.c
@@ -0,0 +1,409 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/* Copyright (c) 2001 NETLAB, Temple University
+ * Copyright (c) 2001 Protocol Engineering Lab, University of Delaware
+ *
+ * Jerry Heinz <gheinz@astro.temple.edu>
+ * John Fiore <jfiore@joda.cis.temple.edu>
+ * Armando L. Caro Jr. <acaro@cis.udel.edu>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the University nor of the Laboratory may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+"@(#) $Header: /tcpdump/master/tcpdump/print-sctp.c,v 1.21 2007-09-13 18:03:49 guy Exp $ (NETLAB/PEL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include "sctpHeader.h"
+#include "sctpConstants.h"
+#include <assert.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h" /* must come after interface.h */
+#include "ip.h"
+#ifdef INET6
+#include "ip6.h"
+#endif
+
+#define CHAN_HP 6704
+#define CHAN_MP 6705
+#define CHAN_LP 6706
+
+struct tok ForCES_channels[] = {
+ { CHAN_HP, "ForCES HP" },
+ { CHAN_MP, "ForCES MP" },
+ { CHAN_LP, "ForCES LP" },
+ { 0, NULL }
+};
+
+static inline int isForCES_port(u_short Port)
+{
+ if (Port == CHAN_HP)
+ return 1;
+ if (Port == CHAN_MP)
+ return 1;
+ if (Port == CHAN_LP)
+ return 1;
+
+ return 0;
+}
+
+void sctp_print(const u_char *bp, /* beginning of sctp packet */
+ const u_char *bp2, /* beginning of enclosing */
+ u_int sctpPacketLength) /* ip packet */
+{
+ const struct sctpHeader *sctpPktHdr;
+ const struct ip *ip;
+#ifdef INET6
+ const struct ip6_hdr *ip6;
+#endif
+ const void *endPacketPtr;
+ u_short sourcePort, destPort;
+ int chunkCount;
+ const struct sctpChunkDesc *chunkDescPtr;
+ const void *nextChunk;
+ const char *sep;
+ int isforces = 0;
+
+
+ sctpPktHdr = (const struct sctpHeader*) bp;
+ endPacketPtr = (const u_char*)sctpPktHdr+sctpPacketLength;
+
+ if( (u_long) endPacketPtr > (u_long) snapend)
+ endPacketPtr = (const void *) snapend;
+ ip = (struct ip *)bp2;
+#ifdef INET6
+ if (IP_V(ip) == 6)
+ ip6 = (const struct ip6_hdr *)bp2;
+ else
+ ip6 = NULL;
+#endif /*INET6*/
+ TCHECK(*sctpPktHdr);
+
+ if (sctpPacketLength < sizeof(struct sctpHeader))
+ {
+ (void)printf("truncated-sctp - %ld bytes missing!",
+ (long)sctpPacketLength-sizeof(struct sctpHeader));
+ return;
+ }
+
+ /* sctpPacketLength -= sizeof(struct sctpHeader); packet length */
+ /* is now only as long as the payload */
+
+ sourcePort = EXTRACT_16BITS(&sctpPktHdr->source);
+ destPort = EXTRACT_16BITS(&sctpPktHdr->destination);
+
+#ifdef INET6
+ if (ip6) {
+ (void)printf("%s.%d > %s.%d: sctp",
+ ip6addr_string(&ip6->ip6_src),
+ sourcePort,
+ ip6addr_string(&ip6->ip6_dst),
+ destPort);
+ } else
+#endif /*INET6*/
+ {
+ (void)printf("%s.%d > %s.%d: sctp",
+ ipaddr_string(&ip->ip_src),
+ sourcePort,
+ ipaddr_string(&ip->ip_dst),
+ destPort);
+ }
+ fflush(stdout);
+
+ if (isForCES_port(sourcePort)) {
+ printf("[%s]", tok2str(ForCES_channels, NULL, sourcePort));
+ isforces = 1;
+ }
+ if (isForCES_port(destPort)) {
+ printf("[%s]", tok2str(ForCES_channels, NULL, destPort));
+ isforces = 1;
+ }
+
+ if (vflag >= 2)
+ sep = "\n\t";
+ else
+ sep = " (";
+ /* cycle through all chunks, printing information on each one */
+ for (chunkCount = 0,
+ chunkDescPtr = (const struct sctpChunkDesc *)
+ ((const u_char*) sctpPktHdr + sizeof(struct sctpHeader));
+ chunkDescPtr != NULL &&
+ ( (const void *)
+ ((const u_char *) chunkDescPtr + sizeof(struct sctpChunkDesc))
+ <= endPacketPtr);
+
+ chunkDescPtr = (const struct sctpChunkDesc *) nextChunk, chunkCount++)
+ {
+ u_int16_t chunkLength;
+ const u_char *chunkEnd;
+ u_int16_t align;
+
+ TCHECK(*chunkDescPtr);
+ chunkLength = EXTRACT_16BITS(&chunkDescPtr->chunkLength);
+ if (chunkLength < sizeof(*chunkDescPtr)) {
+ printf("%s%d) [Bad chunk length %u]", sep, chunkCount+1, chunkLength);
+ break;
+ }
+
+ TCHECK2(*((u_int8_t *)chunkDescPtr), chunkLength);
+ chunkEnd = ((const u_char*)chunkDescPtr + chunkLength);
+
+ align=chunkLength % 4;
+ if (align != 0)
+ align = 4 - align;
+
+ nextChunk = (const void *) (chunkEnd + align);
+
+ printf("%s%d) ", sep, chunkCount+1);
+ switch (chunkDescPtr->chunkID)
+ {
+ case SCTP_DATA :
+ {
+ const struct sctpDataPart *dataHdrPtr;
+
+ printf("[DATA] ");
+
+ if ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED)
+ == SCTP_DATA_UNORDERED)
+ printf("(U)");
+
+ if ((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG)
+ == SCTP_DATA_FIRST_FRAG)
+ printf("(B)");
+
+ if ((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG)
+ == SCTP_DATA_LAST_FRAG)
+ printf("(E)");
+
+ if( ((chunkDescPtr->chunkFlg & SCTP_DATA_UNORDERED)
+ == SCTP_DATA_UNORDERED)
+ ||
+ ((chunkDescPtr->chunkFlg & SCTP_DATA_FIRST_FRAG)
+ == SCTP_DATA_FIRST_FRAG)
+ ||
+ ((chunkDescPtr->chunkFlg & SCTP_DATA_LAST_FRAG)
+ == SCTP_DATA_LAST_FRAG) )
+ printf(" ");
+
+ dataHdrPtr=(const struct sctpDataPart*)(chunkDescPtr+1);
+
+ printf("[TSN: %u] ", EXTRACT_32BITS(&dataHdrPtr->TSN));
+ printf("[SID: %u] ", EXTRACT_16BITS(&dataHdrPtr->streamId));
+ printf("[SSEQ %u] ", EXTRACT_16BITS(&dataHdrPtr->sequence));
+ printf("[PPID 0x%x] ", EXTRACT_32BITS(&dataHdrPtr->payloadtype));
+ fflush(stdout);
+ if (isforces) {
+ const u_char *payloadPtr;
+ u_int chunksize = sizeof(struct sctpDataPart)+
+ sizeof(struct sctpChunkDesc);
+ payloadPtr = (const u_char *) (dataHdrPtr + 1);
+ if (EXTRACT_16BITS(&chunkDescPtr->chunkLength) <
+ sizeof(struct sctpDataPart)+
+ sizeof(struct sctpChunkDesc)+1) {
+ /* Less than 1 byte of chunk payload */
+ printf("bogus ForCES chunk length %u]",
+ EXTRACT_16BITS(&chunkDescPtr->chunkLength));
+ return;
+ }
+
+ forces_print(payloadPtr, EXTRACT_16BITS(&chunkDescPtr->chunkLength)- chunksize);
+ } else if (vflag >= 2) { /* if verbose output is specified */
+ /* at the command line */
+ const u_char *payloadPtr;
+
+ printf("[Payload");
+
+ if (!suppress_default_print) {
+ payloadPtr = (const u_char *) (++dataHdrPtr);
+ printf(":");
+ if (EXTRACT_16BITS(&chunkDescPtr->chunkLength) <
+ sizeof(struct sctpDataPart)+
+ sizeof(struct sctpChunkDesc)+1) {
+ /* Less than 1 byte of chunk payload */
+ printf("bogus chunk length %u]",
+ EXTRACT_16BITS(&chunkDescPtr->chunkLength));
+ return;
+ }
+ default_print(payloadPtr,
+ EXTRACT_16BITS(&chunkDescPtr->chunkLength) -
+ (sizeof(struct sctpDataPart)+
+ sizeof(struct sctpChunkDesc)));
+ } else
+ printf("]");
+ }
+ break;
+ }
+ case SCTP_INITIATION :
+ {
+ const struct sctpInitiation *init;
+
+ printf("[INIT] ");
+ init=(const struct sctpInitiation*)(chunkDescPtr+1);
+ printf("[init tag: %u] ", EXTRACT_32BITS(&init->initTag));
+ printf("[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit));
+ printf("[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams));
+ printf("[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams));
+ printf("[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN));
+
+#if(0) /* ALC you can add code for optional params here */
+ if( (init+1) < chunkEnd )
+ printf(" @@@@@ UNFINISHED @@@@@@%s\n",
+ "Optional params present, but not printed.");
+#endif
+ break;
+ }
+ case SCTP_INITIATION_ACK :
+ {
+ const struct sctpInitiation *init;
+
+ printf("[INIT ACK] ");
+ init=(const struct sctpInitiation*)(chunkDescPtr+1);
+ printf("[init tag: %u] ", EXTRACT_32BITS(&init->initTag));
+ printf("[rwnd: %u] ", EXTRACT_32BITS(&init->rcvWindowCredit));
+ printf("[OS: %u] ", EXTRACT_16BITS(&init->NumPreopenStreams));
+ printf("[MIS: %u] ", EXTRACT_16BITS(&init->MaxInboundStreams));
+ printf("[init TSN: %u] ", EXTRACT_32BITS(&init->initialTSN));
+
+#if(0) /* ALC you can add code for optional params here */
+ if( (init+1) < chunkEnd )
+ printf(" @@@@@ UNFINISHED @@@@@@%s\n",
+ "Optional params present, but not printed.");
+#endif
+ break;
+ }
+ case SCTP_SELECTIVE_ACK:
+ {
+ const struct sctpSelectiveAck *sack;
+ const struct sctpSelectiveFrag *frag;
+ int fragNo, tsnNo;
+ const u_char *dupTSN;
+
+ printf("[SACK] ");
+ sack=(const struct sctpSelectiveAck*)(chunkDescPtr+1);
+ printf("[cum ack %u] ", EXTRACT_32BITS(&sack->highestConseqTSN));
+ printf("[a_rwnd %u] ", EXTRACT_32BITS(&sack->updatedRwnd));
+ printf("[#gap acks %u] ", EXTRACT_16BITS(&sack->numberOfdesc));
+ printf("[#dup tsns %u] ", EXTRACT_16BITS(&sack->numDupTsns));
+
+
+ /* print gaps */
+ for (frag = ( (const struct sctpSelectiveFrag *)
+ ((const struct sctpSelectiveAck *) sack+1)),
+ fragNo=0;
+ (const void *)frag < nextChunk && fragNo < EXTRACT_16BITS(&sack->numberOfdesc);
+ frag++, fragNo++)
+ printf("\n\t\t[gap ack block #%d: start = %u, end = %u] ",
+ fragNo+1,
+ EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentStart),
+ EXTRACT_32BITS(&sack->highestConseqTSN) + EXTRACT_16BITS(&frag->fragmentEnd));
+
+
+ /* print duplicate TSNs */
+ for (dupTSN = (const u_char *)frag, tsnNo=0;
+ (const void *) dupTSN < nextChunk && tsnNo<EXTRACT_16BITS(&sack->numDupTsns);
+ dupTSN += 4, tsnNo++)
+ printf("\n\t\t[dup TSN #%u: %u] ", tsnNo+1,
+ EXTRACT_32BITS(dupTSN));
+
+ break;
+ }
+ case SCTP_HEARTBEAT_REQUEST :
+ {
+ const struct sctpHBsender *hb;
+
+ hb=(const struct sctpHBsender*)chunkDescPtr;
+
+ printf("[HB REQ] ");
+
+ break;
+ }
+ case SCTP_HEARTBEAT_ACK :
+ printf("[HB ACK] ");
+ break;
+ case SCTP_ABORT_ASSOCIATION :
+ printf("[ABORT] ");
+ break;
+ case SCTP_SHUTDOWN :
+ printf("[SHUTDOWN] ");
+ break;
+ case SCTP_SHUTDOWN_ACK :
+ printf("[SHUTDOWN ACK] ");
+ break;
+ case SCTP_OPERATION_ERR :
+ printf("[OP ERR] ");
+ break;
+ case SCTP_COOKIE_ECHO :
+ printf("[COOKIE ECHO] ");
+ break;
+ case SCTP_COOKIE_ACK :
+ printf("[COOKIE ACK] ");
+ break;
+ case SCTP_ECN_ECHO :
+ printf("[ECN ECHO] ");
+ break;
+ case SCTP_ECN_CWR :
+ printf("[ECN CWR] ");
+ break;
+ case SCTP_SHUTDOWN_COMPLETE :
+ printf("[SHUTDOWN COMPLETE] ");
+ break;
+ case SCTP_FORWARD_CUM_TSN :
+ printf("[FOR CUM TSN] ");
+ break;
+ case SCTP_RELIABLE_CNTL :
+ printf("[REL CTRL] ");
+ break;
+ case SCTP_RELIABLE_CNTL_ACK :
+ printf("[REL CTRL ACK] ");
+ break;
+ default :
+ printf("[Unknown chunk type: 0x%x]", chunkDescPtr->chunkID);
+ return;
+ }
+
+ if (vflag < 2)
+ sep = ", (";
+ }
+ return;
+
+trunc:
+ printf("[|sctp]");
+ return;
+}
diff --git a/freebsd/contrib/tcpdump/print-sflow.c b/freebsd/contrib/tcpdump/print-sflow.c
new file mode 100644
index 00000000..a82f7e81
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-sflow.c
@@ -0,0 +1,936 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1998-2007 The TCPDUMP project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * The SFLOW protocol as per http://www.sflow.org/developers/specifications.php
+ *
+ * Original code by Carles Kishimoto <carles.kishimoto@gmail.com>
+ *
+ * Expansion and refactoring by Rick Jones <rick.jones2@hp.com>
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+"@(#) $Header: /tcpdump/master/tcpdump/print-sflow.c,v 1.1 2007-08-08 17:20:58 hannes Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+
+/*
+ * sFlow datagram
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Sflow version (2,4,5) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | IP version (1 for IPv4 | 2 for IPv6) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | IP Address AGENT (4 or 16 bytes) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Sub agent ID |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Datagram sequence number |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Switch uptime in ms |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | num samples in datagram |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+struct sflow_datagram_t {
+ u_int8_t version[4];
+ u_int8_t ip_version[4];
+ u_int8_t agent[4];
+ u_int8_t agent_id[4];
+ u_int8_t seqnum[4];
+ u_int8_t uptime[4];
+ u_int8_t samples[4];
+};
+
+struct sflow_sample_header {
+ u_int8_t format[4];
+ u_int8_t len[4];
+};
+
+#define SFLOW_FLOW_SAMPLE 1
+#define SFLOW_COUNTER_SAMPLE 2
+#define SFLOW_EXPANDED_FLOW_SAMPLE 3
+#define SFLOW_EXPANDED_COUNTER_SAMPLE 4
+
+static const struct tok sflow_format_values[] = {
+ { SFLOW_FLOW_SAMPLE, "flow sample" },
+ { SFLOW_COUNTER_SAMPLE, "counter sample" },
+ { SFLOW_EXPANDED_FLOW_SAMPLE, "expanded flow sample" },
+ { SFLOW_EXPANDED_COUNTER_SAMPLE, "expanded counter sample" },
+ { 0, NULL}
+};
+
+struct sflow_flow_sample_t {
+ u_int8_t seqnum[4];
+ u_int8_t typesource[4];
+ u_int8_t rate[4];
+ u_int8_t pool[4];
+ u_int8_t drops[4];
+ u_int8_t in_interface[4];
+ u_int8_t out_interface[4];
+ u_int8_t records[4];
+
+};
+
+struct sflow_expanded_flow_sample_t {
+ u_int8_t seqnum[4];
+ u_int8_t type[4];
+ u_int8_t index[4];
+ u_int8_t rate[4];
+ u_int8_t pool[4];
+ u_int8_t drops[4];
+ u_int8_t in_interface_format[4];
+ u_int8_t in_interface_value[4];
+ u_int8_t out_interface_format[4];
+ u_int8_t out_interface_value[4];
+ u_int8_t records[4];
+};
+
+#define SFLOW_FLOW_RAW_PACKET 1
+#define SFLOW_FLOW_ETHERNET_FRAME 2
+#define SFLOW_FLOW_IPV4_DATA 3
+#define SFLOW_FLOW_IPV6_DATA 4
+#define SFLOW_FLOW_EXTENDED_SWITCH_DATA 1001
+#define SFLOW_FLOW_EXTENDED_ROUTER_DATA 1002
+#define SFLOW_FLOW_EXTENDED_GATEWAY_DATA 1003
+#define SFLOW_FLOW_EXTENDED_USER_DATA 1004
+#define SFLOW_FLOW_EXTENDED_URL_DATA 1005
+#define SFLOW_FLOW_EXTENDED_MPLS_DATA 1006
+#define SFLOW_FLOW_EXTENDED_NAT_DATA 1007
+#define SFLOW_FLOW_EXTENDED_MPLS_TUNNEL 1008
+#define SFLOW_FLOW_EXTENDED_MPLS_VC 1009
+#define SFLOW_FLOW_EXTENDED_MPLS_FEC 1010
+#define SFLOW_FLOW_EXTENDED_MPLS_LVP_FEC 1011
+#define SFLOW_FLOW_EXTENDED_VLAN_TUNNEL 1012
+
+static const struct tok sflow_flow_type_values[] = {
+ { SFLOW_FLOW_RAW_PACKET, "Raw packet"},
+ { SFLOW_FLOW_ETHERNET_FRAME, "Ethernet frame"},
+ { SFLOW_FLOW_IPV4_DATA, "IPv4 Data"},
+ { SFLOW_FLOW_IPV6_DATA, "IPv6 Data"},
+ { SFLOW_FLOW_EXTENDED_SWITCH_DATA, "Extended Switch data"},
+ { SFLOW_FLOW_EXTENDED_ROUTER_DATA, "Extended Router data"},
+ { SFLOW_FLOW_EXTENDED_GATEWAY_DATA, "Extended Gateway data"},
+ { SFLOW_FLOW_EXTENDED_USER_DATA, "Extended User data"},
+ { SFLOW_FLOW_EXTENDED_URL_DATA, "Extended URL data"},
+ { SFLOW_FLOW_EXTENDED_MPLS_DATA, "Extended MPLS data"},
+ { SFLOW_FLOW_EXTENDED_NAT_DATA, "Extended NAT data"},
+ { SFLOW_FLOW_EXTENDED_MPLS_TUNNEL, "Extended MPLS tunnel"},
+ { SFLOW_FLOW_EXTENDED_MPLS_VC, "Extended MPLS VC"},
+ { SFLOW_FLOW_EXTENDED_MPLS_FEC, "Extended MPLS FEC"},
+ { SFLOW_FLOW_EXTENDED_MPLS_LVP_FEC, "Extended MPLS LVP FEC"},
+ { SFLOW_FLOW_EXTENDED_VLAN_TUNNEL, "Extended VLAN Tunnel"},
+ { 0, NULL}
+};
+
+#define SFLOW_HEADER_PROTOCOL_ETHERNET 1
+#define SFLOW_HEADER_PROTOCOL_IPV4 11
+#define SFLOW_HEADER_PROTOCOL_IPV6 12
+
+static const struct tok sflow_flow_raw_protocol_values[] = {
+ { SFLOW_HEADER_PROTOCOL_ETHERNET, "Ethernet"},
+ { SFLOW_HEADER_PROTOCOL_IPV4, "IPv4"},
+ { SFLOW_HEADER_PROTOCOL_IPV6, "IPv6"},
+ { 0, NULL}
+};
+
+struct sflow_expanded_flow_raw_t {
+ u_int8_t protocol[4];
+ u_int8_t length[4];
+ u_int8_t stripped_bytes[4];
+ u_int8_t header_size[4];
+};
+
+struct sflow_ethernet_frame_t {
+ u_int8_t length[4];
+ u_int8_t src_mac[8];
+ u_int8_t dst_mac[8];
+ u_int8_t type[4];
+};
+
+struct sflow_extended_switch_data_t {
+ u_int8_t src_vlan[4];
+ u_int8_t src_pri[4];
+ u_int8_t dst_vlan[4];
+ u_int8_t dst_pri[4];
+};
+
+struct sflow_counter_record_t {
+ u_int8_t format[4];
+ u_int8_t length[4];
+};
+
+struct sflow_flow_record_t {
+ u_int8_t format[4];
+ u_int8_t length[4];
+};
+
+struct sflow_counter_sample_t {
+ u_int8_t seqnum[4];
+ u_int8_t typesource[4];
+ u_int8_t records[4];
+};
+
+struct sflow_expanded_counter_sample_t {
+ u_int8_t seqnum[4];
+ u_int8_t type[4];
+ u_int8_t index[4];
+ u_int8_t records[4];
+};
+
+#define SFLOW_COUNTER_GENERIC 1
+#define SFLOW_COUNTER_ETHERNET 2
+#define SFLOW_COUNTER_TOKEN_RING 3
+#define SFLOW_COUNTER_BASEVG 4
+#define SFLOW_COUNTER_VLAN 5
+#define SFLOW_COUNTER_PROCESSOR 1001
+
+static const struct tok sflow_counter_type_values[] = {
+ { SFLOW_COUNTER_GENERIC, "Generic counter"},
+ { SFLOW_COUNTER_ETHERNET, "Ethernet counter"},
+ { SFLOW_COUNTER_TOKEN_RING, "Token ring counter"},
+ { SFLOW_COUNTER_BASEVG, "100 BaseVG counter"},
+ { SFLOW_COUNTER_VLAN, "Vlan counter"},
+ { SFLOW_COUNTER_PROCESSOR, "Processor counter"},
+ { 0, NULL}
+};
+
+#define SFLOW_IFACE_DIRECTION_UNKNOWN 0
+#define SFLOW_IFACE_DIRECTION_FULLDUPLEX 1
+#define SFLOW_IFACE_DIRECTION_HALFDUPLEX 2
+#define SFLOW_IFACE_DIRECTION_IN 3
+#define SFLOW_IFACE_DIRECTION_OUT 4
+
+static const struct tok sflow_iface_direction_values[] = {
+ { SFLOW_IFACE_DIRECTION_UNKNOWN, "unknown"},
+ { SFLOW_IFACE_DIRECTION_FULLDUPLEX, "full-duplex"},
+ { SFLOW_IFACE_DIRECTION_HALFDUPLEX, "half-duplex"},
+ { SFLOW_IFACE_DIRECTION_IN, "in"},
+ { SFLOW_IFACE_DIRECTION_OUT, "out"},
+ { 0, NULL}
+};
+
+struct sflow_generic_counter_t {
+ u_int8_t ifindex[4];
+ u_int8_t iftype[4];
+ u_int8_t ifspeed[8];
+ u_int8_t ifdirection[4];
+ u_int8_t ifstatus[4];
+ u_int8_t ifinoctets[8];
+ u_int8_t ifinunicastpkts[4];
+ u_int8_t ifinmulticastpkts[4];
+ u_int8_t ifinbroadcastpkts[4];
+ u_int8_t ifindiscards[4];
+ u_int8_t ifinerrors[4];
+ u_int8_t ifinunkownprotos[4];
+ u_int8_t ifoutoctets[8];
+ u_int8_t ifoutunicastpkts[4];
+ u_int8_t ifoutmulticastpkts[4];
+ u_int8_t ifoutbroadcastpkts[4];
+ u_int8_t ifoutdiscards[4];
+ u_int8_t ifouterrors[4];
+ u_int8_t ifpromiscmode[4];
+};
+
+struct sflow_ethernet_counter_t {
+ u_int8_t alignerrors[4];
+ u_int8_t fcserrors[4];
+ u_int8_t single_collision_frames[4];
+ u_int8_t multiple_collision_frames[4];
+ u_int8_t test_errors[4];
+ u_int8_t deferred_transmissions[4];
+ u_int8_t late_collisions[4];
+ u_int8_t excessive_collisions[4];
+ u_int8_t mac_transmit_errors[4];
+ u_int8_t carrier_sense_errors[4];
+ u_int8_t frame_too_longs[4];
+ u_int8_t mac_receive_errors[4];
+ u_int8_t symbol_errors[4];
+};
+
+struct sflow_100basevg_counter_t {
+ u_int8_t in_highpriority_frames[4];
+ u_int8_t in_highpriority_octets[8];
+ u_int8_t in_normpriority_frames[4];
+ u_int8_t in_normpriority_octets[8];
+ u_int8_t in_ipmerrors[4];
+ u_int8_t in_oversized[4];
+ u_int8_t in_data_errors[4];
+ u_int8_t in_null_addressed_frames[4];
+ u_int8_t out_highpriority_frames[4];
+ u_int8_t out_highpriority_octets[8];
+ u_int8_t transitioninto_frames[4];
+ u_int8_t hc_in_highpriority_octets[8];
+ u_int8_t hc_in_normpriority_octets[8];
+ u_int8_t hc_out_highpriority_octets[8];
+};
+
+struct sflow_vlan_counter_t {
+ u_int8_t vlan_id[4];
+ u_int8_t octets[8];
+ u_int8_t unicast_pkt[4];
+ u_int8_t multicast_pkt[4];
+ u_int8_t broadcast_pkt[4];
+ u_int8_t discards[4];
+};
+
+static int
+print_sflow_counter_generic(const u_char *pointer, u_int len) {
+
+ const struct sflow_generic_counter_t *sflow_gen_counter;
+
+ if (len < sizeof(struct sflow_generic_counter_t))
+ return 1;
+
+
+ sflow_gen_counter = (const struct sflow_generic_counter_t *)pointer;
+ printf("\n\t ifindex %u, iftype %u, ifspeed %" PRIu64 ", ifdirection %u (%s)",
+ EXTRACT_32BITS(sflow_gen_counter->ifindex),
+ EXTRACT_32BITS(sflow_gen_counter->iftype),
+ EXTRACT_64BITS(sflow_gen_counter->ifspeed),
+ EXTRACT_32BITS(sflow_gen_counter->ifdirection),
+ tok2str(sflow_iface_direction_values, "Unknown",
+ EXTRACT_32BITS(sflow_gen_counter->ifdirection)));
+ printf("\n\t ifstatus %u, adminstatus: %s, operstatus: %s",
+ EXTRACT_32BITS(sflow_gen_counter->ifstatus),
+ EXTRACT_32BITS(sflow_gen_counter->ifstatus)&1 ? "up" : "down",
+ (EXTRACT_32BITS(sflow_gen_counter->ifstatus)>>1)&1 ? "up" : "down");
+ printf("\n\t In octets %" PRIu64
+ ", unicast pkts %u, multicast pkts %u, broadcast pkts %u, discards %u",
+ EXTRACT_64BITS(sflow_gen_counter->ifinoctets),
+ EXTRACT_32BITS(sflow_gen_counter->ifinunicastpkts),
+ EXTRACT_32BITS(sflow_gen_counter->ifinmulticastpkts),
+ EXTRACT_32BITS(sflow_gen_counter->ifinbroadcastpkts),
+ EXTRACT_32BITS(sflow_gen_counter->ifindiscards));
+ printf("\n\t In errors %u, unknown protos %u",
+ EXTRACT_32BITS(sflow_gen_counter->ifinerrors),
+ EXTRACT_32BITS(sflow_gen_counter->ifinunkownprotos));
+ printf("\n\t Out octets %" PRIu64
+ ", unicast pkts %u, multicast pkts %u, broadcast pkts %u, discards %u",
+ EXTRACT_64BITS(sflow_gen_counter->ifoutoctets),
+ EXTRACT_32BITS(sflow_gen_counter->ifoutunicastpkts),
+ EXTRACT_32BITS(sflow_gen_counter->ifoutmulticastpkts),
+ EXTRACT_32BITS(sflow_gen_counter->ifoutbroadcastpkts),
+ EXTRACT_32BITS(sflow_gen_counter->ifoutdiscards));
+ printf("\n\t Out errors %u, promisc mode %u",
+ EXTRACT_32BITS(sflow_gen_counter->ifouterrors),
+ EXTRACT_32BITS(sflow_gen_counter->ifpromiscmode));
+
+ return 0;
+}
+
+static int
+print_sflow_counter_ethernet(const u_char *pointer, u_int len){
+
+ const struct sflow_ethernet_counter_t *sflow_eth_counter;
+
+ if (len < sizeof(struct sflow_ethernet_counter_t))
+ return 1;
+
+ sflow_eth_counter = (const struct sflow_ethernet_counter_t *)pointer;
+ printf("\n\t align errors %u, fcs errors %u, single collision %u, multiple collision %u, test error %u",
+ EXTRACT_32BITS(sflow_eth_counter->alignerrors),
+ EXTRACT_32BITS(sflow_eth_counter->fcserrors),
+ EXTRACT_32BITS(sflow_eth_counter->single_collision_frames),
+ EXTRACT_32BITS(sflow_eth_counter->multiple_collision_frames),
+ EXTRACT_32BITS(sflow_eth_counter->test_errors));
+ printf("\n\t deferred %u, late collision %u, excessive collision %u, mac trans error %u",
+ EXTRACT_32BITS(sflow_eth_counter->deferred_transmissions),
+ EXTRACT_32BITS(sflow_eth_counter->late_collisions),
+ EXTRACT_32BITS(sflow_eth_counter->excessive_collisions),
+ EXTRACT_32BITS(sflow_eth_counter->mac_transmit_errors));
+ printf("\n\t carrier error %u, frames too long %u, mac receive errors %u, symbol errors %u",
+ EXTRACT_32BITS(sflow_eth_counter->carrier_sense_errors),
+ EXTRACT_32BITS(sflow_eth_counter->frame_too_longs),
+ EXTRACT_32BITS(sflow_eth_counter->mac_receive_errors),
+ EXTRACT_32BITS(sflow_eth_counter->symbol_errors));
+
+ return 0;
+}
+
+static int
+print_sflow_counter_token_ring(const u_char *pointer _U_, u_int len _U_) {
+
+ return 0;
+}
+
+static int
+print_sflow_counter_basevg(const u_char *pointer, u_int len) {
+
+ const struct sflow_100basevg_counter_t *sflow_100basevg_counter;
+
+ if (len < sizeof(struct sflow_100basevg_counter_t))
+ return 1;
+
+ sflow_100basevg_counter = (const struct sflow_100basevg_counter_t *)pointer;
+ printf("\n\t in high prio frames %u, in high prio octets %" PRIu64,
+ EXTRACT_32BITS(sflow_100basevg_counter->in_highpriority_frames),
+ EXTRACT_64BITS(sflow_100basevg_counter->in_highpriority_octets));
+ printf("\n\t in norm prio frames %u, in norm prio octets %" PRIu64,
+ EXTRACT_32BITS(sflow_100basevg_counter->in_normpriority_frames),
+ EXTRACT_64BITS(sflow_100basevg_counter->in_normpriority_octets));
+ printf("\n\t in ipm errors %u, oversized %u, in data errors %u, null addressed frames %u",
+ EXTRACT_32BITS(sflow_100basevg_counter->in_ipmerrors),
+ EXTRACT_32BITS(sflow_100basevg_counter->in_oversized),
+ EXTRACT_32BITS(sflow_100basevg_counter->in_data_errors),
+ EXTRACT_32BITS(sflow_100basevg_counter->in_null_addressed_frames));
+ printf("\n\t out high prio frames %u, out high prio octets %" PRIu64
+ ", trans into frames %u",
+ EXTRACT_32BITS(sflow_100basevg_counter->out_highpriority_frames),
+ EXTRACT_64BITS(sflow_100basevg_counter->out_highpriority_octets),
+ EXTRACT_32BITS(sflow_100basevg_counter->transitioninto_frames));
+ printf("\n\t in hc high prio octets %" PRIu64
+ ", in hc norm prio octets %" PRIu64
+ ", out hc high prio octets %" PRIu64,
+ EXTRACT_64BITS(sflow_100basevg_counter->hc_in_highpriority_octets),
+ EXTRACT_64BITS(sflow_100basevg_counter->hc_in_normpriority_octets),
+ EXTRACT_64BITS(sflow_100basevg_counter->hc_out_highpriority_octets));
+
+ return 0;
+}
+
+static int
+print_sflow_counter_vlan(const u_char *pointer, u_int len) {
+
+ const struct sflow_vlan_counter_t *sflow_vlan_counter;
+
+ if (len < sizeof(struct sflow_vlan_counter_t))
+ return 1;
+
+ sflow_vlan_counter = (const struct sflow_vlan_counter_t *)pointer;
+ printf("\n\t vlan_id %u, octets %" PRIu64
+ ", unicast_pkt %u, multicast_pkt %u, broadcast_pkt %u, discards %u",
+ EXTRACT_32BITS(sflow_vlan_counter->vlan_id),
+ EXTRACT_64BITS(sflow_vlan_counter->octets),
+ EXTRACT_32BITS(sflow_vlan_counter->unicast_pkt),
+ EXTRACT_32BITS(sflow_vlan_counter->multicast_pkt),
+ EXTRACT_32BITS(sflow_vlan_counter->broadcast_pkt),
+ EXTRACT_32BITS(sflow_vlan_counter->discards));
+
+ return 0;
+}
+
+struct sflow_processor_counter_t {
+ u_int8_t five_sec_util[4];
+ u_int8_t one_min_util[4];
+ u_int8_t five_min_util[4];
+ u_int8_t total_memory[8];
+ u_int8_t free_memory[8];
+};
+
+static int
+print_sflow_counter_processor(const u_char *pointer, u_int len) {
+
+ const struct sflow_processor_counter_t *sflow_processor_counter;
+
+ if (len < sizeof(struct sflow_processor_counter_t))
+ return 1;
+
+ sflow_processor_counter = (const struct sflow_processor_counter_t *)pointer;
+ printf("\n\t 5sec %u, 1min %u, 5min %u, total_mem %" PRIu64
+ ", total_mem %" PRIu64,
+ EXTRACT_32BITS(sflow_processor_counter->five_sec_util),
+ EXTRACT_32BITS(sflow_processor_counter->one_min_util),
+ EXTRACT_32BITS(sflow_processor_counter->five_min_util),
+ EXTRACT_64BITS(sflow_processor_counter->total_memory),
+ EXTRACT_64BITS(sflow_processor_counter->free_memory));
+
+ return 0;
+}
+
+static int
+sflow_print_counter_records(const u_char *pointer, u_int len, u_int records) {
+
+ u_int nrecords;
+ const u_char *tptr;
+ u_int tlen;
+ u_int counter_type;
+ u_int counter_len;
+ u_int enterprise;
+ const struct sflow_counter_record_t *sflow_counter_record;
+
+ nrecords = records;
+ tptr = pointer;
+ tlen = len;
+
+ while (nrecords > 0) {
+ /* do we have the "header?" */
+ if (tlen < sizeof(struct sflow_counter_record_t))
+ return 1;
+ sflow_counter_record = (const struct sflow_counter_record_t *)tptr;
+
+ enterprise = EXTRACT_32BITS(sflow_counter_record->format);
+ counter_type = enterprise & 0x0FFF;
+ enterprise = enterprise >> 20;
+ counter_len = EXTRACT_32BITS(sflow_counter_record->length);
+ printf("\n\t enterprise %u, %s (%u) length %u",
+ enterprise,
+ (enterprise == 0) ? tok2str(sflow_counter_type_values,"Unknown",counter_type) : "Unknown",
+ counter_type,
+ counter_len);
+
+ tptr += sizeof(struct sflow_counter_record_t);
+ tlen -= sizeof(struct sflow_counter_record_t);
+
+ if (tlen < counter_len)
+ return 1;
+ if (enterprise == 0) {
+ switch (counter_type) {
+ case SFLOW_COUNTER_GENERIC:
+ if (print_sflow_counter_generic(tptr,tlen))
+ return 1;
+ break;
+ case SFLOW_COUNTER_ETHERNET:
+ if (print_sflow_counter_ethernet(tptr,tlen))
+ return 1;
+ break;
+ case SFLOW_COUNTER_TOKEN_RING:
+ if (print_sflow_counter_token_ring(tptr,tlen))
+ return 1;
+ break;
+ case SFLOW_COUNTER_BASEVG:
+ if (print_sflow_counter_basevg(tptr,tlen))
+ return 1;
+ break;
+ case SFLOW_COUNTER_VLAN:
+ if (print_sflow_counter_vlan(tptr,tlen))
+ return 1;
+ break;
+ case SFLOW_COUNTER_PROCESSOR:
+ if (print_sflow_counter_processor(tptr,tlen))
+ return 1;
+ break;
+ default:
+ if (vflag <= 1)
+ print_unknown_data(tptr, "\n\t\t", counter_len);
+ break;
+ }
+ }
+ tptr += counter_len;
+ tlen -= counter_len;
+ nrecords--;
+
+ }
+
+ return 0;
+}
+
+
+static int
+sflow_print_counter_sample(const u_char *pointer, u_int len) {
+
+ const struct sflow_counter_sample_t *sflow_counter_sample;
+ u_int nrecords;
+ u_int typesource;
+ u_int type;
+ u_int index;
+
+
+ if (len < sizeof(struct sflow_counter_sample_t))
+ return 1;
+
+ sflow_counter_sample = (const struct sflow_counter_sample_t *)pointer;
+
+ typesource = EXTRACT_32BITS(sflow_counter_sample->typesource);
+ nrecords = EXTRACT_32BITS(sflow_counter_sample->records);
+ type = typesource >> 24;
+ index = typesource & 0x0FFF;
+
+ printf(" seqnum %u, type %u, idx %u, records %u",
+ EXTRACT_32BITS(sflow_counter_sample->seqnum),
+ type,
+ index,
+ nrecords);
+
+ return sflow_print_counter_records(pointer + sizeof(struct sflow_counter_sample_t),
+ len - sizeof(struct sflow_counter_sample_t),
+ nrecords);
+
+}
+
+static int
+sflow_print_expanded_counter_sample(const u_char *pointer, u_int len) {
+
+ const struct sflow_expanded_counter_sample_t *sflow_expanded_counter_sample;
+ u_int nrecords;
+
+
+ if (len < sizeof(struct sflow_expanded_counter_sample_t))
+ return 1;
+
+ sflow_expanded_counter_sample = (const struct sflow_expanded_counter_sample_t *)pointer;
+
+ nrecords = EXTRACT_32BITS(sflow_expanded_counter_sample->records);
+
+ printf(" seqnum %u, type %u, idx %u, records %u",
+ EXTRACT_32BITS(sflow_expanded_counter_sample->seqnum),
+ EXTRACT_32BITS(sflow_expanded_counter_sample->type),
+ EXTRACT_32BITS(sflow_expanded_counter_sample->index),
+ nrecords);
+
+ return sflow_print_counter_records(pointer + sizeof(struct sflow_expanded_counter_sample_t),
+ len - sizeof(struct sflow_expanded_counter_sample_t),
+ nrecords);
+
+}
+
+static int
+print_sflow_raw_packet(const u_char *pointer, u_int len) {
+
+ const struct sflow_expanded_flow_raw_t *sflow_flow_raw;
+
+ if (len < sizeof(struct sflow_expanded_flow_raw_t))
+ return 1;
+
+ sflow_flow_raw = (const struct sflow_expanded_flow_raw_t *)pointer;
+ printf("\n\t protocol %s (%u), length %u, stripped bytes %u, header_size %u",
+ tok2str(sflow_flow_raw_protocol_values,"Unknown",EXTRACT_32BITS(sflow_flow_raw->protocol)),
+ EXTRACT_32BITS(sflow_flow_raw->protocol),
+ EXTRACT_32BITS(sflow_flow_raw->length),
+ EXTRACT_32BITS(sflow_flow_raw->stripped_bytes),
+ EXTRACT_32BITS(sflow_flow_raw->header_size));
+
+ /* QUESTION - should we attempt to print the raw header itself?
+ assuming of course there is wnough data present to do so... */
+
+ return 0;
+}
+
+static int
+print_sflow_ethernet_frame(const u_char *pointer, u_int len) {
+
+ const struct sflow_ethernet_frame_t *sflow_ethernet_frame;
+
+ if (len < sizeof(struct sflow_ethernet_frame_t))
+ return 1;
+
+ sflow_ethernet_frame = (const struct sflow_ethernet_frame_t *)pointer;
+
+ printf("\n\t frame len %u, type %u",
+ EXTRACT_32BITS(sflow_ethernet_frame->length),
+ EXTRACT_32BITS(sflow_ethernet_frame->type));
+
+ return 0;
+}
+
+static int
+print_sflow_extended_switch_data(const u_char *pointer, u_int len) {
+
+ const struct sflow_extended_switch_data_t *sflow_extended_sw_data;
+
+ if (len < sizeof(struct sflow_extended_switch_data_t))
+ return 1;
+
+ sflow_extended_sw_data = (const struct sflow_extended_switch_data_t *)pointer;
+ printf("\n\t src vlan %u, src pri %u, dst vlan %u, dst pri %u",
+ EXTRACT_32BITS(sflow_extended_sw_data->src_vlan),
+ EXTRACT_32BITS(sflow_extended_sw_data->src_pri),
+ EXTRACT_32BITS(sflow_extended_sw_data->dst_vlan),
+ EXTRACT_32BITS(sflow_extended_sw_data->dst_pri));
+
+ return 0;
+}
+
+static int
+sflow_print_flow_records(const u_char *pointer, u_int len, u_int records) {
+
+ u_int nrecords;
+ const u_char *tptr;
+ u_int tlen;
+ u_int flow_type;
+ u_int enterprise;
+ u_int flow_len;
+ const struct sflow_flow_record_t *sflow_flow_record;
+
+ nrecords = records;
+ tptr = pointer;
+ tlen = len;
+
+ while (nrecords > 0) {
+ /* do we have the "header?" */
+ if (tlen < sizeof(struct sflow_flow_record_t))
+ return 1;
+
+ sflow_flow_record = (const struct sflow_flow_record_t *)tptr;
+
+ /* so, the funky encoding means we cannot blythly mask-off
+ bits, we must also check the enterprise. */
+
+ enterprise = EXTRACT_32BITS(sflow_flow_record->format);
+ flow_type = enterprise & 0x0FFF;
+ enterprise = enterprise >> 12;
+ flow_len = EXTRACT_32BITS(sflow_flow_record->length);
+ printf("\n\t enterprise %u %s (%u) length %u",
+ enterprise,
+ (enterprise == 0) ? tok2str(sflow_flow_type_values,"Unknown",flow_type) : "Unknown",
+ flow_type,
+ flow_len);
+
+ tptr += sizeof(struct sflow_flow_record_t);
+ tlen -= sizeof(struct sflow_flow_record_t);
+
+ if (tlen < flow_len)
+ return 1;
+
+ if (enterprise == 0) {
+ switch (flow_type) {
+ case SFLOW_FLOW_RAW_PACKET:
+ if (print_sflow_raw_packet(tptr,tlen))
+ return 1;
+ break;
+ case SFLOW_FLOW_EXTENDED_SWITCH_DATA:
+ if (print_sflow_extended_switch_data(tptr,tlen))
+ return 1;
+ break;
+ case SFLOW_FLOW_ETHERNET_FRAME:
+ if (print_sflow_ethernet_frame(tptr,tlen))
+ return 1;
+ break;
+ /* FIXME these need a decoder */
+ case SFLOW_FLOW_IPV4_DATA:
+ case SFLOW_FLOW_IPV6_DATA:
+ case SFLOW_FLOW_EXTENDED_ROUTER_DATA:
+ case SFLOW_FLOW_EXTENDED_GATEWAY_DATA:
+ case SFLOW_FLOW_EXTENDED_USER_DATA:
+ case SFLOW_FLOW_EXTENDED_URL_DATA:
+ case SFLOW_FLOW_EXTENDED_MPLS_DATA:
+ case SFLOW_FLOW_EXTENDED_NAT_DATA:
+ case SFLOW_FLOW_EXTENDED_MPLS_TUNNEL:
+ case SFLOW_FLOW_EXTENDED_MPLS_VC:
+ case SFLOW_FLOW_EXTENDED_MPLS_FEC:
+ case SFLOW_FLOW_EXTENDED_MPLS_LVP_FEC:
+ case SFLOW_FLOW_EXTENDED_VLAN_TUNNEL:
+ break;
+ default:
+ if (vflag <= 1)
+ print_unknown_data(tptr, "\n\t\t", flow_len);
+ break;
+ }
+ }
+ tptr += flow_len;
+ tlen -= flow_len;
+ nrecords--;
+
+ }
+
+ return 0;
+}
+
+static int
+sflow_print_flow_sample(const u_char *pointer, u_int len) {
+
+ const struct sflow_flow_sample_t *sflow_flow_sample;
+ u_int nrecords;
+ u_int typesource;
+ u_int type;
+ u_int index;
+
+ if (len < sizeof(struct sflow_flow_sample_t))
+ return 1;
+
+ sflow_flow_sample = (struct sflow_flow_sample_t *)pointer;
+
+ typesource = EXTRACT_32BITS(sflow_flow_sample->typesource);
+ nrecords = EXTRACT_32BITS(sflow_flow_sample->records);
+ type = typesource >> 24;
+ index = typesource & 0x0FFF;
+
+ printf(" seqnum %u, type %u, idx %u, rate %u, pool %u, drops %u, input %u output %u records %u",
+ EXTRACT_32BITS(sflow_flow_sample->seqnum),
+ type,
+ index,
+ EXTRACT_32BITS(sflow_flow_sample->rate),
+ EXTRACT_32BITS(sflow_flow_sample->pool),
+ EXTRACT_32BITS(sflow_flow_sample->drops),
+ EXTRACT_32BITS(sflow_flow_sample->in_interface),
+ EXTRACT_32BITS(sflow_flow_sample->out_interface),
+ nrecords);
+
+ return sflow_print_flow_records(pointer + sizeof(struct sflow_flow_sample_t),
+ len - sizeof(struct sflow_flow_sample_t),
+ nrecords);
+
+}
+
+static int
+sflow_print_expanded_flow_sample(const u_char *pointer, u_int len) {
+
+ const struct sflow_expanded_flow_sample_t *sflow_expanded_flow_sample;
+ u_int nrecords;
+
+ if (len < sizeof(struct sflow_expanded_flow_sample_t))
+ return 1;
+
+ sflow_expanded_flow_sample = (const struct sflow_expanded_flow_sample_t *)pointer;
+
+ nrecords = EXTRACT_32BITS(sflow_expanded_flow_sample->records);
+
+ printf(" seqnum %u, type %u, idx %u, rate %u, pool %u, drops %u, records %u",
+ EXTRACT_32BITS(sflow_expanded_flow_sample->seqnum),
+ EXTRACT_32BITS(sflow_expanded_flow_sample->type),
+ EXTRACT_32BITS(sflow_expanded_flow_sample->index),
+ EXTRACT_32BITS(sflow_expanded_flow_sample->rate),
+ EXTRACT_32BITS(sflow_expanded_flow_sample->pool),
+ EXTRACT_32BITS(sflow_expanded_flow_sample->drops),
+ EXTRACT_32BITS(sflow_expanded_flow_sample->records));
+
+ return sflow_print_flow_records(pointer + sizeof(struct sflow_expanded_flow_sample_t),
+ len - sizeof(struct sflow_expanded_flow_sample_t),
+ nrecords);
+
+}
+
+void
+sflow_print(const u_char *pptr, u_int len) {
+
+ const struct sflow_datagram_t *sflow_datagram;
+ const struct sflow_sample_header *sflow_sample;
+
+ const u_char *tptr;
+ u_int tlen;
+ u_int32_t sflow_sample_type, sflow_sample_len;
+ u_int32_t nsamples;
+
+
+ tptr = pptr;
+ tlen = len;
+ sflow_datagram = (const struct sflow_datagram_t *)pptr;
+ TCHECK(*sflow_datagram);
+
+ /*
+ * Sanity checking of the header.
+ */
+ if (EXTRACT_32BITS(sflow_datagram->version) != 5) {
+ printf("sFlow version %u packet not supported",
+ EXTRACT_32BITS(sflow_datagram->version));
+ return;
+ }
+
+ if (vflag < 1) {
+ printf("sFlowv%u, %s agent %s, agent-id %u, length %u",
+ EXTRACT_32BITS(sflow_datagram->version),
+ EXTRACT_32BITS(sflow_datagram->ip_version) == 1 ? "IPv4" : "IPv6",
+ ipaddr_string(sflow_datagram->agent),
+ EXTRACT_32BITS(sflow_datagram->samples),
+ len);
+ return;
+ }
+
+ /* ok they seem to want to know everything - lets fully decode it */
+ nsamples=EXTRACT_32BITS(sflow_datagram->samples);
+ printf("sFlowv%u, %s agent %s, agent-id %u, seqnum %u, uptime %u, samples %u, length %u",
+ EXTRACT_32BITS(sflow_datagram->version),
+ EXTRACT_32BITS(sflow_datagram->ip_version) == 1 ? "IPv4" : "IPv6",
+ ipaddr_string(sflow_datagram->agent),
+ EXTRACT_32BITS(sflow_datagram->agent_id),
+ EXTRACT_32BITS(sflow_datagram->seqnum),
+ EXTRACT_32BITS(sflow_datagram->uptime),
+ nsamples,
+ len);
+
+ /* skip Common header */
+ tptr += sizeof(const struct sflow_datagram_t);
+ tlen -= sizeof(const struct sflow_datagram_t);
+
+ while (nsamples > 0 && tlen > 0) {
+ sflow_sample = (const struct sflow_sample_header *)tptr;
+ TCHECK(*sflow_sample);
+
+ sflow_sample_type = (EXTRACT_32BITS(sflow_sample->format)&0x0FFF);
+ sflow_sample_len = EXTRACT_32BITS(sflow_sample->len);
+
+ if (tlen < sizeof(struct sflow_sample_header))
+ goto trunc;
+
+ tptr += sizeof(struct sflow_sample_header);
+ tlen -= sizeof(struct sflow_sample_header);
+
+ printf("\n\t%s (%u), length %u,",
+ tok2str(sflow_format_values, "Unknown", sflow_sample_type),
+ sflow_sample_type,
+ sflow_sample_len);
+
+ /* basic sanity check */
+ if (sflow_sample_type == 0 || sflow_sample_len ==0) {
+ return;
+ }
+
+ if (tlen < sflow_sample_len)
+ goto trunc;
+
+ /* did we capture enough for fully decoding the sample ? */
+ TCHECK2(*tptr, sflow_sample_len);
+
+ switch(sflow_sample_type) {
+ case SFLOW_FLOW_SAMPLE:
+ if (sflow_print_flow_sample(tptr,tlen))
+ goto trunc;
+ break;
+
+ case SFLOW_COUNTER_SAMPLE:
+ if (sflow_print_counter_sample(tptr,tlen))
+ goto trunc;
+ break;
+
+ case SFLOW_EXPANDED_FLOW_SAMPLE:
+ if (sflow_print_expanded_flow_sample(tptr,tlen))
+ goto trunc;
+ break;
+
+ case SFLOW_EXPANDED_COUNTER_SAMPLE:
+ if (sflow_print_expanded_counter_sample(tptr,tlen))
+ goto trunc;
+ break;
+
+ default:
+ if (vflag <= 1)
+ print_unknown_data(tptr, "\n\t ", sflow_sample_len);
+ break;
+ }
+ tptr += sflow_sample_len;
+ tlen -= sflow_sample_len;
+ nsamples--;
+ }
+ return;
+
+ trunc:
+ printf("[|SFLOW]");
+}
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-sip.c b/freebsd/contrib/tcpdump/print-sip.c
new file mode 100644
index 00000000..266fcbe7
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-sip.c
@@ -0,0 +1,66 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-sip.c,v 1.1 2004-07-27 17:04:20 hannes Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "interface.h"
+#include "extract.h"
+
+#include "udp.h"
+
+void
+sip_print(register const u_char *pptr, register u_int len)
+{
+ u_int idx;
+
+ printf("SIP, length: %u%s", len, vflag ? "\n\t" : "");
+
+ /* in non-verbose mode just lets print the protocol and length */
+ if (vflag < 1)
+ return;
+
+ for (idx = 0; idx < len; idx++) {
+ TCHECK2(*(pptr+idx), 2);
+ if (EXTRACT_16BITS(pptr+idx) != 0x0d0a) { /* linefeed ? */
+ safeputchar(*(pptr+idx));
+ } else {
+ printf("\n\t");
+ idx+=1;
+ }
+ }
+
+ /* do we want to see an additionally hexdump ? */
+ if (vflag> 1)
+ print_unknown_data(pptr,"\n\t",len);
+
+ return;
+
+trunc:
+ printf("[|sip]");
+}
diff --git a/freebsd/contrib/tcpdump/print-sl.c b/freebsd/contrib/tcpdump/print-sl.c
new file mode 100644
index 00000000..9496a918
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-sl.c
@@ -0,0 +1,243 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1989, 1990, 1991, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-sl.c,v 1.65 2005-04-06 21:32:42 mcr Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <pcap.h>
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h" /* must come after interface.h */
+
+#include "ip.h"
+#include "tcp.h"
+#include "slip.h"
+#include "slcompress.h"
+
+static u_int lastlen[2][256];
+static u_int lastconn = 255;
+
+static void sliplink_print(const u_char *, const struct ip *, u_int);
+static void compressed_sl_print(const u_char *, const struct ip *, u_int, int);
+
+u_int
+sl_if_print(const struct pcap_pkthdr *h, const u_char *p)
+{
+ register u_int caplen = h->caplen;
+ register u_int length = h->len;
+ register const struct ip *ip;
+
+ if (caplen < SLIP_HDRLEN) {
+ printf("[|slip]");
+ return (caplen);
+ }
+
+ length -= SLIP_HDRLEN;
+
+ ip = (struct ip *)(p + SLIP_HDRLEN);
+
+ if (eflag)
+ sliplink_print(p, ip, length);
+
+ switch (IP_V(ip)) {
+ case 4:
+ ip_print(gndo, (u_char *)ip, length);
+ break;
+#ifdef INET6
+ case 6:
+ ip6_print(gndo, (u_char *)ip, length);
+ break;
+#endif
+ default:
+ printf ("ip v%d", IP_V(ip));
+ }
+
+ return (SLIP_HDRLEN);
+}
+
+u_int
+sl_bsdos_if_print(const struct pcap_pkthdr *h, const u_char *p)
+{
+ register u_int caplen = h->caplen;
+ register u_int length = h->len;
+ register const struct ip *ip;
+
+ if (caplen < SLIP_HDRLEN) {
+ printf("[|slip]");
+ return (caplen);
+ }
+
+ length -= SLIP_HDRLEN;
+
+ ip = (struct ip *)(p + SLIP_HDRLEN);
+
+#ifdef notdef
+ if (eflag)
+ sliplink_print(p, ip, length);
+#endif
+
+ ip_print(gndo, (u_char *)ip, length);
+
+ return (SLIP_HDRLEN);
+}
+
+static void
+sliplink_print(register const u_char *p, register const struct ip *ip,
+ register u_int length)
+{
+ int dir;
+ u_int hlen;
+
+ dir = p[SLX_DIR];
+ putchar(dir == SLIPDIR_IN ? 'I' : 'O');
+ putchar(' ');
+
+ if (nflag) {
+ /* XXX just dump the header */
+ register int i;
+
+ for (i = SLX_CHDR; i < SLX_CHDR + CHDR_LEN - 1; ++i)
+ printf("%02x.", p[i]);
+ printf("%02x: ", p[SLX_CHDR + CHDR_LEN - 1]);
+ return;
+ }
+ switch (p[SLX_CHDR] & 0xf0) {
+
+ case TYPE_IP:
+ printf("ip %d: ", length + SLIP_HDRLEN);
+ break;
+
+ case TYPE_UNCOMPRESSED_TCP:
+ /*
+ * The connection id is stored in the IP protocol field.
+ * Get it from the link layer since sl_uncompress_tcp()
+ * has restored the IP header copy to IPPROTO_TCP.
+ */
+ lastconn = ((struct ip *)&p[SLX_CHDR])->ip_p;
+ hlen = IP_HL(ip);
+ hlen += TH_OFF((struct tcphdr *)&((int *)ip)[hlen]);
+ lastlen[dir][lastconn] = length - (hlen << 2);
+ printf("utcp %d: ", lastconn);
+ break;
+
+ default:
+ if (p[SLX_CHDR] & TYPE_COMPRESSED_TCP) {
+ compressed_sl_print(&p[SLX_CHDR], ip,
+ length, dir);
+ printf(": ");
+ } else
+ printf("slip-%d!: ", p[SLX_CHDR]);
+ }
+}
+
+static const u_char *
+print_sl_change(const char *str, register const u_char *cp)
+{
+ register u_int i;
+
+ if ((i = *cp++) == 0) {
+ i = EXTRACT_16BITS(cp);
+ cp += 2;
+ }
+ printf(" %s%d", str, i);
+ return (cp);
+}
+
+static const u_char *
+print_sl_winchange(register const u_char *cp)
+{
+ register short i;
+
+ if ((i = *cp++) == 0) {
+ i = EXTRACT_16BITS(cp);
+ cp += 2;
+ }
+ if (i >= 0)
+ printf(" W+%d", i);
+ else
+ printf(" W%d", i);
+ return (cp);
+}
+
+static void
+compressed_sl_print(const u_char *chdr, const struct ip *ip,
+ u_int length, int dir)
+{
+ register const u_char *cp = chdr;
+ register u_int flags, hlen;
+
+ flags = *cp++;
+ if (flags & NEW_C) {
+ lastconn = *cp++;
+ printf("ctcp %d", lastconn);
+ } else
+ printf("ctcp *");
+
+ /* skip tcp checksum */
+ cp += 2;
+
+ switch (flags & SPECIALS_MASK) {
+ case SPECIAL_I:
+ printf(" *SA+%d", lastlen[dir][lastconn]);
+ break;
+
+ case SPECIAL_D:
+ printf(" *S+%d", lastlen[dir][lastconn]);
+ break;
+
+ default:
+ if (flags & NEW_U)
+ cp = print_sl_change("U=", cp);
+ if (flags & NEW_W)
+ cp = print_sl_winchange(cp);
+ if (flags & NEW_A)
+ cp = print_sl_change("A+", cp);
+ if (flags & NEW_S)
+ cp = print_sl_change("S+", cp);
+ break;
+ }
+ if (flags & NEW_I)
+ cp = print_sl_change("I+", cp);
+
+ /*
+ * 'hlen' is the length of the uncompressed TCP/IP header (in words).
+ * 'cp - chdr' is the length of the compressed header.
+ * 'length - hlen' is the amount of data in the packet.
+ */
+ hlen = IP_HL(ip);
+ hlen += TH_OFF((struct tcphdr *)&((int32_t *)ip)[hlen]);
+ lastlen[dir][lastconn] = length - (hlen << 2);
+ printf(" %d (%ld)", lastlen[dir][lastconn], (long)(cp - chdr));
+}
diff --git a/freebsd/contrib/tcpdump/print-sll.c b/freebsd/contrib/tcpdump/print-sll.c
new file mode 100644
index 00000000..264eeb30
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-sll.c
@@ -0,0 +1,233 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-sll.c,v 1.19 2005-11-13 12:12:43 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <pcap.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+#include "extract.h"
+
+#include "ether.h"
+#include "sll.h"
+
+const struct tok sll_pkttype_values[] = {
+ { LINUX_SLL_HOST, "In" },
+ { LINUX_SLL_BROADCAST, "B" },
+ { LINUX_SLL_MULTICAST, "M" },
+ { LINUX_SLL_OTHERHOST, "P" },
+ { LINUX_SLL_OUTGOING, "Out" },
+ { 0, NULL}
+};
+
+static inline void
+sll_print(register const struct sll_header *sllp, u_int length)
+{
+ u_short ether_type;
+
+ printf("%3s ",tok2str(sll_pkttype_values,"?",EXTRACT_16BITS(&sllp->sll_pkttype)));
+
+ /*
+ * XXX - check the link-layer address type value?
+ * For now, we just assume 6 means Ethernet.
+ * XXX - print others as strings of hex?
+ */
+ if (EXTRACT_16BITS(&sllp->sll_halen) == 6)
+ (void)printf("%s ", etheraddr_string(sllp->sll_addr));
+
+ if (!qflag) {
+ ether_type = EXTRACT_16BITS(&sllp->sll_protocol);
+
+ if (ether_type <= ETHERMTU) {
+ /*
+ * Not an Ethernet type; what type is it?
+ */
+ switch (ether_type) {
+
+ case LINUX_SLL_P_802_3:
+ /*
+ * Ethernet_802.3 IPX frame.
+ */
+ (void)printf("802.3");
+ break;
+
+ case LINUX_SLL_P_802_2:
+ /*
+ * 802.2.
+ */
+ (void)printf("802.2");
+ break;
+
+ default:
+ /*
+ * What is it?
+ */
+ (void)printf("ethertype Unknown (0x%04x)",
+ ether_type);
+ break;
+ }
+ } else {
+ (void)printf("ethertype %s (0x%04x)",
+ tok2str(ethertype_values, "Unknown", ether_type),
+ ether_type);
+ }
+ (void)printf(", length %u: ", length);
+ }
+}
+
+/*
+ * This is the top level routine of the printer. 'p' points to the
+ * Linux "cooked capture" header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ */
+u_int
+sll_if_print(const struct pcap_pkthdr *h, const u_char *p)
+{
+ u_int caplen = h->caplen;
+ u_int length = h->len;
+ register const struct sll_header *sllp;
+ u_short ether_type;
+ u_short extracted_ethertype;
+
+ if (caplen < SLL_HDR_LEN) {
+ /*
+ * XXX - this "can't happen" because "pcap-linux.c" always
+ * adds this many bytes of header to every packet in a
+ * cooked socket capture.
+ */
+ printf("[|sll]");
+ return (caplen);
+ }
+
+ sllp = (const struct sll_header *)p;
+
+ if (eflag)
+ sll_print(sllp, length);
+
+ /*
+ * Go past the cooked-mode header.
+ */
+ length -= SLL_HDR_LEN;
+ caplen -= SLL_HDR_LEN;
+ p += SLL_HDR_LEN;
+
+ ether_type = EXTRACT_16BITS(&sllp->sll_protocol);
+
+recurse:
+ /*
+ * Is it (gag) an 802.3 encapsulation, or some non-Ethernet
+ * packet type?
+ */
+ if (ether_type <= ETHERMTU) {
+ /*
+ * Yes - what type is it?
+ */
+ switch (ether_type) {
+
+ case LINUX_SLL_P_802_3:
+ /*
+ * Ethernet_802.3 IPX frame.
+ */
+ ipx_print(p, length);
+ break;
+
+ case LINUX_SLL_P_802_2:
+ /*
+ * 802.2.
+ * Try to print the LLC-layer header & higher layers.
+ */
+ if (llc_print(p, length, caplen, NULL, NULL,
+ &extracted_ethertype) == 0)
+ goto unknown; /* unknown LLC type */
+ break;
+
+ default:
+ extracted_ethertype = 0;
+ /*FALLTHROUGH*/
+
+ unknown:
+ /* ether_type not known, print raw packet */
+ if (!eflag)
+ sll_print(sllp, length + SLL_HDR_LEN);
+ if (extracted_ethertype) {
+ printf("(LLC %s) ",
+ etherproto_string(htons(extracted_ethertype)));
+ }
+ if (!suppress_default_print)
+ default_print(p, caplen);
+ break;
+ }
+ } else if (ether_type == ETHERTYPE_8021Q) {
+ /*
+ * Print VLAN information, and then go back and process
+ * the enclosed type field.
+ */
+ if (caplen < 4 || length < 4) {
+ printf("[|vlan]");
+ return (SLL_HDR_LEN);
+ }
+ if (eflag) {
+ u_int16_t tag = EXTRACT_16BITS(p);
+
+ printf("vlan %u, p %u%s, ",
+ tag & 0xfff,
+ tag >> 13,
+ (tag & 0x1000) ? ", CFI" : "");
+ }
+
+ ether_type = EXTRACT_16BITS(p + 2);
+ if (ether_type <= ETHERMTU)
+ ether_type = LINUX_SLL_P_802_2;
+ if (!qflag) {
+ (void)printf("ethertype %s, ",
+ tok2str(ethertype_values, "Unknown", ether_type));
+ }
+ p += 4;
+ length -= 4;
+ caplen -= 4;
+ goto recurse;
+ } else {
+ if (ethertype_print(gndo, ether_type, p, length, caplen) == 0) {
+ /* ether_type not known, print raw packet */
+ if (!eflag)
+ sll_print(sllp, length + SLL_HDR_LEN);
+ if (!suppress_default_print)
+ default_print(p, caplen);
+ }
+ }
+
+ return (SLL_HDR_LEN);
+}
diff --git a/freebsd/contrib/tcpdump/print-slow.c b/freebsd/contrib/tcpdump/print-slow.c
new file mode 100644
index 00000000..f4430887
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-slow.c
@@ -0,0 +1,663 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1998-2006 The TCPDUMP project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * support for the IEEE "slow protocols" LACP, MARKER as per 802.3ad
+ * OAM as per 802.3ah
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-slow.c,v 1.8 2006-10-12 05:44:33 hannes Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+#include "ether.h"
+#include "oui.h"
+
+struct slow_common_header_t {
+ u_int8_t proto_subtype;
+ u_int8_t version;
+};
+
+#define SLOW_PROTO_LACP 1
+#define SLOW_PROTO_MARKER 2
+#define SLOW_PROTO_OAM 3
+
+#define LACP_VERSION 1
+#define MARKER_VERSION 1
+
+static const struct tok slow_proto_values[] = {
+ { SLOW_PROTO_LACP, "LACP" },
+ { SLOW_PROTO_MARKER, "MARKER" },
+ { SLOW_PROTO_OAM, "OAM" },
+ { 0, NULL}
+};
+
+static const struct tok slow_oam_flag_values[] = {
+ { 0x0001, "Link Fault" },
+ { 0x0002, "Dying Gasp" },
+ { 0x0004, "Critical Event" },
+ { 0x0008, "Local Evaluating" },
+ { 0x0010, "Local Stable" },
+ { 0x0020, "Remote Evaluating" },
+ { 0x0040, "Remote Stable" },
+ { 0, NULL}
+};
+
+#define SLOW_OAM_CODE_INFO 0x00
+#define SLOW_OAM_CODE_EVENT_NOTIF 0x01
+#define SLOW_OAM_CODE_VAR_REQUEST 0x02
+#define SLOW_OAM_CODE_VAR_RESPONSE 0x03
+#define SLOW_OAM_CODE_LOOPBACK_CTRL 0x04
+#define SLOW_OAM_CODE_PRIVATE 0xfe
+
+static const struct tok slow_oam_code_values[] = {
+ { SLOW_OAM_CODE_INFO, "Information" },
+ { SLOW_OAM_CODE_EVENT_NOTIF, "Event Notification" },
+ { SLOW_OAM_CODE_VAR_REQUEST, "Variable Request" },
+ { SLOW_OAM_CODE_VAR_RESPONSE, "Variable Response" },
+ { SLOW_OAM_CODE_LOOPBACK_CTRL, "Loopback Control" },
+ { SLOW_OAM_CODE_PRIVATE, "Vendor Private" },
+ { 0, NULL}
+};
+
+struct slow_oam_info_t {
+ u_int8_t info_type;
+ u_int8_t info_length;
+ u_int8_t oam_version;
+ u_int8_t revision[2];
+ u_int8_t state;
+ u_int8_t oam_config;
+ u_int8_t oam_pdu_config[2];
+ u_int8_t oui[3];
+ u_int8_t vendor_private[4];
+};
+
+#define SLOW_OAM_INFO_TYPE_END_OF_TLV 0x00
+#define SLOW_OAM_INFO_TYPE_LOCAL 0x01
+#define SLOW_OAM_INFO_TYPE_REMOTE 0x02
+#define SLOW_OAM_INFO_TYPE_ORG_SPECIFIC 0xfe
+
+static const struct tok slow_oam_info_type_values[] = {
+ { SLOW_OAM_INFO_TYPE_END_OF_TLV, "End of TLV marker" },
+ { SLOW_OAM_INFO_TYPE_LOCAL, "Local" },
+ { SLOW_OAM_INFO_TYPE_REMOTE, "Remote" },
+ { SLOW_OAM_INFO_TYPE_ORG_SPECIFIC, "Organization specific" },
+ { 0, NULL}
+};
+
+#define OAM_INFO_TYPE_PARSER_MASK 0x3
+static const struct tok slow_oam_info_type_state_parser_values[] = {
+ { 0x00, "forwarding" },
+ { 0x01, "looping back" },
+ { 0x02, "discarding" },
+ { 0x03, "reserved" },
+ { 0, NULL}
+};
+
+#define OAM_INFO_TYPE_MUX_MASK 0x4
+static const struct tok slow_oam_info_type_state_mux_values[] = {
+ { 0x00, "forwarding" },
+ { 0x04, "discarding" },
+ { 0, NULL}
+};
+
+static const struct tok slow_oam_info_type_oam_config_values[] = {
+ { 0x01, "Active" },
+ { 0x02, "Unidirectional" },
+ { 0x04, "Remote-Loopback" },
+ { 0x08, "Link-Events" },
+ { 0x10, "Variable-Retrieval" },
+ { 0, NULL}
+};
+
+/* 11 Bits */
+#define OAM_INFO_TYPE_PDU_SIZE_MASK 0x7ff
+
+#define SLOW_OAM_LINK_EVENT_END_OF_TLV 0x00
+#define SLOW_OAM_LINK_EVENT_ERR_SYM_PER 0x01
+#define SLOW_OAM_LINK_EVENT_ERR_FRM 0x02
+#define SLOW_OAM_LINK_EVENT_ERR_FRM_PER 0x03
+#define SLOW_OAM_LINK_EVENT_ERR_FRM_SUMM 0x04
+#define SLOW_OAM_LINK_EVENT_ORG_SPECIFIC 0xfe
+
+static const struct tok slow_oam_link_event_values[] = {
+ { SLOW_OAM_LINK_EVENT_END_OF_TLV, "End of TLV marker" },
+ { SLOW_OAM_LINK_EVENT_ERR_SYM_PER, "Errored Symbol Period Event" },
+ { SLOW_OAM_LINK_EVENT_ERR_FRM, "Errored Frame Event" },
+ { SLOW_OAM_LINK_EVENT_ERR_FRM_PER, "Errored Frame Period Event" },
+ { SLOW_OAM_LINK_EVENT_ERR_FRM_SUMM, "Errored Frame Seconds Summary Event" },
+ { SLOW_OAM_LINK_EVENT_ORG_SPECIFIC, "Organization specific" },
+ { 0, NULL}
+};
+
+struct slow_oam_link_event_t {
+ u_int8_t event_type;
+ u_int8_t event_length;
+ u_int8_t time_stamp[2];
+ u_int8_t window[8];
+ u_int8_t threshold[8];
+ u_int8_t errors[8];
+ u_int8_t errors_running_total[8];
+ u_int8_t event_running_total[4];
+};
+
+struct slow_oam_variablerequest_t {
+ u_int8_t branch;
+ u_int8_t leaf[2];
+};
+
+struct slow_oam_variableresponse_t {
+ u_int8_t branch;
+ u_int8_t leaf[2];
+ u_int8_t length;
+};
+
+struct slow_oam_loopbackctrl_t {
+ u_int8_t command;
+};
+
+static const struct tok slow_oam_loopbackctrl_cmd_values[] = {
+ { 0x01, "Enable OAM Remote Loopback" },
+ { 0x02, "Disable OAM Remote Loopback" },
+ { 0, NULL}
+};
+
+struct tlv_header_t {
+ u_int8_t type;
+ u_int8_t length;
+};
+
+#define LACP_TLV_TERMINATOR 0x00
+#define LACP_TLV_ACTOR_INFO 0x01
+#define LACP_TLV_PARTNER_INFO 0x02
+#define LACP_TLV_COLLECTOR_INFO 0x03
+
+#define MARKER_TLV_TERMINATOR 0x00
+#define MARKER_TLV_MARKER_INFO 0x01
+
+static const struct tok slow_tlv_values[] = {
+ { (SLOW_PROTO_LACP << 8) + LACP_TLV_TERMINATOR, "Terminator"},
+ { (SLOW_PROTO_LACP << 8) + LACP_TLV_ACTOR_INFO, "Actor Information"},
+ { (SLOW_PROTO_LACP << 8) + LACP_TLV_PARTNER_INFO, "Partner Information"},
+ { (SLOW_PROTO_LACP << 8) + LACP_TLV_COLLECTOR_INFO, "Collector Information"},
+
+ { (SLOW_PROTO_MARKER << 8) + MARKER_TLV_TERMINATOR, "Terminator"},
+ { (SLOW_PROTO_MARKER << 8) + MARKER_TLV_MARKER_INFO, "Marker Information"},
+ { 0, NULL}
+};
+
+struct lacp_tlv_actor_partner_info_t {
+ u_int8_t sys_pri[2];
+ u_int8_t sys[ETHER_ADDR_LEN];
+ u_int8_t key[2];
+ u_int8_t port_pri[2];
+ u_int8_t port[2];
+ u_int8_t state;
+ u_int8_t pad[3];
+};
+
+static const struct tok lacp_tlv_actor_partner_info_state_values[] = {
+ { 0x01, "Activity"},
+ { 0x02, "Timeout"},
+ { 0x04, "Aggregation"},
+ { 0x08, "Synchronization"},
+ { 0x10, "Collecting"},
+ { 0x20, "Distributing"},
+ { 0x40, "Default"},
+ { 0x80, "Expired"},
+ { 0, NULL}
+};
+
+struct lacp_tlv_collector_info_t {
+ u_int8_t max_delay[2];
+ u_int8_t pad[12];
+};
+
+struct marker_tlv_marker_info_t {
+ u_int8_t req_port[2];
+ u_int8_t req_sys[ETHER_ADDR_LEN];
+ u_int8_t req_trans_id[4];
+ u_int8_t pad[2];
+};
+
+struct lacp_marker_tlv_terminator_t {
+ u_int8_t pad[50];
+};
+
+void slow_marker_lacp_print(register const u_char *, register u_int);
+void slow_oam_print(register const u_char *, register u_int);
+
+const struct slow_common_header_t *slow_com_header;
+
+void
+slow_print(register const u_char *pptr, register u_int len) {
+
+ int print_version;
+
+ slow_com_header = (const struct slow_common_header_t *)pptr;
+ TCHECK(*slow_com_header);
+
+ /*
+ * Sanity checking of the header.
+ */
+ switch (slow_com_header->proto_subtype) {
+ case SLOW_PROTO_LACP:
+ if (slow_com_header->version != LACP_VERSION) {
+ printf("LACP version %u packet not supported",slow_com_header->version);
+ return;
+ }
+ print_version = 1;
+ break;
+
+ case SLOW_PROTO_MARKER:
+ if (slow_com_header->version != MARKER_VERSION) {
+ printf("MARKER version %u packet not supported",slow_com_header->version);
+ return;
+ }
+ print_version = 1;
+ break;
+
+ case SLOW_PROTO_OAM: /* fall through */
+ print_version = 0;
+ break;
+
+ default:
+ /* print basic information and exit */
+ print_version = -1;
+ break;
+ }
+
+ if (print_version) {
+ printf("%sv%u, length %u",
+ tok2str(slow_proto_values, "unknown (%u)",slow_com_header->proto_subtype),
+ slow_com_header->version,
+ len);
+ } else {
+ /* some slow protos don't have a version number in the header */
+ printf("%s, length %u",
+ tok2str(slow_proto_values, "unknown (%u)",slow_com_header->proto_subtype),
+ len);
+ }
+
+ /* unrecognized subtype */
+ if (print_version == -1) {
+ print_unknown_data(pptr, "\n\t", len);
+ return;
+ }
+
+ if (!vflag)
+ return;
+
+ switch (slow_com_header->proto_subtype) {
+ default: /* should not happen */
+ break;
+
+ case SLOW_PROTO_OAM:
+ /* skip proto_subtype */
+ slow_oam_print(pptr+1, len-1);
+ break;
+
+ case SLOW_PROTO_LACP: /* LACP and MARKER share the same semantics */
+ case SLOW_PROTO_MARKER:
+ /* skip slow_common_header */
+ len -= sizeof(const struct slow_common_header_t);
+ pptr += sizeof(const struct slow_common_header_t);
+ slow_marker_lacp_print(pptr, len);
+ break;
+ }
+ return;
+
+trunc:
+ printf("\n\t\t packet exceeded snapshot");
+}
+
+void slow_marker_lacp_print(register const u_char *tptr, register u_int tlen) {
+
+ const struct tlv_header_t *tlv_header;
+ const u_char *tlv_tptr;
+ u_int tlv_len, tlv_tlen;
+
+ union {
+ const struct lacp_marker_tlv_terminator_t *lacp_marker_tlv_terminator;
+ const struct lacp_tlv_actor_partner_info_t *lacp_tlv_actor_partner_info;
+ const struct lacp_tlv_collector_info_t *lacp_tlv_collector_info;
+ const struct marker_tlv_marker_info_t *marker_tlv_marker_info;
+ } tlv_ptr;
+
+ while(tlen>0) {
+ /* did we capture enough for fully decoding the tlv header ? */
+ TCHECK2(*tptr, sizeof(struct tlv_header_t));
+ tlv_header = (const struct tlv_header_t *)tptr;
+ tlv_len = tlv_header->length;
+
+ printf("\n\t%s TLV (0x%02x), length %u",
+ tok2str(slow_tlv_values,
+ "Unknown",
+ (slow_com_header->proto_subtype << 8) + tlv_header->type),
+ tlv_header->type,
+ tlv_len);
+
+ if ((tlv_len < sizeof(struct tlv_header_t) ||
+ tlv_len > tlen) &&
+ tlv_header->type != LACP_TLV_TERMINATOR &&
+ tlv_header->type != MARKER_TLV_TERMINATOR) {
+ printf("\n\t-----trailing data-----");
+ print_unknown_data(tptr+sizeof(struct tlv_header_t),"\n\t ",tlen);
+ return;
+ }
+
+ tlv_tptr=tptr+sizeof(struct tlv_header_t);
+ tlv_tlen=tlv_len-sizeof(struct tlv_header_t);
+
+ /* did we capture enough for fully decoding the tlv ? */
+ TCHECK2(*tptr, tlv_len);
+
+ switch((slow_com_header->proto_subtype << 8) + tlv_header->type) {
+
+ /* those two TLVs have the same structure -> fall through */
+ case ((SLOW_PROTO_LACP << 8) + LACP_TLV_ACTOR_INFO):
+ case ((SLOW_PROTO_LACP << 8) + LACP_TLV_PARTNER_INFO):
+ tlv_ptr.lacp_tlv_actor_partner_info = (const struct lacp_tlv_actor_partner_info_t *)tlv_tptr;
+
+ printf("\n\t System %s, System Priority %u, Key %u" \
+ ", Port %u, Port Priority %u\n\t State Flags [%s]",
+ etheraddr_string(tlv_ptr.lacp_tlv_actor_partner_info->sys),
+ EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->sys_pri),
+ EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->key),
+ EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->port),
+ EXTRACT_16BITS(tlv_ptr.lacp_tlv_actor_partner_info->port_pri),
+ bittok2str(lacp_tlv_actor_partner_info_state_values,
+ "none",
+ tlv_ptr.lacp_tlv_actor_partner_info->state));
+
+ break;
+
+ case ((SLOW_PROTO_LACP << 8) + LACP_TLV_COLLECTOR_INFO):
+ tlv_ptr.lacp_tlv_collector_info = (const struct lacp_tlv_collector_info_t *)tlv_tptr;
+
+ printf("\n\t Max Delay %u",
+ EXTRACT_16BITS(tlv_ptr.lacp_tlv_collector_info->max_delay));
+
+ break;
+
+ case ((SLOW_PROTO_MARKER << 8) + MARKER_TLV_MARKER_INFO):
+ tlv_ptr.marker_tlv_marker_info = (const struct marker_tlv_marker_info_t *)tlv_tptr;
+
+ printf("\n\t Request System %s, Request Port %u, Request Transaction ID 0x%08x",
+ etheraddr_string(tlv_ptr.marker_tlv_marker_info->req_sys),
+ EXTRACT_16BITS(tlv_ptr.marker_tlv_marker_info->req_port),
+ EXTRACT_32BITS(tlv_ptr.marker_tlv_marker_info->req_trans_id));
+
+ break;
+
+ /* those two TLVs have the same structure -> fall through */
+ case ((SLOW_PROTO_LACP << 8) + LACP_TLV_TERMINATOR):
+ case ((SLOW_PROTO_MARKER << 8) + LACP_TLV_TERMINATOR):
+ tlv_ptr.lacp_marker_tlv_terminator = (const struct lacp_marker_tlv_terminator_t *)tlv_tptr;
+ if (tlv_len == 0) {
+ tlv_len = sizeof(tlv_ptr.lacp_marker_tlv_terminator->pad) +
+ sizeof(struct tlv_header_t);
+ /* tell the user that we modified the length field */
+ if (vflag>1)
+ printf(" (=%u)",tlv_len);
+ /* we have messed around with the length field - now we need to check
+ * again if there are enough bytes on the wire for the hexdump */
+ TCHECK2(tlv_ptr.lacp_marker_tlv_terminator->pad[0],
+ sizeof(tlv_ptr.lacp_marker_tlv_terminator->pad));
+ }
+
+ break;
+
+ default:
+ if (vflag <= 1)
+ print_unknown_data(tlv_tptr,"\n\t ",tlv_tlen);
+ break;
+ }
+ /* do we want to see an additional hexdump ? */
+ if (vflag > 1) {
+ print_unknown_data(tptr+sizeof(struct tlv_header_t),"\n\t ",
+ tlv_len-sizeof(struct tlv_header_t));
+ }
+
+ tptr+=tlv_len;
+ tlen-=tlv_len;
+ }
+ return;
+trunc:
+ printf("\n\t\t packet exceeded snapshot");
+}
+
+void slow_oam_print(register const u_char *tptr, register u_int tlen) {
+
+ u_int hexdump;
+
+ struct slow_oam_common_header_t {
+ u_int8_t flags[2];
+ u_int8_t code;
+ };
+
+ struct slow_oam_tlv_header_t {
+ u_int8_t type;
+ u_int8_t length;
+ };
+
+ union {
+ const struct slow_oam_common_header_t *slow_oam_common_header;
+ const struct slow_oam_tlv_header_t *slow_oam_tlv_header;
+ } ptr;
+
+ union {
+ const struct slow_oam_info_t *slow_oam_info;
+ const struct slow_oam_link_event_t *slow_oam_link_event;
+ const struct slow_oam_variablerequest_t *slow_oam_variablerequest;
+ const struct slow_oam_variableresponse_t *slow_oam_variableresponse;
+ const struct slow_oam_loopbackctrl_t *slow_oam_loopbackctrl;
+ } tlv;
+
+ ptr.slow_oam_common_header = (struct slow_oam_common_header_t *)tptr;
+ tptr += sizeof(struct slow_oam_common_header_t);
+ tlen -= sizeof(struct slow_oam_common_header_t);
+
+ printf("\n\tCode %s OAM PDU, Flags [%s]",
+ tok2str(slow_oam_code_values, "Unknown (%u)", ptr.slow_oam_common_header->code),
+ bittok2str(slow_oam_flag_values,
+ "none",
+ EXTRACT_16BITS(&ptr.slow_oam_common_header->flags)));
+
+ switch (ptr.slow_oam_common_header->code) {
+ case SLOW_OAM_CODE_INFO:
+ while (tlen > 0) {
+ ptr.slow_oam_tlv_header = (const struct slow_oam_tlv_header_t *)tptr;
+ printf("\n\t %s Information Type (%u), length %u",
+ tok2str(slow_oam_info_type_values, "Reserved",
+ ptr.slow_oam_tlv_header->type),
+ ptr.slow_oam_tlv_header->type,
+ ptr.slow_oam_tlv_header->length);
+
+ hexdump = FALSE;
+ switch (ptr.slow_oam_tlv_header->type) {
+ case SLOW_OAM_INFO_TYPE_END_OF_TLV:
+ if (ptr.slow_oam_tlv_header->length != 0) {
+ printf("\n\t ERROR: illegal length - should be 0");
+ }
+ return;
+
+ case SLOW_OAM_INFO_TYPE_LOCAL: /* identical format - fall through */
+ case SLOW_OAM_INFO_TYPE_REMOTE:
+ tlv.slow_oam_info = (const struct slow_oam_info_t *)tptr;
+
+ if (tlv.slow_oam_info->info_length !=
+ sizeof(struct slow_oam_info_t)) {
+ printf("\n\t ERROR: illegal length - should be %lu",
+ (unsigned long) sizeof(struct slow_oam_info_t));
+ return;
+ }
+
+ printf("\n\t OAM-Version %u, Revision %u",
+ tlv.slow_oam_info->oam_version,
+ EXTRACT_16BITS(&tlv.slow_oam_info->revision));
+
+ printf("\n\t State-Parser-Action %s, State-MUX-Action %s",
+ tok2str(slow_oam_info_type_state_parser_values, "Reserved",
+ tlv.slow_oam_info->state & OAM_INFO_TYPE_PARSER_MASK),
+ tok2str(slow_oam_info_type_state_mux_values, "Reserved",
+ tlv.slow_oam_info->state & OAM_INFO_TYPE_MUX_MASK));
+ printf("\n\t OAM-Config Flags [%s], OAM-PDU-Config max-PDU size %u",
+ bittok2str(slow_oam_info_type_oam_config_values, "none",
+ tlv.slow_oam_info->oam_config),
+ EXTRACT_16BITS(&tlv.slow_oam_info->oam_pdu_config) &
+ OAM_INFO_TYPE_PDU_SIZE_MASK);
+ printf("\n\t OUI %s (0x%06x), Vendor-Private 0x%08x",
+ tok2str(oui_values, "Unknown",
+ EXTRACT_24BITS(&tlv.slow_oam_info->oui)),
+ EXTRACT_24BITS(&tlv.slow_oam_info->oui),
+ EXTRACT_32BITS(&tlv.slow_oam_info->vendor_private));
+ break;
+
+ case SLOW_OAM_INFO_TYPE_ORG_SPECIFIC:
+ hexdump = TRUE;
+ break;
+
+ default:
+ hexdump = TRUE;
+ break;
+ }
+
+ /* infinite loop check */
+ if (!ptr.slow_oam_tlv_header->length) {
+ return;
+ }
+
+ /* do we also want to see a hex dump ? */
+ if (vflag > 1 || hexdump==TRUE) {
+ print_unknown_data(tptr,"\n\t ",
+ ptr.slow_oam_tlv_header->length);
+ }
+
+ tlen -= ptr.slow_oam_tlv_header->length;
+ tptr += ptr.slow_oam_tlv_header->length;
+ }
+ break;
+
+ case SLOW_OAM_CODE_EVENT_NOTIF:
+ while (tlen > 0) {
+ ptr.slow_oam_tlv_header = (const struct slow_oam_tlv_header_t *)tptr;
+ printf("\n\t %s Link Event Type (%u), length %u",
+ tok2str(slow_oam_link_event_values, "Reserved",
+ ptr.slow_oam_tlv_header->type),
+ ptr.slow_oam_tlv_header->type,
+ ptr.slow_oam_tlv_header->length);
+
+ hexdump = FALSE;
+ switch (ptr.slow_oam_tlv_header->type) {
+ case SLOW_OAM_LINK_EVENT_END_OF_TLV:
+ if (ptr.slow_oam_tlv_header->length != 0) {
+ printf("\n\t ERROR: illegal length - should be 0");
+ }
+ return;
+
+ case SLOW_OAM_LINK_EVENT_ERR_SYM_PER: /* identical format - fall through */
+ case SLOW_OAM_LINK_EVENT_ERR_FRM:
+ case SLOW_OAM_LINK_EVENT_ERR_FRM_PER:
+ case SLOW_OAM_LINK_EVENT_ERR_FRM_SUMM:
+ tlv.slow_oam_link_event = (const struct slow_oam_link_event_t *)tptr;
+
+ if (tlv.slow_oam_link_event->event_length !=
+ sizeof(struct slow_oam_link_event_t)) {
+ printf("\n\t ERROR: illegal length - should be %lu",
+ (unsigned long) sizeof(struct slow_oam_link_event_t));
+ return;
+ }
+
+ printf("\n\t Timestamp %u ms, Errored Window %" PRIu64
+ "\n\t Errored Threshold %" PRIu64
+ "\n\t Errors %" PRIu64
+ "\n\t Error Running Total %" PRIu64
+ "\n\t Event Running Total %u",
+ EXTRACT_16BITS(&tlv.slow_oam_link_event->time_stamp)*100,
+ EXTRACT_64BITS(&tlv.slow_oam_link_event->window),
+ EXTRACT_64BITS(&tlv.slow_oam_link_event->threshold),
+ EXTRACT_64BITS(&tlv.slow_oam_link_event->errors),
+ EXTRACT_64BITS(&tlv.slow_oam_link_event->errors_running_total),
+ EXTRACT_32BITS(&tlv.slow_oam_link_event->event_running_total));
+ break;
+
+ case SLOW_OAM_LINK_EVENT_ORG_SPECIFIC:
+ hexdump = TRUE;
+ break;
+
+ default:
+ hexdump = TRUE;
+ break;
+ }
+
+ /* infinite loop check */
+ if (!ptr.slow_oam_tlv_header->length) {
+ return;
+ }
+
+ /* do we also want to see a hex dump ? */
+ if (vflag > 1 || hexdump==TRUE) {
+ print_unknown_data(tptr,"\n\t ",
+ ptr.slow_oam_tlv_header->length);
+ }
+
+ tlen -= ptr.slow_oam_tlv_header->length;
+ tptr += ptr.slow_oam_tlv_header->length;
+ }
+ break;
+
+ case SLOW_OAM_CODE_LOOPBACK_CTRL:
+ tlv.slow_oam_loopbackctrl = (const struct slow_oam_loopbackctrl_t *)tptr;
+ printf("\n\t Command %s (%u)",
+ tok2str(slow_oam_loopbackctrl_cmd_values,
+ "Unknown",
+ tlv.slow_oam_loopbackctrl->command),
+ tlv.slow_oam_loopbackctrl->command);
+ tptr ++;
+ tlen --;
+ break;
+
+ /*
+ * FIXME those are the defined codes that lack a decoder
+ * you are welcome to contribute code ;-)
+ */
+ case SLOW_OAM_CODE_VAR_REQUEST:
+ case SLOW_OAM_CODE_VAR_RESPONSE:
+ case SLOW_OAM_CODE_PRIVATE:
+ default:
+ if (vflag <= 1) {
+ print_unknown_data(tptr,"\n\t ", tlen);
+ }
+ break;
+ }
+ return;
+}
diff --git a/freebsd/contrib/tcpdump/print-smb.c b/freebsd/contrib/tcpdump/print-smb.c
new file mode 100644
index 00000000..ba826762
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-smb.c
@@ -0,0 +1,1512 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) Andrew Tridgell 1995-1999
+ *
+ * This software may be distributed either under the terms of the
+ * BSD-style license that accompanies tcpdump or the GNU GPL version 2
+ * or later
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-smb.c,v 1.47 2007-12-09 00:30:47 guy Exp $";
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "smb.h"
+
+static int request = 0;
+static int unicodestr = 0;
+
+const u_char *startbuf = NULL;
+
+struct smbdescript {
+ const char *req_f1;
+ const char *req_f2;
+ const char *rep_f1;
+ const char *rep_f2;
+ void (*fn)(const u_char *, const u_char *, const u_char *, const u_char *);
+};
+
+struct smbdescriptint {
+ const char *req_f1;
+ const char *req_f2;
+ const char *rep_f1;
+ const char *rep_f2;
+ void (*fn)(const u_char *, const u_char *, int, int);
+};
+
+struct smbfns
+{
+ int id;
+ const char *name;
+ int flags;
+ struct smbdescript descript;
+};
+
+struct smbfnsint
+{
+ int id;
+ const char *name;
+ int flags;
+ struct smbdescriptint descript;
+};
+
+#define DEFDESCRIPT { NULL, NULL, NULL, NULL, NULL }
+
+#define FLG_CHAIN (1 << 0)
+
+static struct smbfns *
+smbfind(int id, struct smbfns *list)
+{
+ int sindex;
+
+ for (sindex = 0; list[sindex].name; sindex++)
+ if (list[sindex].id == id)
+ return(&list[sindex]);
+
+ return(&list[0]);
+}
+
+static struct smbfnsint *
+smbfindint(int id, struct smbfnsint *list)
+{
+ int sindex;
+
+ for (sindex = 0; list[sindex].name; sindex++)
+ if (list[sindex].id == id)
+ return(&list[sindex]);
+
+ return(&list[0]);
+}
+
+static void
+trans2_findfirst(const u_char *param, const u_char *data, int pcnt, int dcnt)
+{
+ const char *fmt;
+
+ if (request)
+ fmt = "Attribute=[A]\nSearchCount=[d]\nFlags=[w]\nLevel=[dP4]\nFile=[S]\n";
+ else
+ fmt = "Handle=[w]\nCount=[d]\nEOS=[w]\nEoffset=[d]\nLastNameOfs=[w]\n";
+
+ smb_fdata(param, fmt, param + pcnt, unicodestr);
+ if (dcnt) {
+ printf("data:\n");
+ print_data(data, dcnt);
+ }
+}
+
+static void
+trans2_qfsinfo(const u_char *param, const u_char *data, int pcnt, int dcnt)
+{
+ static int level = 0;
+ const char *fmt="";
+
+ if (request) {
+ TCHECK2(*param, 2);
+ level = EXTRACT_LE_16BITS(param);
+ fmt = "InfoLevel=[d]\n";
+ smb_fdata(param, fmt, param + pcnt, unicodestr);
+ } else {
+ switch (level) {
+ case 1:
+ fmt = "idFileSystem=[W]\nSectorUnit=[D]\nUnit=[D]\nAvail=[D]\nSectorSize=[d]\n";
+ break;
+ case 2:
+ fmt = "CreationTime=[T2]VolNameLength=[lb]\nVolumeLabel=[c]\n";
+ break;
+ case 0x105:
+ fmt = "Capabilities=[W]\nMaxFileLen=[D]\nVolNameLen=[lD]\nVolume=[C]\n";
+ break;
+ default:
+ fmt = "UnknownLevel\n";
+ break;
+ }
+ smb_fdata(data, fmt, data + dcnt, unicodestr);
+ }
+ if (dcnt) {
+ printf("data:\n");
+ print_data(data, dcnt);
+ }
+ return;
+trunc:
+ printf("[|SMB]");
+ return;
+}
+
+struct smbfnsint trans2_fns[] = {
+ { 0, "TRANSACT2_OPEN", 0,
+ { "Flags2=[w]\nMode=[w]\nSearchAttrib=[A]\nAttrib=[A]\nTime=[T2]\nOFun=[w]\nSize=[D]\nRes=([w, w, w, w, w])\nPath=[S]",
+ NULL,
+ "Handle=[d]\nAttrib=[A]\nTime=[T2]\nSize=[D]\nAccess=[w]\nType=[w]\nState=[w]\nAction=[w]\nInode=[W]\nOffErr=[d]\n|EALength=[d]\n",
+ NULL, NULL }},
+ { 1, "TRANSACT2_FINDFIRST", 0,
+ { NULL, NULL, NULL, NULL, trans2_findfirst }},
+ { 2, "TRANSACT2_FINDNEXT", 0, DEFDESCRIPT },
+ { 3, "TRANSACT2_QFSINFO", 0,
+ { NULL, NULL, NULL, NULL, trans2_qfsinfo }},
+ { 4, "TRANSACT2_SETFSINFO", 0, DEFDESCRIPT },
+ { 5, "TRANSACT2_QPATHINFO", 0, DEFDESCRIPT },
+ { 6, "TRANSACT2_SETPATHINFO", 0, DEFDESCRIPT },
+ { 7, "TRANSACT2_QFILEINFO", 0, DEFDESCRIPT },
+ { 8, "TRANSACT2_SETFILEINFO", 0, DEFDESCRIPT },
+ { 9, "TRANSACT2_FSCTL", 0, DEFDESCRIPT },
+ { 10, "TRANSACT2_IOCTL", 0, DEFDESCRIPT },
+ { 11, "TRANSACT2_FINDNOTIFYFIRST", 0, DEFDESCRIPT },
+ { 12, "TRANSACT2_FINDNOTIFYNEXT", 0, DEFDESCRIPT },
+ { 13, "TRANSACT2_MKDIR", 0, DEFDESCRIPT },
+ { -1, NULL, 0, DEFDESCRIPT }
+};
+
+
+static void
+print_trans2(const u_char *words, const u_char *dat, const u_char *buf, const u_char *maxbuf)
+{
+ u_int bcc;
+ static struct smbfnsint *fn = &trans2_fns[0];
+ const u_char *data, *param;
+ const u_char *w = words + 1;
+ const char *f1 = NULL, *f2 = NULL;
+ int pcnt, dcnt;
+
+ TCHECK(words[0]);
+ if (request) {
+ TCHECK2(w[14 * 2], 2);
+ pcnt = EXTRACT_LE_16BITS(w + 9 * 2);
+ param = buf + EXTRACT_LE_16BITS(w + 10 * 2);
+ dcnt = EXTRACT_LE_16BITS(w + 11 * 2);
+ data = buf + EXTRACT_LE_16BITS(w + 12 * 2);
+ fn = smbfindint(EXTRACT_LE_16BITS(w + 14 * 2), trans2_fns);
+ } else {
+ if (words[0] == 0) {
+ printf("%s\n", fn->name);
+ printf("Trans2Interim\n");
+ return;
+ }
+ TCHECK2(w[7 * 2], 2);
+ pcnt = EXTRACT_LE_16BITS(w + 3 * 2);
+ param = buf + EXTRACT_LE_16BITS(w + 4 * 2);
+ dcnt = EXTRACT_LE_16BITS(w + 6 * 2);
+ data = buf + EXTRACT_LE_16BITS(w + 7 * 2);
+ }
+
+ printf("%s param_length=%d data_length=%d\n", fn->name, pcnt, dcnt);
+
+ if (request) {
+ if (words[0] == 8) {
+ smb_fdata(words + 1,
+ "Trans2Secondary\nTotParam=[d]\nTotData=[d]\nParamCnt=[d]\nParamOff=[d]\nParamDisp=[d]\nDataCnt=[d]\nDataOff=[d]\nDataDisp=[d]\nHandle=[d]\n",
+ maxbuf, unicodestr);
+ return;
+ } else {
+ smb_fdata(words + 1,
+ "TotParam=[d]\nTotData=[d]\nMaxParam=[d]\nMaxData=[d]\nMaxSetup=[b][P1]\nFlags=[w]\nTimeOut=[D]\nRes1=[w]\nParamCnt=[d]\nParamOff=[d]\nDataCnt=[d]\nDataOff=[d]\nSetupCnt=[b][P1]\n",
+ words + 1 + 14 * 2, unicodestr);
+ }
+ f1 = fn->descript.req_f1;
+ f2 = fn->descript.req_f2;
+ } else {
+ smb_fdata(words + 1,
+ "TotParam=[d]\nTotData=[d]\nRes1=[w]\nParamCnt=[d]\nParamOff=[d]\nParamDisp[d]\nDataCnt=[d]\nDataOff=[d]\nDataDisp=[d]\nSetupCnt=[b][P1]\n",
+ words + 1 + 10 * 2, unicodestr);
+ f1 = fn->descript.rep_f1;
+ f2 = fn->descript.rep_f2;
+ }
+
+ TCHECK2(*dat, 2);
+ bcc = EXTRACT_LE_16BITS(dat);
+ printf("smb_bcc=%u\n", bcc);
+ if (fn->descript.fn)
+ (*fn->descript.fn)(param, data, pcnt, dcnt);
+ else {
+ smb_fdata(param, f1 ? f1 : "Parameters=\n", param + pcnt, unicodestr);
+ smb_fdata(data, f2 ? f2 : "Data=\n", data + dcnt, unicodestr);
+ }
+ return;
+trunc:
+ printf("[|SMB]");
+ return;
+}
+
+
+static void
+print_browse(const u_char *param, int paramlen, const u_char *data, int datalen)
+{
+ const u_char *maxbuf = data + datalen;
+ int command;
+
+ TCHECK(data[0]);
+ command = data[0];
+
+ smb_fdata(param, "BROWSE PACKET\n|Param ", param+paramlen, unicodestr);
+
+ switch (command) {
+ case 0xF:
+ data = smb_fdata(data,
+ "BROWSE PACKET:\nType=[B] (LocalMasterAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nElectionVersion=[w]\nBrowserConstant=[w]\n",
+ maxbuf, unicodestr);
+ break;
+
+ case 0x1:
+ data = smb_fdata(data,
+ "BROWSE PACKET:\nType=[B] (HostAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nElectionVersion=[w]\nBrowserConstant=[w]\n",
+ maxbuf, unicodestr);
+ break;
+
+ case 0x2:
+ data = smb_fdata(data,
+ "BROWSE PACKET:\nType=[B] (AnnouncementRequest)\nFlags=[B]\nReplySystemName=[S]\n",
+ maxbuf, unicodestr);
+ break;
+
+ case 0xc:
+ data = smb_fdata(data,
+ "BROWSE PACKET:\nType=[B] (WorkgroupAnnouncement)\nUpdateCount=[w]\nRes1=[B]\nAnnounceInterval=[d]\nName=[n2]\nMajorVersion=[B]\nMinorVersion=[B]\nServerType=[W]\nCommentPointer=[W]\nServerName=[S]\n",
+ maxbuf, unicodestr);
+ break;
+
+ case 0x8:
+ data = smb_fdata(data,
+ "BROWSE PACKET:\nType=[B] (ElectionFrame)\nElectionVersion=[B]\nOSSummary=[W]\nUptime=[(W, W)]\nServerName=[S]\n",
+ maxbuf, unicodestr);
+ break;
+
+ case 0xb:
+ data = smb_fdata(data,
+ "BROWSE PACKET:\nType=[B] (BecomeBackupBrowser)\nName=[S]\n",
+ maxbuf, unicodestr);
+ break;
+
+ case 0x9:
+ data = smb_fdata(data,
+ "BROWSE PACKET:\nType=[B] (GetBackupList)\nListCount?=[B]\nToken=[W]\n",
+ maxbuf, unicodestr);
+ break;
+
+ case 0xa:
+ data = smb_fdata(data,
+ "BROWSE PACKET:\nType=[B] (BackupListResponse)\nServerCount?=[B]\nToken=[W]\n*Name=[S]\n",
+ maxbuf, unicodestr);
+ break;
+
+ case 0xd:
+ data = smb_fdata(data,
+ "BROWSE PACKET:\nType=[B] (MasterAnnouncement)\nMasterName=[S]\n",
+ maxbuf, unicodestr);
+ break;
+
+ case 0xe:
+ data = smb_fdata(data,
+ "BROWSE PACKET:\nType=[B] (ResetBrowser)\nOptions=[B]\n", maxbuf, unicodestr);
+ break;
+
+ default:
+ data = smb_fdata(data, "Unknown Browser Frame ", maxbuf, unicodestr);
+ break;
+ }
+ return;
+trunc:
+ printf("[|SMB]");
+ return;
+}
+
+
+static void
+print_ipc(const u_char *param, int paramlen, const u_char *data, int datalen)
+{
+ if (paramlen)
+ smb_fdata(param, "Command=[w]\nStr1=[S]\nStr2=[S]\n", param + paramlen,
+ unicodestr);
+ if (datalen)
+ smb_fdata(data, "IPC ", data + datalen, unicodestr);
+}
+
+
+static void
+print_trans(const u_char *words, const u_char *data1, const u_char *buf, const u_char *maxbuf)
+{
+ u_int bcc;
+ const char *f1, *f2, *f3, *f4;
+ const u_char *data, *param;
+ const u_char *w = words + 1;
+ int datalen, paramlen;
+
+ if (request) {
+ TCHECK2(w[12 * 2], 2);
+ paramlen = EXTRACT_LE_16BITS(w + 9 * 2);
+ param = buf + EXTRACT_LE_16BITS(w + 10 * 2);
+ datalen = EXTRACT_LE_16BITS(w + 11 * 2);
+ data = buf + EXTRACT_LE_16BITS(w + 12 * 2);
+ f1 = "TotParamCnt=[d] \nTotDataCnt=[d] \nMaxParmCnt=[d] \nMaxDataCnt=[d]\nMaxSCnt=[d] \nTransFlags=[w] \nRes1=[w] \nRes2=[w] \nRes3=[w]\nParamCnt=[d] \nParamOff=[d] \nDataCnt=[d] \nDataOff=[d] \nSUCnt=[d]\n";
+ f2 = "|Name=[S]\n";
+ f3 = "|Param ";
+ f4 = "|Data ";
+ } else {
+ TCHECK2(w[7 * 2], 2);
+ paramlen = EXTRACT_LE_16BITS(w + 3 * 2);
+ param = buf + EXTRACT_LE_16BITS(w + 4 * 2);
+ datalen = EXTRACT_LE_16BITS(w + 6 * 2);
+ data = buf + EXTRACT_LE_16BITS(w + 7 * 2);
+ f1 = "TotParamCnt=[d] \nTotDataCnt=[d] \nRes1=[d]\nParamCnt=[d] \nParamOff=[d] \nRes2=[d] \nDataCnt=[d] \nDataOff=[d] \nRes3=[d]\nLsetup=[d]\n";
+ f2 = "|Unknown ";
+ f3 = "|Param ";
+ f4 = "|Data ";
+ }
+
+ smb_fdata(words + 1, f1, SMBMIN(words + 1 + 2 * words[0], maxbuf),
+ unicodestr);
+
+ TCHECK2(*data1, 2);
+ bcc = EXTRACT_LE_16BITS(data1);
+ printf("smb_bcc=%u\n", bcc);
+ if (bcc > 0) {
+ smb_fdata(data1 + 2, f2, maxbuf - (paramlen + datalen), unicodestr);
+
+ if (strcmp((const char *)(data1 + 2), "\\MAILSLOT\\BROWSE") == 0) {
+ print_browse(param, paramlen, data, datalen);
+ return;
+ }
+
+ if (strcmp((const char *)(data1 + 2), "\\PIPE\\LANMAN") == 0) {
+ print_ipc(param, paramlen, data, datalen);
+ return;
+ }
+
+ if (paramlen)
+ smb_fdata(param, f3, SMBMIN(param + paramlen, maxbuf), unicodestr);
+ if (datalen)
+ smb_fdata(data, f4, SMBMIN(data + datalen, maxbuf), unicodestr);
+ }
+ return;
+trunc:
+ printf("[|SMB]");
+ return;
+}
+
+
+static void
+print_negprot(const u_char *words, const u_char *data, const u_char *buf _U_, const u_char *maxbuf)
+{
+ u_int wct, bcc;
+ const char *f1 = NULL, *f2 = NULL;
+
+ TCHECK(words[0]);
+ wct = words[0];
+ if (request)
+ f2 = "*|Dialect=[Y]\n";
+ else {
+ if (wct == 1)
+ f1 = "Core Protocol\nDialectIndex=[d]";
+ else if (wct == 17)
+ f1 = "NT1 Protocol\nDialectIndex=[d]\nSecMode=[B]\nMaxMux=[d]\nNumVcs=[d]\nMaxBuffer=[D]\nRawSize=[D]\nSessionKey=[W]\nCapabilities=[W]\nServerTime=[T3]TimeZone=[d]\nCryptKey=";
+ else if (wct == 13)
+ f1 = "Coreplus/Lanman1/Lanman2 Protocol\nDialectIndex=[d]\nSecMode=[w]\nMaxXMit=[d]\nMaxMux=[d]\nMaxVcs=[d]\nBlkMode=[w]\nSessionKey=[W]\nServerTime=[T1]TimeZone=[d]\nRes=[W]\nCryptKey=";
+ }
+
+ if (f1)
+ smb_fdata(words + 1, f1, SMBMIN(words + 1 + wct * 2, maxbuf),
+ unicodestr);
+ else
+ print_data(words + 1, SMBMIN(wct * 2, PTR_DIFF(maxbuf, words + 1)));
+
+ TCHECK2(*data, 2);
+ bcc = EXTRACT_LE_16BITS(data);
+ printf("smb_bcc=%u\n", bcc);
+ if (bcc > 0) {
+ if (f2)
+ smb_fdata(data + 2, f2, SMBMIN(data + 2 + EXTRACT_LE_16BITS(data),
+ maxbuf), unicodestr);
+ else
+ print_data(data + 2, SMBMIN(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2)));
+ }
+ return;
+trunc:
+ printf("[|SMB]");
+ return;
+}
+
+static void
+print_sesssetup(const u_char *words, const u_char *data, const u_char *buf _U_, const u_char *maxbuf)
+{
+ u_int wct, bcc;
+ const char *f1 = NULL, *f2 = NULL;
+
+ TCHECK(words[0]);
+ wct = words[0];
+ if (request) {
+ if (wct == 10)
+ f1 = "Com2=[w]\nOff2=[d]\nBufSize=[d]\nMpxMax=[d]\nVcNum=[d]\nSessionKey=[W]\nPassLen=[d]\nCryptLen=[d]\nCryptOff=[d]\nPass&Name=\n";
+ else
+ f1 = "Com2=[B]\nRes1=[B]\nOff2=[d]\nMaxBuffer=[d]\nMaxMpx=[d]\nVcNumber=[d]\nSessionKey=[W]\nCaseInsensitivePasswordLength=[d]\nCaseSensitivePasswordLength=[d]\nRes=[W]\nCapabilities=[W]\nPass1&Pass2&Account&Domain&OS&LanMan=\n";
+ } else {
+ if (wct == 3) {
+ f1 = "Com2=[w]\nOff2=[d]\nAction=[w]\n";
+ } else if (wct == 13) {
+ f1 = "Com2=[B]\nRes=[B]\nOff2=[d]\nAction=[w]\n";
+ f2 = "NativeOS=[S]\nNativeLanMan=[S]\nPrimaryDomain=[S]\n";
+ }
+ }
+
+ if (f1)
+ smb_fdata(words + 1, f1, SMBMIN(words + 1 + wct * 2, maxbuf),
+ unicodestr);
+ else
+ print_data(words + 1, SMBMIN(wct * 2, PTR_DIFF(maxbuf, words + 1)));
+
+ TCHECK2(*data, 2);
+ bcc = EXTRACT_LE_16BITS(data);
+ printf("smb_bcc=%u\n", bcc);
+ if (bcc > 0) {
+ if (f2)
+ smb_fdata(data + 2, f2, SMBMIN(data + 2 + EXTRACT_LE_16BITS(data),
+ maxbuf), unicodestr);
+ else
+ print_data(data + 2, SMBMIN(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2)));
+ }
+ return;
+trunc:
+ printf("[|SMB]");
+ return;
+}
+
+static void
+print_lockingandx(const u_char *words, const u_char *data, const u_char *buf _U_, const u_char *maxbuf)
+{
+ u_int wct, bcc;
+ const u_char *maxwords;
+ const char *f1 = NULL, *f2 = NULL;
+
+ TCHECK(words[0]);
+ wct = words[0];
+ if (request) {
+ f1 = "Com2=[w]\nOff2=[d]\nHandle=[d]\nLockType=[w]\nTimeOut=[D]\nUnlockCount=[d]\nLockCount=[d]\n";
+ TCHECK(words[7]);
+ if (words[7] & 0x10)
+ f2 = "*Process=[d]\n[P2]Offset=[M]\nLength=[M]\n";
+ else
+ f2 = "*Process=[d]\nOffset=[D]\nLength=[D]\n";
+ } else {
+ f1 = "Com2=[w]\nOff2=[d]\n";
+ }
+
+ maxwords = SMBMIN(words + 1 + wct * 2, maxbuf);
+ if (wct)
+ smb_fdata(words + 1, f1, maxwords, unicodestr);
+
+ TCHECK2(*data, 2);
+ bcc = EXTRACT_LE_16BITS(data);
+ printf("smb_bcc=%u\n", bcc);
+ if (bcc > 0) {
+ if (f2)
+ smb_fdata(data + 2, f2, SMBMIN(data + 2 + EXTRACT_LE_16BITS(data),
+ maxbuf), unicodestr);
+ else
+ print_data(data + 2, SMBMIN(EXTRACT_LE_16BITS(data), PTR_DIFF(maxbuf, data + 2)));
+ }
+ return;
+trunc:
+ printf("[|SMB]");
+ return;
+}
+
+
+static struct smbfns smb_fns[] = {
+ { -1, "SMBunknown", 0, DEFDESCRIPT },
+
+ { SMBtcon, "SMBtcon", 0,
+ { NULL, "Path=[Z]\nPassword=[Z]\nDevice=[Z]\n",
+ "MaxXmit=[d]\nTreeId=[d]\n", NULL,
+ NULL } },
+
+ { SMBtdis, "SMBtdis", 0, DEFDESCRIPT },
+ { SMBexit, "SMBexit", 0, DEFDESCRIPT },
+ { SMBioctl, "SMBioctl", 0, DEFDESCRIPT },
+
+ { SMBecho, "SMBecho", 0,
+ { "ReverbCount=[d]\n", NULL,
+ "SequenceNum=[d]\n", NULL,
+ NULL } },
+
+ { SMBulogoffX, "SMBulogoffX", FLG_CHAIN, DEFDESCRIPT },
+
+ { SMBgetatr, "SMBgetatr", 0,
+ { NULL, "Path=[Z]\n",
+ "Attribute=[A]\nTime=[T2]Size=[D]\nRes=([w,w,w,w,w])\n", NULL,
+ NULL } },
+
+ { SMBsetatr, "SMBsetatr", 0,
+ { "Attribute=[A]\nTime=[T2]Res=([w,w,w,w,w])\n", "Path=[Z]\n",
+ NULL, NULL, NULL } },
+
+ { SMBchkpth, "SMBchkpth", 0,
+ { NULL, "Path=[Z]\n", NULL, NULL, NULL } },
+
+ { SMBsearch, "SMBsearch", 0,
+ { "Count=[d]\nAttrib=[A]\n",
+ "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\n",
+ "Count=[d]\n",
+ "BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n",
+ NULL } },
+
+ { SMBopen, "SMBopen", 0,
+ { "Mode=[w]\nAttribute=[A]\n", "Path=[Z]\n",
+ "Handle=[d]\nOAttrib=[A]\nTime=[T2]Size=[D]\nAccess=[w]\n",
+ NULL, NULL } },
+
+ { SMBcreate, "SMBcreate", 0,
+ { "Attrib=[A]\nTime=[T2]", "Path=[Z]\n", "Handle=[d]\n", NULL, NULL } },
+
+ { SMBmknew, "SMBmknew", 0,
+ { "Attrib=[A]\nTime=[T2]", "Path=[Z]\n", "Handle=[d]\n", NULL, NULL } },
+
+ { SMBunlink, "SMBunlink", 0,
+ { "Attrib=[A]\n", "Path=[Z]\n", NULL, NULL, NULL } },
+
+ { SMBread, "SMBread", 0,
+ { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL,
+ "Count=[d]\nRes=([w,w,w,w])\n", NULL, NULL } },
+
+ { SMBwrite, "SMBwrite", 0,
+ { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL,
+ "Count=[d]\n", NULL, NULL } },
+
+ { SMBclose, "SMBclose", 0,
+ { "Handle=[d]\nTime=[T2]", NULL, NULL, NULL, NULL } },
+
+ { SMBmkdir, "SMBmkdir", 0,
+ { NULL, "Path=[Z]\n", NULL, NULL, NULL } },
+
+ { SMBrmdir, "SMBrmdir", 0,
+ { NULL, "Path=[Z]\n", NULL, NULL, NULL } },
+
+ { SMBdskattr, "SMBdskattr", 0,
+ { NULL, NULL,
+ "TotalUnits=[d]\nBlocksPerUnit=[d]\nBlockSize=[d]\nFreeUnits=[d]\nMedia=[w]\n",
+ NULL, NULL } },
+
+ { SMBmv, "SMBmv", 0,
+ { "Attrib=[A]\n", "OldPath=[Z]\nNewPath=[Z]\n", NULL, NULL, NULL } },
+
+ /*
+ * this is a Pathworks specific call, allowing the
+ * changing of the root path
+ */
+ { pSETDIR, "SMBsetdir", 0, { NULL, "Path=[Z]\n", NULL, NULL, NULL } },
+
+ { SMBlseek, "SMBlseek", 0,
+ { "Handle=[d]\nMode=[w]\nOffset=[D]\n", "Offset=[D]\n", NULL, NULL, NULL } },
+
+ { SMBflush, "SMBflush", 0, { "Handle=[d]\n", NULL, NULL, NULL, NULL } },
+
+ { SMBsplopen, "SMBsplopen", 0,
+ { "SetupLen=[d]\nMode=[w]\n", "Ident=[Z]\n", "Handle=[d]\n",
+ NULL, NULL } },
+
+ { SMBsplclose, "SMBsplclose", 0,
+ { "Handle=[d]\n", NULL, NULL, NULL, NULL } },
+
+ { SMBsplretq, "SMBsplretq", 0,
+ { "MaxCount=[d]\nStartIndex=[d]\n", NULL,
+ "Count=[d]\nIndex=[d]\n",
+ "*Time=[T2]Status=[B]\nJobID=[d]\nSize=[D]\nRes=[B]Name=[s16]\n",
+ NULL } },
+
+ { SMBsplwr, "SMBsplwr", 0,
+ { "Handle=[d]\n", NULL, NULL, NULL, NULL } },
+
+ { SMBlock, "SMBlock", 0,
+ { "Handle=[d]\nCount=[D]\nOffset=[D]\n", NULL, NULL, NULL, NULL } },
+
+ { SMBunlock, "SMBunlock", 0,
+ { "Handle=[d]\nCount=[D]\nOffset=[D]\n", NULL, NULL, NULL, NULL } },
+
+ /* CORE+ PROTOCOL FOLLOWS */
+
+ { SMBreadbraw, "SMBreadbraw", 0,
+ { "Handle=[d]\nOffset=[D]\nMaxCount=[d]\nMinCount=[d]\nTimeOut=[D]\nRes=[d]\n",
+ NULL, NULL, NULL, NULL } },
+
+ { SMBwritebraw, "SMBwritebraw", 0,
+ { "Handle=[d]\nTotalCount=[d]\nRes=[w]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nRes2=[W]\n|DataSize=[d]\nDataOff=[d]\n",
+ NULL, "WriteRawAck", NULL, NULL } },
+
+ { SMBwritec, "SMBwritec", 0,
+ { NULL, NULL, "Count=[d]\n", NULL, NULL } },
+
+ { SMBwriteclose, "SMBwriteclose", 0,
+ { "Handle=[d]\nCount=[d]\nOffset=[D]\nTime=[T2]Res=([w,w,w,w,w,w])",
+ NULL, "Count=[d]\n", NULL, NULL } },
+
+ { SMBlockread, "SMBlockread", 0,
+ { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL,
+ "Count=[d]\nRes=([w,w,w,w])\n", NULL, NULL } },
+
+ { SMBwriteunlock, "SMBwriteunlock", 0,
+ { "Handle=[d]\nByteCount=[d]\nOffset=[D]\nCountLeft=[d]\n", NULL,
+ "Count=[d]\n", NULL, NULL } },
+
+ { SMBreadBmpx, "SMBreadBmpx", 0,
+ { "Handle=[d]\nOffset=[D]\nMaxCount=[d]\nMinCount=[d]\nTimeOut=[D]\nRes=[w]\n",
+ NULL,
+ "Offset=[D]\nTotCount=[d]\nRemaining=[d]\nRes=([w,w])\nDataSize=[d]\nDataOff=[d]\n",
+ NULL, NULL } },
+
+ { SMBwriteBmpx, "SMBwriteBmpx", 0,
+ { "Handle=[d]\nTotCount=[d]\nRes=[w]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nRes2=[W]\nDataSize=[d]\nDataOff=[d]\n", NULL,
+ "Remaining=[d]\n", NULL, NULL } },
+
+ { SMBwriteBs, "SMBwriteBs", 0,
+ { "Handle=[d]\nTotCount=[d]\nOffset=[D]\nRes=[W]\nDataSize=[d]\nDataOff=[d]\n",
+ NULL, "Count=[d]\n", NULL, NULL } },
+
+ { SMBsetattrE, "SMBsetattrE", 0,
+ { "Handle=[d]\nCreationTime=[T2]AccessTime=[T2]ModifyTime=[T2]", NULL,
+ NULL, NULL, NULL } },
+
+ { SMBgetattrE, "SMBgetattrE", 0,
+ { "Handle=[d]\n", NULL,
+ "CreationTime=[T2]AccessTime=[T2]ModifyTime=[T2]Size=[D]\nAllocSize=[D]\nAttribute=[A]\n",
+ NULL, NULL } },
+
+ { SMBtranss, "SMBtranss", 0, DEFDESCRIPT },
+ { SMBioctls, "SMBioctls", 0, DEFDESCRIPT },
+
+ { SMBcopy, "SMBcopy", 0,
+ { "TreeID2=[d]\nOFun=[w]\nFlags=[w]\n", "Path=[S]\nNewPath=[S]\n",
+ "CopyCount=[d]\n", "|ErrStr=[S]\n", NULL } },
+
+ { SMBmove, "SMBmove", 0,
+ { "TreeID2=[d]\nOFun=[w]\nFlags=[w]\n", "Path=[S]\nNewPath=[S]\n",
+ "MoveCount=[d]\n", "|ErrStr=[S]\n", NULL } },
+
+ { SMBopenX, "SMBopenX", FLG_CHAIN,
+ { "Com2=[w]\nOff2=[d]\nFlags=[w]\nMode=[w]\nSearchAttrib=[A]\nAttrib=[A]\nTime=[T2]OFun=[w]\nSize=[D]\nTimeOut=[D]\nRes=[W]\n",
+ "Path=[S]\n",
+ "Com2=[w]\nOff2=[d]\nHandle=[d]\nAttrib=[A]\nTime=[T2]Size=[D]\nAccess=[w]\nType=[w]\nState=[w]\nAction=[w]\nFileID=[W]\nRes=[w]\n",
+ NULL, NULL } },
+
+ { SMBreadX, "SMBreadX", FLG_CHAIN,
+ { "Com2=[w]\nOff2=[d]\nHandle=[d]\nOffset=[D]\nMaxCount=[d]\nMinCount=[d]\nTimeOut=[D]\nCountLeft=[d]\n",
+ NULL,
+ "Com2=[w]\nOff2=[d]\nRemaining=[d]\nRes=[W]\nDataSize=[d]\nDataOff=[d]\nRes=([w,w,w,w])\n",
+ NULL, NULL } },
+
+ { SMBwriteX, "SMBwriteX", FLG_CHAIN,
+ { "Com2=[w]\nOff2=[d]\nHandle=[d]\nOffset=[D]\nTimeOut=[D]\nWMode=[w]\nCountLeft=[d]\nRes=[w]\nDataSize=[d]\nDataOff=[d]\n",
+ NULL,
+ "Com2=[w]\nOff2=[d]\nCount=[d]\nRemaining=[d]\nRes=[W]\n",
+ NULL, NULL } },
+
+ { SMBffirst, "SMBffirst", 0,
+ { "Count=[d]\nAttrib=[A]\n",
+ "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\n",
+ "Count=[d]\n",
+ "BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n",
+ NULL } },
+
+ { SMBfunique, "SMBfunique", 0,
+ { "Count=[d]\nAttrib=[A]\n",
+ "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\n",
+ "Count=[d]\n",
+ "BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n",
+ NULL } },
+
+ { SMBfclose, "SMBfclose", 0,
+ { "Count=[d]\nAttrib=[A]\n",
+ "Path=[Z]\nBlkType=[B]\nBlkLen=[d]\n|Res1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\n",
+ "Count=[d]\n",
+ "BlkType=[B]\nBlkLen=[d]\n*\nRes1=[B]\nMask=[s11]\nSrv1=[B]\nDirIndex=[d]\nSrv2=[w]\nRes2=[W]\nAttrib=[a]\nTime=[T1]Size=[D]\nName=[s13]\n",
+ NULL } },
+
+ { SMBfindnclose, "SMBfindnclose", 0,
+ { "Handle=[d]\n", NULL, NULL, NULL, NULL } },
+
+ { SMBfindclose, "SMBfindclose", 0,
+ { "Handle=[d]\n", NULL, NULL, NULL, NULL } },
+
+ { SMBsends, "SMBsends", 0,
+ { NULL, "Source=[Z]\nDest=[Z]\n", NULL, NULL, NULL } },
+
+ { SMBsendstrt, "SMBsendstrt", 0,
+ { NULL, "Source=[Z]\nDest=[Z]\n", "GroupID=[d]\n", NULL, NULL } },
+
+ { SMBsendend, "SMBsendend", 0,
+ { "GroupID=[d]\n", NULL, NULL, NULL, NULL } },
+
+ { SMBsendtxt, "SMBsendtxt", 0,
+ { "GroupID=[d]\n", NULL, NULL, NULL, NULL } },
+
+ { SMBsendb, "SMBsendb", 0,
+ { NULL, "Source=[Z]\nDest=[Z]\n", NULL, NULL, NULL } },
+
+ { SMBfwdname, "SMBfwdname", 0, DEFDESCRIPT },
+ { SMBcancelf, "SMBcancelf", 0, DEFDESCRIPT },
+ { SMBgetmac, "SMBgetmac", 0, DEFDESCRIPT },
+
+ { SMBnegprot, "SMBnegprot", 0,
+ { NULL, NULL, NULL, NULL, print_negprot } },
+
+ { SMBsesssetupX, "SMBsesssetupX", FLG_CHAIN,
+ { NULL, NULL, NULL, NULL, print_sesssetup } },
+
+ { SMBtconX, "SMBtconX", FLG_CHAIN,
+ { "Com2=[w]\nOff2=[d]\nFlags=[w]\nPassLen=[d]\nPasswd&Path&Device=\n",
+ NULL, "Com2=[w]\nOff2=[d]\n", "ServiceType=[R]\n", NULL } },
+
+ { SMBlockingX, "SMBlockingX", FLG_CHAIN,
+ { NULL, NULL, NULL, NULL, print_lockingandx } },
+
+ { SMBtrans2, "SMBtrans2", 0, { NULL, NULL, NULL, NULL, print_trans2 } },
+
+ { SMBtranss2, "SMBtranss2", 0, DEFDESCRIPT },
+ { SMBctemp, "SMBctemp", 0, DEFDESCRIPT },
+ { SMBreadBs, "SMBreadBs", 0, DEFDESCRIPT },
+ { SMBtrans, "SMBtrans", 0, { NULL, NULL, NULL, NULL, print_trans } },
+
+ { SMBnttrans, "SMBnttrans", 0, DEFDESCRIPT },
+ { SMBnttranss, "SMBnttranss", 0, DEFDESCRIPT },
+
+ { SMBntcreateX, "SMBntcreateX", FLG_CHAIN,
+ { "Com2=[w]\nOff2=[d]\nRes=[b]\nNameLen=[ld]\nFlags=[W]\nRootDirectoryFid=[D]\nAccessMask=[W]\nAllocationSize=[L]\nExtFileAttributes=[W]\nShareAccess=[W]\nCreateDisposition=[W]\nCreateOptions=[W]\nImpersonationLevel=[W]\nSecurityFlags=[b]\n",
+ "Path=[C]\n",
+ "Com2=[w]\nOff2=[d]\nOplockLevel=[b]\nFid=[d]\nCreateAction=[W]\nCreateTime=[T3]LastAccessTime=[T3]LastWriteTime=[T3]ChangeTime=[T3]ExtFileAttributes=[W]\nAllocationSize=[L]\nEndOfFile=[L]\nFileType=[w]\nDeviceState=[w]\nDirectory=[b]\n",
+ NULL, NULL } },
+
+ { SMBntcancel, "SMBntcancel", 0, DEFDESCRIPT },
+
+ { -1, NULL, 0, DEFDESCRIPT }
+};
+
+
+/*
+ * print a SMB message
+ */
+static void
+print_smb(const u_char *buf, const u_char *maxbuf)
+{
+ u_int16_t flags2;
+ int nterrcodes;
+ int command;
+ u_int32_t nterror;
+ const u_char *words, *maxwords, *data;
+ struct smbfns *fn;
+ const char *fmt_smbheader =
+ "[P4]SMB Command = [B]\nError class = [BP1]\nError code = [d]\nFlags1 = [B]\nFlags2 = [B][P13]\nTree ID = [d]\nProc ID = [d]\nUID = [d]\nMID = [d]\nWord Count = [b]\n";
+ int smboffset;
+
+ TCHECK(buf[9]);
+ request = (buf[9] & 0x80) ? 0 : 1;
+ flags2 = EXTRACT_LE_16BITS(&buf[10]);
+ unicodestr = flags2 & 0x8000;
+ nterrcodes = flags2 & 0x4000;
+ startbuf = buf;
+
+ command = buf[4];
+
+ fn = smbfind(command, smb_fns);
+
+ if (vflag > 1)
+ printf("\n");
+
+ printf("SMB PACKET: %s (%s)\n", fn->name, request ? "REQUEST" : "REPLY");
+
+ if (vflag < 2)
+ return;
+
+ /* print out the header */
+ smb_fdata(buf, fmt_smbheader, buf + 33, unicodestr);
+
+ if (nterrcodes) {
+ nterror = EXTRACT_LE_32BITS(&buf[5]);
+ if (nterror)
+ printf("NTError = %s\n", nt_errstr(nterror));
+ } else {
+ if (buf[5])
+ printf("SMBError = %s\n", smb_errstr(buf[5], EXTRACT_LE_16BITS(&buf[7])));
+ }
+
+ smboffset = 32;
+
+ for (;;) {
+ const char *f1, *f2;
+ int wct;
+ u_int bcc;
+ int newsmboffset;
+
+ words = buf + smboffset;
+ TCHECK(words[0]);
+ wct = words[0];
+ data = words + 1 + wct * 2;
+ maxwords = SMBMIN(data, maxbuf);
+
+ if (request) {
+ f1 = fn->descript.req_f1;
+ f2 = fn->descript.req_f2;
+ } else {
+ f1 = fn->descript.rep_f1;
+ f2 = fn->descript.rep_f2;
+ }
+
+ if (fn->descript.fn)
+ (*fn->descript.fn)(words, data, buf, maxbuf);
+ else {
+ if (wct) {
+ if (f1)
+ smb_fdata(words + 1, f1, words + 1 + wct * 2, unicodestr);
+ else {
+ int i;
+ int v;
+
+ for (i = 0; &words[1 + 2 * i] < maxwords; i++) {
+ TCHECK2(words[1 + 2 * i], 2);
+ v = EXTRACT_LE_16BITS(words + 1 + 2 * i);
+ printf("smb_vwv[%d]=%d (0x%X)\n", i, v, v);
+ }
+ }
+ }
+
+ TCHECK2(*data, 2);
+ bcc = EXTRACT_LE_16BITS(data);
+ printf("smb_bcc=%u\n", bcc);
+ if (f2) {
+ if (bcc > 0)
+ smb_fdata(data + 2, f2, data + 2 + bcc, unicodestr);
+ } else {
+ if (bcc > 0) {
+ printf("smb_buf[]=\n");
+ print_data(data + 2, SMBMIN(bcc, PTR_DIFF(maxbuf, data + 2)));
+ }
+ }
+ }
+
+ if ((fn->flags & FLG_CHAIN) == 0)
+ break;
+ if (wct == 0)
+ break;
+ TCHECK(words[1]);
+ command = words[1];
+ if (command == 0xFF)
+ break;
+ TCHECK2(words[3], 2);
+ newsmboffset = EXTRACT_LE_16BITS(words + 3);
+
+ fn = smbfind(command, smb_fns);
+
+ printf("\nSMB PACKET: %s (%s) (CHAINED)\n",
+ fn->name, request ? "REQUEST" : "REPLY");
+ if (newsmboffset <= smboffset) {
+ printf("Bad andX offset: %u <= %u\n", newsmboffset, smboffset);
+ break;
+ }
+ smboffset = newsmboffset;
+ }
+
+ printf("\n");
+ return;
+trunc:
+ printf("[|SMB]");
+ return;
+}
+
+
+/*
+ * print a NBT packet received across tcp on port 139
+ */
+void
+nbt_tcp_print(const u_char *data, int length)
+{
+ int caplen;
+ int type;
+ u_int nbt_len;
+ const u_char *maxbuf;
+
+ if (length < 4)
+ goto trunc;
+ if (snapend < data)
+ goto trunc;
+ caplen = snapend - data;
+ if (caplen < 4)
+ goto trunc;
+ maxbuf = data + caplen;
+ type = data[0];
+ nbt_len = EXTRACT_16BITS(data + 2);
+ length -= 4;
+ caplen -= 4;
+
+ startbuf = data;
+
+ if (vflag < 2) {
+ printf(" NBT Session Packet: ");
+ switch (type) {
+ case 0x00:
+ printf("Session Message");
+ break;
+
+ case 0x81:
+ printf("Session Request");
+ break;
+
+ case 0x82:
+ printf("Session Granted");
+ break;
+
+ case 0x83:
+ {
+ int ecode;
+
+ if (nbt_len < 4)
+ goto trunc;
+ if (length < 4)
+ goto trunc;
+ if (caplen < 4)
+ goto trunc;
+ ecode = data[4];
+
+ printf("Session Reject, ");
+ switch (ecode) {
+ case 0x80:
+ printf("Not listening on called name");
+ break;
+ case 0x81:
+ printf("Not listening for calling name");
+ break;
+ case 0x82:
+ printf("Called name not present");
+ break;
+ case 0x83:
+ printf("Called name present, but insufficient resources");
+ break;
+ default:
+ printf("Unspecified error 0x%X", ecode);
+ break;
+ }
+ }
+ break;
+
+ case 0x85:
+ printf("Session Keepalive");
+ break;
+
+ default:
+ data = smb_fdata(data, "Unknown packet type [rB]", maxbuf, 0);
+ break;
+ }
+ } else {
+ printf ("\n>>> NBT Session Packet\n");
+ switch (type) {
+ case 0x00:
+ data = smb_fdata(data, "[P1]NBT Session Message\nFlags=[B]\nLength=[rd]\n",
+ data + 4, 0);
+ if (data == NULL)
+ break;
+ if (nbt_len >= 4 && caplen >= 4 && memcmp(data,"\377SMB",4) == 0) {
+ if ((int)nbt_len > caplen) {
+ if ((int)nbt_len > length)
+ printf("WARNING: Packet is continued in later TCP segments\n");
+ else
+ printf("WARNING: Short packet. Try increasing the snap length by %d\n",
+ nbt_len - caplen);
+ }
+ print_smb(data, maxbuf > data + nbt_len ? data + nbt_len : maxbuf);
+ } else
+ printf("Session packet:(raw data or continuation?)\n");
+ break;
+
+ case 0x81:
+ data = smb_fdata(data,
+ "[P1]NBT Session Request\nFlags=[B]\nLength=[rd]\nDestination=[n1]\nSource=[n1]\n",
+ maxbuf, 0);
+ break;
+
+ case 0x82:
+ data = smb_fdata(data, "[P1]NBT Session Granted\nFlags=[B]\nLength=[rd]\n", maxbuf, 0);
+ break;
+
+ case 0x83:
+ {
+ const u_char *origdata;
+ int ecode;
+
+ origdata = data;
+ data = smb_fdata(data, "[P1]NBT SessionReject\nFlags=[B]\nLength=[rd]\nReason=[B]\n",
+ maxbuf, 0);
+ if (data == NULL)
+ break;
+ if (nbt_len >= 1 && caplen >= 1) {
+ ecode = origdata[4];
+ switch (ecode) {
+ case 0x80:
+ printf("Not listening on called name\n");
+ break;
+ case 0x81:
+ printf("Not listening for calling name\n");
+ break;
+ case 0x82:
+ printf("Called name not present\n");
+ break;
+ case 0x83:
+ printf("Called name present, but insufficient resources\n");
+ break;
+ default:
+ printf("Unspecified error 0x%X\n", ecode);
+ break;
+ }
+ }
+ }
+ break;
+
+ case 0x85:
+ data = smb_fdata(data, "[P1]NBT Session Keepalive\nFlags=[B]\nLength=[rd]\n", maxbuf, 0);
+ break;
+
+ default:
+ data = smb_fdata(data, "NBT - Unknown packet type\nType=[B]\n", maxbuf, 0);
+ break;
+ }
+ printf("\n");
+ fflush(stdout);
+ }
+ return;
+trunc:
+ printf("[|SMB]");
+ return;
+}
+
+
+/*
+ * print a NBT packet received across udp on port 137
+ */
+void
+nbt_udp137_print(const u_char *data, int length)
+{
+ const u_char *maxbuf = data + length;
+ int name_trn_id, response, opcode, nm_flags, rcode;
+ int qdcount, ancount, nscount, arcount;
+ const char *opcodestr;
+ const u_char *p;
+ int total, i;
+
+ TCHECK2(data[10], 2);
+ name_trn_id = EXTRACT_16BITS(data);
+ response = (data[2] >> 7);
+ opcode = (data[2] >> 3) & 0xF;
+ nm_flags = ((data[2] & 0x7) << 4) + (data[3] >> 4);
+ rcode = data[3] & 0xF;
+ qdcount = EXTRACT_16BITS(data + 4);
+ ancount = EXTRACT_16BITS(data + 6);
+ nscount = EXTRACT_16BITS(data + 8);
+ arcount = EXTRACT_16BITS(data + 10);
+ startbuf = data;
+
+ if (maxbuf <= data)
+ return;
+
+ if (vflag > 1)
+ printf("\n>>> ");
+
+ printf("NBT UDP PACKET(137): ");
+
+ switch (opcode) {
+ case 0: opcodestr = "QUERY"; break;
+ case 5: opcodestr = "REGISTRATION"; break;
+ case 6: opcodestr = "RELEASE"; break;
+ case 7: opcodestr = "WACK"; break;
+ case 8: opcodestr = "REFRESH(8)"; break;
+ case 9: opcodestr = "REFRESH"; break;
+ case 15: opcodestr = "MULTIHOMED REGISTRATION"; break;
+ default: opcodestr = "OPUNKNOWN"; break;
+ }
+ printf("%s", opcodestr);
+ if (response) {
+ if (rcode)
+ printf("; NEGATIVE");
+ else
+ printf("; POSITIVE");
+ }
+
+ if (response)
+ printf("; RESPONSE");
+ else
+ printf("; REQUEST");
+
+ if (nm_flags & 1)
+ printf("; BROADCAST");
+ else
+ printf("; UNICAST");
+
+ if (vflag < 2)
+ return;
+
+ printf("\nTrnID=0x%X\nOpCode=%d\nNmFlags=0x%X\nRcode=%d\nQueryCount=%d\nAnswerCount=%d\nAuthorityCount=%d\nAddressRecCount=%d\n",
+ name_trn_id, opcode, nm_flags, rcode, qdcount, ancount, nscount,
+ arcount);
+
+ p = data + 12;
+
+ total = ancount + nscount + arcount;
+
+ if (qdcount > 100 || total > 100) {
+ printf("Corrupt packet??\n");
+ return;
+ }
+
+ if (qdcount) {
+ printf("QuestionRecords:\n");
+ for (i = 0; i < qdcount; i++) {
+ p = smb_fdata(p,
+ "|Name=[n1]\nQuestionType=[rw]\nQuestionClass=[rw]\n#",
+ maxbuf, 0);
+ if (p == NULL)
+ goto out;
+ }
+ }
+
+ if (total) {
+ printf("\nResourceRecords:\n");
+ for (i = 0; i < total; i++) {
+ int rdlen;
+ int restype;
+
+ p = smb_fdata(p, "Name=[n1]\n#", maxbuf, 0);
+ if (p == NULL)
+ goto out;
+ restype = EXTRACT_16BITS(p);
+ p = smb_fdata(p, "ResType=[rw]\nResClass=[rw]\nTTL=[rD]\n", p + 8, 0);
+ if (p == NULL)
+ goto out;
+ rdlen = EXTRACT_16BITS(p);
+ printf("ResourceLength=%d\nResourceData=\n", rdlen);
+ p += 2;
+ if (rdlen == 6) {
+ p = smb_fdata(p, "AddrType=[rw]\nAddress=[b.b.b.b]\n", p + rdlen, 0);
+ if (p == NULL)
+ goto out;
+ } else {
+ if (restype == 0x21) {
+ int numnames;
+
+ TCHECK(*p);
+ numnames = p[0];
+ p = smb_fdata(p, "NumNames=[B]\n", p + 1, 0);
+ if (p == NULL)
+ goto out;
+ while (numnames--) {
+ p = smb_fdata(p, "Name=[n2]\t#", maxbuf, 0);
+ if (p == NULL)
+ goto out;
+ TCHECK(*p);
+ if (p[0] & 0x80)
+ printf("<GROUP> ");
+ switch (p[0] & 0x60) {
+ case 0x00: printf("B "); break;
+ case 0x20: printf("P "); break;
+ case 0x40: printf("M "); break;
+ case 0x60: printf("_ "); break;
+ }
+ if (p[0] & 0x10)
+ printf("<DEREGISTERING> ");
+ if (p[0] & 0x08)
+ printf("<CONFLICT> ");
+ if (p[0] & 0x04)
+ printf("<ACTIVE> ");
+ if (p[0] & 0x02)
+ printf("<PERMANENT> ");
+ printf("\n");
+ p += 2;
+ }
+ } else {
+ print_data(p, min(rdlen, length - (p - data)));
+ p += rdlen;
+ }
+ }
+ }
+ }
+
+ if (p < maxbuf)
+ smb_fdata(p, "AdditionalData:\n", maxbuf, 0);
+
+out:
+ printf("\n");
+ fflush(stdout);
+ return;
+trunc:
+ printf("[|SMB]");
+ return;
+}
+
+/*
+ * Print an SMB-over-TCP packet received across tcp on port 445
+ */
+void
+smb_tcp_print (const u_char * data, int length)
+{
+ int caplen;
+ u_int smb_len;
+ const u_char *maxbuf;
+
+ if (length < 4)
+ goto trunc;
+ if (snapend < data)
+ goto trunc;
+ caplen = snapend - data;
+ if (caplen < 4)
+ goto trunc;
+ maxbuf = data + caplen;
+ smb_len = EXTRACT_24BITS(data + 1);
+ length -= 4;
+ caplen -= 4;
+
+ startbuf = data;
+ data += 4;
+
+ if (smb_len >= 4 && caplen >= 4 && memcmp(data,"\377SMB",4) == 0) {
+ if ((int)smb_len > caplen) {
+ if ((int)smb_len > length)
+ printf("WARNING: Packet is continued in later TCP segments\n");
+ else
+ printf("WARNING: Short packet. Try increasing the snap length by %d\n",
+ smb_len - caplen);
+ }
+ print_smb(data, maxbuf > data + smb_len ? data + smb_len : maxbuf);
+ } else
+ printf("SMB-over-TCP packet:(raw data or continuation?)\n");
+ return;
+trunc:
+ printf("[|SMB]");
+ return;
+}
+
+/*
+ * print a NBT packet received across udp on port 138
+ */
+void
+nbt_udp138_print(const u_char *data, int length)
+{
+ const u_char *maxbuf = data + length;
+
+ if (maxbuf > snapend)
+ maxbuf = snapend;
+ if (maxbuf <= data)
+ return;
+ startbuf = data;
+
+ if (vflag < 2) {
+ printf("NBT UDP PACKET(138)");
+ return;
+ }
+
+ data = smb_fdata(data,
+ "\n>>> NBT UDP PACKET(138) Res=[rw] ID=[rw] IP=[b.b.b.b] Port=[rd] Length=[rd] Res2=[rw]\nSourceName=[n1]\nDestName=[n1]\n#",
+ maxbuf, 0);
+
+ if (data != NULL) {
+ /* If there isn't enough data for "\377SMB", don't check for it. */
+ if (&data[3] >= maxbuf)
+ goto out;
+
+ if (memcmp(data, "\377SMB",4) == 0)
+ print_smb(data, maxbuf);
+ }
+out:
+ printf("\n");
+ fflush(stdout);
+}
+
+
+/*
+ print netbeui frames
+*/
+struct nbf_strings {
+ const char *name;
+ const char *nonverbose;
+ const char *verbose;
+} nbf_strings[0x20] = {
+ { "Add Group Name Query", ", [P23]Name to add=[n2]#",
+ "[P5]ResponseCorrelator=[w]\n[P16]Name to add=[n2]\n" },
+ { "Add Name Query", ", [P23]Name to add=[n2]#",
+ "[P5]ResponseCorrelator=[w]\n[P16]Name to add=[n2]\n" },
+ { "Name In Conflict", NULL, NULL },
+ { "Status Query", NULL, NULL },
+ { NULL, NULL, NULL }, /* not used */
+ { NULL, NULL, NULL }, /* not used */
+ { NULL, NULL, NULL }, /* not used */
+ { "Terminate Trace", NULL, NULL },
+ { "Datagram", NULL,
+ "[P7]Destination=[n2]\nSource=[n2]\n" },
+ { "Broadcast Datagram", NULL,
+ "[P7]Destination=[n2]\nSource=[n2]\n" },
+ { "Name Query", ", [P7]Name=[n2]#",
+ "[P1]SessionNumber=[B]\nNameType=[B][P2]\nResponseCorrelator=[w]\nName=[n2]\nName of sender=[n2]\n" },
+ { NULL, NULL, NULL }, /* not used */
+ { NULL, NULL, NULL }, /* not used */
+ { "Add Name Response", ", [P1]GroupName=[w] [P4]Destination=[n2] Source=[n2]#",
+ "AddNameInProcess=[B]\nGroupName=[w]\nTransmitCorrelator=[w][P2]\nDestination=[n2]\nSource=[n2]\n" },
+ { "Name Recognized", NULL,
+ "[P1]Data2=[w]\nTransmitCorrelator=[w]\nResponseCorelator=[w]\nDestination=[n2]\nSource=[n2]\n" },
+ { "Status Response", NULL, NULL },
+ { NULL, NULL, NULL }, /* not used */
+ { NULL, NULL, NULL }, /* not used */
+ { NULL, NULL, NULL }, /* not used */
+ { "Terminate Trace", NULL, NULL },
+ { "Data Ack", NULL,
+ "[P3]TransmitCorrelator=[w][P2]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" },
+ { "Data First/Middle", NULL,
+ "Flags=[{RECEIVE_CONTINUE|NO_ACK||PIGGYBACK_ACK_INCLUDED|}]\nResyncIndicator=[w][P2]\nResponseCorelator=[w]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" },
+ { "Data Only/Last", NULL,
+ "Flags=[{|NO_ACK|PIGGYBACK_ACK_ALLOWED|PIGGYBACK_ACK_INCLUDED|}]\nResyncIndicator=[w][P2]\nResponseCorelator=[w]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" },
+ { "Session Confirm", NULL,
+ "Data1=[B]\nData2=[w]\nTransmitCorrelator=[w]\nResponseCorelator=[w]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" },
+ { "Session End", NULL,
+ "[P1]Data2=[w][P4]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" },
+ { "Session Initialize", NULL,
+ "Data1=[B]\nData2=[w]\nTransmitCorrelator=[w]\nResponseCorelator=[w]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" },
+ { "No Receive", NULL,
+ "Flags=[{|SEND_NO_ACK}]\nDataBytesAccepted=[b][P4]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" },
+ { "Receive Outstanding", NULL,
+ "[P1]DataBytesAccepted=[b][P4]\nRemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" },
+ { "Receive Continue", NULL,
+ "[P2]TransmitCorrelator=[w]\n[P2]RemoteSessionNumber=[B]\nLocalSessionNumber=[B]\n" },
+ { NULL, NULL, NULL }, /* not used */
+ { NULL, NULL, NULL }, /* not used */
+ { "Session Alive", NULL, NULL }
+};
+
+void
+netbeui_print(u_short control, const u_char *data, int length)
+{
+ const u_char *maxbuf = data + length;
+ int len;
+ int command;
+ const u_char *data2;
+ int is_truncated = 0;
+
+ if (maxbuf > snapend)
+ maxbuf = snapend;
+ TCHECK(data[4]);
+ len = EXTRACT_LE_16BITS(data);
+ command = data[4];
+ data2 = data + len;
+ if (data2 >= maxbuf) {
+ data2 = maxbuf;
+ is_truncated = 1;
+ }
+
+ startbuf = data;
+
+ if (vflag < 2) {
+ printf("NBF Packet: ");
+ data = smb_fdata(data, "[P5]#", maxbuf, 0);
+ } else {
+ printf("\n>>> NBF Packet\nType=0x%X ", control);
+ data = smb_fdata(data, "Length=[d] Signature=[w] Command=[B]\n#", maxbuf, 0);
+ }
+ if (data == NULL)
+ goto out;
+
+ if (command > 0x1f || nbf_strings[command].name == NULL) {
+ if (vflag < 2)
+ data = smb_fdata(data, "Unknown NBF Command#", data2, 0);
+ else
+ data = smb_fdata(data, "Unknown NBF Command\n", data2, 0);
+ } else {
+ if (vflag < 2) {
+ printf("%s", nbf_strings[command].name);
+ if (nbf_strings[command].nonverbose != NULL)
+ data = smb_fdata(data, nbf_strings[command].nonverbose, data2, 0);
+ } else {
+ printf("%s:\n", nbf_strings[command].name);
+ if (nbf_strings[command].verbose != NULL)
+ data = smb_fdata(data, nbf_strings[command].verbose, data2, 0);
+ else
+ printf("\n");
+ }
+ }
+
+ if (vflag < 2)
+ return;
+
+ if (data == NULL)
+ goto out;
+
+ if (is_truncated) {
+ /* data2 was past the end of the buffer */
+ goto out;
+ }
+
+ /* If this isn't a command that would contain an SMB message, quit. */
+ if (command != 0x08 && command != 0x09 && command != 0x15 &&
+ command != 0x16)
+ goto out;
+
+ /* If there isn't enough data for "\377SMB", don't look for it. */
+ if (&data2[3] >= maxbuf)
+ goto out;
+
+ if (memcmp(data2, "\377SMB",4) == 0)
+ print_smb(data2, maxbuf);
+ else {
+ int i;
+ for (i = 0; i < 128; i++) {
+ if (&data2[i + 3] >= maxbuf)
+ break;
+ if (memcmp(&data2[i], "\377SMB", 4) == 0) {
+ printf("found SMB packet at %d\n", i);
+ print_smb(&data2[i], maxbuf);
+ break;
+ }
+ }
+ }
+
+out:
+ printf("\n");
+ return;
+trunc:
+ printf("[|SMB]");
+ return;
+}
+
+
+/*
+ * print IPX-Netbios frames
+ */
+void
+ipx_netbios_print(const u_char *data, u_int length)
+{
+ /*
+ * this is a hack till I work out how to parse the rest of the
+ * NetBIOS-over-IPX stuff
+ */
+ int i;
+ const u_char *maxbuf;
+
+ maxbuf = data + length;
+ /* Don't go past the end of the captured data in the packet. */
+ if (maxbuf > snapend)
+ maxbuf = snapend;
+ startbuf = data;
+ for (i = 0; i < 128; i++) {
+ if (&data[i + 4] > maxbuf)
+ break;
+ if (memcmp(&data[i], "\377SMB", 4) == 0) {
+ smb_fdata(data, "\n>>> IPX transport ", &data[i], 0);
+ print_smb(&data[i], maxbuf);
+ printf("\n");
+ fflush(stdout);
+ break;
+ }
+ }
+ if (i == 128)
+ smb_fdata(data, "\n>>> Unknown IPX ", maxbuf, 0);
+}
diff --git a/freebsd/contrib/tcpdump/print-snmp.c b/freebsd/contrib/tcpdump/print-snmp.c
new file mode 100644
index 00000000..e585a4b5
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-snmp.c
@@ -0,0 +1,1906 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
+ * John Robert LoVerso. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * This implementation has been influenced by the CMU SNMP release,
+ * by Steve Waldbusser. However, this shares no code with that system.
+ * Additional ASN.1 insight gained from Marshall T. Rose's _The_Open_Book_.
+ * Earlier forms of this implementation were derived and/or inspired by an
+ * awk script originally written by C. Philip Wood of LANL (but later
+ * heavily modified by John Robert LoVerso). The copyright notice for
+ * that work is preserved below, even though it may not rightly apply
+ * to this file.
+ *
+ * Support for SNMPv2c/SNMPv3 and the ability to link the module against
+ * the libsmi was added by J. Schoenwaelder, Copyright (c) 1999.
+ *
+ * This started out as a very simple program, but the incremental decoding
+ * (into the BE structure) complicated things.
+ *
+ # Los Alamos National Laboratory
+ #
+ # Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
+ # This software was produced under a U.S. Government contract
+ # (W-7405-ENG-36) by Los Alamos National Laboratory, which is
+ # operated by the University of California for the U.S. Department
+ # of Energy. The U.S. Government is licensed to use, reproduce,
+ # and distribute this software. Permission is granted to the
+ # public to copy and use this software without charge, provided
+ # that this Notice and any statement of authorship are reproduced
+ # on all copies. Neither the Government nor the University makes
+ # any warranty, express or implied, or assumes any liability or
+ # responsibility for the use of this software.
+ # @(#)snmp.awk.x 1.1 (LANL) 1/15/90
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-snmp.c,v 1.64 2005-05-06 07:56:53 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#ifdef HAVE_SMI_H
+#include <smi.h>
+#endif
+
+#include "interface.h"
+#include "addrtoname.h"
+
+#undef OPAQUE /* defined in <wingdi.h> */
+
+/*
+ * Universal ASN.1 types
+ * (we only care about the tag values for those allowed in the Internet SMI)
+ */
+const char *Universal[] = {
+ "U-0",
+ "Boolean",
+ "Integer",
+#define INTEGER 2
+ "Bitstring",
+ "String",
+#define STRING 4
+ "Null",
+#define ASN_NULL 5
+ "ObjID",
+#define OBJECTID 6
+ "ObjectDes",
+ "U-8","U-9","U-10","U-11", /* 8-11 */
+ "U-12","U-13","U-14","U-15", /* 12-15 */
+ "Sequence",
+#define SEQUENCE 16
+ "Set"
+};
+
+/*
+ * Application-wide ASN.1 types from the Internet SMI and their tags
+ */
+const char *Application[] = {
+ "IpAddress",
+#define IPADDR 0
+ "Counter",
+#define COUNTER 1
+ "Gauge",
+#define GAUGE 2
+ "TimeTicks",
+#define TIMETICKS 3
+ "Opaque",
+#define OPAQUE 4
+ "C-5",
+ "Counter64"
+#define COUNTER64 6
+};
+
+/*
+ * Context-specific ASN.1 types for the SNMP PDUs and their tags
+ */
+const char *Context[] = {
+ "GetRequest",
+#define GETREQ 0
+ "GetNextRequest",
+#define GETNEXTREQ 1
+ "GetResponse",
+#define GETRESP 2
+ "SetRequest",
+#define SETREQ 3
+ "Trap",
+#define TRAP 4
+ "GetBulk",
+#define GETBULKREQ 5
+ "Inform",
+#define INFORMREQ 6
+ "V2Trap",
+#define V2TRAP 7
+ "Report"
+#define REPORT 8
+};
+
+#define NOTIFY_CLASS(x) (x == TRAP || x == V2TRAP || x == INFORMREQ)
+#define READ_CLASS(x) (x == GETREQ || x == GETNEXTREQ || x == GETBULKREQ)
+#define WRITE_CLASS(x) (x == SETREQ)
+#define RESPONSE_CLASS(x) (x == GETRESP)
+#define INTERNAL_CLASS(x) (x == REPORT)
+
+/*
+ * Context-specific ASN.1 types for the SNMP Exceptions and their tags
+ */
+const char *Exceptions[] = {
+ "noSuchObject",
+#define NOSUCHOBJECT 0
+ "noSuchInstance",
+#define NOSUCHINSTANCE 1
+ "endOfMibView",
+#define ENDOFMIBVIEW 2
+};
+
+/*
+ * Private ASN.1 types
+ * The Internet SMI does not specify any
+ */
+const char *Private[] = {
+ "P-0"
+};
+
+/*
+ * error-status values for any SNMP PDU
+ */
+const char *ErrorStatus[] = {
+ "noError",
+ "tooBig",
+ "noSuchName",
+ "badValue",
+ "readOnly",
+ "genErr",
+ "noAccess",
+ "wrongType",
+ "wrongLength",
+ "wrongEncoding",
+ "wrongValue",
+ "noCreation",
+ "inconsistentValue",
+ "resourceUnavailable",
+ "commitFailed",
+ "undoFailed",
+ "authorizationError",
+ "notWritable",
+ "inconsistentName"
+};
+#define DECODE_ErrorStatus(e) \
+ ( e >= 0 && (size_t)e < sizeof(ErrorStatus)/sizeof(ErrorStatus[0]) \
+ ? ErrorStatus[e] \
+ : (snprintf(errbuf, sizeof(errbuf), "err=%u", e), errbuf))
+
+/*
+ * generic-trap values in the SNMP Trap-PDU
+ */
+const char *GenericTrap[] = {
+ "coldStart",
+ "warmStart",
+ "linkDown",
+ "linkUp",
+ "authenticationFailure",
+ "egpNeighborLoss",
+ "enterpriseSpecific"
+#define GT_ENTERPRISE 6
+};
+#define DECODE_GenericTrap(t) \
+ ( t >= 0 && (size_t)t < sizeof(GenericTrap)/sizeof(GenericTrap[0]) \
+ ? GenericTrap[t] \
+ : (snprintf(buf, sizeof(buf), "gt=%d", t), buf))
+
+/*
+ * ASN.1 type class table
+ * Ties together the preceding Universal, Application, Context, and Private
+ * type definitions.
+ */
+#define defineCLASS(x) { "x", x, sizeof(x)/sizeof(x[0]) } /* not ANSI-C */
+struct {
+ const char *name;
+ const char **Id;
+ int numIDs;
+ } Class[] = {
+ defineCLASS(Universal),
+#define UNIVERSAL 0
+ defineCLASS(Application),
+#define APPLICATION 1
+ defineCLASS(Context),
+#define CONTEXT 2
+ defineCLASS(Private),
+#define PRIVATE 3
+ defineCLASS(Exceptions),
+#define EXCEPTIONS 4
+};
+
+/*
+ * defined forms for ASN.1 types
+ */
+const char *Form[] = {
+ "Primitive",
+#define PRIMITIVE 0
+ "Constructed",
+#define CONSTRUCTED 1
+};
+
+/*
+ * A structure for the OID tree for the compiled-in MIB.
+ * This is stored as a general-order tree.
+ */
+struct obj {
+ const char *desc; /* name of object */
+ u_char oid; /* sub-id following parent */
+ u_char type; /* object type (unused) */
+ struct obj *child, *next; /* child and next sibling pointers */
+} *objp = NULL;
+
+/*
+ * Include the compiled in SNMP MIB. "mib.h" is produced by feeding
+ * RFC-1156 format files into "makemib". "mib.h" MUST define at least
+ * a value for `mibroot'.
+ *
+ * In particular, this is gross, as this is including initialized structures,
+ * and by right shouldn't be an "include" file.
+ */
+#include "mib.h"
+
+/*
+ * This defines a list of OIDs which will be abbreviated on output.
+ * Currently, this includes the prefixes for the Internet MIB, the
+ * private enterprises tree, and the experimental tree.
+ */
+struct obj_abrev {
+ const char *prefix; /* prefix for this abrev */
+ struct obj *node; /* pointer into object table */
+ const char *oid; /* ASN.1 encoded OID */
+} obj_abrev_list[] = {
+#ifndef NO_ABREV_MIB
+ /* .iso.org.dod.internet.mgmt.mib */
+ { "", &_mib_obj, "\53\6\1\2\1" },
+#endif
+#ifndef NO_ABREV_ENTER
+ /* .iso.org.dod.internet.private.enterprises */
+ { "E:", &_enterprises_obj, "\53\6\1\4\1" },
+#endif
+#ifndef NO_ABREV_EXPERI
+ /* .iso.org.dod.internet.experimental */
+ { "X:", &_experimental_obj, "\53\6\1\3" },
+#endif
+#ifndef NO_ABBREV_SNMPMODS
+ /* .iso.org.dod.internet.snmpV2.snmpModules */
+ { "S:", &_snmpModules_obj, "\53\6\1\6\3" },
+#endif
+ { 0,0,0 }
+};
+
+/*
+ * This is used in the OID print routine to walk down the object tree
+ * rooted at `mibroot'.
+ */
+#define OBJ_PRINT(o, suppressdot) \
+{ \
+ if (objp) { \
+ do { \
+ if ((o) == objp->oid) \
+ break; \
+ } while ((objp = objp->next) != NULL); \
+ } \
+ if (objp) { \
+ printf(suppressdot?"%s":".%s", objp->desc); \
+ objp = objp->child; \
+ } else \
+ printf(suppressdot?"%u":".%u", (o)); \
+}
+
+/*
+ * This is the definition for the Any-Data-Type storage used purely for
+ * temporary internal representation while decoding an ASN.1 data stream.
+ */
+struct be {
+ u_int32_t asnlen;
+ union {
+ caddr_t raw;
+ int32_t integer;
+ u_int32_t uns;
+ const u_char *str;
+ struct {
+ u_int32_t high;
+ u_int32_t low;
+ } uns64;
+ } data;
+ u_short id;
+ u_char form, class; /* tag info */
+ u_char type;
+#define BE_ANY 255
+#define BE_NONE 0
+#define BE_NULL 1
+#define BE_OCTET 2
+#define BE_OID 3
+#define BE_INT 4
+#define BE_UNS 5
+#define BE_STR 6
+#define BE_SEQ 7
+#define BE_INETADDR 8
+#define BE_PDU 9
+#define BE_UNS64 10
+#define BE_NOSUCHOBJECT 128
+#define BE_NOSUCHINST 129
+#define BE_ENDOFMIBVIEW 130
+};
+
+/*
+ * SNMP versions recognized by this module
+ */
+const char *SnmpVersion[] = {
+ "SNMPv1",
+#define SNMP_VERSION_1 0
+ "SNMPv2c",
+#define SNMP_VERSION_2 1
+ "SNMPv2u",
+#define SNMP_VERSION_2U 2
+ "SNMPv3"
+#define SNMP_VERSION_3 3
+};
+
+/*
+ * Defaults for SNMP PDU components
+ */
+#define DEF_COMMUNITY "public"
+
+/*
+ * constants for ASN.1 decoding
+ */
+#define OIDMUX 40
+#define ASNLEN_INETADDR 4
+#define ASN_SHIFT7 7
+#define ASN_SHIFT8 8
+#define ASN_BIT8 0x80
+#define ASN_LONGLEN 0x80
+
+#define ASN_ID_BITS 0x1f
+#define ASN_FORM_BITS 0x20
+#define ASN_FORM_SHIFT 5
+#define ASN_CLASS_BITS 0xc0
+#define ASN_CLASS_SHIFT 6
+
+#define ASN_ID_EXT 0x1f /* extension ID in tag field */
+
+/*
+ * This decodes the next ASN.1 object in the stream pointed to by "p"
+ * (and of real-length "len") and stores the intermediate data in the
+ * provided BE object.
+ *
+ * This returns -l if it fails (i.e., the ASN.1 stream is not valid).
+ * O/w, this returns the number of bytes parsed from "p".
+ */
+static int
+asn1_parse(register const u_char *p, u_int len, struct be *elem)
+{
+ u_char form, class, id;
+ int i, hdr;
+
+ elem->asnlen = 0;
+ elem->type = BE_ANY;
+ if (len < 1) {
+ fputs("[nothing to parse]", stdout);
+ return -1;
+ }
+ TCHECK(*p);
+
+ /*
+ * it would be nice to use a bit field, but you can't depend on them.
+ * +---+---+---+---+---+---+---+---+
+ * + class |frm| id |
+ * +---+---+---+---+---+---+---+---+
+ * 7 6 5 4 3 2 1 0
+ */
+ id = *p & ASN_ID_BITS; /* lower 5 bits, range 00-1f */
+#ifdef notdef
+ form = (*p & 0xe0) >> 5; /* move upper 3 bits to lower 3 */
+ class = form >> 1; /* bits 7&6 -> bits 1&0, range 0-3 */
+ form &= 0x1; /* bit 5 -> bit 0, range 0-1 */
+#else
+ form = (u_char)(*p & ASN_FORM_BITS) >> ASN_FORM_SHIFT;
+ class = (u_char)(*p & ASN_CLASS_BITS) >> ASN_CLASS_SHIFT;
+#endif
+ elem->form = form;
+ elem->class = class;
+ elem->id = id;
+ p++; len--; hdr = 1;
+ /* extended tag field */
+ if (id == ASN_ID_EXT) {
+ /*
+ * The ID follows, as a sequence of octets with the
+ * 8th bit set and the remaining 7 bits being
+ * the next 7 bits of the value, terminated with
+ * an octet with the 8th bit not set.
+ *
+ * First, assemble all the octets with the 8th
+ * bit set. XXX - this doesn't handle a value
+ * that won't fit in 32 bits.
+ */
+ for (id = 0; *p & ASN_BIT8; len--, hdr++, p++) {
+ if (len < 1) {
+ fputs("[Xtagfield?]", stdout);
+ return -1;
+ }
+ TCHECK(*p);
+ id = (id << 7) | (*p & ~ASN_BIT8);
+ }
+ if (len < 1) {
+ fputs("[Xtagfield?]", stdout);
+ return -1;
+ }
+ TCHECK(*p);
+ elem->id = id = (id << 7) | *p;
+ --len;
+ ++hdr;
+ ++p;
+ }
+ if (len < 1) {
+ fputs("[no asnlen]", stdout);
+ return -1;
+ }
+ TCHECK(*p);
+ elem->asnlen = *p;
+ p++; len--; hdr++;
+ if (elem->asnlen & ASN_BIT8) {
+ u_int32_t noct = elem->asnlen % ASN_BIT8;
+ elem->asnlen = 0;
+ if (len < noct) {
+ printf("[asnlen? %d<%d]", len, noct);
+ return -1;
+ }
+ TCHECK2(*p, noct);
+ for (; noct-- > 0; len--, hdr++)
+ elem->asnlen = (elem->asnlen << ASN_SHIFT8) | *p++;
+ }
+ if (len < elem->asnlen) {
+ printf("[len%d<asnlen%u]", len, elem->asnlen);
+ return -1;
+ }
+ if (form >= sizeof(Form)/sizeof(Form[0])) {
+ printf("[form?%d]", form);
+ return -1;
+ }
+ if (class >= sizeof(Class)/sizeof(Class[0])) {
+ printf("[class?%c/%d]", *Form[form], class);
+ return -1;
+ }
+ if ((int)id >= Class[class].numIDs) {
+ printf("[id?%c/%s/%d]", *Form[form], Class[class].name, id);
+ return -1;
+ }
+
+ switch (form) {
+ case PRIMITIVE:
+ switch (class) {
+ case UNIVERSAL:
+ switch (id) {
+ case STRING:
+ elem->type = BE_STR;
+ elem->data.str = p;
+ break;
+
+ case INTEGER: {
+ register int32_t data;
+ elem->type = BE_INT;
+ data = 0;
+
+ TCHECK2(*p, elem->asnlen);
+ if (*p & ASN_BIT8) /* negative */
+ data = -1;
+ for (i = elem->asnlen; i-- > 0; p++)
+ data = (data << ASN_SHIFT8) | *p;
+ elem->data.integer = data;
+ break;
+ }
+
+ case OBJECTID:
+ elem->type = BE_OID;
+ elem->data.raw = (caddr_t)p;
+ break;
+
+ case ASN_NULL:
+ elem->type = BE_NULL;
+ elem->data.raw = NULL;
+ break;
+
+ default:
+ elem->type = BE_OCTET;
+ elem->data.raw = (caddr_t)p;
+ printf("[P/U/%s]",
+ Class[class].Id[id]);
+ break;
+ }
+ break;
+
+ case APPLICATION:
+ switch (id) {
+ case IPADDR:
+ elem->type = BE_INETADDR;
+ elem->data.raw = (caddr_t)p;
+ break;
+
+ case COUNTER:
+ case GAUGE:
+ case TIMETICKS: {
+ register u_int32_t data;
+ TCHECK2(*p, elem->asnlen);
+ elem->type = BE_UNS;
+ data = 0;
+ for (i = elem->asnlen; i-- > 0; p++)
+ data = (data << 8) + *p;
+ elem->data.uns = data;
+ break;
+ }
+
+ case COUNTER64: {
+ register u_int32_t high, low;
+ TCHECK2(*p, elem->asnlen);
+ elem->type = BE_UNS64;
+ high = 0, low = 0;
+ for (i = elem->asnlen; i-- > 0; p++) {
+ high = (high << 8) |
+ ((low & 0xFF000000) >> 24);
+ low = (low << 8) | *p;
+ }
+ elem->data.uns64.high = high;
+ elem->data.uns64.low = low;
+ break;
+ }
+
+ default:
+ elem->type = BE_OCTET;
+ elem->data.raw = (caddr_t)p;
+ printf("[P/A/%s]",
+ Class[class].Id[id]);
+ break;
+ }
+ break;
+
+ case CONTEXT:
+ switch (id) {
+ case NOSUCHOBJECT:
+ elem->type = BE_NOSUCHOBJECT;
+ elem->data.raw = NULL;
+ break;
+
+ case NOSUCHINSTANCE:
+ elem->type = BE_NOSUCHINST;
+ elem->data.raw = NULL;
+ break;
+
+ case ENDOFMIBVIEW:
+ elem->type = BE_ENDOFMIBVIEW;
+ elem->data.raw = NULL;
+ break;
+ }
+ break;
+
+ default:
+ printf("[P/%s/%s]",
+ Class[class].name, Class[class].Id[id]);
+ TCHECK2(*p, elem->asnlen);
+ elem->type = BE_OCTET;
+ elem->data.raw = (caddr_t)p;
+ break;
+ }
+ break;
+
+ case CONSTRUCTED:
+ switch (class) {
+ case UNIVERSAL:
+ switch (id) {
+ case SEQUENCE:
+ elem->type = BE_SEQ;
+ elem->data.raw = (caddr_t)p;
+ break;
+
+ default:
+ elem->type = BE_OCTET;
+ elem->data.raw = (caddr_t)p;
+ printf("C/U/%s", Class[class].Id[id]);
+ break;
+ }
+ break;
+
+ case CONTEXT:
+ elem->type = BE_PDU;
+ elem->data.raw = (caddr_t)p;
+ break;
+
+ default:
+ elem->type = BE_OCTET;
+ elem->data.raw = (caddr_t)p;
+ printf("C/%s/%s",
+ Class[class].name, Class[class].Id[id]);
+ break;
+ }
+ break;
+ }
+ p += elem->asnlen;
+ len -= elem->asnlen;
+ return elem->asnlen + hdr;
+
+trunc:
+ fputs("[|snmp]", stdout);
+ return -1;
+}
+
+/*
+ * Display the ASN.1 object represented by the BE object.
+ * This used to be an integral part of asn1_parse() before the intermediate
+ * BE form was added.
+ */
+static int
+asn1_print(struct be *elem)
+{
+ u_char *p = (u_char *)elem->data.raw;
+ u_int32_t asnlen = elem->asnlen;
+ u_int32_t i;
+
+ switch (elem->type) {
+
+ case BE_OCTET:
+ TCHECK2(*p, asnlen);
+ for (i = asnlen; i-- > 0; p++)
+ printf("_%.2x", *p);
+ break;
+
+ case BE_NULL:
+ break;
+
+ case BE_OID: {
+ int o = 0, first = -1, i = asnlen;
+
+ if (!sflag && !nflag && asnlen > 2) {
+ struct obj_abrev *a = &obj_abrev_list[0];
+ size_t a_len = strlen(a->oid);
+ for (; a->node; a++) {
+ TCHECK2(*p, a_len);
+ if (memcmp(a->oid, (char *)p, a_len) == 0) {
+ objp = a->node->child;
+ i -= strlen(a->oid);
+ p += strlen(a->oid);
+ fputs(a->prefix, stdout);
+ first = 1;
+ break;
+ }
+ }
+ }
+
+ for (; !sflag && i-- > 0; p++) {
+ TCHECK(*p);
+ o = (o << ASN_SHIFT7) + (*p & ~ASN_BIT8);
+ if (*p & ASN_LONGLEN)
+ continue;
+
+ /*
+ * first subitem encodes two items with 1st*OIDMUX+2nd
+ * (see X.690:1997 clause 8.19 for the details)
+ */
+ if (first < 0) {
+ int s;
+ if (!nflag)
+ objp = mibroot;
+ first = 0;
+ s = o / OIDMUX;
+ if (s > 2) s = 2;
+ OBJ_PRINT(s, first);
+ o -= s * OIDMUX;
+ }
+ OBJ_PRINT(o, first);
+ if (--first < 0)
+ first = 0;
+ o = 0;
+ }
+ break;
+ }
+
+ case BE_INT:
+ printf("%d", elem->data.integer);
+ break;
+
+ case BE_UNS:
+ printf("%u", elem->data.uns);
+ break;
+
+ case BE_UNS64: { /* idea borrowed from by Marshall Rose */
+ double d;
+ int j, carry;
+ char *cpf, *cpl, last[6], first[30];
+ if (elem->data.uns64.high == 0) {
+ printf("%u", elem->data.uns64.low);
+ break;
+ }
+ d = elem->data.uns64.high * 4294967296.0; /* 2^32 */
+ if (elem->data.uns64.high <= 0x1fffff) {
+ d += elem->data.uns64.low;
+#if 0 /*is looks illegal, but what is the intention?*/
+ printf("%.f", d);
+#else
+ printf("%f", d);
+#endif
+ break;
+ }
+ d += (elem->data.uns64.low & 0xfffff000);
+#if 0 /*is looks illegal, but what is the intention?*/
+ snprintf(first, sizeof(first), "%.f", d);
+#else
+ snprintf(first, sizeof(first), "%f", d);
+#endif
+ snprintf(last, sizeof(last), "%5.5d",
+ elem->data.uns64.low & 0xfff);
+ for (carry = 0, cpf = first+strlen(first)-1, cpl = last+4;
+ cpl >= last;
+ cpf--, cpl--) {
+ j = carry + (*cpf - '0') + (*cpl - '0');
+ if (j > 9) {
+ j -= 10;
+ carry = 1;
+ } else {
+ carry = 0;
+ }
+ *cpf = j + '0';
+ }
+ fputs(first, stdout);
+ break;
+ }
+
+ case BE_STR: {
+ register int printable = 1, first = 1;
+ const u_char *p = elem->data.str;
+ TCHECK2(*p, asnlen);
+ for (i = asnlen; printable && i-- > 0; p++)
+ printable = isprint(*p) || isspace(*p);
+ p = elem->data.str;
+ if (printable) {
+ putchar('"');
+ if (fn_printn(p, asnlen, snapend)) {
+ putchar('"');
+ goto trunc;
+ }
+ putchar('"');
+ } else
+ for (i = asnlen; i-- > 0; p++) {
+ printf(first ? "%.2x" : "_%.2x", *p);
+ first = 0;
+ }
+ break;
+ }
+
+ case BE_SEQ:
+ printf("Seq(%u)", elem->asnlen);
+ break;
+
+ case BE_INETADDR:
+ if (asnlen != ASNLEN_INETADDR)
+ printf("[inetaddr len!=%d]", ASNLEN_INETADDR);
+ TCHECK2(*p, asnlen);
+ for (i = asnlen; i-- != 0; p++) {
+ printf((i == asnlen-1) ? "%u" : ".%u", *p);
+ }
+ break;
+
+ case BE_NOSUCHOBJECT:
+ case BE_NOSUCHINST:
+ case BE_ENDOFMIBVIEW:
+ printf("[%s]", Class[EXCEPTIONS].Id[elem->id]);
+ break;
+
+ case BE_PDU:
+ printf("%s(%u)",
+ Class[CONTEXT].Id[elem->id], elem->asnlen);
+ break;
+
+ case BE_ANY:
+ fputs("[BE_ANY!?]", stdout);
+ break;
+
+ default:
+ fputs("[be!?]", stdout);
+ break;
+ }
+ return 0;
+
+trunc:
+ fputs("[|snmp]", stdout);
+ return -1;
+}
+
+#ifdef notdef
+/*
+ * This is a brute force ASN.1 printer: recurses to dump an entire structure.
+ * This will work for any ASN.1 stream, not just an SNMP PDU.
+ *
+ * By adding newlines and spaces at the correct places, this would print in
+ * Rose-Normal-Form.
+ *
+ * This is not currently used.
+ */
+static void
+asn1_decode(u_char *p, u_int length)
+{
+ struct be elem;
+ int i = 0;
+
+ while (i >= 0 && length > 0) {
+ i = asn1_parse(p, length, &elem);
+ if (i >= 0) {
+ fputs(" ", stdout);
+ if (asn1_print(&elem) < 0)
+ return;
+ if (elem.type == BE_SEQ || elem.type == BE_PDU) {
+ fputs(" {", stdout);
+ asn1_decode(elem.data.raw, elem.asnlen);
+ fputs(" }", stdout);
+ }
+ length -= i;
+ p += i;
+ }
+ }
+}
+#endif
+
+#ifdef LIBSMI
+
+struct smi2be {
+ SmiBasetype basetype;
+ int be;
+};
+
+static struct smi2be smi2betab[] = {
+ { SMI_BASETYPE_INTEGER32, BE_INT },
+ { SMI_BASETYPE_OCTETSTRING, BE_STR },
+ { SMI_BASETYPE_OCTETSTRING, BE_INETADDR },
+ { SMI_BASETYPE_OBJECTIDENTIFIER, BE_OID },
+ { SMI_BASETYPE_UNSIGNED32, BE_UNS },
+ { SMI_BASETYPE_INTEGER64, BE_NONE },
+ { SMI_BASETYPE_UNSIGNED64, BE_UNS64 },
+ { SMI_BASETYPE_FLOAT32, BE_NONE },
+ { SMI_BASETYPE_FLOAT64, BE_NONE },
+ { SMI_BASETYPE_FLOAT128, BE_NONE },
+ { SMI_BASETYPE_ENUM, BE_INT },
+ { SMI_BASETYPE_BITS, BE_STR },
+ { SMI_BASETYPE_UNKNOWN, BE_NONE }
+};
+
+static int
+smi_decode_oid(struct be *elem, unsigned int *oid,
+ unsigned int oidsize, unsigned int *oidlen)
+{
+ u_char *p = (u_char *)elem->data.raw;
+ u_int32_t asnlen = elem->asnlen;
+ int o = 0, first = -1, i = asnlen;
+
+ for (*oidlen = 0; sflag && i-- > 0; p++) {
+ TCHECK(*p);
+ o = (o << ASN_SHIFT7) + (*p & ~ASN_BIT8);
+ if (*p & ASN_LONGLEN)
+ continue;
+
+ /*
+ * first subitem encodes two items with 1st*OIDMUX+2nd
+ * (see X.690:1997 clause 8.19 for the details)
+ */
+ if (first < 0) {
+ first = 0;
+ if (*oidlen < oidsize) {
+ oid[*oidlen] = o / OIDMUX;
+ if (oid[*oidlen] > 2) oid[*oidlen] = 2;
+ }
+ o -= oid[*oidlen] * OIDMUX;
+ if (*oidlen < oidsize) (*oidlen)++;
+ }
+ if (*oidlen < oidsize) {
+ oid[(*oidlen)++] = o;
+ }
+ o = 0;
+ }
+ return 0;
+
+trunc:
+ fputs("[|snmp]", stdout);
+ return -1;
+}
+
+static int smi_check_type(SmiBasetype basetype, int be)
+{
+ int i;
+
+ for (i = 0; smi2betab[i].basetype != SMI_BASETYPE_UNKNOWN; i++) {
+ if (smi2betab[i].basetype == basetype && smi2betab[i].be == be) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int smi_check_a_range(SmiType *smiType, SmiRange *smiRange,
+ struct be *elem)
+{
+ int ok = 1;
+
+ switch (smiType->basetype) {
+ case SMI_BASETYPE_OBJECTIDENTIFIER:
+ case SMI_BASETYPE_OCTETSTRING:
+ if (smiRange->minValue.value.unsigned32
+ == smiRange->maxValue.value.unsigned32) {
+ ok = (elem->asnlen == smiRange->minValue.value.unsigned32);
+ } else {
+ ok = (elem->asnlen >= smiRange->minValue.value.unsigned32
+ && elem->asnlen <= smiRange->maxValue.value.unsigned32);
+ }
+ break;
+
+ case SMI_BASETYPE_INTEGER32:
+ ok = (elem->data.integer >= smiRange->minValue.value.integer32
+ && elem->data.integer <= smiRange->maxValue.value.integer32);
+ break;
+
+ case SMI_BASETYPE_UNSIGNED32:
+ ok = (elem->data.uns >= smiRange->minValue.value.unsigned32
+ && elem->data.uns <= smiRange->maxValue.value.unsigned32);
+ break;
+
+ case SMI_BASETYPE_UNSIGNED64:
+ /* XXX */
+ break;
+
+ /* case SMI_BASETYPE_INTEGER64: SMIng */
+ /* case SMI_BASETYPE_FLOAT32: SMIng */
+ /* case SMI_BASETYPE_FLOAT64: SMIng */
+ /* case SMI_BASETYPE_FLOAT128: SMIng */
+
+ case SMI_BASETYPE_ENUM:
+ case SMI_BASETYPE_BITS:
+ case SMI_BASETYPE_UNKNOWN:
+ ok = 1;
+ break;
+
+ default:
+ ok = 0;
+ break;
+ }
+
+ return ok;
+}
+
+static int smi_check_range(SmiType *smiType, struct be *elem)
+{
+ SmiRange *smiRange;
+ int ok = 1;
+
+ for (smiRange = smiGetFirstRange(smiType);
+ smiRange;
+ smiRange = smiGetNextRange(smiRange)) {
+
+ ok = smi_check_a_range(smiType, smiRange, elem);
+
+ if (ok) {
+ break;
+ }
+ }
+
+ if (ok) {
+ SmiType *parentType;
+ parentType = smiGetParentType(smiType);
+ if (parentType) {
+ ok = smi_check_range(parentType, elem);
+ }
+ }
+
+ return ok;
+}
+
+static SmiNode *smi_print_variable(struct be *elem, int *status)
+{
+ unsigned int oid[128], oidlen;
+ SmiNode *smiNode = NULL;
+ unsigned int i;
+
+ *status = smi_decode_oid(elem, oid, sizeof(oid)/sizeof(unsigned int),
+ &oidlen);
+ if (*status < 0)
+ return NULL;
+ smiNode = smiGetNodeByOID(oidlen, oid);
+ if (! smiNode) {
+ *status = asn1_print(elem);
+ return NULL;
+ }
+ if (vflag) {
+ fputs(smiGetNodeModule(smiNode)->name, stdout);
+ fputs("::", stdout);
+ }
+ fputs(smiNode->name, stdout);
+ if (smiNode->oidlen < oidlen) {
+ for (i = smiNode->oidlen; i < oidlen; i++) {
+ printf(".%u", oid[i]);
+ }
+ }
+ *status = 0;
+ return smiNode;
+}
+
+static int
+smi_print_value(SmiNode *smiNode, u_char pduid, struct be *elem)
+{
+ unsigned int i, oid[128], oidlen;
+ SmiType *smiType;
+ SmiNamedNumber *nn;
+ int done = 0;
+
+ if (! smiNode || ! (smiNode->nodekind
+ & (SMI_NODEKIND_SCALAR | SMI_NODEKIND_COLUMN))) {
+ return asn1_print(elem);
+ }
+
+ if (elem->type == BE_NOSUCHOBJECT
+ || elem->type == BE_NOSUCHINST
+ || elem->type == BE_ENDOFMIBVIEW) {
+ return asn1_print(elem);
+ }
+
+ if (NOTIFY_CLASS(pduid) && smiNode->access < SMI_ACCESS_NOTIFY) {
+ fputs("[notNotifyable]", stdout);
+ }
+
+ if (READ_CLASS(pduid) && smiNode->access < SMI_ACCESS_READ_ONLY) {
+ fputs("[notReadable]", stdout);
+ }
+
+ if (WRITE_CLASS(pduid) && smiNode->access < SMI_ACCESS_READ_WRITE) {
+ fputs("[notWritable]", stdout);
+ }
+
+ if (RESPONSE_CLASS(pduid)
+ && smiNode->access == SMI_ACCESS_NOT_ACCESSIBLE) {
+ fputs("[noAccess]", stdout);
+ }
+
+ smiType = smiGetNodeType(smiNode);
+ if (! smiType) {
+ return asn1_print(elem);
+ }
+
+ if (! smi_check_type(smiType->basetype, elem->type)) {
+ fputs("[wrongType]", stdout);
+ }
+
+ if (! smi_check_range(smiType, elem)) {
+ fputs("[outOfRange]", stdout);
+ }
+
+ /* resolve bits to named bits */
+
+ /* check whether instance identifier is valid */
+
+ /* apply display hints (integer, octetstring) */
+
+ /* convert instance identifier to index type values */
+
+ switch (elem->type) {
+ case BE_OID:
+ if (smiType->basetype == SMI_BASETYPE_BITS) {
+ /* print bit labels */
+ } else {
+ smi_decode_oid(elem, oid,
+ sizeof(oid)/sizeof(unsigned int),
+ &oidlen);
+ smiNode = smiGetNodeByOID(oidlen, oid);
+ if (smiNode) {
+ if (vflag) {
+ fputs(smiGetNodeModule(smiNode)->name, stdout);
+ fputs("::", stdout);
+ }
+ fputs(smiNode->name, stdout);
+ if (smiNode->oidlen < oidlen) {
+ for (i = smiNode->oidlen;
+ i < oidlen; i++) {
+ printf(".%u", oid[i]);
+ }
+ }
+ done++;
+ }
+ }
+ break;
+
+ case BE_INT:
+ if (smiType->basetype == SMI_BASETYPE_ENUM) {
+ for (nn = smiGetFirstNamedNumber(smiType);
+ nn;
+ nn = smiGetNextNamedNumber(nn)) {
+ if (nn->value.value.integer32
+ == elem->data.integer) {
+ fputs(nn->name, stdout);
+ printf("(%d)", elem->data.integer);
+ done++;
+ break;
+ }
+ }
+ }
+ break;
+ }
+
+ if (! done) {
+ return asn1_print(elem);
+ }
+ return 0;
+}
+#endif
+
+/*
+ * General SNMP header
+ * SEQUENCE {
+ * version INTEGER {version-1(0)},
+ * community OCTET STRING,
+ * data ANY -- PDUs
+ * }
+ * PDUs for all but Trap: (see rfc1157 from page 15 on)
+ * SEQUENCE {
+ * request-id INTEGER,
+ * error-status INTEGER,
+ * error-index INTEGER,
+ * varbindlist SEQUENCE OF
+ * SEQUENCE {
+ * name ObjectName,
+ * value ObjectValue
+ * }
+ * }
+ * PDU for Trap:
+ * SEQUENCE {
+ * enterprise OBJECT IDENTIFIER,
+ * agent-addr NetworkAddress,
+ * generic-trap INTEGER,
+ * specific-trap INTEGER,
+ * time-stamp TimeTicks,
+ * varbindlist SEQUENCE OF
+ * SEQUENCE {
+ * name ObjectName,
+ * value ObjectValue
+ * }
+ * }
+ */
+
+/*
+ * Decode SNMP varBind
+ */
+static void
+varbind_print(u_char pduid, const u_char *np, u_int length)
+{
+ struct be elem;
+ int count = 0, ind;
+#ifdef LIBSMI
+ SmiNode *smiNode = NULL;
+#endif
+ int status;
+
+ /* Sequence of varBind */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_SEQ) {
+ fputs("[!SEQ of varbind]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ if ((u_int)count < length)
+ printf("[%d extra after SEQ of varbind]", length - count);
+ /* descend */
+ length = elem.asnlen;
+ np = (u_char *)elem.data.raw;
+
+ for (ind = 1; length > 0; ind++) {
+ const u_char *vbend;
+ u_int vblength;
+
+ fputs(" ", stdout);
+
+ /* Sequence */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_SEQ) {
+ fputs("[!varbind]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ vbend = np + count;
+ vblength = length - count;
+ /* descend */
+ length = elem.asnlen;
+ np = (u_char *)elem.data.raw;
+
+ /* objName (OID) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_OID) {
+ fputs("[objName!=OID]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+#ifdef LIBSMI
+ smiNode = smi_print_variable(&elem, &status);
+#else
+ status = asn1_print(&elem);
+#endif
+ if (status < 0)
+ return;
+ length -= count;
+ np += count;
+
+ if (pduid != GETREQ && pduid != GETNEXTREQ
+ && pduid != GETBULKREQ)
+ fputs("=", stdout);
+
+ /* objVal (ANY) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (pduid == GETREQ || pduid == GETNEXTREQ
+ || pduid == GETBULKREQ) {
+ if (elem.type != BE_NULL) {
+ fputs("[objVal!=NULL]", stdout);
+ if (asn1_print(&elem) < 0)
+ return;
+ }
+ } else {
+ if (elem.type != BE_NULL) {
+#ifdef LIBSMI
+ status = smi_print_value(smiNode, pduid, &elem);
+#else
+ status = asn1_print(&elem);
+#endif
+ }
+ if (status < 0)
+ return;
+ }
+ length = vblength;
+ np = vbend;
+ }
+}
+
+/*
+ * Decode SNMP PDUs: GetRequest, GetNextRequest, GetResponse, SetRequest,
+ * GetBulk, Inform, V2Trap, and Report
+ */
+static void
+snmppdu_print(u_short pduid, const u_char *np, u_int length)
+{
+ struct be elem;
+ int count = 0, error;
+
+ /* reqId (Integer) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_INT) {
+ fputs("[reqId!=INT]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ if (vflag)
+ printf("R=%d ", elem.data.integer);
+ length -= count;
+ np += count;
+
+ /* errorStatus (Integer) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_INT) {
+ fputs("[errorStatus!=INT]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ error = 0;
+ if ((pduid == GETREQ || pduid == GETNEXTREQ || pduid == SETREQ
+ || pduid == INFORMREQ || pduid == V2TRAP || pduid == REPORT)
+ && elem.data.integer != 0) {
+ char errbuf[20];
+ printf("[errorStatus(%s)!=0]",
+ DECODE_ErrorStatus(elem.data.integer));
+ } else if (pduid == GETBULKREQ) {
+ printf(" N=%d", elem.data.integer);
+ } else if (elem.data.integer != 0) {
+ char errbuf[20];
+ printf(" %s", DECODE_ErrorStatus(elem.data.integer));
+ error = elem.data.integer;
+ }
+ length -= count;
+ np += count;
+
+ /* errorIndex (Integer) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_INT) {
+ fputs("[errorIndex!=INT]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ if ((pduid == GETREQ || pduid == GETNEXTREQ || pduid == SETREQ
+ || pduid == INFORMREQ || pduid == V2TRAP || pduid == REPORT)
+ && elem.data.integer != 0)
+ printf("[errorIndex(%d)!=0]", elem.data.integer);
+ else if (pduid == GETBULKREQ)
+ printf(" M=%d", elem.data.integer);
+ else if (elem.data.integer != 0) {
+ if (!error)
+ printf("[errorIndex(%d) w/o errorStatus]",
+ elem.data.integer);
+ else {
+ printf("@%d", elem.data.integer);
+ error = elem.data.integer;
+ }
+ } else if (error) {
+ fputs("[errorIndex==0]", stdout);
+ error = 0;
+ }
+ length -= count;
+ np += count;
+
+ varbind_print(pduid, np, length);
+ return;
+}
+
+/*
+ * Decode SNMP Trap PDU
+ */
+static void
+trappdu_print(const u_char *np, u_int length)
+{
+ struct be elem;
+ int count = 0, generic;
+
+ putchar(' ');
+
+ /* enterprise (oid) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_OID) {
+ fputs("[enterprise!=OID]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ if (asn1_print(&elem) < 0)
+ return;
+ length -= count;
+ np += count;
+
+ putchar(' ');
+
+ /* agent-addr (inetaddr) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_INETADDR) {
+ fputs("[agent-addr!=INETADDR]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ if (asn1_print(&elem) < 0)
+ return;
+ length -= count;
+ np += count;
+
+ /* generic-trap (Integer) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_INT) {
+ fputs("[generic-trap!=INT]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ generic = elem.data.integer;
+ {
+ char buf[20];
+ printf(" %s", DECODE_GenericTrap(generic));
+ }
+ length -= count;
+ np += count;
+
+ /* specific-trap (Integer) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_INT) {
+ fputs("[specific-trap!=INT]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ if (generic != GT_ENTERPRISE) {
+ if (elem.data.integer != 0)
+ printf("[specific-trap(%d)!=0]", elem.data.integer);
+ } else
+ printf(" s=%d", elem.data.integer);
+ length -= count;
+ np += count;
+
+ putchar(' ');
+
+ /* time-stamp (TimeTicks) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_UNS) { /* XXX */
+ fputs("[time-stamp!=TIMETICKS]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ if (asn1_print(&elem) < 0)
+ return;
+ length -= count;
+ np += count;
+
+ varbind_print (TRAP, np, length);
+ return;
+}
+
+/*
+ * Decode arbitrary SNMP PDUs.
+ */
+static void
+pdu_print(const u_char *np, u_int length, int version)
+{
+ struct be pdu;
+ int count = 0;
+
+ /* PDU (Context) */
+ if ((count = asn1_parse(np, length, &pdu)) < 0)
+ return;
+ if (pdu.type != BE_PDU) {
+ fputs("[no PDU]", stdout);
+ return;
+ }
+ if ((u_int)count < length)
+ printf("[%d extra after PDU]", length - count);
+ if (vflag) {
+ fputs("{ ", stdout);
+ }
+ if (asn1_print(&pdu) < 0)
+ return;
+ fputs(" ", stdout);
+ /* descend into PDU */
+ length = pdu.asnlen;
+ np = (u_char *)pdu.data.raw;
+
+ if (version == SNMP_VERSION_1 &&
+ (pdu.id == GETBULKREQ || pdu.id == INFORMREQ ||
+ pdu.id == V2TRAP || pdu.id == REPORT)) {
+ printf("[v2 PDU in v1 message]");
+ return;
+ }
+
+ if (version == SNMP_VERSION_2 && pdu.id == TRAP) {
+ printf("[v1 PDU in v2 message]");
+ return;
+ }
+
+ switch (pdu.id) {
+ case TRAP:
+ trappdu_print(np, length);
+ break;
+ case GETREQ:
+ case GETNEXTREQ:
+ case GETRESP:
+ case SETREQ:
+ case GETBULKREQ:
+ case INFORMREQ:
+ case V2TRAP:
+ case REPORT:
+ snmppdu_print(pdu.id, np, length);
+ break;
+ }
+
+ if (vflag) {
+ fputs(" } ", stdout);
+ }
+}
+
+/*
+ * Decode a scoped SNMP PDU.
+ */
+static void
+scopedpdu_print(const u_char *np, u_int length, int version)
+{
+ struct be elem;
+ int i, count = 0;
+
+ /* Sequence */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_SEQ) {
+ fputs("[!scoped PDU]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ length = elem.asnlen;
+ np = (u_char *)elem.data.raw;
+
+ /* contextEngineID (OCTET STRING) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_STR) {
+ fputs("[contextEngineID!=STR]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ length -= count;
+ np += count;
+
+ fputs("E= ", stdout);
+ for (i = 0; i < (int)elem.asnlen; i++) {
+ printf("0x%02X", elem.data.str[i]);
+ }
+ fputs(" ", stdout);
+
+ /* contextName (OCTET STRING) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_STR) {
+ fputs("[contextName!=STR]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ length -= count;
+ np += count;
+
+ printf("C=%.*s ", (int)elem.asnlen, elem.data.str);
+
+ pdu_print(np, length, version);
+}
+
+/*
+ * Decode SNMP Community Header (SNMPv1 and SNMPv2c)
+ */
+static void
+community_print(const u_char *np, u_int length, int version)
+{
+ struct be elem;
+ int count = 0;
+
+ /* Community (String) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_STR) {
+ fputs("[comm!=STR]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ /* default community */
+ if (!(elem.asnlen == sizeof(DEF_COMMUNITY) - 1 &&
+ strncmp((char *)elem.data.str, DEF_COMMUNITY,
+ sizeof(DEF_COMMUNITY) - 1) == 0))
+ /* ! "public" */
+ printf("C=%.*s ", (int)elem.asnlen, elem.data.str);
+ length -= count;
+ np += count;
+
+ pdu_print(np, length, version);
+}
+
+/*
+ * Decode SNMPv3 User-based Security Message Header (SNMPv3)
+ */
+static void
+usm_print(const u_char *np, u_int length)
+{
+ struct be elem;
+ int count = 0;
+
+ /* Sequence */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_SEQ) {
+ fputs("[!usm]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ length = elem.asnlen;
+ np = (u_char *)elem.data.raw;
+
+ /* msgAuthoritativeEngineID (OCTET STRING) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_STR) {
+ fputs("[msgAuthoritativeEngineID!=STR]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ length -= count;
+ np += count;
+
+ /* msgAuthoritativeEngineBoots (INTEGER) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_INT) {
+ fputs("[msgAuthoritativeEngineBoots!=INT]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ if (vflag)
+ printf("B=%d ", elem.data.integer);
+ length -= count;
+ np += count;
+
+ /* msgAuthoritativeEngineTime (INTEGER) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_INT) {
+ fputs("[msgAuthoritativeEngineTime!=INT]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ if (vflag)
+ printf("T=%d ", elem.data.integer);
+ length -= count;
+ np += count;
+
+ /* msgUserName (OCTET STRING) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_STR) {
+ fputs("[msgUserName!=STR]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ length -= count;
+ np += count;
+
+ printf("U=%.*s ", (int)elem.asnlen, elem.data.str);
+
+ /* msgAuthenticationParameters (OCTET STRING) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_STR) {
+ fputs("[msgAuthenticationParameters!=STR]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ length -= count;
+ np += count;
+
+ /* msgPrivacyParameters (OCTET STRING) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_STR) {
+ fputs("[msgPrivacyParameters!=STR]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ length -= count;
+ np += count;
+
+ if ((u_int)count < length)
+ printf("[%d extra after usm SEQ]", length - count);
+}
+
+/*
+ * Decode SNMPv3 Message Header (SNMPv3)
+ */
+static void
+v3msg_print(const u_char *np, u_int length)
+{
+ struct be elem;
+ int count = 0;
+ u_char flags;
+ int model;
+ const u_char *xnp = np;
+ int xlength = length;
+
+ /* Sequence */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_SEQ) {
+ fputs("[!message]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ length = elem.asnlen;
+ np = (u_char *)elem.data.raw;
+
+ if (vflag) {
+ fputs("{ ", stdout);
+ }
+
+ /* msgID (INTEGER) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_INT) {
+ fputs("[msgID!=INT]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ length -= count;
+ np += count;
+
+ /* msgMaxSize (INTEGER) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_INT) {
+ fputs("[msgMaxSize!=INT]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ length -= count;
+ np += count;
+
+ /* msgFlags (OCTET STRING) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_STR) {
+ fputs("[msgFlags!=STR]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ if (elem.asnlen != 1) {
+ printf("[msgFlags size %d]", elem.asnlen);
+ return;
+ }
+ flags = elem.data.str[0];
+ if (flags != 0x00 && flags != 0x01 && flags != 0x03
+ && flags != 0x04 && flags != 0x05 && flags != 0x07) {
+ printf("[msgFlags=0x%02X]", flags);
+ return;
+ }
+ length -= count;
+ np += count;
+
+ fputs("F=", stdout);
+ if (flags & 0x01) fputs("a", stdout);
+ if (flags & 0x02) fputs("p", stdout);
+ if (flags & 0x04) fputs("r", stdout);
+ fputs(" ", stdout);
+
+ /* msgSecurityModel (INTEGER) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_INT) {
+ fputs("[msgSecurityModel!=INT]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ model = elem.data.integer;
+ length -= count;
+ np += count;
+
+ if ((u_int)count < length)
+ printf("[%d extra after message SEQ]", length - count);
+
+ if (vflag) {
+ fputs("} ", stdout);
+ }
+
+ if (model == 3) {
+ if (vflag) {
+ fputs("{ USM ", stdout);
+ }
+ } else {
+ printf("[security model %d]", model);
+ return;
+ }
+
+ np = xnp + (np - xnp);
+ length = xlength - (np - xnp);
+
+ /* msgSecurityParameters (OCTET STRING) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_STR) {
+ fputs("[msgSecurityParameters!=STR]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ length -= count;
+ np += count;
+
+ if (model == 3) {
+ usm_print(elem.data.str, elem.asnlen);
+ if (vflag) {
+ fputs("} ", stdout);
+ }
+ }
+
+ if (vflag) {
+ fputs("{ ScopedPDU ", stdout);
+ }
+
+ scopedpdu_print(np, length, 3);
+
+ if (vflag) {
+ fputs("} ", stdout);
+ }
+}
+
+/*
+ * Decode SNMP header and pass on to PDU printing routines
+ */
+void
+snmp_print(const u_char *np, u_int length)
+{
+ struct be elem;
+ int count = 0;
+ int version = 0;
+
+ putchar(' ');
+
+ /* initial Sequence */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_SEQ) {
+ fputs("[!init SEQ]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+ if ((u_int)count < length)
+ printf("[%d extra after iSEQ]", length - count);
+ /* descend */
+ length = elem.asnlen;
+ np = (u_char *)elem.data.raw;
+
+ /* Version (INTEGER) */
+ if ((count = asn1_parse(np, length, &elem)) < 0)
+ return;
+ if (elem.type != BE_INT) {
+ fputs("[version!=INT]", stdout);
+ asn1_print(&elem);
+ return;
+ }
+
+ switch (elem.data.integer) {
+ case SNMP_VERSION_1:
+ case SNMP_VERSION_2:
+ case SNMP_VERSION_3:
+ if (vflag)
+ printf("{ %s ", SnmpVersion[elem.data.integer]);
+ break;
+ default:
+ printf("[version = %d]", elem.data.integer);
+ return;
+ }
+ version = elem.data.integer;
+ length -= count;
+ np += count;
+
+ switch (version) {
+ case SNMP_VERSION_1:
+ case SNMP_VERSION_2:
+ community_print(np, length, version);
+ break;
+ case SNMP_VERSION_3:
+ v3msg_print(np, length);
+ break;
+ default:
+ printf("[version = %d]", elem.data.integer);
+ break;
+ }
+
+ if (vflag) {
+ fputs("} ", stdout);
+ }
+}
diff --git a/freebsd/contrib/tcpdump/print-stp.c b/freebsd/contrib/tcpdump/print-stp.c
new file mode 100644
index 00000000..6cd9432e
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-stp.c
@@ -0,0 +1,460 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 2000 Lennert Buytenhek
+ *
+ * This software may be distributed either under the terms of the
+ * BSD-style license that accompanies tcpdump or the GNU General
+ * Public License
+ *
+ * Format and print IEEE 802.1d spanning tree protocol packets.
+ * Contributed by Lennert Buytenhek <buytenh@gnu.org>
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+"@(#) $Header: /tcpdump/master/tcpdump/print-stp.c,v 1.20 2007-03-18 17:11:46 hannes Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+#define RSTP_EXTRACT_PORT_ROLE(x) (((x)&0x0C)>>2)
+/* STP timers are expressed in multiples of 1/256th second */
+#define STP_TIME_BASE 256
+#define STP_BPDU_MSTP_MIN_LEN 102
+
+struct stp_bpdu_ {
+ u_int8_t protocol_id[2];
+ u_int8_t protocol_version;
+ u_int8_t bpdu_type;
+ u_int8_t flags;
+ u_int8_t root_id[8];
+ u_int8_t root_path_cost[4];
+ u_int8_t bridge_id[8];
+ u_int8_t port_id[2];
+ u_int8_t message_age[2];
+ u_int8_t max_age[2];
+ u_int8_t hello_time[2];
+ u_int8_t forward_delay[2];
+ u_int8_t v1_length;
+};
+
+#define STP_PROTO_REGULAR 0x00
+#define STP_PROTO_RAPID 0x02
+#define STP_PROTO_MSTP 0x03
+#define STP_PROTO_SPB 0x04
+
+struct tok stp_proto_values[] = {
+ { STP_PROTO_REGULAR, "802.1d" },
+ { STP_PROTO_RAPID, "802.1w" },
+ { STP_PROTO_MSTP, "802.1s" },
+ { STP_PROTO_SPB, "802.1aq" },
+ { 0, NULL}
+};
+
+#define STP_BPDU_TYPE_CONFIG 0x00
+#define STP_BPDU_TYPE_RSTP 0x02
+#define STP_BPDU_TYPE_TOPO_CHANGE 0x80
+
+struct tok stp_bpdu_flag_values[] = {
+ { 0x01, "Topology change" },
+ { 0x02, "Proposal" },
+ { 0x10, "Learn" },
+ { 0x20, "Forward" },
+ { 0x40, "Agreement" },
+ { 0x80, "Topology change ACK" },
+ { 0, NULL}
+};
+
+struct tok stp_bpdu_type_values[] = {
+ { STP_BPDU_TYPE_CONFIG, "Config" },
+ { STP_BPDU_TYPE_RSTP, "Rapid STP" },
+ { STP_BPDU_TYPE_TOPO_CHANGE, "Topology Change" },
+ { 0, NULL}
+};
+
+struct tok rstp_obj_port_role_values[] = {
+ { 0x00, "Unknown" },
+ { 0x01, "Alternate" },
+ { 0x02, "Root" },
+ { 0x03, "Designated" },
+ { 0, NULL}
+};
+
+static char *
+stp_print_bridge_id(const u_char *p)
+{
+ static char bridge_id_str[sizeof("pppp.aa:bb:cc:dd:ee:ff")];
+
+ snprintf(bridge_id_str, sizeof(bridge_id_str),
+ "%.2x%.2x.%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
+ p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
+
+ return bridge_id_str;
+}
+
+static void
+stp_print_config_bpdu(const struct stp_bpdu_ *stp_bpdu, u_int length)
+{
+ printf(", Flags [%s]",
+ bittok2str(stp_bpdu_flag_values, "none", stp_bpdu->flags));
+
+ printf(", bridge-id %s.%04x, length %u",
+ stp_print_bridge_id((const u_char *)&stp_bpdu->bridge_id),
+ EXTRACT_16BITS(&stp_bpdu->port_id), length);
+
+ /* in non-verbose mode just print the bridge-id */
+ if (!vflag) {
+ return;
+ }
+
+ printf("\n\tmessage-age %.2fs, max-age %.2fs"
+ ", hello-time %.2fs, forwarding-delay %.2fs",
+ (float)EXTRACT_16BITS(&stp_bpdu->message_age) / STP_TIME_BASE,
+ (float)EXTRACT_16BITS(&stp_bpdu->max_age) / STP_TIME_BASE,
+ (float)EXTRACT_16BITS(&stp_bpdu->hello_time) / STP_TIME_BASE,
+ (float)EXTRACT_16BITS(&stp_bpdu->forward_delay) / STP_TIME_BASE);
+
+ printf("\n\troot-id %s, root-pathcost %u",
+ stp_print_bridge_id((const u_char *)&stp_bpdu->root_id),
+ EXTRACT_32BITS(&stp_bpdu->root_path_cost));
+
+ /* Port role is only valid for 802.1w */
+ if (stp_bpdu->protocol_version == STP_PROTO_RAPID) {
+ printf(", port-role %s",
+ tok2str(rstp_obj_port_role_values, "Unknown",
+ RSTP_EXTRACT_PORT_ROLE(stp_bpdu->flags)));
+ }
+}
+
+/*
+ * MSTP packet format
+ * Ref. IEEE 802.1Q 2003 Ed. Section 14
+ *
+ * MSTP BPDU
+ *
+ * 2 - bytes Protocol Id
+ * 1 - byte Protocol Ver.
+ * 1 - byte BPDU tye
+ * 1 - byte Flags
+ * 8 - bytes CIST Root Identifier
+ * 4 - bytes CIST External Path Cost
+ * 8 - bytes CIST Regional Root Identifier
+ * 2 - bytes CIST Port Identifier
+ * 2 - bytes Message Age
+ * 2 - bytes Max age
+ * 2 - bytes Hello Time
+ * 2 - bytes Forward delay
+ * 1 - byte Version 1 length. Must be 0
+ * 2 - bytes Version 3 length
+ * 1 - byte Config Identifier
+ * 32 - bytes Config Name
+ * 2 - bytes Revision level
+ * 16 - bytes Config Digest [MD5]
+ * 4 - bytes CIST Internal Root Path Cost
+ * 8 - bytes CIST Bridge Identifier
+ * 1 - byte CIST Remaining Hops
+ * 16 - bytes MSTI information [Max 64 MSTI, each 16 bytes]
+ *
+ *
+ * SPB BPDU
+ * Ref. IEEE 802.1aq. Section 14
+ *
+ * 2 - bytes Version 4 length
+ * 1 - byte Aux Config Identifier
+ * 32 - bytes Aux Config Name
+ * 2 - bytes Aux Revision level
+ * 16 - bytes Aux Config Digest [MD5]
+ * 1 - byte (1 - 2) Agreement Number
+ * (3 - 4) Discarded Agreement Number
+ * (5) Agreement Valid Flag
+ * (6) Restricted Role Flag
+ * (7 - 8) Unused sent zero
+ * 1 - byte Unused
+ * 1 - byte (1 - 4) Agreement Digest Format Identifier
+ * (5 - 8) Agreement Digest Format Capabilities
+ * 1 - byte (1 - 4) Agreement Digest Convention Identifier
+ * (5 - 8) Agreement Digest Convention Capabilities
+ * 2 - bytes Agreement Digest Edge Count
+ * 8 - byte Reserved Set
+ * 20 - bytes Computed Topology Digest
+ *
+ *
+ * MSTI Payload
+ *
+ * 1 - byte MSTI flag
+ * 8 - bytes MSTI Regional Root Identifier
+ * 4 - bytes MSTI Regional Path Cost
+ * 1 - byte MSTI Bridge Priority
+ * 1 - byte MSTI Port Priority
+ * 1 - byte MSTI Remaining Hops
+ *
+ */
+
+#define MST_BPDU_MSTI_LENGTH 16
+#define MST_BPDU_CONFIG_INFO_LENGTH 64
+
+/* Offsets of fields from the begginning for the packet */
+#define MST_BPDU_VER3_LEN_OFFSET 36
+#define MST_BPDU_CONFIG_NAME_OFFSET 39
+#define MST_BPDU_CONFIG_DIGEST_OFFSET 73
+#define MST_BPDU_CIST_INT_PATH_COST_OFFSET 89
+#define MST_BPDU_CIST_BRIDGE_ID_OFFSET 93
+#define MST_BPDU_CIST_REMAIN_HOPS_OFFSET 101
+#define MST_BPDU_MSTI_OFFSET 102
+/* Offsets within an MSTI */
+#define MST_BPDU_MSTI_ROOT_PRIO_OFFSET 1
+#define MST_BPDU_MSTI_ROOT_PATH_COST_OFFSET 9
+#define MST_BPDU_MSTI_BRIDGE_PRIO_OFFSET 13
+#define MST_BPDU_MSTI_PORT_PRIO_OFFSET 14
+#define MST_BPDU_MSTI_REMAIN_HOPS_OFFSET 15
+
+#define SPB_BPDU_MIN_LEN 87
+#define SPB_BPDU_CONFIG_NAME_OFFSET 3
+#define SPB_BPDU_CONFIG_REV_OFFSET SPB_BPDU_CONFIG_NAME_OFFSET + 32
+#define SPB_BPDU_CONFIG_DIGEST_OFFSET SPB_BPDU_CONFIG_REV_OFFSET + 2
+#define SPB_BPDU_AGREEMENT_OFFSET SPB_BPDU_CONFIG_DIGEST_OFFSET + 16
+#define SPB_BPDU_AGREEMENT_UNUSED_OFFSET SPB_BPDU_AGREEMENT_OFFSET + 1
+#define SPB_BPDU_AGREEMENT_FORMAT_OFFSET SPB_BPDU_AGREEMENT_UNUSED_OFFSET + 1
+#define SPB_BPDU_AGREEMENT_CON_OFFSET SPB_BPDU_AGREEMENT_FORMAT_OFFSET + 1
+#define SPB_BPDU_AGREEMENT_EDGE_OFFSET SPB_BPDU_AGREEMENT_CON_OFFSET + 1
+#define SPB_BPDU_AGREEMENT_RES1_OFFSET SPB_BPDU_AGREEMENT_EDGE_OFFSET + 2
+#define SPB_BPDU_AGREEMENT_RES2_OFFSET SPB_BPDU_AGREEMENT_RES1_OFFSET + 4
+#define SPB_BPDU_AGREEMENT_DIGEST_OFFSET SPB_BPDU_AGREEMENT_RES2_OFFSET + 4
+
+
+static void
+stp_print_mstp_bpdu(const struct stp_bpdu_ *stp_bpdu, u_int length)
+{
+ const u_char *ptr;
+ u_int16_t v3len;
+ u_int16_t len;
+ u_int16_t msti;
+ u_int16_t offset;
+
+ ptr = (const u_char *)stp_bpdu;
+ printf(", CIST Flags [%s], length %u",
+ bittok2str(stp_bpdu_flag_values, "none", stp_bpdu->flags), length);
+
+ /*
+ * in non-verbose mode just print the flags. We dont read that much
+ * of the packet (DEFAULT_SNAPLEN) to print out cist bridge-id
+ */
+ if (!vflag) {
+ return;
+ }
+
+ printf("\n\tport-role %s, ",
+ tok2str(rstp_obj_port_role_values, "Unknown",
+ RSTP_EXTRACT_PORT_ROLE(stp_bpdu->flags)));
+
+ printf("CIST root-id %s, CIST ext-pathcost %u ",
+ stp_print_bridge_id((const u_char *)&stp_bpdu->root_id),
+ EXTRACT_32BITS(&stp_bpdu->root_path_cost));
+
+ printf("\n\tCIST regional-root-id %s, ",
+ stp_print_bridge_id((const u_char *)&stp_bpdu->bridge_id));
+
+ printf("CIST port-id %04x, ", EXTRACT_16BITS(&stp_bpdu->port_id));
+
+ printf("\n\tmessage-age %.2fs, max-age %.2fs"
+ ", hello-time %.2fs, forwarding-delay %.2fs",
+ (float)EXTRACT_16BITS(&stp_bpdu->message_age) / STP_TIME_BASE,
+ (float)EXTRACT_16BITS(&stp_bpdu->max_age) / STP_TIME_BASE,
+ (float)EXTRACT_16BITS(&stp_bpdu->hello_time) / STP_TIME_BASE,
+ (float)EXTRACT_16BITS(&stp_bpdu->forward_delay) / STP_TIME_BASE);
+
+ printf ("\n\tv3len %d, ", EXTRACT_16BITS(ptr + MST_BPDU_VER3_LEN_OFFSET));
+ printf("MCID Name %s, rev %u, "
+ "\n\t\tdigest %08x%08x%08x%08x, ",
+ ptr + MST_BPDU_CONFIG_NAME_OFFSET,
+ EXTRACT_16BITS(ptr + MST_BPDU_CONFIG_NAME_OFFSET + 32),
+ EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET),
+ EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 4),
+ EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 8),
+ EXTRACT_32BITS(ptr + MST_BPDU_CONFIG_DIGEST_OFFSET + 12));
+
+ printf ("CIST int-root-pathcost %u, ",
+ EXTRACT_32BITS(ptr + MST_BPDU_CIST_INT_PATH_COST_OFFSET));
+
+ printf("\n\tCIST bridge-id %s, ",
+ stp_print_bridge_id(ptr + MST_BPDU_CIST_BRIDGE_ID_OFFSET));
+
+ printf("CIST remaining-hops %d", ptr[MST_BPDU_CIST_REMAIN_HOPS_OFFSET]);
+
+ /* Dump all MSTI's */
+ v3len = EXTRACT_16BITS(ptr + MST_BPDU_VER3_LEN_OFFSET);
+ if (v3len > MST_BPDU_CONFIG_INFO_LENGTH) {
+ len = v3len - MST_BPDU_CONFIG_INFO_LENGTH;
+ offset = MST_BPDU_MSTI_OFFSET;
+ while (len >= MST_BPDU_MSTI_LENGTH) {
+ msti = EXTRACT_16BITS(ptr + offset +
+ MST_BPDU_MSTI_ROOT_PRIO_OFFSET);
+ msti = msti & 0x0FFF;
+
+ printf("\n\tMSTI %d, Flags [%s], port-role %s",
+ msti, bittok2str(stp_bpdu_flag_values, "none", ptr[offset]),
+ tok2str(rstp_obj_port_role_values, "Unknown",
+ RSTP_EXTRACT_PORT_ROLE(ptr[offset])));
+ printf("\n\t\tMSTI regional-root-id %s, pathcost %u",
+ stp_print_bridge_id(ptr + offset +
+ MST_BPDU_MSTI_ROOT_PRIO_OFFSET),
+ EXTRACT_32BITS(ptr + offset +
+ MST_BPDU_MSTI_ROOT_PATH_COST_OFFSET));
+ printf("\n\t\tMSTI bridge-prio %d, port-prio %d, hops %d",
+ ptr[offset + MST_BPDU_MSTI_BRIDGE_PRIO_OFFSET] >> 4,
+ ptr[offset + MST_BPDU_MSTI_PORT_PRIO_OFFSET] >> 4,
+ ptr[offset + MST_BPDU_MSTI_REMAIN_HOPS_OFFSET]);
+
+ len -= MST_BPDU_MSTI_LENGTH;
+ offset += MST_BPDU_MSTI_LENGTH;
+ }
+ }
+
+ if ((length-offset) >= SPB_BPDU_MIN_LEN)
+ {
+ printf("\n\tv4len %d AUXMCID Name %s, Rev %u, \n\t\tdigest %08x%08x%08x%08x",
+ EXTRACT_16BITS (ptr + offset),
+ ptr + offset + SPB_BPDU_CONFIG_NAME_OFFSET,
+ EXTRACT_16BITS(ptr + offset + SPB_BPDU_CONFIG_REV_OFFSET),
+ EXTRACT_32BITS(ptr + offset + SPB_BPDU_CONFIG_DIGEST_OFFSET),
+ EXTRACT_32BITS(ptr + offset + SPB_BPDU_CONFIG_DIGEST_OFFSET + 4),
+ EXTRACT_32BITS(ptr + offset + SPB_BPDU_CONFIG_DIGEST_OFFSET + 8),
+ EXTRACT_32BITS(ptr + offset + SPB_BPDU_CONFIG_DIGEST_OFFSET + 12));
+
+ printf("\n\tAgreement num %d, Discarded Agreement num %d, Agreement valid-"
+ "flag %d, \n\tRestricted role-flag: %d, Format id %d cap %d, "
+ "Convention id %d cap %d, \n\tEdge count %d, "
+ "Agreement digest %08x%08x%08x%08x%08x\n",
+ ptr[offset + SPB_BPDU_AGREEMENT_OFFSET]>>6,
+ ptr[offset + SPB_BPDU_AGREEMENT_OFFSET]>>4 & 0x3,
+ ptr[offset + SPB_BPDU_AGREEMENT_OFFSET]>>3 & 0x1,
+ ptr[offset + SPB_BPDU_AGREEMENT_OFFSET]>>2 & 0x1,
+ ptr[offset + SPB_BPDU_AGREEMENT_FORMAT_OFFSET]>>4,
+ ptr[offset + SPB_BPDU_AGREEMENT_FORMAT_OFFSET]&0x00ff,
+ ptr[offset + SPB_BPDU_AGREEMENT_CON_OFFSET]>>4,
+ ptr[offset + SPB_BPDU_AGREEMENT_CON_OFFSET]&0x00ff,
+ EXTRACT_16BITS(ptr + offset + SPB_BPDU_AGREEMENT_EDGE_OFFSET),
+ EXTRACT_32BITS(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET),
+ EXTRACT_32BITS(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET)+4,
+ EXTRACT_32BITS(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET)+8,
+ EXTRACT_32BITS(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET)+12,
+ EXTRACT_32BITS(ptr + offset + SPB_BPDU_AGREEMENT_DIGEST_OFFSET)+16);
+ }
+}
+
+/*
+ * Print 802.1d / 802.1w / 802.1q (mstp) / 802.1aq (spb) packets.
+ */
+void
+stp_print(const u_char *p, u_int length)
+{
+ const struct stp_bpdu_ *stp_bpdu;
+ u_int16_t mstp_len;
+ u_int16_t spb_len;
+
+ stp_bpdu = (struct stp_bpdu_*)p;
+
+ /* Minimum STP Frame size. */
+ if (length < 4)
+ goto trunc;
+
+ if (EXTRACT_16BITS(&stp_bpdu->protocol_id)) {
+ printf("unknown STP version, length %u", length);
+ return;
+ }
+
+ printf("STP %s", tok2str(stp_proto_values, "Unknown STP protocol (0x%02x)",
+ stp_bpdu->protocol_version));
+
+ switch (stp_bpdu->protocol_version) {
+ case STP_PROTO_REGULAR:
+ case STP_PROTO_RAPID:
+ case STP_PROTO_MSTP:
+ case STP_PROTO_SPB:
+ break;
+ default:
+ return;
+ }
+
+ printf(", %s", tok2str(stp_bpdu_type_values, "Unknown BPDU Type (0x%02x)",
+ stp_bpdu->bpdu_type));
+
+ switch (stp_bpdu->bpdu_type) {
+ case STP_BPDU_TYPE_CONFIG:
+ if (length < sizeof(struct stp_bpdu_) - 1) {
+ goto trunc;
+ }
+ stp_print_config_bpdu(stp_bpdu, length);
+ break;
+
+ case STP_BPDU_TYPE_RSTP:
+ if (stp_bpdu->protocol_version == STP_PROTO_RAPID) {
+ if (length < sizeof(struct stp_bpdu_)) {
+ goto trunc;
+ }
+ stp_print_config_bpdu(stp_bpdu, length);
+ } else if (stp_bpdu->protocol_version == STP_PROTO_MSTP ||
+ stp_bpdu->protocol_version == STP_PROTO_SPB) {
+ if (length < STP_BPDU_MSTP_MIN_LEN) {
+ goto trunc;
+ }
+
+ if (stp_bpdu->v1_length != 0) {
+ /* FIX ME: Emit a message here ? */
+ goto trunc;
+ }
+
+ /* Validate v3 length */
+ mstp_len = EXTRACT_16BITS(p + MST_BPDU_VER3_LEN_OFFSET);
+ mstp_len += 2; /* length encoding itself is 2 bytes */
+ if (length < (sizeof(struct stp_bpdu_) + mstp_len)) {
+ goto trunc;
+ }
+
+ if (stp_bpdu->protocol_version == STP_PROTO_SPB)
+ {
+ /* Validate v4 length */
+ spb_len = EXTRACT_16BITS (p + MST_BPDU_VER3_LEN_OFFSET + mstp_len);
+ spb_len += 2;
+ if (length < (sizeof(struct stp_bpdu_) + mstp_len + spb_len) ||
+ spb_len < SPB_BPDU_MIN_LEN) {
+ goto trunc;
+ }
+ }
+
+ stp_print_mstp_bpdu(stp_bpdu, length);
+ }
+ break;
+
+ case STP_BPDU_TYPE_TOPO_CHANGE:
+ /* always empty message - just break out */
+ break;
+
+ default:
+ break;
+ }
+
+ return;
+ trunc:
+ printf("[|stp %d]", length);
+}
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-sunatm.c b/freebsd/contrib/tcpdump/print-sunatm.c
new file mode 100644
index 00000000..2cd223da
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-sunatm.c
@@ -0,0 +1,119 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1997 Yen Yen Lim and North Dakota State University
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Yen Yen Lim and
+ North Dakota State University
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-sunatm.c,v 1.8 2004-03-17 23:24:38 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+struct mbuf;
+struct rtentry;
+
+#include <stdio.h>
+#include <pcap.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+
+#include "atm.h"
+#include "atmuni31.h"
+
+/* SunATM header for ATM packet */
+#define DIR_POS 0 /* Direction (0x80 = transmit, 0x00 = receive) */
+#define VPI_POS 1 /* VPI */
+#define VCI_POS 2 /* VCI */
+#define PKT_BEGIN_POS 4 /* Start of the ATM packet */
+
+/* Protocol type values in the bottom for bits of the byte at SUNATM_DIR_POS. */
+#define PT_LANE 0x01 /* LANE */
+#define PT_LLC 0x02 /* LLC encapsulation */
+
+/*
+ * This is the top level routine of the printer. 'p' points
+ * to the SunATM pseudo-header for the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ */
+u_int
+sunatm_if_print(const struct pcap_pkthdr *h, const u_char *p)
+{
+ u_int caplen = h->caplen;
+ u_int length = h->len;
+ u_short vci;
+ u_char vpi;
+ u_int traftype;
+
+ if (caplen < PKT_BEGIN_POS) {
+ printf("[|atm]");
+ return (caplen);
+ }
+
+ if (eflag) {
+ if (p[DIR_POS] & 0x80)
+ printf("Tx: ");
+ else
+ printf("Rx: ");
+ }
+
+ switch (p[DIR_POS] & 0x0f) {
+
+ case PT_LANE:
+ traftype = ATM_LANE;
+ break;
+
+ case PT_LLC:
+ traftype = ATM_LLC;
+ break;
+
+ default:
+ traftype = ATM_UNKNOWN;
+ break;
+ }
+
+ vci = EXTRACT_16BITS(&p[VCI_POS]);
+ vpi = p[VPI_POS];
+
+ p += PKT_BEGIN_POS;
+ caplen -= PKT_BEGIN_POS;
+ length -= PKT_BEGIN_POS;
+ atm_print(vpi, vci, traftype, p, length, caplen);
+
+ return (PKT_BEGIN_POS);
+}
diff --git a/freebsd/contrib/tcpdump/print-sunrpc.c b/freebsd/contrib/tcpdump/print-sunrpc.c
new file mode 100644
index 00000000..07eddff2
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-sunrpc.c
@@ -0,0 +1,176 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1992, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-sunrpc.c,v 1.47 2005-04-27 21:43:48 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+/*
+ * At least on HP-UX:
+ *
+ * 1) getrpcbynumber() is declared in <netdb.h>, not any of the RPC
+ * header files
+ *
+ * and
+ *
+ * 2) if _XOPEN_SOURCE_EXTENDED is defined, <netdb.h> doesn't declare
+ * it
+ *
+ * so we undefine it.
+ */
+#undef _XOPEN_SOURCE_EXTENDED
+
+#include <tcpdump-stdinc.h>
+
+#if defined(HAVE_GETRPCBYNUMBER) && defined(HAVE_RPC_RPC_H)
+#include <rpc/rpc.h>
+#ifdef HAVE_RPC_RPCENT_H
+#include <rpc/rpcent.h>
+#endif /* HAVE_RPC_RPCENT_H */
+#endif /* defined(HAVE_GETRPCBYNUMBER) && defined(HAVE_RPC_RPC_H) */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+#include "ip.h"
+#ifdef INET6
+#include "ip6.h"
+#endif
+
+#include "rpc_auth.h"
+#include "rpc_msg.h"
+#include "pmap_prot.h"
+
+static struct tok proc2str[] = {
+ { SUNRPC_PMAPPROC_NULL, "null" },
+ { SUNRPC_PMAPPROC_SET, "set" },
+ { SUNRPC_PMAPPROC_UNSET, "unset" },
+ { SUNRPC_PMAPPROC_GETPORT, "getport" },
+ { SUNRPC_PMAPPROC_DUMP, "dump" },
+ { SUNRPC_PMAPPROC_CALLIT, "call" },
+ { 0, NULL }
+};
+
+/* Forwards */
+static char *progstr(u_int32_t);
+
+void
+sunrpcrequest_print(register const u_char *bp, register u_int length,
+ register const u_char *bp2)
+{
+ register const struct sunrpc_msg *rp;
+ register const struct ip *ip;
+#ifdef INET6
+ register const struct ip6_hdr *ip6;
+#endif
+ u_int32_t x;
+ char srcid[20], dstid[20]; /*fits 32bit*/
+
+ rp = (struct sunrpc_msg *)bp;
+
+ if (!nflag) {
+ snprintf(srcid, sizeof(srcid), "0x%x",
+ EXTRACT_32BITS(&rp->rm_xid));
+ strlcpy(dstid, "sunrpc", sizeof(dstid));
+ } else {
+ snprintf(srcid, sizeof(srcid), "0x%x",
+ EXTRACT_32BITS(&rp->rm_xid));
+ snprintf(dstid, sizeof(dstid), "0x%x", SUNRPC_PMAPPORT);
+ }
+
+ switch (IP_V((struct ip *)bp2)) {
+ case 4:
+ ip = (struct ip *)bp2;
+ printf("%s.%s > %s.%s: %d",
+ ipaddr_string(&ip->ip_src), srcid,
+ ipaddr_string(&ip->ip_dst), dstid, length);
+ break;
+#ifdef INET6
+ case 6:
+ ip6 = (struct ip6_hdr *)bp2;
+ printf("%s.%s > %s.%s: %d",
+ ip6addr_string(&ip6->ip6_src), srcid,
+ ip6addr_string(&ip6->ip6_dst), dstid, length);
+ break;
+#endif
+ default:
+ printf("%s.%s > %s.%s: %d", "?", srcid, "?", dstid, length);
+ break;
+ }
+
+ printf(" %s", tok2str(proc2str, " proc #%u",
+ EXTRACT_32BITS(&rp->rm_call.cb_proc)));
+ x = EXTRACT_32BITS(&rp->rm_call.cb_rpcvers);
+ if (x != 2)
+ printf(" [rpcver %u]", x);
+
+ switch (EXTRACT_32BITS(&rp->rm_call.cb_proc)) {
+
+ case SUNRPC_PMAPPROC_SET:
+ case SUNRPC_PMAPPROC_UNSET:
+ case SUNRPC_PMAPPROC_GETPORT:
+ case SUNRPC_PMAPPROC_CALLIT:
+ x = EXTRACT_32BITS(&rp->rm_call.cb_prog);
+ if (!nflag)
+ printf(" %s", progstr(x));
+ else
+ printf(" %u", x);
+ printf(".%u", EXTRACT_32BITS(&rp->rm_call.cb_vers));
+ break;
+ }
+}
+
+static char *
+progstr(prog)
+ u_int32_t prog;
+{
+#if defined(HAVE_GETRPCBYNUMBER) && defined(HAVE_RPC_RPC_H)
+ register struct rpcent *rp;
+#endif
+ static char buf[32];
+ static u_int32_t lastprog = 0;
+
+ if (lastprog != 0 && prog == lastprog)
+ return (buf);
+#if defined(HAVE_GETRPCBYNUMBER) && defined(HAVE_RPC_RPC_H)
+ rp = getrpcbynumber(prog);
+ if (rp == NULL)
+#endif
+ (void) snprintf(buf, sizeof(buf), "#%u", prog);
+#if defined(HAVE_GETRPCBYNUMBER) && defined(HAVE_RPC_RPC_H)
+ else
+ strlcpy(buf, rp->r_name, sizeof(buf));
+#endif
+ return (buf);
+}
diff --git a/freebsd/contrib/tcpdump/print-symantec.c b/freebsd/contrib/tcpdump/print-symantec.c
new file mode 100644
index 00000000..d42e6faa
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-symantec.c
@@ -0,0 +1,122 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-symantec.c,v 1.5 2005-07-07 01:22:21 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <pcap.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+
+#include "ether.h"
+
+struct symantec_header {
+ u_int8_t stuff1[6];
+ u_int16_t ether_type;
+ u_int8_t stuff2[36];
+};
+
+static inline void
+symantec_hdr_print(register const u_char *bp, u_int length)
+{
+ register const struct symantec_header *sp;
+ u_int16_t etype;
+
+ sp = (const struct symantec_header *)bp;
+
+ etype = EXTRACT_16BITS(&sp->ether_type);
+ if (!qflag) {
+ if (etype <= ETHERMTU)
+ (void)printf("invalid ethertype %u", etype);
+ else
+ (void)printf("ethertype %s (0x%04x)",
+ tok2str(ethertype_values,"Unknown", etype),
+ etype);
+ } else {
+ if (etype <= ETHERMTU)
+ (void)printf("invalid ethertype %u", etype);
+ else
+ (void)printf("%s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", etype));
+ }
+
+ (void)printf(", length %u: ", length);
+}
+
+/*
+ * This is the top level routine of the printer. 'p' points
+ * to the ether header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ */
+u_int
+symantec_if_print(const struct pcap_pkthdr *h, const u_char *p)
+{
+ u_int length = h->len;
+ u_int caplen = h->caplen;
+ struct symantec_header *sp;
+ u_short ether_type;
+
+ if (caplen < sizeof (struct symantec_header)) {
+ printf("[|symantec]");
+ return caplen;
+ }
+
+ if (eflag)
+ symantec_hdr_print(p, length);
+
+ length -= sizeof (struct symantec_header);
+ caplen -= sizeof (struct symantec_header);
+ sp = (struct symantec_header *)p;
+ p += sizeof (struct symantec_header);
+
+ ether_type = EXTRACT_16BITS(&sp->ether_type);
+
+ if (ether_type <= ETHERMTU) {
+ /* ether_type not known, print raw packet */
+ if (!eflag)
+ symantec_hdr_print((u_char *)sp, length + sizeof (struct symantec_header));
+
+ if (!suppress_default_print)
+ default_print(p, caplen);
+ } else if (ethertype_print(gndo, ether_type, p, length, caplen) == 0) {
+ /* ether_type not known, print raw packet */
+ if (!eflag)
+ symantec_hdr_print((u_char *)sp, length + sizeof (struct symantec_header));
+
+ if (!suppress_default_print)
+ default_print(p, caplen);
+ }
+
+ return (sizeof (struct symantec_header));
+}
diff --git a/freebsd/contrib/tcpdump/print-syslog.c b/freebsd/contrib/tcpdump/print-syslog.c
new file mode 100644
index 00000000..8585ee00
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-syslog.c
@@ -0,0 +1,165 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1998-2004 Hannes Gredler <hannes@tcpdump.org>
+ * The TCPDUMP project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-syslog.c,v 1.1 2004-10-29 11:42:53 hannes Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+
+/*
+ * tokenlists and #defines taken from Ethereal - Network traffic analyzer
+ * by Gerald Combs <gerald@ethereal.com>
+ */
+
+#define SYSLOG_SEVERITY_MASK 0x0007 /* 0000 0000 0000 0111 */
+#define SYSLOG_FACILITY_MASK 0x03f8 /* 0000 0011 1111 1000 */
+#define SYSLOG_MAX_DIGITS 3 /* The maximum number if priority digits to read in. */
+
+static const struct tok syslog_severity_values[] = {
+ { 0, "emergency" },
+ { 1, "alert" },
+ { 2, "critical" },
+ { 3, "error" },
+ { 4, "warning" },
+ { 5, "notice" },
+ { 6, "info" },
+ { 7, "debug" },
+ { 0, NULL },
+};
+
+static const struct tok syslog_facility_values[] = {
+ { 0, "kernel" },
+ { 1, "user" },
+ { 2, "mail" },
+ { 3, "daemon" },
+ { 4, "auth" },
+ { 5, "syslog" },
+ { 6, "lpr" },
+ { 7, "news" },
+ { 8, "uucp" },
+ { 9, "cron" },
+ { 10, "authpriv" },
+ { 11, "ftp" },
+ { 12, "ntp" },
+ { 13, "security" },
+ { 14, "console" },
+ { 15, "cron" },
+ { 16, "local0" },
+ { 17, "local1" },
+ { 18, "local2" },
+ { 19, "local3" },
+ { 20, "local4" },
+ { 21, "local5" },
+ { 22, "local6" },
+ { 23, "local7" },
+ { 0, NULL },
+};
+
+void
+syslog_print(register const u_char *pptr, register u_int len)
+{
+ u_int16_t msg_off = 0;
+ u_int16_t pri = 0;
+ u_int16_t facility,severity;
+
+ /* extract decimal figures that are
+ * encapsulated within < > tags
+ * based on this decimal figure extract the
+ * severity and facility values
+ */
+
+ if (!TTEST2(*pptr, 1))
+ goto trunc;
+
+ if (*(pptr+msg_off) == '<') {
+ msg_off++;
+
+ if (!TTEST2(*(pptr+msg_off), 1))
+ goto trunc;
+
+ while ( *(pptr+msg_off) >= '0' &&
+ *(pptr+msg_off) <= '9' &&
+ msg_off <= SYSLOG_MAX_DIGITS) {
+
+ if (!TTEST2(*(pptr+msg_off), 1))
+ goto trunc;
+
+ pri = pri * 10 + (*(pptr+msg_off) - '0');
+ msg_off++;
+
+ if (!TTEST2(*(pptr+msg_off), 1))
+ goto trunc;
+
+ if (*(pptr+msg_off) == '>')
+ msg_off++;
+ }
+ } else {
+ printf("[|syslog]");
+ return;
+ }
+
+ facility = (pri & SYSLOG_FACILITY_MASK) >> 3;
+ severity = pri & SYSLOG_SEVERITY_MASK;
+
+
+ if (vflag < 1 )
+ {
+ printf("SYSLOG %s.%s, length: %u",
+ tok2str(syslog_facility_values, "unknown (%u)", facility),
+ tok2str(syslog_severity_values, "unknown (%u)", severity),
+ len);
+ return;
+ }
+
+ printf("SYSLOG, length: %u\n\tFacility %s (%u), Severity %s (%u)\n\tMsg: ",
+ len,
+ tok2str(syslog_facility_values, "unknown (%u)", facility),
+ facility,
+ tok2str(syslog_severity_values, "unknown (%u)", severity),
+ severity);
+
+ /* print the syslog text in verbose mode */
+ for (; msg_off < len; msg_off++) {
+ if (!TTEST2(*(pptr+msg_off), 1))
+ goto trunc;
+ safeputchar(*(pptr+msg_off));
+ }
+
+ if (vflag > 1) {
+ if(!print_unknown_data(pptr,"\n\t",len))
+ return;
+ }
+
+ return;
+
+trunc:
+ printf("[|syslog]");
+}
diff --git a/freebsd/contrib/tcpdump/print-tcp.c b/freebsd/contrib/tcpdump/print-tcp.c
new file mode 100644
index 00000000..c377bac9
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-tcp.c
@@ -0,0 +1,827 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/* $NetBSD: print-tcp.c,v 1.9 2007/07/26 18:15:12 plunky Exp $ */
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Copyright (c) 1999-2004 The tcpdump.org project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+"@(#) $Header: /tcpdump/master/tcpdump/print-tcp.c,v 1.135 2008-11-09 23:35:03 mcr Exp $ (LBL)";
+#else
+__RCSID("$NetBSD: print-tcp.c,v 1.8 2007/07/24 11:53:48 drochner Exp $");
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+#include "tcp.h"
+
+#include "ip.h"
+#ifdef INET6
+#include "ip6.h"
+#endif
+#include "ipproto.h"
+#include "rpc_auth.h"
+#include "rpc_msg.h"
+
+#include "nameser.h"
+
+#ifdef HAVE_LIBCRYPTO
+#include <openssl/md5.h>
+#include <signature.h>
+
+static int tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp,
+ const u_char *data, int length, const u_char *rcvsig);
+#endif
+
+static void print_tcp_rst_data(register const u_char *sp, u_int length);
+
+#define MAX_RST_DATA_LEN 30
+
+
+struct tha {
+#ifndef INET6
+ struct in_addr src;
+ struct in_addr dst;
+#else
+ struct in6_addr src;
+ struct in6_addr dst;
+#endif /*INET6*/
+ u_int port;
+};
+
+struct tcp_seq_hash {
+ struct tcp_seq_hash *nxt;
+ struct tha addr;
+ tcp_seq seq;
+ tcp_seq ack;
+};
+
+#define TSEQ_HASHSIZE 919
+
+/* These tcp optinos do not have the size octet */
+#define ZEROLENOPT(o) ((o) == TCPOPT_EOL || (o) == TCPOPT_NOP)
+
+static struct tcp_seq_hash tcp_seq_hash[TSEQ_HASHSIZE];
+
+struct tok tcp_flag_values[] = {
+ { TH_FIN, "F" },
+ { TH_SYN, "S" },
+ { TH_RST, "R" },
+ { TH_PUSH, "P" },
+ { TH_ACK, "." },
+ { TH_URG, "U" },
+ { TH_ECNECHO, "E" },
+ { TH_CWR, "W" },
+ { 0, NULL }
+};
+
+struct tok tcp_option_values[] = {
+ { TCPOPT_EOL, "eol" },
+ { TCPOPT_NOP, "nop" },
+ { TCPOPT_MAXSEG, "mss" },
+ { TCPOPT_WSCALE, "wscale" },
+ { TCPOPT_SACKOK, "sackOK" },
+ { TCPOPT_SACK, "sack" },
+ { TCPOPT_ECHO, "echo" },
+ { TCPOPT_ECHOREPLY, "echoreply" },
+ { TCPOPT_TIMESTAMP, "TS" },
+ { TCPOPT_CC, "cc" },
+ { TCPOPT_CCNEW, "ccnew" },
+ { TCPOPT_CCECHO, "" },
+ { TCPOPT_SIGNATURE, "md5" },
+ { TCPOPT_AUTH, "enhanced auth" },
+ { TCPOPT_UTO, "uto" },
+ { 0, NULL }
+};
+
+static int tcp_cksum(register const struct ip *ip,
+ register const struct tcphdr *tp,
+ register u_int len)
+{
+ return (nextproto4_cksum(ip, (const u_int8_t *)tp, len,
+ IPPROTO_TCP));
+}
+
+void
+tcp_print(register const u_char *bp, register u_int length,
+ register const u_char *bp2, int fragmented)
+{
+ register const struct tcphdr *tp;
+ register const struct ip *ip;
+ register u_char flags;
+ register u_int hlen;
+ register char ch;
+ u_int16_t sport, dport, win, urp;
+ u_int32_t seq, ack, thseq, thack;
+ u_int utoval;
+ int threv;
+#ifdef INET6
+ register const struct ip6_hdr *ip6;
+#endif
+
+ tp = (struct tcphdr *)bp;
+ ip = (struct ip *)bp2;
+#ifdef INET6
+ if (IP_V(ip) == 6)
+ ip6 = (struct ip6_hdr *)bp2;
+ else
+ ip6 = NULL;
+#endif /*INET6*/
+ ch = '\0';
+ if (!TTEST(tp->th_dport)) {
+ (void)printf("%s > %s: [|tcp]",
+ ipaddr_string(&ip->ip_src),
+ ipaddr_string(&ip->ip_dst));
+ return;
+ }
+
+ sport = EXTRACT_16BITS(&tp->th_sport);
+ dport = EXTRACT_16BITS(&tp->th_dport);
+
+ hlen = TH_OFF(tp) * 4;
+
+ /*
+ * If data present, header length valid, and NFS port used,
+ * assume NFS.
+ * Pass offset of data plus 4 bytes for RPC TCP msg length
+ * to NFS print routines.
+ */
+ if (!qflag && hlen >= sizeof(*tp) && hlen <= length &&
+ (length - hlen) >= 4) {
+ u_char *fraglenp;
+ u_int32_t fraglen;
+ register struct sunrpc_msg *rp;
+ enum sunrpc_msg_type direction;
+
+ fraglenp = (u_char *)tp + hlen;
+ if (TTEST2(*fraglenp, 4)) {
+ fraglen = EXTRACT_32BITS(fraglenp) & 0x7FFFFFFF;
+ if (fraglen > (length - hlen) - 4)
+ fraglen = (length - hlen) - 4;
+ rp = (struct sunrpc_msg *)(fraglenp + 4);
+ if (TTEST(rp->rm_direction)) {
+ direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction);
+ if (dport == NFS_PORT &&
+ direction == SUNRPC_CALL) {
+ nfsreq_print((u_char *)rp, fraglen,
+ (u_char *)ip);
+ return;
+ }
+ if (sport == NFS_PORT &&
+ direction == SUNRPC_REPLY) {
+ nfsreply_print((u_char *)rp, fraglen,
+ (u_char *)ip);
+ return;
+ }
+ }
+ }
+ }
+#ifdef INET6
+ if (ip6) {
+ if (ip6->ip6_nxt == IPPROTO_TCP) {
+ (void)printf("%s.%s > %s.%s: ",
+ ip6addr_string(&ip6->ip6_src),
+ tcpport_string(sport),
+ ip6addr_string(&ip6->ip6_dst),
+ tcpport_string(dport));
+ } else {
+ (void)printf("%s > %s: ",
+ tcpport_string(sport), tcpport_string(dport));
+ }
+ } else
+#endif /*INET6*/
+ {
+ if (ip->ip_p == IPPROTO_TCP) {
+ (void)printf("%s.%s > %s.%s: ",
+ ipaddr_string(&ip->ip_src),
+ tcpport_string(sport),
+ ipaddr_string(&ip->ip_dst),
+ tcpport_string(dport));
+ } else {
+ (void)printf("%s > %s: ",
+ tcpport_string(sport), tcpport_string(dport));
+ }
+ }
+
+ if (hlen < sizeof(*tp)) {
+ (void)printf(" tcp %d [bad hdr length %u - too short, < %lu]",
+ length - hlen, hlen, (unsigned long)sizeof(*tp));
+ return;
+ }
+
+ TCHECK(*tp);
+
+ seq = EXTRACT_32BITS(&tp->th_seq);
+ ack = EXTRACT_32BITS(&tp->th_ack);
+ win = EXTRACT_16BITS(&tp->th_win);
+ urp = EXTRACT_16BITS(&tp->th_urp);
+
+ if (qflag) {
+ (void)printf("tcp %d", length - hlen);
+ if (hlen > length) {
+ (void)printf(" [bad hdr length %u - too long, > %u]",
+ hlen, length);
+ }
+ return;
+ }
+
+ flags = tp->th_flags;
+ printf("Flags [%s]", bittok2str_nosep(tcp_flag_values, "none", flags));
+
+ if (!Sflag && (flags & TH_ACK)) {
+ register struct tcp_seq_hash *th;
+ const void *src, *dst;
+ register int rev;
+ struct tha tha;
+ /*
+ * Find (or record) the initial sequence numbers for
+ * this conversation. (we pick an arbitrary
+ * collating order so there's only one entry for
+ * both directions).
+ */
+#ifdef INET6
+ rev = 0;
+ if (ip6) {
+ src = &ip6->ip6_src;
+ dst = &ip6->ip6_dst;
+ if (sport > dport)
+ rev = 1;
+ else if (sport == dport) {
+ if (memcmp(src, dst, sizeof ip6->ip6_dst) > 0)
+ rev = 1;
+ }
+ if (rev) {
+ memcpy(&tha.src, dst, sizeof ip6->ip6_dst);
+ memcpy(&tha.dst, src, sizeof ip6->ip6_src);
+ tha.port = dport << 16 | sport;
+ } else {
+ memcpy(&tha.dst, dst, sizeof ip6->ip6_dst);
+ memcpy(&tha.src, src, sizeof ip6->ip6_src);
+ tha.port = sport << 16 | dport;
+ }
+ } else {
+ /*
+ * Zero out the tha structure; the src and dst
+ * fields are big enough to hold an IPv6
+ * address, but we only have IPv4 addresses
+ * and thus must clear out the remaining 124
+ * bits.
+ *
+ * XXX - should we just clear those bytes after
+ * copying the IPv4 addresses, rather than
+ * zeroing out the entire structure and then
+ * overwriting some of the zeroes?
+ *
+ * XXX - this could fail if we see TCP packets
+ * with an IPv6 address with the lower 124 bits
+ * all zero and also see TCP packes with an
+ * IPv4 address with the same 32 bits as the
+ * upper 32 bits of the IPv6 address in question.
+ * Can that happen? Is it likely enough to be
+ * an issue?
+ */
+ memset(&tha, 0, sizeof(tha));
+ src = &ip->ip_src;
+ dst = &ip->ip_dst;
+ if (sport > dport)
+ rev = 1;
+ else if (sport == dport) {
+ if (memcmp(src, dst, sizeof ip->ip_dst) > 0)
+ rev = 1;
+ }
+ if (rev) {
+ memcpy(&tha.src, dst, sizeof ip->ip_dst);
+ memcpy(&tha.dst, src, sizeof ip->ip_src);
+ tha.port = dport << 16 | sport;
+ } else {
+ memcpy(&tha.dst, dst, sizeof ip->ip_dst);
+ memcpy(&tha.src, src, sizeof ip->ip_src);
+ tha.port = sport << 16 | dport;
+ }
+ }
+#else
+ rev = 0;
+ src = &ip->ip_src;
+ dst = &ip->ip_dst;
+ if (sport > dport)
+ rev = 1;
+ else if (sport == dport) {
+ if (memcmp(src, dst, sizeof ip->ip_dst) > 0)
+ rev = 1;
+ }
+ if (rev) {
+ memcpy(&tha.src, dst, sizeof ip->ip_dst);
+ memcpy(&tha.dst, src, sizeof ip->ip_src);
+ tha.port = dport << 16 | sport;
+ } else {
+ memcpy(&tha.dst, dst, sizeof ip->ip_dst);
+ memcpy(&tha.src, src, sizeof ip->ip_src);
+ tha.port = sport << 16 | dport;
+ }
+#endif
+
+ threv = rev;
+ for (th = &tcp_seq_hash[tha.port % TSEQ_HASHSIZE];
+ th->nxt; th = th->nxt)
+ if (memcmp((char *)&tha, (char *)&th->addr,
+ sizeof(th->addr)) == 0)
+ break;
+
+ if (!th->nxt || (flags & TH_SYN)) {
+ /* didn't find it or new conversation */
+ if (th->nxt == NULL) {
+ th->nxt = (struct tcp_seq_hash *)
+ calloc(1, sizeof(*th));
+ if (th->nxt == NULL)
+ error("tcp_print: calloc");
+ }
+ th->addr = tha;
+ if (rev)
+ th->ack = seq, th->seq = ack - 1;
+ else
+ th->seq = seq, th->ack = ack - 1;
+ } else {
+ if (rev)
+ seq -= th->ack, ack -= th->seq;
+ else
+ seq -= th->seq, ack -= th->ack;
+ }
+
+ thseq = th->seq;
+ thack = th->ack;
+ } else {
+ /*fool gcc*/
+ thseq = thack = threv = 0;
+ }
+ if (hlen > length) {
+ (void)printf(" [bad hdr length %u - too long, > %u]",
+ hlen, length);
+ return;
+ }
+
+ if (vflag && !Kflag && !fragmented) {
+ /* Check the checksum, if possible. */
+ u_int16_t sum, tcp_sum;
+
+ if (IP_V(ip) == 4) {
+ if (TTEST2(tp->th_sport, length)) {
+ sum = tcp_cksum(ip, tp, length);
+ tcp_sum = EXTRACT_16BITS(&tp->th_sum);
+
+ (void)printf(", cksum 0x%04x", tcp_sum);
+ if (sum != 0)
+ (void)printf(" (incorrect -> 0x%04x)",
+ in_cksum_shouldbe(tcp_sum, sum));
+ else
+ (void)printf(" (correct)");
+ }
+ }
+#ifdef INET6
+ else if (IP_V(ip) == 6 && ip6->ip6_plen) {
+ if (TTEST2(tp->th_sport, length)) {
+ sum = nextproto6_cksum(ip6, (const u_int8_t *)tp, length, IPPROTO_TCP);
+ tcp_sum = EXTRACT_16BITS(&tp->th_sum);
+
+ (void)printf(", cksum 0x%04x", tcp_sum);
+ if (sum != 0)
+ (void)printf(" (incorrect -> 0x%04x)",
+ in_cksum_shouldbe(tcp_sum, sum));
+ else
+ (void)printf(" (correct)");
+
+ }
+ }
+#endif
+ }
+
+ length -= hlen;
+ if (vflag > 1 || length > 0 || flags & (TH_SYN | TH_FIN | TH_RST)) {
+ (void)printf(", seq %u", seq);
+
+ if (length > 0) {
+ (void)printf(":%u", seq + length);
+ }
+ }
+
+ if (flags & TH_ACK) {
+ (void)printf(", ack %u", ack);
+ }
+
+ (void)printf(", win %d", win);
+
+ if (flags & TH_URG)
+ (void)printf(", urg %d", urp);
+ /*
+ * Handle any options.
+ */
+ if (hlen > sizeof(*tp)) {
+ register const u_char *cp;
+ register u_int i, opt, datalen;
+ register u_int len;
+
+ hlen -= sizeof(*tp);
+ cp = (const u_char *)tp + sizeof(*tp);
+ printf(", options [");
+ while (hlen > 0) {
+ if (ch != '\0')
+ putchar(ch);
+ TCHECK(*cp);
+ opt = *cp++;
+ if (ZEROLENOPT(opt))
+ len = 1;
+ else {
+ TCHECK(*cp);
+ len = *cp++; /* total including type, len */
+ if (len < 2 || len > hlen)
+ goto bad;
+ --hlen; /* account for length byte */
+ }
+ --hlen; /* account for type byte */
+ datalen = 0;
+
+/* Bail if "l" bytes of data are not left or were not captured */
+#define LENCHECK(l) { if ((l) > hlen) goto bad; TCHECK2(*cp, l); }
+
+
+ printf("%s", tok2str(tcp_option_values, "Unknown Option %u", opt));
+
+ switch (opt) {
+
+ case TCPOPT_MAXSEG:
+ datalen = 2;
+ LENCHECK(datalen);
+ (void)printf(" %u", EXTRACT_16BITS(cp));
+ break;
+
+ case TCPOPT_WSCALE:
+ datalen = 1;
+ LENCHECK(datalen);
+ (void)printf(" %u", *cp);
+ break;
+
+ case TCPOPT_SACK:
+ datalen = len - 2;
+ if (datalen % 8 != 0) {
+ (void)printf("malformed sack");
+ } else {
+ u_int32_t s, e;
+
+ (void)printf(" %d ", datalen / 8);
+ for (i = 0; i < datalen; i += 8) {
+ LENCHECK(i + 4);
+ s = EXTRACT_32BITS(cp + i);
+ LENCHECK(i + 8);
+ e = EXTRACT_32BITS(cp + i + 4);
+ if (threv) {
+ s -= thseq;
+ e -= thseq;
+ } else {
+ s -= thack;
+ e -= thack;
+ }
+ (void)printf("{%u:%u}", s, e);
+ }
+ }
+ break;
+
+ case TCPOPT_CC:
+ case TCPOPT_CCNEW:
+ case TCPOPT_CCECHO:
+ case TCPOPT_ECHO:
+ case TCPOPT_ECHOREPLY:
+
+ /*
+ * those options share their semantics.
+ * fall through
+ */
+ datalen = 4;
+ LENCHECK(datalen);
+ (void)printf(" %u", EXTRACT_32BITS(cp));
+ break;
+
+ case TCPOPT_TIMESTAMP:
+ datalen = 8;
+ LENCHECK(datalen);
+ (void)printf(" val %u ecr %u",
+ EXTRACT_32BITS(cp),
+ EXTRACT_32BITS(cp + 4));
+ break;
+
+ case TCPOPT_SIGNATURE:
+ datalen = TCP_SIGLEN;
+ LENCHECK(datalen);
+#ifdef HAVE_LIBCRYPTO
+ switch (tcp_verify_signature(ip, tp,
+ bp + TH_OFF(tp) * 4, length, cp)) {
+
+ case SIGNATURE_VALID:
+ (void)printf("valid");
+ break;
+
+ case SIGNATURE_INVALID:
+ (void)printf("invalid");
+ break;
+
+ case CANT_CHECK_SIGNATURE:
+ (void)printf("can't check - ");
+ for (i = 0; i < TCP_SIGLEN; ++i)
+ (void)printf("%02x", cp[i]);
+ break;
+ }
+#else
+ for (i = 0; i < TCP_SIGLEN; ++i)
+ (void)printf("%02x", cp[i]);
+#endif
+ break;
+
+ case TCPOPT_AUTH:
+ (void)printf("keyid %d", *cp++);
+ datalen = len - 3;
+ for (i = 0; i < datalen; ++i) {
+ LENCHECK(i);
+ (void)printf("%02x", cp[i]);
+ }
+ break;
+
+
+ case TCPOPT_EOL:
+ case TCPOPT_NOP:
+ case TCPOPT_SACKOK:
+ /*
+ * Nothing interesting.
+ * fall through
+ */
+ break;
+
+ case TCPOPT_UTO:
+ datalen = 2;
+ LENCHECK(datalen);
+ utoval = EXTRACT_16BITS(cp);
+ (void)printf("0x%x", utoval);
+ if (utoval & 0x0001)
+ utoval = (utoval >> 1) * 60;
+ else
+ utoval >>= 1;
+ (void)printf(" %u", utoval);
+ break;
+
+ default:
+ datalen = len - 2;
+ for (i = 0; i < datalen; ++i) {
+ LENCHECK(i);
+ (void)printf("%02x", cp[i]);
+ }
+ break;
+ }
+
+ /* Account for data printed */
+ cp += datalen;
+ hlen -= datalen;
+
+ /* Check specification against observed length */
+ ++datalen; /* option octet */
+ if (!ZEROLENOPT(opt))
+ ++datalen; /* size octet */
+ if (datalen != len)
+ (void)printf("[len %d]", len);
+ ch = ',';
+ if (opt == TCPOPT_EOL)
+ break;
+ }
+ putchar(']');
+ }
+
+ /*
+ * Print length field before crawling down the stack.
+ */
+ printf(", length %u", length);
+
+ if (length <= 0)
+ return;
+
+ /*
+ * Decode payload if necessary.
+ */
+ bp += TH_OFF(tp) * 4;
+ if ((flags & TH_RST) && vflag) {
+ print_tcp_rst_data(bp, length);
+ return;
+ }
+
+ if (packettype) {
+ switch (packettype) {
+ case PT_ZMTP1:
+ zmtp1_print(bp, length);
+ break;
+ }
+ return;
+ }
+
+ if (sport == TELNET_PORT || dport == TELNET_PORT) {
+ if (!qflag && vflag)
+ telnet_print(bp, length);
+ } else if (sport == BGP_PORT || dport == BGP_PORT)
+ bgp_print(bp, length);
+ else if (sport == PPTP_PORT || dport == PPTP_PORT)
+ pptp_print(bp);
+#ifdef TCPDUMP_DO_SMB
+ else if (sport == NETBIOS_SSN_PORT || dport == NETBIOS_SSN_PORT)
+ nbt_tcp_print(bp, length);
+ else if (sport == SMB_PORT || dport == SMB_PORT)
+ smb_tcp_print(bp, length);
+#endif
+ else if (sport == BEEP_PORT || dport == BEEP_PORT)
+ beep_print(bp, length);
+ else if (length > 2 &&
+ (sport == NAMESERVER_PORT || dport == NAMESERVER_PORT ||
+ sport == MULTICASTDNS_PORT || dport == MULTICASTDNS_PORT)) {
+ /*
+ * TCP DNS query has 2byte length at the head.
+ * XXX packet could be unaligned, it can go strange
+ */
+ ns_print(bp + 2, length - 2, 0);
+ } else if (sport == MSDP_PORT || dport == MSDP_PORT) {
+ msdp_print(bp, length);
+ } else if (sport == RPKI_RTR_PORT || dport == RPKI_RTR_PORT) {
+ rpki_rtr_print(bp, length);
+ }
+ else if (length > 0 && (sport == LDP_PORT || dport == LDP_PORT)) {
+ ldp_print(bp, length);
+ }
+
+ return;
+ bad:
+ fputs("[bad opt]", stdout);
+ if (ch != '\0')
+ putchar('>');
+ return;
+ trunc:
+ fputs("[|tcp]", stdout);
+ if (ch != '\0')
+ putchar('>');
+}
+
+/*
+ * RFC1122 says the following on data in RST segments:
+ *
+ * 4.2.2.12 RST Segment: RFC-793 Section 3.4
+ *
+ * A TCP SHOULD allow a received RST segment to include data.
+ *
+ * DISCUSSION
+ * It has been suggested that a RST segment could contain
+ * ASCII text that encoded and explained the cause of the
+ * RST. No standard has yet been established for such
+ * data.
+ *
+ */
+
+static void
+print_tcp_rst_data(register const u_char *sp, u_int length)
+{
+ int c;
+
+ if (TTEST2(*sp, length))
+ printf(" [RST");
+ else
+ printf(" [!RST");
+ if (length > MAX_RST_DATA_LEN) {
+ length = MAX_RST_DATA_LEN; /* can use -X for longer */
+ putchar('+'); /* indicate we truncate */
+ }
+ putchar(' ');
+ while (length-- && sp <= snapend) {
+ c = *sp++;
+ safeputchar(c);
+ }
+ putchar(']');
+}
+
+#ifdef HAVE_LIBCRYPTO
+static int
+tcp_verify_signature(const struct ip *ip, const struct tcphdr *tp,
+ const u_char *data, int length, const u_char *rcvsig)
+{
+ struct tcphdr tp1;
+ u_char sig[TCP_SIGLEN];
+ char zero_proto = 0;
+ MD5_CTX ctx;
+ u_int16_t savecsum, tlen;
+#ifdef INET6
+ struct ip6_hdr *ip6;
+ u_int32_t len32;
+ u_int8_t nxt;
+#endif
+
+ if (data + length > snapend) {
+ printf("snaplen too short, ");
+ return (CANT_CHECK_SIGNATURE);
+ }
+
+ tp1 = *tp;
+
+ if (sigsecret == NULL) {
+ printf("shared secret not supplied with -M, ");
+ return (CANT_CHECK_SIGNATURE);
+ }
+
+ MD5_Init(&ctx);
+ /*
+ * Step 1: Update MD5 hash with IP pseudo-header.
+ */
+ if (IP_V(ip) == 4) {
+ MD5_Update(&ctx, (char *)&ip->ip_src, sizeof(ip->ip_src));
+ MD5_Update(&ctx, (char *)&ip->ip_dst, sizeof(ip->ip_dst));
+ MD5_Update(&ctx, (char *)&zero_proto, sizeof(zero_proto));
+ MD5_Update(&ctx, (char *)&ip->ip_p, sizeof(ip->ip_p));
+ tlen = EXTRACT_16BITS(&ip->ip_len) - IP_HL(ip) * 4;
+ tlen = htons(tlen);
+ MD5_Update(&ctx, (char *)&tlen, sizeof(tlen));
+#ifdef INET6
+ } else if (IP_V(ip) == 6) {
+ ip6 = (struct ip6_hdr *)ip;
+ MD5_Update(&ctx, (char *)&ip6->ip6_src, sizeof(ip6->ip6_src));
+ MD5_Update(&ctx, (char *)&ip6->ip6_dst, sizeof(ip6->ip6_dst));
+ len32 = htonl(EXTRACT_16BITS(&ip6->ip6_plen));
+ MD5_Update(&ctx, (char *)&len32, sizeof(len32));
+ nxt = 0;
+ MD5_Update(&ctx, (char *)&nxt, sizeof(nxt));
+ MD5_Update(&ctx, (char *)&nxt, sizeof(nxt));
+ MD5_Update(&ctx, (char *)&nxt, sizeof(nxt));
+ nxt = IPPROTO_TCP;
+ MD5_Update(&ctx, (char *)&nxt, sizeof(nxt));
+#endif
+ } else {
+#ifdef INET6
+ printf("IP version not 4 or 6, ");
+#else
+ printf("IP version not 4, ");
+#endif
+ return (CANT_CHECK_SIGNATURE);
+ }
+
+ /*
+ * Step 2: Update MD5 hash with TCP header, excluding options.
+ * The TCP checksum must be set to zero.
+ */
+ savecsum = tp1.th_sum;
+ tp1.th_sum = 0;
+ MD5_Update(&ctx, (char *)&tp1, sizeof(struct tcphdr));
+ tp1.th_sum = savecsum;
+ /*
+ * Step 3: Update MD5 hash with TCP segment data, if present.
+ */
+ if (length > 0)
+ MD5_Update(&ctx, data, length);
+ /*
+ * Step 4: Update MD5 hash with shared secret.
+ */
+ MD5_Update(&ctx, sigsecret, strlen(sigsecret));
+ MD5_Final(sig, &ctx);
+
+ if (memcmp(rcvsig, sig, TCP_SIGLEN) == 0)
+ return (SIGNATURE_VALID);
+ else
+ return (SIGNATURE_INVALID);
+}
+#endif /* HAVE_LIBCRYPTO */
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-telnet.c b/freebsd/contrib/tcpdump/print-telnet.c
new file mode 100644
index 00000000..a2091789
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-telnet.c
@@ -0,0 +1,269 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/* $NetBSD: print-telnet.c,v 1.2 1999/10/11 12:40:12 sjg Exp $ */
+
+/*-
+ * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Simon J. Gerraty.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the NetBSD
+ * Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * @(#)Copyright (c) 1994, Simon J. Gerraty.
+ *
+ * This is free software. It comes with NO WARRANTY.
+ * Permission to use, modify and distribute this source code
+ * is granted subject to the following conditions.
+ * 1/ that the above copyright notice and this notice
+ * are preserved in all copies.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-telnet.c,v 1.24 2003-12-29 11:05:10 hannes Exp $";
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+#define TELCMDS
+#define TELOPTS
+#include "telnet.h"
+
+/* normal */
+static const char *cmds[] = {
+ "IS", "SEND", "INFO",
+};
+
+/* 37: Authentication */
+static const char *authcmd[] = {
+ "IS", "SEND", "REPLY", "NAME",
+};
+static const char *authtype[] = {
+ "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK",
+ "SRP", "RSA", "SSL", NULL, NULL,
+ "LOKI", "SSA", "KEA_SJ", "KEA_SJ_INTEG", "DSS",
+ "NTLM",
+};
+
+/* 38: Encryption */
+static const char *enccmd[] = {
+ "IS", "SUPPORT", "REPLY", "START", "END",
+ "REQUEST-START", "REQUEST-END", "END_KEYID", "DEC_KEYID",
+};
+static const char *enctype[] = {
+ "NULL", "DES_CFB64", "DES_OFB64", "DES3_CFB64", "DES3_OFB64",
+ NULL, "CAST5_40_CFB64", "CAST5_40_OFB64", "CAST128_CFB64", "CAST128_OFB64",
+};
+
+#define STR_OR_ID(x, tab) \
+ (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x))
+
+static char *
+numstr(int x)
+{
+ static char buf[20];
+
+ snprintf(buf, sizeof(buf), "%#x", x);
+ return buf;
+}
+
+/* sp points to IAC byte */
+static int
+telnet_parse(const u_char *sp, u_int length, int print)
+{
+ int i, x;
+ u_int c;
+ const u_char *osp, *p;
+#define FETCH(c, sp, length) \
+ do { \
+ if (length < 1) \
+ goto pktend; \
+ TCHECK(*sp); \
+ c = *sp++; \
+ length--; \
+ } while (0)
+
+ osp = sp;
+
+ FETCH(c, sp, length);
+ if (c != IAC)
+ goto pktend;
+ FETCH(c, sp, length);
+ if (c == IAC) { /* <IAC><IAC>! */
+ if (print)
+ printf("IAC IAC");
+ goto done;
+ }
+
+ i = c - TELCMD_FIRST;
+ if (i < 0 || i > IAC - TELCMD_FIRST)
+ goto pktend;
+
+ switch (c) {
+ case DONT:
+ case DO:
+ case WONT:
+ case WILL:
+ case SB:
+ /* DONT/DO/WONT/WILL x */
+ FETCH(x, sp, length);
+ if (x >= 0 && x < NTELOPTS) {
+ if (print)
+ (void)printf("%s %s", telcmds[i], telopts[x]);
+ } else {
+ if (print)
+ (void)printf("%s %#x", telcmds[i], x);
+ }
+ if (c != SB)
+ break;
+ /* IAC SB .... IAC SE */
+ p = sp;
+ while (length > (u_int)(p + 1 - sp)) {
+ if (p[0] == IAC && p[1] == SE)
+ break;
+ p++;
+ }
+ if (*p != IAC)
+ goto pktend;
+
+ switch (x) {
+ case TELOPT_AUTHENTICATION:
+ if (p <= sp)
+ break;
+ FETCH(c, sp, length);
+ if (print)
+ (void)printf(" %s", STR_OR_ID(c, authcmd));
+ if (p <= sp)
+ break;
+ FETCH(c, sp, length);
+ if (print)
+ (void)printf(" %s", STR_OR_ID(c, authtype));
+ break;
+ case TELOPT_ENCRYPT:
+ if (p <= sp)
+ break;
+ FETCH(c, sp, length);
+ if (print)
+ (void)printf(" %s", STR_OR_ID(c, enccmd));
+ if (p <= sp)
+ break;
+ FETCH(c, sp, length);
+ if (print)
+ (void)printf(" %s", STR_OR_ID(c, enctype));
+ break;
+ default:
+ if (p <= sp)
+ break;
+ FETCH(c, sp, length);
+ if (print)
+ (void)printf(" %s", STR_OR_ID(c, cmds));
+ break;
+ }
+ while (p > sp) {
+ FETCH(x, sp, length);
+ if (print)
+ (void)printf(" %#x", x);
+ }
+ /* terminating IAC SE */
+ if (print)
+ (void)printf(" SE");
+ sp += 2;
+ length -= 2;
+ break;
+ default:
+ if (print)
+ (void)printf("%s", telcmds[i]);
+ goto done;
+ }
+
+done:
+ return sp - osp;
+
+trunc:
+ (void)printf("[|telnet]");
+pktend:
+ return -1;
+#undef FETCH
+}
+
+void
+telnet_print(const u_char *sp, u_int length)
+{
+ int first = 1;
+ const u_char *osp;
+ int l;
+
+ osp = sp;
+
+ while (length > 0 && *sp == IAC) {
+ l = telnet_parse(sp, length, 0);
+ if (l < 0)
+ break;
+
+ /*
+ * now print it
+ */
+ if (Xflag && 2 < vflag) {
+ if (first)
+ printf("\nTelnet:");
+ hex_print_with_offset("\n", sp, l, sp - osp);
+ if (l > 8)
+ printf("\n\t\t\t\t");
+ else
+ printf("%*s\t", (8 - l) * 3, "");
+ } else
+ printf("%s", (first) ? " [telnet " : ", ");
+
+ (void)telnet_parse(sp, length, 1);
+ first = 0;
+
+ sp += l;
+ length -= l;
+ }
+ if (!first) {
+ if (Xflag && 2 < vflag)
+ printf("\n");
+ else
+ printf("]");
+ }
+}
diff --git a/freebsd/contrib/tcpdump/print-tftp.c b/freebsd/contrib/tcpdump/print-tftp.c
new file mode 100644
index 00000000..2a2f70b4
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-tftp.c
@@ -0,0 +1,155 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Format and print trivial file transfer protocol packets.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-tftp.c,v 1.39 2008-04-11 16:47:38 gianluca Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#ifdef SEGSIZE
+#undef SEGSIZE /* SINIX sucks */
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+#include "tftp.h"
+
+/* op code to string mapping */
+static struct tok op2str[] = {
+ { RRQ, "RRQ" }, /* read request */
+ { WRQ, "WRQ" }, /* write request */
+ { DATA, "DATA" }, /* data packet */
+ { ACK, "ACK" }, /* acknowledgement */
+ { TFTP_ERROR, "ERROR" }, /* error code */
+ { OACK, "OACK" }, /* option acknowledgement */
+ { 0, NULL }
+};
+
+/* error code to string mapping */
+static struct tok err2str[] = {
+ { EUNDEF, "EUNDEF" }, /* not defined */
+ { ENOTFOUND, "ENOTFOUND" }, /* file not found */
+ { EACCESS, "EACCESS" }, /* access violation */
+ { ENOSPACE, "ENOSPACE" }, /* disk full or allocation exceeded */
+ { EBADOP, "EBADOP" }, /* illegal TFTP operation */
+ { EBADID, "EBADID" }, /* unknown transfer ID */
+ { EEXISTS, "EEXISTS" }, /* file already exists */
+ { ENOUSER, "ENOUSER" }, /* no such user */
+ { 0, NULL }
+};
+
+/*
+ * Print trivial file transfer program requests
+ */
+void
+tftp_print(register const u_char *bp, u_int length)
+{
+ register const struct tftphdr *tp;
+ register const char *cp;
+ register const u_char *p;
+ register int opcode, i;
+ static char tstr[] = " [|tftp]";
+
+ tp = (const struct tftphdr *)bp;
+
+ /* Print length */
+ printf(" %d", length);
+
+ /* Print tftp request type */
+ TCHECK(tp->th_opcode);
+ opcode = EXTRACT_16BITS(&tp->th_opcode);
+ cp = tok2str(op2str, "tftp-#%d", opcode);
+ printf(" %s", cp);
+ /* Bail if bogus opcode */
+ if (*cp == 't')
+ return;
+
+ switch (opcode) {
+
+ case RRQ:
+ case WRQ:
+ case OACK:
+ p = (u_char *)tp->th_stuff;
+ putchar(' ');
+ /* Print filename or first option */
+ if (opcode != OACK)
+ putchar('"');
+ i = fn_print(p, snapend);
+ if (opcode != OACK)
+ putchar('"');
+
+ /* Print the mode (RRQ and WRQ only) and any options */
+ while ((p = (const u_char *)strchr((const char *)p, '\0')) != NULL) {
+ if (length <= (u_int)(p - (const u_char *)&tp->th_block))
+ break;
+ p++;
+ if (*p != '\0') {
+ putchar(' ');
+ fn_print(p, snapend);
+ }
+ }
+
+ if (i)
+ goto trunc;
+ break;
+
+ case ACK:
+ case DATA:
+ TCHECK(tp->th_block);
+ printf(" block %d", EXTRACT_16BITS(&tp->th_block));
+ break;
+
+ case TFTP_ERROR:
+ /* Print error code string */
+ TCHECK(tp->th_code);
+ printf(" %s \"", tok2str(err2str, "tftp-err-#%d \"",
+ EXTRACT_16BITS(&tp->th_code)));
+ /* Print error message string */
+ i = fn_print((const u_char *)tp->th_data, snapend);
+ putchar('"');
+ if (i)
+ goto trunc;
+ break;
+
+ default:
+ /* We shouldn't get here */
+ printf("(unknown #%d)", opcode);
+ break;
+ }
+ return;
+trunc:
+ fputs(tstr, stdout);
+ return;
+}
diff --git a/freebsd/contrib/tcpdump/print-timed.c b/freebsd/contrib/tcpdump/print-timed.c
new file mode 100644
index 00000000..b9fabef7
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-timed.c
@@ -0,0 +1,113 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 2000 Ben Smithurst <ben@scientia.demon.co.uk>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-timed.c,v 1.9 2003-11-16 09:36:40 guy Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "timed.h"
+#include "interface.h"
+#include "extract.h"
+
+static const char *tsptype[TSPTYPENUMBER] =
+ { "ANY", "ADJTIME", "ACK", "MASTERREQ", "MASTERACK", "SETTIME", "MASTERUP",
+ "SLAVEUP", "ELECTION", "ACCEPT", "REFUSE", "CONFLICT", "RESOLVE", "QUIT",
+ "DATE", "DATEREQ", "DATEACK", "TRACEON", "TRACEOFF", "MSITE", "MSITEREQ",
+ "TEST", "SETDATE", "SETDATEREQ", "LOOP" };
+
+void
+timed_print(register const u_char *bp)
+{
+#define endof(x) ((u_char *)&(x) + sizeof (x))
+ struct tsp *tsp = (struct tsp *)bp;
+ long sec, usec;
+ const u_char *end;
+
+ if (endof(tsp->tsp_type) > snapend) {
+ fputs("[|timed]", stdout);
+ return;
+ }
+ if (tsp->tsp_type < TSPTYPENUMBER)
+ printf("TSP_%s", tsptype[tsp->tsp_type]);
+ else
+ printf("(tsp_type %#x)", tsp->tsp_type);
+
+ if (endof(tsp->tsp_vers) > snapend) {
+ fputs(" [|timed]", stdout);
+ return;
+ }
+ printf(" vers %d", tsp->tsp_vers);
+
+ if (endof(tsp->tsp_seq) > snapend) {
+ fputs(" [|timed]", stdout);
+ return;
+ }
+ printf(" seq %d", tsp->tsp_seq);
+
+ if (tsp->tsp_type == TSP_LOOP) {
+ if (endof(tsp->tsp_hopcnt) > snapend) {
+ fputs(" [|timed]", stdout);
+ return;
+ }
+ printf(" hopcnt %d", tsp->tsp_hopcnt);
+ } else if (tsp->tsp_type == TSP_SETTIME ||
+ tsp->tsp_type == TSP_ADJTIME ||
+ tsp->tsp_type == TSP_SETDATE ||
+ tsp->tsp_type == TSP_SETDATEREQ) {
+ if (endof(tsp->tsp_time) > snapend) {
+ fputs(" [|timed]", stdout);
+ return;
+ }
+ sec = EXTRACT_32BITS(&tsp->tsp_time.tv_sec);
+ usec = EXTRACT_32BITS(&tsp->tsp_time.tv_usec);
+ if (usec < 0)
+ /* corrupt, skip the rest of the packet */
+ return;
+ fputs(" time ", stdout);
+ if (sec < 0 && usec != 0) {
+ sec++;
+ if (sec == 0)
+ fputc('-', stdout);
+ usec = 1000000 - usec;
+ }
+ printf("%ld.%06ld", sec, usec);
+ }
+
+ end = memchr(tsp->tsp_name, '\0', snapend - (u_char *)tsp->tsp_name);
+ if (end == NULL)
+ fputs(" [|timed]", stdout);
+ else {
+ fputs(" name ", stdout);
+ fwrite(tsp->tsp_name, end - (u_char *)tsp->tsp_name, 1, stdout);
+ }
+}
diff --git a/freebsd/contrib/tcpdump/print-tipc.c b/freebsd/contrib/tcpdump/print-tipc.c
new file mode 100644
index 00000000..d0a20b58
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-tipc.c
@@ -0,0 +1,394 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-arp.c,v 1.66 2006-03-03 22:53:21 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "netdissect.h"
+#include "addrtoname.h"
+#include "ether.h"
+#include "ethertype.h"
+#include "extract.h" /* must come after interface.h */
+
+/*
+ * Transparent Inter-Process Communication (TIPC) protocol.
+ *
+ * http://tipc.sourceforge.net/doc/draft-spec-tipc-07.html
+ * http://tipc.sourceforge.net/doc/tipc_message_formats.html
+ */
+
+#define TIPC_USER_LOW_IMPORTANCE 0
+#define TIPC_USER_MEDIUM_IMPORTANCE 1
+#define TIPC_USER_HIGH_IMPORTANCE 2
+#define TIPC_USER_CRITICAL_IMPORTANCE 3
+#define TIPC_USER_BCAST_PROTOCOL 5
+#define TIPC_USER_MSG_BUNDLER 6
+#define TIPC_USER_LINK_PROTOCOL 7
+#define TIPC_USER_CONN_MANAGER 8
+#define TIPC_USER_CHANGEOVER_PROTOCOL 10
+#define TIPC_USER_NAME_DISTRIBUTOR 11
+#define TIPC_USER_MSG_FRAGMENTER 12
+#define TIPC_USER_LINK_CONFIG 13
+
+#define TIPC_CONN_MSG 0
+#define TIPC_DIRECT_MSG 1
+#define TIPC_NAMED_MSG 2
+#define TIPC_MCAST_MSG 3
+
+#define TIPC_ZONE(addr) (((addr) >> 24) & 0xFF)
+#define TIPC_CLUSTER(addr) (((addr) >> 12) & 0xFFF)
+#define TIPC_NODE(addr) (((addr) >> 0) & 0xFFF)
+
+struct tipc_pkthdr {
+ u_int32_t w0;
+ u_int32_t w1;
+};
+
+#define TIPC_VER(w0) (((w0) >> 29) & 0x07)
+#define TIPC_USER(w0) (((w0) >> 25) & 0x0F)
+#define TIPC_HSIZE(w0) (((w0) >> 21) & 0x0F)
+#define TIPC_MSIZE(w0) (((w0) >> 0) & 0xFFFF)
+#define TIPC_MTYPE(w1) (((w1) >> 29) & 0x07)
+#define TIPC_BROADCAST_ACK(w1) (((w1) >> 0) & 0xFFFF)
+#define TIPC_LINK_ACK(w2) (((w2) >> 16) & 0xFFFF)
+#define TIPC_LINK_SEQ(w2) (((w2) >> 0) & 0xFFFF)
+
+static const struct tok tipcuser_values[] = {
+ { TIPC_USER_LOW_IMPORTANCE, "Low Importance Data payload" },
+ { TIPC_USER_MEDIUM_IMPORTANCE, "Medium Importance Data payload" },
+ { TIPC_USER_HIGH_IMPORTANCE, "High Importance Data payload" },
+ { TIPC_USER_CRITICAL_IMPORTANCE, "Critical Importance Data payload" },
+ { TIPC_USER_BCAST_PROTOCOL, "Broadcast Link Protocol internal" },
+ { TIPC_USER_MSG_BUNDLER, "Message Bundler Protocol internal" },
+ { TIPC_USER_LINK_PROTOCOL, "Link State Protocol internal" },
+ { TIPC_USER_CONN_MANAGER, "Connection Manager internal" },
+ { TIPC_USER_CHANGEOVER_PROTOCOL, "Link Changeover Protocol internal" },
+ { TIPC_USER_NAME_DISTRIBUTOR, "Name Table Update Protocol internal" },
+ { TIPC_USER_MSG_FRAGMENTER, "Message Fragmentation Protocol internal" },
+ { TIPC_USER_LINK_CONFIG, "Neighbor Detection Protocol internal" },
+ { 0, NULL }
+};
+
+static const struct tok tipcmtype_values[] = {
+ { TIPC_CONN_MSG, "CONN_MSG" },
+ { TIPC_DIRECT_MSG, "MCAST_MSG" },
+ { TIPC_NAMED_MSG, "NAMED_MSG" },
+ { TIPC_MCAST_MSG, "DIRECT_MSG" },
+ { 0, NULL }
+};
+
+static const struct tok tipc_linkconf_mtype_values[] = {
+ { 0, "Link request" },
+ { 1, "Link response" },
+ { 0, NULL }
+};
+
+struct payload_tipc_pkthdr {
+ u_int32_t w0;
+ u_int32_t w1;
+ u_int32_t w2;
+ u_int32_t prev_node;
+ u_int32_t orig_port;
+ u_int32_t dest_port;
+ u_int32_t orig_node;
+ u_int32_t dest_node;
+ u_int32_t name_type;
+ u_int32_t w9;
+ u_int32_t wA;
+};
+
+struct internal_tipc_pkthdr {
+ u_int32_t w0;
+ u_int32_t w1;
+ u_int32_t w2;
+ u_int32_t prev_node;
+ u_int32_t w4;
+ u_int32_t w5;
+ u_int32_t orig_node;
+ u_int32_t dest_node;
+ u_int32_t trans_seq;
+ u_int32_t w9;
+};
+
+#define TIPC_SEQ_GAP(w1) (((w1) >> 16) & 0x1FFF)
+#define TIPC_BC_GAP_AFTER(w2) (((w2) >> 16) & 0xFFFF)
+#define TIPC_BC_GAP_TO(w2) (((w2) >> 0) & 0xFFFF)
+#define TIPC_LAST_SENT_FRAG(w4) (((w4) >> 16) & 0xFFFF)
+#define TIPC_NEXT_SENT_FRAG(w4) (((w4) >> 0) & 0xFFFF)
+#define TIPC_SESS_NO(w5) (((w5) >> 16) & 0xFFFF)
+#define TIPC_MSG_CNT(w9) (((w9) >> 16) & 0xFFFF)
+#define TIPC_LINK_TOL(w9) (((w9) >> 0) & 0xFFFF)
+
+struct link_conf_tipc_pkthdr {
+ u_int32_t w0;
+ u_int32_t w1;
+ u_int32_t dest_domain;
+ u_int32_t prev_node;
+ u_int32_t ntwrk_id;
+ u_int32_t w5;
+ u_int8_t media_address[16];
+};
+
+#define TIPC_NODE_SIG(w1) (((w1) >> 0) & 0xFFFF)
+#define TIPC_MEDIA_ID(w5) (((w5) >> 0) & 0xFF)
+
+static void
+print_payload(netdissect_options *ndo, const struct payload_tipc_pkthdr *ap)
+{
+ u_int32_t w0, w1, w2;
+ u_int user;
+ u_int hsize;
+ u_int msize;
+ u_int mtype;
+ u_int broadcast_ack;
+ u_int link_ack;
+ u_int link_seq;
+ u_int prev_node;
+ u_int orig_port;
+ u_int dest_port;
+ u_int orig_node;
+ u_int dest_node;
+
+ ND_TCHECK(ap->dest_port);
+ w0 = EXTRACT_32BITS(&ap->w0);
+ user = TIPC_USER(w0);
+ hsize = TIPC_HSIZE(w0);
+ msize = TIPC_MSIZE(w0);
+ w1 = EXTRACT_32BITS(&ap->w1);
+ mtype = TIPC_MTYPE(w1);
+ prev_node = EXTRACT_32BITS(&ap->prev_node);
+ orig_port = EXTRACT_32BITS(&ap->orig_port);
+ dest_port = EXTRACT_32BITS(&ap->dest_port);
+ if (hsize <= 6) {
+ ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u:%u > %u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s",
+ TIPC_VER(w0),
+ TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node),
+ orig_port, dest_port,
+ hsize*4, msize,
+ tok2str(tipcuser_values, "unknown", user),
+ tok2str(tipcmtype_values, "Unknown", mtype)));
+ } else {
+ ND_TCHECK(ap->dest_node);
+ orig_node = EXTRACT_32BITS(&ap->orig_node);
+ dest_node = EXTRACT_32BITS(&ap->dest_node);
+ ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u:%u > %u.%u.%u:%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s",
+ TIPC_VER(w0),
+ TIPC_ZONE(orig_node), TIPC_CLUSTER(orig_node), TIPC_NODE(orig_node),
+ orig_port,
+ TIPC_ZONE(dest_node), TIPC_CLUSTER(dest_node), TIPC_NODE(dest_node),
+ dest_port,
+ hsize*4, msize,
+ tok2str(tipcuser_values, "unknown", user),
+ tok2str(tipcmtype_values, "Unknown", mtype)));
+
+ if (ndo->ndo_vflag) {
+ broadcast_ack = TIPC_BROADCAST_ACK(w1);
+ w2 = EXTRACT_32BITS(&ap->w2);
+ link_ack = TIPC_LINK_ACK(w2);
+ link_seq = TIPC_LINK_SEQ(w2);
+ ND_PRINT((ndo, "\n\tPrevious Node %u.%u.%u, Broadcast Ack %u, Link Ack %u, Link Sequence %u",
+ TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node),
+ broadcast_ack, link_ack, link_seq));
+ }
+ }
+ return;
+
+trunc:
+ ND_PRINT((ndo, "[|TIPC]"));
+}
+
+static void
+print_internal(netdissect_options *ndo, const struct internal_tipc_pkthdr *ap)
+{
+ u_int32_t w0, w1, w2, w4, w5, w9;
+ u_int user;
+ u_int hsize;
+ u_int msize;
+ u_int mtype;
+ u_int seq_gap;
+ u_int broadcast_ack;
+ u_int bc_gap_after;
+ u_int bc_gap_to;
+ u_int prev_node;
+ u_int last_sent_frag;
+ u_int next_sent_frag;
+ u_int sess_no;
+ u_int orig_node;
+ u_int dest_node;
+ u_int trans_seq;
+ u_int msg_cnt;
+ u_int link_tol;
+
+ ND_TCHECK(ap->dest_node);
+ w0 = EXTRACT_32BITS(&ap->w0);
+ user = TIPC_USER(w0);
+ hsize = TIPC_HSIZE(w0);
+ msize = TIPC_MSIZE(w0);
+ w1 = EXTRACT_32BITS(&ap->w1);
+ mtype = TIPC_MTYPE(w1);
+ orig_node = EXTRACT_32BITS(&ap->orig_node);
+ dest_node = EXTRACT_32BITS(&ap->dest_node);
+ ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u > %u.%u.%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s (0x%08x)",
+ TIPC_VER(w0),
+ TIPC_ZONE(orig_node), TIPC_CLUSTER(orig_node), TIPC_NODE(orig_node),
+ TIPC_ZONE(dest_node), TIPC_CLUSTER(dest_node), TIPC_NODE(dest_node),
+ hsize*4, msize,
+ tok2str(tipcuser_values, "unknown", user),
+ tok2str(tipcmtype_values, "Unknown", mtype), w1));
+
+ if (ndo->ndo_vflag) {
+ ND_TCHECK(*ap);
+ seq_gap = TIPC_SEQ_GAP(w1);
+ broadcast_ack = TIPC_BROADCAST_ACK(w1);
+ w2 = EXTRACT_32BITS(&ap->w2);
+ bc_gap_after = TIPC_BC_GAP_AFTER(w2);
+ bc_gap_to = TIPC_BC_GAP_TO(w2);
+ prev_node = EXTRACT_32BITS(&ap->prev_node);
+ w4 = EXTRACT_32BITS(&ap->w4);
+ last_sent_frag = TIPC_LAST_SENT_FRAG(w4);
+ next_sent_frag = TIPC_NEXT_SENT_FRAG(w4);
+ w5 = EXTRACT_32BITS(&ap->w5);
+ sess_no = TIPC_SESS_NO(w5);
+ trans_seq = EXTRACT_32BITS(&ap->trans_seq);
+ w9 = EXTRACT_32BITS(&ap->w9);
+ msg_cnt = TIPC_MSG_CNT(w9);
+ link_tol = TIPC_LINK_TOL(w9);
+ ND_PRINT((ndo, "\n\tPrevious Node %u.%u.%u, Session No. %u, Broadcast Ack %u, Sequence Gap %u, Broadcast Gap After %u, Broadcast Gap To %u, Last Sent Packet No. %u, Next sent Packet No. %u, Transport Sequence %u, msg_count %u, Link Tolerance %u",
+ TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node),
+ sess_no, broadcast_ack, seq_gap, bc_gap_after, bc_gap_to,
+ last_sent_frag, next_sent_frag, trans_seq, msg_cnt,
+ link_tol));
+ }
+ return;
+
+trunc:
+ ND_PRINT((ndo, "[|TIPC]"));
+}
+
+static void
+print_link_conf(netdissect_options *ndo, const struct link_conf_tipc_pkthdr *ap)
+{
+ u_int32_t w0, w1, w5;
+ u_int user;
+ u_int hsize;
+ u_int msize;
+ u_int mtype;
+ u_int node_sig;
+ u_int prev_node;
+ u_int dest_domain;
+ u_int ntwrk_id;
+ u_int media_id;
+
+ ND_TCHECK(ap->prev_node);
+ w0 = EXTRACT_32BITS(&ap->w0);
+ user = TIPC_USER(w0);
+ hsize = TIPC_HSIZE(w0);
+ msize = TIPC_MSIZE(w0);
+ w1 = EXTRACT_32BITS(&ap->w1);
+ mtype = TIPC_MTYPE(w1);
+ prev_node = EXTRACT_32BITS(&ap->prev_node);
+ dest_domain = EXTRACT_32BITS(&ap->dest_domain);
+ prev_node = EXTRACT_32BITS(&ap->prev_node);
+
+ ND_PRINT((ndo, "TIPC v%u.0 %u.%u.%u > %u.%u.%u, headerlength %u bytes, MessageSize %u bytes, %s, messageType %s",
+ TIPC_VER(w0),
+ TIPC_ZONE(prev_node), TIPC_CLUSTER(prev_node), TIPC_NODE(prev_node),
+ TIPC_ZONE(dest_domain), TIPC_CLUSTER(dest_domain), TIPC_NODE(dest_domain),
+ hsize*4, msize,
+ tok2str(tipcuser_values, "unknown", user),
+ tok2str(tipc_linkconf_mtype_values, "Unknown", mtype)));
+ if (ndo->ndo_vflag) {
+ ND_TCHECK(ap->w5);
+ node_sig = TIPC_NODE_SIG(w1);
+ ntwrk_id = EXTRACT_32BITS(&ap->ntwrk_id);
+ w5 = EXTRACT_32BITS(&ap->w5);
+ media_id = TIPC_MEDIA_ID(w5);
+ ND_PRINT((ndo, "\n\tNodeSignature %u, network_id %u, media_id %u",
+ node_sig, ntwrk_id, media_id));
+ }
+ return;
+
+trunc:
+ ND_PRINT((ndo, "[|TIPC]"));
+}
+
+void
+tipc_print(netdissect_options *ndo, const u_char *bp, u_int length _U_,
+ u_int caplen _U_)
+{
+ const struct tipc_pkthdr *ap;
+ u_int32_t w0;
+ u_int user;
+
+ ap = (struct tipc_pkthdr *)bp;
+ ND_TCHECK(ap->w0);
+ w0 = EXTRACT_32BITS(&ap->w0);
+ user = TIPC_USER(w0);
+
+ switch (user)
+ {
+ case TIPC_USER_LOW_IMPORTANCE:
+ case TIPC_USER_MEDIUM_IMPORTANCE:
+ case TIPC_USER_HIGH_IMPORTANCE:
+ case TIPC_USER_CRITICAL_IMPORTANCE:
+ case TIPC_USER_NAME_DISTRIBUTOR:
+ case TIPC_USER_CONN_MANAGER:
+ print_payload(ndo, (struct payload_tipc_pkthdr *)bp);
+ break;
+
+ case TIPC_USER_LINK_CONFIG:
+ print_link_conf(ndo, (struct link_conf_tipc_pkthdr *)bp);
+ break;
+
+ case TIPC_USER_BCAST_PROTOCOL:
+ case TIPC_USER_MSG_BUNDLER:
+ case TIPC_USER_LINK_PROTOCOL:
+ case TIPC_USER_CHANGEOVER_PROTOCOL:
+ case TIPC_USER_MSG_FRAGMENTER:
+ print_internal(ndo, (struct internal_tipc_pkthdr *)bp);
+ break;
+
+ }
+ return;
+
+trunc:
+ ND_PRINT((ndo, "[|TIPC]"));
+}
+
+/*
+ * Local Variables:
+ * c-style: bsd
+ * End:
+ */
+
diff --git a/freebsd/contrib/tcpdump/print-token.c b/freebsd/contrib/tcpdump/print-token.c
new file mode 100644
index 00000000..5d1a44c3
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-token.c
@@ -0,0 +1,207 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Hacked version of print-ether.c Larry Lile <lile@stdio.com>
+ *
+ * Further tweaked to more closely resemble print-fddi.c
+ * Guy Harris <guy@alum.mit.edu>
+ *
+ * $FreeBSD$
+ */
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-token.c,v 1.27 2005-11-13 12:12:43 guy Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <pcap.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+#include "ethertype.h"
+
+#include "ether.h"
+#include "token.h"
+
+/* Extract src, dst addresses */
+static inline void
+extract_token_addrs(const struct token_header *trp, char *fsrc, char *fdst)
+{
+ memcpy(fdst, (const char *)trp->token_dhost, 6);
+ memcpy(fsrc, (const char *)trp->token_shost, 6);
+}
+
+/*
+ * Print the TR MAC header
+ */
+static inline void
+token_hdr_print(register const struct token_header *trp, register u_int length,
+ register const u_char *fsrc, register const u_char *fdst)
+{
+ const char *srcname, *dstname;
+
+ srcname = etheraddr_string(fsrc);
+ dstname = etheraddr_string(fdst);
+
+ if (vflag)
+ (void) printf("%02x %02x %s %s %d: ",
+ trp->token_ac,
+ trp->token_fc,
+ srcname, dstname,
+ length);
+ else
+ printf("%s %s %d: ", srcname, dstname, length);
+}
+
+static const char *broadcast_indicator[] = {
+ "Non-Broadcast", "Non-Broadcast",
+ "Non-Broadcast", "Non-Broadcast",
+ "All-routes", "All-routes",
+ "Single-route", "Single-route"
+};
+
+static const char *direction[] = {
+ "Forward", "Backward"
+};
+
+static const char *largest_frame[] = {
+ "516",
+ "1500",
+ "2052",
+ "4472",
+ "8144",
+ "11407",
+ "17800",
+ "??"
+};
+
+u_int
+token_print(const u_char *p, u_int length, u_int caplen)
+{
+ const struct token_header *trp;
+ u_short extracted_ethertype;
+ struct ether_header ehdr;
+ u_int route_len = 0, hdr_len = TOKEN_HDRLEN;
+ int seg;
+
+ trp = (const struct token_header *)p;
+
+ if (caplen < TOKEN_HDRLEN) {
+ printf("[|token-ring]");
+ return hdr_len;
+ }
+
+ /*
+ * Get the TR addresses into a canonical form
+ */
+ extract_token_addrs(trp, (char*)ESRC(&ehdr), (char*)EDST(&ehdr));
+
+ /* Adjust for source routing information in the MAC header */
+ if (IS_SOURCE_ROUTED(trp)) {
+ /* Clear source-routed bit */
+ *ESRC(&ehdr) &= 0x7f;
+
+ if (eflag)
+ token_hdr_print(trp, length, ESRC(&ehdr), EDST(&ehdr));
+
+ if (caplen < TOKEN_HDRLEN + 2) {
+ printf("[|token-ring]");
+ return hdr_len;
+ }
+ route_len = RIF_LENGTH(trp);
+ hdr_len += route_len;
+ if (caplen < hdr_len) {
+ printf("[|token-ring]");
+ return hdr_len;
+ }
+ if (vflag) {
+ printf("%s ", broadcast_indicator[BROADCAST(trp)]);
+ printf("%s", direction[DIRECTION(trp)]);
+
+ for (seg = 0; seg < SEGMENT_COUNT(trp); seg++)
+ printf(" [%d:%d]", RING_NUMBER(trp, seg),
+ BRIDGE_NUMBER(trp, seg));
+ } else {
+ printf("rt = %x", EXTRACT_16BITS(&trp->token_rcf));
+
+ for (seg = 0; seg < SEGMENT_COUNT(trp); seg++)
+ printf(":%x", EXTRACT_16BITS(&trp->token_rseg[seg]));
+ }
+ printf(" (%s) ", largest_frame[LARGEST_FRAME(trp)]);
+ } else {
+ if (eflag)
+ token_hdr_print(trp, length, ESRC(&ehdr), EDST(&ehdr));
+ }
+
+ /* Skip over token ring MAC header and routing information */
+ length -= hdr_len;
+ p += hdr_len;
+ caplen -= hdr_len;
+
+ /* Frame Control field determines interpretation of packet */
+ if (FRAME_TYPE(trp) == TOKEN_FC_LLC) {
+ /* Try to print the LLC-layer header & higher layers */
+ if (llc_print(p, length, caplen, ESRC(&ehdr), EDST(&ehdr),
+ &extracted_ethertype) == 0) {
+ /* ether_type not known, print raw packet */
+ if (!eflag)
+ token_hdr_print(trp,
+ length + TOKEN_HDRLEN + route_len,
+ ESRC(&ehdr), EDST(&ehdr));
+ if (extracted_ethertype) {
+ printf("(LLC %s) ",
+ etherproto_string(htons(extracted_ethertype)));
+ }
+ if (!suppress_default_print)
+ default_print(p, caplen);
+ }
+ } else {
+ /* Some kinds of TR packet we cannot handle intelligently */
+ /* XXX - dissect MAC packets if frame type is 0 */
+ if (!eflag)
+ token_hdr_print(trp, length + TOKEN_HDRLEN + route_len,
+ ESRC(&ehdr), EDST(&ehdr));
+ if (!suppress_default_print)
+ default_print(p, caplen);
+ }
+ return (hdr_len);
+}
+
+/*
+ * This is the top level routine of the printer. 'p' points
+ * to the TR header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ */
+u_int
+token_if_print(const struct pcap_pkthdr *h, const u_char *p)
+{
+ return (token_print(p, h->len, h->caplen));
+}
diff --git a/freebsd/contrib/tcpdump/print-udld.c b/freebsd/contrib/tcpdump/print-udld.c
new file mode 100644
index 00000000..82135c9d
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-udld.c
@@ -0,0 +1,175 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1998-2007 The TCPDUMP project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * UNIDIRECTIONAL LINK DETECTION (UDLD) as per
+ * http://www.ietf.org/internet-drafts/draft-foschiano-udld-02.txt
+ *
+ * Original code by Carles Kishimoto <carles.kishimoto@gmail.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+#include "nlpid.h"
+
+#define UDLD_HEADER_LEN 4
+#define UDLD_DEVICE_ID_TLV 0x0001
+#define UDLD_PORT_ID_TLV 0x0002
+#define UDLD_ECHO_TLV 0x0003
+#define UDLD_MESSAGE_INTERVAL_TLV 0x0004
+#define UDLD_TIMEOUT_INTERVAL_TLV 0x0005
+#define UDLD_DEVICE_NAME_TLV 0x0006
+#define UDLD_SEQ_NUMBER_TLV 0x0007
+
+static struct tok udld_tlv_values[] = {
+ { UDLD_DEVICE_ID_TLV, "Device-ID TLV"},
+ { UDLD_PORT_ID_TLV, "Port-ID TLV"},
+ { UDLD_ECHO_TLV, "Echo TLV"},
+ { UDLD_MESSAGE_INTERVAL_TLV, "Message Interval TLV"},
+ { UDLD_TIMEOUT_INTERVAL_TLV, "Timeout Interval TLV"},
+ { UDLD_DEVICE_NAME_TLV, "Device Name TLV"},
+ { UDLD_SEQ_NUMBER_TLV,"Sequence Number TLV"},
+ { 0, NULL}
+};
+
+static struct tok udld_code_values[] = {
+ { 0x00, "Reserved"},
+ { 0x01, "Probe message"},
+ { 0x02, "Echo message"},
+ { 0x03, "Flush message"},
+ { 0, NULL}
+};
+
+static struct tok udld_flags_values[] = {
+ { 0x00, "RT"},
+ { 0x01, "RSY"},
+ { 0, NULL}
+};
+
+/*
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Ver | Opcode | Flags | Checksum |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | List of TLVs (variable length list) |
+ * | ... |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+#define UDLD_EXTRACT_VERSION(x) (((x)&0xe0)>>5)
+#define UDLD_EXTRACT_OPCODE(x) ((x)&0x1f)
+
+void
+udld_print (const u_char *pptr, u_int length)
+{
+ int code, type, len;
+ const u_char *tptr;
+
+ if (length < UDLD_HEADER_LEN)
+ goto trunc;
+
+ tptr = pptr;
+
+ if (!TTEST2(*tptr, UDLD_HEADER_LEN))
+ goto trunc;
+
+ code = UDLD_EXTRACT_OPCODE(*tptr);
+
+ printf("UDLDv%u, Code %s (%x), Flags [%s] (0x%02x), length %u",
+ UDLD_EXTRACT_VERSION(*tptr),
+ tok2str(udld_code_values, "Reserved", code),
+ code,
+ bittok2str(udld_flags_values, "none", *(tptr+1)),
+ *(tptr+1),
+ length);
+
+ /*
+ * In non-verbose mode, just print version and opcode type
+ */
+ if (vflag < 1) {
+ return;
+ }
+
+ printf("\n\tChecksum 0x%04x (unverified)", EXTRACT_16BITS(tptr+2));
+
+ tptr += UDLD_HEADER_LEN;
+
+ while (tptr < (pptr+length)) {
+
+ if (!TTEST2(*tptr, 4))
+ goto trunc;
+
+ type = EXTRACT_16BITS(tptr);
+ len = EXTRACT_16BITS(tptr+2);
+ len -= 4;
+ tptr += 4;
+
+ /* infinite loop check */
+ if (type == 0 || len == 0) {
+ return;
+ }
+
+ printf("\n\t%s (0x%04x) TLV, length %u",
+ tok2str(udld_tlv_values, "Unknown", type),
+ type, len);
+
+ switch (type) {
+ case UDLD_DEVICE_ID_TLV:
+ case UDLD_PORT_ID_TLV:
+ case UDLD_ECHO_TLV:
+ case UDLD_DEVICE_NAME_TLV:
+ printf(", %s", tptr);
+ break;
+
+ case UDLD_MESSAGE_INTERVAL_TLV:
+ case UDLD_TIMEOUT_INTERVAL_TLV:
+ printf(", %us", (*tptr));
+ break;
+
+ case UDLD_SEQ_NUMBER_TLV:
+ printf(", %u", EXTRACT_32BITS(tptr));
+ break;
+
+ default:
+ break;
+ }
+ tptr += len;
+ }
+
+ return;
+
+ trunc:
+ printf("[|udld]");
+}
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-udp.c b/freebsd/contrib/tcpdump/print-udp.c
new file mode 100644
index 00000000..fa419fb8
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-udp.c
@@ -0,0 +1,693 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-udp.c,v 1.142 2007-08-08 17:20:58 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#ifdef SEGSIZE
+#undef SEGSIZE
+#endif
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+#include "appletalk.h"
+
+#include "udp.h"
+
+#include "ip.h"
+#ifdef INET6
+#include "ip6.h"
+#endif
+#include "ipproto.h"
+#include "rpc_auth.h"
+#include "rpc_msg.h"
+
+#include "nameser.h"
+#include "nfs.h"
+#include "bootp.h"
+
+struct rtcphdr {
+ u_int16_t rh_flags; /* T:2 P:1 CNT:5 PT:8 */
+ u_int16_t rh_len; /* length of message (in words) */
+ u_int32_t rh_ssrc; /* synchronization src id */
+};
+
+typedef struct {
+ u_int32_t upper; /* more significant 32 bits */
+ u_int32_t lower; /* less significant 32 bits */
+} ntp64;
+
+/*
+ * Sender report.
+ */
+struct rtcp_sr {
+ ntp64 sr_ntp; /* 64-bit ntp timestamp */
+ u_int32_t sr_ts; /* reference media timestamp */
+ u_int32_t sr_np; /* no. packets sent */
+ u_int32_t sr_nb; /* no. bytes sent */
+};
+
+/*
+ * Receiver report.
+ * Time stamps are middle 32-bits of ntp timestamp.
+ */
+struct rtcp_rr {
+ u_int32_t rr_srcid; /* sender being reported */
+ u_int32_t rr_nl; /* no. packets lost */
+ u_int32_t rr_ls; /* extended last seq number received */
+ u_int32_t rr_dv; /* jitter (delay variance) */
+ u_int32_t rr_lsr; /* orig. ts from last rr from this src */
+ u_int32_t rr_dlsr; /* time from recpt of last rr to xmit time */
+};
+
+/*XXX*/
+#define RTCP_PT_SR 200
+#define RTCP_PT_RR 201
+#define RTCP_PT_SDES 202
+#define RTCP_SDES_CNAME 1
+#define RTCP_SDES_NAME 2
+#define RTCP_SDES_EMAIL 3
+#define RTCP_SDES_PHONE 4
+#define RTCP_SDES_LOC 5
+#define RTCP_SDES_TOOL 6
+#define RTCP_SDES_NOTE 7
+#define RTCP_SDES_PRIV 8
+#define RTCP_PT_BYE 203
+#define RTCP_PT_APP 204
+
+static void
+vat_print(const void *hdr, register const struct udphdr *up)
+{
+ /* vat/vt audio */
+ u_int ts = *(u_int16_t *)hdr;
+ if ((ts & 0xf060) != 0) {
+ /* probably vt */
+ (void)printf("udp/vt %u %d / %d",
+ (u_int32_t)(EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up)),
+ ts & 0x3ff, ts >> 10);
+ } else {
+ /* probably vat */
+ u_int32_t i0 = EXTRACT_32BITS(&((u_int *)hdr)[0]);
+ u_int32_t i1 = EXTRACT_32BITS(&((u_int *)hdr)[1]);
+ printf("udp/vat %u c%d %u%s",
+ (u_int32_t)(EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up) - 8),
+ i0 & 0xffff,
+ i1, i0 & 0x800000? "*" : "");
+ /* audio format */
+ if (i0 & 0x1f0000)
+ printf(" f%d", (i0 >> 16) & 0x1f);
+ if (i0 & 0x3f000000)
+ printf(" s%d", (i0 >> 24) & 0x3f);
+ }
+}
+
+static void
+rtp_print(const void *hdr, u_int len, register const struct udphdr *up)
+{
+ /* rtp v1 or v2 */
+ u_int *ip = (u_int *)hdr;
+ u_int hasopt, hasext, contype, hasmarker;
+ u_int32_t i0 = EXTRACT_32BITS(&((u_int *)hdr)[0]);
+ u_int32_t i1 = EXTRACT_32BITS(&((u_int *)hdr)[1]);
+ u_int dlen = EXTRACT_16BITS(&up->uh_ulen) - sizeof(*up) - 8;
+ const char * ptype;
+
+ ip += 2;
+ len >>= 2;
+ len -= 2;
+ hasopt = 0;
+ hasext = 0;
+ if ((i0 >> 30) == 1) {
+ /* rtp v1 */
+ hasopt = i0 & 0x800000;
+ contype = (i0 >> 16) & 0x3f;
+ hasmarker = i0 & 0x400000;
+ ptype = "rtpv1";
+ } else {
+ /* rtp v2 */
+ hasext = i0 & 0x10000000;
+ contype = (i0 >> 16) & 0x7f;
+ hasmarker = i0 & 0x800000;
+ dlen -= 4;
+ ptype = "rtp";
+ ip += 1;
+ len -= 1;
+ }
+ printf("udp/%s %d c%d %s%s %d %u",
+ ptype,
+ dlen,
+ contype,
+ (hasopt || hasext)? "+" : "",
+ hasmarker? "*" : "",
+ i0 & 0xffff,
+ i1);
+ if (vflag) {
+ printf(" %u", EXTRACT_32BITS(&((u_int *)hdr)[2]));
+ if (hasopt) {
+ u_int i2, optlen;
+ do {
+ i2 = ip[0];
+ optlen = (i2 >> 16) & 0xff;
+ if (optlen == 0 || optlen > len) {
+ printf(" !opt");
+ return;
+ }
+ ip += optlen;
+ len -= optlen;
+ } while ((int)i2 >= 0);
+ }
+ if (hasext) {
+ u_int i2, extlen;
+ i2 = ip[0];
+ extlen = (i2 & 0xffff) + 1;
+ if (extlen > len) {
+ printf(" !ext");
+ return;
+ }
+ ip += extlen;
+ }
+ if (contype == 0x1f) /*XXX H.261 */
+ printf(" 0x%04x", ip[0] >> 16);
+ }
+}
+
+static const u_char *
+rtcp_print(const u_char *hdr, const u_char *ep)
+{
+ /* rtp v2 control (rtcp) */
+ struct rtcp_rr *rr = 0;
+ struct rtcp_sr *sr;
+ struct rtcphdr *rh = (struct rtcphdr *)hdr;
+ u_int len;
+ u_int16_t flags;
+ int cnt;
+ double ts, dts;
+ if ((u_char *)(rh + 1) > ep) {
+ printf(" [|rtcp]");
+ return (ep);
+ }
+ len = (EXTRACT_16BITS(&rh->rh_len) + 1) * 4;
+ flags = EXTRACT_16BITS(&rh->rh_flags);
+ cnt = (flags >> 8) & 0x1f;
+ switch (flags & 0xff) {
+ case RTCP_PT_SR:
+ sr = (struct rtcp_sr *)(rh + 1);
+ printf(" sr");
+ if (len != cnt * sizeof(*rr) + sizeof(*sr) + sizeof(*rh))
+ printf(" [%d]", len);
+ if (vflag)
+ printf(" %u", EXTRACT_32BITS(&rh->rh_ssrc));
+ if ((u_char *)(sr + 1) > ep) {
+ printf(" [|rtcp]");
+ return (ep);
+ }
+ ts = (double)(EXTRACT_32BITS(&sr->sr_ntp.upper)) +
+ ((double)(EXTRACT_32BITS(&sr->sr_ntp.lower)) /
+ 4294967296.0);
+ printf(" @%.2f %u %up %ub", ts, EXTRACT_32BITS(&sr->sr_ts),
+ EXTRACT_32BITS(&sr->sr_np), EXTRACT_32BITS(&sr->sr_nb));
+ rr = (struct rtcp_rr *)(sr + 1);
+ break;
+ case RTCP_PT_RR:
+ printf(" rr");
+ if (len != cnt * sizeof(*rr) + sizeof(*rh))
+ printf(" [%d]", len);
+ rr = (struct rtcp_rr *)(rh + 1);
+ if (vflag)
+ printf(" %u", EXTRACT_32BITS(&rh->rh_ssrc));
+ break;
+ case RTCP_PT_SDES:
+ printf(" sdes %d", len);
+ if (vflag)
+ printf(" %u", EXTRACT_32BITS(&rh->rh_ssrc));
+ cnt = 0;
+ break;
+ case RTCP_PT_BYE:
+ printf(" bye %d", len);
+ if (vflag)
+ printf(" %u", EXTRACT_32BITS(&rh->rh_ssrc));
+ cnt = 0;
+ break;
+ default:
+ printf(" type-0x%x %d", flags & 0xff, len);
+ cnt = 0;
+ break;
+ }
+ if (cnt > 1)
+ printf(" c%d", cnt);
+ while (--cnt >= 0) {
+ if ((u_char *)(rr + 1) > ep) {
+ printf(" [|rtcp]");
+ return (ep);
+ }
+ if (vflag)
+ printf(" %u", EXTRACT_32BITS(&rr->rr_srcid));
+ ts = (double)(EXTRACT_32BITS(&rr->rr_lsr)) / 65536.;
+ dts = (double)(EXTRACT_32BITS(&rr->rr_dlsr)) / 65536.;
+ printf(" %ul %us %uj @%.2f+%.2f",
+ EXTRACT_32BITS(&rr->rr_nl) & 0x00ffffff,
+ EXTRACT_32BITS(&rr->rr_ls),
+ EXTRACT_32BITS(&rr->rr_dv), ts, dts);
+ }
+ return (hdr + len);
+}
+
+static int udp_cksum(register const struct ip *ip,
+ register const struct udphdr *up,
+ register u_int len)
+{
+ return (nextproto4_cksum(ip, (const u_int8_t *)(void *)up, len,
+ IPPROTO_UDP));
+}
+
+#ifdef INET6
+static int udp6_cksum(const struct ip6_hdr *ip6, const struct udphdr *up,
+ u_int len)
+{
+ return (nextproto6_cksum(ip6, (const u_int8_t *)(void *)up, len,
+ IPPROTO_UDP));
+}
+#endif
+
+static void
+udpipaddr_print(const struct ip *ip, int sport, int dport)
+{
+#ifdef INET6
+ const struct ip6_hdr *ip6;
+
+ if (IP_V(ip) == 6)
+ ip6 = (const struct ip6_hdr *)ip;
+ else
+ ip6 = NULL;
+
+ if (ip6) {
+ if (ip6->ip6_nxt == IPPROTO_UDP) {
+ if (sport == -1) {
+ (void)printf("%s > %s: ",
+ ip6addr_string(&ip6->ip6_src),
+ ip6addr_string(&ip6->ip6_dst));
+ } else {
+ (void)printf("%s.%s > %s.%s: ",
+ ip6addr_string(&ip6->ip6_src),
+ udpport_string(sport),
+ ip6addr_string(&ip6->ip6_dst),
+ udpport_string(dport));
+ }
+ } else {
+ if (sport != -1) {
+ (void)printf("%s > %s: ",
+ udpport_string(sport),
+ udpport_string(dport));
+ }
+ }
+ } else
+#endif /*INET6*/
+ {
+ if (ip->ip_p == IPPROTO_UDP) {
+ if (sport == -1) {
+ (void)printf("%s > %s: ",
+ ipaddr_string(&ip->ip_src),
+ ipaddr_string(&ip->ip_dst));
+ } else {
+ (void)printf("%s.%s > %s.%s: ",
+ ipaddr_string(&ip->ip_src),
+ udpport_string(sport),
+ ipaddr_string(&ip->ip_dst),
+ udpport_string(dport));
+ }
+ } else {
+ if (sport != -1) {
+ (void)printf("%s > %s: ",
+ udpport_string(sport),
+ udpport_string(dport));
+ }
+ }
+ }
+}
+
+void
+udp_print(register const u_char *bp, u_int length,
+ register const u_char *bp2, int fragmented)
+{
+ register const struct udphdr *up;
+ register const struct ip *ip;
+ register const u_char *cp;
+ register const u_char *ep = bp + length;
+ u_int16_t sport, dport, ulen;
+#ifdef INET6
+ register const struct ip6_hdr *ip6;
+#endif
+
+ if (ep > snapend)
+ ep = snapend;
+ up = (struct udphdr *)bp;
+ ip = (struct ip *)bp2;
+#ifdef INET6
+ if (IP_V(ip) == 6)
+ ip6 = (struct ip6_hdr *)bp2;
+ else
+ ip6 = NULL;
+#endif /*INET6*/
+ cp = (u_char *)(up + 1);
+ if (!TTEST(up->uh_dport)) {
+ udpipaddr_print(ip, -1, -1);
+ (void)printf("[|udp]");
+ return;
+ }
+
+ sport = EXTRACT_16BITS(&up->uh_sport);
+ dport = EXTRACT_16BITS(&up->uh_dport);
+
+ if (length < sizeof(struct udphdr)) {
+ udpipaddr_print(ip, sport, dport);
+ (void)printf("truncated-udp %d", length);
+ return;
+ }
+ length -= sizeof(struct udphdr);
+
+ if (cp > snapend) {
+ udpipaddr_print(ip, sport, dport);
+ (void)printf("[|udp]");
+ return;
+ }
+
+ ulen = EXTRACT_16BITS(&up->uh_ulen);
+ if (ulen < 8) {
+ udpipaddr_print(ip, sport, dport);
+ (void)printf("truncated-udplength %d", ulen);
+ return;
+ }
+ if (packettype) {
+ register struct sunrpc_msg *rp;
+ enum sunrpc_msg_type direction;
+
+ switch (packettype) {
+
+ case PT_VAT:
+ udpipaddr_print(ip, sport, dport);
+ vat_print((void *)(up + 1), up);
+ break;
+
+ case PT_WB:
+ udpipaddr_print(ip, sport, dport);
+ wb_print((void *)(up + 1), length);
+ break;
+
+ case PT_RPC:
+ rp = (struct sunrpc_msg *)(up + 1);
+ direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction);
+#ifndef __rtems__
+ if (direction == SUNRPC_CALL)
+ sunrpcrequest_print((u_char *)rp, length,
+ (u_char *)ip);
+ else
+#endif
+ nfsreply_print((u_char *)rp, length,
+ (u_char *)ip); /*XXX*/
+ break;
+
+ case PT_RTP:
+ udpipaddr_print(ip, sport, dport);
+ rtp_print((void *)(up + 1), length, up);
+ break;
+
+ case PT_RTCP:
+ udpipaddr_print(ip, sport, dport);
+ while (cp < ep)
+ cp = rtcp_print(cp, ep);
+ break;
+
+ case PT_SNMP:
+ udpipaddr_print(ip, sport, dport);
+ snmp_print((const u_char *)(up + 1), length);
+ break;
+
+ case PT_CNFP:
+ udpipaddr_print(ip, sport, dport);
+ cnfp_print(cp, (const u_char *)ip);
+ break;
+
+ case PT_TFTP:
+ udpipaddr_print(ip, sport, dport);
+ tftp_print(cp, length);
+ break;
+
+ case PT_AODV:
+ udpipaddr_print(ip, sport, dport);
+ aodv_print((const u_char *)(up + 1), length,
+#ifdef INET6
+ ip6 != NULL);
+#else
+ 0);
+#endif
+ break;
+
+ case PT_RADIUS:
+ udpipaddr_print(ip, sport, dport);
+ radius_print(cp, length);
+ break;
+
+ case PT_VXLAN:
+ udpipaddr_print(ip, sport, dport);
+ vxlan_print((const u_char *)(up + 1), length);
+ break;
+ }
+ return;
+ }
+
+ if (!qflag) {
+ register struct sunrpc_msg *rp;
+ enum sunrpc_msg_type direction;
+
+ rp = (struct sunrpc_msg *)(up + 1);
+ if (TTEST(rp->rm_direction)) {
+ direction = (enum sunrpc_msg_type)EXTRACT_32BITS(&rp->rm_direction);
+ if (dport == NFS_PORT && direction == SUNRPC_CALL) {
+ nfsreq_print((u_char *)rp, length,
+ (u_char *)ip);
+ return;
+ }
+ if (sport == NFS_PORT && direction == SUNRPC_REPLY) {
+ nfsreply_print((u_char *)rp, length,
+ (u_char *)ip);
+ return;
+ }
+#ifdef notdef
+ if (dport == SUNRPC_PORT && direction == SUNRPC_CALL) {
+ sunrpcrequest_print((u_char *)rp, length, (u_char *)ip);
+ return;
+ }
+#endif
+ }
+ if (TTEST(((struct LAP *)cp)->type) &&
+ ((struct LAP *)cp)->type == lapDDP &&
+ (atalk_port(sport) || atalk_port(dport))) {
+ if (vflag)
+ fputs("kip ", stdout);
+ llap_print(cp, length);
+ return;
+ }
+ }
+ udpipaddr_print(ip, sport, dport);
+
+ if (vflag && !Kflag && !fragmented) {
+ /* Check the checksum, if possible. */
+ u_int16_t sum, udp_sum;
+
+ /*
+ * XXX - do this even if vflag == 1?
+ * TCP does, and we do so for UDP-over-IPv6.
+ */
+ if (IP_V(ip) == 4 && (vflag > 1)) {
+ udp_sum = EXTRACT_16BITS(&up->uh_sum);
+ if (udp_sum == 0) {
+ (void)printf("[no cksum] ");
+ } else if (TTEST2(cp[0], length)) {
+ sum = udp_cksum(ip, up, length + sizeof(struct udphdr));
+
+ if (sum != 0) {
+ (void)printf("[bad udp cksum 0x%04x -> 0x%04x!] ",
+ udp_sum,
+ in_cksum_shouldbe(udp_sum, sum));
+ } else
+ (void)printf("[udp sum ok] ");
+ }
+ }
+#ifdef INET6
+ else if (IP_V(ip) == 6 && ip6->ip6_plen) {
+ /* for IPv6, UDP checksum is mandatory */
+ if (TTEST2(cp[0], length)) {
+ sum = udp6_cksum(ip6, up, length + sizeof(struct udphdr));
+ udp_sum = EXTRACT_16BITS(&up->uh_sum);
+
+ if (sum != 0) {
+ (void)printf("[bad udp cksum 0x%04x -> 0x%04x!] ",
+ udp_sum,
+ in_cksum_shouldbe(udp_sum, sum));
+ } else
+ (void)printf("[udp sum ok] ");
+ }
+ }
+#endif
+ }
+
+ if (!qflag) {
+#define ISPORT(p) (dport == (p) || sport == (p))
+ if (ISPORT(NAMESERVER_PORT))
+ ns_print((const u_char *)(up + 1), length, 0);
+ else if (ISPORT(MULTICASTDNS_PORT))
+ ns_print((const u_char *)(up + 1), length, 1);
+ else if (ISPORT(TIMED_PORT))
+ timed_print((const u_char *)(up + 1));
+ else if (ISPORT(TFTP_PORT))
+ tftp_print((const u_char *)(up + 1), length);
+ else if (ISPORT(IPPORT_BOOTPC) || ISPORT(IPPORT_BOOTPS))
+ bootp_print((const u_char *)(up + 1), length);
+ else if (ISPORT(RIP_PORT))
+ rip_print((const u_char *)(up + 1), length);
+ else if (ISPORT(AODV_PORT))
+ aodv_print((const u_char *)(up + 1), length,
+#ifdef INET6
+ ip6 != NULL);
+#else
+ 0);
+#endif
+ else if (ISPORT(ISAKMP_PORT))
+ isakmp_print(gndo, (const u_char *)(up + 1), length, bp2);
+ else if (ISPORT(ISAKMP_PORT_NATT))
+ isakmp_rfc3948_print(gndo, (const u_char *)(up + 1), length, bp2);
+#if 1 /*???*/
+ else if (ISPORT(ISAKMP_PORT_USER1) || ISPORT(ISAKMP_PORT_USER2))
+ isakmp_print(gndo, (const u_char *)(up + 1), length, bp2);
+#endif
+ else if (ISPORT(SNMP_PORT) || ISPORT(SNMPTRAP_PORT))
+ snmp_print((const u_char *)(up + 1), length);
+ else if (ISPORT(NTP_PORT))
+ ntp_print((const u_char *)(up + 1), length);
+ else if (ISPORT(KERBEROS_PORT) || ISPORT(KERBEROS_SEC_PORT))
+ krb_print((const void *)(up + 1));
+ else if (ISPORT(L2TP_PORT))
+ l2tp_print((const u_char *)(up + 1), length);
+#ifdef TCPDUMP_DO_SMB
+ else if (ISPORT(NETBIOS_NS_PORT))
+ nbt_udp137_print((const u_char *)(up + 1), length);
+ else if (ISPORT(NETBIOS_DGRAM_PORT))
+ nbt_udp138_print((const u_char *)(up + 1), length);
+#endif
+ else if (dport == 3456)
+ vat_print((const void *)(up + 1), up);
+ else if (ISPORT(ZEPHYR_SRV_PORT) || ISPORT(ZEPHYR_CLT_PORT))
+ zephyr_print((const void *)(up + 1), length);
+ /*
+ * Since there are 10 possible ports to check, I think
+ * a <> test would be more efficient
+ */
+ else if ((sport >= RX_PORT_LOW && sport <= RX_PORT_HIGH) ||
+ (dport >= RX_PORT_LOW && dport <= RX_PORT_HIGH))
+ rx_print((const void *)(up + 1), length, sport, dport,
+ (u_char *) ip);
+#ifdef INET6
+ else if (ISPORT(RIPNG_PORT))
+ ripng_print((const u_char *)(up + 1), length);
+ else if (ISPORT(DHCP6_SERV_PORT) || ISPORT(DHCP6_CLI_PORT))
+ dhcp6_print((const u_char *)(up + 1), length);
+ else if (ISPORT(BABEL_PORT) || ISPORT(BABEL_PORT_OLD))
+ babel_print((const u_char *)(up + 1), length);
+#endif /*INET6*/
+ /*
+ * Kludge in test for whiteboard packets.
+ */
+ else if (dport == 4567)
+ wb_print((const void *)(up + 1), length);
+ else if (ISPORT(CISCO_AUTORP_PORT))
+ cisco_autorp_print((const void *)(up + 1), length);
+ else if (ISPORT(RADIUS_PORT) ||
+ ISPORT(RADIUS_NEW_PORT) ||
+ ISPORT(RADIUS_ACCOUNTING_PORT) ||
+ ISPORT(RADIUS_NEW_ACCOUNTING_PORT) )
+ radius_print((const u_char *)(up+1), length);
+ else if (dport == HSRP_PORT)
+ hsrp_print((const u_char *)(up + 1), length);
+ else if (ISPORT(LWRES_PORT))
+ lwres_print((const u_char *)(up + 1), length);
+ else if (ISPORT(LDP_PORT))
+ ldp_print((const u_char *)(up + 1), length);
+ else if (ISPORT(OLSR_PORT))
+ olsr_print((const u_char *)(up + 1), length,
+#if INET6
+ (IP_V(ip) == 6) ? 1 : 0);
+#else
+ 0);
+#endif
+ else if (ISPORT(MPLS_LSP_PING_PORT))
+ lspping_print((const u_char *)(up + 1), length);
+ else if (dport == BFD_CONTROL_PORT ||
+ dport == BFD_ECHO_PORT )
+ bfd_print((const u_char *)(up+1), length, dport);
+ else if (ISPORT(LMP_PORT))
+ lmp_print((const u_char *)(up + 1), length);
+ else if (ISPORT(VQP_PORT))
+ vqp_print((const u_char *)(up + 1), length);
+ else if (ISPORT(SFLOW_PORT))
+ sflow_print((const u_char *)(up + 1), length);
+ else if (dport == LWAPP_CONTROL_PORT)
+ lwapp_control_print((const u_char *)(up + 1), length, 1);
+ else if (sport == LWAPP_CONTROL_PORT)
+ lwapp_control_print((const u_char *)(up + 1), length, 0);
+ else if (ISPORT(LWAPP_DATA_PORT))
+ lwapp_data_print((const u_char *)(up + 1), length);
+ else if (ISPORT(SIP_PORT))
+ sip_print((const u_char *)(up + 1), length);
+ else if (ISPORT(SYSLOG_PORT))
+ syslog_print((const u_char *)(up + 1), length);
+ else if (ISPORT(OTV_PORT))
+ otv_print((const u_char *)(up + 1), length);
+ else
+ (void)printf("UDP, length %u",
+ (u_int32_t)(ulen - sizeof(*up)));
+#undef ISPORT
+ } else
+ (void)printf("UDP, length %u", (u_int32_t)(ulen - sizeof(*up)));
+}
+
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-usb.c b/freebsd/contrib/tcpdump/print-usb.c
new file mode 100644
index 00000000..393b66b5
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-usb.c
@@ -0,0 +1,176 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright 2009 Bert Vermeulen <bert@biot.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by Paolo Abeni.''
+ * The name of author may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Support for USB packets
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <pcap.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+
+
+#if defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX)
+#include <pcap/usb.h>
+
+/* returns direction: 1=inbound 2=outbound -1=invalid */
+static int
+get_direction(int transfer_type, int event_type)
+{
+ int direction;
+
+ direction = -1;
+ switch(transfer_type){
+ case URB_BULK:
+ case URB_CONTROL:
+ case URB_ISOCHRONOUS:
+ switch(event_type)
+ {
+ case URB_SUBMIT:
+ direction = 2;
+ break;
+ case URB_COMPLETE:
+ case URB_ERROR:
+ direction = 1;
+ break;
+ default:
+ direction = -1;
+ }
+ break;
+ case URB_INTERRUPT:
+ switch(event_type)
+ {
+ case URB_SUBMIT:
+ direction = 1;
+ break;
+ case URB_COMPLETE:
+ case URB_ERROR:
+ direction = 2;
+ break;
+ default:
+ direction = -1;
+ }
+ break;
+ default:
+ direction = -1;
+ }
+
+ return direction;
+}
+
+static void
+usb_header_print(const pcap_usb_header *uh)
+{
+ int direction;
+
+ switch(uh->transfer_type)
+ {
+ case URB_ISOCHRONOUS:
+ printf("ISOCHRONOUS");
+ break;
+ case URB_INTERRUPT:
+ printf("INTERRUPT");
+ break;
+ case URB_CONTROL:
+ printf("CONTROL");
+ break;
+ case URB_BULK:
+ printf("BULK");
+ break;
+ default:
+ printf(" ?");
+ }
+
+ switch(uh->event_type)
+ {
+ case URB_SUBMIT:
+ printf(" SUBMIT");
+ break;
+ case URB_COMPLETE:
+ printf(" COMPLETE");
+ break;
+ case URB_ERROR:
+ printf(" ERROR");
+ break;
+ default:
+ printf(" ?");
+ }
+
+ direction = get_direction(uh->transfer_type, uh->event_type);
+ if(direction == 1)
+ printf(" from");
+ else if(direction == 2)
+ printf(" to");
+ printf(" %d:%d:%d", uh->bus_id, uh->device_address, uh->endpoint_number & 0x7f);
+}
+
+/*
+ * This is the top level routine of the printer for captures with a
+ * 48-byte header.
+ *
+ * 'p' points to the header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ */
+u_int
+usb_linux_48_byte_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ if (h->caplen < sizeof(pcap_usb_header)) {
+ printf("[|usb]");
+ return(sizeof(pcap_usb_header));
+ }
+
+ usb_header_print((const pcap_usb_header *) p);
+
+ return(sizeof(pcap_usb_header));
+}
+
+#ifdef DLT_USB_LINUX_MMAPPED
+/*
+ * This is the top level routine of the printer for captures with a
+ * 64-byte header.
+ *
+ * 'p' points to the header of the packet, 'h->ts' is the timestamp,
+ * 'h->len' is the length of the packet off the wire, and 'h->caplen'
+ * is the number of bytes actually captured.
+ */
+u_int
+usb_linux_64_byte_print(const struct pcap_pkthdr *h, register const u_char *p)
+{
+ if (h->caplen < sizeof(pcap_usb_header_mmapped)) {
+ printf("[|usb]");
+ return(sizeof(pcap_usb_header_mmapped));
+ }
+
+ usb_header_print((const pcap_usb_header *) p);
+
+ return(sizeof(pcap_usb_header_mmapped));
+}
+#endif /* DLT_USB_LINUX_MMAPPED */
+
+#endif /* defined(HAVE_PCAP_USB_H) && defined(DLT_USB_LINUX) */
+
diff --git a/freebsd/contrib/tcpdump/print-vjc.c b/freebsd/contrib/tcpdump/print-vjc.c
new file mode 100644
index 00000000..05f3d3ea
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-vjc.c
@@ -0,0 +1,121 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-vjc.c,v 1.15 2004-03-25 03:31:17 mcr Exp $ (LBL)";
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <pcap.h>
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+
+#include "slcompress.h"
+#include "ppp.h"
+
+/*
+ * XXX - for BSD/OS PPP, what packets get supplied with a PPP header type
+ * of PPP_VJC and what packets get supplied with a PPP header type of
+ * PPP_VJNC? PPP_VJNC is for "UNCOMPRESSED_TCP" packets, and PPP_VJC
+ * is for COMPRESSED_TCP packets (PPP_IP is used for TYPE_IP packets).
+ *
+ * RFC 1144 implies that, on the wire, the packet type is *not* needed
+ * for PPP, as different PPP protocol types can be used; it only needs
+ * to be put on the wire for SLIP.
+ *
+ * It also indicates that, for compressed SLIP:
+ *
+ * If the COMPRESSED_TCP bit is set in the first byte, it's
+ * a COMPRESSED_TCP packet; that byte is the change byte, and
+ * the COMPRESSED_TCP bit, 0x80, isn't used in the change byte.
+ *
+ * If the upper 4 bits of the first byte are 7, it's an
+ * UNCOMPRESSED_TCP packet; that byte is the first byte of
+ * the UNCOMPRESSED_TCP modified IP header, with a connection
+ * number in the protocol field, and with the version field
+ * being 7, not 4.
+ *
+ * Otherwise, the packet is an IPv4 packet (where the upper 4 bits
+ * of the packet are 4).
+ *
+ * So this routine looks as if it's sort-of intended to handle
+ * compressed SLIP, although it doesn't handle UNCOMPRESSED_TCP
+ * correctly for that (it doesn't fix the version number and doesn't
+ * do anything to the protocol field), and doesn't check for COMPRESSED_TCP
+ * packets correctly for that (you only check the first bit - see
+ * B.1 in RFC 1144).
+ *
+ * But it's called for BSD/OS PPP, not SLIP - perhaps BSD/OS does weird
+ * things with the headers?
+ *
+ * Without a BSD/OS VJC-compressed PPP trace, or knowledge of what the
+ * BSD/OS VJC code does, we can't say what's the case.
+ *
+ * We therefore leave "proto" - which is the PPP protocol type - in place,
+ * *not* marked as unused, for now, so that GCC warnings about the
+ * unused argument remind us that we should fix this some day.
+ */
+int
+vjc_print(register const char *bp, u_short proto _U_)
+{
+ int i;
+
+ switch (bp[0] & 0xf0) {
+ case TYPE_IP:
+ if (eflag)
+ printf("(vjc type=IP) ");
+ return PPP_IP;
+ case TYPE_UNCOMPRESSED_TCP:
+ if (eflag)
+ printf("(vjc type=raw TCP) ");
+ return PPP_IP;
+ case TYPE_COMPRESSED_TCP:
+ if (eflag)
+ printf("(vjc type=compressed TCP) ");
+ for (i = 0; i < 8; i++) {
+ if (bp[1] & (0x80 >> i))
+ printf("%c", "?CI?SAWU"[i]);
+ }
+ if (bp[1])
+ printf(" ");
+ printf("C=0x%02x ", bp[2]);
+ printf("sum=0x%04x ", *(u_short *)&bp[3]);
+ return -1;
+ case TYPE_ERROR:
+ if (eflag)
+ printf("(vjc type=error) ");
+ return -1;
+ default:
+ if (eflag)
+ printf("(vjc type=0x%02x) ", bp[0] & 0xf0);
+ return -1;
+ }
+}
diff --git a/freebsd/contrib/tcpdump/print-vqp.c b/freebsd/contrib/tcpdump/print-vqp.c
new file mode 100644
index 00000000..4dcc385c
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-vqp.c
@@ -0,0 +1,211 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1998-2006 The TCPDUMP project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * support for the Cisco prop. VQP Protocol
+ *
+ * Original code by Carles Kishimoto <Carles.Kishimoto@bsc.es>
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-vqp.c,v 1.3 2006-08-19 06:51:13 guy Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+
+#define VQP_VERSION 1
+#define VQP_EXTRACT_VERSION(x) ((x)&0xFF)
+
+/*
+ * VQP common header
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Constant | Packet type | Error Code | nitems |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Packet Sequence Number (4 bytes) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+struct vqp_common_header_t {
+ u_int8_t version;
+ u_int8_t msg_type;
+ u_int8_t error_code;
+ u_int8_t nitems;
+ u_int8_t sequence[4];
+};
+
+struct vqp_obj_tlv_t {
+ u_int8_t obj_type[4];
+ u_int8_t obj_length[2];
+};
+
+#define VQP_OBJ_REQ_JOIN_PORT 0x01
+#define VQP_OBJ_RESP_VLAN 0x02
+#define VQP_OBJ_REQ_RECONFIRM 0x03
+#define VQP_OBJ_RESP_RECONFIRM 0x04
+
+static const struct tok vqp_msg_type_values[] = {
+ { VQP_OBJ_REQ_JOIN_PORT, "Request, Join Port"},
+ { VQP_OBJ_RESP_VLAN, "Response, VLAN"},
+ { VQP_OBJ_REQ_RECONFIRM, "Request, Reconfirm"},
+ { VQP_OBJ_RESP_RECONFIRM, "Response, Reconfirm"},
+ { 0, NULL}
+};
+
+static const struct tok vqp_error_code_values[] = {
+ { 0x00, "No error"},
+ { 0x03, "Access denied"},
+ { 0x04, "Shutdown port"},
+ { 0x05, "Wrong VTP domain"},
+ { 0, NULL}
+};
+
+/* FIXME the heading 0x0c looks ugly - those must be flags etc. */
+#define VQP_OBJ_IP_ADDRESS 0x0c01
+#define VQP_OBJ_PORT_NAME 0x0c02
+#define VQP_OBJ_VLAN_NAME 0x0c03
+#define VQP_OBJ_VTP_DOMAIN 0x0c04
+#define VQP_OBJ_ETHERNET_PKT 0x0c05
+#define VQP_OBJ_MAC_NULL 0x0c06
+#define VQP_OBJ_MAC_ADDRESS 0x0c08
+
+static const struct tok vqp_obj_values[] = {
+ { VQP_OBJ_IP_ADDRESS, "Client IP Address" },
+ { VQP_OBJ_PORT_NAME, "Port Name" },
+ { VQP_OBJ_VLAN_NAME, "VLAN Name" },
+ { VQP_OBJ_VTP_DOMAIN, "VTP Domain" },
+ { VQP_OBJ_ETHERNET_PKT, "Ethernet Packet" },
+ { VQP_OBJ_MAC_NULL, "MAC Null" },
+ { VQP_OBJ_MAC_ADDRESS, "MAC Address" },
+ { 0, NULL}
+};
+
+void
+vqp_print(register const u_char *pptr, register u_int len)
+{
+ const struct vqp_common_header_t *vqp_common_header;
+ const struct vqp_obj_tlv_t *vqp_obj_tlv;
+
+ const u_char *tptr;
+ u_int16_t vqp_obj_len;
+ u_int32_t vqp_obj_type;
+ int tlen;
+ u_int8_t nitems;
+
+ tptr=pptr;
+ tlen = len;
+ vqp_common_header = (const struct vqp_common_header_t *)pptr;
+ TCHECK(*vqp_common_header);
+
+ /*
+ * Sanity checking of the header.
+ */
+ if (VQP_EXTRACT_VERSION(vqp_common_header->version) != VQP_VERSION) {
+ printf("VQP version %u packet not supported",
+ VQP_EXTRACT_VERSION(vqp_common_header->version));
+ return;
+ }
+
+ /* in non-verbose mode just lets print the basic Message Type */
+ if (vflag < 1) {
+ printf("VQPv%u %s Message, error-code %s (%u), length %u",
+ VQP_EXTRACT_VERSION(vqp_common_header->version),
+ tok2str(vqp_msg_type_values, "unknown (%u)",vqp_common_header->msg_type),
+ tok2str(vqp_error_code_values, "unknown (%u)",vqp_common_header->error_code),
+ vqp_common_header->error_code,
+ len);
+ return;
+ }
+
+ /* ok they seem to want to know everything - lets fully decode it */
+ nitems = vqp_common_header->nitems;
+ printf("\n\tVQPv%u, %s Message, error-code %s (%u), seq 0x%08x, items %u, length %u",
+ VQP_EXTRACT_VERSION(vqp_common_header->version),
+ tok2str(vqp_msg_type_values, "unknown (%u)",vqp_common_header->msg_type),
+ tok2str(vqp_error_code_values, "unknown (%u)",vqp_common_header->error_code),
+ vqp_common_header->error_code,
+ EXTRACT_32BITS(&vqp_common_header->sequence),
+ nitems,
+ len);
+
+ /* skip VQP Common header */
+ tptr+=sizeof(const struct vqp_common_header_t);
+ tlen-=sizeof(const struct vqp_common_header_t);
+
+ while (nitems > 0 && tlen > 0) {
+
+ vqp_obj_tlv = (const struct vqp_obj_tlv_t *)tptr;
+ vqp_obj_type = EXTRACT_32BITS(vqp_obj_tlv->obj_type);
+ vqp_obj_len = EXTRACT_16BITS(vqp_obj_tlv->obj_length);
+ tptr+=sizeof(struct vqp_obj_tlv_t);
+ tlen-=sizeof(struct vqp_obj_tlv_t);
+
+ printf("\n\t %s Object (0x%08x), length %u, value: ",
+ tok2str(vqp_obj_values, "Unknown", vqp_obj_type),
+ vqp_obj_type, vqp_obj_len);
+
+ /* basic sanity check */
+ if (vqp_obj_type == 0 || vqp_obj_len ==0) {
+ return;
+ }
+
+ /* did we capture enough for fully decoding the object ? */
+ if (!TTEST2(*tptr, vqp_obj_len))
+ goto trunc;
+
+ switch(vqp_obj_type) {
+ case VQP_OBJ_IP_ADDRESS:
+ printf("%s (0x%08x)", ipaddr_string(tptr), EXTRACT_32BITS(tptr));
+ break;
+ /* those objects have similar semantics - fall through */
+ case VQP_OBJ_PORT_NAME:
+ case VQP_OBJ_VLAN_NAME:
+ case VQP_OBJ_VTP_DOMAIN:
+ case VQP_OBJ_ETHERNET_PKT:
+ safeputs((const char *)tptr, vqp_obj_len);
+ break;
+ /* those objects have similar semantics - fall through */
+ case VQP_OBJ_MAC_ADDRESS:
+ case VQP_OBJ_MAC_NULL:
+ printf("%s", etheraddr_string(tptr));
+ break;
+ default:
+ if (vflag <= 1)
+ print_unknown_data(tptr, "\n\t ", vqp_obj_len);
+ break;
+ }
+ tptr += vqp_obj_len;
+ tlen -= vqp_obj_len;
+ nitems--;
+ }
+ return;
+trunc:
+ printf("\n\t[|VQP]");
+}
diff --git a/freebsd/contrib/tcpdump/print-vrrp.c b/freebsd/contrib/tcpdump/print-vrrp.c
new file mode 100644
index 00000000..dcc7dfaa
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-vrrp.c
@@ -0,0 +1,149 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 2000 William C. Fenner.
+ * All rights reserved.
+ *
+ * Kevin Steves <ks@hp.se> July 2000
+ * Modified to:
+ * - print version, type string and packet length
+ * - print IP address count if > 1 (-v)
+ * - verify checksum (-v)
+ * - print authentication string (-v)
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * The name of William C. Fenner may not be used to endorse or
+ * promote products derived from this software without specific prior
+ * written permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-vrrp.c,v 1.10 2005-05-06 07:56:54 guy Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+
+/*
+ * RFC 2338:
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |Version| Type | Virtual Rtr ID| Priority | Count IP Addrs|
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Auth Type | Adver Int | Checksum |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | IP Address (1) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | . |
+ * | . |
+ * | . |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | IP Address (n) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Authentication Data (1) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Authentication Data (2) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+/* Type */
+#define VRRP_TYPE_ADVERTISEMENT 1
+
+static const struct tok type2str[] = {
+ { VRRP_TYPE_ADVERTISEMENT, "Advertisement" },
+ { 0, NULL }
+};
+
+/* Auth Type */
+#define VRRP_AUTH_NONE 0
+#define VRRP_AUTH_SIMPLE 1
+#define VRRP_AUTH_AH 2
+
+static const struct tok auth2str[] = {
+ { VRRP_AUTH_NONE, "none" },
+ { VRRP_AUTH_SIMPLE, "simple" },
+ { VRRP_AUTH_AH, "ah" },
+ { 0, NULL }
+};
+
+void
+vrrp_print(register const u_char *bp, register u_int len, int ttl)
+{
+ int version, type, auth_type;
+ const char *type_s;
+
+ TCHECK(bp[0]);
+ version = (bp[0] & 0xf0) >> 4;
+ type = bp[0] & 0x0f;
+ type_s = tok2str(type2str, "unknown type (%u)", type);
+ printf("VRRPv%u, %s", version, type_s);
+ if (ttl != 255)
+ printf(", (ttl %u)", ttl);
+ if (version != 2 || type != VRRP_TYPE_ADVERTISEMENT)
+ return;
+ TCHECK(bp[2]);
+ printf(", vrid %u, prio %u", bp[1], bp[2]);
+ TCHECK(bp[5]);
+ auth_type = bp[4];
+ printf(", authtype %s", tok2str(auth2str, NULL, auth_type));
+ printf(", intvl %us, length %u", bp[5],len);
+ if (vflag) {
+ int naddrs = bp[3];
+ int i;
+ char c;
+
+ if (TTEST2(bp[0], len)) {
+ struct cksum_vec vec[1];
+
+ vec[0].ptr = bp;
+ vec[0].len = len;
+ if (in_cksum(vec, 1))
+ printf(", (bad vrrp cksum %x)",
+ EXTRACT_16BITS(&bp[6]));
+ }
+ printf(", addrs");
+ if (naddrs > 1)
+ printf("(%d)", naddrs);
+ printf(":");
+ c = ' ';
+ bp += 8;
+ for (i = 0; i < naddrs; i++) {
+ TCHECK(bp[3]);
+ printf("%c%s", c, ipaddr_string(bp));
+ c = ',';
+ bp += 4;
+ }
+ if (auth_type == VRRP_AUTH_SIMPLE) { /* simple text password */
+ TCHECK(bp[7]);
+ printf(" auth \"");
+ if (fn_printn(bp, 8, snapend)) {
+ printf("\"");
+ goto trunc;
+ }
+ printf("\"");
+ }
+ }
+ return;
+trunc:
+ printf("[|vrrp]");
+}
diff --git a/freebsd/contrib/tcpdump/print-vtp.c b/freebsd/contrib/tcpdump/print-vtp.c
new file mode 100644
index 00000000..47afa101
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-vtp.c
@@ -0,0 +1,380 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1998-2007 The TCPDUMP project
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * VLAN TRUNKING PROTOCOL (VTP)
+ *
+ * Reference documentation:
+ * http://www.cisco.com/en/US/tech/tk389/tk689/technologies_tech_note09186a0080094c52.shtml
+ * http://www.cisco.com/warp/public/473/21.html
+ * http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm
+ *
+ * Original code ode by Carles Kishimoto <carles.kishimoto@gmail.com>
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+#include "nlpid.h"
+
+#define VTP_HEADER_LEN 36
+#define VTP_DOMAIN_NAME_LEN 32
+#define VTP_MD5_DIGEST_LEN 16
+#define VTP_UPDATE_TIMESTAMP_LEN 12
+#define VTP_VLAN_INFO_OFFSET 12
+
+#define VTP_SUMMARY_ADV 0x01
+#define VTP_SUBSET_ADV 0x02
+#define VTP_ADV_REQUEST 0x03
+#define VTP_JOIN_MESSAGE 0x04
+
+struct vtp_vlan_ {
+ u_int8_t len;
+ u_int8_t status;
+ u_int8_t type;
+ u_int8_t name_len;
+ u_int16_t vlanid;
+ u_int16_t mtu;
+ u_int32_t index;
+};
+
+static struct tok vtp_message_type_values[] = {
+ { VTP_SUMMARY_ADV, "Summary advertisement"},
+ { VTP_SUBSET_ADV, "Subset advertisement"},
+ { VTP_ADV_REQUEST, "Advertisement request"},
+ { VTP_JOIN_MESSAGE, "Join message"},
+ { 0, NULL }
+};
+
+static struct tok vtp_header_values[] = {
+ { 0x01, "Followers"}, /* On Summary advertisement, 3rd byte is Followers */
+ { 0x02, "Seq number"}, /* On Subset advertisement, 3rd byte is Sequence number */
+ { 0x03, "Rsvd"}, /* On Adver. requests 3rd byte is Rsvd */
+ { 0x04, "Rsvd"}, /* On Adver. requests 3rd byte is Rsvd */
+ { 0, NULL }
+};
+
+static struct tok vtp_vlan_type_values[] = {
+ { 0x01, "Ethernet"},
+ { 0x02, "FDDI"},
+ { 0x03, "TrCRF"},
+ { 0x04, "FDDI-net"},
+ { 0x05, "TrBRF"},
+ { 0, NULL }
+};
+
+static struct tok vtp_vlan_status[] = {
+ { 0x00, "Operational"},
+ { 0x01, "Suspended"},
+ { 0, NULL }
+};
+
+#define VTP_VLAN_SOURCE_ROUTING_RING_NUMBER 0x01
+#define VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER 0x02
+#define VTP_VLAN_STP_TYPE 0x03
+#define VTP_VLAN_PARENT_VLAN 0x04
+#define VTP_VLAN_TRANS_BRIDGED_VLAN 0x05
+#define VTP_VLAN_PRUNING 0x06
+#define VTP_VLAN_BRIDGE_TYPE 0x07
+#define VTP_VLAN_ARP_HOP_COUNT 0x08
+#define VTP_VLAN_STE_HOP_COUNT 0x09
+#define VTP_VLAN_BACKUP_CRF_MODE 0x0A
+
+static struct tok vtp_vlan_tlv_values[] = {
+ { VTP_VLAN_SOURCE_ROUTING_RING_NUMBER, "Source-Routing Ring Number TLV"},
+ { VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER, "Source-Routing Bridge Number TLV"},
+ { VTP_VLAN_STP_TYPE, "STP type TLV"},
+ { VTP_VLAN_PARENT_VLAN, "Parent VLAN TLV"},
+ { VTP_VLAN_TRANS_BRIDGED_VLAN, "Translationally bridged VLANs TLV"},
+ { VTP_VLAN_PRUNING, "Pruning TLV"},
+ { VTP_VLAN_BRIDGE_TYPE, "Bridge Type TLV"},
+ { VTP_VLAN_ARP_HOP_COUNT, "Max ARP Hop Count TLV"},
+ { VTP_VLAN_STE_HOP_COUNT, "Max STE Hop Count TLV"},
+ { VTP_VLAN_BACKUP_CRF_MODE, "Backup CRF Mode TLV"},
+ { 0, NULL }
+};
+
+static struct tok vtp_stp_type_values[] = {
+ { 1, "SRT"},
+ { 2, "SRB"},
+ { 3, "Auto"},
+ { 0, NULL }
+};
+
+void
+vtp_print (const u_char *pptr, u_int length)
+{
+ int type, len, tlv_len, tlv_value;
+ const u_char *tptr;
+ const struct vtp_vlan_ *vtp_vlan;
+
+ if (length < VTP_HEADER_LEN)
+ goto trunc;
+
+ tptr = pptr;
+
+ if (!TTEST2(*tptr, VTP_HEADER_LEN))
+ goto trunc;
+
+ type = *(tptr+1);
+ printf("VTPv%u, Message %s (0x%02x), length %u",
+ *tptr,
+ tok2str(vtp_message_type_values,"Unknown message type", type),
+ *(tptr+1),
+ length);
+
+ /* In non-verbose mode, just print version and message type */
+ if (vflag < 1) {
+ return;
+ }
+
+ /* verbose mode print all fields */
+ printf("\n\tDomain name: %s, %s: %u",
+ (tptr+4),
+ tok2str(vtp_header_values,"Unknown",*(tptr+1)),
+ *(tptr+2));
+
+ tptr += VTP_HEADER_LEN;
+
+ switch (type) {
+
+ case VTP_SUMMARY_ADV:
+
+ /*
+ * SUMMARY ADVERTISEMENT
+ *
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Version | Code | Followers | MmgtD Len |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Management Domain Name |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Configuration revision number |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Updater Identity IP address |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Update Timestamp (12 bytes) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | MD5 digest (16 bytes) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+ printf("\n\t Config Rev %x, Updater %s",
+ EXTRACT_32BITS(tptr),
+ ipaddr_string(tptr+4));
+ tptr += 8;
+ printf(", Timestamp 0x%08x 0x%08x 0x%08x",
+ EXTRACT_32BITS(tptr),
+ EXTRACT_32BITS(tptr + 4),
+ EXTRACT_32BITS(tptr + 8));
+ tptr += VTP_UPDATE_TIMESTAMP_LEN;
+ printf(", MD5 digest: %08x%08x%08x%08x",
+ EXTRACT_32BITS(tptr),
+ EXTRACT_32BITS(tptr + 4),
+ EXTRACT_32BITS(tptr + 8),
+ EXTRACT_32BITS(tptr + 12));
+ tptr += VTP_MD5_DIGEST_LEN;
+ break;
+
+ case VTP_SUBSET_ADV:
+
+ /*
+ * SUBSET ADVERTISEMENT
+ *
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Version | Code | Seq number | MmgtD Len |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Management Domain Name |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Configuration revision number |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | VLAN info field 1 |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | ................ |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | VLAN info field N |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+ printf(", Config Rev %x", EXTRACT_32BITS(tptr));
+
+ /*
+ * VLAN INFORMATION
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | V info len | Status | VLAN type | VLAN name len |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | ISL vlan id | MTU size |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | 802.10 index (SAID) |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | VLAN name |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+ tptr += 4;
+ while (tptr < (pptr+length)) {
+
+ len = *tptr;
+ if (len == 0)
+ break;
+
+ if (!TTEST2(*tptr, len))
+ goto trunc;
+
+ vtp_vlan = (struct vtp_vlan_*)tptr;
+ printf("\n\tVLAN info status %s, type %s, VLAN-id %u, MTU %u, SAID 0x%08x, Name %s",
+ tok2str(vtp_vlan_status,"Unknown",vtp_vlan->status),
+ tok2str(vtp_vlan_type_values,"Unknown",vtp_vlan->type),
+ EXTRACT_16BITS(&vtp_vlan->vlanid),
+ EXTRACT_16BITS(&vtp_vlan->mtu),
+ EXTRACT_32BITS(&vtp_vlan->index),
+ (tptr + VTP_VLAN_INFO_OFFSET));
+
+ /*
+ * Vlan names are aligned to 32-bit boundaries.
+ */
+ len -= VTP_VLAN_INFO_OFFSET + 4*((vtp_vlan->name_len + 3)/4);
+ tptr += VTP_VLAN_INFO_OFFSET + 4*((vtp_vlan->name_len + 3)/4);
+
+ /* TLV information follows */
+
+ while (len > 0) {
+
+ /*
+ * Cisco specs says 2 bytes for type + 2 bytes for length, take only 1
+ * See: http://www.cisco.com/univercd/cc/td/doc/product/lan/trsrb/frames.htm
+ */
+ type = *tptr;
+ tlv_len = *(tptr+1);
+
+ printf("\n\t\t%s (0x%04x) TLV",
+ tok2str(vtp_vlan_tlv_values, "Unknown", type),
+ type);
+
+ /*
+ * infinite loop check
+ */
+ if (type == 0 || tlv_len == 0) {
+ return;
+ }
+
+ if (!TTEST2(*tptr, tlv_len*2 +2))
+ goto trunc;
+
+ tlv_value = EXTRACT_16BITS(tptr+2);
+
+ switch (type) {
+ case VTP_VLAN_STE_HOP_COUNT:
+ printf(", %u", tlv_value);
+ break;
+
+ case VTP_VLAN_PRUNING:
+ printf(", %s (%u)",
+ tlv_value == 1 ? "Enabled" : "Disabled",
+ tlv_value);
+ break;
+
+ case VTP_VLAN_STP_TYPE:
+ printf(", %s (%u)",
+ tok2str(vtp_stp_type_values, "Unknown", tlv_value),
+ tlv_value);
+ break;
+
+ case VTP_VLAN_BRIDGE_TYPE:
+ printf(", %s (%u)",
+ tlv_value == 1 ? "SRB" : "SRT",
+ tlv_value);
+ break;
+
+ case VTP_VLAN_BACKUP_CRF_MODE:
+ printf(", %s (%u)",
+ tlv_value == 1 ? "Backup" : "Not backup",
+ tlv_value);
+ break;
+
+ /*
+ * FIXME those are the defined TLVs that lack a decoder
+ * you are welcome to contribute code ;-)
+ */
+
+ case VTP_VLAN_SOURCE_ROUTING_RING_NUMBER:
+ case VTP_VLAN_SOURCE_ROUTING_BRIDGE_NUMBER:
+ case VTP_VLAN_PARENT_VLAN:
+ case VTP_VLAN_TRANS_BRIDGED_VLAN:
+ case VTP_VLAN_ARP_HOP_COUNT:
+ default:
+ print_unknown_data(tptr, "\n\t\t ", 2 + tlv_len*2);
+ break;
+ }
+ len -= 2 + tlv_len*2;
+ tptr += 2 + tlv_len*2;
+ }
+ }
+ break;
+
+ case VTP_ADV_REQUEST:
+
+ /*
+ * ADVERTISEMENT REQUEST
+ *
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Version | Code | Reserved | MmgtD Len |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Management Domain Name |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | Start value |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *
+ */
+
+ printf("\n\tStart value: %u", EXTRACT_32BITS(tptr));
+ break;
+
+ case VTP_JOIN_MESSAGE:
+
+ /* FIXME - Could not find message format */
+ break;
+
+ default:
+ break;
+ }
+
+ return;
+
+ trunc:
+ printf("[|vtp]");
+}
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/print-vxlan.c b/freebsd/contrib/tcpdump/print-vxlan.c
new file mode 100644
index 00000000..41ad613c
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-vxlan.c
@@ -0,0 +1,76 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Original code by Francesco Fondelli (francesco dot fondelli, gmail dot com)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+
+#include "udp.h"
+
+/*
+ * VXLAN header, draft-mahalingam-dutt-dcops-vxlan-03
+ *
+ * 0 1 2 3
+ * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * |R|R|R|R|I|R|R|R| Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ * | VXLAN Network Identifier (VNI) | Reserved |
+ * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ */
+
+void
+vxlan_print(const u_char *bp, u_int len)
+{
+ u_int8_t flags;
+ u_int32_t vni;
+
+ if (len < 8) {
+ printf("[|VXLAN]");
+ return;
+ }
+
+ flags = *bp;
+ bp += 4;
+
+ vni = EXTRACT_24BITS(bp);
+ bp += 4;
+
+ printf("VXLAN, ");
+
+ fputs("flags [", stdout);
+ if (flags & 0x08)
+ fputs("I", stdout);
+ else
+ fputs(".", stdout);
+ fputs("] ", stdout);
+
+ printf("(0x%02x), ", flags);
+ printf("vni %u\n", vni);
+
+ ether_print(gndo, bp, len - 8, len - 8, NULL, NULL);
+ return;
+}
diff --git a/freebsd/contrib/tcpdump/print-wb.c b/freebsd/contrib/tcpdump/print-wb.c
new file mode 100644
index 00000000..1bcf4b65
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-wb.c
@@ -0,0 +1,446 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1993, 1994, 1995, 1996
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-wb.c,v 1.33 2004-03-24 04:06:28 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "addrtoname.h"
+#include "extract.h"
+
+/* XXX need to add byte-swapping macros! */
+/* XXX - you mean like the ones in "extract.h"? */
+
+/*
+ * Largest packet size. Everything should fit within this space.
+ * For instance, multiline objects are sent piecewise.
+ */
+#define MAXFRAMESIZE 1024
+
+/*
+ * Multiple drawing ops can be sent in one packet. Each one starts on a
+ * an even multiple of DOP_ALIGN bytes, which must be a power of two.
+ */
+#define DOP_ALIGN 4
+#define DOP_ROUNDUP(x) ((((int)(x)) + (DOP_ALIGN - 1)) & ~(DOP_ALIGN - 1))
+#define DOP_NEXT(d)\
+ ((struct dophdr *)((u_char *)(d) + \
+ DOP_ROUNDUP(EXTRACT_16BITS(&(d)->dh_len) + sizeof(*(d)))))
+
+/*
+ * Format of the whiteboard packet header.
+ * The transport level header.
+ */
+struct pkt_hdr {
+ u_int32_t ph_src; /* site id of source */
+ u_int32_t ph_ts; /* time stamp (for skew computation) */
+ u_int16_t ph_version; /* version number */
+ u_char ph_type; /* message type */
+ u_char ph_flags; /* message flags */
+};
+
+/* Packet types */
+#define PT_DRAWOP 0 /* drawing operation */
+#define PT_ID 1 /* announcement packet */
+#define PT_RREQ 2 /* repair request */
+#define PT_RREP 3 /* repair reply */
+#define PT_KILL 4 /* terminate participation */
+#define PT_PREQ 5 /* page vector request */
+#define PT_PREP 7 /* page vector reply */
+
+#ifdef PF_USER
+#undef PF_USER /* {Digital,Tru64} UNIX define this, alas */
+#endif
+
+/* flags */
+#define PF_USER 0x01 /* hint that packet has interactive data */
+#define PF_VIS 0x02 /* only visible ops wanted */
+
+struct PageID {
+ u_int32_t p_sid; /* session id of initiator */
+ u_int32_t p_uid; /* page number */
+};
+
+struct dophdr {
+ u_int32_t dh_ts; /* sender's timestamp */
+ u_int16_t dh_len; /* body length */
+ u_char dh_flags;
+ u_char dh_type; /* body type */
+ /* body follows */
+};
+/*
+ * Drawing op sub-types.
+ */
+#define DT_RECT 2
+#define DT_LINE 3
+#define DT_ML 4
+#define DT_DEL 5
+#define DT_XFORM 6
+#define DT_ELL 7
+#define DT_CHAR 8
+#define DT_STR 9
+#define DT_NOP 10
+#define DT_PSCODE 11
+#define DT_PSCOMP 12
+#define DT_REF 13
+#define DT_SKIP 14
+#define DT_HOLE 15
+#define DT_MAXTYPE 15
+
+/*
+ * A drawing operation.
+ */
+struct pkt_dop {
+ struct PageID pd_page; /* page that operations apply to */
+ u_int32_t pd_sseq; /* start sequence number */
+ u_int32_t pd_eseq; /* end sequence number */
+ /* drawing ops follow */
+};
+
+/*
+ * A repair request.
+ */
+struct pkt_rreq {
+ u_int32_t pr_id; /* source id of drawops to be repaired */
+ struct PageID pr_page; /* page of drawops */
+ u_int32_t pr_sseq; /* start seqno */
+ u_int32_t pr_eseq; /* end seqno */
+};
+
+/*
+ * A repair reply.
+ */
+struct pkt_rrep {
+ u_int32_t pr_id; /* original site id of ops */
+ struct pkt_dop pr_dop;
+ /* drawing ops follow */
+};
+
+struct id_off {
+ u_int32_t id;
+ u_int32_t off;
+};
+
+struct pgstate {
+ u_int32_t slot;
+ struct PageID page;
+ u_int16_t nid;
+ u_int16_t rsvd;
+ /* seqptr's */
+};
+
+/*
+ * An announcement packet.
+ */
+struct pkt_id {
+ u_int32_t pi_mslot;
+ struct PageID pi_mpage; /* current page */
+ struct pgstate pi_ps;
+ /* seqptr's */
+ /* null-terminated site name */
+};
+
+struct pkt_preq {
+ struct PageID pp_page;
+ u_int32_t pp_low;
+ u_int32_t pp_high;
+};
+
+struct pkt_prep {
+ u_int32_t pp_n; /* size of pageid array */
+ /* pgstate's follow */
+};
+
+static int
+wb_id(const struct pkt_id *id, u_int len)
+{
+ int i;
+ const char *cp;
+ const struct id_off *io;
+ char c;
+ int nid;
+
+ printf(" wb-id:");
+ if (len < sizeof(*id) || (u_char *)(id + 1) > snapend)
+ return (-1);
+ len -= sizeof(*id);
+
+ printf(" %u/%s:%u (max %u/%s:%u) ",
+ EXTRACT_32BITS(&id->pi_ps.slot),
+ ipaddr_string(&id->pi_ps.page.p_sid),
+ EXTRACT_32BITS(&id->pi_ps.page.p_uid),
+ EXTRACT_32BITS(&id->pi_mslot),
+ ipaddr_string(&id->pi_mpage.p_sid),
+ EXTRACT_32BITS(&id->pi_mpage.p_uid));
+
+ nid = EXTRACT_16BITS(&id->pi_ps.nid);
+ len -= sizeof(*io) * nid;
+ io = (struct id_off *)(id + 1);
+ cp = (char *)(io + nid);
+ if ((u_char *)cp + len <= snapend) {
+ putchar('"');
+ (void)fn_print((u_char *)cp, (u_char *)cp + len);
+ putchar('"');
+ }
+
+ c = '<';
+ for (i = 0; i < nid && (u_char *)(io + 1) <= snapend; ++io, ++i) {
+ printf("%c%s:%u",
+ c, ipaddr_string(&io->id), EXTRACT_32BITS(&io->off));
+ c = ',';
+ }
+ if (i >= nid) {
+ printf(">");
+ return (0);
+ }
+ return (-1);
+}
+
+static int
+wb_rreq(const struct pkt_rreq *rreq, u_int len)
+{
+ printf(" wb-rreq:");
+ if (len < sizeof(*rreq) || (u_char *)(rreq + 1) > snapend)
+ return (-1);
+
+ printf(" please repair %s %s:%u<%u:%u>",
+ ipaddr_string(&rreq->pr_id),
+ ipaddr_string(&rreq->pr_page.p_sid),
+ EXTRACT_32BITS(&rreq->pr_page.p_uid),
+ EXTRACT_32BITS(&rreq->pr_sseq),
+ EXTRACT_32BITS(&rreq->pr_eseq));
+ return (0);
+}
+
+static int
+wb_preq(const struct pkt_preq *preq, u_int len)
+{
+ printf(" wb-preq:");
+ if (len < sizeof(*preq) || (u_char *)(preq + 1) > snapend)
+ return (-1);
+
+ printf(" need %u/%s:%u",
+ EXTRACT_32BITS(&preq->pp_low),
+ ipaddr_string(&preq->pp_page.p_sid),
+ EXTRACT_32BITS(&preq->pp_page.p_uid));
+ return (0);
+}
+
+static int
+wb_prep(const struct pkt_prep *prep, u_int len)
+{
+ int n;
+ const struct pgstate *ps;
+ const u_char *ep = snapend;
+
+ printf(" wb-prep:");
+ if (len < sizeof(*prep)) {
+ return (-1);
+ }
+ n = EXTRACT_32BITS(&prep->pp_n);
+ ps = (const struct pgstate *)(prep + 1);
+ while (--n >= 0 && (u_char *)(ps + 1) <= ep) {
+ const struct id_off *io, *ie;
+ char c = '<';
+
+ printf(" %u/%s:%u",
+ EXTRACT_32BITS(&ps->slot),
+ ipaddr_string(&ps->page.p_sid),
+ EXTRACT_32BITS(&ps->page.p_uid));
+ io = (struct id_off *)(ps + 1);
+ for (ie = io + ps->nid; io < ie && (u_char *)(io + 1) <= ep; ++io) {
+ printf("%c%s:%u", c, ipaddr_string(&io->id),
+ EXTRACT_32BITS(&io->off));
+ c = ',';
+ }
+ printf(">");
+ ps = (struct pgstate *)io;
+ }
+ return ((u_char *)ps <= ep? 0 : -1);
+}
+
+
+const char *dopstr[] = {
+ "dop-0!",
+ "dop-1!",
+ "RECT",
+ "LINE",
+ "ML",
+ "DEL",
+ "XFORM",
+ "ELL",
+ "CHAR",
+ "STR",
+ "NOP",
+ "PSCODE",
+ "PSCOMP",
+ "REF",
+ "SKIP",
+ "HOLE",
+};
+
+static int
+wb_dops(const struct dophdr *dh, u_int32_t ss, u_int32_t es)
+{
+ printf(" <");
+ for ( ; ss <= es; ++ss) {
+ register int t = dh->dh_type;
+
+ if (t > DT_MAXTYPE)
+ printf(" dop-%d!", t);
+ else {
+ printf(" %s", dopstr[t]);
+ if (t == DT_SKIP || t == DT_HOLE) {
+ u_int32_t ts = EXTRACT_32BITS(&dh->dh_ts);
+ printf("%d", ts - ss + 1);
+ if (ss > ts || ts > es) {
+ printf("[|]");
+ if (ts < ss)
+ return (0);
+ }
+ ss = ts;
+ }
+ }
+ dh = DOP_NEXT(dh);
+ if ((u_char *)dh > snapend) {
+ printf("[|wb]");
+ break;
+ }
+ }
+ printf(" >");
+ return (0);
+}
+
+static int
+wb_rrep(const struct pkt_rrep *rrep, u_int len)
+{
+ const struct pkt_dop *dop = &rrep->pr_dop;
+
+ printf(" wb-rrep:");
+ if (len < sizeof(*rrep) || (u_char *)(rrep + 1) > snapend)
+ return (-1);
+ len -= sizeof(*rrep);
+
+ printf(" for %s %s:%u<%u:%u>",
+ ipaddr_string(&rrep->pr_id),
+ ipaddr_string(&dop->pd_page.p_sid),
+ EXTRACT_32BITS(&dop->pd_page.p_uid),
+ EXTRACT_32BITS(&dop->pd_sseq),
+ EXTRACT_32BITS(&dop->pd_eseq));
+
+ if (vflag)
+ return (wb_dops((const struct dophdr *)(dop + 1),
+ EXTRACT_32BITS(&dop->pd_sseq),
+ EXTRACT_32BITS(&dop->pd_eseq)));
+ return (0);
+}
+
+static int
+wb_drawop(const struct pkt_dop *dop, u_int len)
+{
+ printf(" wb-dop:");
+ if (len < sizeof(*dop) || (u_char *)(dop + 1) > snapend)
+ return (-1);
+ len -= sizeof(*dop);
+
+ printf(" %s:%u<%u:%u>",
+ ipaddr_string(&dop->pd_page.p_sid),
+ EXTRACT_32BITS(&dop->pd_page.p_uid),
+ EXTRACT_32BITS(&dop->pd_sseq),
+ EXTRACT_32BITS(&dop->pd_eseq));
+
+ if (vflag)
+ return (wb_dops((const struct dophdr *)(dop + 1),
+ EXTRACT_32BITS(&dop->pd_sseq),
+ EXTRACT_32BITS(&dop->pd_eseq)));
+ return (0);
+}
+
+/*
+ * Print whiteboard multicast packets.
+ */
+void
+wb_print(register const void *hdr, register u_int len)
+{
+ register const struct pkt_hdr *ph;
+
+ ph = (const struct pkt_hdr *)hdr;
+ if (len < sizeof(*ph) || (u_char *)(ph + 1) > snapend) {
+ printf("[|wb]");
+ return;
+ }
+ len -= sizeof(*ph);
+
+ if (ph->ph_flags)
+ printf("*");
+ switch (ph->ph_type) {
+
+ case PT_KILL:
+ printf(" wb-kill");
+ return;
+
+ case PT_ID:
+ if (wb_id((struct pkt_id *)(ph + 1), len) >= 0)
+ return;
+ break;
+
+ case PT_RREQ:
+ if (wb_rreq((struct pkt_rreq *)(ph + 1), len) >= 0)
+ return;
+ break;
+
+ case PT_RREP:
+ if (wb_rrep((struct pkt_rrep *)(ph + 1), len) >= 0)
+ return;
+ break;
+
+ case PT_DRAWOP:
+ if (wb_drawop((struct pkt_dop *)(ph + 1), len) >= 0)
+ return;
+ break;
+
+ case PT_PREQ:
+ if (wb_preq((struct pkt_preq *)(ph + 1), len) >= 0)
+ return;
+ break;
+
+ case PT_PREP:
+ if (wb_prep((struct pkt_prep *)(ph + 1), len) >= 0)
+ return;
+ break;
+
+ default:
+ printf(" wb-%d!", ph->ph_type);
+ return;
+ }
+}
diff --git a/freebsd/contrib/tcpdump/print-zephyr.c b/freebsd/contrib/tcpdump/print-zephyr.c
new file mode 100644
index 00000000..7ed72118
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-zephyr.c
@@ -0,0 +1,324 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Decode and print Zephyr packets.
+ *
+ * http://web.mit.edu/zephyr/doc/protocol
+ *
+ * Copyright (c) 2001 Nickolai Zeldovich <kolya@MIT.EDU>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * The name of the author(s) may not be used to endorse or promote
+ * products derived from this software without specific prior written
+ * permission. THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/print-zephyr.c,v 1.10 2007-08-09 18:47:27 hannes Exp $";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "interface.h"
+
+struct z_packet {
+ char *version;
+ int numfields;
+ int kind;
+ char *uid;
+ int port;
+ int auth;
+ int authlen;
+ char *authdata;
+ char *class;
+ char *inst;
+ char *opcode;
+ char *sender;
+ const char *recipient;
+ char *format;
+ int cksum;
+ int multi;
+ char *multi_uid;
+ /* Other fields follow here.. */
+};
+
+enum z_packet_type {
+ Z_PACKET_UNSAFE = 0,
+ Z_PACKET_UNACKED,
+ Z_PACKET_ACKED,
+ Z_PACKET_HMACK,
+ Z_PACKET_HMCTL,
+ Z_PACKET_SERVACK,
+ Z_PACKET_SERVNAK,
+ Z_PACKET_CLIENTACK,
+ Z_PACKET_STAT
+};
+
+static struct tok z_types[] = {
+ { Z_PACKET_UNSAFE, "unsafe" },
+ { Z_PACKET_UNACKED, "unacked" },
+ { Z_PACKET_ACKED, "acked" },
+ { Z_PACKET_HMACK, "hm-ack" },
+ { Z_PACKET_HMCTL, "hm-ctl" },
+ { Z_PACKET_SERVACK, "serv-ack" },
+ { Z_PACKET_SERVNAK, "serv-nak" },
+ { Z_PACKET_CLIENTACK, "client-ack" },
+ { Z_PACKET_STAT, "stat" }
+};
+
+char z_buf[256];
+
+static char *
+parse_field(char **pptr, int *len)
+{
+ char *s;
+
+ if (*len <= 0 || !pptr || !*pptr)
+ return NULL;
+ if (*pptr > (char *) snapend)
+ return NULL;
+
+ s = *pptr;
+ while (*pptr <= (char *) snapend && *len >= 0 && **pptr) {
+ (*pptr)++;
+ (*len)--;
+ }
+ (*pptr)++;
+ (*len)--;
+ if (*len < 0 || *pptr > (char *) snapend)
+ return NULL;
+ return s;
+}
+
+static const char *
+z_triple(char *class, char *inst, const char *recipient)
+{
+ if (!*recipient)
+ recipient = "*";
+ snprintf(z_buf, sizeof(z_buf), "<%s,%s,%s>", class, inst, recipient);
+ z_buf[sizeof(z_buf)-1] = '\0';
+ return z_buf;
+}
+
+static const char *
+str_to_lower(char *string)
+{
+ strncpy(z_buf, string, sizeof(z_buf));
+ z_buf[sizeof(z_buf)-1] = '\0';
+
+ string = z_buf;
+ while (*string) {
+ *string = tolower((unsigned char)(*string));
+ string++;
+ }
+
+ return z_buf;
+}
+
+void
+zephyr_print(const u_char *cp, int length)
+{
+ struct z_packet z;
+ char *parse = (char *) cp;
+ int parselen = length;
+ char *s;
+ int lose = 0;
+
+ /* squelch compiler warnings */
+
+ z.kind = 0;
+ z.class = 0;
+ z.inst = 0;
+ z.opcode = 0;
+ z.sender = 0;
+ z.recipient = 0;
+
+#define PARSE_STRING \
+ s = parse_field(&parse, &parselen); \
+ if (!s) lose = 1;
+
+#define PARSE_FIELD_INT(field) \
+ PARSE_STRING \
+ if (!lose) field = strtol(s, 0, 16);
+
+#define PARSE_FIELD_STR(field) \
+ PARSE_STRING \
+ if (!lose) field = s;
+
+ PARSE_FIELD_STR(z.version);
+ if (lose) return;
+ if (strncmp(z.version, "ZEPH", 4))
+ return;
+
+ PARSE_FIELD_INT(z.numfields);
+ PARSE_FIELD_INT(z.kind);
+ PARSE_FIELD_STR(z.uid);
+ PARSE_FIELD_INT(z.port);
+ PARSE_FIELD_INT(z.auth);
+ PARSE_FIELD_INT(z.authlen);
+ PARSE_FIELD_STR(z.authdata);
+ PARSE_FIELD_STR(z.class);
+ PARSE_FIELD_STR(z.inst);
+ PARSE_FIELD_STR(z.opcode);
+ PARSE_FIELD_STR(z.sender);
+ PARSE_FIELD_STR(z.recipient);
+ PARSE_FIELD_STR(z.format);
+ PARSE_FIELD_INT(z.cksum);
+ PARSE_FIELD_INT(z.multi);
+ PARSE_FIELD_STR(z.multi_uid);
+
+ if (lose) {
+ printf(" [|zephyr] (%d)", length);
+ return;
+ }
+
+ printf(" zephyr");
+ if (strncmp(z.version+4, "0.2", 3)) {
+ printf(" v%s", z.version+4);
+ return;
+ }
+
+ printf(" %s", tok2str(z_types, "type %d", z.kind));
+ if (z.kind == Z_PACKET_SERVACK) {
+ /* Initialization to silence warnings */
+ char *ackdata = NULL;
+ PARSE_FIELD_STR(ackdata);
+ if (!lose && strcmp(ackdata, "SENT"))
+ printf("/%s", str_to_lower(ackdata));
+ }
+ if (*z.sender) printf(" %s", z.sender);
+
+ if (!strcmp(z.class, "USER_LOCATE")) {
+ if (!strcmp(z.opcode, "USER_HIDE"))
+ printf(" hide");
+ else if (!strcmp(z.opcode, "USER_UNHIDE"))
+ printf(" unhide");
+ else
+ printf(" locate %s", z.inst);
+ return;
+ }
+
+ if (!strcmp(z.class, "ZEPHYR_ADMIN")) {
+ printf(" zephyr-admin %s", str_to_lower(z.opcode));
+ return;
+ }
+
+ if (!strcmp(z.class, "ZEPHYR_CTL")) {
+ if (!strcmp(z.inst, "CLIENT")) {
+ if (!strcmp(z.opcode, "SUBSCRIBE") ||
+ !strcmp(z.opcode, "SUBSCRIBE_NODEFS") ||
+ !strcmp(z.opcode, "UNSUBSCRIBE")) {
+
+ printf(" %ssub%s", strcmp(z.opcode, "SUBSCRIBE") ? "un" : "",
+ strcmp(z.opcode, "SUBSCRIBE_NODEFS") ? "" :
+ "-nodefs");
+ if (z.kind != Z_PACKET_SERVACK) {
+ /* Initialization to silence warnings */
+ char *c = NULL, *i = NULL, *r = NULL;
+ PARSE_FIELD_STR(c);
+ PARSE_FIELD_STR(i);
+ PARSE_FIELD_STR(r);
+ if (!lose) printf(" %s", z_triple(c, i, r));
+ }
+ return;
+ }
+
+ if (!strcmp(z.opcode, "GIMME")) {
+ printf(" ret");
+ return;
+ }
+
+ if (!strcmp(z.opcode, "GIMMEDEFS")) {
+ printf(" gimme-defs");
+ return;
+ }
+
+ if (!strcmp(z.opcode, "CLEARSUB")) {
+ printf(" clear-subs");
+ return;
+ }
+
+ printf(" %s", str_to_lower(z.opcode));
+ return;
+ }
+
+ if (!strcmp(z.inst, "HM")) {
+ printf(" %s", str_to_lower(z.opcode));
+ return;
+ }
+
+ if (!strcmp(z.inst, "REALM")) {
+ if (!strcmp(z.opcode, "ADD_SUBSCRIBE"))
+ printf(" realm add-subs");
+ if (!strcmp(z.opcode, "REQ_SUBSCRIBE"))
+ printf(" realm req-subs");
+ if (!strcmp(z.opcode, "RLM_SUBSCRIBE"))
+ printf(" realm rlm-sub");
+ if (!strcmp(z.opcode, "RLM_UNSUBSCRIBE"))
+ printf(" realm rlm-unsub");
+ return;
+ }
+ }
+
+ if (!strcmp(z.class, "HM_CTL")) {
+ printf(" hm_ctl %s", str_to_lower(z.inst));
+ printf(" %s", str_to_lower(z.opcode));
+ return;
+ }
+
+ if (!strcmp(z.class, "HM_STAT")) {
+ if (!strcmp(z.inst, "HMST_CLIENT") && !strcmp(z.opcode, "GIMMESTATS")) {
+ printf(" get-client-stats");
+ return;
+ }
+ }
+
+ if (!strcmp(z.class, "WG_CTL")) {
+ printf(" wg_ctl %s", str_to_lower(z.inst));
+ printf(" %s", str_to_lower(z.opcode));
+ return;
+ }
+
+ if (!strcmp(z.class, "LOGIN")) {
+ if (!strcmp(z.opcode, "USER_FLUSH")) {
+ printf(" flush_locs");
+ return;
+ }
+
+ if (!strcmp(z.opcode, "NONE") ||
+ !strcmp(z.opcode, "OPSTAFF") ||
+ !strcmp(z.opcode, "REALM-VISIBLE") ||
+ !strcmp(z.opcode, "REALM-ANNOUNCED") ||
+ !strcmp(z.opcode, "NET-VISIBLE") ||
+ !strcmp(z.opcode, "NET-ANNOUNCED")) {
+ printf(" set-exposure %s", str_to_lower(z.opcode));
+ return;
+ }
+ }
+
+ if (!*z.recipient)
+ z.recipient = "*";
+
+ printf(" to %s", z_triple(z.class, z.inst, z.recipient));
+ if (*z.opcode)
+ printf(" op %s", z.opcode);
+ return;
+}
diff --git a/freebsd/contrib/tcpdump/print-zeromq.c b/freebsd/contrib/tcpdump/print-zeromq.c
new file mode 100644
index 00000000..ffd90bc1
--- /dev/null
+++ b/freebsd/contrib/tcpdump/print-zeromq.c
@@ -0,0 +1,150 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * This file implements decoding of ZeroMQ network protocol(s).
+ *
+ *
+ * Copyright (c) 2013 The TCPDUMP project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+
+#include "interface.h"
+#include "extract.h"
+
+/* Maximum number of ZMTP/1.0 frame body bytes (without the flags) to dump in
+ * hex and ASCII under a single "-v" flag.
+ */
+#define VBYTES 128
+
+/*
+ * Below is an excerpt from the "13/ZMTP" specification:
+ *
+ * A ZMTP message consists of 1 or more frames.
+ *
+ * A ZMTP frame consists of a length, followed by a flags field and a frame
+ * body of (length - 1) octets. Note: the length includes the flags field, so
+ * an empty frame has a length of 1.
+ *
+ * For frames with a length of 1 to 254 octets, the length SHOULD BE encoded
+ * as a single octet. The minimum valid length of a frame is 1 octet, thus a
+ * length of 0 is invalid and such frames SHOULD be discarded silently.
+ *
+ * For frames with lengths of 255 and greater, the length SHALL BE encoded as
+ * a single octet with the value 255, followed by the length encoded as a
+ * 64-bit unsigned integer in network byte order. For frames with lengths of
+ * 1 to 254 octets this encoding MAY be also used.
+ *
+ * The flags field consists of a single octet containing various control
+ * flags. Bit 0 is the least significant bit.
+ *
+ * - Bit 0 (MORE): More frames to follow. A value of 0 indicates that there
+ * are no more frames to follow. A value of 1 indicates that more frames
+ * will follow. On messages consisting of a single frame the MORE flag MUST
+ * be 0.
+ *
+ * - Bits 1-7: Reserved. Bits 1-7 are reserved for future use and SHOULD be
+ * zero.
+ */
+
+static const u_char *
+zmtp1_print_frame(const u_char *cp, const u_char *ep) {
+ u_int64_t body_len_declared, body_len_captured, header_len;
+ u_int8_t flags;
+
+ printf("\n\t");
+ TCHECK2(*cp, 1); /* length/0xFF */
+
+ if (cp[0] != 0xFF) {
+ header_len = 1; /* length */
+ body_len_declared = cp[0];
+ if (body_len_declared == 0)
+ return cp + header_len; /* skip to next frame */
+ printf(" frame flags+body (8-bit) length %"PRIu8"", cp[0]);
+ TCHECK2(*cp, header_len + 1); /* length, flags */
+ flags = cp[1];
+ } else {
+ header_len = 1 + 8; /* 0xFF, length */
+ printf(" frame flags+body (64-bit) length");
+ TCHECK2(*cp, header_len); /* 0xFF, length */
+ body_len_declared = EXTRACT_64BITS(cp + 1);
+ if (body_len_declared == 0)
+ return cp + header_len; /* skip to next frame */
+ printf(" %"PRIu64"", body_len_declared);
+ TCHECK2(*cp, header_len + 1); /* 0xFF, length, flags */
+ flags = cp[9];
+ }
+
+ body_len_captured = ep - cp - header_len;
+ if (body_len_declared > body_len_captured)
+ printf(" (%"PRIu64" captured)", body_len_captured);
+ printf(", flags 0x%02"PRIx8"", flags);
+
+ if (vflag) {
+ u_int64_t body_len_printed = MIN(body_len_captured, body_len_declared);
+
+ printf(" (%s|%s|%s|%s|%s|%s|%s|%s)",
+ flags & 0x80 ? "MBZ" : "-",
+ flags & 0x40 ? "MBZ" : "-",
+ flags & 0x20 ? "MBZ" : "-",
+ flags & 0x10 ? "MBZ" : "-",
+ flags & 0x08 ? "MBZ" : "-",
+ flags & 0x04 ? "MBZ" : "-",
+ flags & 0x02 ? "MBZ" : "-",
+ flags & 0x01 ? "MORE" : "-");
+
+ if (vflag == 1)
+ body_len_printed = MIN(VBYTES + 1, body_len_printed);
+ if (body_len_printed > 1) {
+ printf(", first %"PRIu64" byte(s) of body:", body_len_printed - 1);
+ hex_and_ascii_print("\n\t ", cp + header_len + 1, body_len_printed - 1);
+ printf("\n");
+ }
+ }
+
+ TCHECK2(*cp, header_len + body_len_declared); /* Next frame within the buffer ? */
+ return cp + header_len + body_len_declared;
+
+trunc:
+ printf(" [|zmtp1]");
+ return ep;
+}
+
+void
+zmtp1_print(const u_char *cp, u_int len) {
+ const u_char *ep = MIN(snapend, cp + len);
+
+ printf(": ZMTP/1.0");
+ while (cp < ep)
+ cp = zmtp1_print_frame(cp, ep);
+}
+
diff --git a/freebsd/contrib/tcpdump/route6d.h b/freebsd/contrib/tcpdump/route6d.h
new file mode 100644
index 00000000..53953fdb
--- /dev/null
+++ b/freebsd/contrib/tcpdump/route6d.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 1995, 1996, 1997 and 1998 WIDE Project.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+/*
+ * $Header: /tcpdump/master/tcpdump/route6d.h,v 1.5 2002-12-11 07:14:10 guy Exp $
+ */
+
+#define RIP6_VERSION 1
+
+#define RIP6_REQUEST 1
+#define RIP6_RESPONSE 2
+
+struct netinfo6 {
+ struct in6_addr rip6_dest;
+ u_int16_t rip6_tag;
+ u_int8_t rip6_plen;
+ u_int8_t rip6_metric;
+};
+
+struct rip6 {
+ u_int8_t rip6_cmd;
+ u_int8_t rip6_vers;
+ u_int8_t rip6_res1[2];
+ union {
+ struct netinfo6 ru6_nets[1];
+ char ru6_tracefile[1];
+ } rip6un;
+#define rip6_nets rip6un.ru6_nets
+#define rip6_tracefile rip6un.ru6_tracefile
+};
+
+#define HOPCNT_INFINITY6 16
+#define MAXRTE 24
+#define NEXTHOP_METRIC 0xff
+
+#ifndef DEBUG
+#define SUPPLY_INTERVAL6 30
+#define RIP_LIFETIME 180
+#define RIP_HOLDDOWN 120
+#define RIP_TRIG_INTERVAL6 5
+#define RIP_TRIG_INTERVAL6_MIN 1
+#else
+/* only for debugging; can not wait for 30sec to appear a bug */
+#define SUPPLY_INTERVAL6 10
+#define RIP_LIFETIME 60
+#define RIP_HOLDDOWN 40
+#define RIP_TRIG_INTERVAL6 5
+#define RIP_TRIG_INTERVAL6_MIN 1
+#endif
+
+#define RIP6_PORT 521
+#define RIP6_DEST "ff02::9"
diff --git a/freebsd/contrib/tcpdump/rpc_auth.h b/freebsd/contrib/tcpdump/rpc_auth.h
new file mode 100644
index 00000000..0e5a1c12
--- /dev/null
+++ b/freebsd/contrib/tcpdump/rpc_auth.h
@@ -0,0 +1,80 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/rpc_auth.h,v 1.2 2005-04-27 21:43:48 guy Exp $ (LBL) */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ *
+ * from: @(#)auth.h 1.17 88/02/08 SMI
+ * from: @(#)auth.h 2.3 88/08/07 4.0 RPCSRC
+ * $FreeBSD$
+ * FreeBSD: src/include/rpc/auth.h,v 1.14.2.1 1999/08/29 14:39:02 peter Exp
+ */
+
+/*
+ * auth.h, Authentication interface.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * The data structures are completely opaque to the client. The client
+ * is required to pass a AUTH * to routines that create rpc
+ * "sessions".
+ */
+
+/*
+ * Status returned from authentication check
+ */
+enum sunrpc_auth_stat {
+ SUNRPC_AUTH_OK=0,
+ /*
+ * failed at remote end
+ */
+ SUNRPC_AUTH_BADCRED=1, /* bogus credentials (seal broken) */
+ SUNRPC_AUTH_REJECTEDCRED=2, /* client should begin new session */
+ SUNRPC_AUTH_BADVERF=3, /* bogus verifier (seal broken) */
+ SUNRPC_AUTH_REJECTEDVERF=4, /* verifier expired or was replayed */
+ SUNRPC_AUTH_TOOWEAK=5, /* rejected due to security reasons */
+ /*
+ * failed locally
+ */
+ SUNRPC_AUTH_INVALIDRESP=6, /* bogus response verifier */
+ SUNRPC_AUTH_FAILED=7 /* some unknown reason */
+};
+
+/*
+ * Authentication info. Opaque to client.
+ */
+struct sunrpc_opaque_auth {
+ u_int32_t oa_flavor; /* flavor of auth */
+ u_int32_t oa_len; /* length of opaque body */
+ /* zero or more bytes of body */
+};
+
+#define SUNRPC_AUTH_NONE 0 /* no authentication */
+#define SUNRPC_AUTH_NULL 0 /* backward compatibility */
+#define SUNRPC_AUTH_UNIX 1 /* unix style (uid, gids) */
+#define SUNRPC_AUTH_SYS 1 /* forward compatibility */
+#define SUNRPC_AUTH_SHORT 2 /* short hand unix style */
+#define SUNRPC_AUTH_DES 3 /* des style (encrypted timestamps) */
diff --git a/freebsd/contrib/tcpdump/rpc_msg.h b/freebsd/contrib/tcpdump/rpc_msg.h
new file mode 100644
index 00000000..9c2770c2
--- /dev/null
+++ b/freebsd/contrib/tcpdump/rpc_msg.h
@@ -0,0 +1,129 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/rpc_msg.h,v 1.2 2005-04-27 21:43:48 guy Exp $ (LBL) */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part. Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California 94043
+ *
+ * from: @(#)rpc_msg.h 1.7 86/07/16 SMI
+ * from: @(#)rpc_msg.h 2.1 88/07/29 4.0 RPCSRC
+ * $FreeBSD$
+ * FreeBSD: src/include/rpc/rpc_msg.h,v 1.11.2.1 1999/08/29 14:39:07 peter Exp
+ */
+
+/*
+ * rpc_msg.h
+ * rpc message definition
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#define SUNRPC_MSG_VERSION ((u_int32_t) 2)
+
+/*
+ * Bottom up definition of an rpc message.
+ * NOTE: call and reply use the same overall stuct but
+ * different parts of unions within it.
+ */
+
+enum sunrpc_msg_type {
+ SUNRPC_CALL=0,
+ SUNRPC_REPLY=1
+};
+
+enum sunrpc_reply_stat {
+ SUNRPC_MSG_ACCEPTED=0,
+ SUNRPC_MSG_DENIED=1
+};
+
+enum sunrpc_accept_stat {
+ SUNRPC_SUCCESS=0,
+ SUNRPC_PROG_UNAVAIL=1,
+ SUNRPC_PROG_MISMATCH=2,
+ SUNRPC_PROC_UNAVAIL=3,
+ SUNRPC_GARBAGE_ARGS=4,
+ SUNRPC_SYSTEM_ERR=5
+};
+
+enum sunrpc_reject_stat {
+ SUNRPC_RPC_MISMATCH=0,
+ SUNRPC_AUTH_ERROR=1
+};
+
+/*
+ * Reply part of an rpc exchange
+ */
+
+/*
+ * Reply to an rpc request that was rejected by the server.
+ */
+struct sunrpc_rejected_reply {
+ u_int32_t rj_stat; /* enum reject_stat */
+ union {
+ struct {
+ u_int32_t low;
+ u_int32_t high;
+ } RJ_versions;
+ u_int32_t RJ_why; /* enum auth_stat - why authentication did not work */
+ } ru;
+#define rj_vers ru.RJ_versions
+#define rj_why ru.RJ_why
+};
+
+/*
+ * Body of a reply to an rpc request.
+ */
+struct sunrpc_reply_body {
+ u_int32_t rp_stat; /* enum reply_stat */
+ struct sunrpc_rejected_reply rp_reject; /* if rejected */
+};
+
+/*
+ * Body of an rpc request call.
+ */
+struct sunrpc_call_body {
+ u_int32_t cb_rpcvers; /* must be equal to two */
+ u_int32_t cb_prog;
+ u_int32_t cb_vers;
+ u_int32_t cb_proc;
+ struct sunrpc_opaque_auth cb_cred;
+ /* followed by opaque verifier */
+};
+
+/*
+ * The rpc message
+ */
+struct sunrpc_msg {
+ u_int32_t rm_xid;
+ u_int32_t rm_direction; /* enum msg_type */
+ union {
+ struct sunrpc_call_body RM_cmb;
+ struct sunrpc_reply_body RM_rmb;
+ } ru;
+#define rm_call ru.RM_cmb
+#define rm_reply ru.RM_rmb
+};
+#define acpted_rply ru.RM_rmb.ru.RP_ar
+#define rjcted_rply ru.RM_rmb.ru.RP_dr
diff --git a/freebsd/contrib/tcpdump/rx.h b/freebsd/contrib/tcpdump/rx.h
new file mode 100644
index 00000000..b79dd30c
--- /dev/null
+++ b/freebsd/contrib/tcpdump/rx.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright: (c) 2000 United States Government as represented by the
+ * Secretary of the Navy. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. The names of the authors may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+/*
+ * Rx protocol format
+ *
+ * $Id: rx.h,v 1.8 2002-12-11 07:14:11 guy Exp $
+ */
+
+#define FS_RX_PORT 7000
+#define CB_RX_PORT 7001
+#define PROT_RX_PORT 7002
+#define VLDB_RX_PORT 7003
+#define KAUTH_RX_PORT 7004
+#define VOL_RX_PORT 7005
+#define ERROR_RX_PORT 7006 /* Doesn't seem to be used */
+#define BOS_RX_PORT 7007
+
+#ifndef AFSNAMEMAX
+#define AFSNAMEMAX 256
+#endif
+
+#ifndef AFSOPAQUEMAX
+#define AFSOPAQUEMAX 1024
+#endif
+
+#define PRNAMEMAX 64
+#define VLNAMEMAX 65
+#define KANAMEMAX 64
+#define BOSNAMEMAX 256
+
+#define PRSFS_READ 1 /* Read files */
+#define PRSFS_WRITE 2 /* Write files */
+#define PRSFS_INSERT 4 /* Insert files into a directory */
+#define PRSFS_LOOKUP 8 /* Lookup files into a directory */
+#define PRSFS_DELETE 16 /* Delete files */
+#define PRSFS_LOCK 32 /* Lock files */
+#define PRSFS_ADMINISTER 64 /* Change ACL's */
+
+struct rx_header {
+ u_int32_t epoch;
+ u_int32_t cid;
+ u_int32_t callNumber;
+ u_int32_t seq;
+ u_int32_t serial;
+ u_int8_t type;
+#define RX_PACKET_TYPE_DATA 1
+#define RX_PACKET_TYPE_ACK 2
+#define RX_PACKET_TYPE_BUSY 3
+#define RX_PACKET_TYPE_ABORT 4
+#define RX_PACKET_TYPE_ACKALL 5
+#define RX_PACKET_TYPE_CHALLENGE 6
+#define RX_PACKET_TYPE_RESPONSE 7
+#define RX_PACKET_TYPE_DEBUG 8
+#define RX_PACKET_TYPE_PARAMS 9
+#define RX_PACKET_TYPE_VERSION 13
+ u_int8_t flags;
+#define RX_CLIENT_INITIATED 1
+#define RX_REQUEST_ACK 2
+#define RX_LAST_PACKET 4
+#define RX_MORE_PACKETS 8
+#define RX_FREE_PACKET 16
+#define RX_SLOW_START_OK 32
+#define RX_JUMBO_PACKET 32
+ u_int8_t userStatus;
+ u_int8_t securityIndex;
+ u_int16_t spare; /* How clever: even though the AFS */
+ u_int16_t serviceId; /* header files indicate that the */
+}; /* serviceId is first, it's really */
+ /* encoded _after_ the spare field */
+ /* I wasted a day figuring that out! */
+
+#define NUM_RX_FLAGS 7
+
+#define RX_MAXACKS 255
+
+struct rx_ackPacket {
+ u_int16_t bufferSpace; /* Number of packet buffers available */
+ u_int16_t maxSkew; /* Max diff between ack'd packet and */
+ /* highest packet received */
+ u_int32_t firstPacket; /* The first packet in ack list */
+ u_int32_t previousPacket; /* Previous packet recv'd (obsolete) */
+ u_int32_t serial; /* # of packet that prompted the ack */
+ u_int8_t reason; /* Reason for acknowledgement */
+ u_int8_t nAcks; /* Number of acknowledgements */
+ u_int8_t acks[RX_MAXACKS]; /* Up to RX_MAXACKS acknowledgements */
+};
+
+/*
+ * Values for the acks array
+ */
+
+#define RX_ACK_TYPE_NACK 0 /* Don't have this packet */
+#define RX_ACK_TYPE_ACK 1 /* I have this packet */
diff --git a/freebsd/contrib/tcpdump/sctpConstants.h b/freebsd/contrib/tcpdump/sctpConstants.h
new file mode 100644
index 00000000..ac28a151
--- /dev/null
+++ b/freebsd/contrib/tcpdump/sctpConstants.h
@@ -0,0 +1,571 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/sctpConstants.h,v 1.4 2003-06-03 23:49:23 guy Exp $ (LBL) */
+
+/* SCTP reference Implementation Copyright (C) 1999 Cisco And Motorola
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of Cisco nor of Motorola may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the SCTP reference Implementation
+ *
+ *
+ * Please send any bug reports or fixes you make to one of the following email
+ * addresses:
+ *
+ * rstewar1@email.mot.com
+ * kmorneau@cisco.com
+ * qxie1@email.mot.com
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorperated into the next SCTP release.
+ */
+
+
+#ifndef __sctpConstants_h__
+#define __sctpConstants_h__
+
+
+ /* If you wish to use MD5 instead of SLA uncomment the line
+ * below. Why you would like to do this:
+ * a) There may be IPR on SHA-1, or so the FIP-180-1 page says,
+ * b) MD5 is 3 times faster (has coded here).
+ *
+ * The disadvantage is, it is thought that MD5 has been
+ * cracked... see RFC2104.
+ */
+/*#define USE_MD5 1*/
+
+/* the SCTP protocol signature
+ * this includes the version number
+ * encoded in the last 4 bits of the
+ * signature.
+ */
+#define PROTO_SIGNATURE_A 0x30000000
+
+#define SCTP_VERSION_NUMBER 0x3
+
+#define MAX_TSN 0xffffffff
+#define MAX_SEQ 0xffff
+
+/* option:
+ * If you comment out the following you will
+ * receive the old behavior of obeying cwnd for
+ * the fast retransmit algorithm. With this defined
+ * a FR happens right away with-out waiting for the
+ * flightsize to drop below the cwnd value (which
+ * is reduced by the FR to 1/2 the inflight packets).
+ */
+#define SCTP_IGNORE_CWND_ON_FR 1
+/* default max I can burst out after a fast retransmit */
+#define SCTP_DEF_MAX_BURST 4
+
+/* Packet transmit states in the sent
+ * field in the SCTP_transmitOnQueue struct
+ */
+#define SCTP_DATAGRAM_UNSENT 0
+#define SCTP_DATAGRAM_SENT 1
+#define SCTP_DATAGRAM_RESEND1 2 /* not used */
+#define SCTP_DATAGRAM_RESEND2 3 /* not used */
+#define SCTP_DATAGRAM_RESEND3 4 /* not used */
+#define SCTP_DATAGRAM_RESEND 5
+#define SCTP_DATAGRAM_ACKED 10010
+#define SCTP_DATAGRAM_INBOUND 10011
+#define SCTP_READY_TO_TRANSMIT 10012
+#define SCTP_DATAGRAM_MARKED 20010
+
+#define MAX_FSID 64 /* debug 5 ints used for cc dynamic tracking */
+
+/* The valid defines for all message
+ * types know to SCTP. 0 is reserved
+ */
+#define SCTP_MSGTYPE_MASK 0xff
+
+#define SCTP_DATA 0x00
+#define SCTP_INITIATION 0x01
+#define SCTP_INITIATION_ACK 0x02
+#define SCTP_SELECTIVE_ACK 0x03
+#define SCTP_HEARTBEAT_REQUEST 0x04
+#define SCTP_HEARTBEAT_ACK 0x05
+#define SCTP_ABORT_ASSOCIATION 0x06
+#define SCTP_SHUTDOWN 0x07
+#define SCTP_SHUTDOWN_ACK 0x08
+#define SCTP_OPERATION_ERR 0x09
+#define SCTP_COOKIE_ECHO 0x0a
+#define SCTP_COOKIE_ACK 0x0b
+#define SCTP_ECN_ECHO 0x0c
+#define SCTP_ECN_CWR 0x0d
+#define SCTP_SHUTDOWN_COMPLETE 0x0e
+#define SCTP_FORWARD_CUM_TSN 0xc0
+#define SCTP_RELIABLE_CNTL 0xc1
+#define SCTP_RELIABLE_CNTL_ACK 0xc2
+
+/* ABORT and SHUTDOWN COMPLETE FLAG */
+#define SCTP_HAD_NO_TCB 0x01
+
+/* Data Chuck Specific Flags */
+#define SCTP_DATA_FRAG_MASK 0x03
+#define SCTP_DATA_MIDDLE_FRAG 0x00
+#define SCTP_DATA_LAST_FRAG 0x01
+#define SCTP_DATA_FIRST_FRAG 0x02
+#define SCTP_DATA_NOT_FRAG 0x03
+#define SCTP_DATA_UNORDERED 0x04
+
+#define SCTP_CRC_ENABLE_BIT 0x01 /* lower bit of reserved */
+
+#define isSCTPControl(a) (a->chunkID != SCTP_DATA)
+#define isSCTPData(a) (a->chunkID == SCTP_DATA)
+
+/* sctp parameter types for init/init-ack */
+
+#define SCTP_IPV4_PARAM_TYPE 0x0005
+#define SCTP_IPV6_PARAM_TYPE 0x0006
+#define SCTP_RESPONDER_COOKIE 0x0007
+#define SCTP_UNRECOG_PARAM 0x0008
+#define SCTP_COOKIE_PRESERVE 0x0009
+#define SCTP_HOSTNAME_VIA_DNS 0x000b
+#define SCTP_RESTRICT_ADDR_TO 0x000c
+
+#define SCTP_ECN_I_CAN_DO_ECN 0x8000
+#define SCTP_OPERATION_SUCCEED 0x4001
+#define SCTP_ERROR_NOT_EXECUTED 0x4002
+
+#define SCTP_UNRELIABLE_STRM 0xc000
+#define SCTP_ADD_IP_ADDRESS 0xc001
+#define SCTP_DEL_IP_ADDRESS 0xc002
+#define SCTP_STRM_FLOW_LIMIT 0xc003
+#define SCTP_PARTIAL_CSUM 0xc004
+#define SCTP_ERROR_CAUSE_TLV 0xc005
+#define SCTP_MIT_STACK_NAME 0xc006
+#define SCTP_SETADDRESS_PRIMARY 0xc007
+
+/* bits for TOS field */
+#define SCTP_ECT_BIT 0x02
+#define SCTP_CE_BIT 0x01
+
+/* error codes */
+#define SCTP_OP_ERROR_NO_ERROR 0x0000
+#define SCTP_OP_ERROR_INV_STRM 0x0001
+#define SCTP_OP_ERROR_MISS_PARAM 0x0002
+#define SCTP_OP_ERROR_STALE_COOKIE 0x0003
+#define SCTP_OP_ERROR_NO_RESOURCE 0x0004
+#define SCTP_OP_ERROR_DNS_FAILED 0x0005
+#define SCTP_OP_ERROR_UNK_CHUNK 0x0006
+#define SCTP_OP_ERROR_INV_PARAM 0x0007
+#define SCTP_OP_ERROR_UNK_PARAM 0x0008
+#define SCTP_OP_ERROR_NO_USERD 0x0009
+#define SCTP_OP_ERROR_COOKIE_SHUT 0x000a
+#define SCTP_OP_ERROR_DELETE_LAST 0x000b
+#define SCTP_OP_ERROR_RESOURCE_SHORT 0x000c
+
+#define SCTP_MAX_ERROR_CAUSE 12
+
+/* empty error causes i.e. nothing but the cause
+ * are SCTP_OP_ERROR_NO_RESOURCE, SCTP_OP_ERROR_INV_PARAM,
+ * SCTP_OP_ERROR_COOKIE_SHUT.
+ */
+
+/* parameter for Heart Beat */
+#define HEART_BEAT_PARAM 0x0001
+
+
+
+/* send options for SCTP
+ */
+#define SCTP_ORDERED_DELIVERY 0x01
+#define SCTP_NON_ORDERED_DELIVERY 0x02
+#define SCTP_DO_CRC16 0x08
+#define SCTP_MY_ADDRESS_ONLY 0x10
+
+/* below turns off above */
+#define SCTP_FLEXIBLE_ADDRESS 0x20
+#define SCTP_NO_HEARTBEAT 0x40
+
+/* mask to get sticky */
+#define SCTP_STICKY_OPTIONS_MASK 0x0c
+
+/* MTU discovery flags */
+#define SCTP_DONT_FRAGMENT 0x0100
+#define SCTP_FRAGMENT_OK 0x0200
+
+
+/* SCTP state defines for internal state machine */
+#define SCTP_STATE_EMPTY 0x0000
+#define SCTP_STATE_INUSE 0x0001
+#define SCTP_STATE_COOKIE_WAIT 0x0002
+#define SCTP_STATE_COOKIE_SENT 0x0004
+#define SCTP_STATE_OPEN 0x0008
+#define SCTP_STATE_SHUTDOWN 0x0010
+#define SCTP_STATE_SHUTDOWN_RECV 0x0020
+#define SCTP_STATE_SHUTDOWN_ACK_SENT 0x0040
+#define SCTP_STATE_SHUTDOWN_PEND 0x0080
+#define SCTP_STATE_MASK 0x007f
+/* SCTP reachability state for each address */
+#define SCTP_ADDR_NOT_REACHABLE 1
+#define SCTP_ADDR_REACHABLE 2
+#define SCTP_ADDR_NOHB 4
+#define SCTP_ADDR_BEING_DELETED 8
+
+/* How long a cookie lives */
+#define SCTP_DEFAULT_COOKIE_LIFE 60 /* seconds */
+
+/* resource limit of streams */
+#define MAX_SCTP_STREAMS 2048
+
+
+/* guess at how big to make the TSN mapping array */
+#define SCTP_STARTING_MAPARRAY 10000
+
+/* Here we define the timer types used
+ * by the implementation has
+ * arguments in the set/get timer type calls.
+ */
+#define SCTP_TIMER_INIT 0
+#define SCTP_TIMER_RECV 1
+#define SCTP_TIMER_SEND 2
+#define SCTP_TIMER_SHUTDOWN 3
+#define SCTP_TIMER_HEARTBEAT 4
+#define SCTP_TIMER_PMTU 5
+/* number of timer types in the base SCTP
+ * structure used in the set/get and has
+ * the base default.
+ */
+#define SCTP_NUM_TMRS 6
+
+
+
+#define SCTP_IPV4_ADDRESS 2
+#define SCTP_IPV6_ADDRESS 4
+
+/* timer types */
+#define SctpTimerTypeNone 0
+#define SctpTimerTypeSend 1
+#define SctpTimerTypeInit 2
+#define SctpTimerTypeRecv 3
+#define SctpTimerTypeShutdown 4
+#define SctpTimerTypeHeartbeat 5
+#define SctpTimerTypeCookie 6
+#define SctpTimerTypeNewCookie 7
+#define SctpTimerTypePathMtuRaise 8
+#define SctpTimerTypeShutdownAck 9
+#define SctpTimerTypeRelReq 10
+
+/* Here are the timer directives given to the
+ * user provided function
+ */
+#define SCTP_TIMER_START 1
+#define SCTP_TIMER_STOP 2
+
+/* running flag states in timer structure */
+#define SCTP_TIMER_IDLE 0x0
+#define SCTP_TIMER_EXPIRED 0x1
+#define SCTP_TIMER_RUNNING 0x2
+
+
+/* number of simultaneous timers running */
+#define SCTP_MAX_NET_TIMERS 6 /* base of where net timers start */
+#define SCTP_NUMBER_TIMERS 12 /* allows up to 6 destinations */
+
+
+/* Of course we really don't collect stale cookies, being
+ * folks of decerning taste. However we do count them, if
+ * we get to many before the association comes up.. we
+ * give up. Below is the constant that dictates when
+ * we give it up...this is a implemenation dependant
+ * treatment. In ours we do not ask for a extension of
+ * time, but just retry this many times...
+ */
+#define SCTP_MAX_STALE_COOKIES_I_COLLECT 10
+
+/* max number of TSN's dup'd that I will hold */
+#define SCTP_MAX_DUP_TSNS 20
+
+/* Here we define the types used when
+ * setting the retry ammounts.
+ */
+/* constants for type of set */
+#define SCTP_MAXATTEMPT_INIT 2
+#define SCTP_MAXATTEMPT_SEND 3
+
+/* Here we define the default timers and the
+ * default number of attemts we make for
+ * each respective side (send/init).
+ */
+
+/* init timer def = 3sec */
+#define SCTP_INIT_SEC 3
+#define SCTP_INIT_NSEC 0
+
+/* send timer def = 3 seconds */
+#define SCTP_SEND_SEC 1
+#define SCTP_SEND_NSEC 0
+
+/* recv timer def = 200ms (in nsec) */
+#define SCTP_RECV_SEC 0
+#define SCTP_RECV_NSEC 200000000
+
+/* 30 seconds + RTO */
+#define SCTP_HB_SEC 30
+#define SCTP_HB_NSEC 0
+
+
+/* 300 ms */
+#define SCTP_SHUTDOWN_SEC 0
+#define SCTP_SHUTDOWN_NSEC 300000000
+
+#define SCTP_RTO_UPPER_BOUND 60000000 /* 60 sec in micro-second's */
+#define SCTP_RTO_UPPER_BOUND_SEC 60 /* for the init timer */
+#define SCTP_RTO_LOWER_BOUND 1000000 /* 1 sec in micro-sec's */
+
+#define SCTP_DEF_MAX_INIT 8
+#define SCTP_DEF_MAX_SEND 10
+
+#define SCTP_DEF_PMTU_RAISE 600 /* 10 Minutes between raise attempts */
+#define SCTP_DEF_PMTU_MIN 600
+
+#define SCTP_MSEC_IN_A_SEC 1000
+#define SCTP_USEC_IN_A_SEC 1000000
+#define SCTP_NSEC_IN_A_SEC 1000000000
+
+
+/* Events that SCTP will look for, these
+ * are or'd together to declare what SCTP
+ * wants. Each select mask/poll list should be
+ * set for the fd, if the bit is on.
+ */
+#define SCTP_EVENT_READ 0x000001
+#define SCTP_EVENT_WRITE 0x000002
+#define SCTP_EVENT_EXCEPT 0x000004
+
+/* The following constant is a value for this
+ * particular implemenation. It is quite arbitrary and
+ * is used to limit how much data will be queued up to
+ * a sender, waiting for cwnd to be larger than flightSize.
+ * All implementations will need this protection is some
+ * way due to buffer size constraints.
+ */
+
+#define SCTP_MAX_OUTSTANDING_DG 10000
+
+
+
+/* This constant (SCTP_MAX_READBUFFER) define
+ * how big the read/write buffer is
+ * when we enter the fd event notification
+ * the buffer is put on the stack, so the bigger
+ * it is the more stack you chew up, however it
+ * has got to be big enough to handle the bigest
+ * message this O/S will send you. In solaris
+ * with sockets (not TLI) we end up at a value
+ * of 64k. In TLI we could do partial reads to
+ * get it all in with less hassel.. but we
+ * write to sockets for generality.
+ */
+#define SCTP_MAX_READBUFFER 65536
+#define SCTP_ADDRMAX 60
+
+/* amount peer is obligated to have in rwnd or
+ * I will abort
+ */
+#define SCTP_MIN_RWND 1500
+
+#define SCTP_WINDOW_MIN 1500 /* smallest rwnd can be */
+#define SCTP_WINDOW_MAX 1048576 /* biggest I can grow rwnd to
+ * My playing around suggests a
+ * value greater than 64k does not
+ * do much, I guess via the kernel
+ * limitations on the stream/socket.
+ */
+
+#define SCTP_MAX_BUNDLE_UP 256 /* max number of chunks I can bundle */
+
+/* I can handle a 1meg re-assembly */
+#define SCTP_DEFAULT_MAXMSGREASM 1048576
+
+
+#define SCTP_DEFAULT_MAXWINDOW 32768 /* default rwnd size */
+#define SCTP_DEFAULT_MAXSEGMENT 1500 /* MTU size, this is the default
+ * to which we set the smallestMTU
+ * size to. This governs what is the
+ * largest size we will use, of course
+ * PMTU will raise this up to
+ * the largest interface MTU or the
+ * ceiling below if there is no
+ * SIOCGIFMTU.
+ */
+#ifdef LYNX
+#define DEFAULT_MTU_CEILING 1500 /* Since Lynx O/S is brain dead
+ * in the way it handles the
+ * raw IP socket, insisting
+ * on makeing its own IP
+ * header, we limit the growth
+ * to that of the e-net size
+ */
+#else
+#define DEFAULT_MTU_CEILING 2048 /* If no SIOCGIFMTU, highest value
+ * to raise the PMTU to, i.e.
+ * don't try to raise above this
+ * value. Tune this per your
+ * largest MTU interface if your
+ * system does not support the
+ * SIOCGIFMTU ioctl.
+ */
+#endif
+#define SCTP_DEFAULT_MINSEGMENT 512 /* MTU size ... if no mtu disc */
+#define SCTP_HOW_MANY_SECRETS 2 /* how many secrets I keep */
+/* This is how long a secret lives, NOT how long a cookie lives */
+#define SCTP_HOW_LONG_COOKIE_LIVE 3600 /* how many seconds the current secret will live */
+
+#define SCTP_NUMBER_OF_SECRETS 8 /* or 8 * 4 = 32 octets */
+#define SCTP_SECRET_SIZE 32 /* number of octets in a 256 bits */
+
+#ifdef USE_MD5
+#define SCTP_SIGNATURE_SIZE 16 /* size of a MD5 signature */
+#else
+#define SCTP_SIGNATURE_SIZE 20 /* size of a SLA-1 signature */
+#endif
+/* Here are the notification constants
+ * that the code and upper layer will get
+ */
+
+/* association is up */
+#define SCTP_NOTIFY_ASSOC_UP 1
+
+/* association is down */
+#define SCTP_NOTIFY_ASSOC_DOWN 2
+
+/* interface on a association is down
+ * and out of consideration for selection.
+ */
+#define SCTP_NOTIFY_INTF_DOWN 3
+
+/* interface on a association is up
+ * and now back in consideration for selection.
+ */
+#define SCTP_NOTIFY_INTF_UP 4
+
+/* The given datagram cannot be delivered
+ * to the peer, this will probably be followed
+ * by a SCTP_NOTFIY_ASSOC_DOWN.
+ */
+#define SCTP_NOTIFY_DG_FAIL 5
+
+/* Sent dg on non-open stream extreme code error!
+ */
+#define SCTP_NOTIFY_STRDATA_ERR 6
+
+#define SCTP_NOTIFY_ASSOC_ABORTED 7
+
+/* The stream ones are not used yet, but could
+ * be when a association opens.
+ */
+#define SCTP_NOTIFY_PEER_OPENED_STR 8
+#define SCTP_NOTIFY_STREAM_OPENED_OK 9
+
+/* association sees a restart event */
+#define SCTP_NOTIFY_ASSOC_RESTART 10
+
+/* a user requested HB returned */
+#define SCTP_NOTIFY_HB_RESP 11
+
+/* a result from a REL-REQ */
+#define SCTP_NOTIFY_RELREQ_RESULT_OK 12
+#define SCTP_NOTIFY_RELREQ_RESULT_FAILED 13
+
+/* clock variance is 10ms or 10,000 us's */
+#define SCTP_CLOCK_GRAINULARITY 10000
+
+#define IP_HDR_SIZE 40 /* we use the size of a IP6 header here
+ * this detracts a small amount for ipv4
+ * but it simplifies the ipv6 addition
+ */
+
+#define SCTP_NUM_FDS 3
+
+/* raw IP filedescriptor */
+#define SCTP_FD_IP 0
+/* raw ICMP filedescriptor */
+#define SCTP_FD_ICMP 1
+/* processes contact me for requests here */
+#define SCTP_REQUEST 2
+
+
+#define SCTP_DEAMON_PORT 9899
+
+/* Deamon registration message types/responses */
+#define DEAMON_REGISTER 0x01
+#define DEAMON_REGISTER_ACK 0x02
+#define DEAMON_DEREGISTER 0x03
+#define DEAMON_DEREGISTER_ACK 0x04
+#define DEAMON_CHECKADDR_LIST 0x05
+
+#define DEAMON_MAGIC_VER_LEN 0xff
+
+/* max times I will attempt to send a message to deamon */
+#define SCTP_MAX_ATTEMPTS_AT_DEAMON 5
+#define SCTP_TIMEOUT_IN_POLL_FOR_DEAMON 1500 /* 1.5 seconds */
+
+/* modular comparison */
+/* True if a > b (mod = M) */
+#define compare_with_wrap(a, b, M) ((a > b) && ((a - b) < (M >> 1))) || \
+ ((b > a) && ((b - a) > (M >> 1)))
+
+#ifndef TIMEVAL_TO_TIMESPEC
+#define TIMEVAL_TO_TIMESPEC(tv, ts) \
+{ \
+ (ts)->tv_sec = (tv)->tv_sec; \
+ (ts)->tv_nsec = (tv)->tv_usec * 1000; \
+}
+#endif
+
+/* pegs */
+#define SCTP_NUMBER_OF_PEGS 21
+/* peg index's */
+#define SCTP_PEG_SACKS_SEEN 0
+#define SCTP_PEG_SACKS_SENT 1
+#define SCTP_PEG_TSNS_SENT 2
+#define SCTP_PEG_TSNS_RCVD 3
+#define SCTP_DATAGRAMS_SENT 4
+#define SCTP_DATAGRAMS_RCVD 5
+#define SCTP_RETRANTSN_SENT 6
+#define SCTP_DUPTSN_RECVD 7
+#define SCTP_HBR_RECV 8
+#define SCTP_HBA_RECV 9
+#define SCTP_HB_SENT 10
+#define SCTP_DATA_DG_SENT 11
+#define SCTP_DATA_DG_RECV 12
+#define SCTP_TMIT_TIMER 13
+#define SCTP_RECV_TIMER 14
+#define SCTP_HB_TIMER 15
+#define SCTP_FAST_RETRAN 16
+#define SCTP_PEG_TSNS_READ 17
+#define SCTP_NONE_LFT_TO 18
+#define SCTP_NONE_LFT_RWND 19
+#define SCTP_NONE_LFT_CWND 20
+
+
+
+#endif
+
diff --git a/freebsd/contrib/tcpdump/sctpHeader.h b/freebsd/contrib/tcpdump/sctpHeader.h
new file mode 100644
index 00000000..63f30b5d
--- /dev/null
+++ b/freebsd/contrib/tcpdump/sctpHeader.h
@@ -0,0 +1,323 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/sctpHeader.h,v 1.6 2002-12-11 07:14:11 guy Exp $ (LBL) */
+
+/* SCTP reference Implementation Copyright (C) 1999 Cisco And Motorola
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 4. Neither the name of Cisco nor of Motorola may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * This file is part of the SCTP reference Implementation
+ *
+ *
+ * Please send any bug reports or fixes you make to one of the following email
+ * addresses:
+ *
+ * rstewar1@email.mot.com
+ * kmorneau@cisco.com
+ * qxie1@email.mot.com
+ *
+ * Any bugs reported given to us we will try to fix... any fixes shared will
+ * be incorperated into the next SCTP release.
+ */
+
+
+#ifndef __sctpHeader_h__
+#define __sctpHeader_h__
+
+#include <sctpConstants.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* the sctp common header */
+
+#ifdef TRU64
+ #define _64BITS 1
+#endif
+
+struct sctpHeader{
+ u_int16_t source;
+ u_int16_t destination;
+ u_int32_t verificationTag;
+ u_int32_t adler32;
+};
+
+/* various descriptor parsers */
+
+struct sctpChunkDesc{
+ u_int8_t chunkID;
+ u_int8_t chunkFlg;
+ u_int16_t chunkLength;
+};
+
+struct sctpParamDesc{
+ u_int16_t paramType;
+ u_int16_t paramLength;
+};
+
+
+struct sctpRelChunkDesc{
+ struct sctpChunkDesc chk;
+ u_int32_t serialNumber;
+};
+
+struct sctpVendorSpecificParam {
+ struct sctpParamDesc p; /* type must be 0xfffe */
+ u_int32_t vendorId; /* vendor ID from RFC 1700 */
+ u_int16_t vendorSpecificType;
+ u_int16_t vendorSpecificLen;
+};
+
+
+/* Structures for the control parts */
+
+
+
+/* Sctp association init request/ack */
+
+/* this is used for init ack, too */
+struct sctpInitiation{
+ u_int32_t initTag; /* tag of mine */
+ u_int32_t rcvWindowCredit; /* rwnd */
+ u_int16_t NumPreopenStreams; /* OS */
+ u_int16_t MaxInboundStreams; /* MIS */
+ u_int32_t initialTSN;
+ /* optional param's follow in sctpParamDesc form */
+};
+
+struct sctpV4IpAddress{
+ struct sctpParamDesc p; /* type is set to SCTP_IPV4_PARAM_TYPE, len=10 */
+ u_int32_t ipAddress;
+};
+
+
+struct sctpV6IpAddress{
+ struct sctpParamDesc p; /* type is set to SCTP_IPV6_PARAM_TYPE, len=22 */
+ u_int8_t ipAddress[16];
+};
+
+struct sctpDNSName{
+ struct sctpParamDesc param;
+ u_int8_t name[1];
+};
+
+
+struct sctpCookiePreserve{
+ struct sctpParamDesc p; /* type is set to SCTP_COOKIE_PRESERVE, len=8 */
+ u_int32_t extraTime;
+};
+
+
+struct sctpTimeStamp{
+ u_int32_t ts_sec;
+ u_int32_t ts_usec;
+};
+
+/* wire structure of my cookie */
+struct cookieMessage{
+ u_int32_t TieTag_curTag; /* copied from assoc if present */
+ u_int32_t TieTag_hisTag; /* copied from assoc if present */
+ int32_t cookieLife; /* life I will award this cookie */
+ struct sctpTimeStamp timeEnteringState; /* the time I built cookie */
+ struct sctpInitiation initAckISent; /* the INIT-ACK that I sent to my peer */
+ u_int32_t addressWhereISent[4]; /* I make this 4 ints so I get 128bits for future */
+ int32_t addrtype; /* address type */
+ u_int16_t locScope; /* V6 local scope flag */
+ u_int16_t siteScope; /* V6 site scope flag */
+ /* at the end is tacked on the INIT chunk sent in
+ * its entirety and of course our
+ * signature.
+ */
+};
+
+
+/* this guy is for use when
+ * I have a initiate message gloming the
+ * things together.
+
+ */
+struct sctpUnifiedInit{
+ struct sctpChunkDesc uh;
+ struct sctpInitiation initm;
+};
+
+struct sctpSendableInit{
+ struct sctpHeader mh;
+ struct sctpUnifiedInit msg;
+};
+
+
+/* Selective Acknowledgement
+ * has the following structure with
+ * a optional ammount of trailing int's
+ * on the last part (based on the numberOfDesc
+ * field).
+ */
+
+struct sctpSelectiveAck{
+ u_int32_t highestConseqTSN;
+ u_int32_t updatedRwnd;
+ u_int16_t numberOfdesc;
+ u_int16_t numDupTsns;
+};
+
+struct sctpSelectiveFrag{
+ u_int16_t fragmentStart;
+ u_int16_t fragmentEnd;
+};
+
+
+struct sctpUnifiedSack{
+ struct sctpChunkDesc uh;
+ struct sctpSelectiveAck sack;
+};
+
+/* for both RTT request/response the
+ * following is sent
+ */
+
+struct sctpHBrequest {
+ u_int32_t time_value_1;
+ u_int32_t time_value_2;
+};
+
+/* here is what I read and respond with to. */
+struct sctpHBunified{
+ struct sctpChunkDesc hdr;
+ struct sctpParamDesc hb;
+};
+
+
+/* here is what I send */
+struct sctpHBsender{
+ struct sctpChunkDesc hdr;
+ struct sctpParamDesc hb;
+ struct sctpHBrequest rtt;
+ int8_t addrFmt[SCTP_ADDRMAX];
+ u_int16_t userreq;
+};
+
+
+
+/* for the abort and shutdown ACK
+ * we must carry the init tag in the common header. Just the
+ * common header is all that is needed with a chunk descriptor.
+ */
+struct sctpUnifiedAbort{
+ struct sctpChunkDesc uh;
+};
+
+struct sctpUnifiedAbortLight{
+ struct sctpHeader mh;
+ struct sctpChunkDesc uh;
+};
+
+struct sctpUnifiedAbortHeavy{
+ struct sctpHeader mh;
+ struct sctpChunkDesc uh;
+ u_int16_t causeCode;
+ u_int16_t causeLen;
+};
+
+/* For the graceful shutdown we must carry
+ * the tag (in common header) and the highest consequitive acking value
+ */
+struct sctpShutdown {
+ u_int32_t TSN_Seen;
+};
+
+struct sctpUnifiedShutdown{
+ struct sctpChunkDesc uh;
+ struct sctpShutdown shut;
+};
+
+/* in the unified message we add the trailing
+ * stream id since it is the only message
+ * that is defined as a operation error.
+ */
+struct sctpOpErrorCause{
+ u_int16_t cause;
+ u_int16_t causeLen;
+};
+
+struct sctpUnifiedOpError{
+ struct sctpChunkDesc uh;
+ struct sctpOpErrorCause c;
+};
+
+struct sctpUnifiedStreamError{
+ struct sctpHeader mh;
+ struct sctpChunkDesc uh;
+ struct sctpOpErrorCause c;
+ u_int16_t strmNum;
+ u_int16_t reserved;
+};
+
+struct staleCookieMsg{
+ struct sctpHeader mh;
+ struct sctpChunkDesc uh;
+ struct sctpOpErrorCause c;
+ u_int32_t moretime;
+};
+
+/* the following is used in all sends
+ * where nothing is needed except the
+ * chunk/type i.e. shutdownAck Abort */
+
+struct sctpUnifiedSingleMsg{
+ struct sctpHeader mh;
+ struct sctpChunkDesc uh;
+};
+
+struct sctpDataPart{
+ u_int32_t TSN;
+ u_int16_t streamId;
+ u_int16_t sequence;
+ u_int32_t payloadtype;
+};
+
+struct sctpUnifiedDatagram{
+ struct sctpChunkDesc uh;
+ struct sctpDataPart dp;
+};
+
+struct sctpECN_echo{
+ struct sctpChunkDesc uh;
+ u_int32_t Lowest_TSN;
+};
+
+
+struct sctpCWR{
+ struct sctpChunkDesc uh;
+ u_int32_t TSN_reduced_at;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/freebsd/contrib/tcpdump/setsignal.c b/freebsd/contrib/tcpdump/setsignal.c
new file mode 100644
index 00000000..7a9d08e0
--- /dev/null
+++ b/freebsd/contrib/tcpdump/setsignal.c
@@ -0,0 +1,95 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/setsignal.c,v 1.11 2003-11-16 09:36:42 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <signal.h>
+#ifdef HAVE_SIGACTION
+#include <string.h>
+#endif
+
+#ifdef HAVE_OS_PROTO_H
+#include "os-proto.h"
+#endif
+
+#include "setsignal.h"
+
+/*
+ * An OS-independent signal() with, whenever possible, partial BSD
+ * semantics, i.e. the signal handler is restored following service
+ * of the signal, but system calls are *not* restarted, so that if
+ * "pcap_breakloop()" is called in a signal handler in a live capture,
+ * the read/recvfrom/whatever in the live capture doesn't get restarted,
+ * it returns -1 and sets "errno" to EINTR, so we can break out of the
+ * live capture loop.
+ *
+ * We use "sigaction()" if available. We don't specify that the signal
+ * should restart system calls, so that should always do what we want.
+ *
+ * Otherwise, if "sigset()" is available, it probably has BSD semantics
+ * while "signal()" has traditional semantics, so we use "sigset()"; it
+ * might cause system calls to be restarted for the signal, however.
+ * I don't know whether, in any systems where it did cause system calls to
+ * be restarted, there was a way to ask it not to do so; there may no
+ * longer be any interesting systems without "sigaction()", however,
+ * and, if there are, they might have "sigvec()" with SV_INTERRUPT
+ * (which I think first appeared in 4.3BSD).
+ *
+ * Otherwise, we use "signal()" - which means we might get traditional
+ * semantics, wherein system calls don't get restarted *but* the
+ * signal handler is reset to SIG_DFL and the signal is not blocked,
+ * so that a subsequent signal would kill the process immediately.
+ *
+ * Did I mention that signals suck? At least in POSIX-compliant systems
+ * they suck far less, as those systems have "sigaction()".
+ */
+RETSIGTYPE
+(*setsignal (int sig, RETSIGTYPE (*func)(int)))(int)
+{
+#ifdef HAVE_SIGACTION
+ struct sigaction old, new;
+
+ memset(&new, 0, sizeof(new));
+ new.sa_handler = func;
+ if (sigaction(sig, &new, &old) < 0)
+ return (SIG_ERR);
+ return (old.sa_handler);
+
+#else
+#ifdef HAVE_SIGSET
+ return (sigset(sig, func));
+#else
+ return (signal(sig, func));
+#endif
+#endif
+}
+
diff --git a/freebsd/contrib/tcpdump/setsignal.h b/freebsd/contrib/tcpdump/setsignal.h
new file mode 100644
index 00000000..984c3407
--- /dev/null
+++ b/freebsd/contrib/tcpdump/setsignal.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * @(#) $Header: /tcpdump/master/tcpdump/setsignal.h,v 1.2 1999-10-07 23:47:13 mcr Exp $ (LBL)
+ */
+#ifndef setsignal_h
+#define setsignal_h
+
+RETSIGTYPE (*setsignal(int, RETSIGTYPE (*)(int)))(int);
+#endif
diff --git a/freebsd/contrib/tcpdump/signature.c b/freebsd/contrib/tcpdump/signature.c
new file mode 100644
index 00000000..373b33a0
--- /dev/null
+++ b/freebsd/contrib/tcpdump/signature.c
@@ -0,0 +1,161 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Functions for signature and digest verification.
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/signature.c,v 1.2 2008-09-22 20:22:10 guy Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <string.h>
+
+#include "interface.h"
+#include "signature.h"
+
+#ifdef HAVE_LIBCRYPTO
+#include <openssl/md5.h>
+#endif
+
+const struct tok signature_check_values[] = {
+ { SIGNATURE_VALID, "valid"},
+ { SIGNATURE_INVALID, "invalid"},
+ { CANT_CHECK_SIGNATURE, "unchecked"},
+ { 0, NULL }
+};
+
+
+#ifdef HAVE_LIBCRYPTO
+/*
+ * Compute a HMAC MD5 sum.
+ * Taken from rfc2104, Appendix.
+ */
+static void
+signature_compute_hmac_md5(const u_int8_t *text, int text_len, unsigned char *key,
+ unsigned int key_len, u_int8_t *digest)
+{
+ MD5_CTX context;
+ unsigned char k_ipad[65]; /* inner padding - key XORd with ipad */
+ unsigned char k_opad[65]; /* outer padding - key XORd with opad */
+ unsigned char tk[16];
+ int i;
+
+ /* if key is longer than 64 bytes reset it to key=MD5(key) */
+ if (key_len > 64) {
+
+ MD5_CTX tctx;
+
+ MD5_Init(&tctx);
+ MD5_Update(&tctx, key, key_len);
+ MD5_Final(tk, &tctx);
+
+ key = tk;
+ key_len = 16;
+ }
+
+ /*
+ * the HMAC_MD5 transform looks like:
+ *
+ * MD5(K XOR opad, MD5(K XOR ipad, text))
+ *
+ * where K is an n byte key
+ * ipad is the byte 0x36 repeated 64 times
+ * opad is the byte 0x5c repeated 64 times
+ * and text is the data being protected
+ */
+
+ /* start out by storing key in pads */
+ memset(k_ipad, 0, sizeof k_ipad);
+ memset(k_opad, 0, sizeof k_opad);
+ memcpy(k_ipad, key, key_len);
+ memcpy(k_opad, key, key_len);
+
+ /* XOR key with ipad and opad values */
+ for (i=0; i<64; i++) {
+ k_ipad[i] ^= 0x36;
+ k_opad[i] ^= 0x5c;
+ }
+
+ /*
+ * perform inner MD5
+ */
+ MD5_Init(&context); /* init context for 1st pass */
+ MD5_Update(&context, k_ipad, 64); /* start with inner pad */
+ MD5_Update(&context, text, text_len); /* then text of datagram */
+ MD5_Final(digest, &context); /* finish up 1st pass */
+
+ /*
+ * perform outer MD5
+ */
+ MD5_Init(&context); /* init context for 2nd pass */
+ MD5_Update(&context, k_opad, 64); /* start with outer pad */
+ MD5_Update(&context, digest, 16); /* then results of 1st hash */
+ MD5_Final(digest, &context); /* finish up 2nd pass */
+}
+#endif
+
+#ifdef HAVE_LIBCRYPTO
+/*
+ * Verify a cryptographic signature of the packet.
+ * Currently only MD5 is supported.
+ */
+int
+signature_verify (const u_char *pptr, u_int plen, u_char *sig_ptr)
+{
+ u_int8_t rcvsig[16];
+ u_int8_t sig[16];
+ unsigned int i;
+
+ /*
+ * Save the signature before clearing it.
+ */
+ memcpy(rcvsig, sig_ptr, sizeof(rcvsig));
+ memset(sig_ptr, 0, sizeof(rcvsig));
+
+ if (!sigsecret) {
+ return (CANT_CHECK_SIGNATURE);
+ }
+
+ signature_compute_hmac_md5(pptr, plen, (unsigned char *)sigsecret,
+ strlen(sigsecret), sig);
+
+ if (memcmp(rcvsig, sig, sizeof(sig)) == 0) {
+ return (SIGNATURE_VALID);
+
+ } else {
+
+ for (i = 0; i < sizeof(sig); ++i) {
+ (void)printf("%02x", sig[i]);
+ }
+
+ return (SIGNATURE_INVALID);
+ }
+}
+#endif
+
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 4
+ * End:
+ */
diff --git a/freebsd/contrib/tcpdump/signature.h b/freebsd/contrib/tcpdump/signature.h
new file mode 100644
index 00000000..e48b7229
--- /dev/null
+++ b/freebsd/contrib/tcpdump/signature.h
@@ -0,0 +1,26 @@
+/*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code
+ * distributions retain the above copyright notice and this paragraph
+ * in its entirety, and (2) distributions including binary code include
+ * the above copyright notice and this paragraph in its entirety in
+ * the documentation or other materials provided with the distribution.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
+ * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
+ * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE.
+ *
+ * Functions for signature and digest verification.
+ *
+ * Original code by Hannes Gredler (hannes@juniper.net)
+ */
+
+/* @(#) $Header: /tcpdump/master/tcpdump/signature.h,v 1.1 2008-08-16 11:36:20 hannes Exp $ (LBL) */
+
+/* signature checking result codes */
+#define SIGNATURE_VALID 0
+#define SIGNATURE_INVALID 1
+#define CANT_CHECK_SIGNATURE 2
+
+extern const struct tok signature_check_values[];
+extern int signature_verify (const u_char *, u_int, u_char *);
diff --git a/freebsd/contrib/tcpdump/slcompress.h b/freebsd/contrib/tcpdump/slcompress.h
new file mode 100644
index 00000000..d10243a9
--- /dev/null
+++ b/freebsd/contrib/tcpdump/slcompress.h
@@ -0,0 +1,87 @@
+/*
+ * Definitions for tcp compression routines.
+ *
+ * @(#) $Header: /tcpdump/master/tcpdump/slcompress.h,v 1.2 2000-10-09 02:03:44 guy Exp $ (LBL)
+ *
+ * Copyright (c) 1989, 1990, 1992, 1993 Regents of the University of
+ * California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Van Jacobson (van@ee.lbl.gov), Dec 31, 1989:
+ * - Initial distribution.
+ */
+
+/*
+ * Compressed packet format:
+ *
+ * The first octet contains the packet type (top 3 bits), TCP
+ * 'push' bit, and flags that indicate which of the 4 TCP sequence
+ * numbers have changed (bottom 5 bits). The next octet is a
+ * conversation number that associates a saved IP/TCP header with
+ * the compressed packet. The next two octets are the TCP checksum
+ * from the original datagram. The next 0 to 15 octets are
+ * sequence number changes, one change per bit set in the header
+ * (there may be no changes and there are two special cases where
+ * the receiver implicitly knows what changed -- see below).
+ *
+ * There are 5 numbers which can change (they are always inserted
+ * in the following order): TCP urgent pointer, window,
+ * acknowlegement, sequence number and IP ID. (The urgent pointer
+ * is different from the others in that its value is sent, not the
+ * change in value.) Since typical use of SLIP links is biased
+ * toward small packets (see comments on MTU/MSS below), changes
+ * use a variable length coding with one octet for numbers in the
+ * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the
+ * range 256 - 65535 or 0. (If the change in sequence number or
+ * ack is more than 65535, an uncompressed packet is sent.)
+ */
+
+/*
+ * Packet types (must not conflict with IP protocol version)
+ *
+ * The top nibble of the first octet is the packet type. There are
+ * three possible types: IP (not proto TCP or tcp with one of the
+ * control flags set); uncompressed TCP (a normal IP/TCP packet but
+ * with the 8-bit protocol field replaced by an 8-bit connection id --
+ * this type of packet syncs the sender & receiver); and compressed
+ * TCP (described above).
+ *
+ * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and
+ * is logically part of the 4-bit "changes" field that follows. Top
+ * three bits are actual packet type. For backward compatibility
+ * and in the interest of conserving bits, numbers are chosen so the
+ * IP protocol version number (4) which normally appears in this nibble
+ * means "IP packet".
+ */
+
+/* packet types */
+#define TYPE_IP 0x40
+#define TYPE_UNCOMPRESSED_TCP 0x70
+#define TYPE_COMPRESSED_TCP 0x80
+#define TYPE_ERROR 0x00
+
+/* Bits in first octet of compressed packet */
+#define NEW_C 0x40 /* flag bits for what changed in a packet */
+#define NEW_I 0x20
+#define NEW_S 0x08
+#define NEW_A 0x04
+#define NEW_W 0x02
+#define NEW_U 0x01
+
+/* reserved, special-case values of above */
+#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */
+#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */
+#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U)
+
+#define TCP_PUSH_BIT 0x10
diff --git a/freebsd/contrib/tcpdump/slip.h b/freebsd/contrib/tcpdump/slip.h
new file mode 100644
index 00000000..aa6402c3
--- /dev/null
+++ b/freebsd/contrib/tcpdump/slip.h
@@ -0,0 +1,34 @@
+/*
+ * Definitions that user level programs might need to know to interact
+ * with serial line IP (slip) lines.
+ *
+ * @(#) $Header: /tcpdump/master/tcpdump/slip.h,v 1.1 2000-10-09 01:53:21 guy Exp $
+ *
+ * Copyright (c) 1990 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley. The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ * definitions of the pseudo- link-level header attached to slip
+ * packets grabbed by the packet filter (bpf) traffic monitor.
+ */
+#define SLIP_HDRLEN 16
+
+#define SLX_DIR 0
+#define SLX_CHDR 1
+#define CHDR_LEN 15
+
+#define SLIPDIR_IN 0
+#define SLIPDIR_OUT 1
diff --git a/freebsd/contrib/tcpdump/sll.h b/freebsd/contrib/tcpdump/sll.h
new file mode 100644
index 00000000..0a34963a
--- /dev/null
+++ b/freebsd/contrib/tcpdump/sll.h
@@ -0,0 +1,127 @@
+/*-
+ * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from the Stanford/CMU enet packet filter,
+ * (net/enet.c) distributed as part of 4.3BSD, and code contributed
+ * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
+ * Berkeley Laboratory.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#) $Header: /tcpdump/master/tcpdump/sll.h,v 1.8 2008-05-30 01:37:41 guy Exp $ (LBL)
+ */
+
+/*
+ * For captures on Linux cooked sockets, we construct a fake header
+ * that includes:
+ *
+ * a 2-byte "packet type" which is one of:
+ *
+ * LINUX_SLL_HOST packet was sent to us
+ * LINUX_SLL_BROADCAST packet was broadcast
+ * LINUX_SLL_MULTICAST packet was multicast
+ * LINUX_SLL_OTHERHOST packet was sent to somebody else
+ * LINUX_SLL_OUTGOING packet was sent *by* us;
+ *
+ * a 2-byte Ethernet protocol field;
+ *
+ * a 2-byte link-layer type;
+ *
+ * a 2-byte link-layer address length;
+ *
+ * an 8-byte source link-layer address, whose actual length is
+ * specified by the previous value.
+ *
+ * All fields except for the link-layer address are in network byte order.
+ *
+ * DO NOT change the layout of this structure, or change any of the
+ * LINUX_SLL_ values below. If you must change the link-layer header
+ * for a "cooked" Linux capture, introduce a new DLT_ type (ask
+ * "tcpdump-workers@lists.tcpdump.org" for one, so that you don't give it
+ * a value that collides with a value already being used), and use the
+ * new header in captures of that type, so that programs that can
+ * handle DLT_LINUX_SLL captures will continue to handle them correctly
+ * without any change, and so that capture files with different headers
+ * can be told apart and programs that read them can dissect the
+ * packets in them.
+ *
+ * This structure, and the #defines below, must be the same in the
+ * libpcap and tcpdump versions of "sll.h".
+ */
+
+/*
+ * A DLT_LINUX_SLL fake link-layer header.
+ */
+#define SLL_HDR_LEN 16 /* total header length */
+#define SLL_ADDRLEN 8 /* length of address field */
+
+struct sll_header {
+ u_int16_t sll_pkttype; /* packet type */
+ u_int16_t sll_hatype; /* link-layer address type */
+ u_int16_t sll_halen; /* link-layer address length */
+ u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */
+ u_int16_t sll_protocol; /* protocol */
+};
+
+/*
+ * The LINUX_SLL_ values for "sll_pkttype"; these correspond to the
+ * PACKET_ values on Linux, but are defined here so that they're
+ * available even on systems other than Linux, and so that they
+ * don't change even if the PACKET_ values change.
+ */
+#define LINUX_SLL_HOST 0
+#define LINUX_SLL_BROADCAST 1
+#define LINUX_SLL_MULTICAST 2
+#define LINUX_SLL_OTHERHOST 3
+#define LINUX_SLL_OUTGOING 4
+
+/*
+ * The LINUX_SLL_ values for "sll_protocol"; these correspond to the
+ * ETH_P_ values on Linux, but are defined here so that they're
+ * available even on systems other than Linux. We assume, for now,
+ * that the ETH_P_ values won't change in Linux; if they do, then:
+ *
+ * if we don't translate them in "pcap-linux.c", capture files
+ * won't necessarily be readable if captured on a system that
+ * defines ETH_P_ values that don't match these values;
+ *
+ * if we do translate them in "pcap-linux.c", that makes life
+ * unpleasant for the BPF code generator, as the values you test
+ * for in the kernel aren't the values that you test for when
+ * reading a capture file, so the fixup code run on BPF programs
+ * handed to the kernel ends up having to do more work.
+ *
+ * Add other values here as necessary, for handling packet types that
+ * might show up on non-Ethernet, non-802.x networks. (Not all the ones
+ * in the Linux "if_ether.h" will, I suspect, actually show up in
+ * captures.)
+ */
+#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */
+#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */
diff --git a/freebsd/contrib/tcpdump/smb.h b/freebsd/contrib/tcpdump/smb.h
new file mode 100644
index 00000000..8eeb303f
--- /dev/null
+++ b/freebsd/contrib/tcpdump/smb.h
@@ -0,0 +1,122 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/smb.h,v 1.9 2004-12-28 22:29:44 guy Exp $ (LBL) */
+/*
+ * Copyright (C) Andrew Tridgell 1995-1999
+ *
+ * This software may be distributed either under the terms of the
+ * BSD-style license that accompanies tcpdump or the GNU GPL version 2
+ * or later
+ */
+
+#define SMBMIN(a,b) ((a)<(b)?(a):(b))
+
+/* the complete */
+#define SMBmkdir 0x00 /* create directory */
+#define SMBrmdir 0x01 /* delete directory */
+#define SMBopen 0x02 /* open file */
+#define SMBcreate 0x03 /* create file */
+#define SMBclose 0x04 /* close file */
+#define SMBflush 0x05 /* flush file */
+#define SMBunlink 0x06 /* delete file */
+#define SMBmv 0x07 /* rename file */
+#define SMBgetatr 0x08 /* get file attributes */
+#define SMBsetatr 0x09 /* set file attributes */
+#define SMBread 0x0A /* read from file */
+#define SMBwrite 0x0B /* write to file */
+#define SMBlock 0x0C /* lock byte range */
+#define SMBunlock 0x0D /* unlock byte range */
+#define SMBctemp 0x0E /* create temporary file */
+#define SMBmknew 0x0F /* make new file */
+#define SMBchkpth 0x10 /* check directory path */
+#define SMBexit 0x11 /* process exit */
+#define SMBlseek 0x12 /* seek */
+#define SMBtcon 0x70 /* tree connect */
+#define SMBtconX 0x75 /* tree connect and X*/
+#define SMBtdis 0x71 /* tree disconnect */
+#define SMBnegprot 0x72 /* negotiate protocol */
+#define SMBdskattr 0x80 /* get disk attributes */
+#define SMBsearch 0x81 /* search directory */
+#define SMBsplopen 0xC0 /* open print spool file */
+#define SMBsplwr 0xC1 /* write to print spool file */
+#define SMBsplclose 0xC2 /* close print spool file */
+#define SMBsplretq 0xC3 /* return print queue */
+#define SMBsends 0xD0 /* send single block message */
+#define SMBsendb 0xD1 /* send broadcast message */
+#define SMBfwdname 0xD2 /* forward user name */
+#define SMBcancelf 0xD3 /* cancel forward */
+#define SMBgetmac 0xD4 /* get machine name */
+#define SMBsendstrt 0xD5 /* send start of multi-block message */
+#define SMBsendend 0xD6 /* send end of multi-block message */
+#define SMBsendtxt 0xD7 /* send text of multi-block message */
+
+/* Core+ protocol */
+#define SMBlockread 0x13 /* Lock a range and read */
+#define SMBwriteunlock 0x14 /* Unlock a range then write */
+#define SMBreadbraw 0x1a /* read a block of data with no smb header */
+#define SMBwritebraw 0x1d /* write a block of data with no smb header */
+#define SMBwritec 0x20 /* secondary write request */
+#define SMBwriteclose 0x2c /* write a file then close it */
+
+/* dos extended protocol */
+#define SMBreadBraw 0x1A /* read block raw */
+#define SMBreadBmpx 0x1B /* read block multiplexed */
+#define SMBreadBs 0x1C /* read block (secondary response) */
+#define SMBwriteBraw 0x1D /* write block raw */
+#define SMBwriteBmpx 0x1E /* write block multiplexed */
+#define SMBwriteBs 0x1F /* write block (secondary request) */
+#define SMBwriteC 0x20 /* write complete response */
+#define SMBsetattrE 0x22 /* set file attributes expanded */
+#define SMBgetattrE 0x23 /* get file attributes expanded */
+#define SMBlockingX 0x24 /* lock/unlock byte ranges and X */
+#define SMBtrans 0x25 /* transaction - name, bytes in/out */
+#define SMBtranss 0x26 /* transaction (secondary request/response) */
+#define SMBioctl 0x27 /* IOCTL */
+#define SMBioctls 0x28 /* IOCTL (secondary request/response) */
+#define SMBcopy 0x29 /* copy */
+#define SMBmove 0x2A /* move */
+#define SMBecho 0x2B /* echo */
+#define SMBopenX 0x2D /* open and X */
+#define SMBreadX 0x2E /* read and X */
+#define SMBwriteX 0x2F /* write and X */
+#define SMBsesssetupX 0x73 /* Session Set Up & X (including User Logon) */
+#define SMBffirst 0x82 /* find first */
+#define SMBfunique 0x83 /* find unique */
+#define SMBfclose 0x84 /* find close */
+#define SMBinvalid 0xFE /* invalid command */
+
+/* Extended 2.0 protocol */
+#define SMBtrans2 0x32 /* TRANS2 protocol set */
+#define SMBtranss2 0x33 /* TRANS2 protocol set, secondary command */
+#define SMBfindclose 0x34 /* Terminate a TRANSACT2_FINDFIRST */
+#define SMBfindnclose 0x35 /* Terminate a TRANSACT2_FINDNOTIFYFIRST */
+#define SMBulogoffX 0x74 /* user logoff */
+
+/* NT SMB extensions. */
+#define SMBnttrans 0xA0 /* NT transact */
+#define SMBnttranss 0xA1 /* NT transact secondary */
+#define SMBntcreateX 0xA2 /* NT create and X */
+#define SMBntcancel 0xA4 /* NT cancel */
+
+/* pathworks special */
+#define pSETDIR '\377'
+
+
+/* these are the TRANS2 sub commands */
+#define TRANSACT2_OPEN 0
+#define TRANSACT2_FINDFIRST 1
+#define TRANSACT2_FINDNEXT 2
+#define TRANSACT2_QFSINFO 3
+#define TRANSACT2_SETFSINFO 4
+#define TRANSACT2_QPATHINFO 5
+#define TRANSACT2_SETPATHINFO 6
+#define TRANSACT2_QFILEINFO 7
+#define TRANSACT2_SETFILEINFO 8
+#define TRANSACT2_FSCTL 9
+#define TRANSACT2_IOCTL 10
+#define TRANSACT2_FINDNOTIFYFIRST 11
+#define TRANSACT2_FINDNOTIFYNEXT 12
+#define TRANSACT2_MKDIR 13
+
+#define PTR_DIFF(p1, p2) ((size_t)(((char *)(p1)) - (char *)(p2)))
+
+/* some protos */
+const u_char *smb_fdata(const u_char *, const char *, const u_char *, int);
diff --git a/freebsd/contrib/tcpdump/smbutil.c b/freebsd/contrib/tcpdump/smbutil.c
new file mode 100644
index 00000000..e27f280b
--- /dev/null
+++ b/freebsd/contrib/tcpdump/smbutil.c
@@ -0,0 +1,1891 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (C) Andrew Tridgell 1995-1999
+ *
+ * This software may be distributed either under the terms of the
+ * BSD-style license that accompanies tcpdump or the GNU GPL version 2
+ * or later
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/smbutil.c,v 1.39 2007-07-15 19:07:39 guy Exp $";
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "smb.h"
+
+static u_int32_t stringlen;
+extern const u_char *startbuf;
+
+/*
+ * interpret a 32 bit dos packed date/time to some parameters
+ */
+static void
+interpret_dos_date(u_int32_t date, struct tm *tp)
+{
+ u_int32_t p0, p1, p2, p3;
+
+ p0 = date & 0xFF;
+ p1 = ((date & 0xFF00) >> 8) & 0xFF;
+ p2 = ((date & 0xFF0000) >> 16) & 0xFF;
+ p3 = ((date & 0xFF000000) >> 24) & 0xFF;
+
+ tp->tm_sec = 2 * (p0 & 0x1F);
+ tp->tm_min = ((p0 >> 5) & 0xFF) + ((p1 & 0x7) << 3);
+ tp->tm_hour = (p1 >> 3) & 0xFF;
+ tp->tm_mday = (p2 & 0x1F);
+ tp->tm_mon = ((p2 >> 5) & 0xFF) + ((p3 & 0x1) << 3) - 1;
+ tp->tm_year = ((p3 >> 1) & 0xFF) + 80;
+}
+
+/*
+ * common portion:
+ * create a unix date from a dos date
+ */
+static time_t
+int_unix_date(u_int32_t dos_date)
+{
+ struct tm t;
+
+ if (dos_date == 0)
+ return(0);
+
+ interpret_dos_date(dos_date, &t);
+ t.tm_wday = 1;
+ t.tm_yday = 1;
+ t.tm_isdst = 0;
+
+ return (mktime(&t));
+}
+
+/*
+ * create a unix date from a dos date
+ * in network byte order
+ */
+static time_t
+make_unix_date(const u_char *date_ptr)
+{
+ u_int32_t dos_date = 0;
+
+ dos_date = EXTRACT_LE_32BITS(date_ptr);
+
+ return int_unix_date(dos_date);
+}
+
+/*
+ * create a unix date from a dos date
+ * in halfword-swapped network byte order!
+ */
+static time_t
+make_unix_date2(const u_char *date_ptr)
+{
+ u_int32_t x, x2;
+
+ x = EXTRACT_LE_32BITS(date_ptr);
+ x2 = ((x & 0xFFFF) << 16) | ((x & 0xFFFF0000) >> 16);
+ return int_unix_date(x2);
+}
+
+/*
+ * interpret an 8 byte "filetime" structure to a time_t
+ * It's originally in "100ns units since jan 1st 1601"
+ */
+static time_t
+interpret_long_date(const u_char *p)
+{
+ double d;
+ time_t ret;
+
+ /* this gives us seconds since jan 1st 1601 (approx) */
+ d = (EXTRACT_LE_32BITS(p + 4) * 256.0 + p[3]) * (1.0e-7 * (1 << 24));
+
+ /* now adjust by 369 years to make the secs since 1970 */
+ d -= 369.0 * 365.25 * 24 * 60 * 60;
+
+ /* and a fudge factor as we got it wrong by a few days */
+ d += (3 * 24 * 60 * 60 + 6 * 60 * 60 + 2);
+
+ if (d < 0)
+ return(0);
+
+ ret = (time_t)d;
+
+ return(ret);
+}
+
+/*
+ * interpret the weird netbios "name". Return the name type, or -1 if
+ * we run past the end of the buffer
+ */
+static int
+name_interpret(const u_char *in, const u_char *maxbuf, char *out)
+{
+ int ret;
+ int len;
+
+ if (in >= maxbuf)
+ return(-1); /* name goes past the end of the buffer */
+ TCHECK2(*in, 1);
+ len = (*in++) / 2;
+
+ *out=0;
+
+ if (len > 30 || len < 1)
+ return(0);
+
+ while (len--) {
+ TCHECK2(*in, 2);
+ if (in + 1 >= maxbuf)
+ return(-1); /* name goes past the end of the buffer */
+ if (in[0] < 'A' || in[0] > 'P' || in[1] < 'A' || in[1] > 'P') {
+ *out = 0;
+ return(0);
+ }
+ *out = ((in[0] - 'A') << 4) + (in[1] - 'A');
+ in += 2;
+ out++;
+ }
+ *out = 0;
+ ret = out[-1];
+
+ return(ret);
+
+trunc:
+ return(-1);
+}
+
+/*
+ * find a pointer to a netbios name
+ */
+static const u_char *
+name_ptr(const u_char *buf, int ofs, const u_char *maxbuf)
+{
+ const u_char *p;
+ u_char c;
+
+ p = buf + ofs;
+ if (p >= maxbuf)
+ return(NULL); /* name goes past the end of the buffer */
+ TCHECK2(*p, 1);
+
+ c = *p;
+
+ /* XXX - this should use the same code that the DNS dissector does */
+ if ((c & 0xC0) == 0xC0) {
+ u_int16_t l;
+
+ TCHECK2(*p, 2);
+ if ((p + 1) >= maxbuf)
+ return(NULL); /* name goes past the end of the buffer */
+ l = EXTRACT_16BITS(p) & 0x3FFF;
+ if (l == 0) {
+ /* We have a pointer that points to itself. */
+ return(NULL);
+ }
+ p = buf + l;
+ if (p >= maxbuf)
+ return(NULL); /* name goes past the end of the buffer */
+ TCHECK2(*p, 1);
+ }
+ return(p);
+
+trunc:
+ return(NULL); /* name goes past the end of the buffer */
+}
+
+/*
+ * extract a netbios name from a buf
+ */
+static int
+name_extract(const u_char *buf, int ofs, const u_char *maxbuf, char *name)
+{
+ const u_char *p = name_ptr(buf, ofs, maxbuf);
+ if (p == NULL)
+ return(-1); /* error (probably name going past end of buffer) */
+ name[0] = '\0';
+ return(name_interpret(p, maxbuf, name));
+}
+
+
+/*
+ * return the total storage length of a mangled name
+ */
+static int
+name_len(const unsigned char *s, const unsigned char *maxbuf)
+{
+ const unsigned char *s0 = s;
+ unsigned char c;
+
+ if (s >= maxbuf)
+ return(-1); /* name goes past the end of the buffer */
+ TCHECK2(*s, 1);
+ c = *s;
+ if ((c & 0xC0) == 0xC0)
+ return(2);
+ while (*s) {
+ if (s >= maxbuf)
+ return(-1); /* name goes past the end of the buffer */
+ TCHECK2(*s, 1);
+ s += (*s) + 1;
+ }
+ return(PTR_DIFF(s, s0) + 1);
+
+trunc:
+ return(-1); /* name goes past the end of the buffer */
+}
+
+static void
+print_asc(const unsigned char *buf, int len)
+{
+ int i;
+ for (i = 0; i < len; i++)
+ safeputchar(buf[i]);
+}
+
+static const char *
+name_type_str(int name_type)
+{
+ const char *f = NULL;
+
+ switch (name_type) {
+ case 0: f = "Workstation"; break;
+ case 0x03: f = "Client?"; break;
+ case 0x20: f = "Server"; break;
+ case 0x1d: f = "Master Browser"; break;
+ case 0x1b: f = "Domain Controller"; break;
+ case 0x1e: f = "Browser Server"; break;
+ default: f = "Unknown"; break;
+ }
+ return(f);
+}
+
+void
+print_data(const unsigned char *buf, int len)
+{
+ int i = 0;
+
+ if (len <= 0)
+ return;
+ printf("[%03X] ", i);
+ for (i = 0; i < len; /*nothing*/) {
+ TCHECK(buf[i]);
+ printf("%02X ", buf[i] & 0xff);
+ i++;
+ if (i%8 == 0)
+ printf(" ");
+ if (i % 16 == 0) {
+ print_asc(&buf[i - 16], 8);
+ printf(" ");
+ print_asc(&buf[i - 8], 8);
+ printf("\n");
+ if (i < len)
+ printf("[%03X] ", i);
+ }
+ }
+ if (i % 16) {
+ int n;
+
+ n = 16 - (i % 16);
+ printf(" ");
+ if (n>8)
+ printf(" ");
+ while (n--)
+ printf(" ");
+
+ n = SMBMIN(8, i % 16);
+ print_asc(&buf[i - (i % 16)], n);
+ printf(" ");
+ n = (i % 16) - n;
+ if (n > 0)
+ print_asc(&buf[i - n], n);
+ printf("\n");
+ }
+ return;
+
+trunc:
+ printf("\n");
+ printf("WARNING: Short packet. Try increasing the snap length\n");
+}
+
+
+static void
+write_bits(unsigned int val, const char *fmt)
+{
+ const char *p = fmt;
+ int i = 0;
+
+ while ((p = strchr(fmt, '|'))) {
+ size_t l = PTR_DIFF(p, fmt);
+ if (l && (val & (1 << i)))
+ printf("%.*s ", (int)l, fmt);
+ fmt = p + 1;
+ i++;
+ }
+}
+
+/* convert a UCS2 string into iso-8859-1 string */
+#define MAX_UNISTR_SIZE 1000
+static const char *
+unistr(const u_char *s, u_int32_t *len, int use_unicode)
+{
+ static char buf[MAX_UNISTR_SIZE+1];
+ size_t l = 0;
+ u_int32_t strsize;
+ const u_char *sp;
+
+ if (use_unicode) {
+ /*
+ * Skip padding that puts the string on an even boundary.
+ */
+ if (((s - startbuf) % 2) != 0) {
+ TCHECK(s[0]);
+ s++;
+ }
+ }
+ if (*len == 0) {
+ /*
+ * Null-terminated string.
+ */
+ strsize = 0;
+ sp = s;
+ if (!use_unicode) {
+ for (;;) {
+ TCHECK(sp[0]);
+ *len += 1;
+ if (sp[0] == 0)
+ break;
+ sp++;
+ }
+ strsize = *len - 1;
+ } else {
+ for (;;) {
+ TCHECK2(sp[0], 2);
+ *len += 2;
+ if (sp[0] == 0 && sp[1] == 0)
+ break;
+ sp += 2;
+ }
+ strsize = *len - 2;
+ }
+ } else {
+ /*
+ * Counted string.
+ */
+ strsize = *len;
+ }
+ if (!use_unicode) {
+ while (strsize != 0) {
+ TCHECK(s[0]);
+ if (l >= MAX_UNISTR_SIZE)
+ break;
+ if (isprint(s[0]))
+ buf[l] = s[0];
+ else {
+ if (s[0] == 0)
+ break;
+ buf[l] = '.';
+ }
+ l++;
+ s++;
+ strsize--;
+ }
+ } else {
+ while (strsize != 0) {
+ TCHECK2(s[0], 2);
+ if (l >= MAX_UNISTR_SIZE)
+ break;
+ if (s[1] == 0 && isprint(s[0])) {
+ /* It's a printable ASCII character */
+ buf[l] = s[0];
+ } else {
+ /* It's a non-ASCII character or a non-printable ASCII character */
+ if (s[0] == 0 && s[1] == 0)
+ break;
+ buf[l] = '.';
+ }
+ l++;
+ s += 2;
+ if (strsize == 1)
+ break;
+ strsize -= 2;
+ }
+ }
+ buf[l] = 0;
+ return buf;
+
+trunc:
+ return NULL;
+}
+
+static const u_char *
+smb_fdata1(const u_char *buf, const char *fmt, const u_char *maxbuf,
+ int unicodestr)
+{
+ int reverse = 0;
+ const char *attrib_fmt = "READONLY|HIDDEN|SYSTEM|VOLUME|DIR|ARCHIVE|";
+
+ while (*fmt && buf<maxbuf) {
+ switch (*fmt) {
+ case 'a':
+ TCHECK(buf[0]);
+ write_bits(buf[0], attrib_fmt);
+ buf++;
+ fmt++;
+ break;
+
+ case 'A':
+ TCHECK2(buf[0], 2);
+ write_bits(EXTRACT_LE_16BITS(buf), attrib_fmt);
+ buf += 2;
+ fmt++;
+ break;
+
+ case '{':
+ {
+ char bitfmt[128];
+ char *p;
+ int l;
+
+ p = strchr(++fmt, '}');
+ l = PTR_DIFF(p, fmt);
+
+ if ((unsigned int)l > sizeof(bitfmt) - 1)
+ l = sizeof(bitfmt)-1;
+
+ strncpy(bitfmt, fmt, l);
+ bitfmt[l] = '\0';
+ fmt = p + 1;
+ TCHECK(buf[0]);
+ write_bits(buf[0], bitfmt);
+ buf++;
+ break;
+ }
+
+ case 'P':
+ {
+ int l = atoi(fmt + 1);
+ TCHECK2(buf[0], l);
+ buf += l;
+ fmt++;
+ while (isdigit((unsigned char)*fmt))
+ fmt++;
+ break;
+ }
+ case 'r':
+ reverse = !reverse;
+ fmt++;
+ break;
+ case 'b':
+ {
+ unsigned int x;
+ TCHECK(buf[0]);
+ x = buf[0];
+ printf("%u (0x%x)", x, x);
+ buf += 1;
+ fmt++;
+ break;
+ }
+ case 'd':
+ {
+ unsigned int x;
+ TCHECK2(buf[0], 2);
+ x = reverse ? EXTRACT_16BITS(buf) :
+ EXTRACT_LE_16BITS(buf);
+ printf("%d (0x%x)", x, x);
+ buf += 2;
+ fmt++;
+ break;
+ }
+ case 'D':
+ {
+ unsigned int x;
+ TCHECK2(buf[0], 4);
+ x = reverse ? EXTRACT_32BITS(buf) :
+ EXTRACT_LE_32BITS(buf);
+ printf("%d (0x%x)", x, x);
+ buf += 4;
+ fmt++;
+ break;
+ }
+ case 'L':
+ {
+ u_int64_t x;
+ TCHECK2(buf[0], 8);
+ x = reverse ? EXTRACT_64BITS(buf) :
+ EXTRACT_LE_64BITS(buf);
+ printf("%" PRIu64 " (0x%" PRIx64 ")", x, x);
+ buf += 8;
+ fmt++;
+ break;
+ }
+ case 'M':
+ {
+ /* Weird mixed-endian length values in 64-bit locks */
+ u_int32_t x1, x2;
+ u_int64_t x;
+ TCHECK2(buf[0], 8);
+ x1 = reverse ? EXTRACT_32BITS(buf) :
+ EXTRACT_LE_32BITS(buf);
+ x2 = reverse ? EXTRACT_32BITS(buf + 4) :
+ EXTRACT_LE_32BITS(buf + 4);
+ x = (((u_int64_t)x1) << 32) | x2;
+ printf("%" PRIu64 " (0x%" PRIx64 ")", x, x);
+ buf += 8;
+ fmt++;
+ break;
+ }
+ case 'B':
+ {
+ unsigned int x;
+ TCHECK(buf[0]);
+ x = buf[0];
+ printf("0x%X", x);
+ buf += 1;
+ fmt++;
+ break;
+ }
+ case 'w':
+ {
+ unsigned int x;
+ TCHECK2(buf[0], 2);
+ x = reverse ? EXTRACT_16BITS(buf) :
+ EXTRACT_LE_16BITS(buf);
+ printf("0x%X", x);
+ buf += 2;
+ fmt++;
+ break;
+ }
+ case 'W':
+ {
+ unsigned int x;
+ TCHECK2(buf[0], 4);
+ x = reverse ? EXTRACT_32BITS(buf) :
+ EXTRACT_LE_32BITS(buf);
+ printf("0x%X", x);
+ buf += 4;
+ fmt++;
+ break;
+ }
+ case 'l':
+ {
+ fmt++;
+ switch (*fmt) {
+
+ case 'b':
+ TCHECK(buf[0]);
+ stringlen = buf[0];
+ printf("%u", stringlen);
+ buf += 1;
+ break;
+
+ case 'd':
+ TCHECK2(buf[0], 2);
+ stringlen = reverse ? EXTRACT_16BITS(buf) :
+ EXTRACT_LE_16BITS(buf);
+ printf("%u", stringlen);
+ buf += 2;
+ break;
+
+ case 'D':
+ TCHECK2(buf[0], 4);
+ stringlen = reverse ? EXTRACT_32BITS(buf) :
+ EXTRACT_LE_32BITS(buf);
+ printf("%u", stringlen);
+ buf += 4;
+ break;
+ }
+ fmt++;
+ break;
+ }
+ case 'S':
+ case 'R': /* like 'S', but always ASCII */
+ {
+ /*XXX unistr() */
+ const char *s;
+ u_int32_t len;
+
+ len = 0;
+ s = unistr(buf, &len, (*fmt == 'R') ? 0 : unicodestr);
+ if (s == NULL)
+ goto trunc;
+ printf("%s", s);
+ buf += len;
+ fmt++;
+ break;
+ }
+ case 'Z':
+ case 'Y': /* like 'Z', but always ASCII */
+ {
+ const char *s;
+ u_int32_t len;
+
+ TCHECK(*buf);
+ if (*buf != 4 && *buf != 2) {
+ printf("Error! ASCIIZ buffer of type %u", *buf);
+ return maxbuf; /* give up */
+ }
+ len = 0;
+ s = unistr(buf + 1, &len, (*fmt == 'Y') ? 0 : unicodestr);
+ if (s == NULL)
+ goto trunc;
+ printf("%s", s);
+ buf += len + 1;
+ fmt++;
+ break;
+ }
+ case 's':
+ {
+ int l = atoi(fmt + 1);
+ TCHECK2(*buf, l);
+ printf("%-*.*s", l, l, buf);
+ buf += l;
+ fmt++;
+ while (isdigit((unsigned char)*fmt))
+ fmt++;
+ break;
+ }
+ case 'c':
+ {
+ TCHECK2(*buf, stringlen);
+ printf("%-*.*s", (int)stringlen, (int)stringlen, buf);
+ buf += stringlen;
+ fmt++;
+ while (isdigit((unsigned char)*fmt))
+ fmt++;
+ break;
+ }
+ case 'C':
+ {
+ const char *s;
+ s = unistr(buf, &stringlen, unicodestr);
+ if (s == NULL)
+ goto trunc;
+ printf("%s", s);
+ buf += stringlen;
+ fmt++;
+ break;
+ }
+ case 'h':
+ {
+ int l = atoi(fmt + 1);
+ TCHECK2(*buf, l);
+ while (l--)
+ printf("%02x", *buf++);
+ fmt++;
+ while (isdigit((unsigned char)*fmt))
+ fmt++;
+ break;
+ }
+ case 'n':
+ {
+ int t = atoi(fmt+1);
+ char nbuf[255];
+ int name_type;
+ int len;
+
+ switch (t) {
+ case 1:
+ name_type = name_extract(startbuf, PTR_DIFF(buf, startbuf),
+ maxbuf, nbuf);
+ if (name_type < 0)
+ goto trunc;
+ len = name_len(buf, maxbuf);
+ if (len < 0)
+ goto trunc;
+ buf += len;
+ printf("%-15.15s NameType=0x%02X (%s)", nbuf, name_type,
+ name_type_str(name_type));
+ break;
+ case 2:
+ TCHECK(buf[15]);
+ name_type = buf[15];
+ printf("%-15.15s NameType=0x%02X (%s)", buf, name_type,
+ name_type_str(name_type));
+ buf += 16;
+ break;
+ }
+ fmt++;
+ while (isdigit((unsigned char)*fmt))
+ fmt++;
+ break;
+ }
+ case 'T':
+ {
+ time_t t;
+ struct tm *lt;
+ const char *tstring;
+ u_int32_t x;
+
+ switch (atoi(fmt + 1)) {
+ case 1:
+ TCHECK2(buf[0], 4);
+ x = EXTRACT_LE_32BITS(buf);
+ if (x == 0 || x == 0xFFFFFFFF)
+ t = 0;
+ else
+ t = make_unix_date(buf);
+ buf += 4;
+ break;
+ case 2:
+ TCHECK2(buf[0], 4);
+ x = EXTRACT_LE_32BITS(buf);
+ if (x == 0 || x == 0xFFFFFFFF)
+ t = 0;
+ else
+ t = make_unix_date2(buf);
+ buf += 4;
+ break;
+ case 3:
+ TCHECK2(buf[0], 8);
+ t = interpret_long_date(buf);
+ buf += 8;
+ break;
+ default:
+ t = 0;
+ break;
+ }
+ if (t != 0) {
+ lt = localtime(&t);
+ if (lt != NULL)
+ tstring = asctime(lt);
+ else
+ tstring = "(Can't convert time)\n";
+ } else
+ tstring = "NULL\n";
+ printf("%s", tstring);
+ fmt++;
+ while (isdigit((unsigned char)*fmt))
+ fmt++;
+ break;
+ }
+ default:
+ putchar(*fmt);
+ fmt++;
+ break;
+ }
+ }
+
+ if (buf >= maxbuf && *fmt)
+ printf("END OF BUFFER\n");
+
+ return(buf);
+
+trunc:
+ printf("\n");
+ printf("WARNING: Short packet. Try increasing the snap length\n");
+ return(NULL);
+}
+
+const u_char *
+smb_fdata(const u_char *buf, const char *fmt, const u_char *maxbuf,
+ int unicodestr)
+{
+ static int depth = 0;
+ char s[128];
+ char *p;
+
+ while (*fmt) {
+ switch (*fmt) {
+ case '*':
+ fmt++;
+ while (buf < maxbuf) {
+ const u_char *buf2;
+ depth++;
+ buf2 = smb_fdata(buf, fmt, maxbuf, unicodestr);
+ depth--;
+ if (buf2 == NULL)
+ return(NULL);
+ if (buf2 == buf)
+ return(buf);
+ buf = buf2;
+ }
+ return(buf);
+
+ case '|':
+ fmt++;
+ if (buf >= maxbuf)
+ return(buf);
+ break;
+
+ case '%':
+ fmt++;
+ buf = maxbuf;
+ break;
+
+ case '#':
+ fmt++;
+ return(buf);
+ break;
+
+ case '[':
+ fmt++;
+ if (buf >= maxbuf)
+ return(buf);
+ memset(s, 0, sizeof(s));
+ p = strchr(fmt, ']');
+ if ((size_t)(p - fmt + 1) > sizeof(s)) {
+ /* overrun */
+ return(buf);
+ }
+ strncpy(s, fmt, p - fmt);
+ s[p - fmt] = '\0';
+ fmt = p + 1;
+ buf = smb_fdata1(buf, s, maxbuf, unicodestr);
+ if (buf == NULL)
+ return(NULL);
+ break;
+
+ default:
+ putchar(*fmt);
+ fmt++;
+ fflush(stdout);
+ break;
+ }
+ }
+ if (!depth && buf < maxbuf) {
+ size_t len = PTR_DIFF(maxbuf, buf);
+ printf("Data: (%lu bytes)\n", (unsigned long)len);
+ print_data(buf, len);
+ return(buf + len);
+ }
+ return(buf);
+}
+
+typedef struct {
+ const char *name;
+ int code;
+ const char *message;
+} err_code_struct;
+
+/* DOS Error Messages */
+static const err_code_struct dos_msgs[] = {
+ { "ERRbadfunc", 1, "Invalid function." },
+ { "ERRbadfile", 2, "File not found." },
+ { "ERRbadpath", 3, "Directory invalid." },
+ { "ERRnofids", 4, "No file descriptors available" },
+ { "ERRnoaccess", 5, "Access denied." },
+ { "ERRbadfid", 6, "Invalid file handle." },
+ { "ERRbadmcb", 7, "Memory control blocks destroyed." },
+ { "ERRnomem", 8, "Insufficient server memory to perform the requested function." },
+ { "ERRbadmem", 9, "Invalid memory block address." },
+ { "ERRbadenv", 10, "Invalid environment." },
+ { "ERRbadformat", 11, "Invalid format." },
+ { "ERRbadaccess", 12, "Invalid open mode." },
+ { "ERRbaddata", 13, "Invalid data." },
+ { "ERR", 14, "reserved." },
+ { "ERRbaddrive", 15, "Invalid drive specified." },
+ { "ERRremcd", 16, "A Delete Directory request attempted to remove the server's current directory." },
+ { "ERRdiffdevice", 17, "Not same device." },
+ { "ERRnofiles", 18, "A File Search command can find no more files matching the specified criteria." },
+ { "ERRbadshare", 32, "The sharing mode specified for an Open conflicts with existing FIDs on the file." },
+ { "ERRlock", 33, "A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process." },
+ { "ERRfilexists", 80, "The file named in a Create Directory, Make New File or Link request already exists." },
+ { "ERRbadpipe", 230, "Pipe invalid." },
+ { "ERRpipebusy", 231, "All instances of the requested pipe are busy." },
+ { "ERRpipeclosing", 232, "Pipe close in progress." },
+ { "ERRnotconnected", 233, "No process on other end of pipe." },
+ { "ERRmoredata", 234, "There is more data to be returned." },
+ { NULL, -1, NULL }
+ };
+
+/* Server Error Messages */
+static const err_code_struct server_msgs[] = {
+ { "ERRerror", 1, "Non-specific error code." },
+ { "ERRbadpw", 2, "Bad password - name/password pair in a Tree Connect or Session Setup are invalid." },
+ { "ERRbadtype", 3, "reserved." },
+ { "ERRaccess", 4, "The requester does not have the necessary access rights within the specified context for the requested function. The context is defined by the TID or the UID." },
+ { "ERRinvnid", 5, "The tree ID (TID) specified in a command was invalid." },
+ { "ERRinvnetname", 6, "Invalid network name in tree connect." },
+ { "ERRinvdevice", 7, "Invalid device - printer request made to non-printer connection or non-printer request made to printer connection." },
+ { "ERRqfull", 49, "Print queue full (files) -- returned by open print file." },
+ { "ERRqtoobig", 50, "Print queue full -- no space." },
+ { "ERRqeof", 51, "EOF on print queue dump." },
+ { "ERRinvpfid", 52, "Invalid print file FID." },
+ { "ERRsmbcmd", 64, "The server did not recognize the command received." },
+ { "ERRsrverror", 65, "The server encountered an internal error, e.g., system file unavailable." },
+ { "ERRfilespecs", 67, "The file handle (FID) and pathname parameters contained an invalid combination of values." },
+ { "ERRreserved", 68, "reserved." },
+ { "ERRbadpermits", 69, "The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute." },
+ { "ERRreserved", 70, "reserved." },
+ { "ERRsetattrmode", 71, "The attribute mode in the Set File Attribute request is invalid." },
+ { "ERRpaused", 81, "Server is paused." },
+ { "ERRmsgoff", 82, "Not receiving messages." },
+ { "ERRnoroom", 83, "No room to buffer message." },
+ { "ERRrmuns", 87, "Too many remote user names." },
+ { "ERRtimeout", 88, "Operation timed out." },
+ { "ERRnoresource", 89, "No resources currently available for request." },
+ { "ERRtoomanyuids", 90, "Too many UIDs active on this session." },
+ { "ERRbaduid", 91, "The UID is not known as a valid ID on this session." },
+ { "ERRusempx", 250, "Temp unable to support Raw, use MPX mode." },
+ { "ERRusestd", 251, "Temp unable to support Raw, use standard read/write." },
+ { "ERRcontmpx", 252, "Continue in MPX mode." },
+ { "ERRreserved", 253, "reserved." },
+ { "ERRreserved", 254, "reserved." },
+ { "ERRnosupport", 0xFFFF, "Function not supported." },
+ { NULL, -1, NULL }
+};
+
+/* Hard Error Messages */
+static const err_code_struct hard_msgs[] = {
+ { "ERRnowrite", 19, "Attempt to write on write-protected diskette." },
+ { "ERRbadunit", 20, "Unknown unit." },
+ { "ERRnotready", 21, "Drive not ready." },
+ { "ERRbadcmd", 22, "Unknown command." },
+ { "ERRdata", 23, "Data error (CRC)." },
+ { "ERRbadreq", 24, "Bad request structure length." },
+ { "ERRseek", 25 , "Seek error." },
+ { "ERRbadmedia", 26, "Unknown media type." },
+ { "ERRbadsector", 27, "Sector not found." },
+ { "ERRnopaper", 28, "Printer out of paper." },
+ { "ERRwrite", 29, "Write fault." },
+ { "ERRread", 30, "Read fault." },
+ { "ERRgeneral", 31, "General failure." },
+ { "ERRbadshare", 32, "A open conflicts with an existing open." },
+ { "ERRlock", 33, "A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process." },
+ { "ERRwrongdisk", 34, "The wrong disk was found in a drive." },
+ { "ERRFCBUnavail", 35, "No FCBs are available to process request." },
+ { "ERRsharebufexc", 36, "A sharing buffer has been exceeded." },
+ { NULL, -1, NULL }
+};
+
+static const struct {
+ int code;
+ const char *class;
+ const err_code_struct *err_msgs;
+} err_classes[] = {
+ { 0, "SUCCESS", NULL },
+ { 0x01, "ERRDOS", dos_msgs },
+ { 0x02, "ERRSRV", server_msgs },
+ { 0x03, "ERRHRD", hard_msgs },
+ { 0x04, "ERRXOS", NULL },
+ { 0xE1, "ERRRMX1", NULL },
+ { 0xE2, "ERRRMX2", NULL },
+ { 0xE3, "ERRRMX3", NULL },
+ { 0xFF, "ERRCMD", NULL },
+ { -1, NULL, NULL }
+};
+
+/*
+ * return a SMB error string from a SMB buffer
+ */
+char *
+smb_errstr(int class, int num)
+{
+ static char ret[128];
+ int i, j;
+
+ ret[0] = 0;
+
+ for (i = 0; err_classes[i].class; i++)
+ if (err_classes[i].code == class) {
+ if (err_classes[i].err_msgs) {
+ const err_code_struct *err = err_classes[i].err_msgs;
+ for (j = 0; err[j].name; j++)
+ if (num == err[j].code) {
+ snprintf(ret, sizeof(ret), "%s - %s (%s)",
+ err_classes[i].class, err[j].name, err[j].message);
+ return ret;
+ }
+ }
+
+ snprintf(ret, sizeof(ret), "%s - %d", err_classes[i].class, num);
+ return ret;
+ }
+
+ snprintf(ret, sizeof(ret), "ERROR: Unknown error (%d,%d)", class, num);
+ return(ret);
+}
+
+typedef struct {
+ u_int32_t code;
+ const char *name;
+} nt_err_code_struct;
+
+/*
+ * NT Error codes
+ */
+static const nt_err_code_struct nt_errors[] = {
+ { 0x00000000, "STATUS_SUCCESS" },
+ { 0x00000000, "STATUS_WAIT_0" },
+ { 0x00000001, "STATUS_WAIT_1" },
+ { 0x00000002, "STATUS_WAIT_2" },
+ { 0x00000003, "STATUS_WAIT_3" },
+ { 0x0000003F, "STATUS_WAIT_63" },
+ { 0x00000080, "STATUS_ABANDONED" },
+ { 0x00000080, "STATUS_ABANDONED_WAIT_0" },
+ { 0x000000BF, "STATUS_ABANDONED_WAIT_63" },
+ { 0x000000C0, "STATUS_USER_APC" },
+ { 0x00000100, "STATUS_KERNEL_APC" },
+ { 0x00000101, "STATUS_ALERTED" },
+ { 0x00000102, "STATUS_TIMEOUT" },
+ { 0x00000103, "STATUS_PENDING" },
+ { 0x00000104, "STATUS_REPARSE" },
+ { 0x00000105, "STATUS_MORE_ENTRIES" },
+ { 0x00000106, "STATUS_NOT_ALL_ASSIGNED" },
+ { 0x00000107, "STATUS_SOME_NOT_MAPPED" },
+ { 0x00000108, "STATUS_OPLOCK_BREAK_IN_PROGRESS" },
+ { 0x00000109, "STATUS_VOLUME_MOUNTED" },
+ { 0x0000010A, "STATUS_RXACT_COMMITTED" },
+ { 0x0000010B, "STATUS_NOTIFY_CLEANUP" },
+ { 0x0000010C, "STATUS_NOTIFY_ENUM_DIR" },
+ { 0x0000010D, "STATUS_NO_QUOTAS_FOR_ACCOUNT" },
+ { 0x0000010E, "STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED" },
+ { 0x00000110, "STATUS_PAGE_FAULT_TRANSITION" },
+ { 0x00000111, "STATUS_PAGE_FAULT_DEMAND_ZERO" },
+ { 0x00000112, "STATUS_PAGE_FAULT_COPY_ON_WRITE" },
+ { 0x00000113, "STATUS_PAGE_FAULT_GUARD_PAGE" },
+ { 0x00000114, "STATUS_PAGE_FAULT_PAGING_FILE" },
+ { 0x00000115, "STATUS_CACHE_PAGE_LOCKED" },
+ { 0x00000116, "STATUS_CRASH_DUMP" },
+ { 0x00000117, "STATUS_BUFFER_ALL_ZEROS" },
+ { 0x00000118, "STATUS_REPARSE_OBJECT" },
+ { 0x0000045C, "STATUS_NO_SHUTDOWN_IN_PROGRESS" },
+ { 0x40000000, "STATUS_OBJECT_NAME_EXISTS" },
+ { 0x40000001, "STATUS_THREAD_WAS_SUSPENDED" },
+ { 0x40000002, "STATUS_WORKING_SET_LIMIT_RANGE" },
+ { 0x40000003, "STATUS_IMAGE_NOT_AT_BASE" },
+ { 0x40000004, "STATUS_RXACT_STATE_CREATED" },
+ { 0x40000005, "STATUS_SEGMENT_NOTIFICATION" },
+ { 0x40000006, "STATUS_LOCAL_USER_SESSION_KEY" },
+ { 0x40000007, "STATUS_BAD_CURRENT_DIRECTORY" },
+ { 0x40000008, "STATUS_SERIAL_MORE_WRITES" },
+ { 0x40000009, "STATUS_REGISTRY_RECOVERED" },
+ { 0x4000000A, "STATUS_FT_READ_RECOVERY_FROM_BACKUP" },
+ { 0x4000000B, "STATUS_FT_WRITE_RECOVERY" },
+ { 0x4000000C, "STATUS_SERIAL_COUNTER_TIMEOUT" },
+ { 0x4000000D, "STATUS_NULL_LM_PASSWORD" },
+ { 0x4000000E, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH" },
+ { 0x4000000F, "STATUS_RECEIVE_PARTIAL" },
+ { 0x40000010, "STATUS_RECEIVE_EXPEDITED" },
+ { 0x40000011, "STATUS_RECEIVE_PARTIAL_EXPEDITED" },
+ { 0x40000012, "STATUS_EVENT_DONE" },
+ { 0x40000013, "STATUS_EVENT_PENDING" },
+ { 0x40000014, "STATUS_CHECKING_FILE_SYSTEM" },
+ { 0x40000015, "STATUS_FATAL_APP_EXIT" },
+ { 0x40000016, "STATUS_PREDEFINED_HANDLE" },
+ { 0x40000017, "STATUS_WAS_UNLOCKED" },
+ { 0x40000018, "STATUS_SERVICE_NOTIFICATION" },
+ { 0x40000019, "STATUS_WAS_LOCKED" },
+ { 0x4000001A, "STATUS_LOG_HARD_ERROR" },
+ { 0x4000001B, "STATUS_ALREADY_WIN32" },
+ { 0x4000001C, "STATUS_WX86_UNSIMULATE" },
+ { 0x4000001D, "STATUS_WX86_CONTINUE" },
+ { 0x4000001E, "STATUS_WX86_SINGLE_STEP" },
+ { 0x4000001F, "STATUS_WX86_BREAKPOINT" },
+ { 0x40000020, "STATUS_WX86_EXCEPTION_CONTINUE" },
+ { 0x40000021, "STATUS_WX86_EXCEPTION_LASTCHANCE" },
+ { 0x40000022, "STATUS_WX86_EXCEPTION_CHAIN" },
+ { 0x40000023, "STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE" },
+ { 0x40000024, "STATUS_NO_YIELD_PERFORMED" },
+ { 0x40000025, "STATUS_TIMER_RESUME_IGNORED" },
+ { 0x80000001, "STATUS_GUARD_PAGE_VIOLATION" },
+ { 0x80000002, "STATUS_DATATYPE_MISALIGNMENT" },
+ { 0x80000003, "STATUS_BREAKPOINT" },
+ { 0x80000004, "STATUS_SINGLE_STEP" },
+ { 0x80000005, "STATUS_BUFFER_OVERFLOW" },
+ { 0x80000006, "STATUS_NO_MORE_FILES" },
+ { 0x80000007, "STATUS_WAKE_SYSTEM_DEBUGGER" },
+ { 0x8000000A, "STATUS_HANDLES_CLOSED" },
+ { 0x8000000B, "STATUS_NO_INHERITANCE" },
+ { 0x8000000C, "STATUS_GUID_SUBSTITUTION_MADE" },
+ { 0x8000000D, "STATUS_PARTIAL_COPY" },
+ { 0x8000000E, "STATUS_DEVICE_PAPER_EMPTY" },
+ { 0x8000000F, "STATUS_DEVICE_POWERED_OFF" },
+ { 0x80000010, "STATUS_DEVICE_OFF_LINE" },
+ { 0x80000011, "STATUS_DEVICE_BUSY" },
+ { 0x80000012, "STATUS_NO_MORE_EAS" },
+ { 0x80000013, "STATUS_INVALID_EA_NAME" },
+ { 0x80000014, "STATUS_EA_LIST_INCONSISTENT" },
+ { 0x80000015, "STATUS_INVALID_EA_FLAG" },
+ { 0x80000016, "STATUS_VERIFY_REQUIRED" },
+ { 0x80000017, "STATUS_EXTRANEOUS_INFORMATION" },
+ { 0x80000018, "STATUS_RXACT_COMMIT_NECESSARY" },
+ { 0x8000001A, "STATUS_NO_MORE_ENTRIES" },
+ { 0x8000001B, "STATUS_FILEMARK_DETECTED" },
+ { 0x8000001C, "STATUS_MEDIA_CHANGED" },
+ { 0x8000001D, "STATUS_BUS_RESET" },
+ { 0x8000001E, "STATUS_END_OF_MEDIA" },
+ { 0x8000001F, "STATUS_BEGINNING_OF_MEDIA" },
+ { 0x80000020, "STATUS_MEDIA_CHECK" },
+ { 0x80000021, "STATUS_SETMARK_DETECTED" },
+ { 0x80000022, "STATUS_NO_DATA_DETECTED" },
+ { 0x80000023, "STATUS_REDIRECTOR_HAS_OPEN_HANDLES" },
+ { 0x80000024, "STATUS_SERVER_HAS_OPEN_HANDLES" },
+ { 0x80000025, "STATUS_ALREADY_DISCONNECTED" },
+ { 0x80000026, "STATUS_LONGJUMP" },
+ { 0x80040111, "MAPI_E_LOGON_FAILED" },
+ { 0x80090300, "SEC_E_INSUFFICIENT_MEMORY" },
+ { 0x80090301, "SEC_E_INVALID_HANDLE" },
+ { 0x80090302, "SEC_E_UNSUPPORTED_FUNCTION" },
+ { 0x8009030B, "SEC_E_NO_IMPERSONATION" },
+ { 0x8009030D, "SEC_E_UNKNOWN_CREDENTIALS" },
+ { 0x8009030E, "SEC_E_NO_CREDENTIALS" },
+ { 0x8009030F, "SEC_E_MESSAGE_ALTERED" },
+ { 0x80090310, "SEC_E_OUT_OF_SEQUENCE" },
+ { 0x80090311, "SEC_E_NO_AUTHENTICATING_AUTHORITY" },
+ { 0xC0000001, "STATUS_UNSUCCESSFUL" },
+ { 0xC0000002, "STATUS_NOT_IMPLEMENTED" },
+ { 0xC0000003, "STATUS_INVALID_INFO_CLASS" },
+ { 0xC0000004, "STATUS_INFO_LENGTH_MISMATCH" },
+ { 0xC0000005, "STATUS_ACCESS_VIOLATION" },
+ { 0xC0000006, "STATUS_IN_PAGE_ERROR" },
+ { 0xC0000007, "STATUS_PAGEFILE_QUOTA" },
+ { 0xC0000008, "STATUS_INVALID_HANDLE" },
+ { 0xC0000009, "STATUS_BAD_INITIAL_STACK" },
+ { 0xC000000A, "STATUS_BAD_INITIAL_PC" },
+ { 0xC000000B, "STATUS_INVALID_CID" },
+ { 0xC000000C, "STATUS_TIMER_NOT_CANCELED" },
+ { 0xC000000D, "STATUS_INVALID_PARAMETER" },
+ { 0xC000000E, "STATUS_NO_SUCH_DEVICE" },
+ { 0xC000000F, "STATUS_NO_SUCH_FILE" },
+ { 0xC0000010, "STATUS_INVALID_DEVICE_REQUEST" },
+ { 0xC0000011, "STATUS_END_OF_FILE" },
+ { 0xC0000012, "STATUS_WRONG_VOLUME" },
+ { 0xC0000013, "STATUS_NO_MEDIA_IN_DEVICE" },
+ { 0xC0000014, "STATUS_UNRECOGNIZED_MEDIA" },
+ { 0xC0000015, "STATUS_NONEXISTENT_SECTOR" },
+ { 0xC0000016, "STATUS_MORE_PROCESSING_REQUIRED" },
+ { 0xC0000017, "STATUS_NO_MEMORY" },
+ { 0xC0000018, "STATUS_CONFLICTING_ADDRESSES" },
+ { 0xC0000019, "STATUS_NOT_MAPPED_VIEW" },
+ { 0xC000001A, "STATUS_UNABLE_TO_FREE_VM" },
+ { 0xC000001B, "STATUS_UNABLE_TO_DELETE_SECTION" },
+ { 0xC000001C, "STATUS_INVALID_SYSTEM_SERVICE" },
+ { 0xC000001D, "STATUS_ILLEGAL_INSTRUCTION" },
+ { 0xC000001E, "STATUS_INVALID_LOCK_SEQUENCE" },
+ { 0xC000001F, "STATUS_INVALID_VIEW_SIZE" },
+ { 0xC0000020, "STATUS_INVALID_FILE_FOR_SECTION" },
+ { 0xC0000021, "STATUS_ALREADY_COMMITTED" },
+ { 0xC0000022, "STATUS_ACCESS_DENIED" },
+ { 0xC0000023, "STATUS_BUFFER_TOO_SMALL" },
+ { 0xC0000024, "STATUS_OBJECT_TYPE_MISMATCH" },
+ { 0xC0000025, "STATUS_NONCONTINUABLE_EXCEPTION" },
+ { 0xC0000026, "STATUS_INVALID_DISPOSITION" },
+ { 0xC0000027, "STATUS_UNWIND" },
+ { 0xC0000028, "STATUS_BAD_STACK" },
+ { 0xC0000029, "STATUS_INVALID_UNWIND_TARGET" },
+ { 0xC000002A, "STATUS_NOT_LOCKED" },
+ { 0xC000002B, "STATUS_PARITY_ERROR" },
+ { 0xC000002C, "STATUS_UNABLE_TO_DECOMMIT_VM" },
+ { 0xC000002D, "STATUS_NOT_COMMITTED" },
+ { 0xC000002E, "STATUS_INVALID_PORT_ATTRIBUTES" },
+ { 0xC000002F, "STATUS_PORT_MESSAGE_TOO_LONG" },
+ { 0xC0000030, "STATUS_INVALID_PARAMETER_MIX" },
+ { 0xC0000031, "STATUS_INVALID_QUOTA_LOWER" },
+ { 0xC0000032, "STATUS_DISK_CORRUPT_ERROR" },
+ { 0xC0000033, "STATUS_OBJECT_NAME_INVALID" },
+ { 0xC0000034, "STATUS_OBJECT_NAME_NOT_FOUND" },
+ { 0xC0000035, "STATUS_OBJECT_NAME_COLLISION" },
+ { 0xC0000037, "STATUS_PORT_DISCONNECTED" },
+ { 0xC0000038, "STATUS_DEVICE_ALREADY_ATTACHED" },
+ { 0xC0000039, "STATUS_OBJECT_PATH_INVALID" },
+ { 0xC000003A, "STATUS_OBJECT_PATH_NOT_FOUND" },
+ { 0xC000003B, "STATUS_OBJECT_PATH_SYNTAX_BAD" },
+ { 0xC000003C, "STATUS_DATA_OVERRUN" },
+ { 0xC000003D, "STATUS_DATA_LATE_ERROR" },
+ { 0xC000003E, "STATUS_DATA_ERROR" },
+ { 0xC000003F, "STATUS_CRC_ERROR" },
+ { 0xC0000040, "STATUS_SECTION_TOO_BIG" },
+ { 0xC0000041, "STATUS_PORT_CONNECTION_REFUSED" },
+ { 0xC0000042, "STATUS_INVALID_PORT_HANDLE" },
+ { 0xC0000043, "STATUS_SHARING_VIOLATION" },
+ { 0xC0000044, "STATUS_QUOTA_EXCEEDED" },
+ { 0xC0000045, "STATUS_INVALID_PAGE_PROTECTION" },
+ { 0xC0000046, "STATUS_MUTANT_NOT_OWNED" },
+ { 0xC0000047, "STATUS_SEMAPHORE_LIMIT_EXCEEDED" },
+ { 0xC0000048, "STATUS_PORT_ALREADY_SET" },
+ { 0xC0000049, "STATUS_SECTION_NOT_IMAGE" },
+ { 0xC000004A, "STATUS_SUSPEND_COUNT_EXCEEDED" },
+ { 0xC000004B, "STATUS_THREAD_IS_TERMINATING" },
+ { 0xC000004C, "STATUS_BAD_WORKING_SET_LIMIT" },
+ { 0xC000004D, "STATUS_INCOMPATIBLE_FILE_MAP" },
+ { 0xC000004E, "STATUS_SECTION_PROTECTION" },
+ { 0xC000004F, "STATUS_EAS_NOT_SUPPORTED" },
+ { 0xC0000050, "STATUS_EA_TOO_LARGE" },
+ { 0xC0000051, "STATUS_NONEXISTENT_EA_ENTRY" },
+ { 0xC0000052, "STATUS_NO_EAS_ON_FILE" },
+ { 0xC0000053, "STATUS_EA_CORRUPT_ERROR" },
+ { 0xC0000054, "STATUS_FILE_LOCK_CONFLICT" },
+ { 0xC0000055, "STATUS_LOCK_NOT_GRANTED" },
+ { 0xC0000056, "STATUS_DELETE_PENDING" },
+ { 0xC0000057, "STATUS_CTL_FILE_NOT_SUPPORTED" },
+ { 0xC0000058, "STATUS_UNKNOWN_REVISION" },
+ { 0xC0000059, "STATUS_REVISION_MISMATCH" },
+ { 0xC000005A, "STATUS_INVALID_OWNER" },
+ { 0xC000005B, "STATUS_INVALID_PRIMARY_GROUP" },
+ { 0xC000005C, "STATUS_NO_IMPERSONATION_TOKEN" },
+ { 0xC000005D, "STATUS_CANT_DISABLE_MANDATORY" },
+ { 0xC000005E, "STATUS_NO_LOGON_SERVERS" },
+ { 0xC000005F, "STATUS_NO_SUCH_LOGON_SESSION" },
+ { 0xC0000060, "STATUS_NO_SUCH_PRIVILEGE" },
+ { 0xC0000061, "STATUS_PRIVILEGE_NOT_HELD" },
+ { 0xC0000062, "STATUS_INVALID_ACCOUNT_NAME" },
+ { 0xC0000063, "STATUS_USER_EXISTS" },
+ { 0xC0000064, "STATUS_NO_SUCH_USER" },
+ { 0xC0000065, "STATUS_GROUP_EXISTS" },
+ { 0xC0000066, "STATUS_NO_SUCH_GROUP" },
+ { 0xC0000067, "STATUS_MEMBER_IN_GROUP" },
+ { 0xC0000068, "STATUS_MEMBER_NOT_IN_GROUP" },
+ { 0xC0000069, "STATUS_LAST_ADMIN" },
+ { 0xC000006A, "STATUS_WRONG_PASSWORD" },
+ { 0xC000006B, "STATUS_ILL_FORMED_PASSWORD" },
+ { 0xC000006C, "STATUS_PASSWORD_RESTRICTION" },
+ { 0xC000006D, "STATUS_LOGON_FAILURE" },
+ { 0xC000006E, "STATUS_ACCOUNT_RESTRICTION" },
+ { 0xC000006F, "STATUS_INVALID_LOGON_HOURS" },
+ { 0xC0000070, "STATUS_INVALID_WORKSTATION" },
+ { 0xC0000071, "STATUS_PASSWORD_EXPIRED" },
+ { 0xC0000072, "STATUS_ACCOUNT_DISABLED" },
+ { 0xC0000073, "STATUS_NONE_MAPPED" },
+ { 0xC0000074, "STATUS_TOO_MANY_LUIDS_REQUESTED" },
+ { 0xC0000075, "STATUS_LUIDS_EXHAUSTED" },
+ { 0xC0000076, "STATUS_INVALID_SUB_AUTHORITY" },
+ { 0xC0000077, "STATUS_INVALID_ACL" },
+ { 0xC0000078, "STATUS_INVALID_SID" },
+ { 0xC0000079, "STATUS_INVALID_SECURITY_DESCR" },
+ { 0xC000007A, "STATUS_PROCEDURE_NOT_FOUND" },
+ { 0xC000007B, "STATUS_INVALID_IMAGE_FORMAT" },
+ { 0xC000007C, "STATUS_NO_TOKEN" },
+ { 0xC000007D, "STATUS_BAD_INHERITANCE_ACL" },
+ { 0xC000007E, "STATUS_RANGE_NOT_LOCKED" },
+ { 0xC000007F, "STATUS_DISK_FULL" },
+ { 0xC0000080, "STATUS_SERVER_DISABLED" },
+ { 0xC0000081, "STATUS_SERVER_NOT_DISABLED" },
+ { 0xC0000082, "STATUS_TOO_MANY_GUIDS_REQUESTED" },
+ { 0xC0000083, "STATUS_GUIDS_EXHAUSTED" },
+ { 0xC0000084, "STATUS_INVALID_ID_AUTHORITY" },
+ { 0xC0000085, "STATUS_AGENTS_EXHAUSTED" },
+ { 0xC0000086, "STATUS_INVALID_VOLUME_LABEL" },
+ { 0xC0000087, "STATUS_SECTION_NOT_EXTENDED" },
+ { 0xC0000088, "STATUS_NOT_MAPPED_DATA" },
+ { 0xC0000089, "STATUS_RESOURCE_DATA_NOT_FOUND" },
+ { 0xC000008A, "STATUS_RESOURCE_TYPE_NOT_FOUND" },
+ { 0xC000008B, "STATUS_RESOURCE_NAME_NOT_FOUND" },
+ { 0xC000008C, "STATUS_ARRAY_BOUNDS_EXCEEDED" },
+ { 0xC000008D, "STATUS_FLOAT_DENORMAL_OPERAND" },
+ { 0xC000008E, "STATUS_FLOAT_DIVIDE_BY_ZERO" },
+ { 0xC000008F, "STATUS_FLOAT_INEXACT_RESULT" },
+ { 0xC0000090, "STATUS_FLOAT_INVALID_OPERATION" },
+ { 0xC0000091, "STATUS_FLOAT_OVERFLOW" },
+ { 0xC0000092, "STATUS_FLOAT_STACK_CHECK" },
+ { 0xC0000093, "STATUS_FLOAT_UNDERFLOW" },
+ { 0xC0000094, "STATUS_INTEGER_DIVIDE_BY_ZERO" },
+ { 0xC0000095, "STATUS_INTEGER_OVERFLOW" },
+ { 0xC0000096, "STATUS_PRIVILEGED_INSTRUCTION" },
+ { 0xC0000097, "STATUS_TOO_MANY_PAGING_FILES" },
+ { 0xC0000098, "STATUS_FILE_INVALID" },
+ { 0xC0000099, "STATUS_ALLOTTED_SPACE_EXCEEDED" },
+ { 0xC000009A, "STATUS_INSUFFICIENT_RESOURCES" },
+ { 0xC000009B, "STATUS_DFS_EXIT_PATH_FOUND" },
+ { 0xC000009C, "STATUS_DEVICE_DATA_ERROR" },
+ { 0xC000009D, "STATUS_DEVICE_NOT_CONNECTED" },
+ { 0xC000009E, "STATUS_DEVICE_POWER_FAILURE" },
+ { 0xC000009F, "STATUS_FREE_VM_NOT_AT_BASE" },
+ { 0xC00000A0, "STATUS_MEMORY_NOT_ALLOCATED" },
+ { 0xC00000A1, "STATUS_WORKING_SET_QUOTA" },
+ { 0xC00000A2, "STATUS_MEDIA_WRITE_PROTECTED" },
+ { 0xC00000A3, "STATUS_DEVICE_NOT_READY" },
+ { 0xC00000A4, "STATUS_INVALID_GROUP_ATTRIBUTES" },
+ { 0xC00000A5, "STATUS_BAD_IMPERSONATION_LEVEL" },
+ { 0xC00000A6, "STATUS_CANT_OPEN_ANONYMOUS" },
+ { 0xC00000A7, "STATUS_BAD_VALIDATION_CLASS" },
+ { 0xC00000A8, "STATUS_BAD_TOKEN_TYPE" },
+ { 0xC00000A9, "STATUS_BAD_MASTER_BOOT_RECORD" },
+ { 0xC00000AA, "STATUS_INSTRUCTION_MISALIGNMENT" },
+ { 0xC00000AB, "STATUS_INSTANCE_NOT_AVAILABLE" },
+ { 0xC00000AC, "STATUS_PIPE_NOT_AVAILABLE" },
+ { 0xC00000AD, "STATUS_INVALID_PIPE_STATE" },
+ { 0xC00000AE, "STATUS_PIPE_BUSY" },
+ { 0xC00000AF, "STATUS_ILLEGAL_FUNCTION" },
+ { 0xC00000B0, "STATUS_PIPE_DISCONNECTED" },
+ { 0xC00000B1, "STATUS_PIPE_CLOSING" },
+ { 0xC00000B2, "STATUS_PIPE_CONNECTED" },
+ { 0xC00000B3, "STATUS_PIPE_LISTENING" },
+ { 0xC00000B4, "STATUS_INVALID_READ_MODE" },
+ { 0xC00000B5, "STATUS_IO_TIMEOUT" },
+ { 0xC00000B6, "STATUS_FILE_FORCED_CLOSED" },
+ { 0xC00000B7, "STATUS_PROFILING_NOT_STARTED" },
+ { 0xC00000B8, "STATUS_PROFILING_NOT_STOPPED" },
+ { 0xC00000B9, "STATUS_COULD_NOT_INTERPRET" },
+ { 0xC00000BA, "STATUS_FILE_IS_A_DIRECTORY" },
+ { 0xC00000BB, "STATUS_NOT_SUPPORTED" },
+ { 0xC00000BC, "STATUS_REMOTE_NOT_LISTENING" },
+ { 0xC00000BD, "STATUS_DUPLICATE_NAME" },
+ { 0xC00000BE, "STATUS_BAD_NETWORK_PATH" },
+ { 0xC00000BF, "STATUS_NETWORK_BUSY" },
+ { 0xC00000C0, "STATUS_DEVICE_DOES_NOT_EXIST" },
+ { 0xC00000C1, "STATUS_TOO_MANY_COMMANDS" },
+ { 0xC00000C2, "STATUS_ADAPTER_HARDWARE_ERROR" },
+ { 0xC00000C3, "STATUS_INVALID_NETWORK_RESPONSE" },
+ { 0xC00000C4, "STATUS_UNEXPECTED_NETWORK_ERROR" },
+ { 0xC00000C5, "STATUS_BAD_REMOTE_ADAPTER" },
+ { 0xC00000C6, "STATUS_PRINT_QUEUE_FULL" },
+ { 0xC00000C7, "STATUS_NO_SPOOL_SPACE" },
+ { 0xC00000C8, "STATUS_PRINT_CANCELLED" },
+ { 0xC00000C9, "STATUS_NETWORK_NAME_DELETED" },
+ { 0xC00000CA, "STATUS_NETWORK_ACCESS_DENIED" },
+ { 0xC00000CB, "STATUS_BAD_DEVICE_TYPE" },
+ { 0xC00000CC, "STATUS_BAD_NETWORK_NAME" },
+ { 0xC00000CD, "STATUS_TOO_MANY_NAMES" },
+ { 0xC00000CE, "STATUS_TOO_MANY_SESSIONS" },
+ { 0xC00000CF, "STATUS_SHARING_PAUSED" },
+ { 0xC00000D0, "STATUS_REQUEST_NOT_ACCEPTED" },
+ { 0xC00000D1, "STATUS_REDIRECTOR_PAUSED" },
+ { 0xC00000D2, "STATUS_NET_WRITE_FAULT" },
+ { 0xC00000D3, "STATUS_PROFILING_AT_LIMIT" },
+ { 0xC00000D4, "STATUS_NOT_SAME_DEVICE" },
+ { 0xC00000D5, "STATUS_FILE_RENAMED" },
+ { 0xC00000D6, "STATUS_VIRTUAL_CIRCUIT_CLOSED" },
+ { 0xC00000D7, "STATUS_NO_SECURITY_ON_OBJECT" },
+ { 0xC00000D8, "STATUS_CANT_WAIT" },
+ { 0xC00000D9, "STATUS_PIPE_EMPTY" },
+ { 0xC00000DA, "STATUS_CANT_ACCESS_DOMAIN_INFO" },
+ { 0xC00000DB, "STATUS_CANT_TERMINATE_SELF" },
+ { 0xC00000DC, "STATUS_INVALID_SERVER_STATE" },
+ { 0xC00000DD, "STATUS_INVALID_DOMAIN_STATE" },
+ { 0xC00000DE, "STATUS_INVALID_DOMAIN_ROLE" },
+ { 0xC00000DF, "STATUS_NO_SUCH_DOMAIN" },
+ { 0xC00000E0, "STATUS_DOMAIN_EXISTS" },
+ { 0xC00000E1, "STATUS_DOMAIN_LIMIT_EXCEEDED" },
+ { 0xC00000E2, "STATUS_OPLOCK_NOT_GRANTED" },
+ { 0xC00000E3, "STATUS_INVALID_OPLOCK_PROTOCOL" },
+ { 0xC00000E4, "STATUS_INTERNAL_DB_CORRUPTION" },
+ { 0xC00000E5, "STATUS_INTERNAL_ERROR" },
+ { 0xC00000E6, "STATUS_GENERIC_NOT_MAPPED" },
+ { 0xC00000E7, "STATUS_BAD_DESCRIPTOR_FORMAT" },
+ { 0xC00000E8, "STATUS_INVALID_USER_BUFFER" },
+ { 0xC00000E9, "STATUS_UNEXPECTED_IO_ERROR" },
+ { 0xC00000EA, "STATUS_UNEXPECTED_MM_CREATE_ERR" },
+ { 0xC00000EB, "STATUS_UNEXPECTED_MM_MAP_ERROR" },
+ { 0xC00000EC, "STATUS_UNEXPECTED_MM_EXTEND_ERR" },
+ { 0xC00000ED, "STATUS_NOT_LOGON_PROCESS" },
+ { 0xC00000EE, "STATUS_LOGON_SESSION_EXISTS" },
+ { 0xC00000EF, "STATUS_INVALID_PARAMETER_1" },
+ { 0xC00000F0, "STATUS_INVALID_PARAMETER_2" },
+ { 0xC00000F1, "STATUS_INVALID_PARAMETER_3" },
+ { 0xC00000F2, "STATUS_INVALID_PARAMETER_4" },
+ { 0xC00000F3, "STATUS_INVALID_PARAMETER_5" },
+ { 0xC00000F4, "STATUS_INVALID_PARAMETER_6" },
+ { 0xC00000F5, "STATUS_INVALID_PARAMETER_7" },
+ { 0xC00000F6, "STATUS_INVALID_PARAMETER_8" },
+ { 0xC00000F7, "STATUS_INVALID_PARAMETER_9" },
+ { 0xC00000F8, "STATUS_INVALID_PARAMETER_10" },
+ { 0xC00000F9, "STATUS_INVALID_PARAMETER_11" },
+ { 0xC00000FA, "STATUS_INVALID_PARAMETER_12" },
+ { 0xC00000FB, "STATUS_REDIRECTOR_NOT_STARTED" },
+ { 0xC00000FC, "STATUS_REDIRECTOR_STARTED" },
+ { 0xC00000FD, "STATUS_STACK_OVERFLOW" },
+ { 0xC00000FE, "STATUS_NO_SUCH_PACKAGE" },
+ { 0xC00000FF, "STATUS_BAD_FUNCTION_TABLE" },
+ { 0xC0000100, "STATUS_VARIABLE_NOT_FOUND" },
+ { 0xC0000101, "STATUS_DIRECTORY_NOT_EMPTY" },
+ { 0xC0000102, "STATUS_FILE_CORRUPT_ERROR" },
+ { 0xC0000103, "STATUS_NOT_A_DIRECTORY" },
+ { 0xC0000104, "STATUS_BAD_LOGON_SESSION_STATE" },
+ { 0xC0000105, "STATUS_LOGON_SESSION_COLLISION" },
+ { 0xC0000106, "STATUS_NAME_TOO_LONG" },
+ { 0xC0000107, "STATUS_FILES_OPEN" },
+ { 0xC0000108, "STATUS_CONNECTION_IN_USE" },
+ { 0xC0000109, "STATUS_MESSAGE_NOT_FOUND" },
+ { 0xC000010A, "STATUS_PROCESS_IS_TERMINATING" },
+ { 0xC000010B, "STATUS_INVALID_LOGON_TYPE" },
+ { 0xC000010C, "STATUS_NO_GUID_TRANSLATION" },
+ { 0xC000010D, "STATUS_CANNOT_IMPERSONATE" },
+ { 0xC000010E, "STATUS_IMAGE_ALREADY_LOADED" },
+ { 0xC000010F, "STATUS_ABIOS_NOT_PRESENT" },
+ { 0xC0000110, "STATUS_ABIOS_LID_NOT_EXIST" },
+ { 0xC0000111, "STATUS_ABIOS_LID_ALREADY_OWNED" },
+ { 0xC0000112, "STATUS_ABIOS_NOT_LID_OWNER" },
+ { 0xC0000113, "STATUS_ABIOS_INVALID_COMMAND" },
+ { 0xC0000114, "STATUS_ABIOS_INVALID_LID" },
+ { 0xC0000115, "STATUS_ABIOS_SELECTOR_NOT_AVAILABLE" },
+ { 0xC0000116, "STATUS_ABIOS_INVALID_SELECTOR" },
+ { 0xC0000117, "STATUS_NO_LDT" },
+ { 0xC0000118, "STATUS_INVALID_LDT_SIZE" },
+ { 0xC0000119, "STATUS_INVALID_LDT_OFFSET" },
+ { 0xC000011A, "STATUS_INVALID_LDT_DESCRIPTOR" },
+ { 0xC000011B, "STATUS_INVALID_IMAGE_NE_FORMAT" },
+ { 0xC000011C, "STATUS_RXACT_INVALID_STATE" },
+ { 0xC000011D, "STATUS_RXACT_COMMIT_FAILURE" },
+ { 0xC000011E, "STATUS_MAPPED_FILE_SIZE_ZERO" },
+ { 0xC000011F, "STATUS_TOO_MANY_OPENED_FILES" },
+ { 0xC0000120, "STATUS_CANCELLED" },
+ { 0xC0000121, "STATUS_CANNOT_DELETE" },
+ { 0xC0000122, "STATUS_INVALID_COMPUTER_NAME" },
+ { 0xC0000123, "STATUS_FILE_DELETED" },
+ { 0xC0000124, "STATUS_SPECIAL_ACCOUNT" },
+ { 0xC0000125, "STATUS_SPECIAL_GROUP" },
+ { 0xC0000126, "STATUS_SPECIAL_USER" },
+ { 0xC0000127, "STATUS_MEMBERS_PRIMARY_GROUP" },
+ { 0xC0000128, "STATUS_FILE_CLOSED" },
+ { 0xC0000129, "STATUS_TOO_MANY_THREADS" },
+ { 0xC000012A, "STATUS_THREAD_NOT_IN_PROCESS" },
+ { 0xC000012B, "STATUS_TOKEN_ALREADY_IN_USE" },
+ { 0xC000012C, "STATUS_PAGEFILE_QUOTA_EXCEEDED" },
+ { 0xC000012D, "STATUS_COMMITMENT_LIMIT" },
+ { 0xC000012E, "STATUS_INVALID_IMAGE_LE_FORMAT" },
+ { 0xC000012F, "STATUS_INVALID_IMAGE_NOT_MZ" },
+ { 0xC0000130, "STATUS_INVALID_IMAGE_PROTECT" },
+ { 0xC0000131, "STATUS_INVALID_IMAGE_WIN_16" },
+ { 0xC0000132, "STATUS_LOGON_SERVER_CONFLICT" },
+ { 0xC0000133, "STATUS_TIME_DIFFERENCE_AT_DC" },
+ { 0xC0000134, "STATUS_SYNCHRONIZATION_REQUIRED" },
+ { 0xC0000135, "STATUS_DLL_NOT_FOUND" },
+ { 0xC0000136, "STATUS_OPEN_FAILED" },
+ { 0xC0000137, "STATUS_IO_PRIVILEGE_FAILED" },
+ { 0xC0000138, "STATUS_ORDINAL_NOT_FOUND" },
+ { 0xC0000139, "STATUS_ENTRYPOINT_NOT_FOUND" },
+ { 0xC000013A, "STATUS_CONTROL_C_EXIT" },
+ { 0xC000013B, "STATUS_LOCAL_DISCONNECT" },
+ { 0xC000013C, "STATUS_REMOTE_DISCONNECT" },
+ { 0xC000013D, "STATUS_REMOTE_RESOURCES" },
+ { 0xC000013E, "STATUS_LINK_FAILED" },
+ { 0xC000013F, "STATUS_LINK_TIMEOUT" },
+ { 0xC0000140, "STATUS_INVALID_CONNECTION" },
+ { 0xC0000141, "STATUS_INVALID_ADDRESS" },
+ { 0xC0000142, "STATUS_DLL_INIT_FAILED" },
+ { 0xC0000143, "STATUS_MISSING_SYSTEMFILE" },
+ { 0xC0000144, "STATUS_UNHANDLED_EXCEPTION" },
+ { 0xC0000145, "STATUS_APP_INIT_FAILURE" },
+ { 0xC0000146, "STATUS_PAGEFILE_CREATE_FAILED" },
+ { 0xC0000147, "STATUS_NO_PAGEFILE" },
+ { 0xC0000148, "STATUS_INVALID_LEVEL" },
+ { 0xC0000149, "STATUS_WRONG_PASSWORD_CORE" },
+ { 0xC000014A, "STATUS_ILLEGAL_FLOAT_CONTEXT" },
+ { 0xC000014B, "STATUS_PIPE_BROKEN" },
+ { 0xC000014C, "STATUS_REGISTRY_CORRUPT" },
+ { 0xC000014D, "STATUS_REGISTRY_IO_FAILED" },
+ { 0xC000014E, "STATUS_NO_EVENT_PAIR" },
+ { 0xC000014F, "STATUS_UNRECOGNIZED_VOLUME" },
+ { 0xC0000150, "STATUS_SERIAL_NO_DEVICE_INITED" },
+ { 0xC0000151, "STATUS_NO_SUCH_ALIAS" },
+ { 0xC0000152, "STATUS_MEMBER_NOT_IN_ALIAS" },
+ { 0xC0000153, "STATUS_MEMBER_IN_ALIAS" },
+ { 0xC0000154, "STATUS_ALIAS_EXISTS" },
+ { 0xC0000155, "STATUS_LOGON_NOT_GRANTED" },
+ { 0xC0000156, "STATUS_TOO_MANY_SECRETS" },
+ { 0xC0000157, "STATUS_SECRET_TOO_LONG" },
+ { 0xC0000158, "STATUS_INTERNAL_DB_ERROR" },
+ { 0xC0000159, "STATUS_FULLSCREEN_MODE" },
+ { 0xC000015A, "STATUS_TOO_MANY_CONTEXT_IDS" },
+ { 0xC000015B, "STATUS_LOGON_TYPE_NOT_GRANTED" },
+ { 0xC000015C, "STATUS_NOT_REGISTRY_FILE" },
+ { 0xC000015D, "STATUS_NT_CROSS_ENCRYPTION_REQUIRED" },
+ { 0xC000015E, "STATUS_DOMAIN_CTRLR_CONFIG_ERROR" },
+ { 0xC000015F, "STATUS_FT_MISSING_MEMBER" },
+ { 0xC0000160, "STATUS_ILL_FORMED_SERVICE_ENTRY" },
+ { 0xC0000161, "STATUS_ILLEGAL_CHARACTER" },
+ { 0xC0000162, "STATUS_UNMAPPABLE_CHARACTER" },
+ { 0xC0000163, "STATUS_UNDEFINED_CHARACTER" },
+ { 0xC0000164, "STATUS_FLOPPY_VOLUME" },
+ { 0xC0000165, "STATUS_FLOPPY_ID_MARK_NOT_FOUND" },
+ { 0xC0000166, "STATUS_FLOPPY_WRONG_CYLINDER" },
+ { 0xC0000167, "STATUS_FLOPPY_UNKNOWN_ERROR" },
+ { 0xC0000168, "STATUS_FLOPPY_BAD_REGISTERS" },
+ { 0xC0000169, "STATUS_DISK_RECALIBRATE_FAILED" },
+ { 0xC000016A, "STATUS_DISK_OPERATION_FAILED" },
+ { 0xC000016B, "STATUS_DISK_RESET_FAILED" },
+ { 0xC000016C, "STATUS_SHARED_IRQ_BUSY" },
+ { 0xC000016D, "STATUS_FT_ORPHANING" },
+ { 0xC000016E, "STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT" },
+ { 0xC0000172, "STATUS_PARTITION_FAILURE" },
+ { 0xC0000173, "STATUS_INVALID_BLOCK_LENGTH" },
+ { 0xC0000174, "STATUS_DEVICE_NOT_PARTITIONED" },
+ { 0xC0000175, "STATUS_UNABLE_TO_LOCK_MEDIA" },
+ { 0xC0000176, "STATUS_UNABLE_TO_UNLOAD_MEDIA" },
+ { 0xC0000177, "STATUS_EOM_OVERFLOW" },
+ { 0xC0000178, "STATUS_NO_MEDIA" },
+ { 0xC000017A, "STATUS_NO_SUCH_MEMBER" },
+ { 0xC000017B, "STATUS_INVALID_MEMBER" },
+ { 0xC000017C, "STATUS_KEY_DELETED" },
+ { 0xC000017D, "STATUS_NO_LOG_SPACE" },
+ { 0xC000017E, "STATUS_TOO_MANY_SIDS" },
+ { 0xC000017F, "STATUS_LM_CROSS_ENCRYPTION_REQUIRED" },
+ { 0xC0000180, "STATUS_KEY_HAS_CHILDREN" },
+ { 0xC0000181, "STATUS_CHILD_MUST_BE_VOLATILE" },
+ { 0xC0000182, "STATUS_DEVICE_CONFIGURATION_ERROR" },
+ { 0xC0000183, "STATUS_DRIVER_INTERNAL_ERROR" },
+ { 0xC0000184, "STATUS_INVALID_DEVICE_STATE" },
+ { 0xC0000185, "STATUS_IO_DEVICE_ERROR" },
+ { 0xC0000186, "STATUS_DEVICE_PROTOCOL_ERROR" },
+ { 0xC0000187, "STATUS_BACKUP_CONTROLLER" },
+ { 0xC0000188, "STATUS_LOG_FILE_FULL" },
+ { 0xC0000189, "STATUS_TOO_LATE" },
+ { 0xC000018A, "STATUS_NO_TRUST_LSA_SECRET" },
+ { 0xC000018B, "STATUS_NO_TRUST_SAM_ACCOUNT" },
+ { 0xC000018C, "STATUS_TRUSTED_DOMAIN_FAILURE" },
+ { 0xC000018D, "STATUS_TRUSTED_RELATIONSHIP_FAILURE" },
+ { 0xC000018E, "STATUS_EVENTLOG_FILE_CORRUPT" },
+ { 0xC000018F, "STATUS_EVENTLOG_CANT_START" },
+ { 0xC0000190, "STATUS_TRUST_FAILURE" },
+ { 0xC0000191, "STATUS_MUTANT_LIMIT_EXCEEDED" },
+ { 0xC0000192, "STATUS_NETLOGON_NOT_STARTED" },
+ { 0xC0000193, "STATUS_ACCOUNT_EXPIRED" },
+ { 0xC0000194, "STATUS_POSSIBLE_DEADLOCK" },
+ { 0xC0000195, "STATUS_NETWORK_CREDENTIAL_CONFLICT" },
+ { 0xC0000196, "STATUS_REMOTE_SESSION_LIMIT" },
+ { 0xC0000197, "STATUS_EVENTLOG_FILE_CHANGED" },
+ { 0xC0000198, "STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT" },
+ { 0xC0000199, "STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT" },
+ { 0xC000019A, "STATUS_NOLOGON_SERVER_TRUST_ACCOUNT" },
+ { 0xC000019B, "STATUS_DOMAIN_TRUST_INCONSISTENT" },
+ { 0xC000019C, "STATUS_FS_DRIVER_REQUIRED" },
+ { 0xC0000202, "STATUS_NO_USER_SESSION_KEY" },
+ { 0xC0000203, "STATUS_USER_SESSION_DELETED" },
+ { 0xC0000204, "STATUS_RESOURCE_LANG_NOT_FOUND" },
+ { 0xC0000205, "STATUS_INSUFF_SERVER_RESOURCES" },
+ { 0xC0000206, "STATUS_INVALID_BUFFER_SIZE" },
+ { 0xC0000207, "STATUS_INVALID_ADDRESS_COMPONENT" },
+ { 0xC0000208, "STATUS_INVALID_ADDRESS_WILDCARD" },
+ { 0xC0000209, "STATUS_TOO_MANY_ADDRESSES" },
+ { 0xC000020A, "STATUS_ADDRESS_ALREADY_EXISTS" },
+ { 0xC000020B, "STATUS_ADDRESS_CLOSED" },
+ { 0xC000020C, "STATUS_CONNECTION_DISCONNECTED" },
+ { 0xC000020D, "STATUS_CONNECTION_RESET" },
+ { 0xC000020E, "STATUS_TOO_MANY_NODES" },
+ { 0xC000020F, "STATUS_TRANSACTION_ABORTED" },
+ { 0xC0000210, "STATUS_TRANSACTION_TIMED_OUT" },
+ { 0xC0000211, "STATUS_TRANSACTION_NO_RELEASE" },
+ { 0xC0000212, "STATUS_TRANSACTION_NO_MATCH" },
+ { 0xC0000213, "STATUS_TRANSACTION_RESPONDED" },
+ { 0xC0000214, "STATUS_TRANSACTION_INVALID_ID" },
+ { 0xC0000215, "STATUS_TRANSACTION_INVALID_TYPE" },
+ { 0xC0000216, "STATUS_NOT_SERVER_SESSION" },
+ { 0xC0000217, "STATUS_NOT_CLIENT_SESSION" },
+ { 0xC0000218, "STATUS_CANNOT_LOAD_REGISTRY_FILE" },
+ { 0xC0000219, "STATUS_DEBUG_ATTACH_FAILED" },
+ { 0xC000021A, "STATUS_SYSTEM_PROCESS_TERMINATED" },
+ { 0xC000021B, "STATUS_DATA_NOT_ACCEPTED" },
+ { 0xC000021C, "STATUS_NO_BROWSER_SERVERS_FOUND" },
+ { 0xC000021D, "STATUS_VDM_HARD_ERROR" },
+ { 0xC000021E, "STATUS_DRIVER_CANCEL_TIMEOUT" },
+ { 0xC000021F, "STATUS_REPLY_MESSAGE_MISMATCH" },
+ { 0xC0000220, "STATUS_MAPPED_ALIGNMENT" },
+ { 0xC0000221, "STATUS_IMAGE_CHECKSUM_MISMATCH" },
+ { 0xC0000222, "STATUS_LOST_WRITEBEHIND_DATA" },
+ { 0xC0000223, "STATUS_CLIENT_SERVER_PARAMETERS_INVALID" },
+ { 0xC0000224, "STATUS_PASSWORD_MUST_CHANGE" },
+ { 0xC0000225, "STATUS_NOT_FOUND" },
+ { 0xC0000226, "STATUS_NOT_TINY_STREAM" },
+ { 0xC0000227, "STATUS_RECOVERY_FAILURE" },
+ { 0xC0000228, "STATUS_STACK_OVERFLOW_READ" },
+ { 0xC0000229, "STATUS_FAIL_CHECK" },
+ { 0xC000022A, "STATUS_DUPLICATE_OBJECTID" },
+ { 0xC000022B, "STATUS_OBJECTID_EXISTS" },
+ { 0xC000022C, "STATUS_CONVERT_TO_LARGE" },
+ { 0xC000022D, "STATUS_RETRY" },
+ { 0xC000022E, "STATUS_FOUND_OUT_OF_SCOPE" },
+ { 0xC000022F, "STATUS_ALLOCATE_BUCKET" },
+ { 0xC0000230, "STATUS_PROPSET_NOT_FOUND" },
+ { 0xC0000231, "STATUS_MARSHALL_OVERFLOW" },
+ { 0xC0000232, "STATUS_INVALID_VARIANT" },
+ { 0xC0000233, "STATUS_DOMAIN_CONTROLLER_NOT_FOUND" },
+ { 0xC0000234, "STATUS_ACCOUNT_LOCKED_OUT" },
+ { 0xC0000235, "STATUS_HANDLE_NOT_CLOSABLE" },
+ { 0xC0000236, "STATUS_CONNECTION_REFUSED" },
+ { 0xC0000237, "STATUS_GRACEFUL_DISCONNECT" },
+ { 0xC0000238, "STATUS_ADDRESS_ALREADY_ASSOCIATED" },
+ { 0xC0000239, "STATUS_ADDRESS_NOT_ASSOCIATED" },
+ { 0xC000023A, "STATUS_CONNECTION_INVALID" },
+ { 0xC000023B, "STATUS_CONNECTION_ACTIVE" },
+ { 0xC000023C, "STATUS_NETWORK_UNREACHABLE" },
+ { 0xC000023D, "STATUS_HOST_UNREACHABLE" },
+ { 0xC000023E, "STATUS_PROTOCOL_UNREACHABLE" },
+ { 0xC000023F, "STATUS_PORT_UNREACHABLE" },
+ { 0xC0000240, "STATUS_REQUEST_ABORTED" },
+ { 0xC0000241, "STATUS_CONNECTION_ABORTED" },
+ { 0xC0000242, "STATUS_BAD_COMPRESSION_BUFFER" },
+ { 0xC0000243, "STATUS_USER_MAPPED_FILE" },
+ { 0xC0000244, "STATUS_AUDIT_FAILED" },
+ { 0xC0000245, "STATUS_TIMER_RESOLUTION_NOT_SET" },
+ { 0xC0000246, "STATUS_CONNECTION_COUNT_LIMIT" },
+ { 0xC0000247, "STATUS_LOGIN_TIME_RESTRICTION" },
+ { 0xC0000248, "STATUS_LOGIN_WKSTA_RESTRICTION" },
+ { 0xC0000249, "STATUS_IMAGE_MP_UP_MISMATCH" },
+ { 0xC0000250, "STATUS_INSUFFICIENT_LOGON_INFO" },
+ { 0xC0000251, "STATUS_BAD_DLL_ENTRYPOINT" },
+ { 0xC0000252, "STATUS_BAD_SERVICE_ENTRYPOINT" },
+ { 0xC0000253, "STATUS_LPC_REPLY_LOST" },
+ { 0xC0000254, "STATUS_IP_ADDRESS_CONFLICT1" },
+ { 0xC0000255, "STATUS_IP_ADDRESS_CONFLICT2" },
+ { 0xC0000256, "STATUS_REGISTRY_QUOTA_LIMIT" },
+ { 0xC0000257, "STATUS_PATH_NOT_COVERED" },
+ { 0xC0000258, "STATUS_NO_CALLBACK_ACTIVE" },
+ { 0xC0000259, "STATUS_LICENSE_QUOTA_EXCEEDED" },
+ { 0xC000025A, "STATUS_PWD_TOO_SHORT" },
+ { 0xC000025B, "STATUS_PWD_TOO_RECENT" },
+ { 0xC000025C, "STATUS_PWD_HISTORY_CONFLICT" },
+ { 0xC000025E, "STATUS_PLUGPLAY_NO_DEVICE" },
+ { 0xC000025F, "STATUS_UNSUPPORTED_COMPRESSION" },
+ { 0xC0000260, "STATUS_INVALID_HW_PROFILE" },
+ { 0xC0000261, "STATUS_INVALID_PLUGPLAY_DEVICE_PATH" },
+ { 0xC0000262, "STATUS_DRIVER_ORDINAL_NOT_FOUND" },
+ { 0xC0000263, "STATUS_DRIVER_ENTRYPOINT_NOT_FOUND" },
+ { 0xC0000264, "STATUS_RESOURCE_NOT_OWNED" },
+ { 0xC0000265, "STATUS_TOO_MANY_LINKS" },
+ { 0xC0000266, "STATUS_QUOTA_LIST_INCONSISTENT" },
+ { 0xC0000267, "STATUS_FILE_IS_OFFLINE" },
+ { 0xC0000268, "STATUS_EVALUATION_EXPIRATION" },
+ { 0xC0000269, "STATUS_ILLEGAL_DLL_RELOCATION" },
+ { 0xC000026A, "STATUS_LICENSE_VIOLATION" },
+ { 0xC000026B, "STATUS_DLL_INIT_FAILED_LOGOFF" },
+ { 0xC000026C, "STATUS_DRIVER_UNABLE_TO_LOAD" },
+ { 0xC000026D, "STATUS_DFS_UNAVAILABLE" },
+ { 0xC000026E, "STATUS_VOLUME_DISMOUNTED" },
+ { 0xC000026F, "STATUS_WX86_INTERNAL_ERROR" },
+ { 0xC0000270, "STATUS_WX86_FLOAT_STACK_CHECK" },
+ { 0xC0000271, "STATUS_VALIDATE_CONTINUE" },
+ { 0xC0000272, "STATUS_NO_MATCH" },
+ { 0xC0000273, "STATUS_NO_MORE_MATCHES" },
+ { 0xC0000275, "STATUS_NOT_A_REPARSE_POINT" },
+ { 0xC0000276, "STATUS_IO_REPARSE_TAG_INVALID" },
+ { 0xC0000277, "STATUS_IO_REPARSE_TAG_MISMATCH" },
+ { 0xC0000278, "STATUS_IO_REPARSE_DATA_INVALID" },
+ { 0xC0000279, "STATUS_IO_REPARSE_TAG_NOT_HANDLED" },
+ { 0xC0000280, "STATUS_REPARSE_POINT_NOT_RESOLVED" },
+ { 0xC0000281, "STATUS_DIRECTORY_IS_A_REPARSE_POINT" },
+ { 0xC0000282, "STATUS_RANGE_LIST_CONFLICT" },
+ { 0xC0000283, "STATUS_SOURCE_ELEMENT_EMPTY" },
+ { 0xC0000284, "STATUS_DESTINATION_ELEMENT_FULL" },
+ { 0xC0000285, "STATUS_ILLEGAL_ELEMENT_ADDRESS" },
+ { 0xC0000286, "STATUS_MAGAZINE_NOT_PRESENT" },
+ { 0xC0000287, "STATUS_REINITIALIZATION_NEEDED" },
+ { 0x80000288, "STATUS_DEVICE_REQUIRES_CLEANING" },
+ { 0x80000289, "STATUS_DEVICE_DOOR_OPEN" },
+ { 0xC000028A, "STATUS_ENCRYPTION_FAILED" },
+ { 0xC000028B, "STATUS_DECRYPTION_FAILED" },
+ { 0xC000028C, "STATUS_RANGE_NOT_FOUND" },
+ { 0xC000028D, "STATUS_NO_RECOVERY_POLICY" },
+ { 0xC000028E, "STATUS_NO_EFS" },
+ { 0xC000028F, "STATUS_WRONG_EFS" },
+ { 0xC0000290, "STATUS_NO_USER_KEYS" },
+ { 0xC0000291, "STATUS_FILE_NOT_ENCRYPTED" },
+ { 0xC0000292, "STATUS_NOT_EXPORT_FORMAT" },
+ { 0xC0000293, "STATUS_FILE_ENCRYPTED" },
+ { 0x40000294, "STATUS_WAKE_SYSTEM" },
+ { 0xC0000295, "STATUS_WMI_GUID_NOT_FOUND" },
+ { 0xC0000296, "STATUS_WMI_INSTANCE_NOT_FOUND" },
+ { 0xC0000297, "STATUS_WMI_ITEMID_NOT_FOUND" },
+ { 0xC0000298, "STATUS_WMI_TRY_AGAIN" },
+ { 0xC0000299, "STATUS_SHARED_POLICY" },
+ { 0xC000029A, "STATUS_POLICY_OBJECT_NOT_FOUND" },
+ { 0xC000029B, "STATUS_POLICY_ONLY_IN_DS" },
+ { 0xC000029C, "STATUS_VOLUME_NOT_UPGRADED" },
+ { 0xC000029D, "STATUS_REMOTE_STORAGE_NOT_ACTIVE" },
+ { 0xC000029E, "STATUS_REMOTE_STORAGE_MEDIA_ERROR" },
+ { 0xC000029F, "STATUS_NO_TRACKING_SERVICE" },
+ { 0xC00002A0, "STATUS_SERVER_SID_MISMATCH" },
+ { 0xC00002A1, "STATUS_DS_NO_ATTRIBUTE_OR_VALUE" },
+ { 0xC00002A2, "STATUS_DS_INVALID_ATTRIBUTE_SYNTAX" },
+ { 0xC00002A3, "STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED" },
+ { 0xC00002A4, "STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS" },
+ { 0xC00002A5, "STATUS_DS_BUSY" },
+ { 0xC00002A6, "STATUS_DS_UNAVAILABLE" },
+ { 0xC00002A7, "STATUS_DS_NO_RIDS_ALLOCATED" },
+ { 0xC00002A8, "STATUS_DS_NO_MORE_RIDS" },
+ { 0xC00002A9, "STATUS_DS_INCORRECT_ROLE_OWNER" },
+ { 0xC00002AA, "STATUS_DS_RIDMGR_INIT_ERROR" },
+ { 0xC00002AB, "STATUS_DS_OBJ_CLASS_VIOLATION" },
+ { 0xC00002AC, "STATUS_DS_CANT_ON_NON_LEAF" },
+ { 0xC00002AD, "STATUS_DS_CANT_ON_RDN" },
+ { 0xC00002AE, "STATUS_DS_CANT_MOD_OBJ_CLASS" },
+ { 0xC00002AF, "STATUS_DS_CROSS_DOM_MOVE_FAILED" },
+ { 0xC00002B0, "STATUS_DS_GC_NOT_AVAILABLE" },
+ { 0xC00002B1, "STATUS_DIRECTORY_SERVICE_REQUIRED" },
+ { 0xC00002B2, "STATUS_REPARSE_ATTRIBUTE_CONFLICT" },
+ { 0xC00002B3, "STATUS_CANT_ENABLE_DENY_ONLY" },
+ { 0xC00002B4, "STATUS_FLOAT_MULTIPLE_FAULTS" },
+ { 0xC00002B5, "STATUS_FLOAT_MULTIPLE_TRAPS" },
+ { 0xC00002B6, "STATUS_DEVICE_REMOVED" },
+ { 0xC00002B7, "STATUS_JOURNAL_DELETE_IN_PROGRESS" },
+ { 0xC00002B8, "STATUS_JOURNAL_NOT_ACTIVE" },
+ { 0xC00002B9, "STATUS_NOINTERFACE" },
+ { 0xC00002C1, "STATUS_DS_ADMIN_LIMIT_EXCEEDED" },
+ { 0xC00002C2, "STATUS_DRIVER_FAILED_SLEEP" },
+ { 0xC00002C3, "STATUS_MUTUAL_AUTHENTICATION_FAILED" },
+ { 0xC00002C4, "STATUS_CORRUPT_SYSTEM_FILE" },
+ { 0xC00002C5, "STATUS_DATATYPE_MISALIGNMENT_ERROR" },
+ { 0xC00002C6, "STATUS_WMI_READ_ONLY" },
+ { 0xC00002C7, "STATUS_WMI_SET_FAILURE" },
+ { 0xC00002C8, "STATUS_COMMITMENT_MINIMUM" },
+ { 0xC00002C9, "STATUS_REG_NAT_CONSUMPTION" },
+ { 0xC00002CA, "STATUS_TRANSPORT_FULL" },
+ { 0xC00002CB, "STATUS_DS_SAM_INIT_FAILURE" },
+ { 0xC00002CC, "STATUS_ONLY_IF_CONNECTED" },
+ { 0xC00002CD, "STATUS_DS_SENSITIVE_GROUP_VIOLATION" },
+ { 0xC00002CE, "STATUS_PNP_RESTART_ENUMERATION" },
+ { 0xC00002CF, "STATUS_JOURNAL_ENTRY_DELETED" },
+ { 0xC00002D0, "STATUS_DS_CANT_MOD_PRIMARYGROUPID" },
+ { 0xC00002D1, "STATUS_SYSTEM_IMAGE_BAD_SIGNATURE" },
+ { 0xC00002D2, "STATUS_PNP_REBOOT_REQUIRED" },
+ { 0xC00002D3, "STATUS_POWER_STATE_INVALID" },
+ { 0xC00002D4, "STATUS_DS_INVALID_GROUP_TYPE" },
+ { 0xC00002D5, "STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN" },
+ { 0xC00002D6, "STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN" },
+ { 0xC00002D7, "STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER" },
+ { 0xC00002D8, "STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER" },
+ { 0xC00002D9, "STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER" },
+ { 0xC00002DA, "STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER" },
+ { 0xC00002DB, "STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER" },
+ { 0xC00002DC, "STATUS_DS_HAVE_PRIMARY_MEMBERS" },
+ { 0xC00002DD, "STATUS_WMI_NOT_SUPPORTED" },
+ { 0xC00002DE, "STATUS_INSUFFICIENT_POWER" },
+ { 0xC00002DF, "STATUS_SAM_NEED_BOOTKEY_PASSWORD" },
+ { 0xC00002E0, "STATUS_SAM_NEED_BOOTKEY_FLOPPY" },
+ { 0xC00002E1, "STATUS_DS_CANT_START" },
+ { 0xC00002E2, "STATUS_DS_INIT_FAILURE" },
+ { 0xC00002E3, "STATUS_SAM_INIT_FAILURE" },
+ { 0xC00002E4, "STATUS_DS_GC_REQUIRED" },
+ { 0xC00002E5, "STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY" },
+ { 0xC00002E6, "STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS" },
+ { 0xC00002E7, "STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED" },
+ { 0xC00002E8, "STATUS_MULTIPLE_FAULT_VIOLATION" },
+ { 0xC0000300, "STATUS_NOT_SUPPORTED_ON_SBS" },
+ { 0xC0009898, "STATUS_WOW_ASSERTION" },
+ { 0xC0020001, "RPC_NT_INVALID_STRING_BINDING" },
+ { 0xC0020002, "RPC_NT_WRONG_KIND_OF_BINDING" },
+ { 0xC0020003, "RPC_NT_INVALID_BINDING" },
+ { 0xC0020004, "RPC_NT_PROTSEQ_NOT_SUPPORTED" },
+ { 0xC0020005, "RPC_NT_INVALID_RPC_PROTSEQ" },
+ { 0xC0020006, "RPC_NT_INVALID_STRING_UUID" },
+ { 0xC0020007, "RPC_NT_INVALID_ENDPOINT_FORMAT" },
+ { 0xC0020008, "RPC_NT_INVALID_NET_ADDR" },
+ { 0xC0020009, "RPC_NT_NO_ENDPOINT_FOUND" },
+ { 0xC002000A, "RPC_NT_INVALID_TIMEOUT" },
+ { 0xC002000B, "RPC_NT_OBJECT_NOT_FOUND" },
+ { 0xC002000C, "RPC_NT_ALREADY_REGISTERED" },
+ { 0xC002000D, "RPC_NT_TYPE_ALREADY_REGISTERED" },
+ { 0xC002000E, "RPC_NT_ALREADY_LISTENING" },
+ { 0xC002000F, "RPC_NT_NO_PROTSEQS_REGISTERED" },
+ { 0xC0020010, "RPC_NT_NOT_LISTENING" },
+ { 0xC0020011, "RPC_NT_UNKNOWN_MGR_TYPE" },
+ { 0xC0020012, "RPC_NT_UNKNOWN_IF" },
+ { 0xC0020013, "RPC_NT_NO_BINDINGS" },
+ { 0xC0020014, "RPC_NT_NO_PROTSEQS" },
+ { 0xC0020015, "RPC_NT_CANT_CREATE_ENDPOINT" },
+ { 0xC0020016, "RPC_NT_OUT_OF_RESOURCES" },
+ { 0xC0020017, "RPC_NT_SERVER_UNAVAILABLE" },
+ { 0xC0020018, "RPC_NT_SERVER_TOO_BUSY" },
+ { 0xC0020019, "RPC_NT_INVALID_NETWORK_OPTIONS" },
+ { 0xC002001A, "RPC_NT_NO_CALL_ACTIVE" },
+ { 0xC002001B, "RPC_NT_CALL_FAILED" },
+ { 0xC002001C, "RPC_NT_CALL_FAILED_DNE" },
+ { 0xC002001D, "RPC_NT_PROTOCOL_ERROR" },
+ { 0xC002001F, "RPC_NT_UNSUPPORTED_TRANS_SYN" },
+ { 0xC0020021, "RPC_NT_UNSUPPORTED_TYPE" },
+ { 0xC0020022, "RPC_NT_INVALID_TAG" },
+ { 0xC0020023, "RPC_NT_INVALID_BOUND" },
+ { 0xC0020024, "RPC_NT_NO_ENTRY_NAME" },
+ { 0xC0020025, "RPC_NT_INVALID_NAME_SYNTAX" },
+ { 0xC0020026, "RPC_NT_UNSUPPORTED_NAME_SYNTAX" },
+ { 0xC0020028, "RPC_NT_UUID_NO_ADDRESS" },
+ { 0xC0020029, "RPC_NT_DUPLICATE_ENDPOINT" },
+ { 0xC002002A, "RPC_NT_UNKNOWN_AUTHN_TYPE" },
+ { 0xC002002B, "RPC_NT_MAX_CALLS_TOO_SMALL" },
+ { 0xC002002C, "RPC_NT_STRING_TOO_LONG" },
+ { 0xC002002D, "RPC_NT_PROTSEQ_NOT_FOUND" },
+ { 0xC002002E, "RPC_NT_PROCNUM_OUT_OF_RANGE" },
+ { 0xC002002F, "RPC_NT_BINDING_HAS_NO_AUTH" },
+ { 0xC0020030, "RPC_NT_UNKNOWN_AUTHN_SERVICE" },
+ { 0xC0020031, "RPC_NT_UNKNOWN_AUTHN_LEVEL" },
+ { 0xC0020032, "RPC_NT_INVALID_AUTH_IDENTITY" },
+ { 0xC0020033, "RPC_NT_UNKNOWN_AUTHZ_SERVICE" },
+ { 0xC0020034, "EPT_NT_INVALID_ENTRY" },
+ { 0xC0020035, "EPT_NT_CANT_PERFORM_OP" },
+ { 0xC0020036, "EPT_NT_NOT_REGISTERED" },
+ { 0xC0020037, "RPC_NT_NOTHING_TO_EXPORT" },
+ { 0xC0020038, "RPC_NT_INCOMPLETE_NAME" },
+ { 0xC0020039, "RPC_NT_INVALID_VERS_OPTION" },
+ { 0xC002003A, "RPC_NT_NO_MORE_MEMBERS" },
+ { 0xC002003B, "RPC_NT_NOT_ALL_OBJS_UNEXPORTED" },
+ { 0xC002003C, "RPC_NT_INTERFACE_NOT_FOUND" },
+ { 0xC002003D, "RPC_NT_ENTRY_ALREADY_EXISTS" },
+ { 0xC002003E, "RPC_NT_ENTRY_NOT_FOUND" },
+ { 0xC002003F, "RPC_NT_NAME_SERVICE_UNAVAILABLE" },
+ { 0xC0020040, "RPC_NT_INVALID_NAF_ID" },
+ { 0xC0020041, "RPC_NT_CANNOT_SUPPORT" },
+ { 0xC0020042, "RPC_NT_NO_CONTEXT_AVAILABLE" },
+ { 0xC0020043, "RPC_NT_INTERNAL_ERROR" },
+ { 0xC0020044, "RPC_NT_ZERO_DIVIDE" },
+ { 0xC0020045, "RPC_NT_ADDRESS_ERROR" },
+ { 0xC0020046, "RPC_NT_FP_DIV_ZERO" },
+ { 0xC0020047, "RPC_NT_FP_UNDERFLOW" },
+ { 0xC0020048, "RPC_NT_FP_OVERFLOW" },
+ { 0xC0021007, "RPC_P_RECEIVE_ALERTED" },
+ { 0xC0021008, "RPC_P_CONNECTION_CLOSED" },
+ { 0xC0021009, "RPC_P_RECEIVE_FAILED" },
+ { 0xC002100A, "RPC_P_SEND_FAILED" },
+ { 0xC002100B, "RPC_P_TIMEOUT" },
+ { 0xC002100C, "RPC_P_SERVER_TRANSPORT_ERROR" },
+ { 0xC002100E, "RPC_P_EXCEPTION_OCCURED" },
+ { 0xC0021012, "RPC_P_CONNECTION_SHUTDOWN" },
+ { 0xC0021015, "RPC_P_THREAD_LISTENING" },
+ { 0xC0030001, "RPC_NT_NO_MORE_ENTRIES" },
+ { 0xC0030002, "RPC_NT_SS_CHAR_TRANS_OPEN_FAIL" },
+ { 0xC0030003, "RPC_NT_SS_CHAR_TRANS_SHORT_FILE" },
+ { 0xC0030004, "RPC_NT_SS_IN_NULL_CONTEXT" },
+ { 0xC0030005, "RPC_NT_SS_CONTEXT_MISMATCH" },
+ { 0xC0030006, "RPC_NT_SS_CONTEXT_DAMAGED" },
+ { 0xC0030007, "RPC_NT_SS_HANDLES_MISMATCH" },
+ { 0xC0030008, "RPC_NT_SS_CANNOT_GET_CALL_HANDLE" },
+ { 0xC0030009, "RPC_NT_NULL_REF_POINTER" },
+ { 0xC003000A, "RPC_NT_ENUM_VALUE_OUT_OF_RANGE" },
+ { 0xC003000B, "RPC_NT_BYTE_COUNT_TOO_SMALL" },
+ { 0xC003000C, "RPC_NT_BAD_STUB_DATA" },
+ { 0xC0020049, "RPC_NT_CALL_IN_PROGRESS" },
+ { 0xC002004A, "RPC_NT_NO_MORE_BINDINGS" },
+ { 0xC002004B, "RPC_NT_GROUP_MEMBER_NOT_FOUND" },
+ { 0xC002004C, "EPT_NT_CANT_CREATE" },
+ { 0xC002004D, "RPC_NT_INVALID_OBJECT" },
+ { 0xC002004F, "RPC_NT_NO_INTERFACES" },
+ { 0xC0020050, "RPC_NT_CALL_CANCELLED" },
+ { 0xC0020051, "RPC_NT_BINDING_INCOMPLETE" },
+ { 0xC0020052, "RPC_NT_COMM_FAILURE" },
+ { 0xC0020053, "RPC_NT_UNSUPPORTED_AUTHN_LEVEL" },
+ { 0xC0020054, "RPC_NT_NO_PRINC_NAME" },
+ { 0xC0020055, "RPC_NT_NOT_RPC_ERROR" },
+ { 0x40020056, "RPC_NT_UUID_LOCAL_ONLY" },
+ { 0xC0020057, "RPC_NT_SEC_PKG_ERROR" },
+ { 0xC0020058, "RPC_NT_NOT_CANCELLED" },
+ { 0xC0030059, "RPC_NT_INVALID_ES_ACTION" },
+ { 0xC003005A, "RPC_NT_WRONG_ES_VERSION" },
+ { 0xC003005B, "RPC_NT_WRONG_STUB_VERSION" },
+ { 0xC003005C, "RPC_NT_INVALID_PIPE_OBJECT" },
+ { 0xC003005D, "RPC_NT_INVALID_PIPE_OPERATION" },
+ { 0xC003005E, "RPC_NT_WRONG_PIPE_VERSION" },
+ { 0x400200AF, "RPC_NT_SEND_INCOMPLETE" },
+ { 0, NULL }
+};
+
+/*
+ * return an NT error string from a SMB buffer
+ */
+const char *
+nt_errstr(u_int32_t err)
+{
+ static char ret[128];
+ int i;
+
+ ret[0] = 0;
+
+ for (i = 0; nt_errors[i].name; i++) {
+ if (err == nt_errors[i].code)
+ return nt_errors[i].name;
+ }
+
+ snprintf(ret, sizeof(ret), "0x%08x", err);
+ return ret;
+}
diff --git a/freebsd/contrib/tcpdump/tcp.h b/freebsd/contrib/tcpdump/tcp.h
new file mode 100644
index 00000000..92d505ae
--- /dev/null
+++ b/freebsd/contrib/tcpdump/tcp.h
@@ -0,0 +1,112 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/tcp.h,v 1.14 2007-12-09 00:30:47 guy Exp $ (LBL) */
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)tcp.h 8.1 (Berkeley) 6/10/93
+ */
+
+typedef u_int32_t tcp_seq;
+/*
+ * TCP header.
+ * Per RFC 793, September, 1981.
+ */
+struct tcphdr {
+ u_int16_t th_sport; /* source port */
+ u_int16_t th_dport; /* destination port */
+ tcp_seq th_seq; /* sequence number */
+ tcp_seq th_ack; /* acknowledgement number */
+ u_int8_t th_offx2; /* data offset, rsvd */
+ u_int8_t th_flags;
+ u_int16_t th_win; /* window */
+ u_int16_t th_sum; /* checksum */
+ u_int16_t th_urp; /* urgent pointer */
+};
+
+#define TH_OFF(th) (((th)->th_offx2 & 0xf0) >> 4)
+
+/* TCP flags */
+#define TH_FIN 0x01
+#define TH_SYN 0x02
+#define TH_RST 0x04
+#define TH_PUSH 0x08
+#define TH_ACK 0x10
+#define TH_URG 0x20
+#define TH_ECNECHO 0x40 /* ECN Echo */
+#define TH_CWR 0x80 /* ECN Cwnd Reduced */
+
+
+#define TCPOPT_EOL 0
+#define TCPOPT_NOP 1
+#define TCPOPT_MAXSEG 2
+#define TCPOLEN_MAXSEG 4
+#define TCPOPT_WSCALE 3 /* window scale factor (rfc1323) */
+#define TCPOPT_SACKOK 4 /* selective ack ok (rfc2018) */
+#define TCPOPT_SACK 5 /* selective ack (rfc2018) */
+#define TCPOPT_ECHO 6 /* echo (rfc1072) */
+#define TCPOPT_ECHOREPLY 7 /* echo (rfc1072) */
+#define TCPOPT_TIMESTAMP 8 /* timestamp (rfc1323) */
+#define TCPOLEN_TIMESTAMP 10
+#define TCPOLEN_TSTAMP_APPA (TCPOLEN_TIMESTAMP+2) /* appendix A */
+#define TCPOPT_CC 11 /* T/TCP CC options (rfc1644) */
+#define TCPOPT_CCNEW 12 /* T/TCP CC options (rfc1644) */
+#define TCPOPT_CCECHO 13 /* T/TCP CC options (rfc1644) */
+#define TCPOPT_SIGNATURE 19 /* Keyed MD5 (rfc2385) */
+#define TCPOLEN_SIGNATURE 18
+#define TCP_SIGLEN 16 /* length of an option 19 digest */
+#define TCPOPT_AUTH 20 /* Enhanced AUTH option */
+#define TCPOPT_UTO 28 /* tcp user timeout (rfc5482) */
+#define TCPOLEN_UTO 4
+
+
+#define TCPOPT_TSTAMP_HDR \
+ (TCPOPT_NOP<<24|TCPOPT_NOP<<16|TCPOPT_TIMESTAMP<<8|TCPOLEN_TIMESTAMP)
+
+#ifndef TELNET_PORT
+#define TELNET_PORT 23
+#endif
+#ifndef BGP_PORT
+#define BGP_PORT 179
+#endif
+#define NETBIOS_SSN_PORT 139
+#ifndef PPTP_PORT
+#define PPTP_PORT 1723
+#endif
+#define BEEP_PORT 10288
+#ifndef NFS_PORT
+#define NFS_PORT 2049
+#endif
+#define MSDP_PORT 639
+#define RPKI_RTR_PORT 323
+#define LDP_PORT 646
+#ifndef SMB_PORT
+#define SMB_PORT 445
+#endif
diff --git a/freebsd/contrib/tcpdump/tcpdump-stdinc.h b/freebsd/contrib/tcpdump/tcpdump-stdinc.h
new file mode 100644
index 00000000..411326a4
--- /dev/null
+++ b/freebsd/contrib/tcpdump/tcpdump-stdinc.h
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2002 - 2003
+ * NetGroup, Politecnico di Torino (Italy)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the Politecnico di Torino nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * @(#) $Header: /tcpdump/master/tcpdump/tcpdump-stdinc.h,v 1.18 2007-11-24 18:13:33 mcr Exp $ (LBL)
+ */
+
+/*
+ * Include the appropriate OS header files on Windows and various flavors
+ * of UNIX, and also define some additional items and include various
+ * non-OS header files on Windows, and; this isolates most of the platform
+ * differences to this one file.
+ */
+
+#ifndef tcpdump_stdinc_h
+#define tcpdump_stdinc_h
+
+#ifdef WIN32
+
+#include <stdio.h>
+#include <winsock2.h>
+#include <Ws2tcpip.h>
+#include "bittypes.h"
+#include <ctype.h>
+#include <time.h>
+#include <io.h>
+#include <fcntl.h>
+#include <rtems/bsd/sys/types.h>
+#include <net/netdb.h> /* in wpcap's Win32/include */
+
+#ifndef NBBY
+#define NBBY 8
+#endif
+
+#if !defined(__MINGW32__) && !defined(__WATCOMC__)
+#undef toascii
+#define isascii __isascii
+#define toascii __toascii
+#define stat _stat
+#define open _open
+#define fstat _fstat
+#define read _read
+#define close _close
+#define O_RDONLY _O_RDONLY
+
+typedef short ino_t;
+#endif /* __MINGW32__ */
+
+#ifdef __MINGW32__
+#include <stdint.h>
+#endif
+
+/* Protos for missing/x.c functions (ideally <missing/addrinfo.h>
+ * should be used, but it clashes with <ws2tcpip.h>).
+ */
+extern const char *inet_ntop (int, const void *, char *, size_t);
+extern int inet_pton (int, const char *, void *);
+extern int inet_aton (const char *cp, struct in_addr *addr);
+
+#ifndef INET6_ADDRSTRLEN
+#define INET6_ADDRSTRLEN 46
+#endif
+
+#ifndef toascii
+#define toascii(c) ((c) & 0x7f)
+#endif
+
+#ifndef caddr_t
+typedef char* caddr_t;
+#endif /* caddr_t */
+
+#define MAXHOSTNAMELEN 64
+#define NI_MAXHOST 1025
+#define snprintf _snprintf
+#define vsnprintf _vsnprintf
+#define RETSIGTYPE void
+
+#else /* WIN32 */
+
+#include <ctype.h>
+#include <unistd.h>
+#include <netdb.h>
+#if HAVE_INTTYPES_H
+#include <inttypes.h>
+#else
+#if HAVE_STDINT_H
+#include <stdint.h>
+#endif
+#endif
+#ifdef HAVE_SYS_BITYPES_H
+#include <sys/bitypes.h>
+#endif
+#include <rtems/bsd/sys/param.h>
+#include <rtems/bsd/sys/types.h> /* concession to AIX */
+#include <rtems/bsd/sys/time.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#ifdef TIME_WITH_SYS_TIME
+#include <time.h>
+#endif
+
+#include <arpa/inet.h>
+
+#endif /* WIN32 */
+
+#ifndef HAVE___ATTRIBUTE__
+#define __attribute__(x)
+#endif
+
+/*
+ * Used to declare a structure unaligned, so that the C compiler,
+ * if necessary, generates code that doesn't assume alignment.
+ * This is required because there is no guarantee that the packet
+ * data we get from libpcap/WinPcap is properly aligned.
+ *
+ * This assumes that, for all compilers that support __attribute__:
+ *
+ * 1) they support __attribute__((packed));
+ *
+ * 2) for all instruction set architectures requiring strict
+ * alignment, declaring a structure with that attribute
+ * causes the compiler to generate code that handles
+ * misaligned 2-byte, 4-byte, and 8-byte integral
+ * quantities.
+ *
+ * It does not (yet) handle compilers where you can get the compiler
+ * to generate code of that sort by some other means.
+ *
+ * This is required in order to, for example, keep the compiler from
+ * generating, for
+ *
+ * if (bp->bp_htype == 1 && bp->bp_hlen == 6 && bp->bp_op == BOOTPREQUEST) {
+ *
+ * in print-bootp.c, code that loads the first 4-byte word of a
+ * "struct bootp", masking out the bp_hops field, and comparing the result
+ * against 0x01010600.
+ *
+ * Note: this also requires that padding be put into the structure,
+ * at least for compilers where it's implemented as __attribute__((packed)).
+ */
+#define UNALIGNED __attribute__((packed))
+
+#if defined(WIN32) || defined(MSDOS)
+ #define FOPEN_READ_TXT "rt"
+ #define FOPEN_READ_BIN "rb"
+ #define FOPEN_WRITE_TXT "wt"
+ #define FOPEN_WRITE_BIN "wb"
+#else
+ #define FOPEN_READ_TXT "r"
+ #define FOPEN_READ_BIN FOPEN_READ_TXT
+ #define FOPEN_WRITE_TXT "w"
+ #define FOPEN_WRITE_BIN FOPEN_WRITE_TXT
+#endif
+
+#if defined(__GNUC__) && defined(__i386__) && !defined(__APPLE__) && !defined(__ntohl)
+ #undef ntohl
+ #undef ntohs
+ #undef htonl
+ #undef htons
+
+ static __inline__ unsigned long __ntohl (unsigned long x);
+ static __inline__ unsigned short __ntohs (unsigned short x);
+
+ #define ntohl(x) __ntohl(x)
+ #define ntohs(x) __ntohs(x)
+ #define htonl(x) __ntohl(x)
+ #define htons(x) __ntohs(x)
+
+ static __inline__ unsigned long __ntohl (unsigned long x)
+ {
+ __asm__ ("xchgb %b0, %h0\n\t" /* swap lower bytes */
+ "rorl $16, %0\n\t" /* swap words */
+ "xchgb %b0, %h0" /* swap higher bytes */
+ : "=q" (x) : "0" (x));
+ return (x);
+ }
+
+ static __inline__ unsigned short __ntohs (unsigned short x)
+ {
+ __asm__ ("xchgb %b0, %h0" /* swap bytes */
+ : "=q" (x) : "0" (x));
+ return (x);
+ }
+#endif
+
+#ifndef INET_ADDRSTRLEN
+#define INET_ADDRSTRLEN 16
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#endif /* tcpdump_stdinc_h */
diff --git a/freebsd/contrib/tcpdump/tcpdump.c b/freebsd/contrib/tcpdump/tcpdump.c
new file mode 100644
index 00000000..32ffb456
--- /dev/null
+++ b/freebsd/contrib/tcpdump/tcpdump.c
@@ -0,0 +1,2201 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Support for splitting captures into multiple files with a maximum
+ * file size:
+ *
+ * Copyright (c) 2001
+ * Seth Webster <swebster@sst.ll.mit.edu>
+ */
+
+#if 0
+#ifndef lint
+static const char copyright[] _U_ =
+ "@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
+The Regents of the University of California. All rights reserved.\n";
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.283 2008-09-25 21:45:50 guy Exp $ (LBL)";
+#endif
+#endif
+
+/* $FreeBSD$ */
+
+/*
+ * tcpdump - monitor tcp/ip traffic on an ethernet.
+ *
+ * First written in 1987 by Van Jacobson, Lawrence Berkeley Laboratory.
+ * Mercilessly hacked and occasionally improved since then via the
+ * combined efforts of Van, Steve McCanne and Craig Leres of LBL.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#if __rtems__
+#define __need_getopt_newlib
+#include <getopt.h>
+#define setpriority(a, b, c)
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#ifdef WIN32
+#include "getopt.h"
+#include "w32_fzs.h"
+extern int strcasecmp (const char *__s1, const char *__s2);
+extern int SIZE_BUF;
+#define off_t long
+#define uint UINT
+#endif /* WIN32 */
+
+#ifdef HAVE_SMI_H
+#include <smi.h>
+#endif
+
+#include <pcap.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#ifndef WIN32
+#include <sys/wait.h>
+#include <rtems/bsd/sys/resource.h>
+#include <pwd.h>
+#include <grp.h>
+#include <errno.h>
+#endif /* WIN32 */
+
+/* capabilities convinience library */
+#ifdef HAVE_CAP_NG_H
+#include <cap-ng.h>
+#endif /* HAVE_CAP_NG_H */
+
+#include "netdissect.h"
+#include "interface.h"
+#include "addrtoname.h"
+#include "machdep.h"
+#include "setsignal.h"
+#include "gmt2local.h"
+#include "pcap-missing.h"
+
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+
+#ifdef SIGINFO
+#define SIGNAL_REQ_INFO SIGINFO
+#elif SIGUSR1
+#define SIGNAL_REQ_INFO SIGUSR1
+#endif
+
+netdissect_options Gndo;
+netdissect_options *gndo = &Gndo;
+
+static int dflag; /* print filter code */
+static int Lflag; /* list available data link types and exit */
+#ifdef HAVE_PCAP_SET_TSTAMP_TYPE
+static int Jflag; /* list available time stamp types */
+#endif
+static char *zflag = NULL; /* compress each savefile using a specified command (like gzip or bzip2) */
+
+static int infodelay;
+static int infoprint;
+
+char *program_name;
+
+int32_t thiszone; /* seconds offset from gmt to local time */
+
+/* Forwards */
+static RETSIGTYPE cleanup(int);
+static RETSIGTYPE child_cleanup(int);
+static void usage(void) __attribute__((noreturn));
+static void show_dlts_and_exit(const char *device, pcap_t *pd) __attribute__((noreturn));
+
+static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *);
+static void ndo_default_print(netdissect_options *, const u_char *, u_int);
+static void dump_packet_and_trunc(u_char *, const struct pcap_pkthdr *, const u_char *);
+static void dump_packet(u_char *, const struct pcap_pkthdr *, const u_char *);
+static void droproot(const char *, const char *);
+static void ndo_error(netdissect_options *ndo, const char *fmt, ...)
+ __attribute__ ((noreturn, format (printf, 2, 3)));
+static void ndo_warning(netdissect_options *ndo, const char *fmt, ...);
+
+#ifdef SIGNAL_REQ_INFO
+RETSIGTYPE requestinfo(int);
+#endif
+
+#if defined(USE_WIN32_MM_TIMER)
+ #include <MMsystem.h>
+ static UINT timer_id;
+ static void CALLBACK verbose_stats_dump(UINT, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR);
+#elif defined(HAVE_ALARM)
+ static void verbose_stats_dump(int sig);
+#endif
+
+static void info(int);
+static u_int packets_captured;
+
+struct printer {
+ if_printer f;
+ int type;
+};
+
+
+struct ndo_printer {
+ if_ndo_printer f;
+ int type;
+};
+
+
+static const struct printer printers[] = {
+#if !__rtems__
+ { arcnet_if_print, DLT_ARCNET },
+#endif
+#ifdef DLT_ARCNET_LINUX
+ { arcnet_linux_if_print, DLT_ARCNET_LINUX },
+#endif
+#if !__rtems__
+ { token_if_print, DLT_IEEE802 },
+#endif
+#ifdef DLT_LANE8023
+ { lane_if_print, DLT_LANE8023 },
+#endif
+#ifdef DLT_CIP
+ { cip_if_print, DLT_CIP },
+#endif
+#ifdef DLT_ATM_CLIP
+ { cip_if_print, DLT_ATM_CLIP },
+#endif
+ { sl_if_print, DLT_SLIP },
+#ifdef DLT_SLIP_BSDOS
+ { sl_bsdos_if_print, DLT_SLIP_BSDOS },
+#endif
+ { ppp_if_print, DLT_PPP },
+#ifdef DLT_PPP_WITHDIRECTION
+ { ppp_if_print, DLT_PPP_WITHDIRECTION },
+#endif
+#ifdef DLT_PPP_BSDOS
+ { ppp_bsdos_if_print, DLT_PPP_BSDOS },
+#endif
+#if !__rtems__
+ { fddi_if_print, DLT_FDDI },
+#endif
+ { null_if_print, DLT_NULL },
+#ifdef DLT_LOOP
+ { null_if_print, DLT_LOOP },
+#endif
+ { raw_if_print, DLT_RAW },
+#if !__rtems__
+ { atm_if_print, DLT_ATM_RFC1483 },
+#endif
+#ifdef DLT_C_HDLC
+ { chdlc_if_print, DLT_C_HDLC },
+#endif
+#ifdef DLT_HDLC
+ { chdlc_if_print, DLT_HDLC },
+#endif
+#ifdef DLT_PPP_SERIAL
+ { ppp_hdlc_if_print, DLT_PPP_SERIAL },
+#endif
+#ifdef DLT_PPP_ETHER
+ { pppoe_if_print, DLT_PPP_ETHER },
+#endif
+#ifdef DLT_LINUX_SLL
+ { sll_if_print, DLT_LINUX_SLL },
+#endif
+#ifdef DLT_IEEE802_11
+ { ieee802_11_if_print, DLT_IEEE802_11},
+#endif
+#ifdef DLT_LTALK
+ { ltalk_if_print, DLT_LTALK },
+#endif
+#if defined(DLT_PFLOG) && defined(HAVE_NET_PFVAR_H)
+ { pflog_if_print, DLT_PFLOG },
+#endif
+#ifdef DLT_FR
+ { fr_if_print, DLT_FR },
+#endif
+#ifdef DLT_FRELAY
+ { fr_if_print, DLT_FRELAY },
+#endif
+#ifdef DLT_SUNATM
+ { sunatm_if_print, DLT_SUNATM },
+#endif
+#ifdef DLT_IP_OVER_FC
+ { ipfc_if_print, DLT_IP_OVER_FC },
+#endif
+#ifdef DLT_PRISM_HEADER
+ { prism_if_print, DLT_PRISM_HEADER },
+#endif
+#ifdef DLT_IEEE802_11_RADIO
+ { ieee802_11_radio_if_print, DLT_IEEE802_11_RADIO },
+#endif
+#ifdef DLT_ENC
+ { enc_if_print, DLT_ENC },
+#endif
+#ifdef DLT_SYMANTEC_FIREWALL
+ { symantec_if_print, DLT_SYMANTEC_FIREWALL },
+#endif
+#ifdef DLT_APPLE_IP_OVER_IEEE1394
+ { ap1394_if_print, DLT_APPLE_IP_OVER_IEEE1394 },
+#endif
+#ifdef DLT_IEEE802_11_RADIO_AVS
+ { ieee802_11_radio_avs_if_print, DLT_IEEE802_11_RADIO_AVS },
+#endif
+#ifdef DLT_JUNIPER_ATM1
+ { juniper_atm1_print, DLT_JUNIPER_ATM1 },
+#endif
+#ifdef DLT_JUNIPER_ATM2
+ { juniper_atm2_print, DLT_JUNIPER_ATM2 },
+#endif
+#ifdef DLT_JUNIPER_MFR
+ { juniper_mfr_print, DLT_JUNIPER_MFR },
+#endif
+#ifdef DLT_JUNIPER_MLFR
+ { juniper_mlfr_print, DLT_JUNIPER_MLFR },
+#endif
+#ifdef DLT_JUNIPER_MLPPP
+ { juniper_mlppp_print, DLT_JUNIPER_MLPPP },
+#endif
+#ifdef DLT_JUNIPER_PPPOE
+ { juniper_pppoe_print, DLT_JUNIPER_PPPOE },
+#endif
+#ifdef DLT_JUNIPER_PPPOE_ATM
+ { juniper_pppoe_atm_print, DLT_JUNIPER_PPPOE_ATM },
+#endif
+#ifdef DLT_JUNIPER_GGSN
+ { juniper_ggsn_print, DLT_JUNIPER_GGSN },
+#endif
+#ifdef DLT_JUNIPER_ES
+ { juniper_es_print, DLT_JUNIPER_ES },
+#endif
+#ifdef DLT_JUNIPER_MONITOR
+ { juniper_monitor_print, DLT_JUNIPER_MONITOR },
+#endif
+#ifdef DLT_JUNIPER_SERVICES
+ { juniper_services_print, DLT_JUNIPER_SERVICES },
+#endif
+#ifdef DLT_JUNIPER_ETHER
+ { juniper_ether_print, DLT_JUNIPER_ETHER },
+#endif
+#ifdef DLT_JUNIPER_PPP
+ { juniper_ppp_print, DLT_JUNIPER_PPP },
+#endif
+#ifdef DLT_JUNIPER_FRELAY
+ { juniper_frelay_print, DLT_JUNIPER_FRELAY },
+#endif
+#ifdef DLT_JUNIPER_CHDLC
+ { juniper_chdlc_print, DLT_JUNIPER_CHDLC },
+#endif
+#ifdef DLT_MFR
+ { mfr_if_print, DLT_MFR },
+#endif
+#if defined(DLT_BLUETOOTH_HCI_H4_WITH_PHDR) && defined(HAVE_PCAP_BLUETOOTH_H)
+ { bt_if_print, DLT_BLUETOOTH_HCI_H4_WITH_PHDR},
+#endif
+#ifdef HAVE_PCAP_USB_H
+#ifdef DLT_USB_LINUX
+ { usb_linux_48_byte_print, DLT_USB_LINUX},
+#endif /* DLT_USB_LINUX */
+#ifdef DLT_USB_LINUX_MMAPPED
+ { usb_linux_64_byte_print, DLT_USB_LINUX_MMAPPED},
+#endif /* DLT_USB_LINUX_MMAPPED */
+#endif /* HAVE_PCAP_USB_H */
+#ifdef DLT_IPV4
+ { raw_if_print, DLT_IPV4 },
+#endif
+#ifdef DLT_IPV6
+ { raw_if_print, DLT_IPV6 },
+#endif
+ { NULL, 0 },
+};
+
+static const struct ndo_printer ndo_printers[] = {
+ { ether_if_print, DLT_EN10MB },
+#ifdef DLT_IPNET
+ { ipnet_if_print, DLT_IPNET },
+#endif
+#ifdef DLT_IEEE802_15_4
+ { ieee802_15_4_if_print, DLT_IEEE802_15_4 },
+#endif
+#ifdef DLT_IEEE802_15_4_NOFCS
+ { ieee802_15_4_if_print, DLT_IEEE802_15_4_NOFCS },
+#endif
+#ifdef DLT_PPI
+ { ppi_if_print, DLT_PPI },
+#endif
+#ifdef DLT_NETANALYZER
+ { netanalyzer_if_print, DLT_NETANALYZER },
+#endif
+#ifdef DLT_NETANALYZER_TRANSPARENT
+ { netanalyzer_transparent_if_print, DLT_NETANALYZER_TRANSPARENT },
+#endif
+ { NULL, 0 },
+};
+
+if_printer
+lookup_printer(int type)
+{
+ struct printer *p;
+
+ for (p = printers; p->f; ++p)
+ if (type == p->type)
+ return p->f;
+
+ return NULL;
+ /* NOTREACHED */
+}
+
+if_ndo_printer
+lookup_ndo_printer(int type)
+{
+ struct ndo_printer *p;
+
+ for (p = ndo_printers; p->f; ++p)
+ if (type == p->type)
+ return p->f;
+
+ return NULL;
+ /* NOTREACHED */
+}
+
+static pcap_t *pd;
+
+static int supports_monitor_mode;
+
+#ifdef __rtems__
+#define optind getopt_data.optind
+#define optarg getopt_data.optarg
+#define opterr getopt_data.opterr
+#define optopt getopt_data.optopt
+#define getopt(argc, argv, opt) getopt_r(argc, argv, "+" opt, &getopt_data)
+#else
+extern int optind;
+extern int opterr;
+extern char *optarg;
+#endif
+
+struct print_info {
+ netdissect_options *ndo;
+ union {
+ if_printer printer;
+ if_ndo_printer ndo_printer;
+ } p;
+ int ndo_type;
+};
+
+struct dump_info {
+ char *WFileName;
+ char *CurrentFileName;
+ pcap_t *pd;
+ pcap_dumper_t *p;
+};
+
+#ifdef HAVE_PCAP_SET_TSTAMP_TYPE
+static void
+show_tstamp_types_and_exit(const char *device, pcap_t *pd)
+{
+ int n_tstamp_types;
+ int *tstamp_types = 0;
+ const char *tstamp_type_name;
+ int i;
+
+ n_tstamp_types = pcap_list_tstamp_types(pd, &tstamp_types);
+ if (n_tstamp_types < 0)
+ error("%s", pcap_geterr(pd));
+
+ if (n_tstamp_types == 0) {
+ fprintf(stderr, "Time stamp type cannot be set for %s\n",
+ device);
+ exit(0);
+ }
+ fprintf(stderr, "Time stamp types for %s (use option -j to set):\n",
+ device);
+ for (i = 0; i < n_tstamp_types; i++) {
+ tstamp_type_name = pcap_tstamp_type_val_to_name(tstamp_types[i]);
+ if (tstamp_type_name != NULL) {
+ (void) fprintf(stderr, " %s (%s)\n", tstamp_type_name,
+ pcap_tstamp_type_val_to_description(tstamp_types[i]));
+ } else {
+ (void) fprintf(stderr, " %d\n", tstamp_types[i]);
+ }
+ }
+ pcap_free_tstamp_types(tstamp_types);
+ exit(0);
+}
+#endif
+
+static void
+show_dlts_and_exit(const char *device, pcap_t *pd)
+{
+ int n_dlts;
+ int *dlts = 0;
+ const char *dlt_name;
+
+ n_dlts = pcap_list_datalinks(pd, &dlts);
+ if (n_dlts < 0)
+ error("%s", pcap_geterr(pd));
+ else if (n_dlts == 0 || !dlts)
+ error("No data link types.");
+
+ /*
+ * If the interface is known to support monitor mode, indicate
+ * whether these are the data link types available when not in
+ * monitor mode, if -I wasn't specified, or when in monitor mode,
+ * when -I was specified (the link-layer types available in
+ * monitor mode might be different from the ones available when
+ * not in monitor mode).
+ */
+ if (supports_monitor_mode)
+ (void) fprintf(stderr, "Data link types for %s %s (use option -y to set):\n",
+ device,
+ Iflag ? "when in monitor mode" : "when not in monitor mode");
+ else
+ (void) fprintf(stderr, "Data link types for %s (use option -y to set):\n",
+ device);
+
+ while (--n_dlts >= 0) {
+ dlt_name = pcap_datalink_val_to_name(dlts[n_dlts]);
+ if (dlt_name != NULL) {
+ (void) fprintf(stderr, " %s (%s)", dlt_name,
+ pcap_datalink_val_to_description(dlts[n_dlts]));
+
+ /*
+ * OK, does tcpdump handle that type?
+ */
+ if (lookup_printer(dlts[n_dlts]) == NULL
+ && lookup_ndo_printer(dlts[n_dlts]) == NULL)
+ (void) fprintf(stderr, " (printing not supported)");
+ fprintf(stderr, "\n");
+ } else {
+ (void) fprintf(stderr, " DLT %d (printing not supported)\n",
+ dlts[n_dlts]);
+ }
+ }
+#ifdef HAVE_PCAP_FREE_DATALINKS
+ pcap_free_datalinks(dlts);
+#endif
+ exit(0);
+}
+
+/*
+ * Set up flags that might or might not be supported depending on the
+ * version of libpcap we're using.
+ */
+#if defined(HAVE_PCAP_CREATE) || defined(WIN32)
+#define B_FLAG "B:"
+#define B_FLAG_USAGE " [ -B size ]"
+#else /* defined(HAVE_PCAP_CREATE) || defined(WIN32) */
+#define B_FLAG
+#define B_FLAG_USAGE
+#endif /* defined(HAVE_PCAP_CREATE) || defined(WIN32) */
+
+#ifdef HAVE_PCAP_CREATE
+#define I_FLAG "I"
+#else /* HAVE_PCAP_CREATE */
+#define I_FLAG
+#endif /* HAVE_PCAP_CREATE */
+
+#ifdef HAVE_PCAP_SET_TSTAMP_TYPE
+#define j_FLAG "j:"
+#define j_FLAG_USAGE " [ -j tstamptype ]"
+#define J_FLAG "J"
+#else /* PCAP_ERROR_TSTAMP_TYPE_NOTSUP */
+#define j_FLAG
+#define j_FLAG_USAGE
+#define J_FLAG
+#endif /* PCAP_ERROR_TSTAMP_TYPE_NOTSUP */
+
+#ifdef HAVE_PCAP_FINDALLDEVS
+#ifndef HAVE_PCAP_IF_T
+#undef HAVE_PCAP_FINDALLDEVS
+#endif
+#endif
+
+#ifdef HAVE_PCAP_FINDALLDEVS
+#define D_FLAG "D"
+#else
+#define D_FLAG
+#endif
+
+#ifdef HAVE_PCAP_DUMP_FLUSH
+#define U_FLAG "U"
+#else
+#define U_FLAG
+#endif
+
+#ifndef WIN32
+/* Drop root privileges and chroot if necessary */
+static void
+droproot(const char *username, const char *chroot_dir)
+{
+ struct passwd *pw = NULL;
+
+ if (chroot_dir && !username) {
+ fprintf(stderr, "tcpdump: Chroot without dropping root is insecure\n");
+ exit(1);
+ }
+
+ pw = getpwnam(username);
+ if (pw) {
+ if (chroot_dir) {
+ if (chroot(chroot_dir) != 0 || chdir ("/") != 0) {
+ fprintf(stderr, "tcpdump: Couldn't chroot/chdir to '%.64s': %s\n",
+ chroot_dir, pcap_strerror(errno));
+ exit(1);
+ }
+ }
+#ifdef HAVE_CAP_NG_H
+ int ret = capng_change_id(pw->pw_uid, pw->pw_gid, CAPNG_NO_FLAG);
+ if (ret < 0) {
+ printf("error : ret %d\n", ret);
+ }
+ /* We don't need CAP_SETUID and CAP_SETGID */
+ capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_SETUID);
+ capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_SETUID);
+ capng_update(CAPNG_DROP, CAPNG_PERMITTED, CAP_SETUID);
+ capng_update(CAPNG_DROP, CAPNG_PERMITTED, CAP_SETUID);
+ capng_apply(CAPNG_SELECT_BOTH);
+
+#else
+#ifndef __rtems__
+ if (initgroups(pw->pw_name, pw->pw_gid) != 0 ||
+ setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) {
+ fprintf(stderr, "tcpdump: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n",
+ username,
+ (unsigned long)pw->pw_uid,
+ (unsigned long)pw->pw_gid,
+ pcap_strerror(errno));
+ exit(1);
+ }
+#endif
+#endif /* HAVE_CAP_NG_H */
+ }
+ else {
+ fprintf(stderr, "tcpdump: Couldn't find user '%.32s'\n",
+ username);
+ exit(1);
+ }
+}
+#endif /* WIN32 */
+
+static int
+getWflagChars(int x)
+{
+ int c = 0;
+
+ x -= 1;
+ while (x > 0) {
+ c += 1;
+ x /= 10;
+ }
+
+ return c;
+}
+
+
+static void
+MakeFilename(char *buffer, char *orig_name, int cnt, int max_chars)
+{
+ char *filename = malloc(PATH_MAX + 1);
+ if (filename == NULL)
+ error("Makefilename: malloc");
+
+ /* Process with strftime if Gflag is set. */
+ if (Gflag != 0) {
+ struct tm *local_tm;
+
+ /* Convert Gflag_time to a usable format */
+ if ((local_tm = localtime(&Gflag_time)) == NULL) {
+ error("MakeTimedFilename: localtime");
+ }
+
+ /* There's no good way to detect an error in strftime since a return
+ * value of 0 isn't necessarily failure.
+ */
+ strftime(filename, PATH_MAX, orig_name, local_tm);
+ } else {
+ strncpy(filename, orig_name, PATH_MAX);
+ }
+
+ if (cnt == 0 && max_chars == 0)
+ strncpy(buffer, filename, PATH_MAX + 1);
+ else
+ if (snprintf(buffer, PATH_MAX + 1, "%s%0*d", filename, max_chars, cnt) > PATH_MAX)
+ /* Report an error if the filename is too large */
+ error("too many output files or filename is too long (> %d)", PATH_MAX);
+ free(filename);
+}
+
+static int tcpdump_printf(netdissect_options *ndo _U_,
+ const char *fmt, ...)
+{
+
+ va_list args;
+ int ret;
+
+ va_start(args, fmt);
+ ret=vfprintf(stdout, fmt, args);
+ va_end(args);
+
+ return ret;
+}
+
+static struct print_info
+get_print_info(int type)
+{
+ struct print_info printinfo;
+
+ printinfo.ndo_type = 1;
+ printinfo.ndo = gndo;
+ printinfo.p.ndo_printer = lookup_ndo_printer(type);
+ if (printinfo.p.ndo_printer == NULL) {
+ printinfo.p.printer = lookup_printer(type);
+ printinfo.ndo_type = 0;
+ if (printinfo.p.printer == NULL) {
+ gndo->ndo_dltname = pcap_datalink_val_to_name(type);
+ if (gndo->ndo_dltname != NULL)
+ error("packet printing is not supported for link type %s: use -w",
+ gndo->ndo_dltname);
+ else
+ error("packet printing is not supported for link type %d: use -w", type);
+ }
+ }
+ return (printinfo);
+}
+
+static char *
+get_next_file(FILE *VFile, char *ptr)
+{
+ char *ret;
+
+ ret = fgets(ptr, PATH_MAX, VFile);
+ if (!ret)
+ return NULL;
+
+ if (ptr[strlen(ptr) - 1] == '\n')
+ ptr[strlen(ptr) - 1] = '\0';
+
+ return ret;
+}
+
+#ifdef __rtems__
+static int main(int argc, char **argv);
+
+int rtems_bsd_command_tcpdump(int argc, char *argv[])
+{
+ int exit_code;
+
+ rtems_bsd_program_lock();
+
+ dflag = 0;
+ Lflag = 0;
+#ifdef HAVE_PCAP_SET_TSTAMP_TYPE
+ Jflag = 0;
+#endif
+ zflag = NULL;
+ infodelay = 0;
+ infoprint = 0;
+ program_name = NULL;
+ thiszone = 0;
+ packets_captured = 0;
+ pd = 0;
+ supports_monitor_mode = 0;
+
+ exit_code = rtems_bsd_program_call_main("tcpdump", main, argc, argv);
+
+ rtems_bsd_program_unlock();
+
+ return exit_code;
+}
+#endif /* __rtems__ */
+int
+#ifndef __rtems__
+main(int argc, char *const *argv)
+#else /* __rtems__ */
+main(int argc, char **argv)
+#endif /* __rtems__ */
+{
+ register int cnt, op, i;
+ bpf_u_int32 localnet, netmask;
+ register char *cp, *infile, *cmdbuf, *device, *RFileName, *VFileName, *WFileName;
+ pcap_handler callback;
+ int type;
+ int dlt;
+ int new_dlt;
+ const char *dlt_name;
+ struct bpf_program fcode;
+#ifndef WIN32
+ RETSIGTYPE (*oldhandler)(int);
+#endif
+ struct print_info printinfo;
+ struct dump_info dumpinfo;
+ u_char *pcap_userdata;
+ char ebuf[PCAP_ERRBUF_SIZE];
+ char VFileLine[PATH_MAX + 1];
+ char *username = NULL;
+ char *chroot_dir = NULL;
+ char *ret = NULL;
+ char *end;
+#ifdef HAVE_PCAP_FINDALLDEVS
+ pcap_if_t *devpointer;
+ int devnum;
+#endif
+ int status;
+ FILE *VFile;
+#ifdef __rtems__
+ struct getopt_data getopt_data;
+ memset(&getopt_data, 0, sizeof(getopt_data));
+#endif
+#ifdef WIN32
+ if(wsockinit() != 0) return 1;
+#endif /* WIN32 */
+
+ jflag=-1; /* not set */
+ gndo->ndo_Oflag=1;
+ gndo->ndo_Rflag=1;
+ gndo->ndo_dlt=-1;
+ gndo->ndo_default_print=ndo_default_print;
+ gndo->ndo_printf=tcpdump_printf;
+ gndo->ndo_error=ndo_error;
+ gndo->ndo_warning=ndo_warning;
+ gndo->ndo_snaplen = DEFAULT_SNAPLEN;
+
+ cnt = -1;
+ device = NULL;
+ infile = NULL;
+ RFileName = NULL;
+ VFileName = NULL;
+ VFile = NULL;
+ WFileName = NULL;
+ dlt = -1;
+ if ((cp = strrchr(argv[0], '/')) != NULL)
+ program_name = cp + 1;
+ else
+ program_name = argv[0];
+
+ if (abort_on_misalignment(ebuf, sizeof(ebuf)) < 0)
+ error("%s", ebuf);
+
+#ifdef LIBSMI
+ smiInit("tcpdump");
+#endif
+
+ while (
+ (op = getopt(argc, argv, "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hHi:" I_FLAG j_FLAG J_FLAG "KlLm:M:nNOpqr:Rs:StT:u" U_FLAG "V:vw:W:xXy:Yz:Z:")) != -1)
+ switch (op) {
+
+ case 'a':
+ /* compatibility for old -a */
+ break;
+
+ case 'A':
+ ++Aflag;
+ break;
+
+ case 'b':
+ ++bflag;
+ break;
+
+#if defined(HAVE_PCAP_CREATE) || defined(WIN32)
+ case 'B':
+ Bflag = atoi(optarg)*1024;
+ if (Bflag <= 0)
+ error("invalid packet buffer size %s", optarg);
+ break;
+#endif /* defined(HAVE_PCAP_CREATE) || defined(WIN32) */
+
+ case 'c':
+ cnt = atoi(optarg);
+ if (cnt <= 0)
+ error("invalid packet count %s", optarg);
+ break;
+
+ case 'C':
+ Cflag = atoi(optarg) * 1000000;
+ if (Cflag < 0)
+ error("invalid file size %s", optarg);
+ break;
+
+ case 'd':
+ ++dflag;
+ break;
+
+#ifdef HAVE_PCAP_FINDALLDEVS
+ case 'D':
+ if (pcap_findalldevs(&devpointer, ebuf) < 0)
+ error("%s", ebuf);
+ else {
+ for (i = 0; devpointer != 0; i++) {
+ printf("%d.%s", i+1, devpointer->name);
+ if (devpointer->description != NULL)
+ printf(" (%s)", devpointer->description);
+ printf("\n");
+ devpointer = devpointer->next;
+ }
+ }
+ return 0;
+#endif /* HAVE_PCAP_FINDALLDEVS */
+
+ case 'L':
+ Lflag++;
+ break;
+
+ case 'e':
+ ++eflag;
+ break;
+
+ case 'E':
+#ifndef HAVE_LIBCRYPTO
+ warning("crypto code not compiled in");
+#endif
+ gndo->ndo_espsecret = optarg;
+ break;
+
+ case 'f':
+ ++fflag;
+ break;
+
+ case 'F':
+ infile = optarg;
+ break;
+
+ case 'G':
+ Gflag = atoi(optarg);
+ if (Gflag < 0)
+ error("invalid number of seconds %s", optarg);
+
+ /* We will create one file initially. */
+ Gflag_count = 0;
+
+ /* Grab the current time for rotation use. */
+ if ((Gflag_time = time(NULL)) == (time_t)-1) {
+ error("main: can't get current time: %s",
+ pcap_strerror(errno));
+ }
+ break;
+
+ case 'h':
+ usage();
+ break;
+
+ case 'H':
+ ++Hflag;
+ break;
+
+ case 'i':
+ if (optarg[0] == '0' && optarg[1] == 0)
+ error("Invalid adapter index");
+
+#ifdef HAVE_PCAP_FINDALLDEVS
+ /*
+ * If the argument is a number, treat it as
+ * an index into the list of adapters, as
+ * printed by "tcpdump -D".
+ *
+ * This should be OK on UNIX systems, as interfaces
+ * shouldn't have names that begin with digits.
+ * It can be useful on Windows, where more than
+ * one interface can have the same name.
+ */
+ devnum = strtol(optarg, &end, 10);
+ if (optarg != end && *end == '\0') {
+ if (devnum < 0)
+ error("Invalid adapter index");
+
+ if (pcap_findalldevs(&devpointer, ebuf) < 0)
+ error("%s", ebuf);
+ else {
+ /*
+ * Look for the devnum-th entry
+ * in the list of devices
+ * (1-based).
+ */
+ for (i = 0;
+ i < devnum-1 && devpointer != NULL;
+ i++, devpointer = devpointer->next)
+ ;
+ if (devpointer == NULL)
+ error("Invalid adapter index");
+ }
+ device = devpointer->name;
+ break;
+ }
+#endif /* HAVE_PCAP_FINDALLDEVS */
+ device = optarg;
+ break;
+
+#ifdef HAVE_PCAP_CREATE
+ case 'I':
+ ++Iflag;
+ break;
+#endif /* HAVE_PCAP_CREATE */
+
+#ifdef HAVE_PCAP_SET_TSTAMP_TYPE
+ case 'j':
+ jflag = pcap_tstamp_type_name_to_val(optarg);
+ if (jflag < 0)
+ error("invalid time stamp type %s", optarg);
+ break;
+
+ case 'J':
+ Jflag++;
+ break;
+#endif
+
+ case 'l':
+#ifdef WIN32
+ /*
+ * _IOLBF is the same as _IOFBF in Microsoft's C
+ * libraries; the only alternative they offer
+ * is _IONBF.
+ *
+ * XXX - this should really be checking for MSVC++,
+ * not WIN32, if, for example, MinGW has its own
+ * C library that is more UNIX-compatible.
+ */
+ setvbuf(stdout, NULL, _IONBF, 0);
+#else /* WIN32 */
+#ifdef HAVE_SETLINEBUF
+ setlinebuf(stdout);
+#else
+ setvbuf(stdout, NULL, _IOLBF, 0);
+#endif
+#endif /* WIN32 */
+ break;
+
+ case 'K':
+ ++Kflag;
+ break;
+
+ case 'm':
+#ifdef LIBSMI
+ if (smiLoadModule(optarg) == 0) {
+ error("could not load MIB module %s", optarg);
+ }
+ sflag = 1;
+#else
+ (void)fprintf(stderr, "%s: ignoring option `-m %s' ",
+ program_name, optarg);
+ (void)fprintf(stderr, "(no libsmi support)\n");
+#endif
+ break;
+
+ case 'M':
+ /* TCP-MD5 shared secret */
+#ifndef HAVE_LIBCRYPTO
+ warning("crypto code not compiled in");
+#endif
+ sigsecret = optarg;
+ break;
+
+ case 'n':
+ ++nflag;
+ break;
+
+ case 'N':
+ ++Nflag;
+ break;
+
+ case 'O':
+ Oflag = 0;
+ break;
+
+ case 'p':
+ ++pflag;
+ break;
+
+ case 'q':
+ ++qflag;
+ ++suppress_default_print;
+ break;
+
+ case 'r':
+ RFileName = optarg;
+ break;
+
+ case 'R':
+ Rflag = 0;
+ break;
+
+ case 's':
+ snaplen = strtol(optarg, &end, 0);
+ if (optarg == end || *end != '\0'
+ || snaplen < 0 || snaplen > MAXIMUM_SNAPLEN)
+ error("invalid snaplen %s", optarg);
+ else if (snaplen == 0)
+ snaplen = MAXIMUM_SNAPLEN;
+ break;
+
+ case 'S':
+ ++Sflag;
+ break;
+
+ case 't':
+ ++tflag;
+ break;
+
+ case 'T':
+ if (strcasecmp(optarg, "vat") == 0)
+ packettype = PT_VAT;
+ else if (strcasecmp(optarg, "wb") == 0)
+ packettype = PT_WB;
+ else if (strcasecmp(optarg, "rpc") == 0)
+ packettype = PT_RPC;
+ else if (strcasecmp(optarg, "rtp") == 0)
+ packettype = PT_RTP;
+ else if (strcasecmp(optarg, "rtcp") == 0)
+ packettype = PT_RTCP;
+ else if (strcasecmp(optarg, "snmp") == 0)
+ packettype = PT_SNMP;
+ else if (strcasecmp(optarg, "cnfp") == 0)
+ packettype = PT_CNFP;
+ else if (strcasecmp(optarg, "tftp") == 0)
+ packettype = PT_TFTP;
+ else if (strcasecmp(optarg, "aodv") == 0)
+ packettype = PT_AODV;
+ else if (strcasecmp(optarg, "carp") == 0)
+ packettype = PT_CARP;
+ else if (strcasecmp(optarg, "radius") == 0)
+ packettype = PT_RADIUS;
+ else if (strcasecmp(optarg, "zmtp1") == 0)
+ packettype = PT_ZMTP1;
+ else if (strcasecmp(optarg, "vxlan") == 0)
+ packettype = PT_VXLAN;
+ else
+ error("unknown packet type `%s'", optarg);
+ break;
+
+ case 'u':
+ ++uflag;
+ break;
+
+#ifdef HAVE_PCAP_DUMP_FLUSH
+ case 'U':
+ ++Uflag;
+ break;
+#endif
+
+ case 'v':
+ ++vflag;
+ break;
+
+ case 'V':
+ VFileName = optarg;
+ break;
+
+ case 'w':
+ WFileName = optarg;
+ break;
+
+ case 'W':
+ Wflag = atoi(optarg);
+ if (Wflag < 0)
+ error("invalid number of output files %s", optarg);
+ WflagChars = getWflagChars(Wflag);
+ break;
+
+ case 'x':
+ ++xflag;
+ ++suppress_default_print;
+ break;
+
+ case 'X':
+ ++Xflag;
+ ++suppress_default_print;
+ break;
+
+ case 'y':
+ gndo->ndo_dltname = optarg;
+ gndo->ndo_dlt =
+ pcap_datalink_name_to_val(gndo->ndo_dltname);
+ if (gndo->ndo_dlt < 0)
+ error("invalid data link type %s", gndo->ndo_dltname);
+ break;
+
+#if defined(HAVE_PCAP_DEBUG) || defined(HAVE_YYDEBUG)
+ case 'Y':
+ {
+ /* Undocumented flag */
+#ifdef HAVE_PCAP_DEBUG
+ extern int pcap_debug;
+ pcap_debug = 1;
+#else
+ extern int yydebug;
+ yydebug = 1;
+#endif
+ }
+ break;
+#endif
+ case 'z':
+ if (optarg) {
+ zflag = strdup(optarg);
+ } else {
+ usage();
+ /* NOTREACHED */
+ }
+ break;
+
+ case 'Z':
+ if (optarg) {
+ username = strdup(optarg);
+ }
+ else {
+ usage();
+ /* NOTREACHED */
+ }
+ break;
+
+ default:
+ usage();
+ /* NOTREACHED */
+ }
+
+ switch (tflag) {
+
+ case 0: /* Default */
+ case 4: /* Default + Date*/
+ thiszone = gmt2local(0);
+ break;
+
+ case 1: /* No time stamp */
+ case 2: /* Unix timeval style */
+ case 3: /* Microseconds since previous packet */
+ case 5: /* Microseconds since first packet */
+ break;
+
+ default: /* Not supported */
+ error("only -t, -tt, -ttt, -tttt and -ttttt are supported");
+ break;
+ }
+
+ if (fflag != 0 && (VFileName != NULL || RFileName != NULL))
+ error("-f can not be used with -V or -r");
+
+ if (VFileName != NULL && RFileName != NULL)
+ error("-V and -r are mutually exclusive.");
+
+#ifdef WITH_CHROOT
+ /* if run as root, prepare for chrooting */
+ if (getuid() == 0 || geteuid() == 0) {
+ /* future extensibility for cmd-line arguments */
+ if (!chroot_dir)
+ chroot_dir = WITH_CHROOT;
+ }
+#endif
+
+#ifdef WITH_USER
+ /* if run as root, prepare for dropping root privileges */
+ if (getuid() == 0 || geteuid() == 0) {
+ /* Run with '-Z root' to restore old behaviour */
+ if (!username)
+ username = WITH_USER;
+ }
+#endif
+
+ if (RFileName != NULL || VFileName != NULL) {
+ /*
+ * If RFileName is non-null, it's the pathname of a
+ * savefile to read. If VFileName is non-null, it's
+ * the pathname of a file containing a list of pathnames
+ * (one per line) of savefiles to read.
+ *
+ * In either case, we're reading a savefile, not doing
+ * a live capture.
+ */
+#ifndef WIN32
+ /*
+ * We don't need network access, so relinquish any set-UID
+ * or set-GID privileges we have (if any).
+ *
+ * We do *not* want set-UID privileges when opening a
+ * trace file, as that might let the user read other
+ * people's trace files (especially if we're set-UID
+ * root).
+ */
+ if (setgid(getgid()) != 0 || setuid(getuid()) != 0 )
+ fprintf(stderr, "Warning: setgid/setuid failed !\n");
+#endif /* WIN32 */
+ if (VFileName != NULL) {
+ if (VFileName[0] == '-' && VFileName[1] == '\0')
+ VFile = stdin;
+ else
+ VFile = fopen(VFileName, "r");
+
+ if (VFile == NULL)
+ error("Unable to open file: %s\n", strerror(errno));
+
+ ret = get_next_file(VFile, VFileLine);
+ if (!ret)
+ error("Nothing in %s\n", VFileName);
+ RFileName = VFileLine;
+ }
+
+ pd = pcap_open_offline(RFileName, ebuf);
+ if (pd == NULL)
+ error("%s", ebuf);
+ dlt = pcap_datalink(pd);
+ dlt_name = pcap_datalink_val_to_name(dlt);
+ if (dlt_name == NULL) {
+ fprintf(stderr, "reading from file %s, link-type %u\n",
+ RFileName, dlt);
+ } else {
+ fprintf(stderr,
+ "reading from file %s, link-type %s (%s)\n",
+ RFileName, dlt_name,
+ pcap_datalink_val_to_description(dlt));
+ }
+ localnet = 0;
+ netmask = 0;
+ } else {
+ /*
+ * We're doing a live capture.
+ */
+ if (device == NULL) {
+ device = pcap_lookupdev(ebuf);
+ if (device == NULL)
+ error("%s", ebuf);
+ }
+#ifdef WIN32
+ /*
+ * Print a message to the standard error on Windows.
+ * XXX - why do it here, with a different message?
+ */
+ if(strlen(device) == 1) //we assume that an ASCII string is always longer than 1 char
+ { //a Unicode string has a \0 as second byte (so strlen() is 1)
+ fprintf(stderr, "%s: listening on %ws\n", program_name, device);
+ }
+ else
+ {
+ fprintf(stderr, "%s: listening on %s\n", program_name, device);
+ }
+
+ fflush(stderr);
+#endif /* WIN32 */
+#ifdef HAVE_PCAP_CREATE
+ pd = pcap_create(device, ebuf);
+ if (pd == NULL)
+ error("%s", ebuf);
+#ifdef HAVE_PCAP_SET_TSTAMP_TYPE
+ if (Jflag)
+ show_tstamp_types_and_exit(device, pd);
+#endif
+ /*
+ * Is this an interface that supports monitor mode?
+ */
+ if (pcap_can_set_rfmon(pd) == 1)
+ supports_monitor_mode = 1;
+ else
+ supports_monitor_mode = 0;
+ status = pcap_set_snaplen(pd, snaplen);
+ if (status != 0)
+ error("%s: Can't set snapshot length: %s",
+ device, pcap_statustostr(status));
+ status = pcap_set_promisc(pd, !pflag);
+ if (status != 0)
+ error("%s: Can't set promiscuous mode: %s",
+ device, pcap_statustostr(status));
+ if (Iflag) {
+ status = pcap_set_rfmon(pd, 1);
+ if (status != 0)
+ error("%s: Can't set monitor mode: %s",
+ device, pcap_statustostr(status));
+ }
+ status = pcap_set_timeout(pd, 1000);
+ if (status != 0)
+ error("%s: pcap_set_timeout failed: %s",
+ device, pcap_statustostr(status));
+ if (Bflag != 0) {
+ status = pcap_set_buffer_size(pd, Bflag);
+ if (status != 0)
+ error("%s: Can't set buffer size: %s",
+ device, pcap_statustostr(status));
+ }
+#ifdef HAVE_PCAP_SET_TSTAMP_TYPE
+ if (jflag != -1) {
+ status = pcap_set_tstamp_type(pd, jflag);
+ if (status < 0)
+ error("%s: Can't set time stamp type: %s",
+ device, pcap_statustostr(status));
+ }
+#endif
+ status = pcap_activate(pd);
+ if (status < 0) {
+ /*
+ * pcap_activate() failed.
+ */
+ cp = pcap_geterr(pd);
+ if (status == PCAP_ERROR)
+ error("%s", cp);
+ else if ((status == PCAP_ERROR_NO_SUCH_DEVICE ||
+ status == PCAP_ERROR_PERM_DENIED) &&
+ *cp != '\0')
+ error("%s: %s\n(%s)", device,
+ pcap_statustostr(status), cp);
+ else
+ error("%s: %s", device,
+ pcap_statustostr(status));
+ } else if (status > 0) {
+ /*
+ * pcap_activate() succeeded, but it's warning us
+ * of a problem it had.
+ */
+ cp = pcap_geterr(pd);
+ if (status == PCAP_WARNING)
+ warning("%s", cp);
+ else if (status == PCAP_WARNING_PROMISC_NOTSUP &&
+ *cp != '\0')
+ warning("%s: %s\n(%s)", device,
+ pcap_statustostr(status), cp);
+ else
+ warning("%s: %s", device,
+ pcap_statustostr(status));
+ }
+#else
+ *ebuf = '\0';
+ pd = pcap_open_live(device, snaplen, !pflag, 1000, ebuf);
+ if (pd == NULL)
+ error("%s", ebuf);
+ else if (*ebuf)
+ warning("%s", ebuf);
+#endif /* HAVE_PCAP_CREATE */
+ /*
+ * Let user own process after socket has been opened.
+ */
+#ifndef WIN32
+ if (setgid(getgid()) != 0 || setuid(getuid()) != 0)
+ fprintf(stderr, "Warning: setgid/setuid failed !\n");
+#endif /* WIN32 */
+#if !defined(HAVE_PCAP_CREATE) && defined(WIN32)
+ if(Bflag != 0)
+ if(pcap_setbuff(pd, Bflag)==-1){
+ error("%s", pcap_geterr(pd));
+ }
+#endif /* !defined(HAVE_PCAP_CREATE) && defined(WIN32) */
+ if (Lflag)
+ show_dlts_and_exit(device, pd);
+ if (gndo->ndo_dlt >= 0) {
+#ifdef HAVE_PCAP_SET_DATALINK
+ if (pcap_set_datalink(pd, gndo->ndo_dlt) < 0)
+ error("%s", pcap_geterr(pd));
+#else
+ /*
+ * We don't actually support changing the
+ * data link type, so we only let them
+ * set it to what it already is.
+ */
+ if (gndo->ndo_dlt != pcap_datalink(pd)) {
+ error("%s is not one of the DLTs supported by this device\n",
+ gndo->ndo_dltname);
+ }
+#endif
+ (void)fprintf(stderr, "%s: data link type %s\n",
+ program_name, gndo->ndo_dltname);
+ (void)fflush(stderr);
+ }
+ i = pcap_snapshot(pd);
+ if (snaplen < i) {
+ warning("snaplen raised from %d to %d", snaplen, i);
+ snaplen = i;
+ }
+ if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) {
+ localnet = 0;
+ netmask = 0;
+ warning("%s", ebuf);
+ }
+ }
+ if (infile)
+ cmdbuf = read_infile(infile);
+ else
+ cmdbuf = copy_argv(&argv[optind]);
+
+ if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0)
+ error("%s", pcap_geterr(pd));
+ if (dflag) {
+ bpf_dump(&fcode, dflag);
+ pcap_close(pd);
+ free(cmdbuf);
+ exit(0);
+ }
+ init_addrtoname(localnet, netmask);
+ init_checksum();
+
+#ifndef WIN32
+ (void)setsignal(SIGPIPE, cleanup);
+ (void)setsignal(SIGTERM, cleanup);
+ (void)setsignal(SIGINT, cleanup);
+#endif /* WIN32 */
+#if defined(HAVE_FORK) || defined(HAVE_VFORK)
+ (void)setsignal(SIGCHLD, child_cleanup);
+#endif
+ /* Cooperate with nohup(1) */
+#ifndef WIN32
+ if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL)
+ (void)setsignal(SIGHUP, oldhandler);
+#endif /* WIN32 */
+
+#ifndef WIN32
+ /*
+ * If a user name was specified with "-Z", attempt to switch to
+ * that user's UID. This would probably be used with sudo,
+ * to allow tcpdump to be run in a special restricted
+ * account (if you just want to allow users to open capture
+ * devices, and can't just give users that permission,
+ * you'd make tcpdump set-UID or set-GID).
+ *
+ * Tcpdump doesn't necessarily write only to one savefile;
+ * the general only way to allow a -Z instance to write to
+ * savefiles as the user under whose UID it's run, rather
+ * than as the user specified with -Z, would thus be to switch
+ * to the original user ID before opening a capture file and
+ * then switch back to the -Z user ID after opening the savefile.
+ * Switching to the -Z user ID only after opening the first
+ * savefile doesn't handle the general case.
+ */
+
+#ifdef HAVE_CAP_NG_H
+ /* We are running as root and we will be writing to savefile */
+ if ((getuid() == 0 || geteuid() == 0) && WFileName) {
+ if (username) {
+ /* Drop all capabilities from effective set */
+ capng_clear(CAPNG_EFFECTIVE);
+ /* Add capabilities we will need*/
+ capng_update(CAPNG_ADD, CAPNG_PERMITTED, CAP_SETUID);
+ capng_update(CAPNG_ADD, CAPNG_PERMITTED, CAP_SETGID);
+ capng_update(CAPNG_ADD, CAPNG_PERMITTED, CAP_DAC_OVERRIDE);
+
+ capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_SETUID);
+ capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_SETGID);
+ capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE);
+
+ capng_apply(CAPNG_SELECT_BOTH);
+ }
+ }
+#endif /* HAVE_CAP_NG_H */
+
+ if (getuid() == 0 || geteuid() == 0) {
+ if (username || chroot_dir)
+ droproot(username, chroot_dir);
+
+ }
+#endif /* WIN32 */
+
+ if (pcap_setfilter(pd, &fcode) < 0)
+ error("%s", pcap_geterr(pd));
+ if (WFileName) {
+ pcap_dumper_t *p;
+ /* Do not exceed the default PATH_MAX for files. */
+ dumpinfo.CurrentFileName = (char *)malloc(PATH_MAX + 1);
+
+ if (dumpinfo.CurrentFileName == NULL)
+ error("malloc of dumpinfo.CurrentFileName");
+
+ /* We do not need numbering for dumpfiles if Cflag isn't set. */
+ if (Cflag != 0)
+ MakeFilename(dumpinfo.CurrentFileName, WFileName, 0, WflagChars);
+ else
+ MakeFilename(dumpinfo.CurrentFileName, WFileName, 0, 0);
+
+ p = pcap_dump_open(pd, dumpinfo.CurrentFileName);
+#ifdef HAVE_CAP_NG_H
+ /* Give up capabilities, clear Effective set */
+ capng_clear(CAPNG_EFFECTIVE);
+#endif
+ if (p == NULL)
+ error("%s", pcap_geterr(pd));
+ if (Cflag != 0 || Gflag != 0) {
+ callback = dump_packet_and_trunc;
+ dumpinfo.WFileName = WFileName;
+ dumpinfo.pd = pd;
+ dumpinfo.p = p;
+ pcap_userdata = (u_char *)&dumpinfo;
+ } else {
+ callback = dump_packet;
+ pcap_userdata = (u_char *)p;
+ }
+#ifdef HAVE_PCAP_DUMP_FLUSH
+ if (Uflag)
+ pcap_dump_flush(p);
+#endif
+ } else {
+ type = pcap_datalink(pd);
+ printinfo = get_print_info(type);
+ callback = print_packet;
+ pcap_userdata = (u_char *)&printinfo;
+ }
+
+#ifdef SIGNAL_REQ_INFO
+ /*
+ * We can't get statistics when reading from a file rather
+ * than capturing from a device.
+ */
+ if (RFileName == NULL)
+ (void)setsignal(SIGNAL_REQ_INFO, requestinfo);
+#endif
+
+ if (vflag > 0 && WFileName) {
+ /*
+ * When capturing to a file, "-v" means tcpdump should,
+ * every 10 secodns, "v"erbosely report the number of
+ * packets captured.
+ */
+#ifdef USE_WIN32_MM_TIMER
+ /* call verbose_stats_dump() each 1000 +/-100msec */
+ timer_id = timeSetEvent(1000, 100, verbose_stats_dump, 0, TIME_PERIODIC);
+ setvbuf(stderr, NULL, _IONBF, 0);
+#elif defined(HAVE_ALARM)
+ (void)setsignal(SIGALRM, verbose_stats_dump);
+ alarm(1);
+#endif
+ }
+
+#ifndef WIN32
+ if (RFileName == NULL) {
+ /*
+ * Live capture (if -V was specified, we set RFileName
+ * to a file from the -V file). Print a message to
+ * the standard error on UN*X.
+ */
+ if (!vflag && !WFileName) {
+ (void)fprintf(stderr,
+ "%s: verbose output suppressed, use -v or -vv for full protocol decode\n",
+ program_name);
+ } else
+ (void)fprintf(stderr, "%s: ", program_name);
+ dlt = pcap_datalink(pd);
+ dlt_name = pcap_datalink_val_to_name(dlt);
+ if (dlt_name == NULL) {
+ (void)fprintf(stderr, "listening on %s, link-type %u, capture size %u bytes\n",
+ device, dlt, snaplen);
+ } else {
+ (void)fprintf(stderr, "listening on %s, link-type %s (%s), capture size %u bytes\n",
+ device, dlt_name,
+ pcap_datalink_val_to_description(dlt), snaplen);
+ }
+ (void)fflush(stderr);
+ }
+#endif /* WIN32 */
+ do {
+ status = pcap_loop(pd, cnt, callback, pcap_userdata);
+ if (WFileName == NULL) {
+ /*
+ * We're printing packets. Flush the printed output,
+ * so it doesn't get intermingled with error output.
+ */
+ if (status == -2) {
+ /*
+ * We got interrupted, so perhaps we didn't
+ * manage to finish a line we were printing.
+ * Print an extra newline, just in case.
+ */
+ putchar('\n');
+ }
+ (void)fflush(stdout);
+ }
+ if (status == -1) {
+ /*
+ * Error. Report it.
+ */
+ (void)fprintf(stderr, "%s: pcap_loop: %s\n",
+ program_name, pcap_geterr(pd));
+ }
+ if (RFileName == NULL) {
+ /*
+ * We're doing a live capture. Report the capture
+ * statistics.
+ */
+ info(1);
+ }
+ pcap_close(pd);
+ if (VFileName != NULL) {
+ ret = get_next_file(VFile, VFileLine);
+ if (ret) {
+ RFileName = VFileLine;
+ pd = pcap_open_offline(RFileName, ebuf);
+ if (pd == NULL)
+ error("%s", ebuf);
+ new_dlt = pcap_datalink(pd);
+ if (WFileName && new_dlt != dlt)
+ error("%s: new dlt does not match original", RFileName);
+ printinfo = get_print_info(new_dlt);
+ dlt_name = pcap_datalink_val_to_name(new_dlt);
+ if (dlt_name == NULL) {
+ fprintf(stderr, "reading from file %s, link-type %u\n",
+ RFileName, new_dlt);
+ } else {
+ fprintf(stderr,
+ "reading from file %s, link-type %s (%s)\n",
+ RFileName, dlt_name,
+ pcap_datalink_val_to_description(new_dlt));
+ }
+ if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0)
+ error("%s", pcap_geterr(pd));
+ if (pcap_setfilter(pd, &fcode) < 0)
+ error("%s", pcap_geterr(pd));
+ }
+ }
+ }
+ while (ret != NULL);
+
+ free(cmdbuf);
+ exit(status == -1 ? 1 : 0);
+}
+
+/* make a clean exit on interrupts */
+static RETSIGTYPE
+cleanup(int signo _U_)
+{
+#ifdef USE_WIN32_MM_TIMER
+ if (timer_id)
+ timeKillEvent(timer_id);
+ timer_id = 0;
+#elif defined(HAVE_ALARM)
+ alarm(0);
+#endif
+
+#ifdef HAVE_PCAP_BREAKLOOP
+ /*
+ * We have "pcap_breakloop()"; use it, so that we do as little
+ * as possible in the signal handler (it's probably not safe
+ * to do anything with standard I/O streams in a signal handler -
+ * the ANSI C standard doesn't say it is).
+ */
+ pcap_breakloop(pd);
+#else
+ /*
+ * We don't have "pcap_breakloop()"; this isn't safe, but
+ * it's the best we can do. Print the summary if we're
+ * not reading from a savefile - i.e., if we're doing a
+ * live capture - and exit.
+ */
+ if (pd != NULL && pcap_file(pd) == NULL) {
+ /*
+ * We got interrupted, so perhaps we didn't
+ * manage to finish a line we were printing.
+ * Print an extra newline, just in case.
+ */
+ putchar('\n');
+ (void)fflush(stdout);
+ info(1);
+ }
+ exit(0);
+#endif
+}
+
+/*
+ On windows, we do not use a fork, so we do not care less about
+ waiting a child processes to die
+ */
+#if defined(HAVE_FORK) || defined(HAVE_VFORK)
+static RETSIGTYPE
+child_cleanup(int signo _U_)
+{
+ wait(NULL);
+}
+#endif /* HAVE_FORK && HAVE_VFORK */
+
+static void
+info(register int verbose)
+{
+ struct pcap_stat stat;
+
+ /*
+ * Older versions of libpcap didn't set ps_ifdrop on some
+ * platforms; initialize it to 0 to handle that.
+ */
+ stat.ps_ifdrop = 0;
+ if (pcap_stats(pd, &stat) < 0) {
+ (void)fprintf(stderr, "pcap_stats: %s\n", pcap_geterr(pd));
+ infoprint = 0;
+ return;
+ }
+
+ if (!verbose)
+ fprintf(stderr, "%s: ", program_name);
+
+ (void)fprintf(stderr, "%u packet%s captured", packets_captured,
+ PLURAL_SUFFIX(packets_captured));
+ if (!verbose)
+ fputs(", ", stderr);
+ else
+ putc('\n', stderr);
+ (void)fprintf(stderr, "%u packet%s received by filter", stat.ps_recv,
+ PLURAL_SUFFIX(stat.ps_recv));
+ if (!verbose)
+ fputs(", ", stderr);
+ else
+ putc('\n', stderr);
+ (void)fprintf(stderr, "%u packet%s dropped by kernel", stat.ps_drop,
+ PLURAL_SUFFIX(stat.ps_drop));
+ if (stat.ps_ifdrop != 0) {
+ if (!verbose)
+ fputs(", ", stderr);
+ else
+ putc('\n', stderr);
+ (void)fprintf(stderr, "%u packet%s dropped by interface\n",
+ stat.ps_ifdrop, PLURAL_SUFFIX(stat.ps_ifdrop));
+ } else
+ putc('\n', stderr);
+ infoprint = 0;
+}
+
+#if defined(HAVE_FORK) || defined(HAVE_VFORK)
+static void
+compress_savefile(const char *filename)
+{
+# ifdef HAVE_FORK
+ if (fork())
+# else
+ if (vfork())
+# endif
+ return;
+ /*
+ * Set to lowest priority so that this doesn't disturb the capture
+ */
+#ifdef NZERO
+ setpriority(PRIO_PROCESS, 0, NZERO - 1);
+#else
+ setpriority(PRIO_PROCESS, 0, 19);
+#endif
+ if (execlp(zflag, zflag, filename, (char *)NULL) == -1)
+ fprintf(stderr,
+ "compress_savefile:execlp(%s, %s): %s\n",
+ zflag,
+ filename,
+ strerror(errno));
+# ifdef HAVE_FORK
+ exit(1);
+# else
+ _exit(1);
+# endif
+}
+#else /* HAVE_FORK && HAVE_VFORK */
+static void
+compress_savefile(const char *filename)
+{
+ fprintf(stderr,
+ "compress_savefile failed. Functionality not implemented under your system\n");
+}
+#endif /* HAVE_FORK && HAVE_VFORK */
+
+static void
+dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
+{
+ struct dump_info *dump_info;
+
+ ++packets_captured;
+
+ ++infodelay;
+
+ dump_info = (struct dump_info *)user;
+
+ /*
+ * XXX - this won't force the file to rotate on the specified time
+ * boundary, but it will rotate on the first packet received after the
+ * specified Gflag number of seconds. Note: if a Gflag time boundary
+ * and a Cflag size boundary coincide, the time rotation will occur
+ * first thereby cancelling the Cflag boundary (since the file should
+ * be 0).
+ */
+ if (Gflag != 0) {
+ /* Check if it is time to rotate */
+ time_t t;
+
+ /* Get the current time */
+ if ((t = time(NULL)) == (time_t)-1) {
+ error("dump_and_trunc_packet: can't get current_time: %s",
+ pcap_strerror(errno));
+ }
+
+
+ /* If the time is greater than the specified window, rotate */
+ if (t - Gflag_time >= Gflag) {
+ /* Update the Gflag_time */
+ Gflag_time = t;
+ /* Update Gflag_count */
+ Gflag_count++;
+ /*
+ * Close the current file and open a new one.
+ */
+ pcap_dump_close(dump_info->p);
+
+ /*
+ * Compress the file we just closed, if the user asked for it
+ */
+ if (zflag != NULL)
+ compress_savefile(dump_info->CurrentFileName);
+
+ /*
+ * Check to see if we've exceeded the Wflag (when
+ * not using Cflag).
+ */
+ if (Cflag == 0 && Wflag > 0 && Gflag_count >= Wflag) {
+ (void)fprintf(stderr, "Maximum file limit reached: %d\n",
+ Wflag);
+ exit(0);
+ /* NOTREACHED */
+ }
+ if (dump_info->CurrentFileName != NULL)
+ free(dump_info->CurrentFileName);
+ /* Allocate space for max filename + \0. */
+ dump_info->CurrentFileName = (char *)malloc(PATH_MAX + 1);
+ if (dump_info->CurrentFileName == NULL)
+ error("dump_packet_and_trunc: malloc");
+ /*
+ * This is always the first file in the Cflag
+ * rotation: e.g. 0
+ * We also don't need numbering if Cflag is not set.
+ */
+ if (Cflag != 0)
+ MakeFilename(dump_info->CurrentFileName, dump_info->WFileName, 0,
+ WflagChars);
+ else
+ MakeFilename(dump_info->CurrentFileName, dump_info->WFileName, 0, 0);
+
+#ifdef HAVE_CAP_NG_H
+ capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE);
+ capng_apply(CAPNG_EFFECTIVE);
+#endif /* HAVE_CAP_NG_H */
+ dump_info->p = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName);
+#ifdef HAVE_CAP_NG_H
+ capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE);
+ capng_apply(CAPNG_EFFECTIVE);
+#endif /* HAVE_CAP_NG_H */
+ if (dump_info->p == NULL)
+ error("%s", pcap_geterr(pd));
+ }
+ }
+
+ /*
+ * XXX - this won't prevent capture files from getting
+ * larger than Cflag - the last packet written to the
+ * file could put it over Cflag.
+ */
+ if (Cflag != 0 && pcap_dump_ftell(dump_info->p) > Cflag) {
+ /*
+ * Close the current file and open a new one.
+ */
+ pcap_dump_close(dump_info->p);
+
+ /*
+ * Compress the file we just closed, if the user asked for it
+ */
+ if (zflag != NULL)
+ compress_savefile(dump_info->CurrentFileName);
+
+ Cflag_count++;
+ if (Wflag > 0) {
+ if (Cflag_count >= Wflag)
+ Cflag_count = 0;
+ }
+ if (dump_info->CurrentFileName != NULL)
+ free(dump_info->CurrentFileName);
+ dump_info->CurrentFileName = (char *)malloc(PATH_MAX + 1);
+ if (dump_info->CurrentFileName == NULL)
+ error("dump_packet_and_trunc: malloc");
+ MakeFilename(dump_info->CurrentFileName, dump_info->WFileName, Cflag_count, WflagChars);
+ dump_info->p = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName);
+ if (dump_info->p == NULL)
+ error("%s", pcap_geterr(pd));
+ }
+
+ pcap_dump((u_char *)dump_info->p, h, sp);
+#ifdef HAVE_PCAP_DUMP_FLUSH
+ if (Uflag)
+ pcap_dump_flush(dump_info->p);
+#endif
+
+ --infodelay;
+ if (infoprint)
+ info(0);
+}
+
+static void
+dump_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
+{
+ ++packets_captured;
+
+ ++infodelay;
+
+ pcap_dump(user, h, sp);
+#ifdef HAVE_PCAP_DUMP_FLUSH
+ if (Uflag)
+ pcap_dump_flush((pcap_dumper_t *)user);
+#endif
+
+ --infodelay;
+ if (infoprint)
+ info(0);
+}
+
+static void
+print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
+{
+ struct print_info *print_info;
+ u_int hdrlen;
+
+ ++packets_captured;
+
+ ++infodelay;
+ ts_print(&h->ts);
+
+ print_info = (struct print_info *)user;
+
+ /*
+ * Some printers want to check that they're not walking off the
+ * end of the packet.
+ * Rather than pass it all the way down, we set this global.
+ */
+ snapend = sp + h->caplen;
+
+ if(print_info->ndo_type) {
+ hdrlen = (*print_info->p.ndo_printer)(print_info->ndo, h, sp);
+ } else {
+ hdrlen = (*print_info->p.printer)(h, sp);
+ }
+
+ if (Xflag) {
+ /*
+ * Print the raw packet data in hex and ASCII.
+ */
+ if (Xflag > 1) {
+ /*
+ * Include the link-layer header.
+ */
+ hex_and_ascii_print("\n\t", sp, h->caplen);
+ } else {
+ /*
+ * Don't include the link-layer header - and if
+ * we have nothing past the link-layer header,
+ * print nothing.
+ */
+ if (h->caplen > hdrlen)
+ hex_and_ascii_print("\n\t", sp + hdrlen,
+ h->caplen - hdrlen);
+ }
+ } else if (xflag) {
+ /*
+ * Print the raw packet data in hex.
+ */
+ if (xflag > 1) {
+ /*
+ * Include the link-layer header.
+ */
+ hex_print("\n\t", sp, h->caplen);
+ } else {
+ /*
+ * Don't include the link-layer header - and if
+ * we have nothing past the link-layer header,
+ * print nothing.
+ */
+ if (h->caplen > hdrlen)
+ hex_print("\n\t", sp + hdrlen,
+ h->caplen - hdrlen);
+ }
+ } else if (Aflag) {
+ /*
+ * Print the raw packet data in ASCII.
+ */
+ if (Aflag > 1) {
+ /*
+ * Include the link-layer header.
+ */
+ ascii_print(sp, h->caplen);
+ } else {
+ /*
+ * Don't include the link-layer header - and if
+ * we have nothing past the link-layer header,
+ * print nothing.
+ */
+ if (h->caplen > hdrlen)
+ ascii_print(sp + hdrlen, h->caplen - hdrlen);
+ }
+ }
+
+ putchar('\n');
+
+ --infodelay;
+ if (infoprint)
+ info(0);
+}
+
+#ifdef WIN32
+ /*
+ * XXX - there should really be libpcap calls to get the version
+ * number as a string (the string would be generated from #defines
+ * at run time, so that it's not generated from string constants
+ * in the library, as, on many UNIX systems, those constants would
+ * be statically linked into the application executable image, and
+ * would thus reflect the version of libpcap on the system on
+ * which the application was *linked*, not the system on which it's
+ * *running*.
+ *
+ * That routine should be documented, unlike the "version[]"
+ * string, so that UNIX vendors providing their own libpcaps
+ * don't omit it (as a couple of vendors have...).
+ *
+ * Packet.dll should perhaps also export a routine to return the
+ * version number of the Packet.dll code, to supply the
+ * "Wpcap_version" information on Windows.
+ */
+ char WDversion[]="current-cvs.tcpdump.org";
+#if !defined(HAVE_GENERATED_VERSION)
+ char version[]="current-cvs.tcpdump.org";
+#endif
+ char pcap_version[]="current-cvs.tcpdump.org";
+ char Wpcap_version[]="3.1";
+#endif
+
+/*
+ * By default, print the specified data out in hex and ASCII.
+ */
+static void
+ndo_default_print(netdissect_options *ndo _U_, const u_char *bp, u_int length)
+{
+ hex_and_ascii_print("\n\t", bp, length); /* pass on lf and identation string */
+}
+
+void
+default_print(const u_char *bp, u_int length)
+{
+ ndo_default_print(gndo, bp, length);
+}
+
+#ifdef SIGNAL_REQ_INFO
+RETSIGTYPE requestinfo(int signo _U_)
+{
+ if (infodelay)
+ ++infoprint;
+ else
+ info(0);
+}
+#endif
+
+/*
+ * Called once each second in verbose mode while dumping to file
+ */
+#ifdef USE_WIN32_MM_TIMER
+void CALLBACK verbose_stats_dump (UINT timer_id _U_, UINT msg _U_, DWORD_PTR arg _U_,
+ DWORD_PTR dw1 _U_, DWORD_PTR dw2 _U_)
+{
+ struct pcap_stat stat;
+
+ if (infodelay == 0 && pcap_stats(pd, &stat) >= 0)
+ fprintf(stderr, "Got %u\r", packets_captured);
+}
+#elif defined(HAVE_ALARM)
+static void verbose_stats_dump(int sig _U_)
+{
+ struct pcap_stat stat;
+
+ if (infodelay == 0 && pcap_stats(pd, &stat) >= 0)
+ fprintf(stderr, "Got %u\r", packets_captured);
+ alarm(1);
+}
+#endif
+
+static void
+usage(void)
+{
+#if __rtems__
+ #define version "RTEMS Version"
+#else
+ extern char version[];
+#endif
+#ifndef HAVE_PCAP_LIB_VERSION
+#if defined(WIN32) || defined(HAVE_PCAP_VERSION)
+ extern char pcap_version[];
+#else /* defined(WIN32) || defined(HAVE_PCAP_VERSION) */
+ static char pcap_version[] = "unknown";
+#endif /* defined(WIN32) || defined(HAVE_PCAP_VERSION) */
+#endif /* HAVE_PCAP_LIB_VERSION */
+
+#ifdef HAVE_PCAP_LIB_VERSION
+#ifdef WIN32
+ (void)fprintf(stderr, "%s version %s, based on tcpdump version %s\n", program_name, WDversion, version);
+#else /* WIN32 */
+ (void)fprintf(stderr, "%s version %s\n", program_name, version);
+#endif /* WIN32 */
+ (void)fprintf(stderr, "%s\n",pcap_lib_version());
+#else /* HAVE_PCAP_LIB_VERSION */
+#ifdef WIN32
+ (void)fprintf(stderr, "%s version %s, based on tcpdump version %s\n", program_name, WDversion, version);
+ (void)fprintf(stderr, "WinPcap version %s, based on libpcap version %s\n",Wpcap_version, pcap_version);
+#else /* WIN32 */
+ (void)fprintf(stderr, "%s version %s\n", program_name, version);
+ (void)fprintf(stderr, "libpcap version %s\n", pcap_version);
+#endif /* WIN32 */
+#endif /* HAVE_PCAP_LIB_VERSION */
+ (void)fprintf(stderr,
+"Usage: %s [-aAbd" D_FLAG "efhH" I_FLAG J_FLAG "KlLnNOpqRStu" U_FLAG "vxX]" B_FLAG_USAGE " [ -c count ]\n", program_name);
+ (void)fprintf(stderr,
+"\t\t[ -C file_size ] [ -E algo:secret ] [ -F file ] [ -G seconds ]\n");
+ (void)fprintf(stderr,
+"\t\t[ -i interface ]" j_FLAG_USAGE " [ -M secret ]\n");
+ (void)fprintf(stderr,
+"\t\t[ -r file ] [ -s snaplen ] [ -T type ] [ -V file ] [ -w file ]\n");
+ (void)fprintf(stderr,
+"\t\t[ -W filecount ] [ -y datalinktype ] [ -z command ]\n");
+ (void)fprintf(stderr,
+"\t\t[ -Z user ] [ expression ]\n");
+ exit(1);
+}
+
+
+
+/* VARARGS */
+static void
+ndo_error(netdissect_options *ndo _U_, const char *fmt, ...)
+{
+ va_list ap;
+
+ (void)fprintf(stderr, "%s: ", program_name);
+ va_start(ap, fmt);
+ (void)vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ if (*fmt) {
+ fmt += strlen(fmt);
+ if (fmt[-1] != '\n')
+ (void)fputc('\n', stderr);
+ }
+ exit(1);
+ /* NOTREACHED */
+}
+
+/* VARARGS */
+static void
+ndo_warning(netdissect_options *ndo _U_, const char *fmt, ...)
+{
+ va_list ap;
+
+ (void)fprintf(stderr, "%s: WARNING: ", program_name);
+ va_start(ap, fmt);
+ (void)vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ if (*fmt) {
+ fmt += strlen(fmt);
+ if (fmt[-1] != '\n')
+ (void)fputc('\n', stderr);
+ }
+}
diff --git a/freebsd/contrib/tcpdump/telnet.h b/freebsd/contrib/tcpdump/telnet.h
new file mode 100644
index 00000000..33a07be9
--- /dev/null
+++ b/freebsd/contrib/tcpdump/telnet.h
@@ -0,0 +1,348 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/telnet.h,v 1.5 2007-08-29 02:31:44 mcr Exp $ (LBL) */
+
+/* NetBSD: telnet.h,v 1.9 2001/06/11 01:50:50 wiz Exp */
+
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)telnet.h 8.2 (Berkeley) 12/15/93
+ */
+
+#ifndef _ARPA_TELNET_H_
+#define _ARPA_TELNET_H_
+
+/*
+ * Definitions for the TELNET protocol.
+ */
+#define IAC 255 /* interpret as command: */
+#define DONT 254 /* you are not to use option */
+#define DO 253 /* please, you use option */
+#define WONT 252 /* I won't use option */
+#define WILL 251 /* I will use option */
+#define SB 250 /* interpret as subnegotiation */
+#define GA 249 /* you may reverse the line */
+#define EL 248 /* erase the current line */
+#define EC 247 /* erase the current character */
+#define AYT 246 /* are you there */
+#define AO 245 /* abort output--but let prog finish */
+#define IP 244 /* interrupt process--permanently */
+#define BREAK 243 /* break */
+#define DM 242 /* data mark--for connect. cleaning */
+#define NOP 241 /* nop */
+#define SE 240 /* end sub negotiation */
+#define EOR 239 /* end of record (transparent mode) */
+#define ABORT 238 /* Abort process */
+#define SUSP 237 /* Suspend process */
+#define xEOF 236 /* End of file: EOF is already used... */
+
+#define SYNCH 242 /* for telfunc calls */
+
+#ifdef TELCMDS
+const char *telcmds[] = {
+ "EOF", "SUSP", "ABORT", "EOR",
+ "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",
+ "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0,
+};
+#else
+extern char *telcmds[];
+#endif
+
+#define TELCMD_FIRST xEOF
+#define TELCMD_LAST IAC
+#define TELCMD_OK(x) ((unsigned int)(x) <= TELCMD_LAST && \
+ (unsigned int)(x) >= TELCMD_FIRST)
+#define TELCMD(x) telcmds[(x)-TELCMD_FIRST]
+
+/* telnet options */
+#define TELOPT_BINARY 0 /* 8-bit data path */
+#define TELOPT_ECHO 1 /* echo */
+#define TELOPT_RCP 2 /* prepare to reconnect */
+#define TELOPT_SGA 3 /* suppress go ahead */
+#define TELOPT_NAMS 4 /* approximate message size */
+#define TELOPT_STATUS 5 /* give status */
+#define TELOPT_TM 6 /* timing mark */
+#define TELOPT_RCTE 7 /* remote controlled transmission and echo */
+#define TELOPT_NAOL 8 /* negotiate about output line width */
+#define TELOPT_NAOP 9 /* negotiate about output page size */
+#define TELOPT_NAOCRD 10 /* negotiate about CR disposition */
+#define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */
+#define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */
+#define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */
+#define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */
+#define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */
+#define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */
+#define TELOPT_XASCII 17 /* extended ascic character set */
+#define TELOPT_LOGOUT 18 /* force logout */
+#define TELOPT_BM 19 /* byte macro */
+#define TELOPT_DET 20 /* data entry terminal */
+#define TELOPT_SUPDUP 21 /* supdup protocol */
+#define TELOPT_SUPDUPOUTPUT 22 /* supdup output */
+#define TELOPT_SNDLOC 23 /* send location */
+#define TELOPT_TTYPE 24 /* terminal type */
+#define TELOPT_EOR 25 /* end or record */
+#define TELOPT_TUID 26 /* TACACS user identification */
+#define TELOPT_OUTMRK 27 /* output marking */
+#define TELOPT_TTYLOC 28 /* terminal location number */
+#define TELOPT_3270REGIME 29 /* 3270 regime */
+#define TELOPT_X3PAD 30 /* X.3 PAD */
+#define TELOPT_NAWS 31 /* window size */
+#define TELOPT_TSPEED 32 /* terminal speed */
+#define TELOPT_LFLOW 33 /* remote flow control */
+#define TELOPT_LINEMODE 34 /* Linemode option */
+#define TELOPT_XDISPLOC 35 /* X Display Location */
+#define TELOPT_OLD_ENVIRON 36 /* Old - Environment variables */
+#define TELOPT_AUTHENTICATION 37/* Authenticate */
+#define TELOPT_ENCRYPT 38 /* Encryption option */
+#define TELOPT_NEW_ENVIRON 39 /* New - Environment variables */
+#define TELOPT_EXOPL 255 /* extended-options-list */
+
+
+#define NTELOPTS (1+TELOPT_NEW_ENVIRON)
+#ifdef TELOPTS
+const char *telopts[NTELOPTS+1] = {
+ "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",
+ "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP",
+ "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",
+ "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
+ "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT",
+ "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD",
+ "TACACS UID", "OUTPUT MARKING", "TTYLOC",
+ "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW",
+ "LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION",
+ "ENCRYPT", "NEW-ENVIRON",
+ 0,
+};
+#define TELOPT_FIRST TELOPT_BINARY
+#define TELOPT_LAST TELOPT_NEW_ENVIRON
+#define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST)
+#define TELOPT(x) telopts[(x)-TELOPT_FIRST]
+#endif
+
+/* sub-option qualifiers */
+#define TELQUAL_IS 0 /* option is... */
+#define TELQUAL_SEND 1 /* send option */
+#define TELQUAL_INFO 2 /* ENVIRON: informational version of IS */
+#define TELQUAL_REPLY 2 /* AUTHENTICATION: client version of IS */
+#define TELQUAL_NAME 3 /* AUTHENTICATION: client version of IS */
+
+#define LFLOW_OFF 0 /* Disable remote flow control */
+#define LFLOW_ON 1 /* Enable remote flow control */
+#define LFLOW_RESTART_ANY 2 /* Restart output on any char */
+#define LFLOW_RESTART_XON 3 /* Restart output only on XON */
+
+/*
+ * LINEMODE suboptions
+ */
+
+#define LM_MODE 1
+#define LM_FORWARDMASK 2
+#define LM_SLC 3
+
+#define MODE_EDIT 0x01
+#define MODE_TRAPSIG 0x02
+#define MODE_ACK 0x04
+#define MODE_SOFT_TAB 0x08
+#define MODE_LIT_ECHO 0x10
+
+#define MODE_MASK 0x1f
+
+/* Not part of protocol, but needed to simplify things... */
+#define MODE_FLOW 0x0100
+#define MODE_ECHO 0x0200
+#define MODE_INBIN 0x0400
+#define MODE_OUTBIN 0x0800
+#define MODE_FORCE 0x1000
+
+#define SLC_SYNCH 1
+#define SLC_BRK 2
+#define SLC_IP 3
+#define SLC_AO 4
+#define SLC_AYT 5
+#define SLC_EOR 6
+#define SLC_ABORT 7
+#define SLC_EOF 8
+#define SLC_SUSP 9
+#define SLC_EC 10
+#define SLC_EL 11
+#define SLC_EW 12
+#define SLC_RP 13
+#define SLC_LNEXT 14
+#define SLC_XON 15
+#define SLC_XOFF 16
+#define SLC_FORW1 17
+#define SLC_FORW2 18
+#define SLC_MCL 19
+#define SLC_MCR 20
+#define SLC_MCWL 21
+#define SLC_MCWR 22
+#define SLC_MCBOL 23
+#define SLC_MCEOL 24
+#define SLC_INSRT 25
+#define SLC_OVER 26
+#define SLC_ECR 27
+#define SLC_EWR 28
+#define SLC_EBOL 29
+#define SLC_EEOL 30
+
+#define NSLC 30
+
+/*
+ * For backwards compatibility, we define SLC_NAMES to be the
+ * list of names if SLC_NAMES is not defined.
+ */
+#define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \
+ "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
+ "LNEXT", "XON", "XOFF", "FORW1", "FORW2", \
+ "MCL", "MCR", "MCWL", "MCWR", "MCBOL", \
+ "MCEOL", "INSRT", "OVER", "ECR", "EWR", \
+ "EBOL", "EEOL", \
+ 0,
+
+#ifdef SLC_NAMES
+const char *slc_names[] = {
+ SLC_NAMELIST
+};
+#else
+extern char *slc_names[];
+#define SLC_NAMES SLC_NAMELIST
+#endif
+
+#define SLC_NAME_OK(x) ((unsigned int)(x) <= NSLC)
+#define SLC_NAME(x) slc_names[x]
+
+#define SLC_NOSUPPORT 0
+#define SLC_CANTCHANGE 1
+#define SLC_VARIABLE 2
+#define SLC_DEFAULT 3
+#define SLC_LEVELBITS 0x03
+
+#define SLC_FUNC 0
+#define SLC_FLAGS 1
+#define SLC_VALUE 2
+
+#define SLC_ACK 0x80
+#define SLC_FLUSHIN 0x40
+#define SLC_FLUSHOUT 0x20
+
+#define OLD_ENV_VAR 1
+#define OLD_ENV_VALUE 0
+#define NEW_ENV_VAR 0
+#define NEW_ENV_VALUE 1
+#define ENV_ESC 2
+#define ENV_USERVAR 3
+
+/*
+ * AUTHENTICATION suboptions
+ */
+
+/*
+ * Who is authenticating who ...
+ */
+#define AUTH_WHO_CLIENT 0 /* Client authenticating server */
+#define AUTH_WHO_SERVER 1 /* Server authenticating client */
+#define AUTH_WHO_MASK 1
+
+/*
+ * amount of authentication done
+ */
+#define AUTH_HOW_ONE_WAY 0
+#define AUTH_HOW_MUTUAL 2
+#define AUTH_HOW_MASK 2
+
+/*
+ * should we be encrypting? (not yet formally standardized)
+ */
+#define AUTH_ENCRYPT_OFF 0
+#define AUTH_ENCRYPT_ON 4
+#define AUTH_ENCRYPT_MASK 4
+
+#define AUTHTYPE_NULL 0
+#define AUTHTYPE_KERBEROS_V4 1
+#define AUTHTYPE_KERBEROS_V5 2
+#define AUTHTYPE_SPX 3
+#define AUTHTYPE_MINK 4
+#define AUTHTYPE_CNT 5
+
+#define AUTHTYPE_TEST 99
+
+#ifdef AUTH_NAMES
+const char *authtype_names[] = {
+ "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0,
+};
+#else
+extern char *authtype_names[];
+#endif
+
+#define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT)
+#define AUTHTYPE_NAME(x) authtype_names[x]
+
+/*
+ * ENCRYPTion suboptions
+ */
+#define ENCRYPT_IS 0 /* I pick encryption type ... */
+#define ENCRYPT_SUPPORT 1 /* I support encryption types ... */
+#define ENCRYPT_REPLY 2 /* Initial setup response */
+#define ENCRYPT_START 3 /* Am starting to send encrypted */
+#define ENCRYPT_END 4 /* Am ending encrypted */
+#define ENCRYPT_REQSTART 5 /* Request you start encrypting */
+#define ENCRYPT_REQEND 6 /* Request you send encrypting */
+#define ENCRYPT_ENC_KEYID 7
+#define ENCRYPT_DEC_KEYID 8
+#define ENCRYPT_CNT 9
+
+#define ENCTYPE_ANY 0
+#define ENCTYPE_DES_CFB64 1
+#define ENCTYPE_DES_OFB64 2
+#define ENCTYPE_CNT 3
+
+#ifdef ENCRYPT_NAMES
+const char *encrypt_names[] = {
+ "IS", "SUPPORT", "REPLY", "START", "END",
+ "REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID",
+ 0,
+};
+const char *enctype_names[] = {
+ "ANY", "DES_CFB64", "DES_OFB64", 0,
+};
+#else
+extern char *encrypt_names[];
+extern char *enctype_names[];
+#endif
+
+
+#define ENCRYPT_NAME_OK(x) ((unsigned int)(x) < ENCRYPT_CNT)
+#define ENCRYPT_NAME(x) encrypt_names[x]
+
+#define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT)
+#define ENCTYPE_NAME(x) enctype_names[x]
+
+#endif /* _ARPA_TELNET_H_ */
diff --git a/freebsd/contrib/tcpdump/tftp.h b/freebsd/contrib/tcpdump/tftp.h
new file mode 100644
index 00000000..6a092e0a
--- /dev/null
+++ b/freebsd/contrib/tcpdump/tftp.h
@@ -0,0 +1,82 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/tftp.h,v 1.2 2008-04-11 16:47:38 gianluca Exp $ (LBL) */
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)tftp.h 8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef _TFTP_H_
+#define _TFTP_H_
+
+/*
+ * Trivial File Transfer Protocol (IEN-133)
+ */
+#define SEGSIZE 512 /* data segment size */
+
+/*
+ * Packet types.
+ */
+#define RRQ 01 /* read request */
+#define WRQ 02 /* write request */
+#define DATA 03 /* data packet */
+#define ACK 04 /* acknowledgement */
+#define TFTP_ERROR 05 /* error code */
+#define OACK 06 /* option acknowledgement */
+
+struct tftphdr {
+ unsigned short th_opcode; /* packet type */
+ union {
+ unsigned short tu_block; /* block # */
+ unsigned short tu_code; /* error code */
+ char tu_stuff[1]; /* request packet stuff */
+ } th_u;
+ char th_data[1]; /* data or error string */
+};
+
+#define th_block th_u.tu_block
+#define th_code th_u.tu_code
+#define th_stuff th_u.tu_stuff
+#define th_msg th_data
+
+/*
+ * Error codes.
+ */
+#define EUNDEF 0 /* not defined */
+#define ENOTFOUND 1 /* file not found */
+#define EACCESS 2 /* access violation */
+#define ENOSPACE 3 /* disk full or allocation exceeded */
+#define EBADOP 4 /* illegal TFTP operation */
+#define EBADID 5 /* unknown transfer ID */
+#define EEXISTS 6 /* file already exists */
+#define ENOUSER 7 /* no such user */
+
+#endif /* !_TFTP_H_ */
diff --git a/freebsd/contrib/tcpdump/timed.h b/freebsd/contrib/tcpdump/timed.h
new file mode 100644
index 00000000..f8d5a113
--- /dev/null
+++ b/freebsd/contrib/tcpdump/timed.h
@@ -0,0 +1,97 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/timed.h,v 1.6 2008-02-05 19:46:19 guy Exp $ (LBL) */
+/*
+ * Copyright (c) 1983, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)timed.h 8.1 (Berkeley) 6/2/93
+ */
+
+#ifndef _PROTOCOLS_TIMED_H_
+#define _PROTOCOLS_TIMED_H_
+
+/*
+ * Time Synchronization Protocol
+ */
+
+#define TSPVERSION 1
+#define ANYADDR NULL
+
+struct tsp_timeval {
+ u_int32_t tv_sec;
+ u_int32_t tv_usec;
+};
+
+struct tsp {
+ u_int8_t tsp_type;
+ u_int8_t tsp_vers;
+ u_int16_t tsp_seq;
+ union {
+ struct tsp_timeval tspu_time;
+ int8_t tspu_hopcnt;
+ } tsp_u;
+ int8_t tsp_name[256];
+};
+
+#define tsp_time tsp_u.tspu_time
+#define tsp_hopcnt tsp_u.tspu_hopcnt
+
+/*
+ * Command types.
+ */
+#define TSP_ANY 0 /* match any types */
+#define TSP_ADJTIME 1 /* send adjtime */
+#define TSP_ACK 2 /* generic acknowledgement */
+#define TSP_MASTERREQ 3 /* ask for master's name */
+#define TSP_MASTERACK 4 /* acknowledge master request */
+#define TSP_SETTIME 5 /* send network time */
+#define TSP_MASTERUP 6 /* inform slaves that master is up */
+#define TSP_SLAVEUP 7 /* slave is up but not polled */
+#define TSP_ELECTION 8 /* advance candidature for master */
+#define TSP_ACCEPT 9 /* support candidature of master */
+#define TSP_REFUSE 10 /* reject candidature of master */
+#define TSP_CONFLICT 11 /* two or more masters present */
+#define TSP_RESOLVE 12 /* masters' conflict resolution */
+#define TSP_QUIT 13 /* reject candidature if master is up */
+#define TSP_DATE 14 /* reset the time (date command) */
+#define TSP_DATEREQ 15 /* remote request to reset the time */
+#define TSP_DATEACK 16 /* acknowledge time setting */
+#define TSP_TRACEON 17 /* turn tracing on */
+#define TSP_TRACEOFF 18 /* turn tracing off */
+#define TSP_MSITE 19 /* find out master's site */
+#define TSP_MSITEREQ 20 /* remote master's site request */
+#define TSP_TEST 21 /* for testing election algo */
+#define TSP_SETDATE 22 /* New from date command */
+#define TSP_SETDATEREQ 23 /* New remote for above */
+#define TSP_LOOP 24 /* loop detection packet */
+
+#define TSPTYPENUMBER 25
+
+#endif /* !_TIMED_H_ */
diff --git a/freebsd/contrib/tcpdump/token.h b/freebsd/contrib/tcpdump/token.h
new file mode 100644
index 00000000..19524c6c
--- /dev/null
+++ b/freebsd/contrib/tcpdump/token.h
@@ -0,0 +1,53 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/token.h,v 1.6 2002-12-11 07:14:12 guy Exp $ (LBL) */
+/*
+ * Copyright (c) 1998, Larry Lile
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice unmodified, this list of conditions, and the following
+ * disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#define TOKEN_HDRLEN 14
+#define TOKEN_RING_MAC_LEN 6
+#define ROUTING_SEGMENT_MAX 16
+#define IS_SOURCE_ROUTED(trp) ((trp)->token_shost[0] & 0x80)
+#define FRAME_TYPE(trp) (((trp)->token_fc & 0xC0) >> 6)
+#define TOKEN_FC_LLC 1
+
+#define BROADCAST(trp) ((EXTRACT_16BITS(&(trp)->token_rcf) & 0xE000) >> 13)
+#define RIF_LENGTH(trp) ((EXTRACT_16BITS(&(trp)->token_rcf) & 0x1f00) >> 8)
+#define DIRECTION(trp) ((EXTRACT_16BITS(&(trp)->token_rcf) & 0x0080) >> 7)
+#define LARGEST_FRAME(trp) ((EXTRACT_16BITS(&(trp)->token_rcf) & 0x0070) >> 4)
+#define RING_NUMBER(trp, x) ((EXTRACT_16BITS(&(trp)->token_rseg[x]) & 0xfff0) >> 4)
+#define BRIDGE_NUMBER(trp, x) ((EXTRACT_16BITS(&(trp)->token_rseg[x]) & 0x000f))
+#define SEGMENT_COUNT(trp) ((int)((RIF_LENGTH(trp) - 2) / 2))
+
+struct token_header {
+ u_int8_t token_ac;
+ u_int8_t token_fc;
+ u_int8_t token_dhost[TOKEN_RING_MAC_LEN];
+ u_int8_t token_shost[TOKEN_RING_MAC_LEN];
+ u_int16_t token_rcf;
+ u_int16_t token_rseg[ROUTING_SEGMENT_MAX];
+};
diff --git a/freebsd/contrib/tcpdump/udp.h b/freebsd/contrib/tcpdump/udp.h
new file mode 100644
index 00000000..b07cdd43
--- /dev/null
+++ b/freebsd/contrib/tcpdump/udp.h
@@ -0,0 +1,96 @@
+/* @(#) $Header: /tcpdump/master/tcpdump/udp.h,v 1.13 2007-08-08 17:20:58 hannes Exp $ (LBL) */
+/*
+ * Copyright (c) 1982, 1986, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * @(#)udp.h 8.1 (Berkeley) 6/10/93
+ */
+
+/*
+ * Udp protocol header.
+ * Per RFC 768, September, 1981.
+ */
+struct udphdr {
+ u_int16_t uh_sport; /* source port */
+ u_int16_t uh_dport; /* destination port */
+ u_int16_t uh_ulen; /* udp length */
+ u_int16_t uh_sum; /* udp checksum */
+};
+
+#define TFTP_PORT 69 /*XXX*/
+#define KERBEROS_PORT 88 /*XXX*/
+#define SUNRPC_PORT 111 /*XXX*/
+#define SNMP_PORT 161 /*XXX*/
+#define NTP_PORT 123 /*XXX*/
+#define SNMPTRAP_PORT 162 /*XXX*/
+#define ISAKMP_PORT 500 /*XXX*/
+#define SYSLOG_PORT 514 /* rfc3164 */
+#define TIMED_PORT 525 /*XXX*/
+#define RIP_PORT 520 /*XXX*/
+#define LDP_PORT 646
+#define AODV_PORT 654 /*XXX*/
+#define OLSR_PORT 698 /* rfc3626 */
+#define KERBEROS_SEC_PORT 750 /*XXX*/
+#define L2TP_PORT 1701 /*XXX*/
+#define SIP_PORT 5060
+#define ISAKMP_PORT_NATT 4500 /* rfc3948 */
+#define ISAKMP_PORT_USER1 7500 /*XXX - nonstandard*/
+#define ISAKMP_PORT_USER2 8500 /*XXX - nonstandard*/
+#define RX_PORT_LOW 7000 /*XXX*/
+#define RX_PORT_HIGH 7009 /*XXX*/
+#define NETBIOS_NS_PORT 137
+#define NETBIOS_DGRAM_PORT 138
+#define CISCO_AUTORP_PORT 496 /*XXX*/
+#define RADIUS_PORT 1645
+#define RADIUS_NEW_PORT 1812
+#define RADIUS_ACCOUNTING_PORT 1646
+#define RADIUS_NEW_ACCOUNTING_PORT 1813
+#define HSRP_PORT 1985 /*XXX*/
+#define LMP_PORT 701 /* rfc4204 */
+#define LWRES_PORT 921
+#define VQP_PORT 1589
+#define ZEPHYR_SRV_PORT 2103
+#define ZEPHYR_CLT_PORT 2104
+#define MPLS_LSP_PING_PORT 3503 /* draft-ietf-mpls-lsp-ping-02.txt */
+#define BFD_CONTROL_PORT 3784 /* draft-katz-ward-bfd-v4v6-1hop-00.txt */
+#define BFD_ECHO_PORT 3785 /* draft-katz-ward-bfd-v4v6-1hop-00.txt */
+#define SFLOW_PORT 6343 /* http://www.sflow.org/developers/specifications.php */
+#define LWAPP_DATA_PORT 12222 /* draft-ohara-capwap-lwapp-04.txt */
+#define LWAPP_CONTROL_PORT 12223 /* draft-ohara-capwap-lwapp-04.txt */
+#define OTV_PORT 8472 /* draft-hasmit-otv-04 */
+
+#ifdef INET6
+#define RIPNG_PORT 521 /*XXX*/
+#define DHCP6_SERV_PORT 546 /*XXX*/
+#define DHCP6_CLI_PORT 547 /*XXX*/
+#define BABEL_PORT 6696
+#define BABEL_PORT_OLD 6697
+#endif
diff --git a/freebsd/contrib/tcpdump/util.c b/freebsd/contrib/tcpdump/util.c
new file mode 100644
index 00000000..d50e1254
--- /dev/null
+++ b/freebsd/contrib/tcpdump/util.c
@@ -0,0 +1,610 @@
+#include <machine/rtems-bsd-user-space.h>
+
+/*
+ * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+static const char rcsid[] _U_ =
+ "@(#) $Header: /tcpdump/master/tcpdump/util.c,v 1.109 2007-01-29 09:59:42 hannes Exp $ (LBL)";
+#endif
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <sys/stat.h>
+
+#include <errno.h>
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#include <pcap.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "interface.h"
+
+char * ts_format(register int, register int);
+
+/*
+ * Print out a null-terminated filename (or other ascii string).
+ * If ep is NULL, assume no truncation check is needed.
+ * Return true if truncated.
+ */
+int
+fn_print(register const u_char *s, register const u_char *ep)
+{
+ register int ret;
+ register u_char c;
+
+ ret = 1; /* assume truncated */
+ while (ep == NULL || s < ep) {
+ c = *s++;
+ if (c == '\0') {
+ ret = 0;
+ break;
+ }
+ if (!isascii(c)) {
+ c = toascii(c);
+ putchar('M');
+ putchar('-');
+ }
+ if (!isprint(c)) {
+ c ^= 0x40; /* DEL to ?, others to alpha */
+ putchar('^');
+ }
+ putchar(c);
+ }
+ return(ret);
+}
+
+/*
+ * Print out a counted filename (or other ascii string).
+ * If ep is NULL, assume no truncation check is needed.
+ * Return true if truncated.
+ */
+int
+fn_printn(register const u_char *s, register u_int n,
+ register const u_char *ep)
+{
+ register u_char c;
+
+ while (n > 0 && (ep == NULL || s < ep)) {
+ n--;
+ c = *s++;
+ if (!isascii(c)) {
+ c = toascii(c);
+ putchar('M');
+ putchar('-');
+ }
+ if (!isprint(c)) {
+ c ^= 0x40; /* DEL to ?, others to alpha */
+ putchar('^');
+ }
+ putchar(c);
+ }
+ return (n == 0) ? 0 : 1;
+}
+
+/*
+ * Print out a null-padded filename (or other ascii string).
+ * If ep is NULL, assume no truncation check is needed.
+ * Return true if truncated.
+ */
+int
+fn_printzp(register const u_char *s, register u_int n,
+ register const u_char *ep)
+{
+ register int ret;
+ register u_char c;
+
+ ret = 1; /* assume truncated */
+ while (n > 0 && (ep == NULL || s < ep)) {
+ n--;
+ c = *s++;
+ if (c == '\0') {
+ ret = 0;
+ break;
+ }
+ if (!isascii(c)) {
+ c = toascii(c);
+ putchar('M');
+ putchar('-');
+ }
+ if (!isprint(c)) {
+ c ^= 0x40; /* DEL to ?, others to alpha */
+ putchar('^');
+ }
+ putchar(c);
+ }
+ return (n == 0) ? 0 : ret;
+}
+
+/*
+ * Format the timestamp
+ */
+char *
+ts_format(register int sec, register int usec)
+{
+ static char buf[sizeof("00:00:00.000000")];
+ (void)snprintf(buf, sizeof(buf), "%02d:%02d:%02d.%06u",
+ sec / 3600, (sec % 3600) / 60, sec % 60, usec);
+
+ return buf;
+}
+
+/*
+ * Print the timestamp
+ */
+void
+ts_print(register const struct timeval *tvp)
+{
+ register int s;
+ struct tm *tm;
+ time_t Time;
+ static unsigned b_sec;
+ static unsigned b_usec;
+ int d_usec;
+ int d_sec;
+
+ switch (tflag) {
+
+ case 0: /* Default */
+ s = (tvp->tv_sec + thiszone) % 86400;
+ (void)printf("%s ", ts_format(s, tvp->tv_usec));
+ break;
+
+ case 1: /* No time stamp */
+ break;
+
+ case 2: /* Unix timeval style */
+ (void)printf("%u.%06u ",
+ (unsigned)tvp->tv_sec,
+ (unsigned)tvp->tv_usec);
+ break;
+
+ case 3: /* Microseconds since previous packet */
+ case 5: /* Microseconds since first packet */
+ if (b_sec == 0) {
+ /* init timestamp for first packet */
+ b_usec = tvp->tv_usec;
+ b_sec = tvp->tv_sec;
+ }
+
+ d_usec = tvp->tv_usec - b_usec;
+ d_sec = tvp->tv_sec - b_sec;
+
+ while (d_usec < 0) {
+ d_usec += 1000000;
+ d_sec--;
+ }
+
+ (void)printf("%s ", ts_format(d_sec, d_usec));
+
+ if (tflag == 3) { /* set timestamp for last packet */
+ b_sec = tvp->tv_sec;
+ b_usec = tvp->tv_usec;
+ }
+ break;
+
+ case 4: /* Default + Date*/
+ s = (tvp->tv_sec + thiszone) % 86400;
+ Time = (tvp->tv_sec + thiszone) - s;
+ tm = gmtime (&Time);
+ if (!tm)
+ printf("Date fail ");
+ else
+ printf("%04d-%02d-%02d %s ",
+ tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
+ ts_format(s, tvp->tv_usec));
+ break;
+ }
+}
+
+/*
+ * Print a relative number of seconds (e.g. hold time, prune timer)
+ * in the form 5m1s. This does no truncation, so 32230861 seconds
+ * is represented as 1y1w1d1h1m1s.
+ */
+void
+relts_print(int secs)
+{
+ static const char *lengths[] = {"y", "w", "d", "h", "m", "s"};
+ static const int seconds[] = {31536000, 604800, 86400, 3600, 60, 1};
+ const char **l = lengths;
+ const int *s = seconds;
+
+ if (secs == 0) {
+ (void)printf("0s");
+ return;
+ }
+ if (secs < 0) {
+ (void)printf("-");
+ secs = -secs;
+ }
+ while (secs > 0) {
+ if (secs >= *s) {
+ (void)printf("%d%s", secs / *s, *l);
+ secs -= (secs / *s) * *s;
+ }
+ s++;
+ l++;
+ }
+}
+
+/*
+ * this is a generic routine for printing unknown data;
+ * we pass on the linefeed plus indentation string to
+ * get a proper output - returns 0 on error
+ */
+
+int
+print_unknown_data(const u_char *cp,const char *ident,int len)
+{
+ if (len < 0) {
+ printf("%sDissector error: print_unknown_data called with negative length",
+ ident);
+ return(0);
+ }
+ if (snapend - cp < len)
+ len = snapend - cp;
+ if (len < 0) {
+ printf("%sDissector error: print_unknown_data called with pointer past end of packet",
+ ident);
+ return(0);
+ }
+ hex_print(ident,cp,len);
+ return(1); /* everything is ok */
+}
+
+/*
+ * Convert a token value to a string; use "fmt" if not found.
+ */
+const char *
+tok2strbuf(register const struct tok *lp, register const char *fmt,
+ register int v, char *buf, size_t bufsize)
+{
+ if (lp != NULL) {
+ while (lp->s != NULL) {
+ if (lp->v == v)
+ return (lp->s);
+ ++lp;
+ }
+ }
+ if (fmt == NULL)
+ fmt = "#%d";
+
+ (void)snprintf(buf, bufsize, fmt, v);
+ return (const char *)buf;
+}
+
+/*
+ * Convert a token value to a string; use "fmt" if not found.
+ */
+const char *
+tok2str(register const struct tok *lp, register const char *fmt,
+ register int v)
+{
+ static char buf[4][128];
+ static int idx = 0;
+ char *ret;
+
+ ret = buf[idx];
+ idx = (idx+1) & 3;
+ return tok2strbuf(lp, fmt, v, ret, sizeof(buf[0]));
+}
+
+/*
+ * Convert a bit token value to a string; use "fmt" if not found.
+ * this is useful for parsing bitfields, the output strings are seperated
+ * if the s field is positive.
+ */
+static char *
+bittok2str_internal(register const struct tok *lp, register const char *fmt,
+ register int v, register int sep)
+{
+ static char buf[256]; /* our stringbuffer */
+ int buflen=0;
+ register int rotbit; /* this is the bit we rotate through all bitpositions */
+ register int tokval;
+
+ while (lp != NULL && lp->s != NULL) {
+ tokval=lp->v; /* load our first value */
+ rotbit=1;
+ while (rotbit != 0) {
+ /*
+ * lets AND the rotating bit with our token value
+ * and see if we have got a match
+ */
+ if (tokval == (v&rotbit)) {
+ /* ok we have found something */
+ buflen+=snprintf(buf+buflen, sizeof(buf)-buflen, "%s%s",
+ lp->s, sep ? ", " : "");
+ break;
+ }
+ rotbit=rotbit<<1; /* no match - lets shift and try again */
+ }
+ lp++;
+ }
+
+ /* user didn't want string seperation - no need to cut off trailing seperators */
+ if (!sep) {
+ return (buf);
+ }
+
+ if (buflen != 0) { /* did we find anything */
+ /* yep, set the the trailing zero 2 bytes before to eliminate the last comma & whitespace */
+ buf[buflen-2] = '\0';
+ return (buf);
+ }
+ else {
+ /* bummer - lets print the "unknown" message as advised in the fmt string if we got one */
+ if (fmt == NULL)
+ fmt = "#%d";
+ (void)snprintf(buf, sizeof(buf), fmt, v);
+ return (buf);
+ }
+}
+
+/*
+ * Convert a bit token value to a string; use "fmt" if not found.
+ * this is useful for parsing bitfields, the output strings are not seperated.
+ */
+char *
+bittok2str_nosep(register const struct tok *lp, register const char *fmt,
+ register int v)
+{
+ return (bittok2str_internal(lp, fmt, v, 0));
+}
+
+/*
+ * Convert a bit token value to a string; use "fmt" if not found.
+ * this is useful for parsing bitfields, the output strings are comma seperated.
+ */
+char *
+bittok2str(register const struct tok *lp, register const char *fmt,
+ register int v)
+{
+ return (bittok2str_internal(lp, fmt, v, 1));
+}
+
+/*
+ * Convert a value to a string using an array; the macro
+ * tok2strary() in <interface.h> is the public interface to
+ * this function and ensures that the second argument is
+ * correct for bounds-checking.
+ */
+const char *
+tok2strary_internal(register const char **lp, int n, register const char *fmt,
+ register int v)
+{
+ static char buf[128];
+
+ if (v >= 0 && v < n && lp[v] != NULL)
+ return lp[v];
+ if (fmt == NULL)
+ fmt = "#%d";
+ (void)snprintf(buf, sizeof(buf), fmt, v);
+ return (buf);
+}
+
+/*
+ * Convert a 32-bit netmask to prefixlen if possible
+ * the function returns the prefix-len; if plen == -1
+ * then conversion was not possible;
+ */
+
+int
+mask2plen(u_int32_t mask)
+{
+ u_int32_t bitmasks[33] = {
+ 0x00000000,
+ 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000,
+ 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000,
+ 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000,
+ 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000,
+ 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000,
+ 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00,
+ 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0,
+ 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff
+ };
+ int prefix_len = 32;
+
+ /* let's see if we can transform the mask into a prefixlen */
+ while (prefix_len >= 0) {
+ if (bitmasks[prefix_len] == mask)
+ break;
+ prefix_len--;
+ }
+ return (prefix_len);
+}
+
+#ifdef INET6
+int
+mask62plen(const u_char *mask)
+{
+ u_char bitmasks[9] = {
+ 0x00,
+ 0x80, 0xc0, 0xe0, 0xf0,
+ 0xf8, 0xfc, 0xfe, 0xff
+ };
+ int byte;
+ int cidr_len = 0;
+
+ for (byte = 0; byte < 16; byte++) {
+ u_int bits;
+
+ for (bits = 0; bits < (sizeof (bitmasks) / sizeof (bitmasks[0])); bits++) {
+ if (mask[byte] == bitmasks[bits]) {
+ cidr_len += bits;
+ break;
+ }
+ }
+
+ if (mask[byte] != 0xff)
+ break;
+ }
+ return (cidr_len);
+}
+#endif /* INET6 */
+
+/* VARARGS */
+void
+error(const char *fmt, ...)
+{
+ va_list ap;
+
+ (void)fprintf(stderr, "%s: ", program_name);
+ va_start(ap, fmt);
+ (void)vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ if (*fmt) {
+ fmt += strlen(fmt);
+ if (fmt[-1] != '\n')
+ (void)fputc('\n', stderr);
+ }
+ exit(1);
+ /* NOTREACHED */
+}
+
+/* VARARGS */
+void
+warning(const char *fmt, ...)
+{
+ va_list ap;
+
+ (void)fprintf(stderr, "%s: WARNING: ", program_name);
+ va_start(ap, fmt);
+ (void)vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ if (*fmt) {
+ fmt += strlen(fmt);
+ if (fmt[-1] != '\n')
+ (void)fputc('\n', stderr);
+ }
+}
+
+/*
+ * Copy arg vector into a new buffer, concatenating arguments with spaces.
+ */
+char *
+copy_argv(register char **argv)
+{
+ register char **p;
+ register u_int len = 0;
+ char *buf;
+ char *src, *dst;
+
+ p = argv;
+ if (*p == 0)
+ return 0;
+
+ while (*p)
+ len += strlen(*p++) + 1;
+
+ buf = (char *)malloc(len);
+ if (buf == NULL)
+ error("copy_argv: malloc");
+
+ p = argv;
+ dst = buf;
+ while ((src = *p++) != NULL) {
+ while ((*dst++ = *src++) != '\0')
+ ;
+ dst[-1] = ' ';
+ }
+ dst[-1] = '\0';
+
+ return buf;
+}
+
+/*
+ * On Windows, we need to open the file in binary mode, so that
+ * we get all the bytes specified by the size we get from "fstat()".
+ * On UNIX, that's not necessary. O_BINARY is defined on Windows;
+ * we define it as 0 if it's not defined, so it does nothing.
+ */
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+char *
+read_infile(char *fname)
+{
+ register int i, fd, cc;
+ register char *cp;
+ struct stat buf;
+
+ fd = open(fname, O_RDONLY|O_BINARY);
+ if (fd < 0)
+ error("can't open %s: %s", fname, pcap_strerror(errno));
+
+ if (fstat(fd, &buf) < 0)
+ error("can't stat %s: %s", fname, pcap_strerror(errno));
+
+ cp = malloc((u_int)buf.st_size + 1);
+ if (cp == NULL)
+ error("malloc(%d) for %s: %s", (u_int)buf.st_size + 1,
+ fname, pcap_strerror(errno));
+ cc = read(fd, cp, (u_int)buf.st_size);
+ if (cc < 0)
+ error("read %s: %s", fname, pcap_strerror(errno));
+ if (cc != buf.st_size)
+ error("short read %s (%d != %d)", fname, cc, (int)buf.st_size);
+
+ close(fd);
+ /* replace "# comment" with spaces */
+ for (i = 0; i < cc; i++) {
+ if (cp[i] == '#')
+ while (i < cc && cp[i] != '\n')
+ cp[i++] = ' ';
+ }
+ cp[cc] = '\0';
+ return (cp);
+}
+
+void
+safeputs(const char *s, int maxlen)
+{
+ int idx = 0;
+
+ while (*s && idx < maxlen) {
+ safeputchar(*s);
+ idx++;
+ s++;
+ }
+}
+
+void
+safeputchar(int c)
+{
+ unsigned char ch;
+
+ ch = (unsigned char)(c & 0xff);
+ if (ch < 0x80 && isprint(ch))
+ printf("%c", ch);
+ else
+ printf("\\0x%02x", ch);
+}
diff --git a/freebsd/usr.sbin/tcpdump/tcpdump/config.h b/freebsd/usr.sbin/tcpdump/tcpdump/config.h
new file mode 100644
index 00000000..62fa3cd3
--- /dev/null
+++ b/freebsd/usr.sbin/tcpdump/tcpdump/config.h
@@ -0,0 +1,328 @@
+/* $FreeBSD$ */
+/* This is an edited copy of the config.h generated by configure. */
+
+/* config.h. Generated from config.h.in by configure. */
+/* config.h.in. Generated from configure.in by autoheader. */
+/* "generated automatically" means DO NOT MAKE CHANGES TO config.h.in --
+ * make them to acconfig.h and rerun autoheader */
+
+/* Define if you enable IPv6 support */
+/* See Makefile */
+/* #undef INET6 */
+
+/* Define if you enable support for the libsmi. */
+/* #undef LIBSMI */
+
+/* define if you have the addrinfo function. */
+#define HAVE_ADDRINFO 1
+
+/* define if you need to include missing/addrinfoh.h. */
+/* #undef NEED_ADDRINFO_H */
+
+/* define ifyou have the h_errno variable. */
+#define HAVE_H_ERRNO 1
+
+/* define if you have struct sockaddr_storage */
+#define HAVE_SOCKADDR_STORAGE 1
+
+/* define if you have both getipnodebyname() and getipnodebyaddr() */
+/* #undef USE_GETIPNODEBY */
+
+/* define if you have ether_ntohost() and it works */
+#define USE_ETHER_NTOHOST 1
+
+/* define if libpcap has pcap_version */
+/* #undef HAVE_PCAP_VERSION */
+
+/* define if libpcap has pcap_debug */
+/* #undef HAVE_PCAP_DEBUG */
+
+/* define if libpcap has yydebug */
+/* #undef HAVE_YYDEBUG */
+
+/* define if libpcap has pcap_list_datalinks() */
+#define HAVE_PCAP_LIST_DATALINKS 1
+
+/* define if libpcap has pcap_set_datalink() */
+#define HAVE_PCAP_SET_DATALINK 1
+
+/* define if libpcap has pcap_datalink_name_to_val() */
+#define HAVE_PCAP_DATALINK_NAME_TO_VAL 1
+
+/* define if libpcap has pcap_datalink_val_to_description() */
+#define HAVE_PCAP_DATALINK_VAL_TO_DESCRIPTION 1
+
+/* define if libpcap has pcap_dump_ftell() */
+#define HAVE_PCAP_DUMP_FTELL 1
+
+/* define if you have getrpcbynumber() */
+#define HAVE_GETRPCBYNUMBER 1
+
+/* Workaround for missing 64-bit formats */
+/* #undef PRId64 */
+/* #undef PRIo64 */
+/* #undef PRIx64 */
+/* #undef PRIu64 */
+
+/* Whether or not to include the possibly-buggy SMB printer */
+#define TCPDUMP_DO_SMB 1
+
+/* Define if you have the dnet_htoa function. */
+/* #undef HAVE_DNET_HTOA */
+
+/* Define if you have a dnet_htoa declaration in <netdnet/dnetdb.h>. */
+/* #undef HAVE_NETDNET_DNETDB_H_DNET_HTOA */
+
+/* define if should drop privileges by default */
+/* #undef WITH_USER */
+
+/* define if should chroot when dropping privileges */
+/* #undef WITH_CHROOT */
+
+/* Define to 1 if you have the `alarm' function. */
+#define HAVE_ALARM 1
+
+/* Define to 1 if you have the `bpf_dump' function. */
+#define HAVE_BPF_DUMP 1
+
+/* Define to 1 if you have the declaration of `ether_ntohost', and to 0 if you
+ don't. */
+#define HAVE_DECL_ETHER_NTOHOST 1
+
+/* Define to 1 if you have the `ether_ntohost' function. */
+#define HAVE_ETHER_NTOHOST 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have the `fork' function. */
+#define HAVE_FORK 1
+
+/* Define to 1 if you have the `getnameinfo' function. */
+#define HAVE_GETNAMEINFO 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the `crypto' library (-lcrypto). */
+/* See Makefile */
+/* #undef HAVE_LIBCRYPTO */
+
+/* Define to 1 if you have the `rpc' library (-lrpc). */
+/* #undef HAVE_LIBRPC */
+
+/* Define to 1 if you have the `smi' library (-lsmi). */
+/* #undef HAVE_LIBSMI */
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the <netdnet/dnetdb.h> header file. */
+/* #undef HAVE_NETDNET_DNETDB_H */
+
+/* Define to 1 if you have the <netinet/ether.h> header file. */
+/* #undef HAVE_NETINET_ETHER_H */
+
+/* Define to 1 if you have the <netinet/if_ether.h> header file. */
+#define HAVE_NETINET_IF_ETHER_H 1
+
+/* Define to 1 if you have the <net/pfvar.h> header file. */
+/* See Makefile */
+/* #undef HAVE_NET_PFVAR_H */
+
+/* Define to 1 if you have the <openssl/evp.h> header file. */
+/* See Makefile */
+/* #undef HAVE_OPENSSL_EVP_H 1 */
+
+/* if there's an os_proto.h for this platform, to use additional prototypes */
+/* #undef HAVE_OS_PROTO_H */
+
+/* Define to 1 if you have the <pcap/bluetooth.h> header file. */
+/* #undef HAVE_PCAP_BLUETOOTH_H */
+
+/* Define to 1 if you have the `pcap_breakloop' function. */
+#define HAVE_PCAP_BREAKLOOP 1
+
+/* Define to 1 if you have the `pcap_create' function. */
+#define HAVE_PCAP_CREATE 1
+
+/* Define to 1 if you have the `pcap_dump_flush' function. */
+#define HAVE_PCAP_DUMP_FLUSH 1
+
+/* Define to 1 if you have the `pcap_findalldevs' function. */
+#define HAVE_PCAP_FINDALLDEVS 1
+
+/* Define to 1 if the system has the type `pcap_if_t'. */
+#define HAVE_PCAP_IF_T 1
+
+/* Define to 1 if you have the `pcap_lib_version' function. */
+#define HAVE_PCAP_LIB_VERSION 1
+
+/* Define to 1 if you have the `pcap_set_tstamp_type' function. */
+#define HAVE_PCAP_SET_TSTAMP_TYPE 1
+
+/* Define to 1 if you have the <pcap/usb.h> header file. */
+/* #undef HAVE_PCAP_USB_H */
+
+/* Define to 1 if you have the `pfopen' function. */
+/* #undef HAVE_PFOPEN */
+
+/* Define to 1 if you have the <rpc/rpcent.h> header file. */
+#define HAVE_RPC_RPCENT_H 1
+
+/* Define to 1 if you have the <rpc/rpc.h> header file. */
+#define HAVE_RPC_RPC_H 1
+
+/* Define to 1 if you have the `setlinebuf' function. */
+#define HAVE_SETLINEBUF 1
+
+/* Define to 1 if you have the `sigaction' function. */
+#define HAVE_SIGACTION 1
+
+/* Define to 1 if you have the `sigset' function. */
+/* #undef HAVE_SIGSET */
+
+/* Define to 1 if you have the <smi.h> header file. */
+/* #undef HAVE_SMI_H */
+
+/* Define to 1 if you have the `snprintf' function. */
+#define HAVE_SNPRINTF 1
+
+/* if struct sockaddr has the sa_len member */
+#define HAVE_SOCKADDR_SA_LEN 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#define HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the `strdup' function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the `strftime' function. */
+#define HAVE_STRFTIME 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the `strlcat' function. */
+#define HAVE_STRLCAT 1
+
+/* Define to 1 if you have the `strlcpy' function. */
+#define HAVE_STRLCPY 1
+
+/* Define to 1 if you have the `strsep' function. */
+#define HAVE_STRSEP 1
+
+/* Define to 1 if the system has the type `struct ether_addr'. */
+/* #undef HAVE_STRUCT_ETHER_ADDR */
+
+/* Define to 1 if you have the <sys/bitypes.h> header file. */
+/* #undef HAVE_SYS_BITYPES_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the `vfork' function. */
+#define HAVE_VFORK 1
+
+/* Define to 1 if you have the `vfprintf' function. */
+#define HAVE_VFPRINTF 1
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#define HAVE_VSNPRINTF 1
+
+/* define if your compiler has __attribute__ */
+#define HAVE___ATTRIBUTE__ 1
+
+/* if unaligned access fails */
+/* #undef LBL_ALIGN */
+
+/* Define to 1 if netinet/ether.h declares `ether_ntohost' */
+/* #undef NETINET_ETHER_H_DECLARES_ETHER_NTOHOST */
+
+/* Define to 1 if netinet/if_ether.h declares `ether_ntohost' */
+#define NETINET_IF_ETHER_H_DECLARES_ETHER_NTOHOST /**/
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT ""
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME ""
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING ""
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION ""
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* return value of signal handlers */
+#define RETSIGVAL /**/
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* get BSD semantics on Irix */
+/* #undef _BSD_SIGNALS */
+
+/* needed on HP-UX */
+/* #undef _HPUX_SOURCE */
+
+/* define on AIX to get certain functions */
+/* #undef _SUN */
+
+/* define if your compiler allows __attribute__((format)) to be applied to
+ function pointers */
+#define __ATTRIBUTE___FORMAT_OK_FOR_FUNCTION_POINTERS 1
+
+/* to handle Ultrix compilers that don't support const in prototypes */
+/* #undef const */
+
+/* Define as token for inline if inlining supported */
+#define inline inline
+
+/* Define to `short' if int16_t not defined. */
+/* #undef int16_t */
+
+/* Define to `int' if int32_t not defined. */
+/* #undef int32_t */
+
+/* Define to `long long' if int64_t not defined. */
+/* #undef int64_t */
+
+/* Define to `signed char' if int8_t not defined. */
+/* #undef int8_t */
+
+/* Define to `unsigned short' if u_int16_t not defined. */
+/* #undef u_int16_t */
+
+/* Define to `unsigned int' if u_int32_t not defined. */
+/* #undef u_int32_t */
+
+/* Define to `unsigned long long' if u_int64_t not defined. */
+/* #undef u_int64_t */
+
+/* Define to `unsigned char' if u_int8_t not defined. */
+/* #undef u_int8_t */
diff --git a/libbsd.py b/libbsd.py
index 4d98e515..56d3a7aa 100755
--- a/libbsd.py
+++ b/libbsd.py
@@ -137,7 +137,7 @@ def rtems(mm):
mm.generator['rtems-path'](),
mm.generator['no-convert'](),
mm.generator['no-convert'](),
- mm.generator['kvm-symbols']()))
+ mm.generator['kvm-symbols'](includes = 'rtemsbsd/rtems')))
mod.addFile(mm.generator['file']('lib/libc/net/nslexer.l',
mm.generator['freebsd-path'](),
mm.generator['convert'](),
@@ -1856,7 +1856,7 @@ def user_space(mm):
'sbin/dhclient/tree.h',
'sbin/ifconfig/ifconfig.h',
'sbin/ifconfig/regdomain.h',
- 'usr.bin/netstat/netstat.h',
+ 'usr.bin/netstat/netstat.h'
]
)
mod.addFile(mm.generator['file']('include/rpc/rpcb_prot.x',
@@ -1871,7 +1871,7 @@ def user_space(mm):
mm.generator['route-keywords']()))
mod.addUserSpaceSourceFiles(
[
- 'lib/libc/db/btree/bt_close.c',
+ 'lib/libc/db/btree/bt_close.c',
'lib/libc/db/btree/bt_conv.c',
'lib/libc/db/btree/bt_debug.c',
'lib/libc/db/btree/bt_delete.c',
@@ -2044,6 +2044,322 @@ def user_space(mm):
return mod
#
+# Contrib libpcap
+#
+def contrib_libpcap(mm):
+ mod = builder.Module('contrib_libpcap')
+ cflags = ['-DINET6',
+ '-D_U_=__attribute__((unused))',
+ '-DHAVE_INTTYPES=1',
+ '-DHAVE_STDINT=1',
+ '-DHAVE_STRERROR=1',
+ '-DHAVE_STRLCPY=1',
+ '-DHAVE_SNPRINTF=1',
+ '-DHAVE_VSNPRINTF=1']
+ mod.addUserSpaceHeaderFiles(
+ [
+ 'contrib/libpcap/arcnet.h',
+ 'contrib/libpcap/atmuni31.h',
+ 'contrib/libpcap/ethertype.h',
+ 'contrib/libpcap/gencode.h',
+ 'contrib/libpcap/ieee80211.h',
+ 'contrib/libpcap/llc.h',
+ 'contrib/libpcap/nlpid.h',
+ 'contrib/libpcap/pcap-common.h',
+ 'contrib/libpcap/pcap-int.h',
+ 'contrib/libpcap/pcap-namedb.h',
+ 'contrib/libpcap/pcap.h',
+ 'contrib/libpcap/pcap/ipnet.h',
+ 'contrib/libpcap/pcap/namedb.h',
+ 'contrib/libpcap/pcap/pcap.h',
+ 'contrib/libpcap/pcap/sll.h',
+ 'contrib/libpcap/pcap/usb.h',
+ 'contrib/libpcap/ppp.h',
+ 'contrib/libpcap/sf-pcap-ng.h',
+ 'contrib/libpcap/sf-pcap.h',
+ 'contrib/libpcap/sunatmpos.h',
+ ]
+ )
+ gen_cflags = cflags + ['-DNEED_YYPARSE_WRAPPER=1',
+ '-Dyylval=pcap_lval']
+ mod.addFile(mm.generator['file']('contrib/libpcap/scanner.l',
+ mm.generator['freebsd-path'](),
+ mm.generator['convert'](),
+ mm.generator['convert'](),
+ mm.generator['lex']('pcap',
+ 'scanner.c',
+ gen_cflags)))
+ mod.addFile(mm.generator['file']('contrib/libpcap/grammar.y',
+ mm.generator['freebsd-path'](),
+ mm.generator['convert'](),
+ mm.generator['convert'](),
+ mm.generator['yacc']('pcap',
+ 'tokdefs.h',
+ gen_cflags)))
+ mod.addUserSpaceSourceFiles(
+ [
+ 'contrib/libpcap/bpf_image.c',
+ 'contrib/libpcap/etherent.c',
+ 'contrib/libpcap/fad-getad.c',
+ 'contrib/libpcap/gencode.c',
+ 'contrib/libpcap/inet.c',
+ 'contrib/libpcap/pcap.c',
+ 'contrib/libpcap/pcap-bpf.c',
+ 'contrib/libpcap/pcap-common.c',
+ 'contrib/libpcap/optimize.c',
+ 'contrib/libpcap/nametoaddr.c',
+ 'contrib/libpcap/savefile.c',
+ 'contrib/libpcap/sf-pcap.c',
+ 'contrib/libpcap/sf-pcap-ng.c',
+ ],
+ mm.generator['source'](cflags)
+ )
+ return mod
+
+#
+# /usr/sbin/tcpdump
+#
+def usr_sbin_tcpdump(mm):
+ mod = builder.Module('usr_sbin_tcpdump')
+ mod.addUserSpaceHeaderFiles(
+ [
+ 'contrib/tcpdump/addrtoname.h',
+ 'contrib/tcpdump/af.h',
+ 'contrib/tcpdump/ah.h',
+ 'contrib/tcpdump/aodv.h',
+ 'contrib/tcpdump/appletalk.h',
+ 'contrib/tcpdump/arcnet.h',
+ 'contrib/tcpdump/atm.h',
+ 'contrib/tcpdump/bgp.h',
+ 'contrib/tcpdump/bootp.h',
+ 'contrib/tcpdump/chdlc.h',
+ 'contrib/tcpdump/cpack.h',
+ 'contrib/tcpdump/dccp.h',
+ 'contrib/tcpdump/decnet.h',
+ 'contrib/tcpdump/decode_prefix.h',
+ 'contrib/tcpdump/enc.h',
+ 'contrib/tcpdump/esp.h',
+ 'contrib/tcpdump/ether.h',
+ 'contrib/tcpdump/ethertype.h',
+ 'contrib/tcpdump/extract.h',
+ 'contrib/tcpdump/fddi.h',
+ 'contrib/tcpdump/forces.h',
+ 'contrib/tcpdump/gmpls.h',
+ 'contrib/tcpdump/gmt2local.h',
+ 'contrib/tcpdump/icmp6.h',
+ 'contrib/tcpdump/ieee802_11.h',
+ 'contrib/tcpdump/ieee802_11_radio.h',
+ 'contrib/tcpdump/igrp.h',
+ 'contrib/tcpdump/interface.h',
+ 'contrib/tcpdump/ip.h',
+ 'contrib/tcpdump/ip6.h',
+ 'contrib/tcpdump/ipfc.h',
+ 'contrib/tcpdump/ipnet.h',
+ 'contrib/tcpdump/ipproto.h',
+ 'contrib/tcpdump/ipsec_doi.h',
+ 'contrib/tcpdump/ipx.h',
+ 'contrib/tcpdump/isakmp.h',
+ 'contrib/tcpdump/l2tp.h',
+ 'contrib/tcpdump/l2vpn.h',
+ 'contrib/tcpdump/lane.h',
+ 'contrib/tcpdump/llc.h',
+ 'contrib/tcpdump/machdep.h',
+ 'contrib/tcpdump/mib.h',
+ 'contrib/tcpdump/mpls.h',
+ 'contrib/tcpdump/nameser.h',
+ 'contrib/tcpdump/netbios.h',
+ 'contrib/tcpdump/netdissect.h',
+ 'contrib/tcpdump/nfs.h',
+ 'contrib/tcpdump/nfsfh.h',
+ 'contrib/tcpdump/nlpid.h',
+ 'contrib/tcpdump/ntp.h',
+ 'contrib/tcpdump/oakley.h',
+ 'contrib/tcpdump/ospf.h',
+ 'contrib/tcpdump/ospf6.h',
+ 'contrib/tcpdump/oui.h',
+ 'contrib/tcpdump/pcap-missing.h',
+ 'contrib/tcpdump/pmap_prot.h',
+ 'contrib/tcpdump/ppi.h',
+ 'contrib/tcpdump/ppp.h',
+ 'contrib/tcpdump/route6d.h',
+ 'contrib/tcpdump/rpc_auth.h',
+ 'contrib/tcpdump/rpc_msg.h',
+ 'contrib/tcpdump/rx.h',
+ 'contrib/tcpdump/sctpConstants.h',
+ 'contrib/tcpdump/sctpHeader.h',
+ 'contrib/tcpdump/setsignal.h',
+ 'contrib/tcpdump/signature.h',
+ 'contrib/tcpdump/slcompress.h',
+ 'contrib/tcpdump/slip.h',
+ 'contrib/tcpdump/sll.h',
+ 'contrib/tcpdump/smb.h',
+ 'contrib/tcpdump/tcp.h',
+ 'contrib/tcpdump/tcpdump-stdinc.h',
+ 'contrib/tcpdump/telnet.h',
+ 'contrib/tcpdump/tftp.h',
+ 'contrib/tcpdump/timed.h',
+ 'contrib/tcpdump/token.h',
+ 'contrib/tcpdump/udp.h',
+ 'usr.sbin/tcpdump/tcpdump/config.h',
+ ]
+ )
+ mod.addUserSpaceSourceFiles(
+ [
+ 'contrib/tcpdump/addrtoname.c',
+ 'contrib/tcpdump/af.c',
+ 'contrib/tcpdump/bpf_dump.c',
+ 'contrib/tcpdump/checksum.c',
+ 'contrib/tcpdump/cpack.c',
+ 'contrib/tcpdump/gmpls.c',
+ 'contrib/tcpdump/gmt2local.c',
+ 'contrib/tcpdump/in_cksum.c',
+ 'contrib/tcpdump/ipproto.c',
+ 'contrib/tcpdump/machdep.c',
+ 'contrib/tcpdump/nlpid.c',
+ 'contrib/tcpdump/l2vpn.c',
+ 'contrib/tcpdump/oui.c',
+ 'contrib/tcpdump/parsenfsfh.c',
+ 'contrib/tcpdump/print-802_11.c',
+ 'contrib/tcpdump/print-802_15_4.c',
+ 'contrib/tcpdump/print-ah.c',
+ 'contrib/tcpdump/print-aodv.c',
+ 'contrib/tcpdump/print-ap1394.c',
+ 'contrib/tcpdump/print-arcnet.c',
+ 'contrib/tcpdump/print-arp.c',
+ 'contrib/tcpdump/print-ascii.c',
+ 'contrib/tcpdump/print-atalk.c',
+ 'contrib/tcpdump/print-atm.c',
+ 'contrib/tcpdump/print-babel.c',
+ 'contrib/tcpdump/print-beep.c',
+ 'contrib/tcpdump/print-bfd.c',
+ 'contrib/tcpdump/print-bgp.c',
+ 'contrib/tcpdump/print-bootp.c',
+ 'contrib/tcpdump/print-bt.c',
+ 'contrib/tcpdump/print-carp.c',
+ 'contrib/tcpdump/print-cdp.c',
+ 'contrib/tcpdump/print-cfm.c',
+ 'contrib/tcpdump/print-chdlc.c',
+ 'contrib/tcpdump/print-cip.c',
+ 'contrib/tcpdump/print-cnfp.c',
+ 'contrib/tcpdump/print-dccp.c',
+ 'contrib/tcpdump/print-decnet.c',
+ 'contrib/tcpdump/print-dhcp6.c',
+ 'contrib/tcpdump/print-domain.c',
+ 'contrib/tcpdump/print-dtp.c',
+ 'contrib/tcpdump/print-dvmrp.c',
+ 'contrib/tcpdump/print-eap.c',
+ 'contrib/tcpdump/print-egp.c',
+ 'contrib/tcpdump/print-eigrp.c',
+ 'contrib/tcpdump/print-enc.c',
+ 'contrib/tcpdump/print-esp.c',
+ 'contrib/tcpdump/print-ether.c',
+ 'contrib/tcpdump/print-fddi.c',
+ 'contrib/tcpdump/print-forces.c',
+ 'contrib/tcpdump/print-fr.c',
+ 'contrib/tcpdump/print-frag6.c',
+ 'contrib/tcpdump/print-gre.c',
+ 'contrib/tcpdump/print-hsrp.c',
+ 'contrib/tcpdump/print-icmp.c',
+ 'contrib/tcpdump/print-icmp6.c',
+ 'contrib/tcpdump/print-igmp.c',
+ 'contrib/tcpdump/print-igrp.c',
+ 'contrib/tcpdump/print-ip.c',
+ 'contrib/tcpdump/print-ip6.c',
+ 'contrib/tcpdump/print-ip6opts.c',
+ 'contrib/tcpdump/print-ipcomp.c',
+ 'contrib/tcpdump/print-ipfc.c',
+ 'contrib/tcpdump/print-ipnet.c',
+ 'contrib/tcpdump/print-ipx.c',
+ 'contrib/tcpdump/print-isakmp.c',
+ 'contrib/tcpdump/print-isoclns.c',
+ 'contrib/tcpdump/print-juniper.c',
+ 'contrib/tcpdump/print-krb.c',
+ 'contrib/tcpdump/print-l2tp.c',
+ 'contrib/tcpdump/print-lane.c',
+ 'contrib/tcpdump/print-ldp.c',
+ 'contrib/tcpdump/print-llc.c',
+ 'contrib/tcpdump/print-lldp.c',
+ 'contrib/tcpdump/print-lmp.c',
+ 'contrib/tcpdump/print-lspping.c',
+ 'contrib/tcpdump/print-lwapp.c',
+ 'contrib/tcpdump/print-lwres.c',
+ 'contrib/tcpdump/print-mobile.c',
+ 'contrib/tcpdump/print-mobility.c',
+ 'contrib/tcpdump/print-mpcp.c',
+ 'contrib/tcpdump/print-mpls.c',
+ 'contrib/tcpdump/print-msdp.c',
+ 'contrib/tcpdump/print-msnlb.c',
+ 'contrib/tcpdump/print-netbios.c',
+ 'contrib/tcpdump/print-nfs.c',
+ 'contrib/tcpdump/print-ntp.c',
+ 'contrib/tcpdump/print-null.c',
+ 'contrib/tcpdump/print-olsr.c',
+ 'contrib/tcpdump/print-ospf.c',
+ 'contrib/tcpdump/print-ospf6.c',
+ 'contrib/tcpdump/print-otv.c',
+ 'contrib/tcpdump/print-pflog.c',
+ 'contrib/tcpdump/print-pfsync.c',
+ 'contrib/tcpdump/print-pgm.c',
+ 'contrib/tcpdump/print-pim.c',
+ 'contrib/tcpdump/print-ppi.c',
+ 'contrib/tcpdump/print-ppp.c',
+ 'contrib/tcpdump/print-pppoe.c',
+ 'contrib/tcpdump/print-pptp.c',
+ 'contrib/tcpdump/print-radius.c',
+ 'contrib/tcpdump/print-raw.c',
+ 'contrib/tcpdump/print-rip.c',
+ 'contrib/tcpdump/print-ripng.c',
+ 'contrib/tcpdump/print-rpki-rtr.c',
+ 'contrib/tcpdump/print-rrcp.c',
+ 'contrib/tcpdump/print-rsvp.c',
+ 'contrib/tcpdump/print-rt6.c',
+ 'contrib/tcpdump/print-rx.c',
+ 'contrib/tcpdump/print-sctp.c',
+ 'contrib/tcpdump/print-sflow.c',
+ 'contrib/tcpdump/print-sip.c',
+ 'contrib/tcpdump/print-sl.c',
+ 'contrib/tcpdump/print-sll.c',
+ 'contrib/tcpdump/print-slow.c',
+ 'contrib/tcpdump/print-smb.c',
+ 'contrib/tcpdump/print-snmp.c',
+ 'contrib/tcpdump/print-stp.c',
+ 'contrib/tcpdump/print-sunatm.c',
+ #'contrib/tcpdump/print-sunrpc.c',
+ 'contrib/tcpdump/print-symantec.c',
+ 'contrib/tcpdump/print-syslog.c',
+ 'contrib/tcpdump/print-tcp.c',
+ 'contrib/tcpdump/print-telnet.c',
+ 'contrib/tcpdump/print-tftp.c',
+ 'contrib/tcpdump/print-timed.c',
+ 'contrib/tcpdump/print-tipc.c',
+ 'contrib/tcpdump/print-token.c',
+ 'contrib/tcpdump/print-udld.c',
+ 'contrib/tcpdump/print-udp.c',
+ 'contrib/tcpdump/print-usb.c',
+ 'contrib/tcpdump/print-vjc.c',
+ 'contrib/tcpdump/print-vqp.c',
+ 'contrib/tcpdump/print-vrrp.c',
+ 'contrib/tcpdump/print-vtp.c',
+ 'contrib/tcpdump/print-vxlan.c',
+ 'contrib/tcpdump/print-wb.c',
+ 'contrib/tcpdump/print-zephyr.c',
+ 'contrib/tcpdump/print-zeromq.c',
+ 'contrib/tcpdump/setsignal.c',
+ 'contrib/tcpdump/signature.c',
+ 'contrib/tcpdump/smbutil.c',
+ 'contrib/tcpdump/tcpdump.c',
+ 'contrib/tcpdump/util.c',
+ ],
+ mm.generator['source'](['-DINET6',
+ '-D_U_=__attribute__((unused))',
+ '-DHAVE_CONFIG_H=1',
+ '-DHAVE_NET_PFVAR_H=1'],
+ ['freebsd/contrib/tcpdump',
+ 'freebsd/usr.sbin/tcpdump/tcpdump'])
+ )
+ return mod
+
+#
# in_chksum Module
#
def in_cksum(mm):
@@ -2289,6 +2605,8 @@ def sources(mm):
mm.addModule(in_cksum(mm))
mm.addModule(user_space(mm))
+ mm.addModule(contrib_libpcap(mm))
+ mm.addModule(usr_sbin_tcpdump(mm))
mm.addModule(tests(mm))
mm.addModule(dhcpcd(mm))
diff --git a/makefile.py b/makefile.py
index 122650f4..3058e599 100755
--- a/makefile.py
+++ b/makefile.py
@@ -38,14 +38,26 @@ import builder
class SourceFileFragmentComposer(builder.BuildSystemFragmentComposer):
- def __init__(self, cflags = None):
+ def __init__(self, cflags = None, includes = None):
self.cflags = cflags
+ self.includes = includes
def compose(self, path):
fragment = 'LIB_C_FILES += ' + path + '\n'
+ cflags = ''
+ if self.includes != None:
+ if type(self.includes) is list:
+ cflags += ' '.join(self.includes)
+ else:
+ cflags += self.includes
if self.cflags != None:
+ if type(self.cflags) is list:
+ cflags += ' '.join(self.cflags)
+ else:
+ cflags += self.cflags
+ if len(cflags) > 0:
fragment = fragment + path[:-1] + 'o: ' + path + '\n' \
- + '\t$(CC) $(CPPFLAGS) $(CFLAGS) ' + self.cflags + ' -c $< -o $@\n'
+ + '\t$(CC) $(CPPFLAGS) $(CFLAGS) ' + cflags + ' -c $< -o $@\n'
return fragment
class TestFragementComposer(builder.BuildSystemFragmentComposer):
@@ -111,32 +123,54 @@ class RouteKeywordsFragmentComposer(builder.BuildSystemFragmentComposer):
class LexFragmentComposer(builder.BuildSystemFragmentComposer):
- def __init__(self, sym, dep):
+ def __init__(self, sym, dep, cflags = None, includes = None):
self.sym = sym
self.dep = dep
+ self.cflags = ''
+ if cflags is not None:
+ self.cflags += ' '.join(cflags)
+ if includes is not None:
+ self.cflags += ' -I'.join(includes)
def compose(self, path):
src = path[:-2] + '.c'
dep = path[:path.rfind('/')] + '/' + self.dep
- return 'LIB_C_FILES += ' + src + '\n' \
+ fragment = 'LIB_C_FILES += ' + src + '\n' \
+ src + ': ' + path + ' ' + dep + '\n' \
'\t${LEX} -P ' + self.sym + ' -t $< | sed -e \'/YY_BUF_SIZE/s/16384/1024/\' > $@\n'
+ if len(self.cflags) > 0:
+ fragment = fragment + src[:-1] + 'o: ' + src + '\n' \
+ + '\t$(CC) $(CPPFLAGS) $(CFLAGS) ' + self.cflags + ' -c $< -o $@\n'
+ return fragment
class YaccFragmentComposer(builder.BuildSystemFragmentComposer):
- def __init__(self, sym, header):
+ def __init__(self, sym, header, cflags = None, includes = None):
self.sym = sym
self.header = header
+ self.cflags = ''
+ if cflags is not None:
+ self.cflags += ' '.join(cflags)
+ if includes is not None:
+ self.cflags += ' -I'.join(includes)
def compose(self, path):
src = path[:-2] + '.c'
hdr = path[:path.rfind('/')] + '/' + self.header
- return 'LIB_C_FILES += ' + src + '\n' \
+ if self.sym is not None:
+ sym = '-b %s' % (self.sym)
+ else:
+ sym = os.path.basename(src)[:-2]
+ fragment = 'LIB_C_FILES += ' + src + '\n' \
+ src + ': ' + path + '\n' \
- '\tyacc -b ' + self.sym + ' -d -p ' + self.sym + ' $<\n' \
- '\tsed -e ''/YY_BUF_SIZE/s/16384/1024/'' < ' + self.sym + '.tab.c > $@\n' \
- '\trm -f ' + self.sym + '.tab.c\n' \
- '\tmv ' + self.sym + '.tab.h ' + hdr + '\n'
+ '\tyacc -b ' + sym + ' -d -p ' + sym + ' $<\n' \
+ '\tsed -e ''/YY_BUF_SIZE/s/16384/1024/'' < ' + sym + '.tab.c > $@\n' \
+ '\trm -f ' + sym + '.tab.c\n' \
+ '\tmv ' + sym + '.tab.h ' + hdr + '\n'
+ if len(self.cflags) > 0:
+ fragment = fragment + src[:-1] + 'o: ' + src + '\n' \
+ + '\t$(CC) $(CPPFLAGS) $(CFLAGS) ' + self.cflags + ' -c $< -o $@\n'
+ return fragment
# Module Manager - Collection of Modules
class ModuleManager(builder.ModuleManager):
diff --git a/rtemsbsd/include/machine/rtems-bsd-commands.h b/rtemsbsd/include/machine/rtems-bsd-commands.h
index 6618b933..df251787 100644
--- a/rtemsbsd/include/machine/rtems-bsd-commands.h
+++ b/rtemsbsd/include/machine/rtems-bsd-commands.h
@@ -58,6 +58,8 @@ int rtems_bsd_command_route(int argc, char **argv);
int rtems_bsd_command_dhcpcd(int argc, char **argv);
+int rtems_bsd_command_tcpdump(int argc, char **argv);
+
__END_DECLS
#endif /* _RTEMS_BSD_MACHINE_RTEMS_BSD_COMMANDS_H_ */
diff --git a/waf_generator.py b/waf_generator.py
index 4c9be070..800f8a47 100755
--- a/waf_generator.py
+++ b/waf_generator.py
@@ -48,13 +48,29 @@ def _add_files(name, files):
data[name] = []
data[name] += files
+def _clfags_includes(cflags, includes):
+ if type(cflags) is not list:
+ if cflags is not None:
+ _cflags = cflags.split(' ')
+ else:
+ _cflags = [None]
+ else:
+ _cflags = cflags
+ if type(includes) is not list:
+ _includes = [includes]
+ else:
+ _includes = includes
+ return _cflags, _includes
+
class SourceFileFragmentComposer(builder.BuildSystemFragmentComposer):
- def __init__(self, cflags = "default"):
- self.cflags = cflags
+ def __init__(self, cflags = "default", includes = None):
+ self.cflags, self.includes = _clfags_includes(cflags, includes)
def compose(self, path):
- return ['sources', self.cflags], [path]
+ if None in self.includes:
+ return ['sources', self.cflags], [path], self.cflags, self.includes
+ return ['sources', self.cflags + self.includes], [path], self.cflags, self.includes
class TestFragementComposer(builder.BuildSystemFragmentComposer):
@@ -72,7 +88,7 @@ class TestFragementComposer(builder.BuildSystemFragmentComposer):
class KVMSymbolsFragmentComposer(builder.BuildSystemFragmentComposer):
def compose(self, path):
- return ['KVMSymbols', 'files'], [path]
+ return ['KVMSymbols', 'files'], [path], self.includes
class RPCGENFragmentComposer(builder.BuildSystemFragmentComposer):
@@ -86,25 +102,37 @@ class RouteKeywordsFragmentComposer(builder.BuildSystemFragmentComposer):
class LexFragmentComposer(builder.BuildSystemFragmentComposer):
- def __init__(self, sym, dep):
+ def __init__(self, sym, dep, cflags = None, includes = None):
self.sym = sym
self.dep = dep
+ self.cflags, self.includes = _clfags_includes(cflags, includes)
def compose(self, path):
- return ['lex', path], { 'file': path,
- 'sym': self.sym,
- 'dep': self.dep }
+ d = { 'file': path,
+ 'sym': self.sym,
+ 'dep': self.dep }
+ if None not in self.cflags:
+ d['cflags'] = self.cflags
+ if None not in self.includes:
+ d['includes'] = self.includes
+ return ['lex', path], d
class YaccFragmentComposer(builder.BuildSystemFragmentComposer):
- def __init__(self, sym, header):
+ def __init__(self, sym, header, cflags = None, includes = None):
self.sym = sym
self.header = header
+ self.cflags, self.includes = _clfags_includes(cflags, includes)
def compose(self, path):
- return ['yacc', path], { 'file': path,
- 'sym': self.sym,
- 'header': self.header }
+ d = { 'file': path,
+ 'sym': self.sym,
+ 'header': self.header }
+ if None not in self.cflags:
+ d['cflags'] = self.cflags
+ if None not in self.includes:
+ d['includes'] = self.includes
+ return ['yacc', path], d
# Module Manager - Collection of Modules
class ModuleManager(builder.ModuleManager):
@@ -174,17 +202,35 @@ class ModuleManager(builder.ModuleManager):
# The default handler returns an empty string. Skip it.
#
if type(frag) is not str:
+ # Start at the top of the tree
d = data
- for p in frag[0]:
- if p not in d:
- d[p] = {}
- d = d[p]
+ path = frag[0]
+ if path[0] not in d:
+ d[path[0]] = {}
+ # Select the sub-part of the tree as the compile options
+ # specialise how files are built.
+ d = d[path[0]]
+ if type(path[1]) is list:
+ p = ' '.join(path[1])
+ else:
+ p = path[1]
+ if p not in d:
+ d[p] = {}
+ d = d[p]
+ if cpu not in d:
+ d[cpu] = []
if type(frag[1]) is list:
- if cpu not in d:
- d[cpu] = []
d[cpu] += frag[1]
else:
d[cpu] = frag[1]
+ if len(frag) > 3:
+ if 'cflags' not in d[cpu]:
+ d['cflags'] = []
+ d['cflags'] += frag[2]
+ if len(frag) >= 3 and None not in frag[-1]:
+ if 'includes' not in d[cpu]:
+ d['includes'] = []
+ d['includes'] += frag[-1]
data = { }
@@ -273,7 +319,7 @@ class ModuleManager(builder.ModuleManager):
self.add(' cxxflags = %r + common_flags' % (builder.cxxflags()))
self.add('')
self.add(' # Include paths')
- self.add(' includes = []')
+ self.add(' includes = ["."]')
for i in builder.includes():
self.add(' includes += ["%s"]' % (i[2:]))
self.add(' for i in %r:' % (builder.cpu_includes()))
@@ -338,6 +384,10 @@ class ModuleManager(builder.ModuleManager):
#
if 'KVMSymbols' in data:
kvmsymbols = data['KVMSymbols']
+ if 'includes' in kvmsymbols['files']:
+ includes = kvmsymbols['files']['includes']
+ else:
+ includes = []
self.add(' # KVM Symbols')
self.add(' bld(target = "%s",' % (kvmsymbols['files']['all'][0]))
self.add(' source = "rtemsbsd/rtems/generate_kvm_symbols",')
@@ -346,7 +396,7 @@ class ModuleManager(builder.ModuleManager):
self.add(' bld.objects(target = "kvmsymbols",')
self.add(' features = "c",')
self.add(' cflags = cflags,')
- self.add(' includes = includes + ["rtemsbsd/rtems"],')
+ self.add(' includes = %r + includes,' % (includes))
self.add(' source = "%s")' % (kvmsymbols['files']['all'][0]))
self.add(' libbsd_use += ["kvmsymbols"]')
self.add('')
@@ -382,6 +432,14 @@ class ModuleManager(builder.ModuleManager):
self.add(' # Lex')
for l in lexes:
lex = lexes[l]['all']
+ if 'cflags' in lex:
+ lex_defines = [d[2:] for d in lex['cflags']]
+ else:
+ lex_defines = []
+ if 'includes' in lex:
+ lex_includes = lex['includes']
+ else:
+ lex_includes = []
self.add(' if bld.env.AUTO_REGEN:')
self.add(' bld(target = "%s.c",' % (lex['file'][:-2]))
self.add(' source = "%s",' % (lex['file']))
@@ -390,7 +448,8 @@ class ModuleManager(builder.ModuleManager):
self.add(' bld.objects(target = "lex_%s",' % (lex['sym']))
self.add(' features = "c",')
self.add(' cflags = cflags,')
- self.add(' includes = includes,')
+ self.add(' includes = %r + includes,' % (lex_includes))
+ self.add(' defines = %r,' % (lex_defines))
self.add(' source = "%s.c")' % (lex['file'][:-2]))
self.add(' libbsd_use += ["lex_%s"]' % (lex['sym']))
self.add('')
@@ -401,8 +460,19 @@ class ModuleManager(builder.ModuleManager):
for y in yaccs:
yacc = yaccs[y]['all']
yacc_file = yacc['file']
- yacc_sym = yacc['sym']
+ if yacc['sym'] is not None:
+ yacc_sym = yacc['sym']
+ else:
+ yacc_sym = os.path.basename(yacc_file)[:-2]
yacc_header = '%s/%s' % (os.path.dirname(yacc_file), yacc['header'])
+ if 'cflags' in yacc:
+ yacc_defines = [d[2:] for d in yacc['cflags']]
+ else:
+ yacc_defines = []
+ if 'includes' in yacc:
+ yacc_includes = yacc['includes']
+ else:
+ yacc_includes = []
self.add(' if bld.env.AUTO_REGEN:')
self.add(' bld(target = "%s.c",' % (yacc_file[:-2]))
self.add(' source = "%s",' % (yacc_file))
@@ -412,7 +482,8 @@ class ModuleManager(builder.ModuleManager):
self.add(' bld.objects(target = "yacc_%s",' % (yacc_sym))
self.add(' features = "c",')
self.add(' cflags = cflags,')
- self.add(' includes = includes,')
+ self.add(' includes = %r + includes,' % (yacc_includes))
+ self.add(' defines = %r,' % (yacc_defines))
self.add(' source = "%s.c")' % (yacc_file[:-2]))
self.add(' libbsd_use += ["yacc_%s"]' % (yacc_sym))
self.add('')
@@ -423,22 +494,29 @@ class ModuleManager(builder.ModuleManager):
#
objs = 0
self.add(' # Objects built with different CFLAGS')
- for cflags in sorted(data['sources']):
- if cflags is not 'default':
+ for flags in sorted(data['sources']):
+ if flags is not 'default':
objs += 1
- _source_list(' objs%02d_source' % objs, sorted(data['sources'][cflags]['all']))
- archs = sorted(data['sources'][cflags])
+ _source_list(' objs%02d_source' % objs, sorted(data['sources'][flags]['all']))
+ archs = sorted(data['sources'][flags])
for arch in archs:
- if arch is not 'all':
+ if arch not in ['all', 'cflags', 'includes']:
self.add(' if bld.get_env()["RTEMS_ARCH"] == "%s":' % arch)
_source_list(' objs%02d_source' % objs,
- sorted(data['sources'][cflags][arch]),
+ sorted(data['sources'][flags][arch]),
append = True)
- defines = [d[2:] for d in cflags.split(' ')]
+ if 'cflags' in data['sources'][flags]:
+ defines = [d[2:] for d in data['sources'][flags]['cflags']]
+ else:
+ defines = []
+ if 'includes' in data['sources'][flags]:
+ includes = data['sources'][flags]['includes']
+ else:
+ includes = []
self.add(' bld.objects(target = "objs%02d",' % (objs))
self.add(' features = "c",')
self.add(' cflags = cflags,')
- self.add(' includes = includes,')
+ self.add(' includes = %r + includes,' % (includes))
self.add(' defines = %r,' % (defines))
self.add(' source = objs%02d_source)' % objs)
self.add(' libbsd_use += ["objs%02d"]' % (objs))
diff --git a/wscript b/wscript
index d02d3684..8e412243 100644
--- a/wscript
+++ b/wscript
@@ -70,7 +70,7 @@ def build(bld):
cxxflags = ['-std=gnu++11'] + common_flags
# Include paths
- includes = []
+ includes = ["."]
includes += ["rtemsbsd/include"]
includes += ["freebsd/sys"]
includes += ["freebsd/sys/contrib/altq"]
@@ -83,6 +83,7 @@ def build(bld):
includes += ["freebsd/lib/libkvm"]
includes += ["freebsd/lib/libmemstat"]
includes += ["freebsd/lib/libipsec"]
+ includes += ["freebsd/contrib/libpcap"]
includes += ["rtemsbsd/sys"]
includes += ["mDNSResponder/mDNSCore"]
includes += ["mDNSResponder/mDNSShared"]
@@ -142,7 +143,7 @@ def build(bld):
bld.objects(target = "kvmsymbols",
features = "c",
cflags = cflags,
- includes = includes + ["rtemsbsd/rtems"],
+ includes = ['rtemsbsd/rtems'] + includes,
source = "rtemsbsd/rtems/rtems-kvm-symbols.c")
libbsd_use += ["kvmsymbols"]
@@ -168,7 +169,8 @@ def build(bld):
bld.objects(target = "lex__nsyy",
features = "c",
cflags = cflags,
- includes = includes,
+ includes = [] + includes,
+ defines = [],
source = "freebsd/lib/libc/net/nslexer.c")
libbsd_use += ["lex__nsyy"]
@@ -179,10 +181,23 @@ def build(bld):
bld.objects(target = "lex___libipsecyy",
features = "c",
cflags = cflags,
- includes = includes,
+ includes = [] + includes,
+ defines = [],
source = "freebsd/lib/libipsec/policy_token.c")
libbsd_use += ["lex___libipsecyy"]
+ if bld.env.AUTO_REGEN:
+ bld(target = "freebsd/contrib/libpcap/scanner.c",
+ source = "freebsd/contrib/libpcap/scanner.l",
+ rule = "${LEX} -P pcap -t ${SRC} | sed -e '/YY_BUF_SIZE/s/16384/1024/' > ${TGT}")
+ bld.objects(target = "lex_pcap",
+ features = "c",
+ cflags = cflags,
+ includes = [] + includes,
+ defines = ['INET6', '_U_=__attribute__((unused))', 'HAVE_INTTYPES=1', 'HAVE_STDINT=1', 'HAVE_STRERROR=1', 'HAVE_STRLCPY=1', 'HAVE_SNPRINTF=1', 'HAVE_VSNPRINTF=1', 'NEED_YYPARSE_WRAPPER=1', 'yylval=pcap_lval'],
+ source = "freebsd/contrib/libpcap/scanner.c")
+ libbsd_use += ["lex_pcap"]
+
# Yacc
if bld.env.AUTO_REGEN:
bld(target = "freebsd/lib/libipsec/policy_parse.c",
@@ -191,7 +206,8 @@ def build(bld):
bld.objects(target = "yacc___libipsecyy",
features = "c",
cflags = cflags,
- includes = includes,
+ includes = [] + includes,
+ defines = [],
source = "freebsd/lib/libipsec/policy_parse.c")
libbsd_use += ["yacc___libipsecyy"]
if bld.env.AUTO_REGEN:
@@ -201,9 +217,21 @@ def build(bld):
bld.objects(target = "yacc__nsyy",
features = "c",
cflags = cflags,
- includes = includes,
+ includes = [] + includes,
+ defines = [],
source = "freebsd/lib/libc/net/nsparser.c")
libbsd_use += ["yacc__nsyy"]
+ if bld.env.AUTO_REGEN:
+ bld(target = "freebsd/contrib/libpcap/grammar.c",
+ source = "freebsd/contrib/libpcap/grammar.y",
+ rule = "${YACC} -b pcap -d -p pcap ${SRC} && sed -e '/YY_BUF_SIZE/s/16384/1024/' < pcap.tab.c > ${TGT} && rm -f pcap.tab.c && mv pcap.tab.h freebsd/contrib/libpcap/tokdefs.h")
+ bld.objects(target = "yacc_pcap",
+ features = "c",
+ cflags = cflags,
+ includes = [] + includes,
+ defines = ['INET6', '_U_=__attribute__((unused))', 'HAVE_INTTYPES=1', 'HAVE_STDINT=1', 'HAVE_STRERROR=1', 'HAVE_STRLCPY=1', 'HAVE_SNPRINTF=1', 'HAVE_VSNPRINTF=1', 'NEED_YYPARSE_WRAPPER=1', 'yylval=pcap_lval'],
+ source = "freebsd/contrib/libpcap/grammar.c")
+ libbsd_use += ["yacc_pcap"]
# Objects built with different CFLAGS
objs01_source = ['freebsd/bin/hostname/hostname.c',
@@ -347,21 +375,193 @@ def build(bld):
bld.objects(target = "objs01",
features = "c",
cflags = cflags,
- includes = includes,
+ includes = [] + includes,
defines = ['INET6'],
source = objs01_source)
libbsd_use += ["objs01"]
- objs02_source = ['rtemsbsd/mghttpd/mongoose.c']
+ objs02_source = ['freebsd/contrib/tcpdump/addrtoname.c',
+ 'freebsd/contrib/tcpdump/af.c',
+ 'freebsd/contrib/tcpdump/bpf_dump.c',
+ 'freebsd/contrib/tcpdump/checksum.c',
+ 'freebsd/contrib/tcpdump/cpack.c',
+ 'freebsd/contrib/tcpdump/gmpls.c',
+ 'freebsd/contrib/tcpdump/gmt2local.c',
+ 'freebsd/contrib/tcpdump/in_cksum.c',
+ 'freebsd/contrib/tcpdump/ipproto.c',
+ 'freebsd/contrib/tcpdump/l2vpn.c',
+ 'freebsd/contrib/tcpdump/machdep.c',
+ 'freebsd/contrib/tcpdump/nlpid.c',
+ 'freebsd/contrib/tcpdump/oui.c',
+ 'freebsd/contrib/tcpdump/parsenfsfh.c',
+ 'freebsd/contrib/tcpdump/print-802_11.c',
+ 'freebsd/contrib/tcpdump/print-802_15_4.c',
+ 'freebsd/contrib/tcpdump/print-ah.c',
+ 'freebsd/contrib/tcpdump/print-aodv.c',
+ 'freebsd/contrib/tcpdump/print-ap1394.c',
+ 'freebsd/contrib/tcpdump/print-arcnet.c',
+ 'freebsd/contrib/tcpdump/print-arp.c',
+ 'freebsd/contrib/tcpdump/print-ascii.c',
+ 'freebsd/contrib/tcpdump/print-atalk.c',
+ 'freebsd/contrib/tcpdump/print-atm.c',
+ 'freebsd/contrib/tcpdump/print-babel.c',
+ 'freebsd/contrib/tcpdump/print-beep.c',
+ 'freebsd/contrib/tcpdump/print-bfd.c',
+ 'freebsd/contrib/tcpdump/print-bgp.c',
+ 'freebsd/contrib/tcpdump/print-bootp.c',
+ 'freebsd/contrib/tcpdump/print-bt.c',
+ 'freebsd/contrib/tcpdump/print-carp.c',
+ 'freebsd/contrib/tcpdump/print-cdp.c',
+ 'freebsd/contrib/tcpdump/print-cfm.c',
+ 'freebsd/contrib/tcpdump/print-chdlc.c',
+ 'freebsd/contrib/tcpdump/print-cip.c',
+ 'freebsd/contrib/tcpdump/print-cnfp.c',
+ 'freebsd/contrib/tcpdump/print-dccp.c',
+ 'freebsd/contrib/tcpdump/print-decnet.c',
+ 'freebsd/contrib/tcpdump/print-dhcp6.c',
+ 'freebsd/contrib/tcpdump/print-domain.c',
+ 'freebsd/contrib/tcpdump/print-dtp.c',
+ 'freebsd/contrib/tcpdump/print-dvmrp.c',
+ 'freebsd/contrib/tcpdump/print-eap.c',
+ 'freebsd/contrib/tcpdump/print-egp.c',
+ 'freebsd/contrib/tcpdump/print-eigrp.c',
+ 'freebsd/contrib/tcpdump/print-enc.c',
+ 'freebsd/contrib/tcpdump/print-esp.c',
+ 'freebsd/contrib/tcpdump/print-ether.c',
+ 'freebsd/contrib/tcpdump/print-fddi.c',
+ 'freebsd/contrib/tcpdump/print-forces.c',
+ 'freebsd/contrib/tcpdump/print-fr.c',
+ 'freebsd/contrib/tcpdump/print-frag6.c',
+ 'freebsd/contrib/tcpdump/print-gre.c',
+ 'freebsd/contrib/tcpdump/print-hsrp.c',
+ 'freebsd/contrib/tcpdump/print-icmp.c',
+ 'freebsd/contrib/tcpdump/print-icmp6.c',
+ 'freebsd/contrib/tcpdump/print-igmp.c',
+ 'freebsd/contrib/tcpdump/print-igrp.c',
+ 'freebsd/contrib/tcpdump/print-ip.c',
+ 'freebsd/contrib/tcpdump/print-ip6.c',
+ 'freebsd/contrib/tcpdump/print-ip6opts.c',
+ 'freebsd/contrib/tcpdump/print-ipcomp.c',
+ 'freebsd/contrib/tcpdump/print-ipfc.c',
+ 'freebsd/contrib/tcpdump/print-ipnet.c',
+ 'freebsd/contrib/tcpdump/print-ipx.c',
+ 'freebsd/contrib/tcpdump/print-isakmp.c',
+ 'freebsd/contrib/tcpdump/print-isoclns.c',
+ 'freebsd/contrib/tcpdump/print-juniper.c',
+ 'freebsd/contrib/tcpdump/print-krb.c',
+ 'freebsd/contrib/tcpdump/print-l2tp.c',
+ 'freebsd/contrib/tcpdump/print-lane.c',
+ 'freebsd/contrib/tcpdump/print-ldp.c',
+ 'freebsd/contrib/tcpdump/print-llc.c',
+ 'freebsd/contrib/tcpdump/print-lldp.c',
+ 'freebsd/contrib/tcpdump/print-lmp.c',
+ 'freebsd/contrib/tcpdump/print-lspping.c',
+ 'freebsd/contrib/tcpdump/print-lwapp.c',
+ 'freebsd/contrib/tcpdump/print-lwres.c',
+ 'freebsd/contrib/tcpdump/print-mobile.c',
+ 'freebsd/contrib/tcpdump/print-mobility.c',
+ 'freebsd/contrib/tcpdump/print-mpcp.c',
+ 'freebsd/contrib/tcpdump/print-mpls.c',
+ 'freebsd/contrib/tcpdump/print-msdp.c',
+ 'freebsd/contrib/tcpdump/print-msnlb.c',
+ 'freebsd/contrib/tcpdump/print-netbios.c',
+ 'freebsd/contrib/tcpdump/print-nfs.c',
+ 'freebsd/contrib/tcpdump/print-ntp.c',
+ 'freebsd/contrib/tcpdump/print-null.c',
+ 'freebsd/contrib/tcpdump/print-olsr.c',
+ 'freebsd/contrib/tcpdump/print-ospf.c',
+ 'freebsd/contrib/tcpdump/print-ospf6.c',
+ 'freebsd/contrib/tcpdump/print-otv.c',
+ 'freebsd/contrib/tcpdump/print-pflog.c',
+ 'freebsd/contrib/tcpdump/print-pfsync.c',
+ 'freebsd/contrib/tcpdump/print-pgm.c',
+ 'freebsd/contrib/tcpdump/print-pim.c',
+ 'freebsd/contrib/tcpdump/print-ppi.c',
+ 'freebsd/contrib/tcpdump/print-ppp.c',
+ 'freebsd/contrib/tcpdump/print-pppoe.c',
+ 'freebsd/contrib/tcpdump/print-pptp.c',
+ 'freebsd/contrib/tcpdump/print-radius.c',
+ 'freebsd/contrib/tcpdump/print-raw.c',
+ 'freebsd/contrib/tcpdump/print-rip.c',
+ 'freebsd/contrib/tcpdump/print-ripng.c',
+ 'freebsd/contrib/tcpdump/print-rpki-rtr.c',
+ 'freebsd/contrib/tcpdump/print-rrcp.c',
+ 'freebsd/contrib/tcpdump/print-rsvp.c',
+ 'freebsd/contrib/tcpdump/print-rt6.c',
+ 'freebsd/contrib/tcpdump/print-rx.c',
+ 'freebsd/contrib/tcpdump/print-sctp.c',
+ 'freebsd/contrib/tcpdump/print-sflow.c',
+ 'freebsd/contrib/tcpdump/print-sip.c',
+ 'freebsd/contrib/tcpdump/print-sl.c',
+ 'freebsd/contrib/tcpdump/print-sll.c',
+ 'freebsd/contrib/tcpdump/print-slow.c',
+ 'freebsd/contrib/tcpdump/print-smb.c',
+ 'freebsd/contrib/tcpdump/print-snmp.c',
+ 'freebsd/contrib/tcpdump/print-stp.c',
+ 'freebsd/contrib/tcpdump/print-sunatm.c',
+ 'freebsd/contrib/tcpdump/print-symantec.c',
+ 'freebsd/contrib/tcpdump/print-syslog.c',
+ 'freebsd/contrib/tcpdump/print-tcp.c',
+ 'freebsd/contrib/tcpdump/print-telnet.c',
+ 'freebsd/contrib/tcpdump/print-tftp.c',
+ 'freebsd/contrib/tcpdump/print-timed.c',
+ 'freebsd/contrib/tcpdump/print-tipc.c',
+ 'freebsd/contrib/tcpdump/print-token.c',
+ 'freebsd/contrib/tcpdump/print-udld.c',
+ 'freebsd/contrib/tcpdump/print-udp.c',
+ 'freebsd/contrib/tcpdump/print-usb.c',
+ 'freebsd/contrib/tcpdump/print-vjc.c',
+ 'freebsd/contrib/tcpdump/print-vqp.c',
+ 'freebsd/contrib/tcpdump/print-vrrp.c',
+ 'freebsd/contrib/tcpdump/print-vtp.c',
+ 'freebsd/contrib/tcpdump/print-vxlan.c',
+ 'freebsd/contrib/tcpdump/print-wb.c',
+ 'freebsd/contrib/tcpdump/print-zephyr.c',
+ 'freebsd/contrib/tcpdump/print-zeromq.c',
+ 'freebsd/contrib/tcpdump/setsignal.c',
+ 'freebsd/contrib/tcpdump/signature.c',
+ 'freebsd/contrib/tcpdump/smbutil.c',
+ 'freebsd/contrib/tcpdump/tcpdump.c',
+ 'freebsd/contrib/tcpdump/util.c']
bld.objects(target = "objs02",
features = "c",
cflags = cflags,
- includes = includes,
- defines = ['NO_SSL', 'NO_POPEN', 'NO_CGI', 'USE_WEBSOCKET'],
+ includes = ['freebsd/contrib/tcpdump', 'freebsd/usr.sbin/tcpdump/tcpdump'] + includes,
+ defines = ['INET6', '_U_=__attribute__((unused))', 'HAVE_CONFIG_H=1', 'HAVE_NET_PFVAR_H=1'],
source = objs02_source)
libbsd_use += ["objs02"]
- objs03_source = ['freebsd/lib/libc/db/btree/bt_close.c',
+ objs03_source = ['freebsd/contrib/libpcap/bpf_image.c',
+ 'freebsd/contrib/libpcap/etherent.c',
+ 'freebsd/contrib/libpcap/fad-getad.c',
+ 'freebsd/contrib/libpcap/gencode.c',
+ 'freebsd/contrib/libpcap/inet.c',
+ 'freebsd/contrib/libpcap/nametoaddr.c',
+ 'freebsd/contrib/libpcap/optimize.c',
+ 'freebsd/contrib/libpcap/pcap-bpf.c',
+ 'freebsd/contrib/libpcap/pcap-common.c',
+ 'freebsd/contrib/libpcap/pcap.c',
+ 'freebsd/contrib/libpcap/savefile.c',
+ 'freebsd/contrib/libpcap/sf-pcap-ng.c',
+ 'freebsd/contrib/libpcap/sf-pcap.c']
+ bld.objects(target = "objs03",
+ features = "c",
+ cflags = cflags,
+ includes = [] + includes,
+ defines = ['INET6', '_U_=__attribute__((unused))', 'HAVE_INTTYPES=1', 'HAVE_STDINT=1', 'HAVE_STRERROR=1', 'HAVE_STRLCPY=1', 'HAVE_SNPRINTF=1', 'HAVE_VSNPRINTF=1'],
+ source = objs03_source)
+ libbsd_use += ["objs03"]
+
+ objs04_source = ['rtemsbsd/mghttpd/mongoose.c']
+ bld.objects(target = "objs04",
+ features = "c",
+ cflags = cflags,
+ includes = [] + includes,
+ defines = ['NO_SSL', 'NO_POPEN', 'NO_CGI', 'USE_WEBSOCKET'],
+ source = objs04_source)
+ libbsd_use += ["objs04"]
+
+ objs05_source = ['freebsd/lib/libc/db/btree/bt_close.c',
'freebsd/lib/libc/db/btree/bt_conv.c',
'freebsd/lib/libc/db/btree/bt_debug.c',
'freebsd/lib/libc/db/btree/bt_delete.c',
@@ -385,15 +585,15 @@ def build(bld):
'freebsd/lib/libc/db/recno/rec_search.c',
'freebsd/lib/libc/db/recno/rec_seq.c',
'freebsd/lib/libc/db/recno/rec_utils.c']
- bld.objects(target = "objs03",
+ bld.objects(target = "objs05",
features = "c",
cflags = cflags,
- includes = includes,
+ includes = [] + includes,
defines = ['__DBINTERFACE_PRIVATE', 'INET6'],
- source = objs03_source)
- libbsd_use += ["objs03"]
+ source = objs05_source)
+ libbsd_use += ["objs05"]
- objs04_source = ['dhcpcd/arp.c',
+ objs06_source = ['dhcpcd/arp.c',
'dhcpcd/auth.c',
'dhcpcd/bpf.c',
'dhcpcd/common.c',
@@ -415,13 +615,13 @@ def build(bld):
'dhcpcd/ipv6nd.c',
'dhcpcd/net.c',
'dhcpcd/platform-bsd.c']
- bld.objects(target = "objs04",
+ bld.objects(target = "objs06",
features = "c",
cflags = cflags,
- includes = includes,
+ includes = [] + includes,
defines = ['__FreeBSD__', 'THERE_IS_NO_FORK', 'MASTER_ONLY', 'INET', 'INET6'],
- source = objs04_source)
- libbsd_use += ["objs04"]
+ source = objs06_source)
+ libbsd_use += ["objs06"]
source = ['freebsd/sys/arm/xilinx/zy7_slcr.c',
'freebsd/sys/cam/cam.c',
@@ -861,6 +1061,8 @@ def build(bld):
source += ['freebsd/sys/bfin/bfin/in_cksum.c',
'freebsd/sys/bfin/bfin/legacy.c',
'freebsd/sys/bfin/pci/pci_bus.c']
+ if bld.get_env()["RTEMS_ARCH"] == "cflags":
+ source += ['default']
if bld.get_env()["RTEMS_ARCH"] == "h8300":
source += ['freebsd/sys/h8300/h8300/in_cksum.c',
'freebsd/sys/h8300/h8300/legacy.c',