readipifc.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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;
  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. /* allocate new interface */
  69. *l = ifc = mallocz(sizeof(Ipifc), 1);
  70. if(ifc == nil)
  71. return l;
  72. l = &ifc->next;
  73. ifc->index = index;
  74. lines = getfields(buf, line, nelem(line), 1, "\n");
  75. /* pick off device specific info(first line) */
  76. n = tokenize(line[0], f, nelem(f));
  77. strncpy(ifc->dev, findfield("device", f, n), sizeof(ifc->dev));
  78. ifc->dev[sizeof(ifc->dev)-1] = 0;
  79. if(ifc->dev[0] == 0){
  80. free(ifc);
  81. return l;
  82. }
  83. ifc->mtu = strtoul(findfield("maxmtu", f, n), nil, 10);
  84. ifc->sendra6 = atoi(findfield("sendra", f, n));
  85. ifc->recvra6 = atoi(findfield("recvra", f, n));
  86. ifc->rp.mflag = atoi(findfield("mflag", f, n));
  87. ifc->rp.oflag = atoi(findfield("oflag", f, n));
  88. ifc->rp.maxraint = atoi(findfield("maxraint", f, n));
  89. ifc->rp.minraint = atoi(findfield("minraint", f, n));
  90. ifc->rp.linkmtu = atoi(findfield("linkmtu", f, n));
  91. ifc->rp.reachtime = atoi(findfield("reachtime", f, n));
  92. ifc->rp.rxmitra = atoi(findfield("rxmitra", f, n));
  93. ifc->rp.ttl = atoi(findfield("ttl", f, n));
  94. ifc->rp.routerlt = atoi(findfield("routerlt", f, n));
  95. ifc->pktin = strtoul(findfield("pktin", f, n), nil, 10);
  96. ifc->pktout = strtoul(findfield("pktout", f, n), nil, 10);
  97. ifc->errin = strtoul(findfield("errin", f, n), nil, 10);
  98. ifc->errout = strtoul(findfield("errout", f, n), nil, 10);
  99. /* now read the addresses */
  100. ll = &ifc->lifc;
  101. for(i = 1; i < lines; i++){
  102. n = tokenize(line[i], f, nelem(f));
  103. if(n < 5)
  104. break;
  105. /* allocate new local address */
  106. *ll = lifc = mallocz(sizeof(Iplifc), 1);
  107. ll = &lifc->next;
  108. parseip(lifc->ip, f[0]);
  109. parseipmask(lifc->mask, f[1]);
  110. parseip(lifc->net, f[2]);
  111. lifc->validlt = strtoul(f[3], nil, 10);
  112. lifc->preflt = strtoul(f[4], nil, 10);
  113. }
  114. return l;
  115. }
  116. static void
  117. _freeifc(Ipifc *ifc)
  118. {
  119. Ipifc *next;
  120. Iplifc *lnext, *lifc;
  121. if(ifc == nil)
  122. return;
  123. for(; ifc; ifc = next){
  124. next = ifc->next;
  125. for(lifc = ifc->lifc; lifc; lifc = lnext){
  126. lnext = lifc->next;
  127. free(lifc);
  128. }
  129. free(ifc);
  130. }
  131. }
  132. Ipifc*
  133. readipifc(char *net, Ipifc *ifc, int index)
  134. {
  135. int fd, i, n;
  136. Dir *dir;
  137. char directory[128];
  138. char buf[128];
  139. Ipifc **l;
  140. _freeifc(ifc);
  141. l = &ifc;
  142. ifc = nil;
  143. if(net == 0)
  144. net = "/net";
  145. snprint(directory, sizeof(directory), "%s/ipifc", net);
  146. if(index >= 0){
  147. snprint(buf, sizeof(buf), "%s/%d/status", directory, index);
  148. _readipifc(buf, l, index);
  149. } else {
  150. fd = open(directory, OREAD);
  151. if(fd < 0)
  152. return nil;
  153. n = dirreadall(fd, &dir);
  154. close(fd);
  155. for(i = 0; i < n; i++){
  156. if(strcmp(dir[i].name, "clone") == 0)
  157. continue;
  158. if(strcmp(dir[i].name, "stats") == 0)
  159. continue;
  160. snprint(buf, sizeof(buf), "%s/%s/status", directory, dir[i].name);
  161. l = _readipifc(buf, l, atoi(dir[i].name));
  162. }
  163. free(dir);
  164. }
  165. return ifc;
  166. }