Browse Source

Plan 9 from Bell Labs 2005-10-02

David du Colombier 15 years ago
parent
commit
690ffa710b

+ 33 - 25
dist/replica/_plan9.db

@@ -7717,7 +7717,7 @@ sys/man/8/secstore - 664 sys sys 1105016705 1954
 sys/man/8/securenet - 664 sys sys 954305552 3160
 sys/man/8/send - 664 sys sys 1045501634 2168
 sys/man/8/smtp - 664 sys sys 1091126310 4724
-sys/man/8/snoopy - 664 sys sys 1112238597 3809
+sys/man/8/snoopy - 664 sys sys 1128179510 4054
 sys/man/8/stats - 664 sys sys 1067722908 4291
 sys/man/8/stub - 664 sys sys 1044830500 943
 sys/man/8/swap - 664 sys sys 944959679 880
@@ -11996,37 +11996,43 @@ sys/src/cmd/ip/rexexec.c - 664 sys sys 1121977160 742
 sys/src/cmd/ip/rip.c - 664 sys sys 1050760698 12424
 sys/src/cmd/ip/rlogind.c - 664 sys sys 1121977161 757
 sys/src/cmd/ip/snoopy - 20000000775 sys sys 1015090062 0
-sys/src/cmd/ip/snoopy/arp.c - 664 sys sys 1032059928 1902
-sys/src/cmd/ip/snoopy/bootp.c - 664 sys sys 1032059929 3428
-sys/src/cmd/ip/snoopy/dat.h - 664 sys sys 1045505292 1900
-sys/src/cmd/ip/snoopy/dhcp.c - 664 sys sys 1032059930 9098
-sys/src/cmd/ip/snoopy/dump.c - 664 sys sys 1032059927 1130
-sys/src/cmd/ip/snoopy/ether.c - 664 sys sys 1055699192 1979
+sys/src/cmd/ip/snoopy/arp.c - 664 sys sys 1128179536 1914
+sys/src/cmd/ip/snoopy/bootp.c - 664 sys sys 1128179536 3440
+sys/src/cmd/ip/snoopy/dat.h - 664 sys sys 1128179536 1915
+sys/src/cmd/ip/snoopy/dhcp.c - 664 sys sys 1128179537 9104
+sys/src/cmd/ip/snoopy/dump.c - 664 sys sys 1128179537 1136
+sys/src/cmd/ip/snoopy/eap.c - 664 sys sys 1128179537 3996
+sys/src/cmd/ip/snoopy/eap_identity.c - 664 sys sys 1128179537 50
+sys/src/cmd/ip/snoopy/eapol.c - 664 sys sys 1128179537 1890
+sys/src/cmd/ip/snoopy/eapol_key.c - 664 sys sys 1128179537 2025
+sys/src/cmd/ip/snoopy/ether.c - 664 sys sys 1128179537 2013
 sys/src/cmd/ip/snoopy/filter.y - 664 sys sys 1045505292 1536
 sys/src/cmd/ip/snoopy/gre.c - 664 sys sys 1015090059 1503
-sys/src/cmd/ip/snoopy/hdlc.c - 664 sys sys 1045505305 4273
-sys/src/cmd/ip/snoopy/icmp.c - 664 sys sys 1032059932 2960
-sys/src/cmd/ip/snoopy/icmp6.c - 664 sys sys 1045505383 7727
-sys/src/cmd/ip/snoopy/il.c - 664 sys sys 1055699197 2246
-sys/src/cmd/ip/snoopy/ip.c - 664 sys sys 1055699194 4291
-sys/src/cmd/ip/snoopy/ip6.c - 664 sys sys 1067722979 5362
-sys/src/cmd/ip/snoopy/main.c - 664 sys sys 1063306798 14371
-sys/src/cmd/ip/snoopy/mkfile - 664 sys sys 1089299190 788
-sys/src/cmd/ip/snoopy/ninep.c - 664 sys sys 1077484166 695
-sys/src/cmd/ip/snoopy/ospf.c - 664 sys sys 1032059934 7516
-sys/src/cmd/ip/snoopy/ppp.c - 664 sys sys 1045505315 10502
+sys/src/cmd/ip/snoopy/hdlc.c - 664 sys sys 1128179537 4285
+sys/src/cmd/ip/snoopy/icmp.c - 664 sys sys 1128179538 2969
+sys/src/cmd/ip/snoopy/icmp6.c - 664 sys sys 1128179538 7736
+sys/src/cmd/ip/snoopy/il.c - 664 sys sys 1128179538 2255
+sys/src/cmd/ip/snoopy/ip.c - 664 sys sys 1128179538 4300
+sys/src/cmd/ip/snoopy/ip6.c - 664 sys sys 1128179538 5371
+sys/src/cmd/ip/snoopy/main.c - 664 sys sys 1128179536 15408
+sys/src/cmd/ip/snoopy/mkfile - 664 sys sys 1128179536 849
+sys/src/cmd/ip/snoopy/ninep.c - 664 sys sys 1128179538 701
+sys/src/cmd/ip/snoopy/ospf.c - 664 sys sys 1128179539 7522
+sys/src/cmd/ip/snoopy/ppp.c - 664 sys sys 1128179539 10544
 sys/src/cmd/ip/snoopy/ppp_ccp.c - 664 sys sys 1015090061 50
 sys/src/cmd/ip/snoopy/ppp_chap.c - 664 sys sys 1015090061 50
 sys/src/cmd/ip/snoopy/ppp_comp.c - 664 sys sys 1015090061 50
 sys/src/cmd/ip/snoopy/ppp_ipcp.c - 664 sys sys 1015090061 50
 sys/src/cmd/ip/snoopy/ppp_lcp.c - 664 sys sys 1015090061 50
-sys/src/cmd/ip/snoopy/pppoe_disc.c - 664 sys sys 1033797942 2495
+sys/src/cmd/ip/snoopy/pppoe_disc.c - 664 sys sys 1128179539 2513
 sys/src/cmd/ip/snoopy/pppoe_sess.c - 664 sys sys 1033797942 36
 sys/src/cmd/ip/snoopy/rarp.c - 664 sys sys 1015090062 50
-sys/src/cmd/ip/snoopy/rtcp.c - 664 sys sys 1089389638 1958
-sys/src/cmd/ip/snoopy/rtp.c - 664 sys sys 1089389638 1160
-sys/src/cmd/ip/snoopy/tcp.c - 664 sys sys 1055699196 3593
-sys/src/cmd/ip/snoopy/udp.c - 664 sys sys 1089299190 1990
+sys/src/cmd/ip/snoopy/rc4keydesc.c - 664 sys sys 1128179539 56
+sys/src/cmd/ip/snoopy/rtcp.c - 664 sys sys 1128179540 1964
+sys/src/cmd/ip/snoopy/rtp.c - 664 sys sys 1128179540 1166
+sys/src/cmd/ip/snoopy/tcp.c - 664 sys sys 1128179540 3602
+sys/src/cmd/ip/snoopy/ttls.c - 664 sys sys 1128179540 1451
+sys/src/cmd/ip/snoopy/udp.c - 664 sys sys 1128179540 1999
 sys/src/cmd/ip/telnet.c - 664 sys sys 1127523945 8573
 sys/src/cmd/ip/telnet.h - 664 sys sys 1015090250 5902
 sys/src/cmd/ip/telnetd.c - 664 sys sys 1127523098 11721
@@ -13651,11 +13657,11 @@ sys/src/cmd/wikifs/mkfile - 664 sys sys 1045503591 468
 sys/src/cmd/wikifs/parse.c - 664 sys sys 1124975709 5394
 sys/src/cmd/wikifs/parsehist.c - 664 sys sys 1124975708 1988
 sys/src/cmd/wikifs/testwrite.c - 664 sys sys 1018211093 818
-sys/src/cmd/wikifs/tohtml.c - 664 sys sys 1113252121 14301
+sys/src/cmd/wikifs/tohtml.c - 664 sys sys 1128179598 14527
 sys/src/cmd/wikifs/util.c - 664 sys sys 1018211093 1807
 sys/src/cmd/wikifs/wdir.c - 664 sys sys 1018211094 876
 sys/src/cmd/wikifs/wiki.h - 664 sys sys 1113275619 1897
