summaryrefslogtreecommitdiff
path: root/sys/src/cmd/ip/rarpd.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /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-xsys/src/cmd/ip/rarpd.c192
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;
+}