readipifc.c 4.3 KB

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