-sys/src/cmd/wikifs/wiki2html.c - 664 sys sys 1018211094 815
+sys/src/cmd/wikifs/wiki2html.c - 664 sys sys 1128176575 916
 sys/src/cmd/wikifs/wiki2text.c - 664 sys sys 1018211094 779
 sys/src/cmd/winwatch.c - 664 sys sys 1113312596 4869
 sys/src/cmd/xd.c - 664 sys sys 1124993597 5770
@@ -14967,3 +14973,5 @@ usr/glenda/lib/profile - 664 glenda glenda 1105128663 890
 usr/glenda/readme.acme - 664 glenda glenda 1019860628 4753
 usr/glenda/readme.rio - 664 glenda glenda 1019860628 6370
 usr/glenda/tmp - 20000000775 glenda glenda 1018802620 0
+386/bin/wikifs - 775 sys sys 1128222506 202486
+386/bin/snoopy - 775 sys sys 1128222506 168209

+ 33 - 27
dist/replica/plan9.db

@@ -396,7 +396,7 @@
 386/bin/snap - 775 sys sys 1125346012 303711
 386/bin/snapfs - 775 sys sys 1125346013 372678
 386/bin/sniffer - 775 sys sys 1038443185 99028
-386/bin/snoopy - 775 sys sys 1125346014 157537
+386/bin/snoopy - 775 sys sys 1128222506 168209
 386/bin/sort - 775 sys sys 1125346014 82276
 386/bin/spin - 775 sys sys 1127360605 758519
 386/bin/split - 775 sys sys 1125346015 75635
@@ -503,7 +503,7 @@
 386/bin/webcookies - 775 sys sys 1125346039 161625
 386/bin/webfs - 775 sys sys 1127360616 350516
 386/bin/webfsget - 775 sys sys 1115950144 39143
-386/bin/wikifs - 775 sys sys 1125889831 202134
+386/bin/wikifs - 775 sys sys 1128222506 202486
 386/bin/winwatch - 775 sys sys 1115950145 154555
 386/bin/xd - 775 sys sys 1125346040 64044
 386/bin/xmr - 775 sys sys 1115950145 40157
@@ -7717,7 +7717,7 @@ sys/man/8/secstore - 664 sys sys 1105016705 1954
 sys/man/8/securenet - 664 sys sys 954305552 3160
 sys/man/8/send - 664 sys sys 1045501634 2168
 sys/man/8/smtp - 664 sys sys 1091126310 4724
-sys/man/8/snoopy - 664 sys sys 1112238597 3809
+sys/man/8/snoopy - 664 sys sys 1128179510 4054
 sys/man/8/stats - 664 sys sys 1067722908 4291
 sys/man/8/stub - 664 sys sys 1044830500 943
 sys/man/8/swap - 664 sys sys 944959679 880
@@ -11996,37 +11996,43 @@ sys/src/cmd/ip/rexexec.c - 664 sys sys 1121977160 742
 sys/src/cmd/ip/rip.c - 664 sys sys 1050760698 12424
 sys/src/cmd/ip/rlogind.c - 664 sys sys 1121977161 757
 sys/src/cmd/ip/snoopy - 20000000775 sys sys 1015090062 0
-sys/src/cmd/ip/snoopy/arp.c - 664 sys sys 1032059928 1902
-sys/src/cmd/ip/snoopy/bootp.c - 664 sys sys 1032059929 3428
-sys/src/cmd/ip/snoopy/dat.h - 664 sys sys 1045505292 1900
-sys/src/cmd/ip/snoopy/dhcp.c - 664 sys sys 1032059930 9098
-sys/src/cmd/ip/snoopy/dump.c - 664 sys sys 1032059927 1130
-sys/src/cmd/ip/snoopy/ether.c - 664 sys sys 1055699192 1979
+sys/src/cmd/ip/snoopy/arp.c - 664 sys sys 1128179536 1914
+sys/src/cmd/ip/snoopy/bootp.c - 664 sys sys 1128179536 3440
+sys/src/cmd/ip/snoopy/dat.h - 664 sys sys 1128179536 1915
+sys/src/cmd/ip/snoopy/dhcp.c - 664 sys sys 1128179537 9104
+sys/src/cmd/ip/snoopy/dump.c - 664 sys sys 1128179537 1136
+sys/src/cmd/ip/snoopy/eap.c - 664 sys sys 1128179537 3996
+sys/src/cmd/ip/snoopy/eap_identity.c - 664 sys sys 1128179537 50
+sys/src/cmd/ip/snoopy/eapol.c - 664 sys sys 1128179537 1890
+sys/src/cmd/ip/snoopy/eapol_key.c - 664 sys sys 1128179537 2025
+sys/src/cmd/ip/snoopy/ether.c - 664 sys sys 1128179537 2013
 sys/src/cmd/ip/snoopy/filter.y - 664 sys sys 1045505292 1536
 sys/src/cmd/ip/snoopy/gre.c - 664 sys sys 1015090059 1503
-sys/src/cmd/ip/snoopy/hdlc.c - 664 sys sys 1045505305 4273
-sys/src/cmd/ip/snoopy/icmp.c - 664 sys sys 1032059932 2960
-sys/src/cmd/ip/snoopy/icmp6.c - 664 sys sys 1045505383 7727
-sys/src/cmd/ip/snoopy/il.c - 664 sys sys 1055699197 2246
-sys/src/cmd/ip/snoopy/ip.c - 664 sys sys 1055699194 4291
-sys/src/cmd/ip/snoopy/ip6.c - 664 sys sys 1067722979 5362
-sys/src/cmd/ip/snoopy/main.c - 664 sys sys 1063306798 14371
-sys/src/cmd/ip/snoopy/mkfile - 664 sys sys 1089299190 788
-sys/src/cmd/ip/snoopy/ninep.c - 664 sys sys 1077484166 695
-sys/src/cmd/ip/snoopy/ospf.c - 664 sys sys 1032059934 7516
-sys/src/cmd/ip/snoopy/ppp.c - 664 sys sys 1045505315 10502
+sys/src/cmd/ip/snoopy/hdlc.c - 664 sys sys 1128179537 4285
+sys/src/cmd/ip/snoopy/icmp.c - 664 sys sys 1128179538 2969
+sys/src/cmd/ip/snoopy/icmp6.c - 664 sys sys 1128179538 7736
+sys/src/cmd/ip/snoopy/il.c - 664 sys sys 1128179538 2255
+sys/src/cmd/ip/snoopy/ip.c - 664 sys sys 1128179538 4300
+sys/src/cmd/ip/snoopy/ip6.c - 664 sys sys 1128179538 5371
+sys/src/cmd/ip/snoopy/main.c - 664 sys sys 1128179536 15408
+sys/src/cmd/ip/snoopy/mkfile - 664 sys sys 1128179536 849
+sys/src/cmd/ip/snoopy/ninep.c - 664 sys sys 1128179538 701
+sys/src/cmd/ip/snoopy/ospf.c - 664 sys sys 1128179539 7522
+sys/src/cmd/ip/snoopy/ppp.c - 664 sys sys 1128179539 10544
 sys/src/cmd/ip/snoopy/ppp_ccp.c - 664 sys sys 1015090061 50
 sys/src/cmd/ip/snoopy/ppp_chap.c - 664 sys sys 1015090061 50
 sys/src/cmd/ip/snoopy/ppp_comp.c - 664 sys sys 1015090061 50
 sys/src/cmd/ip/snoopy/ppp_ipcp.c - 664 sys sys 1015090061 50
 sys/src/cmd/ip/snoopy/ppp_lcp.c - 664 sys sys 1015090061 50
-sys/src/cmd/ip/snoopy/pppoe_disc.c - 664 sys sys 1033797942 2495
+sys/src/cmd/ip/snoopy/pppoe_disc.c - 664 sys sys 1128179539 2513
 sys/src/cmd/ip/snoopy/pppoe_sess.c - 664 sys sys 1033797942 36
 sys/src/cmd/ip/snoopy/rarp.c - 664 sys sys 1015090062 50
