xref: /inferno-os/appl/lib/ether.b (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1implement Ether;
2
3include "sys.m";
4	sys: Sys;
5
6include "ether.m";
7
8init()
9{
10	sys = load Sys Sys->PATH;
11}
12
13parse(s: string): array of byte
14{
15	a := array[Eaddrlen] of byte;
16	for(i := 0; i < len a; i++){
17		n: int;
18		(n, s) = hex(s);
19		if(n < 0){
20			sys->werrstr("invalid ether address");
21			return nil;
22		}
23		a[i] = byte n;
24		if(s != nil && s[0] == ':')
25			s = s[1:];
26	}
27	return a;
28}
29
30hex(s: string): (int, string)
31{
32	n := 0;
33	for(i := 0; i < len s && i < 2; i++){
34		if((c := s[i]) >= '0' && c <= '9')
35			c -= '0';
36		else if(c >= 'a' && c <= 'f')
37			c += 10 - 'a';
38		else if(c >= 'A' && c <= 'F')
39			c += 10 - 'A';
40		else if(c == ':')
41			break;
42		else
43			return (-1, s);
44		n = (n<<4) | c;
45	}
46	if(i == 0)
47		return (-1, s);
48	return (n, s[i:]);
49}
50
51text(a: array of byte): string
52{
53	if(len a < Eaddrlen)
54		return "<invalid>";
55	return sys->sprint("%.2ux%.2ux%.2ux%.2ux%.2ux%.2ux",
56		int a[0], int a[1], int a[2], int a[3], int a[4], int a[5]);
57}
58
59addressof(dev: string): array of byte
60{
61	if(dev != nil && dev[0] != '/')
62		dev = "/net/"+dev;
63	fd := sys->open(dev+"/addr", Sys->OREAD);
64	if(fd == nil)
65		return nil;
66	buf := array[64] of byte;
67	n := sys->read(fd, buf, len buf);
68	if(n <= 0)
69		return nil;
70	if(n > 0 && buf[n-1] == byte '\n')
71		n--;
72	return parse(string buf[0:n]);
73}
74
75eqaddr(a: array of byte, b: array of byte): int
76{
77	if(len a != len b)
78		return 0;
79	for(i := 0; i < len a; i++)
80		if(a[i] != b[i])
81			return 0;
82	return 1;
83}
84