rarpd.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include <ip.h>
  5. #include <ndb.h>
  6. #include "arp.h"
  7. typedef struct Rarp Rarp;
  8. struct Rarp
  9. {
  10. uchar edst[6];
  11. uchar esrc[6];
  12. uchar type[2];
  13. uchar hrd[2];
  14. uchar pro[2];
  15. uchar hln;
  16. uchar pln;
  17. uchar op[2];
  18. uchar sha[6];
  19. uchar spa[4];
  20. uchar tha[6];
  21. uchar tpa[4];
  22. };
  23. uchar myip[IPaddrlen];
  24. uchar myether[6];
  25. char rlog[] = "ipboot";
  26. char *device = "ether0";
  27. int debug;
  28. Ndb *db;
  29. char* lookup(char*, char*, char*, char*, int);
  30. void
  31. error(char *s)
  32. {
  33. syslog(1, rlog, "error %s: %r", s);
  34. exits(s);
  35. }
  36. char net[32];
  37. void
  38. usage(void)
  39. {
  40. fprint(2, "usage: %s [-e device] [-x netmtpt] [-f ndb-file] [-d]\n", argv0);
  41. exits("usage");
  42. }
  43. void
  44. main(int argc, char *argv[])
  45. {
  46. int edata, ectl;
  47. uchar buf[2048];
  48. long n;
  49. Rarp *rp;
  50. char ebuf[16];
  51. char ipbuf[64];
  52. char file[128];
  53. int arp;
  54. char *p, *ndbfile;
  55. ndbfile = nil;
  56. setnetmtpt(net, sizeof(net), nil);
  57. ARGBEGIN{
  58. case 'e':
  59. p = ARGF();
  60. if(p == nil)
  61. usage();
  62. device = p;
  63. break;
  64. case 'd':
  65. debug = 1;
  66. break;
  67. case 'f':
  68. p = ARGF();
  69. if(p == nil)
  70. usage();
  71. ndbfile = p;
  72. break;
  73. case 'x':
  74. p = ARGF();
  75. if(p == nil)
  76. usage();
  77. setnetmtpt(net, sizeof(net), p);
  78. break;
  79. }ARGEND
  80. USED(argc, argv);
  81. fmtinstall('E', eipfmt);
  82. fmtinstall('I', eipfmt);
  83. fmtinstall('V', eipfmt);
  84. db = ndbopen(ndbfile);
  85. if(db == 0)
  86. error("can't open the database");
  87. edata = dial(netmkaddr("0x8035", device, 0), 0, 0, &ectl);
  88. if(edata < 0)
  89. error("can't open ethernet");
  90. if(myipaddr(myip, net) < 0)
  91. error("can't get my ip address");
  92. sprint(ebuf, "%s/%s", net, device);
  93. if(myetheraddr(myether, ebuf) < 0)
  94. error("can't get my ether address");
  95. snprint(file, sizeof(file), "%s/arp", net);
  96. if((arp = open(file, ORDWR)) < 0)
  97. fprint(2, "rarpd: can't open %s\n", file);
  98. switch(rfork(RFNOTEG|RFPROC|RFFDG)) {
  99. case -1:
  100. error("fork");
  101. case 0:
  102. break;
  103. default:
  104. exits(0);
  105. }
  106. for(;;){
  107. n = read(edata, buf, sizeof(buf));
  108. if(n <= 0)
  109. error("reading");
  110. if(n < sizeof(Rarp)){
  111. syslog(debug, rlog, "bad packet size %ld", n);
  112. continue;
  113. }
  114. rp = (Rarp*)buf;
  115. if(rp->op[0]!=0 && rp->op[1]!=3){
  116. syslog(debug, rlog, "bad op %d %d %E",
  117. rp->op[1], rp->op[0], rp->esrc);
  118. continue;
  119. }
  120. if(debug)
  121. syslog(debug, rlog, "rcv se %E si %V te %E ti %V",
  122. rp->sha, rp->spa, rp->tha, rp->tpa);
  123. sprint(ebuf, "%E", rp->tha);
  124. if(lookup("ether", ebuf, "ip", ipbuf, sizeof ipbuf) == nil){
  125. syslog(debug, rlog, "client lookup failed: %s", ebuf);
  126. continue;
  127. }
  128. v4parseip(rp->tpa, ipbuf);
  129. memmove(rp->sha, myether, sizeof(rp->sha));
  130. v6tov4(rp->spa, myip);
  131. rp->op[0] = 0;
  132. rp->op[1] = 4;
  133. memmove(rp->edst, rp->esrc, sizeof(rp->edst));
  134. if(debug)
  135. syslog(debug, rlog, "send se %E si %V te %E ti %V",
  136. rp->sha, rp->spa, rp->tha, rp->tpa);
  137. if(write(edata, buf, 60) != 60)
  138. error("write failed");
  139. if(arp < 0)
  140. continue;
  141. if(fprint(arp, "add %E %V", rp->esrc, rp->tpa) < 0)
  142. fprint(2, "can't write arp entry\n");
  143. }
  144. }
  145. char*
  146. lookup(char *sattr, char *sval, char *tattr, char *tval, int len)
  147. {
  148. static Ndb *db;
  149. char *attrs[1];
  150. Ndbtuple *t;
  151. if(db == nil)
  152. db = ndbopen(0);
  153. if(db == nil)
  154. return nil;
  155. if(sattr == nil)
  156. sattr = ipattr(sval);
  157. attrs[0] = tattr;
  158. t = ndbipinfo(db, sattr, sval, attrs, 1);
  159. if(t == nil)
  160. return nil;
  161. strncpy(tval, t->val, len);
  162. tval[len-1] = 0;
  163. ndbfree(t);
  164. return tval;
  165. }