-sys/src/cmd/ip/snoopy/rtcp.c - 664 sys sys 1089389638 1958
-sys/src/cmd/ip/snoopy/rtp.c - 664 sys sys 1089389638 1160
-sys/src/cmd/ip/snoopy/tcp.c - 664 sys sys 1055699196 3593
-sys/src/cmd/ip/snoopy/udp.c - 664 sys sys 1089299190 1990
+sys/src/cmd/ip/snoopy/rc4keydesc.c - 664 sys sys 1128179539 56
+sys/src/cmd/ip/snoopy/rtcp.c - 664 sys sys 1128179540 1964
+sys/src/cmd/ip/snoopy/rtp.c - 664 sys sys 1128179540 1166
+sys/src/cmd/ip/snoopy/tcp.c - 664 sys sys 1128179540 3602
+sys/src/cmd/ip/snoopy/ttls.c - 664 sys sys 1128179540 1451
+sys/src/cmd/ip/snoopy/udp.c - 664 sys sys 1128179540 1999
 sys/src/cmd/ip/telnet.c - 664 sys sys 1127523945 8573
 sys/src/cmd/ip/telnet.h - 664 sys sys 1015090250 5902
 sys/src/cmd/ip/telnetd.c - 664 sys sys 1127523098 11721
@@ -13651,11 +13657,11 @@ sys/src/cmd/wikifs/mkfile - 664 sys sys 1045503591 468
 sys/src/cmd/wikifs/parse.c - 664 sys sys 1124975709 5394
 sys/src/cmd/wikifs/parsehist.c - 664 sys sys 1124975708 1988
 sys/src/cmd/wikifs/testwrite.c - 664 sys sys 1018211093 818
-sys/src/cmd/wikifs/tohtml.c - 664 sys sys 1113252121 14301
+sys/src/cmd/wikifs/tohtml.c - 664 sys sys 1128179598 14527
 sys/src/cmd/wikifs/util.c - 664 sys sys 1018211093 1807
 sys/src/cmd/wikifs/wdir.c - 664 sys sys 1018211094 876
 sys/src/cmd/wikifs/wiki.h - 664 sys sys 1113275619 1897
-sys/src/cmd/wikifs/wiki2html.c - 664 sys sys 1018211094 815
+sys/src/cmd/wikifs/wiki2html.c - 664 sys sys 1128176575 916
 sys/src/cmd/wikifs/wiki2text.c - 664 sys sys 1018211094 779
 sys/src/cmd/winwatch.c - 664 sys sys 1113312596 4869
 sys/src/cmd/xd.c - 664 sys sys 1124993597 5770

+ 34 - 0
dist/replica/plan9.log

@@ -21493,3 +21493,37 @@
 1128040289 0 c sys/games/lib/fortunes - 664 sys sys 1128038631 256100
 1128051093 0 c 386/bin/stats - 775 sys sys 1128049805 190269
 1128094306 0 c sys/games/lib/fortunes - 664 sys sys 1128093789 256215
+1128177007 0 c sys/src/cmd/wikifs/tohtml.c - 664 sys sys 1128176575 14522
+1128177007 1 c sys/src/cmd/wikifs/wiki2html.c - 664 sys sys 1128176575 916
+1128180608 0 c sys/man/8/snoopy - 664 sys sys 1128179510 4054
+1128180608 1 c sys/src/cmd/ip/snoopy/arp.c - 664 sys sys 1128179536 1914
+1128180608 2 c sys/src/cmd/ip/snoopy/bootp.c - 664 sys sys 1128179536 3440
+1128180608 3 c sys/src/cmd/ip/snoopy/dat.h - 664 sys sys 1128179536 1915
+1128180608 4 c sys/src/cmd/ip/snoopy/dhcp.c - 664 sys sys 1128179537 9104
+1128180608 5 c sys/src/cmd/ip/snoopy/dump.c - 664 sys sys 1128179537 1136
+1128180608 6 a sys/src/cmd/ip/snoopy/eap.c - 664 sys sys 1128179537 3996
+1128180608 7 a sys/src/cmd/ip/snoopy/eap_identity.c - 664 sys sys 1128179537 50
+1128180608 8 a sys/src/cmd/ip/snoopy/eapol.c - 664 sys sys 1128179537 1890
+1128180608 9 a sys/src/cmd/ip/snoopy/eapol_key.c - 664 sys sys 1128179537 2025
+1128180608 10 c sys/src/cmd/ip/snoopy/ether.c - 664 sys sys 1128179537 2013
+1128180608 11 c sys/src/cmd/ip/snoopy/hdlc.c - 664 sys sys 1128179537 4285
+1128180608 12 c sys/src/cmd/ip/snoopy/icmp.c - 664 sys sys 1128179538 2969
+1128180608 13 c sys/src/cmd/ip/snoopy/icmp6.c - 664 sys sys 1128179538 7736
+1128180608 14 c sys/src/cmd/ip/snoopy/il.c - 664 sys sys 1128179538 2255
+1128180608 15 c sys/src/cmd/ip/snoopy/ip.c - 664 sys sys 1128179538 4300
+1128180608 16 c sys/src/cmd/ip/snoopy/ip6.c - 664 sys sys 1128179538 5371
+1128180608 17 c sys/src/cmd/ip/snoopy/main.c - 664 sys sys 1128179536 15408
+1128180608 18 c sys/src/cmd/ip/snoopy/mkfile - 664 sys sys 1128179536 849
+1128180608 19 c sys/src/cmd/ip/snoopy/ninep.c - 664 sys sys 1128179538 701
+1128180608 20 c sys/src/cmd/ip/snoopy/ospf.c - 664 sys sys 1128179539 7522
+1128180608 21 c sys/src/cmd/ip/snoopy/ppp.c - 664 sys sys 1128179539 10544
+1128180608 22 c sys/src/cmd/ip/snoopy/pppoe_disc.c - 664 sys sys 1128179539 2513
+1128180608 23 a sys/src/cmd/ip/snoopy/rc4keydesc.c - 664 sys sys 1128179539 56
+1128180608 24 c sys/src/cmd/ip/snoopy/rtcp.c - 664 sys sys 1128179540 1964
+1128180608 25 c sys/src/cmd/ip/snoopy/rtp.c - 664 sys sys 1128179540 1166
+1128180608 26 c sys/src/cmd/ip/snoopy/tcp.c - 664 sys sys 1128179540 3602
+1128180608 27 a sys/src/cmd/ip/snoopy/ttls.c - 664 sys sys 1128179540 1451
+1128180608 28 c sys/src/cmd/ip/snoopy/udp.c - 664 sys sys 1128179540 1999
+1128180608 29 c sys/src/cmd/wikifs/tohtml.c - 664 sys sys 1128179598 14527
+1128223818 0 c 386/bin/wikifs - 775 sys sys 1128222506 202486
+1128223818 1 c 386/bin/snoopy - 775 sys sys 1128222506 168209

+ 69 - 54
sys/man/8/snoopy

@@ -4,18 +4,24 @@ snoopy \- spy on network packets
 .SH SYNOPSIS
 .B snoopy
 [
-.B -?stdCp
-] [
-.B -f
-.I filter-expression
+.B -CDdpst
 ] [
 .B -N
 .I n
 ] [
+.B -f
+.I filter-expression
+] [
 .B -h first-header
 ] [
 packet-file
 ]
+.PP
+.B snoopy
+.B -?
+[
+.I proto...
+]
 .SH DESCRIPTION
 .PP
 .I Snoopy
@@ -33,14 +39,14 @@ and each contains the dump of a single protocol header.  The last line
 contains the dump of any contained data.  For example, a
 .SM BOOTP
 packet would look like:
-.sp
+.IP
 .EX
 324389 ms
