19a747e4fSDavid du Colombier #include <u.h>
29a747e4fSDavid du Colombier #include <libc.h>
39a747e4fSDavid du Colombier #include <ip.h>
49a747e4fSDavid du Colombier #include "dat.h"
59a747e4fSDavid du Colombier #include "protos.h"
69a747e4fSDavid du Colombier
79a747e4fSDavid du Colombier typedef struct Hdr Hdr;
89a747e4fSDavid du Colombier struct Hdr
99a747e4fSDavid du Colombier { uchar type;
109a747e4fSDavid du Colombier uchar code;
119a747e4fSDavid du Colombier uchar cksum[2]; /* Checksum */
129a747e4fSDavid du Colombier uchar data[1];
139a747e4fSDavid du Colombier };
149a747e4fSDavid du Colombier
159a747e4fSDavid du Colombier enum
169a747e4fSDavid du Colombier {
179a747e4fSDavid du Colombier ICMP6LEN= 4,
189a747e4fSDavid du Colombier };
199a747e4fSDavid du Colombier
209a747e4fSDavid du Colombier enum
219a747e4fSDavid du Colombier {
229a747e4fSDavid du Colombier Ot, /* type */
23*e6dcbf51SDavid du Colombier Op, /* next protocol */
24*e6dcbf51SDavid du Colombier };
259a747e4fSDavid du Colombier
269a747e4fSDavid du Colombier static Field p_fields[] =
279a747e4fSDavid du Colombier {
289a747e4fSDavid du Colombier {"t", Fnum, Ot, "type", } ,
299a747e4fSDavid du Colombier {0}
309a747e4fSDavid du Colombier };
319a747e4fSDavid du Colombier
329a747e4fSDavid du Colombier enum
339a747e4fSDavid du Colombier {
34*e6dcbf51SDavid du Colombier /* ICMPv6 types */
359a747e4fSDavid du Colombier EchoReply = 0,
369a747e4fSDavid du Colombier UnreachableV6 = 1,
379a747e4fSDavid du Colombier PacketTooBigV6 = 2,
389a747e4fSDavid du Colombier TimeExceedV6 = 3,
399a747e4fSDavid du Colombier ParamProblemV6 = 4,
409a747e4fSDavid du Colombier Redirect = 5,
419a747e4fSDavid du Colombier EchoRequest = 8,
429a747e4fSDavid du Colombier TimeExceed = 11,
439a747e4fSDavid du Colombier InParmProblem = 12,
449a747e4fSDavid du Colombier Timestamp = 13,
459a747e4fSDavid du Colombier TimestampReply = 14,
469a747e4fSDavid du Colombier InfoRequest = 15,
479a747e4fSDavid du Colombier InfoReply = 16,
489a747e4fSDavid du Colombier AddrMaskRequest = 17,
499a747e4fSDavid du Colombier AddrMaskReply = 18,
509a747e4fSDavid du Colombier EchoRequestV6 = 128,
519a747e4fSDavid du Colombier EchoReplyV6 = 129,
529a747e4fSDavid du Colombier RouterSolicit = 133,
539a747e4fSDavid du Colombier RouterAdvert = 134,
549a747e4fSDavid du Colombier NbrSolicit = 135,
559a747e4fSDavid du Colombier NbrAdvert = 136,
569a747e4fSDavid du Colombier RedirectV6 = 137,
579a747e4fSDavid du Colombier
589a747e4fSDavid du Colombier Maxtype6 = 137,
599a747e4fSDavid du Colombier };
609a747e4fSDavid du Colombier
619a747e4fSDavid du Colombier static Mux p_mux[] =
629a747e4fSDavid du Colombier {
639a747e4fSDavid du Colombier {"ip6", UnreachableV6, },
649a747e4fSDavid du Colombier {"ip6", RedirectV6, },
659a747e4fSDavid du Colombier {"ip6", TimeExceedV6, },
669a747e4fSDavid du Colombier {0},
679a747e4fSDavid du Colombier };
689a747e4fSDavid du Colombier
693ff48bf5SDavid du Colombier char *icmpmsg6[256] =
709a747e4fSDavid du Colombier {
719a747e4fSDavid du Colombier [EchoReply] "EchoReply",
729a747e4fSDavid du Colombier [UnreachableV6] "UnreachableV6",
739a747e4fSDavid du Colombier [PacketTooBigV6] "PacketTooBigV6",
749a747e4fSDavid du Colombier [TimeExceedV6] "TimeExceedV6",
759a747e4fSDavid du Colombier [Redirect] "Redirect",
769a747e4fSDavid du Colombier [EchoRequest] "EchoRequest",
779a747e4fSDavid du Colombier [TimeExceed] "TimeExceed",
789a747e4fSDavid du Colombier [InParmProblem] "InParmProblem",
799a747e4fSDavid du Colombier [Timestamp] "Timestamp",
809a747e4fSDavid du Colombier [TimestampReply] "TimestampReply",
819a747e4fSDavid du Colombier [InfoRequest] "InfoRequest",
829a747e4fSDavid du Colombier [InfoReply] "InfoReply",
839a747e4fSDavid du Colombier [AddrMaskRequest] "AddrMaskRequest",
849a747e4fSDavid du Colombier [AddrMaskReply] "AddrMaskReply",
859a747e4fSDavid du Colombier [EchoRequestV6] "EchoRequestV6",
869a747e4fSDavid du Colombier [EchoReplyV6] "EchoReplyV6",
879a747e4fSDavid du Colombier [RouterSolicit] "RouterSolicit",
889a747e4fSDavid du Colombier [RouterAdvert] "RouterAdvert",
899a747e4fSDavid du Colombier [NbrSolicit] "NbrSolicit",
909a747e4fSDavid du Colombier [NbrAdvert] "NbrAdvert",
919a747e4fSDavid du Colombier [RedirectV6] "RedirectV6",
929a747e4fSDavid du Colombier };
939a747e4fSDavid du Colombier
949a747e4fSDavid du Colombier static char *unreachcode[] =
959a747e4fSDavid du Colombier {
969a747e4fSDavid du Colombier [0] "no route to destination",
979a747e4fSDavid du Colombier [1] "comm with destination administratively prohibited",
989a747e4fSDavid du Colombier [2] "icmp unreachable: unassigned error code (2)",
999a747e4fSDavid du Colombier [3] "address unreachable",
1009a747e4fSDavid du Colombier [4] "port unreachable",
1019a747e4fSDavid du Colombier [5] "icmp unreachable: unknown code",
1029a747e4fSDavid du Colombier };
1039a747e4fSDavid du Colombier
1049a747e4fSDavid du Colombier static char *timexcode[] =
1059a747e4fSDavid du Colombier {
1069a747e4fSDavid du Colombier [0] "hop limit exc",
1079a747e4fSDavid du Colombier [1] "reassmbl time exc",
1089a747e4fSDavid du Colombier [2] "icmp time exc: unknown code",
1099a747e4fSDavid du Colombier };
1109a747e4fSDavid du Colombier
1119a747e4fSDavid du Colombier static char *parpcode[] =
1129a747e4fSDavid du Colombier {
1139a747e4fSDavid du Colombier [0] "erroneous header field encountered",
1149a747e4fSDavid du Colombier [1] "unrecognized Next Header type encountered",
1159a747e4fSDavid du Colombier [2] "unrecognized IPv6 option encountered",
1169a747e4fSDavid du Colombier [3] "icmp par prob: unknown code",
1179a747e4fSDavid du Colombier };
1189a747e4fSDavid du Colombier enum
1199a747e4fSDavid du Colombier {
1209a747e4fSDavid du Colombier sll = 1,
1219a747e4fSDavid du Colombier tll = 2,
1229a747e4fSDavid du Colombier pref = 3,
1239a747e4fSDavid du Colombier redir = 4,
1249a747e4fSDavid du Colombier mtu = 5,
1259a747e4fSDavid du Colombier };
1269a747e4fSDavid du Colombier
1273ff48bf5SDavid du Colombier static char *icmp6opts[256] =
1289a747e4fSDavid du Colombier {
1299a747e4fSDavid du Colombier [0] "unknown opt",
1309a747e4fSDavid du Colombier [1] "sll_addr",
1319a747e4fSDavid du Colombier [2] "tll_addr",
1329a747e4fSDavid du Colombier [3] "pref_opt",
1339a747e4fSDavid du Colombier [4] "redirect",
1349a747e4fSDavid du Colombier [5] "mtu_opt",
1359a747e4fSDavid du Colombier };
1369a747e4fSDavid du Colombier
1379a747e4fSDavid du Colombier static void
p_compile(Filter * f)1389a747e4fSDavid du Colombier p_compile(Filter *f)
1399a747e4fSDavid du Colombier {
1409a747e4fSDavid du Colombier if(f->op == '='){
1419a747e4fSDavid du Colombier compile_cmp(icmp6.name, f, p_fields);
1429a747e4fSDavid du Colombier return;
1439a747e4fSDavid du Colombier }
1449a747e4fSDavid du Colombier if(strcmp(f->s, "ip6") == 0){
1459a747e4fSDavid du Colombier f->pr = p_mux->pr;
1469a747e4fSDavid du Colombier f->subop = Op;
1479a747e4fSDavid du Colombier return;
1489a747e4fSDavid du Colombier }
1499a747e4fSDavid du Colombier sysfatal("unknown icmp field or protocol: %s", f->s);
1509a747e4fSDavid du Colombier }
1519a747e4fSDavid du Colombier
1529a747e4fSDavid du Colombier static int
p_filter(Filter * f,Msg * m)1539a747e4fSDavid du Colombier p_filter(Filter *f, Msg *m)
1549a747e4fSDavid du Colombier {
1559a747e4fSDavid du Colombier Hdr *h;
1569a747e4fSDavid du Colombier
1579a747e4fSDavid du Colombier if(m->pe - m->ps < ICMP6LEN)
1589a747e4fSDavid du Colombier return 0;
1599a747e4fSDavid du Colombier
1609a747e4fSDavid du Colombier h = (Hdr*)m->ps;
1619a747e4fSDavid du Colombier m->ps += ICMP6LEN;
1629a747e4fSDavid du Colombier
1639a747e4fSDavid du Colombier switch(f->subop){
1649a747e4fSDavid du Colombier
1659a747e4fSDavid du Colombier case Ot:
1669a747e4fSDavid du Colombier if(h->type == f->ulv)
1679a747e4fSDavid du Colombier return 1;
1689a747e4fSDavid du Colombier break;
1699a747e4fSDavid du Colombier case Op:
1709a747e4fSDavid du Colombier switch(h->type){
1719a747e4fSDavid du Colombier case UnreachableV6:
1729a747e4fSDavid du Colombier case RedirectV6:
1739a747e4fSDavid du Colombier case TimeExceedV6:
1749a747e4fSDavid du Colombier m->ps += 4;
1759a747e4fSDavid du Colombier return 1;
1769a747e4fSDavid du Colombier }
1779a747e4fSDavid du Colombier }
1789a747e4fSDavid du Colombier return 0;
1799a747e4fSDavid du Colombier }
1809a747e4fSDavid du Colombier
1819a747e4fSDavid du Colombier static char*
opt_seprint(Msg * m)1829a747e4fSDavid du Colombier opt_seprint(Msg *m)
1839a747e4fSDavid du Colombier {
1849a747e4fSDavid du Colombier int otype, osz, pktsz;
1859a747e4fSDavid du Colombier uchar *a;
1869a747e4fSDavid du Colombier char *p = m->p;
1879a747e4fSDavid du Colombier char *e = m->e;
1883ff48bf5SDavid du Colombier char *opt;
1893ff48bf5SDavid du Colombier char optbuf[12];
1909a747e4fSDavid du Colombier
1919a747e4fSDavid du Colombier pktsz = m->pe - m->ps;
1929a747e4fSDavid du Colombier a = m->ps;
1939a747e4fSDavid du Colombier while (pktsz > 0) {
1949a747e4fSDavid du Colombier otype = *a;
1953ff48bf5SDavid du Colombier opt = icmp6opts[otype];
1963ff48bf5SDavid du Colombier if(opt == nil){
1973ff48bf5SDavid du Colombier sprint(optbuf, "0x%ux", otype);
1983ff48bf5SDavid du Colombier opt = optbuf;
1993ff48bf5SDavid du Colombier }
2009a747e4fSDavid du Colombier osz = (*(a+1)) * 8;
2019a747e4fSDavid du Colombier
2029a747e4fSDavid du Colombier switch (otype) {
2039a747e4fSDavid du Colombier default:
2043ff48bf5SDavid du Colombier p = seprint(p, e, "\n option=%s ", opt);
2059a747e4fSDavid du Colombier m->pr = &dump;
2069a747e4fSDavid du Colombier return p;
2079a747e4fSDavid du Colombier
2089a747e4fSDavid du Colombier case sll:
2099a747e4fSDavid du Colombier case tll:
210*e6dcbf51SDavid du Colombier if (pktsz < osz || osz != 8) {
211*e6dcbf51SDavid du Colombier p = seprint(p, e, "\n option=%s bad size=%d",
212*e6dcbf51SDavid du Colombier opt, osz);
2139a747e4fSDavid du Colombier m->pr = &dump;
2149a747e4fSDavid du Colombier return p;
2159a747e4fSDavid du Colombier }
2163ff48bf5SDavid du Colombier p = seprint(p, e, "\n option=%s maddr=%E", opt, a+2);
2179a747e4fSDavid du Colombier pktsz -= osz;
2189a747e4fSDavid du Colombier a += osz;
2199a747e4fSDavid du Colombier break;
2209a747e4fSDavid du Colombier
2219a747e4fSDavid du Colombier case pref:
2229a747e4fSDavid du Colombier if ((pktsz < osz) || (osz != 32)) {
223*e6dcbf51SDavid du Colombier p = seprint(p, e, "\n option=%s: bad size=%d",
224*e6dcbf51SDavid du Colombier opt, osz);
2259a747e4fSDavid du Colombier m->pr = &dump;
2269a747e4fSDavid du Colombier return p;
2279a747e4fSDavid du Colombier }
2289a747e4fSDavid du Colombier
229*e6dcbf51SDavid du Colombier p = seprint(p, e, "\n option=%s pref=%I "
230*e6dcbf51SDavid du Colombier "preflen=%3.3d lflag=%1.1d aflag=%1.1d "
231*e6dcbf51SDavid du Colombier "unused1=%1.1d validlt=%d preflt=%d unused2=%1.1d",
2323ff48bf5SDavid du Colombier opt,
2339a747e4fSDavid du Colombier a+16,
2349a747e4fSDavid du Colombier (int) (*(a+2)),
2359a747e4fSDavid du Colombier (*(a+3) & (1 << 7)) != 0,
2369a747e4fSDavid du Colombier (*(a+3) & (1 << 6)) != 0,
2379a747e4fSDavid du Colombier (*(a+3) & 63) != 0,
2389a747e4fSDavid du Colombier NetL(a+4),
2399a747e4fSDavid du Colombier NetL(a+8),
2409a747e4fSDavid du Colombier NetL(a+12)!=0);
2419a747e4fSDavid du Colombier
2429a747e4fSDavid du Colombier pktsz -= osz;
2439a747e4fSDavid du Colombier a += osz;
2449a747e4fSDavid du Colombier break;
2459a747e4fSDavid du Colombier
2469a747e4fSDavid du Colombier case redir:
2479a747e4fSDavid du Colombier if (pktsz < osz) {
248*e6dcbf51SDavid du Colombier p = seprint(p, e, "\n option=%s: bad size=%d",
249*e6dcbf51SDavid du Colombier opt, osz);
2509a747e4fSDavid du Colombier m->pr = &dump;
2519a747e4fSDavid du Colombier return p;
2529a747e4fSDavid du Colombier }
2539a747e4fSDavid du Colombier
2543ff48bf5SDavid du Colombier p = seprint(p, e, "\n option=%s len %d", opt, osz);
2559a747e4fSDavid du Colombier a += osz;
2569a747e4fSDavid du Colombier m->ps = a;
2579a747e4fSDavid du Colombier return p;
2589a747e4fSDavid du Colombier
2599a747e4fSDavid du Colombier case mtu:
260*e6dcbf51SDavid du Colombier if (pktsz < osz || osz != 8) {
261*e6dcbf51SDavid du Colombier p = seprint(p, e, "\n option=%s: bad size=%d",
262*e6dcbf51SDavid du Colombier opt, osz);
2639a747e4fSDavid du Colombier m->pr = &dump;
2649a747e4fSDavid du Colombier return p;
2659a747e4fSDavid du Colombier }
2669a747e4fSDavid du Colombier
267*e6dcbf51SDavid du Colombier p = seprint(p, e, "\n option=%s unused=%1.1d mtu=%d",
268*e6dcbf51SDavid du Colombier opt, NetL(a+2) != 0, NetL(a+4));
2699a747e4fSDavid du Colombier pktsz -= osz;
2709a747e4fSDavid du Colombier a += osz;
2719a747e4fSDavid du Colombier break;
2729a747e4fSDavid du Colombier }
2739a747e4fSDavid du Colombier }
2749a747e4fSDavid du Colombier
2759a747e4fSDavid du Colombier m->ps = a;
2769a747e4fSDavid du Colombier return p;
2779a747e4fSDavid du Colombier }
2789a747e4fSDavid du Colombier
2799a747e4fSDavid du Colombier static int
p_seprint(Msg * m)2809a747e4fSDavid du Colombier p_seprint(Msg *m)
2819a747e4fSDavid du Colombier {
282*e6dcbf51SDavid du Colombier int i;
283*e6dcbf51SDavid du Colombier // ushort cksum2, cksum;
2849a747e4fSDavid du Colombier char *tn;
2859a747e4fSDavid du Colombier char *p = m->p;
2869a747e4fSDavid du Colombier char *e = m->e;
2879a747e4fSDavid du Colombier uchar *a;
288*e6dcbf51SDavid du Colombier Hdr *h;
2899a747e4fSDavid du Colombier
2909a747e4fSDavid du Colombier h = (Hdr*)m->ps;
2919a747e4fSDavid du Colombier m->ps += ICMP6LEN;
2929a747e4fSDavid du Colombier m->pr = &dump;
2939a747e4fSDavid du Colombier a = m->ps;
2949a747e4fSDavid du Colombier
2959a747e4fSDavid du Colombier if(m->pe - m->ps < ICMP6LEN)
2969a747e4fSDavid du Colombier return -1;
2979a747e4fSDavid du Colombier
2989a747e4fSDavid du Colombier tn = icmpmsg6[h->type];
2999a747e4fSDavid du Colombier if(tn == nil)
3009a747e4fSDavid du Colombier p = seprint(p, e, "t=%ud c=%d ck=%4.4ux", h->type,
3019a747e4fSDavid du Colombier h->code, (ushort)NetS(h->cksum));
3029a747e4fSDavid du Colombier else
3039a747e4fSDavid du Colombier p = seprint(p, e, "t=%s c=%d ck=%4.4ux", tn,
3049a747e4fSDavid du Colombier h->code, (ushort)NetS(h->cksum));
3059a747e4fSDavid du Colombier
3069a747e4fSDavid du Colombier /*
3079a747e4fSDavid du Colombier if(Cflag){
3089a747e4fSDavid du Colombier cksum = NetS(h->cksum);
3099a747e4fSDavid du Colombier h->cksum[0] = 0;
3109a747e4fSDavid du Colombier h->cksum[1] = 0;
3119a747e4fSDavid du Colombier cksum2 = ~ptclbsum((uchar*)h, m->pe - m->ps + ICMP6LEN) & 0xffff;
3129a747e4fSDavid du Colombier if(cksum != cksum2)
3139a747e4fSDavid du Colombier p = seprint(p,e, " !ck=%4.4ux", cksum2);
3149a747e4fSDavid du Colombier }
3159a747e4fSDavid du Colombier */
3169a747e4fSDavid du Colombier
3179a747e4fSDavid du Colombier switch(h->type){
3189a747e4fSDavid du Colombier
3199a747e4fSDavid du Colombier case UnreachableV6:
3209a747e4fSDavid du Colombier m->ps += 4;
3219a747e4fSDavid du Colombier m->pr = &ip6;
3223ff48bf5SDavid du Colombier if (h->code >= nelem(unreachcode))
3233ff48bf5SDavid du Colombier i = nelem(unreachcode)-1;
3249a747e4fSDavid du Colombier else
3259a747e4fSDavid du Colombier i = h->code;
326*e6dcbf51SDavid du Colombier p = seprint(p, e, " code=%s unused=%1.1d ", unreachcode[i],
327*e6dcbf51SDavid du Colombier NetL(a) != 0);
3289a747e4fSDavid du Colombier break;
3299a747e4fSDavid du Colombier
3309a747e4fSDavid du Colombier case PacketTooBigV6:
3319a747e4fSDavid du Colombier m->ps += 4;
3329a747e4fSDavid du Colombier m->pr = &ip6;
3339a747e4fSDavid du Colombier p = seprint(p, e, " mtu=%4.4d ", NetL(a));
3349a747e4fSDavid du Colombier break;
3359a747e4fSDavid du Colombier
3369a747e4fSDavid du Colombier case TimeExceedV6:
3379a747e4fSDavid du Colombier m->ps += 4;
3389a747e4fSDavid du Colombier m->pr = &ip6;
3393ff48bf5SDavid du Colombier if (h->code >= nelem(timexcode))
3403ff48bf5SDavid du Colombier i = nelem(timexcode)-1;
3419a747e4fSDavid du Colombier else
3429a747e4fSDavid du Colombier i = h->code;
343*e6dcbf51SDavid du Colombier p = seprint(p, e, " code=%s unused=%1.1d ", timexcode[i],
344*e6dcbf51SDavid du Colombier NetL(a) != 0);
3459a747e4fSDavid du Colombier break;
3469a747e4fSDavid du Colombier
3479a747e4fSDavid du Colombier case ParamProblemV6:
3489a747e4fSDavid du Colombier m->ps += 4;
3499a747e4fSDavid du Colombier m->pr = &ip6;
3503ff48bf5SDavid du Colombier if (h->code > nelem(parpcode))
3513ff48bf5SDavid du Colombier i = nelem(parpcode)-1;
3529a747e4fSDavid du Colombier else
3539a747e4fSDavid du Colombier i = h->code;
3549a747e4fSDavid du Colombier p = seprint(p, e, " code=%s ptr=%2.2ux", parpcode[i], h->data[0]);
3559a747e4fSDavid du Colombier break;
3569a747e4fSDavid du Colombier
3579a747e4fSDavid du Colombier case EchoReplyV6:
3589a747e4fSDavid du Colombier case EchoRequestV6:
3599a747e4fSDavid du Colombier m->ps += 4;
3609a747e4fSDavid du Colombier p = seprint(p, e, " id=%ux seq=%ux",
3619a747e4fSDavid du Colombier NetS(h->data), NetS(h->data+2));
3629a747e4fSDavid du Colombier break;
3639a747e4fSDavid du Colombier
3649a747e4fSDavid du Colombier case RouterSolicit:
3659a747e4fSDavid du Colombier m->ps += 4;
3669a747e4fSDavid du Colombier m->pr = nil;
3679a747e4fSDavid du Colombier m->p = seprint(p, e, " unused=%1.1d ", NetL(a)!=0);
3689a747e4fSDavid du Colombier p = opt_seprint(m);
3699a747e4fSDavid du Colombier break;
3709a747e4fSDavid du Colombier
3719a747e4fSDavid du Colombier case RouterAdvert:
3729a747e4fSDavid du Colombier m->ps += 12;
3739a747e4fSDavid du Colombier m->pr = nil;
374*e6dcbf51SDavid du Colombier m->p = seprint(p, e, " hoplim=%3.3d mflag=%1.1d oflag=%1.1d "
375*e6dcbf51SDavid du Colombier "unused=%1.1d routerlt=%8.8d reachtime=%d rxmtimer=%d",
3769a747e4fSDavid du Colombier (int) *a,
3779a747e4fSDavid du Colombier (*(a+1) & (1 << 7)) != 0,
3789a747e4fSDavid du Colombier (*(a+1) & (1 << 6)) != 0,
3799a747e4fSDavid du Colombier (*(a+1) & 63) != 0,
3809a747e4fSDavid du Colombier NetS(a+2),
3819a747e4fSDavid du Colombier NetL(a+4),
3829a747e4fSDavid du Colombier NetL(a+8));
3839a747e4fSDavid du Colombier p = opt_seprint(m);
3849a747e4fSDavid du Colombier break;
3859a747e4fSDavid du Colombier
3869a747e4fSDavid du Colombier case NbrSolicit:
3879a747e4fSDavid du Colombier m->ps += 20;
3889a747e4fSDavid du Colombier m->pr = nil;
3899a747e4fSDavid du Colombier m->p = seprint(p, e, " unused=%1.1d targ %I", NetL(a) != 0, a+4);
3909a747e4fSDavid du Colombier p = opt_seprint(m);
3919a747e4fSDavid du Colombier break;
3929a747e4fSDavid du Colombier
3939a747e4fSDavid du Colombier case NbrAdvert:
3949a747e4fSDavid du Colombier m->ps += 20;
3959a747e4fSDavid du Colombier m->pr = nil;
3969a747e4fSDavid du Colombier m->p = seprint(p, e, " rflag=%1.1d sflag=%1.1d oflag=%1.1d targ=%I",
3979a747e4fSDavid du Colombier (*a & (1 << 7)) != 0,
3989a747e4fSDavid du Colombier (*a & (1 << 6)) != 0,
3999a747e4fSDavid du Colombier (*a & (1 << 5)) != 0,
4009a747e4fSDavid du Colombier a+4);
4019a747e4fSDavid du Colombier p = opt_seprint(m);
4029a747e4fSDavid du Colombier break;
4039a747e4fSDavid du Colombier
4049a747e4fSDavid du Colombier case RedirectV6:
4059a747e4fSDavid du Colombier m->ps += 36;
4069a747e4fSDavid du Colombier m->pr = &ip6;
407*e6dcbf51SDavid du Colombier m->p = seprint(p, e, " unused=%1.1d targ=%I dest=%I",
408*e6dcbf51SDavid du Colombier NetL(a) != 0, a+4, a+20);
4099a747e4fSDavid du Colombier p = opt_seprint(m);
4109a747e4fSDavid du Colombier break;
4119a747e4fSDavid du Colombier
4129a747e4fSDavid du Colombier case Timestamp:
4139a747e4fSDavid du Colombier case TimestampReply:
4149a747e4fSDavid du Colombier m->ps += 12;
4159a747e4fSDavid du Colombier p = seprint(p, e, " orig=%ud rcv=%ux xmt=%ux",
416*e6dcbf51SDavid du Colombier NetL(h->data), NetL(h->data+4), NetL(h->data+8));
4179a747e4fSDavid du Colombier m->pr = nil;
4189a747e4fSDavid du Colombier break;
4199a747e4fSDavid du Colombier
4209a747e4fSDavid du Colombier case InfoRequest:
4219a747e4fSDavid du Colombier case InfoReply:
4229a747e4fSDavid du Colombier break;
4239a747e4fSDavid du Colombier
4249a747e4fSDavid du Colombier }
4259a747e4fSDavid du Colombier m->p = p;
4269a747e4fSDavid du Colombier return 0;
4279a747e4fSDavid du Colombier }
4289a747e4fSDavid du Colombier
4299a747e4fSDavid du Colombier Proto icmp6 =
4309a747e4fSDavid du Colombier {
4319a747e4fSDavid du Colombier "icmp6",
4329a747e4fSDavid du Colombier p_compile,
4339a747e4fSDavid du Colombier p_filter,
4349a747e4fSDavid du Colombier p_seprint,
4359a747e4fSDavid du Colombier p_mux,
436ed397113SDavid du Colombier "%lud",
4379a747e4fSDavid du Colombier p_fields,
4383ff48bf5SDavid du Colombier defaultframer,
4399a747e4fSDavid du Colombier };
440