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