ifls.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343
  1. /*
  2. * test programs, list all interfaces and their ip address
  3. *
  4. * Copyright (C) 2001-2003 FhG Fokus
  5. *
  6. * This file is part of Kamailio, a free SIP server.
  7. *
  8. * Kamailio is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation; either version 2 of the License, or
  11. * (at your option) any later version
  12. *
  13. * Kamailio is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  21. */
  22. /*
  23. * History:
  24. * --------
  25. * 2002-09-09 created by andrei
  26. */
  27. #include <sys/types.h>
  28. #include <sys/socket.h>
  29. #include <netinet/in.h>
  30. #include <sys/ioctl.h>
  31. #include <net/if.h>
  32. #ifdef __sun__
  33. #include <sys/sockio.h>
  34. #endif
  35. #include <stdio.h>
  36. #include <stdlib.h>
  37. #include <ctype.h>
  38. #include <string.h>
  39. #include <unistd.h>
  40. #include <errno.h>
  41. #define FLAGS 1
  42. #define IF_DOWN 2
  43. #define IF_UP 4
  44. static char* version="ifls 0.1";
  45. static char* id="$Id$";
  46. static char* help_msg="\
  47. Usage: ifls [-6hV} [interface...]\n\
  48. (if no interface name is specified it will list all the interfaces)\n\
  49. Options:\n\
  50. -a list both ipv4 and ipv6 interfaces (default)\n\
  51. -4 list only ipv4 interfaces\n\
  52. -6 list only ipv6 interfaces\n\
  53. -f show also the interface flags\n\
  54. -U brings all the matching interfaces up\n\
  55. -D brings all the matching interfaces down\n\
  56. -V version number\n\
  57. -h this help message\n\
  58. ";
  59. #define MAX(a,b) ( ((a)>(b))?(a):(b))
  60. void print_sockaddr(struct sockaddr* sa)
  61. {
  62. unsigned char* buf;
  63. int r;
  64. switch(sa->sa_family){
  65. case AF_INET:
  66. buf=(char*)&(((struct sockaddr_in*)sa)->sin_addr).s_addr;
  67. printf("%d.%d.%d.%d\n", buf[0], buf[1], buf[2], buf[3]);
  68. break;
  69. case AF_INET6:
  70. buf=(((struct sockaddr_in6*)sa)->sin6_addr).s6_addr;
  71. for(r=0; r<16; r++)
  72. printf("%02x%s", buf[r], ((r%2)&&(r!=15))?":":"" );
  73. printf("\n");
  74. break;
  75. default:
  76. printf("unknown af %d\n", sa->sa_family);
  77. #ifdef __FreeBSD__
  78. for (r=0; r<sa->sa_len; r++)
  79. printf("%02x ", ((unsigned char*)sa)[r]);
  80. printf("\n");
  81. #endif
  82. }
  83. }
  84. int ls_ifflags(char* name, int family , int options)
  85. {
  86. struct ifreq ifr;
  87. int s;
  88. memset(&ifr, 0, sizeof(ifr)); /* init to 0 (check if filled)*/
  89. s=socket(family, SOCK_DGRAM, 0);
  90. strncpy(ifr.ifr_name, name, IFNAMSIZ);
  91. #if 0
  92. if (ioctl(s, SIOCGIFADDR, &ifr)==-1){
  93. if(errno==EBADF) return 0; /* invalid descriptor => no address*/
  94. fprintf(stderr, "ls_if: ioctl for %s failed: %s\n", name,
  95. strerror(errno));
  96. goto error;
  97. };
  98. printf("%s:\n", ifr.ifr_name);
  99. printf(" dbg: family=%d", ifr.ifr_addr.sa_family);
  100. #ifdef __FreeBSD__
  101. printf(", len=%d\n", ifr.ifr_addr.sa_len);
  102. #else
  103. printf("\n");
  104. #endif
  105. if (ifr.ifr_addr.sa_family==0){
  106. printf("ls_if: OS BUG: SIOCGIFADDR doesn't work!\n");
  107. goto error;
  108. }
  109. printf(" ");
  110. print_sockaddr(&ifr.ifr_addr);
  111. if (ifr.ifr_addr.sa_family!=family){
  112. printf("ls_if: strange family %d\n", ifr.ifr_addr.sa_family);
  113. /*goto error;*/
  114. }
  115. #endif
  116. if (options & (FLAGS|IF_DOWN|IF_UP)){
  117. if (ioctl(s, SIOCGIFFLAGS, &ifr)==-1){
  118. fprintf(stderr, "ls_if: flags ioctl for %s failed: %s\n",
  119. name, strerror(errno));
  120. goto error;
  121. }
  122. if (ifr.ifr_flags & IFF_UP) printf ("UP ");
  123. if (ifr.ifr_flags & IFF_BROADCAST) printf ("BROADCAST ");
  124. if (ifr.ifr_flags & IFF_DEBUG) printf ("DEBUG ");
  125. if (ifr.ifr_flags & IFF_LOOPBACK) printf ("LOOPBACK ");
  126. if (ifr.ifr_flags & IFF_POINTOPOINT) printf ("POINTOPOINT ");
  127. if (ifr.ifr_flags & IFF_RUNNING) printf ("RUNNING ");
  128. if (ifr.ifr_flags & IFF_NOARP) printf ("NOARP ");
  129. if (ifr.ifr_flags & IFF_PROMISC) printf ("PROMISC ");
  130. /*if (ifr.ifr_flags & IFF_NOTRAILERS) printf ("NOTRAILERS ");*/
  131. if (ifr.ifr_flags & IFF_ALLMULTI) printf ("ALLMULTI ");
  132. /*if (ifr.ifr_flags & IFF_MASTER) printf ("MASTER ");*/
  133. /*if (ifr.ifr_flags & IFF_SLAVE) printf ("SLAVE ");*/
  134. if (ifr.ifr_flags & IFF_MULTICAST) printf ("MULTICAST ");
  135. /*if (ifr.ifr_flags & IFF_PORTSEL) printf ("PORTSEL ");*/
  136. /*if (ifr.ifr_flags & IFF_AUTOMEDIA) printf ("AUTOMEDIA ");*/
  137. /*if (ifr.ifr_flags & IFF_DYNAMIC ) printf ("DYNAMIC ");*/
  138. printf ("\n");
  139. if (options & IF_DOWN){
  140. ifr.ifr_flags &= ~IFF_UP;
  141. }
  142. if (options & IF_UP){
  143. ifr.ifr_flags |= IFF_UP;
  144. }
  145. if (options & (IF_UP|IF_DOWN)){
  146. if (ioctl(s, SIOCSIFFLAGS, &ifr)==-1){
  147. fprintf(stderr, "ls_if: set flags ioctl for %s failed: %s\n",
  148. name, strerror(errno));
  149. goto error;
  150. }
  151. }
  152. };
  153. close(s);
  154. return 0;
  155. error:
  156. close(s);
  157. return -1;
  158. }
  159. int ls_ifs(char* name, int family, int options)
  160. {
  161. struct ifconf ifc;
  162. struct ifreq* ifr;
  163. char* last;
  164. int size;
  165. int lastlen;
  166. int s;
  167. /* ipv4 or ipv6 only*/
  168. s=socket(family, SOCK_DGRAM, 0);
  169. lastlen=0;
  170. for (size=2; ; size*=2){
  171. ifc.ifc_len=size*sizeof(struct ifreq);
  172. ifc.ifc_req=(struct ifreq*) malloc(size*sizeof(struct ifreq));
  173. if (ifc.ifc_req==0){
  174. fprintf(stderr, "memory allocation failure\n");
  175. goto error;
  176. }
  177. if (ioctl(s, SIOCGIFCONF, &ifc)==-1){
  178. if(errno==EBADF) return 0; /* invalid descriptor => no such ifs*/
  179. fprintf(stderr, "ioctl failed: %s\n", strerror(errno));
  180. goto error;
  181. }
  182. if ((lastlen) && (ifc.ifc_len==lastlen)) break; /*success,
  183. len not changed*/
  184. lastlen=ifc.ifc_len;
  185. /* try a bigger array*/
  186. free(ifc.ifc_req);
  187. }
  188. last=(char*)ifc.ifc_req+ifc.ifc_len;
  189. for(ifr=ifc.ifc_req; (char*)ifr<last;
  190. ifr=(struct ifreq*)((char*)ifr+sizeof(ifr->ifr_name)+
  191. #ifdef __FreeBSD__
  192. MAX(ifr->ifr_addr.sa_len, sizeof(struct sockaddr))
  193. #else
  194. ( (ifr->ifr_addr.sa_family==AF_INET)?
  195. sizeof(struct sockaddr_in):
  196. ((ifr->ifr_addr.sa_family==AF_INET6)?
  197. sizeof(struct sockaddr_in6):sizeof(struct sockaddr)) )
  198. #endif
  199. )
  200. )
  201. {
  202. /*
  203. printf("\nls_all dbg: %s family=%d", ifr->ifr_name,
  204. ifr->ifr_addr.sa_family);
  205. #ifdef __FreeBSD__
  206. printf(", len=%d\n", ifr->ifr_addr.sa_len);
  207. #else
  208. printf("\n");
  209. #endif
  210. */
  211. if (ifr->ifr_addr.sa_family!=family){
  212. /*printf("strange family %d skipping...\n",
  213. ifr->ifr_addr.sa_family);*/
  214. continue;
  215. }
  216. if ((name==0)||
  217. (strncmp(name, ifr->ifr_name, sizeof(ifr->ifr_name))==0)){
  218. printf("%s:\n", ifr->ifr_name);
  219. printf(" ");
  220. print_sockaddr(&(ifr->ifr_addr));
  221. printf(" ");
  222. ls_ifflags(ifr->ifr_name, family, options);
  223. printf("\n");
  224. }
  225. }
  226. free(ifc.ifc_req); /*clean up*/
  227. close(s);
  228. return 0;
  229. error:
  230. close(s);
  231. return -1;
  232. }
  233. int main(int argc, char**argv)
  234. {
  235. char** name;
  236. int no;
  237. int options;
  238. int ipv6, ipv4;
  239. int r;
  240. char c;
  241. options=0;
  242. ipv6=ipv4=1;
  243. name=0;
  244. no=0;
  245. opterr=0;
  246. while((c=getopt(argc, argv, "a46fhVUD"))!=-1){
  247. switch(c){
  248. case 'a':
  249. ipv6=ipv4=1;
  250. break;
  251. case '4':
  252. ipv6=0;
  253. ipv4=1;
  254. break;
  255. case '6':
  256. ipv4=0;
  257. ipv6=1;
  258. break;
  259. case 'f':
  260. options|=FLAGS;
  261. break;
  262. case 'V':
  263. printf("version: %s\n", version);
  264. printf("%s\n", id);
  265. exit(0);
  266. break;
  267. case 'D':
  268. options|=IF_DOWN;
  269. break;
  270. case 'U':
  271. options|=IF_UP;
  272. break;
  273. case 'h':
  274. printf("version: %s\n", version);
  275. printf("%s", help_msg);
  276. exit(0);
  277. break;
  278. case '?':
  279. if (isprint(optopt))
  280. fprintf(stderr, "Unknown option `-%c´\n", optopt);
  281. else
  282. fprintf(stderr, "Unknown character `\\x%x´\n", optopt);
  283. goto error;
  284. case ':':
  285. fprintf(stderr, "Option `-%c´ requires an argument\n",
  286. optopt);
  287. goto error;
  288. default:
  289. abort();
  290. };
  291. };
  292. /* check if we have non-options */
  293. if( optind < argc){
  294. no=argc-optind;
  295. name=&argv[optind];
  296. }
  297. if (no==0){
  298. /* list all interfaces */
  299. if (ipv4) ls_ifs(0, AF_INET, options);
  300. if (ipv6) ls_ifs(0, AF_INET6, options);
  301. }else{
  302. for(r=0; r<no; r++){
  303. if (ipv4) ls_ifs(name[r], AF_INET, options);
  304. if (ipv6) ls_ifs(name[r], AF_INET6, options);
  305. }
  306. };
  307. exit(0);
  308. error:
  309. exit(-1);
  310. };