readipifc.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  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 <ctype.h>
  12. #include <ip.h>
  13. static Ipifc**
  14. _readoldipifc(char *buf, Ipifc **l, int index)
  15. {
  16. char *f[200];
  17. int i, n;
  18. Ipifc *ifc;
  19. Iplifc *lifc, **ll;
  20. /* allocate new interface */
  21. *l = ifc = mallocz(sizeof(Ipifc), 1);
  22. if(ifc == nil)
  23. return l;
  24. l = &ifc->next;
  25. ifc->index = index;
  26. n = tokenize(buf, f, nelem(f));
  27. if(n < 2)
  28. return l;
  29. strncpy(ifc->dev, f[0], sizeof ifc->dev);
  30. ifc->dev[sizeof(ifc->dev) - 1] = 0;
  31. ifc->mtu = strtoul(f[1], nil, 10);
  32. ll = &ifc->lifc;
  33. for(i = 2; n-i >= 7; i += 7){
  34. /* allocate new local address */
  35. *ll = lifc = mallocz(sizeof(Iplifc), 1);
  36. ll = &lifc->next;
  37. parseip(lifc->ip, f[i]);
  38. parseipmask(lifc->mask, f[i+1]);
  39. parseip(lifc->net, f[i+2]);
  40. ifc->pktin = strtoul(f[i+3], nil, 10);
  41. ifc->pktout = strtoul(f[i+4], nil, 10);
  42. ifc->errin = strtoul(f[i+5], nil, 10);
  43. ifc->errout = strtoul(f[i+6], nil, 10);
  44. }
  45. return l;
  46. }
  47. static char*
  48. findfield(char *name, char **f, int n)
  49. {
  50. int i;
  51. for(i = 0; i < n-1; i++)
  52. if(strcmp(f[i], name) == 0)
  53. return f[i+1];
  54. return "";
  55. }
  56. static Ipifc**
  57. _readipifc(char *file, Ipifc **l, int index)
  58. {
  59. int i, n, fd, lines;
  60. char buf[4*1024];
  61. char *line[32];
  62. char *f[64];
  63. Ipifc *ifc, **l0;
  64. Iplifc *lifc, **ll;
  65. /* read the file */
  66. fd = open(file, OREAD);
  67. if(fd < 0)
  68. return l;
  69. n = 0;
  70. while((i = read(fd, buf+n, sizeof(buf)-1-n)) > 0 && n < sizeof(buf) - 1)
  71. n += i;
  72. buf[n] = 0;
  73. close(fd);
  74. if(strncmp(buf, "device", 6) != 0)
  75. return _readoldipifc(buf, l, index);
  76. /* ignore ifcs with no associated device */
  77. if(strncmp(buf+6, " ", 2) == 0)
  78. return l;
  79. /* allocate new interface */
  80. *l = ifc = mallocz(sizeof(Ipifc), 1);
  81. if(ifc == nil)
  82. return l;
  83. l0 = l;
  84. l = &ifc->next;
  85. ifc->index = index;
  86. lines = getfields(buf, line, nelem(line), 1, "\n");
  87. /* pick off device specific info(first line) */
  88. n = tokenize(line[0], f, nelem(f));
  89. if(n%2 != 0)
  90. goto lose;
  91. strncpy(ifc->dev, findfield("device", f, n), sizeof(ifc->dev));
  92. ifc->dev[sizeof(ifc->dev)-1] = 0;
  93. if(ifc->dev[0] == 0){
  94. lose:
  95. free(ifc);
  96. *l0 = nil;
  97. return l;
  98. }
  99. ifc->mtu = strtoul(findfield("maxtu", f, n), nil, 10);
  100. ifc->sendra6 = atoi(findfield("sendra", f, n));
  101. ifc->recvra6 = atoi(findfield("recvra", f, n));
  102. ifc->rp.mflag = atoi(findfield("mflag", f, n));
  103. ifc->rp.oflag = atoi(findfield("oflag", f, n));
  104. ifc->rp.maxraint = atoi(findfield("maxraint", f, n));
  105. ifc->rp.minraint = atoi(findfield("minraint", f, n));
  106. ifc->rp.linkmtu = atoi(findfield("linkmtu", f, n));
  107. ifc->rp.reachtime = atoi(findfield("reachtime", f, n));
  108. ifc->rp.rxmitra = atoi(findfield("rxmitra", f, n));
  109. ifc->rp.ttl = atoi(findfield("ttl", f, n));
  110. ifc->rp.routerlt = atoi(findfield("routerlt", f, n));
  111. ifc->pktin = strtoul(findfield("pktin", f, n), nil, 10);
  112. ifc->pktout = strtoul(findfield("pktout", f, n), nil, 10);
  113. ifc->errin = strtoul(findfield("errin", f, n), nil, 10);
  114. ifc->errout = strtoul(findfield("errout", f, n), nil, 10);
  115. /* now read the addresses */
  116. ll = &ifc->lifc;
  117. for(i = 1; i < lines; i++){
  118. n = tokenize(line[i], f, nelem(f));
  119. if(n < 5)
  120. break;
  121. /* allocate new local address */
  122. *ll = lifc = mallocz(sizeof(Iplifc), 1);
  123. ll = &lifc->next;
  124. parseip(lifc->ip, f[0]);
  125. parseipmask(lifc->mask, f[1]);
  126. parseip(lifc->net, f[2]);
  127. lifc->validlt = strtoul(f[3], nil, 10);
  128. lifc->preflt = strtoul(f[4], nil, 10);
  129. }
  130. return l;
  131. }
  132. static void
  133. _freeifc(Ipifc *ifc)
  134. {
  135. Ipifc *next;
  136. Iplifc *lnext, *lifc;
  137. if(ifc == nil)
  138. return;
  139. for(; ifc; ifc = next){
  140. next = ifc->next;
  141. for(lifc = ifc->lifc; lifc; lifc = lnext){
  142. lnext = lifc->next;
  143. free(lifc);
  144. }
  145. free(ifc);
  146. }
  147. }
  148. Ipifc*
  149. readipifc(char *net, Ipifc *ifc, int index)
  150. {
  151. int fd, i, n;
  152. Dir *dir;
  153. char directory[128];
  154. char buf[128];
  155. Ipifc **l;
  156. _freeifc(ifc);
  157. l = &ifc;
  158. ifc = nil;
  159. if(net == 0)
  160. net = "/net";
  161. snprint(directory, sizeof(directory), "%s/ipifc", net);
  162. if(index >= 0){
  163. snprint(buf, sizeof(buf), "%s/%d/status", directory, index);
  164. _readipifc(buf, l, index);
  165. } else {
  166. fd = open(directory, OREAD);
  167. if(fd < 0)
  168. return nil;
  169. n = dirreadall(fd, &dir);
  170. close(fd);
  171. for(i = 0; i < n; i++){
  172. if(strcmp(dir[i].name, "clone") == 0)
  173. continue;
  174. if(strcmp(dir[i].name, "stats") == 0)
  175. continue;
  176. snprint(buf, sizeof(buf), "%s/%s/status", directory, dir[i].name);
  177. l = _readipifc(buf, l, atoi(dir[i].name));
  178. }
  179. free(dir);
  180. }
  181. return ifc;
  182. }