-	ether(s=0000929b1b54 d=ffffffffffff pr=0800 ln=342)
-	ip(s=135.104.9.62 d=255.255.255.255 id=5099 frag=0000...
-	udp(s=68 d=67 ck=d151 ln= 308)
-	bootp(t=Req ht=1 hl=16 hp=0 xid=217e5f27 sec=0 fl=800...
-	dhcp(t=Request clientid=0152415320704e7266238ebf01030...
+  	ether(s=0000929b1b54 d=ffffffffffff pr=0800 ln=342)
+  	ip(s=135.104.9.62 d=255.255.255.255 id=5099 frag=0000...
+  	udp(s=68 d=67 ck=d151 ln= 308)
+  	bootp(t=Req ht=1 hl=16 hp=0 xid=217e5f27 sec=0 fl=800...
+  	dhcp(t=Request clientid=0152415320704e7266238ebf01030...
 .EE
 .PP
 The binary format consists of:
@@ -54,41 +60,47 @@ the packet
 Filters are expressions specifying protocols to be traced
 and specific values for fields in the protocol headers.
 The grammar is:
-.sp
+.IP
 .EX
-expr	: protocol
-	| field '=' value
-	| protocol '(' expr ')'
-	| '(' expr ')'
-	| expr '||' expr
-	| expr '&&' expr
-	| '!' expr
+\fIexpr\fP:	  \fIprotocol\fP
+	| \fIfield\fP '=' \fIvalue\fP
+	| \fIprotocol\fP '(' \fIexpr\fP ')'
+	| '(' \fIexpr\fP ')'
+	| \fIexpr\fP '||' \fIexpr\fP
+	| \fIexpr\fP '&&' \fIexpr\fP
+	| '!' \fIexpr\fP
 .EE
 .PP
-The values for <protocol> and <field> can
+The values for
+.I protocol
+and 
+.I field
+can
 be obtained using the
 .B -?
-option.  It will list each known protocol,
+option.  With no arguments, it lists the known protocols.
+Otherwise it prints, for each protocol specified,
 which subprotocols it can multiplex to,
 and which fields can be used for filtering.
 For example, the listing for ethernet is currently:
-.sp
+.IP
 .EX
-ether's filter attr:
-	s	- source address
-	d	- destination address
-	a	- source|destination address
-	t	- type
+ether's filter attributes:
+  s  - source address
+  d  - destination address
+  a  - source|destination address
+  sd - source|destination address
+  t  - type
 ether's subprotos:
-	ip
-	arp
-	rarp
-	ip6
-	pppoe_disc
-	pppoe_sess
+  0x0800 ip		  0x8863 pppoe_disc
+  0x0806 arp		  0x8864 pppoe_sess
+  0x0806 rarp		  0x888e eapol
+  0x86dd ip6
 .EE
 .PP
-The format of <value> depends on context.  In general,
+The format of 
+.I value
+depends on context.  In general,
 ethernet addresses are entered as a string of hex
 digits; IP numbers in the canonical `.' format for v4 and `:' format
 for v6; and ports in decimal.
@@ -96,30 +108,33 @@ for v6; and ports in decimal.
 .IR Snoopy 's
 options are:
 .TP
-.B -t
-input is a binary trace file.  The default assumes
-a packet device, one packet per read.
-.TP
-.B -d
-output will be a binary trace file.  The default is
-human readable.
-.TP
-.B -s
-force one output line per packet.  The
-default is multiline.
-.TP
 .B -C
-compute correct checksums and if doesn't match
-the contained one, add a field
+compute the correct checksum for each packet;
+on mismatch, add a field
 .B !ck=\fIxxxx\fP
 where
 .I xxxx
 is the correct checksum.
 .TP
+.B -D
+output will be a binary trace file in Unix pcap format.
+.TP
+.B -d
+output will be a binary trace file.
+.TP
+.B -t
+input is a binary trace file as generated with the
+.B -d
+option.
+.TP
 .B -p
 do not enter promiscuous mode.  Only packets to
 this interface will be seen.
 .TP
+.B -s
+force one output line per packet.  The
+default is multiline.
+.TP
 .B -N
 dump
 .I n
@@ -137,15 +152,15 @@ assume the first header per packet to be
 The default is
 .IR ether .
 .SH EXAMPLES
-the following would display only
+To display only
 .SM BOOTP
 and
 .SM ARP
 packets:
-.sp
+.IP
 .EX
 % snoopy -f 'arp || bootp'
-after optimize: ether( arp || ip( udp( bootp ) ) )
+after optimize: ether(arp || ip(udp(bootp)))
 .EE
 .PP
 The first line of output shows the completed filter
@@ -157,7 +172,7 @@ comparisons.
 .PP
 To save all packets between 135.104.9.2 to 135.104.9.6 and
 later display those to/from TCP port 80:
-.sp
+.IP
 .EX
 % ramfs
 % snoopy -df 'ip(s=135.104.9.2 && d=135.104.9.6) ||\\
@@ -172,6 +187,6 @@ Ethernet device
 .SH SOURCE
 .B /sys/src/cmd/ip/snoopy
 .SH BUGS
-At the moment it only dumps ethernet packets because there's
-no device to get IP packets without the media header.  This will
-be corrected soon.
+.I Snoopy
+only dumps ethernet packets, because there's
+no device to get IP packets without a media header.

+ 2 - 0
sys/src/cmd/ip/snoopy/arp.c

@@ -112,6 +112,7 @@ Proto arp =
 	p_filter,
 	p_seprint,
 	nil,
+	nil,
 	p_fields,
 	defaultframer,
 };
@@ -123,6 +124,7 @@ Proto rarp =
 	p_filter,
 	p_seprint,
 	nil,
+	nil,
 	p_fields,
 	defaultframer,
 };

+ 1 - 0
sys/src/cmd/ip/snoopy/bootp.c

@@ -171,6 +171,7 @@ Proto bootp =
 	p_filter,
 	p_seprint,
 	p_mux,
+	"%#.8lux",
 	p_fields,
 	defaultframer,
 };

+ 1 - 0
sys/src/cmd/ip/snoopy/dat.h

@@ -18,6 +18,7 @@ struct Proto
 	int	(*filter)(Filter*, Msg*);
 	int	(*seprint)(Msg*);
 	Mux*	mux;
+	char*	valfmt;
 	Field*	field;
 	int	(*framer)(int, uchar*, int);
 };

+ 1 - 0
sys/src/cmd/ip/snoopy/dhcp.c

@@ -476,6 +476,7 @@ Proto dhcp =
 	p_seprint,
 	nil,
 	nil,
+	nil,
 	defaultframer,
 };
 

+ 1 - 0
sys/src/cmd/ip/snoopy/dump.c

@@ -85,5 +85,6 @@ Proto dump =
 	p_seprint,
 	nil,
 	nil,
+	nil,
 	defaultframer,
 };

+ 247 - 0
sys/src/cmd/ip/snoopy/eap.c

