ifconfig.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <errno.h>
  5. #include <string.h>
  6. #include <ctype.h>
  7. #include <sys/ioctl.h>
  8. #include <sys/socket.h>
  9. #include <netinet/in.h>
  10. #include <linux/if.h>
  11. #include <linux/sockios.h>
  12. #include <arpa/inet.h>
  13. static void die(const char *s)
  14. {
  15. fprintf(stderr,"error: %s (%s)\n", s, strerror(errno));
  16. exit(-1);
  17. }
  18. static void setflags(int s, struct ifreq *ifr, int set, int clr)
  19. {
  20. if(ioctl(s, SIOCGIFFLAGS, ifr) < 0) die("SIOCGIFFLAGS");
  21. ifr->ifr_flags = (ifr->ifr_flags & (~clr)) | set;
  22. if(ioctl(s, SIOCSIFFLAGS, ifr) < 0) die("SIOCSIFFLAGS");
  23. }
  24. static inline void init_sockaddr_in(struct sockaddr_in *sin, const char *addr)
  25. {
  26. sin->sin_family = AF_INET;
  27. sin->sin_port = 0;
  28. sin->sin_addr.s_addr = inet_addr(addr);
  29. }
  30. static void setmtu(int s, struct ifreq *ifr, const char *mtu)
  31. {
  32. int m = atoi(mtu);
  33. ifr->ifr_mtu = m;
  34. if(ioctl(s, SIOCSIFMTU, ifr) < 0) die("SIOCSIFMTU");
  35. }
  36. static void setdstaddr(int s, struct ifreq *ifr, const char *addr)
  37. {
  38. init_sockaddr_in((struct sockaddr_in *) &ifr->ifr_dstaddr, addr);
  39. if(ioctl(s, SIOCSIFDSTADDR, ifr) < 0) die("SIOCSIFDSTADDR");
  40. }
  41. static void setnetmask(int s, struct ifreq *ifr, const char *addr)
  42. {
  43. init_sockaddr_in((struct sockaddr_in *) &ifr->ifr_netmask, addr);
  44. if(ioctl(s, SIOCSIFNETMASK, ifr) < 0) die("SIOCSIFNETMASK");
  45. }
  46. static void setaddr(int s, struct ifreq *ifr, const char *addr)
  47. {
  48. init_sockaddr_in((struct sockaddr_in *) &ifr->ifr_addr, addr);
  49. if(ioctl(s, SIOCSIFADDR, ifr) < 0) die("SIOCSIFADDR");
  50. }
  51. int main(int argc, char *argv[])
  52. {
  53. struct ifreq ifr;
  54. int s;
  55. unsigned int addr, mask, flags;
  56. char astring[20];
  57. char mstring[20];
  58. char *updown, *brdcst, *loopbk, *ppp, *running, *multi;
  59. argc--;
  60. argv++;
  61. if(argc == 0) return 0;
  62. memset(&ifr, 0, sizeof(struct ifreq));
  63. strncpy(ifr.ifr_name, argv[0], IFNAMSIZ);
  64. ifr.ifr_name[IFNAMSIZ-1] = 0;
  65. argc--, argv++;
  66. if((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  67. die("cannot open control socket\n");
  68. }
  69. if (argc == 0) {
  70. if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
  71. perror(ifr.ifr_name);
  72. return -1;
  73. } else
  74. addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
  75. if (ioctl(s, SIOCGIFNETMASK, &ifr) < 0) {
  76. perror(ifr.ifr_name);
  77. return -1;
  78. } else
  79. mask = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
  80. if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0) {
  81. perror(ifr.ifr_name);
  82. return -1;
  83. } else
  84. flags = ifr.ifr_flags;
  85. sprintf(astring, "%d.%d.%d.%d",
  86. addr & 0xff,
  87. ((addr >> 8) & 0xff),
  88. ((addr >> 16) & 0xff),
  89. ((addr >> 24) & 0xff));
  90. sprintf(mstring, "%d.%d.%d.%d",
  91. mask & 0xff,
  92. ((mask >> 8) & 0xff),
  93. ((mask >> 16) & 0xff),
  94. ((mask >> 24) & 0xff));
  95. printf("%s: ip %s mask %s flags [", ifr.ifr_name,
  96. astring,
  97. mstring
  98. );
  99. updown = (flags & IFF_UP) ? "up" : "down";
  100. brdcst = (flags & IFF_BROADCAST) ? " broadcast" : "";
  101. loopbk = (flags & IFF_LOOPBACK) ? " loopback" : "";
  102. ppp = (flags & IFF_POINTOPOINT) ? " point-to-point" : "";
  103. running = (flags & IFF_RUNNING) ? " running" : "";
  104. multi = (flags & IFF_MULTICAST) ? " multicast" : "";
  105. printf("%s%s%s%s%s%s]\n", updown, brdcst, loopbk, ppp, running, multi);
  106. return 0;
  107. }
  108. while(argc > 0) {
  109. if (!strcmp(argv[0], "up")) {
  110. setflags(s, &ifr, IFF_UP, 0);
  111. } else if (!strcmp(argv[0], "mtu")) {
  112. argc--, argv++;
  113. if (!argc) {
  114. errno = EINVAL;
  115. die("expecting a value for parameter \"mtu\"");
  116. }
  117. setmtu(s, &ifr, argv[0]);
  118. } else if (!strcmp(argv[0], "-pointopoint")) {
  119. setflags(s, &ifr, IFF_POINTOPOINT, 1);
  120. } else if (!strcmp(argv[0], "pointopoint")) {
  121. argc--, argv++;
  122. if (!argc) {
  123. errno = EINVAL;
  124. die("expecting an IP address for parameter \"pointtopoint\"");
  125. }
  126. setdstaddr(s, &ifr, argv[0]);
  127. setflags(s, &ifr, IFF_POINTOPOINT, 0);
  128. } else if (!strcmp(argv[0], "down")) {
  129. setflags(s, &ifr, 0, IFF_UP);
  130. } else if (!strcmp(argv[0], "netmask")) {
  131. argc--, argv++;
  132. if (!argc) {
  133. errno = EINVAL;
  134. die("expecting an IP address for parameter \"netmask\"");
  135. }
  136. setnetmask(s, &ifr, argv[0]);
  137. } else if (isdigit(argv[0][0])) {
  138. setaddr(s, &ifr, argv[0]);
  139. setflags(s, &ifr, IFF_UP, 0);
  140. }
  141. argc--, argv++;
  142. }
  143. return 0;
  144. }