rarpd.c 3.7 KB

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