tbootp.c - plan9port - [fork] Plan 9 from user space | |
git clone git://src.adamsgaard.dk/plan9port | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
tbootp.c (3436B) | |
--- | |
1 #include <u.h> | |
2 #include <libc.h> | |
3 #include <ip.h> | |
4 #include "dat.h" | |
5 #include "protos.h" | |
6 | |
7 enum | |
8 { | |
9 OfferTimeout= 60, /* when an offer times o… | |
10 MaxLease= 60*60, /* longest lease for dyna… | |
11 MinLease= 15*60, /* shortest lease for dyn… | |
12 StaticLease= 30*60, /* lease for static bi… | |
13 | |
14 IPUDPHDRSIZE= 28, /* size of an IP plus UD… | |
15 MINSUPPORTED= 576, /* biggest IP message t… | |
16 | |
17 /* lengths of some bootp fields */ | |
18 Maxhwlen= 16, | |
19 Maxfilelen= 128, | |
20 Maxoptlen= 312-4, | |
21 | |
22 /* bootp types */ | |
23 Bootrequest= 1, | |
24 Bootreply= 2, | |
25 | |
26 /* bootp flags */ | |
27 Fbroadcast= 1<<15 | |
28 }; | |
29 | |
30 typedef struct Hdr Hdr; | |
31 struct Hdr | |
32 { | |
33 uchar op; /* opcode */ | |
34 uchar htype; /* hardware type */ | |
35 uchar hlen; /* hardware address le… | |
36 uchar hops; /* hops */ | |
37 uchar xid[4]; /* a random number */ | |
38 uchar secs[2]; /* elapsed since client sta… | |
39 uchar flags[2]; | |
40 uchar ciaddr[IPv4addrlen]; /* client IP address (c… | |
41 uchar yiaddr[IPv4addrlen]; /* client IP address (s… | |
42 uchar siaddr[IPv4addrlen]; /* server IP address */ | |
43 uchar giaddr[IPv4addrlen]; /* gateway IP address */ | |
44 uchar chaddr[Maxhwlen]; /* client hardware address… | |
45 char sname[64]; /* server host name (optio… | |
46 char file[Maxfilelen]; /* boot file name */ | |
47 uchar optmagic[4]; | |
48 uchar optdata[Maxoptlen]; | |
49 }; | |
50 | |
51 enum | |
52 { | |
53 Oca, | |
54 Osa, | |
55 Ot | |
56 }; | |
57 | |
58 static Field p_fields[] = | |
59 { | |
60 {"ca", Fv4ip, Oca, "client IP addr"… | |
61 {"sa", Fv4ip, Osa, "server IP addr"… | |
62 {0} | |
63 }; | |
64 | |
65 #define plan9opt ((ulong)(('p'<<24) | ('9'<<16) | (' '<<8) | ' ')) | |
66 #define genericopt (0x63825363UL) | |
67 | |
68 static Mux p_mux[] = | |
69 { | |
70 {"dhcp", genericopt,}, | |
71 {"plan9bootp", plan9opt,}, | |
72 {"dump", 0,}, | |
73 {0} | |
74 }; | |
75 | |
76 static void | |
77 p_compile(Filter *f) | |
78 { | |
79 Mux *m; | |
80 | |
81 if(f->op == '='){ | |
82 compile_cmp(arp.name, f, p_fields); | |
83 return; | |
84 } | |
85 for(m = p_mux; m->name != nil; m++) | |
86 if(strcmp(f->s, m->name) == 0){ | |
87 f->pr = m->pr; | |
88 f->ulv = m->val; | |
89 f->subop = Ot; | |
90 return; | |
91 } | |
92 sysfatal("unknown bootp field: %s", f->s); | |
93 } | |
94 | |
95 static int | |
96 p_filter(Filter *f, Msg *m) | |
97 { | |
98 Hdr *h; | |
99 | |
100 h = (Hdr*)m->ps; | |
101 | |
102 if(m->pe < (uchar*)h->sname) | |
103 return 0; | |
104 m->ps = h->optdata; | |
105 | |
106 switch(f->subop){ | |
107 case Oca: | |
108 return NetL(h->ciaddr) == f->ulv || NetL(h->yiaddr) == f… | |
109 case Osa: | |
110 return NetL(h->siaddr) == f->ulv; | |
111 case Ot: | |
112 return NetL(h->optmagic) == f->ulv; | |
113 } | |
114 return 0; | |
115 } | |
116 | |
117 static char* | |
118 op(int i) | |
119 { | |
120 static char x[20]; | |
121 | |
122 switch(i){ | |
123 case Bootrequest: | |
124 return "Req"; | |
125 case Bootreply: | |
126 return "Rep"; | |
127 default: | |
128 sprint(x, "%d", i); | |
129 return x; | |
130 } | |
131 } | |
132 | |
133 | |
134 static int | |
135 p_seprint(Msg *m) | |
136 { | |
137 Hdr *h; | |
138 ulong x; | |
139 | |
140 h = (Hdr*)m->ps; | |
141 | |
142 if(m->pe < (uchar*)h->sname) | |
143 return -1; | |
144 | |
145 /* point past data */ | |
146 m->ps = h->optdata; | |
147 | |
148 /* next protocol */ | |
149 m->pr = nil; | |
150 if(m->pe >= (uchar*)h->optdata){ | |
151 x = NetL(h->optmagic); | |
152 demux(p_mux, x, x, m, &dump); | |
153 } | |
154 | |
155 m->p = seprint(m->p, m->e, "t=%s ht=%d hl=%d hp=%d xid=%ux sec=%… | |
156 op(h->op), h->htype, h->hlen, h->hops, | |
157 NetL(h->xid), NetS(h->secs), NetS(h->flags), | |
158 h->ciaddr, h->yiaddr, h->siaddr, h->giaddr, h->chaddr, | |
159 (ulong)NetL(h->optmagic)); | |
160 if(m->pe > (uchar*)h->sname && *h->sname) | |
161 m->p = seprint(m->p, m->e, " snam=%s", h->sname); | |
162 if(m->pe > (uchar*)h->file && *h->file) | |
163 m->p = seprint(m->p, m->e, " file=%s", h->file); | |
164 return 0; | |
165 } | |
166 | |
167 Proto bootp = | |
168 { | |
169 "bootp", | |
170 p_compile, | |
171 p_filter, | |
172 p_seprint, | |
173 p_mux, | |
174 "%#.8lux", | |
175 p_fields, | |
176 defaultframer | |
177 }; |