@@ -0,0 +1,247 @@
+#include <u.h>
+#include <libc.h>
+#include <ip.h>
+#include "dat.h"
+#include "protos.h"
+
+typedef struct Hdr	Hdr;
+struct Hdr
+{
+	uchar	code;
+	uchar	id;
+	uchar	len[2];	/* length including this header */
+
+	uchar	tp;	/* optional, only for Request/Response */
+};
+
+enum
+{
+	EAPHDR=	4,	/* sizeof(code)+sizeof(id)+sizeof(len) */
+	TPHDR= 1,	/* sizeof(tp) */
+
+	/* eap types */
+	Request = 1,
+	Response,
+	Success,
+	Fail,
+
+	/* eap request/response sub-types */
+	Identity = 1,		/* Identity */
+	Notify,		/* Notification */
+	Nak,			/* Nak (Response only) */
+	Md5,		/* MD5-challenge */
+	Otp,			/* one time password */
+	Gtc,			/* generic token card */
+	Ttls = 21,		/* tunneled TLS */
+	Xpnd = 254,	/* expanded types */
+	Xprm,		/* experimental use */
+};
+
+enum
+{
+	Ot,
+};
+
+static Mux p_mux[] =
+{
+	{ "eap_identity", Identity, },
+	{ "eap_notify", Notify, },
+	{ "eap_nak", Nak, },
+	{ "eap_md5", Md5, },
+	{ "eap_otp", Otp, },
+	{ "eap_gtc", Gtc, },
+	{ "ttls", Ttls, },
+	{ "eap_xpnd", Xpnd, },
+	{ "eap_xprm", Xprm, }, 
+	{ 0 }
+};
+
+static char *eapsubtype[256] =
+{
+[Identity]	"Identity",
+[Notify]	"Notify",
+[Nak]		"Nak",
+[Md5]	"Md5",
+[Otp]		"Otp",
+[Gtc]		"Gtc",
+[Ttls]		"Ttls",
+[Xpnd]	"Xpnd",
+[Xprm]	"Xprm",
+};
+
+
+static void
+p_compile(Filter *f)
+{
+	Mux *m;
+
+	for(m = p_mux; m->name != nil; m++)
+		if(strcmp(f->s, m->name) == 0){
+			f->pr = m->pr;
+			f->ulv = m->val;
+			f->subop = Ot;
+			return;
+		}
+	sysfatal("unknown eap field or type: %s", f->s);
+}
+
+static int
+p_filter(Filter *f, Msg *m)
+{
+	Hdr *h;
+	int len;
+
+	if(f->subop != Ot)
+		return 0;
+
+	if(m->pe - m->ps < EAPHDR)
+		return -1;
+
+	h = (Hdr*)m->ps;
+
+	/* truncate the message if there's extra */
+	/* len includes header */
+	len = NetS(h->len);
+	if(m->ps+len < m->pe)
+		m->pe = m->ps+len;
+	else if(m->ps+len > m->pe)
+		return -1;
+	m->ps += EAPHDR;
+
+	if(h->code != Request && h->code != Response)
+		return 0;
+	m->ps += TPHDR;
+
+	if(h->tp == f->ulv)
+		return 1;
+
+	return 0;
+}
+
+static char*
+op(int i)
+{
+	static char x[20];
+
+	switch(i){
+	case Request:
+		return "Request";
+	case Response:
+		return "Response";
+	case Success:
+		return "Success";
+	case Fail:
+		return "Fail";
+	default:
+		sprint(x, "%1d", i);
+		return x;
+	}
+}
+
+static char*
+subop(uchar val)
+{
+	static char x[20], *p;
+
+	p = eapsubtype[val];
+	if(p != nil)
+		return p;
+	else {
+		sprint(x, "%1d", val);
+		return x;
+	}
+}
+
+static int
+p_seprint(Msg *m)
+{
+	Hdr *h;
+	int len;
+	char *p, *e;
+
+	if(m->pe - m->ps < EAPHDR)
+		return -1;
+
+	p = m->p;
+	e = m->e;
+	h = (Hdr*)m->ps;
+
+	/* resize packet (should already be done by eapol) */
+	/* len includes header */
+	len = NetS(h->len);
+	if(m->ps+len < m->pe)
+		m->pe = m->ps+len;
+	else if(m->ps+len > m->pe)
+		return -1;
+	m->ps += EAPHDR;
+
+	p = seprint(p, e, "id=%1d code=%s", h->id, op(h->code));
+	switch(h->code) {
+	case Request:
+	case Response:
+		m->ps += TPHDR;
+		p = seprint(p, e, " type=%s", subop(h->tp));
+		/* special case needed to print eap_notify notification as unicode */
+		demux(p_mux, h->tp, h->tp, m, &dump);
+		break;
+	default:
+		demux(p_mux, 0, 0, m, &dump);
+		break;
+	}
+	m->p = seprint(p, e, " len=%1d", len);
+	return 0;
+}
+
+static int
+p_seprintidentity(Msg *m)
+{
+	char *ps, *pe, *z;
+	int len;
+
+	m->pr = nil;
+	ps = (char*)m->ps;
+	pe = (char*)m->pe;
+
+	/* we would like to do this depending on the 'context':
+	 *  - one for eap_identity request and
+	 *  - one for eap_identity response
+	 * but we've lost the context, or haven't we?
+	 * so we treat them the same, so we might erroneously
+	 * print a response as if it was a request. too bad. - axel
+	 */
+	for (z=ps; *z != '\0' && z+1 < pe; z++)
+		;
+	if (*z == '\0' && z+1 < pe) {
+		m->p = seprint(m->p, m->e, "prompt=(%s)", ps);
+		len = pe - (z+1);
+		m->p = seprint(m->p, m->e, " options=(%.*s)", len, z+1);
+	} else {
+		len = pe - ps;
+		m->p = seprint(m->p, m->e, "%.*s", len, ps);
+	}
+	return 0;
+}
+
+Proto eap =
+{
+	"eap",
+	p_compile,
+	p_filter,
+	p_seprint,
+	p_mux,
+	"%lud",
+	nil,
+	defaultframer,
+};
+
+Proto eap_identity =
+{
+	"eap_identity",
+	p_compile,
+	p_filter,
+	p_seprintidentity,
+	nil,
+	nil,
+	nil,
+	defaultframer,
+};

+ 1 - 0
sys/src/cmd/ip/snoopy/eap_identity.c

@@ -0,0 +1 @@
+/* place holder, this stuff is really in eap.c */

+ 138 - 0
sys/src/cmd/ip/snoopy/eapol.c

@@ -0,0 +1,138 @@
+#include <u.h>
+#include <libc.h>
+#include <ip.h>
+#include "dat.h"
+#include "protos.h"
+
+typedef struct Hdr	Hdr;
+struct Hdr
+{
+	uchar	vi;		/* version */
+	uchar	type;
+	uchar	len[2];	/* length of data following this header */
+};
+
+enum
+{
+	EAPOLHDR=	4,		/* sizeof(Hdr) */
+
+	/* eapol types */
+	Eap = 0,
+	Start,
+	Logoff,
+	Key,
+	AsfAlert,
+};
+
+enum
+{
+	Ot,	/* type */
+};
+
+static Mux p_mux[] =
+{
+	{ "eap", Eap, },
+	{ "eapol_start", Start, },
+	{ "eapol_logoff", Logoff, },
+	{ "eapol_key", Key, },
+	{ "asf_alert", AsfAlert, },
+	{ 0 }
+};
+
+static void
+p_compile(Filter *f)
+{
+	Mux *m;
+
+	for(m = p_mux; m->name != nil; m++)
+		if(strcmp(f->s, m->name) == 0){
+			f->pr = m->pr;
+			f->ulv = m->val;
+			f->subop = Ot;
+			return;
+		}
+	sysfatal("unknown eapol field or type: %s", f->s);
+}
+
+static int
+p_filter(Filter *f, Msg *m)
+{
+	Hdr *h;
+
+	if(m->pe - m->ps < EAPOLHDR)
+		return 0;
+
+	h = (Hdr*)m->ps;
+
+	/* len does not include header */
+	m->ps += EAPOLHDR;
+
+	switch(f->subop){
+	case Ot:
+		return h->type == f->ulv;
+	}
+	return 0;
+}
+
+static char*
+op(int i)
+{
+	static char x[20];
+
+	switch(i){
+	case Eap:
+		return "Eap";
+	case Start:
+		return "Start";
+	case Logoff:
+		return "Logoff";
+	case Key:
+		return "Key";
+	case AsfAlert:
+		return "AsfAlert";
+	default:
+		sprint(x, "%1d", i);
+		return x;
+	}
+}
+
+static int
+p_seprint(Msg *m)
+{
+	Hdr *h;
+	int len;
+
+	if(m->pe - m->ps < EAPOLHDR)
+		return -1;
+
+	h = (Hdr*)m->ps;
+
+	/* len does not include header */
+	m->ps += EAPOLHDR;
+
+	/* truncate the message if there's extra */
+	len = NetS(h->len);
+	if(m->ps + len < m->pe)
+		m->pe = m->ps + len;
+	else if(m->ps+len > m->pe)
+		return -1;
+
+	/* next protocol  depending on type*/
+	demux(p_mux, h->type, h->type, m, &dump);
+
+	m->p = seprint(m->p, m->e, "type=%s version=%1d datalen=%1d",
+			op(h->type), h->vi, len);
+	return 0;
+}
+
+Proto eapol =
+{
+	"eapol",
+	p_compile,
+	p_filter,
+	p_seprint,
+	p_mux,
+	"%lud",
+	nil,
+	defaultframer,
+};

+ 155 - 0
sys/src/cmd/ip/snoopy/eapol_key.c

