History

20070510-1000 remove use of oldheaders mode

Charles.Forsyth committed 19 years ago

Commit 9b073201 parent 32fe12d12 files · +22 −835Browse files

Unified · Split

12 files
  1. CHANGES +3 −0
  2. appl/cmd/ip/bootpd.b +1 −2
  3. appl/cmd/ip/dhcp.b +1 −1
  4. appl/cmd/ip/mkfile +0 −1
  5. appl/cmd/ip/obootpd.b +0 −777
  6. appl/cmd/ip/tftpd.b +1 −3
  7. appl/cmd/ip/virgild.b +1 −2
  8. appl/cmd/ndb/dns.b +4 −9
  9. appl/lib/dhcpclient.b +9 −19
  10. appl/lib/virgil.b +1 −2
  11. include/version.h +1 −1
  12. man/3/ip +0 −18
CHANGES+3−0
@@ -1,3 +1,6 @@
120070510
2 quickly remove references to udp's "oldheaders" because plan 9 removed it
3 remove obootpd completely
120070418420070418
2 add scan code to X11 (issue 45)5 add scan code to X11 (issue 45)
320070411620070411
appl/cmd/ip/bootpd.b+1−2
@@ -50,7 +50,7 @@ ndbfile := "/lib/ndb/local"; · 49 unmodified lines
50mtime := 0;50mtime := 0;
51testing := 0;51testing := 0;
52 52
53Udphdrsize: con IP->OUdphdrlen;53Udphdrsize: con IP->Udphdrlen;
54 54
55init(nil: ref Draw->Context, args: list of string)55init(nil: ref Draw->Context, args: list of string)
56{56{
@@ -125,7 +125,6 @@ init(nil: ref Draw->Context, args: list of string) · 68 unmodified lines
125 error(sys->sprint("can't announce %s: %r", addr));125 error(sys->sprint("can't announce %s: %r", addr));
126 if(sys->fprint(c.cfd, "headers") < 0)126 if(sys->fprint(c.cfd, "headers") < 0)
127 error(sys->sprint("can't set headers mode: %r"));127 error(sys->sprint("can't set headers mode: %r"));
128 sys->fprint(c.cfd, "oldheaders");
129 128
130 if(debug)129 if(debug)
131 sys->fprint(stderr, "bootpd: opening %s/data\n", c.dir);130 sys->fprint(stderr, "bootpd: opening %s/data\n", c.dir);
appl/cmd/ip/dhcp.b+1−1
@@ -11,7 +11,7 @@ include "draw.m"; · 10 unmodified lines
11 11
12include "ip.m";12include "ip.m";
13 ip: IP;13 ip: IP;
14 IPv4off, IPaddrlen, OUdphdrlen: import IP;14 IPv4off, IPaddrlen: import IP;
15 IPaddr: import ip;15 IPaddr: import ip;
16 get2, get4, put2, put4: import ip;16 get2, get4, put2, put4: import ip;
17 17
appl/cmd/ip/mkfile+0−1
@@ -11,7 +11,6 @@ TARG=\ · 10 unmodified lines
11 rip.dis\11 rip.dis\
12 tftpd.dis\12 tftpd.dis\
13 virgild.dis\13 virgild.dis\
14 obootpd.dis\
15 sntp.dis\14 sntp.dis\
16 15
17SYSMODULES=\16SYSMODULES=\
appl/cmd/ip/obootpd.b+0−777
@@ -1,777 +0,0 @@
1implement Bootpd;
2
3include "sys.m";
4 sys: Sys;
5
6include "draw.m";
7
8include "bufio.m";
9 bufio: Bufio;
10 Iobuf: import bufio;
11
12include "attrdb.m";
13 attrdb: Attrdb;
14 Db, Dbentry: import attrdb;
15
16include "ip.m";
17 ip: IP;
18 IPaddr, Udphdr: import ip;
19
20include "ether.m";
21 ether: Ether;
22
23include "arg.m";
24
25Bootpd: module
26{
27 init: fn(nil: ref Draw->Context, argv: list of string);
28};
29
30stderr: ref Sys->FD;
31debug: int;
32sniff: int;
33verbose: int;
34
35siaddr: array of byte;
36sysname: string;
37progname := "bootpd";
38net := "/net";
39
40Udphdrsize: con IP->OUdphdrlen;
41
42NEED_HA: con 1;
43NEED_IP: con 0;
44NEED_BF: con 0;
45NEED_SM: con 0;
46NEED_GW: con 0;
47NEED_FS: con 0;
48NEED_AU: con 0;
49
50init(nil: ref Draw->Context, args: list of string)
51{
52 sys = load Sys Sys->PATH;
53 stderr = sys->fildes(2);
54 bufio = load Bufio Bufio->PATH;
55 if(bufio == nil)
56 loadfail(Bufio->PATH);
57 attrdb = load Attrdb Attrdb->PATH;
58 if(attrdb == nil)
59 loadfail(Attrdb->PATH);
60 attrdb->init();
61 ip = load IP IP->PATH;
62 if(ip == nil)
63 loadfail(IP->PATH);
64 ip->init();
65 ether = load Ether Ether->PATH;
66 if(ether == nil)
67 loadfail(Ether->PATH);
68 ether->init();
69
70 fname := "/services/bootp/db";
71 verbose = 1;
72 sniff = 0;
73 debug = 0;
74 arg := load Arg Arg->PATH;
75 if(arg == nil)
76 raise "fail: load Arg";
77 arg->init(args);
78 arg->setusage("bootpd [-dsqv] [-f file] [-x network]");
79 progname = arg->progname();
80 while((o := arg->opt()) != 0)
81 case o {
82 'd' => debug++;
83 's' => sniff = 1; debug = 255;
84 'q' => verbose = 0;
85 'v' => verbose = 1;
86 'x' => net = arg->earg();
87 'f' => fname = arg->earg();
88 * => arg->usage();
89 }
90 args = arg->argv();
91 if(args != nil)
92 arg->usage();
93 arg = nil;
94
95 sys->pctl(Sys->FORKFD|Sys->FORKNS, nil);
96 if(tabopen(fname))
97 raise "fail: open database";
98
99 if(!sniff && (err := dbread()) != nil)
100 error(sys->sprint("error in %s: %s", fname, err));
101
102 addr := net+"/udp!*!67";
103 if(debug)
104 sys->fprint(stderr, "bootp: announcing %s\n", addr);
105 (ok, c) := sys->announce(addr);
106 if(ok < 0)
107 error(sys->sprint("can't announce %s: %r", addr));
108 get_sysname();
109 get_ip();
110
111 if(sys->fprint(c.cfd, "headers") < 0)
112 error(sys->sprint("can't set headers mode: %r"));
113 sys->fprint(c.cfd, "oldheaders");
114
115 if(debug)
116 sys->fprint(stderr, "bootp: opening %s/data\n", c.dir);
117 c.dfd = sys->open(c.dir+"/data", sys->ORDWR);
118 if(c.dfd == nil)
119 error(sys->sprint("can't open %s/data: %r", c.dir));
120
121 spawn server(c);
122}
123
124loadfail(s: string)
125{
126 error(sys->sprint("can't load %s: %r", s));
127}
128
129error(s: string)
130{
131 sys->fprint(stderr, "bootp: %s\n", s);
132 raise "fail:error";
133}
134
135server(c: Sys->Connection)
136{
137 buf := array[2048] of byte;
138 badread := 0;
139 for(;;) {
140 if(debug)
141 sys->fprint(stderr, "bootp: listening for bootp requests...\n");
142 n := sys->read(c.dfd, buf, len buf);
143 if(n <0) {
144 if (badread++ > 10)
145 break;
146 continue;
147 }
148 badread = 0;
149 if(n < Udphdrsize) {
150 if(debug)
151 sys->fprint(stderr, "bootp: short Udphdr: %d bytes\n", n);
152 continue;
153 }
154 hdr := Udphdr.unpack(buf, Udphdrsize);
155 if(debug)
156 sys->fprint(stderr, "bootp: received request from udp!%s!%d\n", hdr.raddr.text(), hdr.rport);
157 if(n < Udphdrsize+300) {
158 if(debug)
159 sys->fprint(stderr, "bootp: short request of %d bytes\n", n - Udphdrsize);
160 continue;
161 }
162
163 (err, bootp) := M2S(buf[Udphdrsize:]);
164 if(err != nil) {
165 if(debug)
166 sys->fprint(stderr, "bootp: M2S failed: %s\n", err);
167 continue;
168 }
169 if(debug >= 2)
170 ppkt(bootp);
171 if(sniff)
172 continue;
173 if(bootp.htype != byte 1 || bootp.hlen != byte 6) {
174 # if it isn't ether, we don't do it
175 if(debug)
176 sys->fprint(stderr, "bootp: hardware type not ether; ignoring.\n");
177 continue;
178 }
179 if((err = dbread()) != nil) {
180 sys->fprint(stderr, "bootp: getreply: dbread failed: %s\n", err);
181 continue;
182 }
183 rec := lookup(bootp);
184 if(rec == nil) {
185 # we can't answer this request
186 if(debug)
187 sys->fprint(stderr, "bootp: cannot answer request.\n");
188 continue;
189 }
190 if(debug){
191 sys->fprint(stderr, "bootp: found a matching entry:\n");
192 pinfbp(rec);
193 }
194 mkreply(bootp, rec);
195 if(verbose) sys->print("bootp: %s -> %s %s\n", ether->text(rec.ha), rec.hostname, iptoa(rec.ip));
196 if(debug >= 2) {
197 sys->fprint(stderr, "bootp: reply message:\n");
198 ppkt(bootp);
199 }
200 repl:= S2M(bootp);
201
202 if(debug)
203 sys->fprint(stderr, "bootp: sending reply.\n");
204 arpenter(iptoa(rec.ip), ether->text(rec.ha));
205 send(repl);
206 }
207 sys->fprint(stderr, "bootp: %d read errors: %r\n", badread);
208}
209
210arpenter(ip, ha: string)
211{
212 if(debug) sys->fprint(stderr, "bootp: arp: %s -> %s\n", ip, ha);
213 fd := sys->open(net+"/arp", Sys->OWRITE);
214 if(fd == nil) {
215 if(debug)
216 sys->fprint(stderr, "bootp: arp open failed: %r\n");
217 return;
218 }
219 if(sys->fprint(fd, "add %s %s", ip, ha) < 0){
220 if(debug)
221 sys->fprint(stderr, "bootp: error writing arp: %r\n");
222 }
223}
224
225get_sysname()
226{
227 fd := sys->open("/dev/sysname", sys->OREAD);
228 if(fd == nil) {
229 sysname = "anon";
230 return;
231 }
232 buf := array[128] of byte;
233 n := sys->read(fd, buf, len buf);
234 if(n <= 0) {
235 sysname = "anon";
236 return;
237 }
238 sysname = string buf[0:n];
239}
240
241get_ip()
242{
243 siaddr = array[4] of { * => byte 0 };
244 # get a local IP address by translating our sysname with cs(8)
245 fd := sys->open(net+"/cs", Sys->ORDWR);
246 if(fd == nil){
247 if(debug)
248 sys->fprint(stderr, "bootp: cannot open %s/cs for reading: %r.\n", net);
249 return;
250 }
251 if(sys->fprint(fd, "net!%s!0", sysname) < 0){
252 if(debug)
253 sys->fprint(stderr, "bootp: can't translate net!%s!0 via %s/cs: %r\n", sysname, net);
254 return;
255 }
256 sys->seek(fd, big 0, 0);
257 a := array[1024] of byte;
258 n := sys->read(fd, a, len a);
259 if(n < 0) {
260 if(debug) sys->fprint(stderr, "bootp: read from /net/cs: %r.\n");
261 return;
262 }
263 reply := string a[0:n];
264 if(debug) sys->fprint(stderr, "bootp: read %s from /net/cs\n", reply);
265
266 (l, addr):= sys->tokenize(reply, " ");
267 if(l != 2) {
268 if(debug) sys->fprint(stderr, "bootp: bad format from cs\n");
269 return;
270 }
271 (l, addr) = sys->tokenize(hd tl addr, "!");
272 if(l < 2) {
273 if(debug) sys->fprint(stderr, "bootp: short addr from cs\n");
274 return;
275 }
276 err:= "";
277 (err, siaddr) = get_ipaddr(hd addr);
278 if(err != nil || siaddr == nil) {
279 if(debug) sys->fprint(stderr, "bootp: invalid local IP addr %s.\n", hd tl addr);
280 siaddr = array[4] of { * => byte 0 };
281 };
282 if(debug) sys->fprint(stderr, "bootp: local IP address is %s.\n", iptoa(siaddr));
283}
284
285# byte op; /* opcode */
286# byte htype; /* hardware type */
287# byte hlen; /* hardware address len */
288# byte hops; /* hops */
289# byte xid[4]; /* a random number */
290# byte secs[2]; /* elapsed snce client started booting */
291# byte pad[2];
292# byte ciaddr[4]; /* client IP address (client tells server) */
293# byte yiaddr[4]; /* client IP address (server tells client) */
294# byte siaddr[4]; /* server IP address */
295# byte giaddr[4]; /* gateway IP address */
296# byte chaddr[16]; /* client hardware address */
297# byte sname[64]; /* server host name (optional) */
298# byte file[128]; /* boot file name */
299# byte vend[128]; /* vendor-specific goo */
300
301BootpPKT: adt
302{
303 op: byte; # Start of udp datagram
304 htype: byte;
305 hlen: byte;
306 hops: byte;
307 xid: int;
308 secs: int;
309 ciaddr: array of byte;
310 yiaddr: array of byte;
311 siaddr: array of byte;
312 giaddr: array of byte;
313 chaddr: array of byte;
314 sname: string;
315 file: string;
316 vend: array of byte;
317};
318
319InfBP: adt {
320 hostname: string;
321
322 ha: array of byte; # hardware addr
323 ip: array of byte; # client IP addr
324 bf: array of byte; # boot file path
325 sm: array of byte; # subnet mask
326 gw: array of byte; # gateway IP addr
327 fs: array of byte; # file server IP addr
328 au: array of byte; # authentication server IP addr
329};
330
331records: array of ref InfBP;
332
333tabbio: ref Bufio->Iobuf;
334tabname: string;
335mtime: int;
336
337tabopen(fname: string): int
338{
339 if(sniff) return 0;
340 tabname = fname;
341 if((tabbio = bufio->open(tabname, bufio->OREAD)) == nil) {
342 sys->fprint(stderr, "bootp: cannot open %s: %r\n", tabname);
343 return 1;
344 }
345 return 0;
346}
347
348send(msg: array of byte)
349{
350 if(debug) sys->fprint(stderr, "bootp: dialing udp!broadcast!68\n");
351 (n, c) := sys->dial(net+"/udp!255.255.255.255!68", "67");
352# (n, c) := sys->dial(net+"/udp!255.255.255.255!68", "192.168.129.1!67");
353 if(n < 0) {
354 sys->fprint(stderr, "bootp: send: error calling dial: %r\n");
355 return;
356 }
357 if(debug) sys->fprint(stderr, "bootp: writing to %s/data\n", c.dir);
358 n = sys->write(c.dfd, msg, len msg);
359 if(n <=0) {
360 sys->fprint(stderr, "bootp: send: error writing to %s/data: %r\n", c.dir);
361 return;
362 }
363 if(debug) sys->fprint(stderr, "bootp: successfully wrote %d bytes to %s/data\n", n, c.dir);
364}
365
366mkreply(bootp: ref BootpPKT, rec: ref InfBP)
367{
368 bootp.op = byte 2; # boot reply
369 bootp.yiaddr = rec.ip;
370 bootp.siaddr = siaddr;
371 bootp.giaddr = array[4] of { * => byte 0 };
372 bootp.sname = sysname;
373 bootp.file = string rec.bf;
374 bootp.vend = array of byte sys->sprint("p9 %s %s %s %s", iptoa(rec.sm), iptoa(rec.fs), iptoa(rec.au), iptoa(rec.gw));
375}
376
377lookup(bootp: ref BootpPKT): ref InfBP
378{
379 for(i := 0; i < len records; i++)
380 if(eqa(bootp.chaddr[0:6], records[i].ha) || eqa(bootp.ciaddr, records[i].ip))
381 return records[i];
382 return nil;
383}
384
385dbread(): string
386{
387 (n, dir) := sys->fstat(tabbio.fd);
388 if(n < 0)
389 return sys->sprint("cannot fstat %s: %r", tabname);
390 if(mtime == 0 || mtime != dir.mtime) {
391 if(bufio->tabbio.seek(big 0, Sys->SEEKSTART) < big 0)
392 return sys->sprint("error seeking to start of %s.", tabname);
393 mtime = dir.mtime;
394 lnum: int = 0;
395 trecs: list of ref InfBP;
396LINES: while((line := bufio->tabbio.gets('\n')) != nil) {
397 lnum++;
398 if(line[0] == '#') # comment
399 continue LINES;
400 fields: list of string;
401 (n, fields) = sys->tokenize(line, ":\r\n");
402 if(n <= 0) { # blank line or colons
403 if(len line > 0) {
404 sys->fprint(stderr, "bootp: %s: %d empty entry.\n", tabname, lnum);
405 }
406 continue LINES;
407 }
408 rec := ref InfBP;
409 rec.hostname = hd fields;
410 fields = tl fields;
411 err: string;
412FIELDS: for(; fields != nil; fields = tl fields) {
413 field := hd fields;
414 if(len field <= len "xx=") {
415 sys->fprint(stderr, "bootp: %s:%d invalid field \"%s\" in entry for %s",
416 tabname, lnum, field, rec.hostname);
417 continue FIELDS;
418 }
419 err = nil;
420 case field[0:3] {
421 "ha=" =>
422 if(rec.ha != nil) {
423 sys->fprint(stderr,
424 "bootp: warning: %s:%d hardware address redefined for %s.\n",
425 tabname, lnum, rec.hostname);
426 }
427 (err, rec.ha) = get_haddr(field[3:]);
428 "ip=" =>
429 if(rec.ip != nil) {
430 sys->fprint(stderr, "bootp: warning: %s:%d IP address redefined for %s.\n",
431 tabname, lnum, rec.hostname);
432 }
433 (err, rec.ip) = get_ipaddr(field[3:]);
434 "bf=" =>
435 if(rec.bf != nil) {
436 sys->fprint(stderr, "bootp: warning: %s:%d bootfile redefined for %s.\n",
437 tabname, lnum, rec.hostname);
438 }
439 (err, rec.bf) = get_path(field[3:]);
440 "sm=" =>
441 if(rec.sm != nil) {
442 sys->fprint(stderr, "bootp: warning: %s:%d subnet mask redefined for %s.\n",
443 tabname, lnum, rec.hostname);
444 }
445 (err, rec.sm) = get_ipaddr(field[3:]);
446 "gw=" =>
447 if(rec.gw != nil) {
448 sys->fprint(stderr, "bootp: warning: %s:%d gateway redefined for %s.\n",
449 tabname, lnum, rec.hostname);
450 }
451 (err, rec.gw) = get_ipaddr(field[3:]);
452 "fs=" =>
453 if(rec.fs != nil) {
454 sys->fprint(stderr, "bootp: warning: %s:%d file server redefined for %s.\n",
455 tabname, lnum, rec.hostname);
456 }
457 (err, rec.fs) = get_ipaddr(field[3:]);
458 "au=" =>
459 if(rec.au != nil) {
460 sys->fprint(stderr,
461 "bootp: warning: %s:%d authentication server redefined for %s.\n",
462 tabname, lnum, rec.hostname);
463 }
464 (err, rec.au) = get_ipaddr(field[3:]);
465 * =>
466 sys->fprint(stderr,
467 "bootp: %s:%d invalid or unsupported tag \"%s\" in entry for %s.\n",
468 tabname, lnum, field[0:2], rec.hostname);
469 continue FIELDS;
470 }
471 if(err != nil) {
472 sys->fprint(stderr,
473 "bootp: %s:%d %s for %s.\nbootp: skipping entry for %s.\n",
474 tabname, lnum, err, rec.hostname,
475 rec.hostname);
476 continue LINES;
477 }
478 }
479 if(rec.ha == nil) {
480 if(NEED_HA) {
481 sys->fprint(stderr, "bootp: %s:%d no hardware address defined for %s.\n",
482 tabname, lnum, rec.hostname);
483 sys->fprint(stderr, "bootp: skipping entry for %s.\n", rec.hostname);
484 continue LINES;
485 }
486 }
487 if(rec.ip == nil) {
488 if(NEED_IP) {
489 sys->fprint(stderr, "bootp: %s:%d no IP address defined for %s.\n",
490 tabname, lnum, rec.hostname);
491 sys->fprint(stderr, "bootp: skipping entry for %s.\n", rec.hostname);
492 continue LINES;
493 }
494 }
495 if(rec.bf == nil) {
496 if(NEED_BF) {
497 sys->fprint(stderr, "bootp: %s:%d no bootfile defined for %s.\n",
498 tabname, lnum, rec.hostname);
499 sys->fprint(stderr, "bootp: skipping entry for %s.\n", rec.hostname);
500 continue LINES;
501 }
502 }
503 if(rec.sm == nil) {
504 if(NEED_SM) {
505 sys->fprint(stderr, "bootp: %s:%d no subnet mask defined for %s.\n",
506 tabname, lnum, rec.hostname);
507 sys->fprint(stderr, "bootp: skipping entry for %s.\n", rec.hostname);
508 continue LINES;
509 }
510 }
511 if(rec.gw == nil) {
512 if(NEED_GW) {
513 sys->fprint(stderr, "bootp: %s:%d no gateway defined for %s.\n",
514 tabname, lnum, rec.hostname);
515 sys->fprint(stderr, "bootp: skipping entry for %s.\n", rec.hostname);
516 continue LINES;
517 }
518 }
519 if(rec.fs == nil) {
520 if(NEED_FS) {
521 sys->fprint(stderr, "bootp: %s:%d no file server defined for %s.\n",
522 tabname, lnum, rec.hostname);
523 sys->fprint(stderr, "bootp: skipping entry for %s.\n", rec.hostname);
524 continue LINES;
525 }
526 }
527 if(rec.au == nil) {
528 if(NEED_AU) {
529 sys->fprint(stderr,
530 "bootp: %s:%d no authentication server defined for %s.\n",
531 tabname, lnum, rec.hostname);
532 sys->fprint(stderr, "bootp: skipping entry for %s.\n", rec.hostname);
533 continue LINES;
534 }
535 }
536 if(debug) pinfbp(rec);
537 trecs = rec :: trecs;
538 }
539 if(trecs == nil) {
540 sys->fprint(stderr, "bootp: no valid entries in %s.\n", tabname);
541 if(records != nil) {
542 sys->fprint(stderr, "bootp: reverting to previous state.\n");
543 return nil;
544 }
545 return "no entries.";
546 }
547 records = array[len trecs] of ref InfBP;
548 for(n = len records; n > 0; trecs = tl trecs)
549 records[--n] = hd trecs;
550 }
551 return nil;
552}
553
554get_haddr(str: string): (string, array of byte)
555{
556 addr := ether->parse(str);
557 if(addr == nil)
558 return (sys->sprint("invalid hardware address \"%s\"", str), nil);
559 return (nil, addr);
560}
561
562get_ipaddr(str: string): (string, array of byte)
563{
564 (ok, a) := IPaddr.parse(str);
565 if(ok < 0)
566 return (sys->sprint("invalid address: %s", str), nil);
567 return (nil, a.v4());
568}
569
570get_path(str: string): (string, array of byte)
571{
572 if(str == nil) {
573 return ("nil path", nil);
574 }
575 path := array of byte str;
576 if(len path > 128)
577 return (sys->sprint("path too long (>128 bytes) \"%s...\"", string path[0:16]), nil);
578 return (nil, path);
579}
580
581iptoa(addr: array of byte): string
582{
583 if(len addr != 4)
584 return "0.0.0.0";
585 return sys->sprint("%d.%d.%d.%d",
586 int addr[0],
587 int addr[1],
588 int addr[2],
589 int addr[3]);
590}
591
592dtoa(data: array of byte): string
593{
594 if(data == nil)
595 return nil;
596 result: string;
597 for(i:=0; i < len data; i++)
598 result += sys->sprint(".%d", int data[i]);
599 return result[1:];
600}
601
602bptohw(bp: ref BootpPKT): string
603{
604 l := int bp.hlen;
605 if(l > 0 && l < len bp.chaddr)
606 return ether->text(bp.chaddr[0:l]);
607 return "";
608}
609
610ctostr(cstr: array of byte): string
611{
612 for(i:=0; i<len cstr; i++)
613 if(cstr[i] == byte 0)
614 break;
615 return string cstr[0:i];
616}
617
618strtoc(s: string): array of byte
619{
620 as := array of byte s;
621 cs := array[1 + len as] of byte;
622 cs[0:] = as;
623 cs[len cs - 1] = byte 0;
624 return cs;
625}
626
627ppkt(bootp: ref BootpPKT)
628{
629 sys->fprint(stderr, "BootpPKT {\n");
630 sys->fprint(stderr, "\top == %d\n", int bootp.op);
631 sys->fprint(stderr, "\thtype == %d\n", int bootp.htype);
632 sys->fprint(stderr, "\thlen == %d\n", int bootp.hlen);
633 sys->fprint(stderr, "\thops == %d\n", int bootp.hops);
634 sys->fprint(stderr, "\txid == %d\n", bootp.xid);
635 sys->fprint(stderr, "\tsecs == %d\n", bootp.secs);
636 sys->fprint(stderr, "\tC client == %s\n", dtoa(bootp.ciaddr));
637 sys->fprint(stderr, "\tY client == %s\n", dtoa(bootp.yiaddr));
638 sys->fprint(stderr, "\tserver == %s\n", dtoa(bootp.siaddr));
639 sys->fprint(stderr, "\tgateway == %s\n", dtoa(bootp.giaddr));
640 sys->fprint(stderr, "\thwaddr == %s\n", bptohw(bootp));
641 sys->fprint(stderr, "\thost == %s\n", bootp.sname);
642 sys->fprint(stderr, "\tfile == %s\n", bootp.file);
643 sys->fprint(stderr, "\tmagic == %s\n", magic(bootp.vend[0:4]));
644 if(magic(bootp.vend[0:4]) == "plan9") {
645 (n, strs) := sys->tokenize(string bootp.vend[4:], " \r\n");
646 if(strs != nil) {
647 sys->fprint(stderr, "\t\tsm == %s\n", hd strs);
648 strs = tl strs;
649 }
650 if(strs != nil) {
651 sys->fprint(stderr, "\t\tfs == %s\n", hd strs);
652 strs = tl strs;
653 }
654 if(strs != nil) {
655 sys->fprint(stderr, "\t\tau == %s\n", hd strs);
656 strs = tl strs;
657 }
658 if(strs != nil) {
659 sys->fprint(stderr, "\t\tgw == %s\n", hd strs);
660 strs = tl strs;
661 }
662 }
663 sys->fprint(stderr, "}\n\n");
664}
665
666eqa(a1: array of byte, a2: array of byte): int
667{
668 if(len a1 != len a2)
669 return 0;
670 for(i := 0; i < len a1; i++)
671 if(a1[i] != a2[i])
672 return 0;
673 return 1;
674}
675
676magic(cookie: array of byte): string
677{
678 if(eqa(cookie, array[] of { byte 'p', byte '9', byte ' ', byte ' ' }))
679 return "plan9";
680 if(eqa(cookie, array[] of { byte 99, byte 130, byte 83, byte 99 }))
681 return "rfc1048";
682 if(eqa(cookie, array[] of { byte 'C', byte 'M', byte 'U', byte 0 }))
683 return "cmu";
684 return dtoa(cookie);
685}
686
687pinfbp(rec: ref InfBP)
688{
689 sys->fprint(stderr, "Bootp entry {\n");
690 sys->fprint(stderr, "\tha == %s\n", ether->text(rec.ha));
691 sys->fprint(stderr, "\tip == %s\n", dtoa(rec.ip));
692 sys->fprint(stderr, "\tbf == %s\n", string rec.bf);
693 sys->fprint(stderr, "\tsm == %s\n", dtoa(rec.sm));
694 sys->fprint(stderr, "\tgw == %s\n", dtoa(rec.gw));
695 sys->fprint(stderr, "\tfs == %s\n", dtoa(rec.fs));
696 sys->fprint(stderr, "\tau == %s\n", dtoa(rec.au));
697 sys->fprint(stderr, "}\n");
698}
699
700M2S(data: array of byte): (string, ref BootpPKT)
701{
702 if(len data < 300)
703 return ("too short", nil);
704
705 bootp := ref BootpPKT;
706
707 bootp.op = data[0];
708 bootp.htype = data[1];
709 bootp.hlen = data[2];
710 bootp.hops = data[3];
711 bootp.xid = nhgetl(data[4:8]);
712 bootp.secs = nhgets(data[8:10]);
713 # data[10:12] unused
714 bootp.ciaddr = data[12:16];
715 bootp.yiaddr = data[16:20];
716 bootp.siaddr = data[20:24];
717 bootp.giaddr = data[24:28];
718 bootp.chaddr = data[28:44];
719 bootp.sname = ctostr(data[44:108]);
720 bootp.file = ctostr(data[108:236]);
721 bootp.vend = data[236:300];
722
723 return (nil, bootp);
724}
725
726S2M(bootp: ref BootpPKT): array of byte
727{
728 data := array[364] of { * => byte 0 };
729
730 data[0] = bootp.op;
731 data[1] = bootp.htype;
732 data[2] = bootp.hlen;
733 data[3] = bootp.hops;
734 data[4:] = nhputl(bootp.xid);
735 data[8:] = nhputs(bootp.secs);
736 # data[10:12] unused
737 data[12:] = bootp.ciaddr;
738 data[16:] = bootp.yiaddr;
739 data[20:] = bootp.siaddr;
740 data[24:] = bootp.giaddr;
741 data[28:] = bootp.chaddr;
742 data[44:] = array of byte bootp.sname;
743 data[108:] = array of byte bootp.file;
744 data[236:] = bootp.vend;
745
746 return data;
747}
748
749nhgetl(data: array of byte): int
750{
751 return (int data[0]<<24) | (int data[1]<<16) |
752 (int data[2]<<8) | int data[3];
753}
754
755nhgets(data: array of byte): int
756{
757 return (int data[0]<<8) | int data[1];
758}
759
760nhputl(value: int): array of byte
761{
762 return array[] of {
763 byte (value >> 24),
764 byte (value >> 16),
765 byte (value >> 8),
766 byte (value >> 0),
767 };
768}
769
770nhputs(value: int): array of byte
771{
772 return array[] of {
773 byte (value >> 8),
774 byte (value >> 0),
775 };
776}
777
appl/cmd/ip/tftpd.b+1−3
@@ -32,7 +32,7 @@ dbg := 0; · 31 unmodified lines
32restricted := 0;32restricted := 0;
33port := 69;33port := 69;
34 34
35Udphdrsize: con IP->OUdphdrlen;35Udphdrsize: con IP->Udphdrlen;
36 36
37tftpcon: Sys->Connection;37tftpcon: Sys->Connection;
38tftpreq: ref Sys->FD;38tftpreq: ref Sys->FD;
@@ -498,8 +498,6 @@ openlisten() · 459 unmodified lines
498 fatal("can't announce "+name);498 fatal("can't announce "+name);
499 if(sys->fprint(tftpcon.cfd, "headers") < 0)499 if(sys->fprint(tftpcon.cfd, "headers") < 0)
500 fatal("can't set header mode");500 fatal("can't set header mode");
501 sys->fprint(tftpcon.cfd, "oldheaders");
502
503 tftpreq = sys->open(tftpcon.dir+"/data", sys->ORDWR);501 tftpreq = sys->open(tftpcon.dir+"/data", sys->ORDWR);
504 if(tftpreq == nil)502 if(tftpreq == nil)
505 fatal("open udp data");503 fatal("open udp data");
appl/cmd/ip/virgild.b+1−2
@@ -14,7 +14,7 @@ Virgild: module · 13 unmodified lines
14 14
15stderr: ref Sys->FD;15stderr: ref Sys->FD;
16 16
17Udphdrsize: con IP->OUdphdrlen;17Udphdrsize: con IP->Udphdrlen;
18 18
19init(nil: ref Draw->Context, nil: list of string)19init(nil: ref Draw->Context, nil: list of string)
20{20{
@@ -76,7 +76,6 @@ openlisten(): ref Sys->FD · 55 unmodified lines
76 sys->fprint(stderr, "virgild: can't set headers: %r\n");76 sys->fprint(stderr, "virgild: can't set headers: %r\n");
77 return nil;77 return nil;
78 }78 }
79 sys->fprint(c.cfd, "oldheaders");
80 79
81 c.dfd = sys->open(c.dir+"/data", Sys->ORDWR);80 c.dfd = sys->open(c.dir+"/data", Sys->ORDWR);
82 if(c.dfd == nil) {81 if(c.dfd == nil) {
appl/cmd/ndb/dns.b+4−9
@@ -30,7 +30,7 @@ include "srv.m"; · 29 unmodified lines
30 30
31include "ip.m";31include "ip.m";
32 ip: IP;32 ip: IP;
33 IPaddrlen, IPaddr, IPv4off, OUdphdrlen: import ip;33 IPaddrlen, IPaddr, IPv4off, Udphdrlen, Udpraddr, Udpladdr, Udprport, Udplport: import ip;
34 34
35include "arg.m";35include "arg.m";
36 36
@@ -924,7 +924,7 @@ fullresult(name: string, attr: string, l: list of string): list of string · 887 unmodified lines
924 924
925arpa2addr(a: string): string925arpa2addr(a: string): string
926{926{
927 (nf, flds) := sys->tokenize(a, ".");927 (nil, flds) := sys->tokenize(a, ".");
928 rl: list of string;928 rl: list of string;
929 for(; flds != nil && lower(s := hd flds) != "in-addr"; flds = tl flds)929 for(; flds != nil && lower(s := hd flds) != "in-addr"; flds = tl flds)
930 rl = s :: rl;930 rl = s :: rl;
@@ -1648,13 +1648,9 @@ rrtypename(t: int): string · 717 unmodified lines
1648}1648}
1649 1649
1650#1650#
1651# format of UDP head read and written in `oldheaders' mode1651# format of UDP head read and written in `headers' mode
1652#1652#
1653Udphdrsize: con OUdphdrlen;1653Udphdrsize: con Udphdrlen;
1654Udpraddr: con 0;
1655Udpladdr: con IPaddrlen;
1656Udprport: con 2*IPaddrlen;
1657Udplport: con 2*IPaddrlen+2;
1658dnsid := 1;1654dnsid := 1;
1659 1655
1660mkquery(qtype: int, qclass: int, name: string): (int, array of byte, string)1656mkquery(qtype: int, qclass: int, name: string): (int, array of byte, string)
@@ -1779,7 +1775,6 @@ udpport(): ref Sys->FD · 118 unmodified lines
1779 sys->fprint(stderr, "dns: can't set headers mode: %r\n");1775 sys->fprint(stderr, "dns: can't set headers mode: %r\n");
1780 return nil;1776 return nil;
1781 }1777 }
1782 sys->fprint(conn.cfd, "oldheaders"); # plan 9 interface
1783 conn.dfd = sys->open(conn.dir+"/data", Sys->ORDWR);1778 conn.dfd = sys->open(conn.dir+"/data", Sys->ORDWR);
1784 if(conn.dfd == nil){1779 if(conn.dfd == nil){
1785 sys->fprint(stderr, "dns: can't open %s/data: %r\n", conn.dir);1780 sys->fprint(stderr, "dns: can't open %s/data: %r\n", conn.dir);
appl/lib/dhcpclient.b+9−19
@@ -10,7 +10,7 @@ include "sys.m"; · 9 unmodified lines
10 10
11include "ip.m";11include "ip.m";
12 ip: IP;12 ip: IP;
13 IPv4off, IPaddrlen, OUdphdrlen: import IP;13 IPv4off, IPaddrlen, Udphdrlen, Udpraddr, Udpladdr, Udprport, Udplport: import IP;
14 IPaddr: import ip;14 IPaddr: import ip;
15 get2, get4, put2, put4: import ip;15 get2, get4, put2, put4: import ip;
16 16
@@ -21,15 +21,6 @@ include "dhcp.m"; · 4 unmodified lines
21 21
22debug := 0;22debug := 0;
23 23
24#
25# format of UDP head read and written in `oldheaders' mode
26#
27Udphdrsize: con OUdphdrlen;
28Udpraddr: con 0;
29Udpladdr: con IPaddrlen;
30Udprport: con 2*IPaddrlen;
31Udplport: con 2*IPaddrlen+2;
32
33xidgen: int;24xidgen: int;
34 25
35init()26init()
@@ -226,9 +217,9 @@ magic := array[] of {byte 99, byte 130, byte 83, byte 99}; # RFC2132 (replacing · 190 unmodified lines
226dhcpsend(fd: ref Sys->FD, xid: int, dhcp: ref Dhcp)217dhcpsend(fd: ref Sys->FD, xid: int, dhcp: ref Dhcp)
227{218{
228 dhcp.xid = xid;219 dhcp.xid = xid;
229 abuf := array[576+Udphdrsize] of {* => byte 0};220 abuf := array[576+Udphdrlen] of {* => byte 0};
230 abuf[0:] = dhcp.udphdr;221 abuf[0:] = dhcp.udphdr;
231 buf := abuf[Udphdrsize:];222 buf := abuf[Udphdrlen:];
232 buf[0] = byte dhcp.op;223 buf[0] = byte dhcp.op;
233 buf[1] = byte dhcp.htype;224 buf[1] = byte dhcp.htype;
234 buf[2] = byte len dhcp.chaddr;225 buf[2] = byte len dhcp.chaddr;
@@ -309,7 +300,7 @@ dhcpreader(pidc: chan of int, srv: ref DhcpIO) · 74 unmodified lines
309{300{
310 pidc <-= sys->pctl(0, nil);301 pidc <-= sys->pctl(0, nil);
311 for(;;){302 for(;;){
312 abuf := array [576+Udphdrsize] of byte;303 abuf := array [576+Udphdrlen] of byte;
313 n := sys->read(srv.fd, abuf, len abuf);304 n := sys->read(srv.fd, abuf, len abuf);
314 if(n < 0){305 if(n < 0){
315 if(debug)306 if(debug)
@@ -317,13 +308,13 @@ dhcpreader(pidc: chan of int, srv: ref DhcpIO) · 1 unmodified line
317 sys->sleep(1000);308 sys->sleep(1000);
318 continue;309 continue;
319 }310 }
320 if(n < Udphdrsize+236){311 if(n < Udphdrlen+236){
321 if(debug)312 if(debug)
322 sys->print("short read: %d\n", n);313 sys->print("short read: %d\n", n);
323 continue;314 continue;
324 }315 }
325 buf := abuf[Udphdrsize:n];316 buf := abuf[Udphdrlen:n];
326 n -= Udphdrsize;317 n -= Udphdrlen;
327 dhcp := ref Dhcp;318 dhcp := ref Dhcp;
328 dhcp.op = int buf[0];319 dhcp.op = int buf[0];
329 if(dhcp.op != Bootpreply){320 if(dhcp.op != Bootpreply){
@@ -342,7 +333,7 @@ dhcpreader(pidc: chan of int, srv: ref DhcpIO) · 12 unmodified lines
342 sys->print("dhcp: ignore dhcp op %d\n", dhcp.dhcpop);333 sys->print("dhcp: ignore dhcp op %d\n", dhcp.dhcpop);
343 continue;334 continue;
344 }335 }
345 dhcp.udphdr = abuf[0:Udphdrsize];336 dhcp.udphdr = abuf[0:Udphdrlen];
346 dhcp.htype = int buf[1];337 dhcp.htype = int buf[1];
347 hlen := int buf[2];338 hlen := int buf[2];
348 dhcp.hops = int buf[3];339 dhcp.hops = int buf[3];
@@ -411,7 +402,7 @@ newrequest(dest: IPaddr, bootfile: string, htype: int, haddr: array of byte, ipa · 62 unmodified lines
411{402{
412 dhcp := ref Dhcp;403 dhcp := ref Dhcp;
413 dhcp.op = Bootprequest;404 dhcp.op = Bootprequest;
414 hdr := array[Udphdrsize] of {* => byte 0};405 hdr := array[Udphdrlen] of {* => byte 0};
415 hdr[Udpraddr:] = dest.v6();406 hdr[Udpraddr:] = dest.v6();
416 put2(hdr, Udprport, 67);407 put2(hdr, Udprport, 67);
417 dhcp.udphdr = hdr;408 dhcp.udphdr = hdr;
@@ -449,7 +440,6 @@ udpannounce(net: string): (ref Sys->FD, string) · 31 unmodified lines
449 return (nil, sys->sprint("can't announce dhcp port: %r"));440 return (nil, sys->sprint("can't announce dhcp port: %r"));
450 if(sys->fprint(conn.cfd, "headers") < 0)441 if(sys->fprint(conn.cfd, "headers") < 0)
451 return (nil, sys->sprint("can't set headers mode on dhcp port: %r"));442 return (nil, sys->sprint("can't set headers mode on dhcp port: %r"));
452 sys->fprint(conn.cfd, "oldheaders");
453 conn.dfd = sys->open(conn.dir+"/data", Sys->ORDWR);443 conn.dfd = sys->open(conn.dir+"/data", Sys->ORDWR);
454 if(conn.dfd == nil)444 if(conn.dfd == nil)
455 return (nil, sys->sprint("can't open %s: %r", conn.dir+"/data"));445 return (nil, sys->sprint("can't open %s: %r", conn.dir+"/data"));
appl/lib/virgil.b+1−2
@@ -12,7 +12,7 @@ include "ip.m"; · 11 unmodified lines
12 12
13stderr: ref Sys->FD;13stderr: ref Sys->FD;
14done: int;14done: int;
15Udphdrsize: con IP->OUdphdrlen; # use oldheaders format for compatibility15Udphdrsize: con IP->Udphdrlen;
16Virgilport: con 2202;16Virgilport: con 2202;
17 17
18#18#
@@ -75,7 +75,6 @@ virgil(argv: list of string): string · 56 unmodified lines
75 return nil;75 return nil;
76 if(sys->fprint(c.cfd, "headers") < 0)76 if(sys->fprint(c.cfd, "headers") < 0)
77 return nil;77 return nil;
78 sys->fprint(c.cfd, "oldheaders");
79 c.dfd = sys->open(c.dir+"/data", sys->ORDWR);78 c.dfd = sys->open(c.dir+"/data", sys->ORDWR);
80 if(c.dfd == nil)79 if(c.dfd == nil)
81 return nil;80 return nil;
include/version.h+1−1
@@ -1 +1 @@
1#define VERSION "Fourth Edition (20070418)"1#define VERSION "Fourth Edition (20070510)"
man/3/ip+0−18
@@ -322,24 +322,6 @@ and if the local IP address corresponds to a valid local unicast interface, · 321 unmodified lines
322that address is used, otherwise the IP address of the transmitting interface322that address is used, otherwise the IP address of the transmitting interface
323is substituted.323is substituted.
324.TP324.TP
325.B oldheaders
326Set the connection to use an address header with IPv6 addressing
327on reads and writes of the data file,
328allowing a single connection to send datagrams to converse with
329many different destination addresses and ports.
330The 36 byte binary header appears before the data
331read or written.
332It contains: remote IP address, local IP address, remote port, and local port.
333The IP addresses are 16 bytes each in IPv6 format,
334the port addresses are 2 bytes each, all written in network (big-endian) order.
335On reads, the header gives the values from the incoming datagram,
336except that if the remote used a multicast destination address, the IP address
337of the receiving interface is substituted.
338On writes, the header provides the destination for the resulting datagram,
339and if the local IP address corresponds to a valid local unicast interface,
340that address is used, otherwise the IP address of the transmitting interface
341is substituted.
342.TP
343.B headers4325.B headers4
344Set the connection to use an address header with IPv4 addresses326Set the connection to use an address header with IPv4 addresses
345on reads and writes of the data file,327on reads and writes of the data file,