123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- #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;
- }
|