@@ -0,0 +1,155 @@
+#include <u.h>
+#include <libc.h>
+#include <ip.h>
+#include "dat.h"
+#include "protos.h"
+
+typedef struct Hdr
+{
+	uchar	desc;
+} Hdr;
+
+typedef struct Rc4KeyDesc
+{
+	uchar	ln[2];
+	uchar	replay[8];
+	uchar	iv[16];
+	uchar	idx;
+	uchar	md[16];
+} Rc4KeyDesc;
+
+enum
+{
+	HDR=	1,		/* sizeof(Hdr) */
+	RC4KEYDESC=	43,	/* sizeof(Rc4KeyDesc) */
+
+	DescTpRC4= 1,
+};
+
+enum
+{
+	Odesc,
+};
+
+static Mux p_mux[] =
+{
+	{ "rc4keydesc", DescTpRC4, },
+	{ 0 }
+};
+
+static Mux p_muxrc4[] =
+{
+	{ "dump", 0, },
+	{ 0 }
+};
+
+static void
+p_compile(Filter *f)
+{
+	Mux *m;
+
+	for(m = p_mux; m->name != nil; m++)
+		if(strcmp(f->s, m->name) == 0){
+			f->pr = m->pr;
+			f->ulv = m->val;
+			f->subop = Odesc;
+			return;
+		}
+	sysfatal("unknown eap_key field or type: %s", f->s);
+}
+
+static int
+p_filter(Filter *f, Msg *m)
+{
+	Hdr *h;
+
+	if(m->pe - m->ps < HDR)
+		return 0;
+
+	h = (Hdr*)m->ps;
+	m->ps += HDR;
+
+	switch(f->subop){
+	case Odesc:
+		return h->desc == f->ulv;
+	}
+	return 0;
+}
+
+static char*
+op(int i)
+{
+	static char x[20];
+
+	switch(i){
+	case DescTpRC4:
+		return "RC4KeyDesc";
+	default:
+		sprint(x, "%1d", i);
+		return x;
+	}
+}
+
+static int
+p_seprint(Msg *m)
+{
+	Hdr *h;
+
+	if(m->pe - m->ps < HDR)
+		return -1;
+
+	h = (Hdr*)m->ps;
+	m->ps += HDR;
+
+	/* next protocol  depending on type*/
+	demux(p_mux, h->desc, h->desc, m, &dump);
+
+	m->p = seprint(m->p, m->e, "desc=%s", op(h->desc));
+	return 0;
+}
+
+static int
+p_seprintrc4(Msg *m)
+{
+	Rc4KeyDesc *h;
+	int len;
+
+	if(m->pe - m->ps < RC4KEYDESC)
+		return -1;
+
+	h = (Rc4KeyDesc*)m->ps;
+	m->ps += RC4KEYDESC;
+	m->pr = nil;
+	len = m->pe - m->ps;
+
+	m->p = seprint(m->p, m->e, "keylen=%1d replay=%1d iv=%1d idx=%1d md=%1d",
+			NetS(h->ln), NetS(h->replay), NetS(h->iv), h->idx, NetS(h->md));
+	m->p = seprint(m->p, m->e, " dataln=%d", len);
+	if (len > 0)
+		m->p = seprint(m->p, m->e, " data=%.*H", len, m->ps);
+	return 0;
+}
+
+Proto eapol_key =
+{
+	"eapol_key",
+	p_compile,
+	p_filter,
+	p_seprint,
+	p_mux,
+	"%lud",
+	nil,
+	defaultframer,
+};
+
+Proto rc4keydesc =
+{
+	"rc4keydesc",
+	p_compile,
+	nil,
+	p_seprintrc4,
+	nil,
+	nil,
+	nil,
+	defaultframer,
+};

+ 2 - 0
sys/src/cmd/ip/snoopy/ether.c

@@ -23,6 +23,7 @@ static Mux p_mux[] =
 	{"ip6", 	0x86dd, } ,
 	{"pppoe_disc",	0x8863, },
 	{"pppoe_sess",	0x8864, },
+	{"eapol",	0x888e, },
 	{0}
 };
 
@@ -116,6 +117,7 @@ Proto ether =
 	p_filter,
 	p_seprint,
 	p_mux,
+	"%#.4lux",
 	p_fields,
 	defaultframer
 };

+ 1 - 0
sys/src/cmd/ip/snoopy/hdlc.c

@@ -169,6 +169,7 @@ Proto hdlc =
 	p_filter,
 	p_seprint,
 	p_mux,
+	"%#.4lux",
 	nil,
 	p_framer,
 };

+ 1 - 0
sys/src/cmd/ip/snoopy/icmp.c

@@ -191,6 +191,7 @@ Proto icmp =
 	p_filter,
 	p_seprint,
 	p_mux,
+	"%lud",
 	p_fields,
 	defaultframer,
 };

+ 1 - 0
sys/src/cmd/ip/snoopy/icmp6.c

@@ -423,6 +423,7 @@ Proto icmp6 =
 	p_filter,
 	p_seprint,
 	p_mux,
+	"%lud",
 	p_fields,
 	defaultframer,
 };

+ 1 - 0
sys/src/cmd/ip/snoopy/il.c

@@ -142,6 +142,7 @@ Proto il =
 	p_filter,
 	p_seprint,
 	p_mux,
+	"%lud",
 	p_fields,
 	defaultframer,
 };

+ 1 - 0
sys/src/cmd/ip/snoopy/ip.c

@@ -231,6 +231,7 @@ Proto ip =
 	p_filter,
 	p_seprint,
 	p_mux,
+	"%lud",
 	p_fields,
 	defaultframer,
 };

+ 1 - 0
sys/src/cmd/ip/snoopy/ip6.c

@@ -304,6 +304,7 @@ Proto ip6 =
 	p_filter,
 	p_seprint,
 	p_mux,
+	"%lud",
 	p_fields,
 	defaultframer,
 };

+ 104 - 28
sys/src/cmd/ip/snoopy/main.c

@@ -35,14 +35,21 @@ void	mkprotograph(void);
 Proto*	findproto(char *name);
 Filter*	compile(Filter *f);
 void	printfilter(Filter *f, char *tag);
-void	printhelp(void);
+void	printhelp(char*);
 void	tracepkt(uchar*, int);
 void	pcaphdr(void);
 
+void
+printusage(void)
+{
+	fprint(2, "usage: %s [-CDdpst] [-N n] [-f filter] [-h first-header] path\n", argv0);
+	fprint(2, "  for protocol help: %s -? [proto]\n", argv0);
+}
+
 void
 usage(void)
 {
-	fprint(2, "usage: %s [-std?] [-c] [-N n] [-f filter] [-h first-header] path", argv0);
+	printusage();
 	exits("usage");
 }
 
@@ -74,20 +81,19 @@ main(int argc, char **argv)
 	mkprotograph();
 
 	ARGBEGIN{
+	default:
+		usage();
 	case '?':
-		printhelp();
+		printusage();
+		printhelp(ARGF());
 		exits(0);
 		break;
 	case 'N':
-		p = ARGF();
-		if(p == nil)
-			usage();
+		p = EARGF(usage());
 		Nflag = atoi(p);
 		break;
 	case 'f':
-		p = ARGF();
-		if(p == nil)
-			usage();
+		p = EARGF(usage());
 		yyinit(p);
 		yyparse();
 		break;
@@ -95,9 +101,7 @@ main(int argc, char **argv)
 		sflag = 1;
 		break;
 	case 'h':
-		p = ARGF();
-		if(p == nil)
-			usage();
+		p = EARGF(usage());
 		root = findproto(p);
 		if(root == nil)
 			sysfatal("unknown protocol: %s", p);
@@ -770,9 +774,9 @@ _pf(Filter *f)
 	case WORD:
 		fprint(2, "%s", f->s);
 		if(f->l != nil){
-			fprint(2, "( ");
+			fprint(2, "(");
 			_pf(f->l);
-			fprint(2, " )");
+			fprint(2, ")");
 		}
 		break;
 	case LAND:
@@ -805,24 +809,96 @@ printfilter(Filter *f, char *tag)
 }
 
 void
