pppoe_disc.c (2516B)
1 #include <u.h> 2 #include <libc.h> 3 #include <ip.h> 4 #include "dat.h" 5 #include "protos.h" 6 7 typedef struct Hdr Hdr; 8 struct Hdr { 9 uchar verstype; 10 uchar code; 11 uchar sessid[2]; 12 uchar length[2]; /* of payload */ 13 }; 14 enum 15 { 16 HDRSIZE = 1+1+2+2 17 }; 18 19 static Mux p_mux[] = 20 { 21 {"ppp", 0, } , 22 {0} 23 }; 24 25 enum 26 { 27 Overs, 28 Otype, 29 Ocode, 30 Osess 31 }; 32 33 static Field p_fields[] = 34 { 35 {"v", Fnum, Overs, "version", } , 36 {"t", Fnum, Otype, "type", } , 37 {"c", Fnum, Ocode, "code" } , 38 {"s", Fnum, Osess, "sessid" } , 39 {0} 40 }; 41 42 static void 43 p_compilesess(Filter *f) 44 { 45 /* Mux *m; */ 46 47 if(f->op == '='){ 48 compile_cmp(pppoe_sess.name, f, p_fields); 49 return; 50 } 51 /* 52 for(m = p_mux; m->name != nil; m++) 53 if(strcmp(f->s, m->name) == 0){ 54 f->pr = m->pr; 55 f->ulv = m->val; 56 f->subop = Ot; 57 return; 58 } 59 */ 60 sysfatal("unknown pppoe field or protocol: %s", f->s); 61 } 62 static void 63 p_compiledisc(Filter *f) 64 { 65 /* Mux *m; */ 66 67 if(f->op == '='){ 68 compile_cmp(pppoe_disc.name, f, p_fields); 69 return; 70 } 71 /* 72 for(m = p_mux; m->name != nil; m++) 73 if(strcmp(f->s, m->name) == 0){ 74 f->pr = m->pr; 75 f->ulv = m->val; 76 f->subop = Ot; 77 return; 78 } 79 */ 80 sysfatal("unknown pppoe field or protocol: %s", f->s); 81 } 82 83 static int 84 p_filter(Filter *f, Msg *m) 85 { 86 Hdr *h; 87 88 if(m->pe - m->ps < HDRSIZE) 89 return 0; 90 91 h = (Hdr*)m->ps; 92 m->ps += HDRSIZE; 93 94 switch(f->subop){ 95 case Overs: 96 return (h->verstype>>4) == f->ulv; 97 case Otype: 98 return (h->verstype&0xF) == f->ulv; 99 case Ocode: 100 return h->code == f->ulv; 101 case Osess: 102 return NetS(h->sessid) == f->ulv; 103 } 104 return 0; 105 } 106 107 /* BUG: print all the discovery types */ 108 static int 109 p_seprintdisc(Msg *m) 110 { 111 Hdr *h; 112 int len; 113 114 len = m->pe - m->ps; 115 if(len < HDRSIZE) 116 return -1; 117 118 h = (Hdr*)m->ps; 119 m->ps += HDRSIZE; 120 121 m->pr = nil; 122 123 m->p = seprint(m->p, m->e, "v=%d t=%d c=0x%x s=0x%ux, len=%d", 124 h->verstype>>4, h->verstype&0xF, h->code, NetS(h->sessid), NetS(h->length)); 125 126 return 0; 127 } 128 129 static int 130 p_seprintsess(Msg *m) 131 { 132 Hdr *h; 133 int len; 134 135 len = m->pe - m->ps; 136 if(len < HDRSIZE) 137 return -1; 138 139 h = (Hdr*)m->ps; 140 m->ps += HDRSIZE; 141 142 /* this will call ppp for me */ 143 demux(p_mux, 0, 0, m, &dump); 144 145 m->p = seprint(m->p, m->e, "v=%d t=%d c=0x%x s=0x%ux, len=%d", 146 h->verstype>>4, h->verstype&0xF, h->code, NetS(h->sessid), NetS(h->length)); 147 148 return 0; 149 } 150 151 Proto pppoe_disc = 152 { 153 "pppoe_disc", 154 p_compiledisc, 155 p_filter, 156 p_seprintdisc, 157 p_mux, 158 "%lud", 159 p_fields, 160 defaultframer 161 }; 162 163 Proto pppoe_sess = 164 { 165 "pppoe_sess", 166 p_compilesess, 167 p_filter, 168 p_seprintsess, 169 p_mux, 170 "%lud", 171 p_fields, 172 defaultframer 173 };