diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/ip/rarpd.c |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/ip/rarpd.c')
-rwxr-xr-x | sys/src/cmd/ip/rarpd.c | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/sys/src/cmd/ip/rarpd.c b/sys/src/cmd/ip/rarpd.c new file mode 100755 index 000000000..22c281ec9 --- /dev/null +++ b/sys/src/cmd/ip/rarpd.c @@ -0,0 +1,192 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include <ip.h> +#include <ndb.h> +#include "arp.h" + +typedef struct Rarp Rarp; + +struct Rarp +{ + uchar edst[6]; + uchar esrc[6]; + uchar type[2]; + uchar hrd[2]; + uchar pro[2]; + uchar hln; + uchar pln; + uchar op[2]; + uchar sha[6]; + uchar spa[4]; + uchar tha[6]; + uchar tpa[4]; +}; + +uchar myip[IPaddrlen]; +uchar myether[6]; +char rlog[] = "ipboot"; +char *device = "ether0"; +int debug; +Ndb *db; + +char* lookup(char*, char*, char*, char*, int); + +void +error(char *s) +{ + syslog(1, rlog, "error %s: %r", s); + exits(s); +} + +char net[32]; + +void +usage(void) +{ + fprint(2, "usage: %s [-e device] [-x netmtpt] [-f ndb-file] [-d]\n", argv0); + exits("usage"); +} + +void +main(int argc, char *argv[]) +{ + int edata, ectl; + uchar buf[2048]; + long n; + Rarp *rp; + char ebuf[16]; + char ipbuf[64]; + char file[128]; + int arp; + char *p, *ndbfile; + + ndbfile = nil; + setnetmtpt(net, sizeof(net), nil); + ARGBEGIN{ + case 'e': + p = ARGF(); + if(p == nil) + usage(); + device = p; + break; + case 'd': + debug = 1; + break; + case 'f': + p = ARGF(); + if(p == nil) + usage(); + ndbfile = p; + break; + case 'x': + p = ARGF(); + if(p == nil) + usage(); + setnetmtpt(net, sizeof(net), p); + break; + }ARGEND + USED(argc, argv); + + fmtinstall('E', eipfmt); + fmtinstall('I', eipfmt); + fmtinstall('V', eipfmt); + + db = ndbopen(ndbfile); + if(db == 0) + error("can't open the database"); + + edata = dial(netmkaddr("0x8035", device, 0), 0, 0, &ectl); + if(edata < 0) + error("can't open ethernet"); + + if(myipaddr(myip, net) < 0) + error("can't get my ip address"); + sprint(ebuf, "%s/%s", net, device); + if(myetheraddr(myether, ebuf) < 0) + error("can't get my ether address"); + + snprint(file, sizeof(file), "%s/arp", net); + if((arp = open(file, ORDWR)) < 0) + fprint(2, "rarpd: can't open %s\n", file); + + switch(rfork(RFNOTEG|RFPROC|RFFDG)) { + case -1: + error("fork"); + case 0: + break; + default: + exits(0); + } + + for(;;){ + n = read(edata, buf, sizeof(buf)); + if(n <= 0) + error("reading"); + if(n < sizeof(Rarp)){ + syslog(debug, rlog, "bad packet size %ld", n); + continue; + } + rp = (Rarp*)buf; + if(rp->op[0]!=0 && rp->op[1]!=3){ + syslog(debug, rlog, "bad op %d %d %E", + rp->op[1], rp->op[0], rp->esrc); + continue; + } + + if(debug) + syslog(debug, rlog, "rcv se %E si %V te %E ti %V", + rp->sha, rp->spa, rp->tha, rp->tpa); + + sprint(ebuf, "%E", rp->tha); + if(lookup("ether", ebuf, "ip", ipbuf, sizeof ipbuf) == nil){ + syslog(debug, rlog, "client lookup failed: %s", ebuf); + continue; + } + v4parseip(rp->tpa, ipbuf); + + memmove(rp->sha, myether, sizeof(rp->sha)); + v6tov4(rp->spa, myip); + + rp->op[0] = 0; + rp->op[1] = 4; + memmove(rp->edst, rp->esrc, sizeof(rp->edst)); + + if(debug) + syslog(debug, rlog, "send se %E si %V te %E ti %V", + rp->sha, rp->spa, rp->tha, rp->tpa); + + if(write(edata, buf, 60) != 60) + error("write failed"); + + if(arp < 0) + continue; + if(fprint(arp, "add %E %V", rp->esrc, rp->tpa) < 0) + fprint(2, "can't write arp entry\n"); + } +} + +char* +lookup(char *sattr, char *sval, char *tattr, char *tval, int len) +{ + static Ndb *db; + char *attrs[1]; + Ndbtuple *t; + + if(db == nil) + db = ndbopen(0); + if(db == nil) + return nil; + + if(sattr == nil) + sattr = ipattr(sval); + + attrs[0] = tattr; + t = ndbipinfo(db, sattr, sval, attrs, 1); + if(t == nil) + return nil; + strncpy(tval, t->val, len); + tval[len-1] = 0; + ndbfree(t); + return tval; +} |