-printhelp(void)
+cat(void)
 {
+	char buf[1024];
+	int n;
+	
+	while((n = read(0, buf, sizeof buf)) > 0)
+		write(1, buf, n);
+}
+
+static int fd1 = -1;
+void
+startmc(void)
+{
+	int p[2];
+	
+	if(fd1 == -1)
+		fd1 = dup(1, -1);
+	
+	if(pipe(p) < 0)
+		return;
+	switch(fork()){
+	case -1:
+		return;
+	default:
+		close(p[0]);
+		dup(p[1], 1);
+		if(p[1] != 1)
+			close(p[1]);
+		return;
+	case 0:
+		close(p[1]);
+		dup(p[0], 0);
+		if(p[0] != 0)
+			close(p[0]);
+		execl("/bin/mc", "mc", nil);
+		cat();
+		_exits(0);
+	}
+}
+
+void
+stopmc(void)
+{
+	close(1);
+	dup(fd1, 1);
+	waitpid();
+}
+
+void
+printhelp(char *name)
+{
+	int len;
 	Proto *pr, **l;
 	Mux *m;
 	Field *f;
-
-	for(l = protos; *l != nil; l++){
-		pr = *l;
-		if(pr->field != nil){
-			print("%s's filter attr:\n", pr->name);
-			for(f = pr->field; f->name != nil; f++)
-				print("\t%s\t- %s\n", f->name, f->help);
-		}
-		if(pr->mux != nil){
-			print("%s's subprotos:\n", pr->name);
-			for(m = pr->mux; m->name != nil; m++)
-				print("\t%s\n", m->name);
-		}
+	char fmt[40];
+	
+	if(name == nil){
+		print("protocols:\n");
+		startmc();
+		for(l=protos; (pr=*l) != nil; l++)
+			print("  %s\n", pr->name);
+		stopmc();
+		return;
+	}
+	
+	pr = findproto(name);
+	if(pr == nil){
+		print("unknown protocol %s\n", name);
+		return;
+	}
+	
+	if(pr->field){
+		print("%s's filter attributes:\n", pr->name);
+		len = 0;
+		for(f=pr->field; f->name; f++)
+			if(len < strlen(f->name))
+				len = strlen(f->name);
+		startmc();
+		for(f=pr->field; f->name; f++)
+			print("  %-*s - %s\n", len, f->name, f->help);
+		stopmc();
+	}
+	if(pr->mux){
+		print("%s's subprotos:\n", pr->name);
+		startmc();
+		snprint(fmt, sizeof fmt, "  %s %%s\n", pr->valfmt);
+		for(m=pr->mux; m->name != nil; m++)
+			print(fmt, m->val, m->name);
+		stopmc();
 	}
 }
 

+ 19 - 13
sys/src/cmd/ip/snoopy/mkfile

@@ -2,31 +2,37 @@
 
 TARG=snoopy
 PROTOS=\
-	ether\
-	ip\
-	ip6\
-	dump\
 	arp\
-	rarp\
-	udp\
 	bootp\
 	dhcp\
+	dump\
+	eap\
+	eap_identity\
+	eapol\
+	eapol_key\
+	ether\
 	hdlc\
-	rtp\
-	rtcp\
-	tcp\
-	il\
-	icmp\
 	icmp6\
+	icmp\
+	il\
+	ip6\
+	ip\
 	ninep\
 	ospf\
 	ppp\
 	ppp_ccp\
-	ppp_lcp\
 	ppp_chap\
 	ppp_ipcp\
-	pppoe_sess\
+	ppp_lcp\
 	pppoe_disc\
+	pppoe_sess\
+	rarp\
+	rc4keydesc\
+	rtcp\
+	rtp\
+	tcp\
+	ttls\
+	udp\
 
 POBJS=${PROTOS:%=%.$O}
 

+ 1 - 0
sys/src/cmd/ip/snoopy/ninep.c

@@ -49,5 +49,6 @@ Proto ninep =
 	p_seprint,
 	nil,
 	nil,
+	nil,
 	defaultframer,
 };

+ 1 - 0
sys/src/cmd/ip/snoopy/ospf.c

@@ -397,5 +397,6 @@ Proto ospf =
 	p_seprint,
 	nil,
 	nil,
+	nil,
 	defaultframer,
 };

+ 6 - 0
sys/src/cmd/ip/snoopy/ppp.c

@@ -569,6 +569,7 @@ Proto ppp =
 	p_filter,
 	p_seprint,
 	p_mux,
+	"%#.4lux",
 	nil,
 	defaultframer,
 };
@@ -581,6 +582,7 @@ Proto ppp_ipcp =
 	p_seprintipcp,
 	nil,
 	nil,
+	nil,
 	defaultframer,
 };
 
@@ -592,6 +594,7 @@ Proto ppp_lcp =
 	p_seprintlcp,
 	nil,
 	nil,
+	nil,
 	defaultframer,
 };
 
@@ -603,6 +606,7 @@ Proto ppp_ccp =
 	p_seprintccp,
 	nil,
 	nil,
+	nil,
 	defaultframer,
 };
 
@@ -614,6 +618,7 @@ Proto ppp_chap =
 	p_seprintchap,
 	nil,
 	nil,
+	nil,
 	defaultframer,
 };
 
@@ -625,5 +630,6 @@ Proto ppp_comp =
 	p_seprintcomp,
 	nil,
 	nil,
+	nil,
 	defaultframer,
 };

+ 2 - 0
sys/src/cmd/ip/snoopy/pppoe_disc.c

@@ -155,6 +155,7 @@ Proto pppoe_disc =
 	p_filter,
 	p_seprintdisc,
 	p_mux,
+	"%lud",
 	p_fields,
 	defaultframer
 };
@@ -166,6 +167,7 @@ Proto pppoe_sess =
 	p_filter,
 	p_seprintsess,
 	p_mux,
+	"%lud",
 	p_fields,
 	defaultframer
 };

+ 1 - 0
sys/src/cmd/ip/snoopy/rc4keydesc.c

@@ -0,0 +1 @@
+/* place holder, this stuff is really in eapol_key.c */

+ 1 - 0
sys/src/cmd/ip/snoopy/rtcp.c

@@ -91,5 +91,6 @@ Proto rtcp = {
 	p_seprint,
 	nil,
 	nil,
+	nil,
 	defaultframer,
 };

+ 1 - 0
sys/src/cmd/ip/snoopy/rtp.c

@@ -70,5 +70,6 @@ Proto rtp = {
 	p_seprint,
 	nil,
 	nil,
+	nil,
 	defaultframer,
 };

+ 1 - 0
sys/src/cmd/ip/snoopy/tcp.c

@@ -216,6 +216,7 @@ Proto tcp =
 	p_filter,
 	p_seprint,
 	p_mux,
+	"%lud",
 	p_fields,
 	defaultframer,
 };

+ 96 - 0
sys/src/cmd/ip/snoopy/ttls.c

@@ -0,0 +1,96 @@
+#include <u.h>
+#include <libc.h>
+#include <ip.h>
+#include "dat.h"
+#include "protos.h"
+
+typedef struct Hdr	Hdr;
+struct Hdr
+{
+	uchar	flags;
+	uchar	ln[4];	/* optional, present if L flag set*/
+};
+
+enum
+{
+	FLHDR=	1,	/* sizeof(flags) */
+	LNHDR=	4,	/* sizeof(ln) */
+};
+
+enum
+{
+	FlagL = 1<<7, 
+	FlagM = 1<<6,
+	FlagS = 1<<5,
+	Version = (1<<2)|(1<<1)|(1<<0),
+};
+
+static Mux p_mux[] =
+{
+	{ "dump", 0, },
+	{ 0 }
+};
+
+static char*
+flags(int f)
+{
+	static char fl[20];
+	char *p;
+
+	p = fl;
+	if(f & FlagS)
+		*p++ = 'S';
+	if(f & FlagM)
+		*p++ = 'M';
+	if(f & FlagL)
+		*p++ = 'L';
+	*p = 0;
+	return fl;
+}
+
+static int
+p_seprint(Msg *m)
+{
+	Hdr *h;
+
+	if(m->pe - m->ps < FLHDR)
+		return -1;
+
+	h = (Hdr*)m->ps;
+	m->ps += FLHDR;
+
+	if (h->flags & FlagL) {
+		if(m->pe - m->ps < LNHDR)
+			return -1;
+		else
+			m->ps += LNHDR;
+	}
+
+	/* next protocol  depending on type*/
+	demux(p_mux, 0, 0, m, &dump);
+
+	m->p = seprint(m->p, m->e, "ver=%1d", h->flags & Version);
+	m->p = seprint(m->p, m->e, " fl=%s", flags(h->flags));
+
+	if (h->flags & FlagL)
+		m->p = seprint(m->p, m->e, " totallen=%1d", NetL(h->ln));
+
+	/* these are not in the header, just print them for our convenience */
+	m->p = seprint(m->p, m->e, " dataln=%1ld", m->pe - m->ps);
+	if ((h->flags & (FlagL|FlagS|FlagM)) == 0 && m->ps == m->pe)
+		m->p = seprint(m->p, m->e, " ack");
+
+	return 0;
+}
+
+Proto ttls =
+{
+	"ttls",
+	nil,
+	nil,
+	p_seprint,
+	p_mux, /* we need this to get the dump printed */
+	"%lud",
+	nil,
+	defaultframer,
+};

+ 1 - 0
sys/src/cmd/ip/snoopy/udp.c

@@ -126,6 +126,7 @@ Proto udp =
 	p_filter,
 	p_seprint,
 	p_mux,
+	"%lud",
 	p_fields,
 	defaultframer,
 };

+ 82 - 71
sys/src/cmd/wikifs/tohtml.c

@@ -177,11 +177,47 @@ mkurl(char *s, int ty)
 	return p;
 }
 
