plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

llc.c (2491B)


      1 /*
      2  * LLC.  Only enough to dispatch to SNAP and IP.
      3  */
      4 
      5 #include <u.h>
      6 #include <libc.h>
      7 #include <ip.h>
      8 #include "dat.h"
      9 #include "protos.h"
     10 
     11 enum
     12 {
     13 	UFmt = 3,
     14 	Gsap = 1,
     15 	IG = 1,
     16 	SFmt = 1,
     17 	UPoll = 0x10,
     18 	IsPoll = 0x100,
     19 	XidFi = 0x81,
     20 
     21 	SapNull = 0,
     22 	SapGlobal = 0xff,
     23 	Sap8021BI = 0x02,
     24 	Sap8021BG = 0x03,
     25 	SapSNA = 0x04,
     26 	SapIP = 0x06,
     27 	SapProwayNM = 0x0e,
     28 	Sap8021D = 0x42,
     29 	SapRS511 = 0x4e,
     30 	SapISO8208 = 0x7e,
     31 	SapProway = 0x8e,
     32 	SapSnap = 0xaa,
     33 	SapIpx = 0xe0,
     34 	SapNetbeui = 0xf0,
     35 	SapIsons = 0xfe,
     36 };
     37 
     38 static Mux p_mux[] =
     39 {
     40 // Linux gives llc -> snap not llc -> ip.
     41 // If we don't tell snoopy about llc -> ip, then the default patterns
     42 // like snoopy -h radiotap -f dns work better.
     43 //	{ "ip", SapIP },
     44 	{ "snap", SapSnap },
     45 	{ 0 }
     46 };
     47 
     48 typedef struct Hdr Hdr;
     49 struct Hdr
     50 {
     51 	uchar dsap;
     52 	uchar ssap;
     53 	uchar dsapf;
     54 	uchar ssapf;
     55 	ushort ctl;
     56 	uchar isu;
     57 	int hdrlen;
     58 };
     59 
     60 static int
     61 unpackhdr(uchar *p, uchar *ep, Hdr *h)
     62 {
     63 	if(p+3 > ep)
     64 		return -1;
     65 	h->dsapf = p[0];
     66 	h->dsap = h->dsapf & ~IG;
     67 	h->ssapf = p[1];
     68 	h->ssap = h->ssapf & ~Gsap;
     69 	h->ctl = p[2];
     70 	h->hdrlen = 3;
     71 	if((h->ctl&UFmt) == UFmt)
     72 		h->isu = 1;
     73 	else{
     74 		if(p+4 > ep)
     75 			return -1;
     76 		h->hdrlen = 4;
     77 		h->ctl = LittleS(p+2);
     78 	}
     79 	return 0;
     80 }
     81 
     82 enum
     83 {
     84 	Ossap,
     85 	Odsap,
     86 	Ot,
     87 };
     88 
     89 static Field p_fields[] =
     90 {
     91 	{ "ssap",	Fnum,	Ossap,	"ssap" },
     92 	{ "dsap",	Fnum,	Odsap,	"dsap" },
     93 	{ 0 }
     94 };
     95 
     96 static void
     97 p_compile(Filter *f)
     98 {
     99 	Mux *m;
    100 
    101 	if(f->op == '='){
    102 		compile_cmp(llc.name, f, p_fields);
    103 		return;
    104 	}
    105 	for(m = p_mux; m->name != nil; m++){
    106 		if(strcmp(f->s, m->name) == 0){
    107 			f->pr = m->pr;
    108 			f->ulv = m->val;
    109 			f->subop = Ot;
    110 			return;
    111 		}
    112 	}
    113 	sysfatal("unknown llc field or protocol: %s", f->s);
    114 }
    115 
    116 static int
    117 p_filter(Filter *f, Msg *m)
    118 {
    119 	Hdr h;
    120 
    121 	memset(&h, 0, sizeof h);
    122 	if(unpackhdr(m->ps, m->pe, &h) < 0)
    123 		return 0;
    124 	m->ps += h.hdrlen;
    125 
    126 	switch(f->subop){
    127 	case Ossap:
    128 		return f->ulv == h.ssap;
    129 	case Odsap:
    130 		return f->ulv == h.dsap;
    131 	case Ot:
    132 		return f->ulv == h.ssap && f->ulv == h.dsap;
    133 	}
    134 	return 0;
    135 }
    136 
    137 static int
    138 p_seprint(Msg *m)
    139 {
    140 	Hdr h;
    141 
    142 	memset(&h, 0, sizeof h);
    143 	if(unpackhdr(m->ps, m->pe, &h) < 0)
    144 		return -1;
    145 
    146 	m->pr = &dump;
    147 	m->p = seprint(m->p, m->e, "ssap=%02x dsap=%02x ctl=%04x", h.ssap, h.dsap, h.ctl);
    148 	m->ps += h.hdrlen;
    149 	m->pr = &dump;
    150 	if(h.ssap == h.dsap){
    151 		switch(h.ssap){
    152 		case SapIP:
    153 			m->pr = &ip;
    154 			break;
    155 		case SapSnap:
    156 			m->pr = &snap;
    157 			break;
    158 		}
    159 	}
    160 	return 0;
    161 }
    162 
    163 Proto llc =
    164 {
    165 	"llc",
    166 	p_compile,
    167 	p_filter,
    168 	p_seprint,
    169 	p_mux,
    170 	nil,
    171 	nil,
    172 	defaultframer
    173 };