+int okayinlist[Nwtxt] =
+{
+	[Wbullet]	1,
+	[Wlink]	1,
+	[Wman]	1,
+	[Wplain]	1,
+};
+
+int okayinpre[Nwtxt] =
+{
+	[Wlink]	1,
+	[Wman]	1,
+	[Wpre]	1,
+};
+
+int okayinpara[Nwtxt] =
+{
+	[Wpara]	1,
+	[Wlink]	1,
+	[Wman]	1,
+	[Wplain]	1,
+};
+
+char*
+nospaces(char *s)
+{
+	char *q;
+	s = strdup(s);
+	if(s == nil)
+		return nil;
+	for(q=s; *q; q++)
+		if(*q == ' ')
+			*q = '_';
+	return s;
+}
+	
 String*
 pagehtml(String *s, Wpage *wtxt, int ty)
 {
-	int inlist, inpre, inpara;
 	char *p, tmp[40];
+	int inlist, inpara, inpre, t, tnext;
 	Wpage *w;
 
 	inlist = 0;
@@ -189,54 +225,54 @@ pagehtml(String *s, Wpage *wtxt, int ty)
 	inpara = 0;
 
 	for(w=wtxt; w; w=w->next){
-		switch(w->type){
+		t = w->type;
+		tnext = Whr;
+		if(w->next)
+			tnext = w->next->type;
+
+		if(inlist && !okayinlist[t]){
+			inlist = 0;
+			s = s_append(s, "\n</li>\n</ul>\n");
+		}
+		if(inpre && !okayinpre[t]){
+			inpre = 0;
+			s = s_append(s, "</pre>\n");
+		}
+
+		switch(t){
 		case Wheading:
-			/*
-			if(!inpara){
-				inpara = 1;
-				s = s_append(s, "\n<p>\n");
-			}			
-			*/
-			s = s_appendlist(s, "<br />\n<a name=\"",w->text,"\" /><h3>", w->text, "</h3>\n", nil);
+			p = nospaces(w->text);
+			s = s_appendlist(s, 
+				"\n<a name=\"", p, "\" /><h3>", 
+				w->text, "</h3>\n", nil);
+			free(p);
 			break;
 
 		case Wpara:
-			if(inlist){
-				inlist = 0;
-				s = s_append(s, "\n</ul>\n");
-			}
-			if(inpre){
-				inpre = 0;
-				s = s_append(s, "</pre>\n");
+			if(inpara){
+				s = s_append(s, "\n</p>\n");
+				inpara = 0;
 			}
-			if(!inpara){
+			if(okayinpara[tnext]){
+				s = s_append(s, "\n<p class='para'>\n");
 				inpara = 1;
-				s = s_append(s, "\n<p>\n");
 			}
 			break;
 
 		case Wbullet:
-			if(inpre){
-				inpre = 0;
-				s = s_append(s, "</pre>\n");
-			}
 			if(!inlist){
 				inlist = 1;
 				s = s_append(s, "\n<ul>\n");
-			}
-			if(inpara)
-				inpara = 0;
+			}else
+				s = s_append(s, "\n</li>\n");
 			s = s_append(s, "\n<li>\n");
 			break;
 
 		case Wlink:
-			if(inpara)
-				inpara = 0;
 			if(w->url == nil)
 				p = mkurl(w->text, ty);
 			else
 				p = w->url;
-
 			s = s_appendlist(s, "<a href=\"", p, "\">", nil);
 			s = s_escappend(s, w->text, 0);
 			s = s_append(s, "</a>");
@@ -245,9 +281,6 @@ pagehtml(String *s, Wpage *wtxt, int ty)
 			break;
 
 		case Wman:
-			if(inpara)
-				inpara = 0;
-			
 			sprint(tmp, "%d", w->section);
 			s = s_appendlist(s, 
 				"<a href=\"http://plan9.bell-labs.com/magic/man2html/",
@@ -256,12 +289,6 @@ pagehtml(String *s, Wpage *wtxt, int ty)
 			break;
 			
 		case Wpre:
-			if(inpara)
-				inpara = 0;
-			if(inlist){
-				inlist = 0;
-				s = s_append(s, "\n</ul>\n");
-			}
 			if(!inpre){
 				inpre = 1;
 				s = s_append(s, "\n<pre>\n");
@@ -275,37 +302,19 @@ pagehtml(String *s, Wpage *wtxt, int ty)
 			break;
 
 		case Wplain:
-			if(inpre){
-				inpre = 0;
-				s = s_append(s, "</pre>\n");
-			}
-			if(inpara)
-				inpara = 0;
 			s = s_escappend(s, w->text, 0);
 			break;
 		}
 	}
 	if(inlist)
-		s = s_append(s, "\n</ul>\n");
+		s = s_append(s, "\n</li>\n</ul>\n");
 	if(inpre)
 		s = s_append(s, "</pre>\n");
-	if(!inpara)
-		s = s_append(s, "\n<p>\n");
+	if(inpara)
+		s = s_append(s, "\n</p>\n");
 	return s;
 }
 
-static String*
-grey(String *s)
-{
-	return s_append(s, "<font color=#777777>");
-}
-
-static String*
-ungrey(String *s)
-{
-	return s_append(s, "</font>");
-}
-
 static String*
 copythru(String *s, char **newp, int *nlinep, int l)
 {
@@ -394,25 +403,27 @@ s_diff(String *s, Whist *h, int i, int j)
 			p[Blinelen(&b)-1] = '\0';
 			if((q = strpbrk(p, "acd")) == nil)
 				continue;
+			n1 = atoi(q+1);
+			if(q = strchr(q, ','))
+				n2 = atoi(q+1);
+			else
+				n2 = n1;
 			switch(*q){
 			case 'a':
 			case 'c':
-				n1 = atoi(q+1);
-				if(q = strchr(q, ','))
-					n2 = atoi(q+1);
-				else
-					n2 = n1;
-				s = grey(s);
+				s = s_append(s, "<span class='old_text'>");
 				s = copythru(s, &pnew, &nline, n1-1);
-				s = ungrey(s);
+				s = s_append(s, "</span><span class='new_text'>");
 				s = copythru(s, &pnew, &nline, n2);
+				s = s_append(s, "</span>");
 				break;
 			}
 		}
 		close(fdiff);
-		s = grey(s);
+		s = s_append(s, "<span class='old_text'>");
 		s = s_append(s, pnew);
-		s = ungrey(s);
+		s = s_append(s, "</span>");
+
 	}
 	s_free(new);
 	s_free(old);
@@ -429,7 +440,7 @@ diffhtml(String *s, Whist *h)
 	char *atime;
 
 	for(i=h->ndoc-1; i>=0; i--){
-		s = s_append(s, "<hr>\n");
+		s = s_append(s, "<hr /><div class='diff_head'>\n");
 		if(i==h->current)
 			sprint(tmp, "index.html");
 		else
@@ -445,8 +456,8 @@ diffhtml(String *s, Whist *h)
 			s = s_append(s, ", conflicting write");
 		s = s_append(s, "\n");
 		if(h->doc[i].comment)
-			s = s_appendlist(s, "<br><i>", h->doc[i].comment, "</i>\n", nil);
-		s = s_append(s, "<br><hr>");
+			s = s_appendlist(s, "<br /><i>", h->doc[i].comment, "</i>\n", nil);
+		s = s_append(s, "</div><hr />");
 		s = s_diff(s, h, i, i-1);
 	}
 	s = s_append(s, "<hr>");
@@ -564,7 +575,7 @@ s_appendbrk(String *s, char *p, char *prefix, int dosharp)
 			break;
 		x = e; l=LINELEN;
 		while(l--)
-			x+=chartorune(&r,x);
+			x+=chartorune(&r, x);
 		x = strchr(x, ' ');
 		if(x){
 			*x = '\0';

+ 8 - 1
sys/src/cmd/wikifs/wiki2html.c

@@ -10,7 +10,7 @@ char *wikidir;
 void
 usage(void)
 {
-	fprint(2, "usage: wiki2html [-d dir] wikifile\n");
+	fprint(2, "usage: wiki2html [-hoDP ] [-d dir] wikifile\n");
 	exits("usage");
 }
 
@@ -18,6 +18,7 @@ void
 main(int argc, char **argv)
 {
 	int t;
+	int parse;
 	String *h;
 	Whist *doc;
 
@@ -39,6 +40,8 @@ main(int argc, char **argv)
 	case 'D':
 		t = Tdiff;
 		break;
+	case 'P':
+		parse = 1;
 	}ARGEND
 
 	if(argc != 1)
@@ -52,6 +55,10 @@ main(int argc, char **argv)
 	if(doc == nil)
 		sysfatal("doc: %r");
 
+	if(parse){
+		printpage(doc->doc->wtxt);
+		exits(0);
+	}
 	if((h = tohtml(doc, doc->doc+doc->ndoc-1, t)) == nil)
 		sysfatal("wiki2html: %r");