Jelajahi Sumber

*** empty log message ***

Andrei Pelinescu-Onciul 23 tahun lalu
induk
melakukan
523813bdd1
1 mengubah file dengan 217 tambahan dan 0 penghapusan
  1. 217 0
      test/ifls.c

+ 217 - 0
test/ifls.c

@@ -0,0 +1,217 @@
+/* $Id$
+ *
+ *
+ * test programs, list all interfaces and their ip address
+ */
+
+
+#include <sys/ioctl.h>
+#include <net/if.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#define FLAGS 1
+
+
+static char* version="ifls 0.1";
+static char* id="$Id$";
+static char* help_msg="\
+Usage: ifls [-6hV} [interface...]\n\
+(if no interface name is specified it will list all the interfaces)\n\
+Options:\n\
+    -a      list both ipv4 and ipv6 interfaces (default)\n\
+    -4      list only ipv4 interfaces\n\
+    -6      list only ipv6 interfaces\n\
+    -f      show also the interface flags\n\
+    -V      version number\n\
+    -h      this help message\n\
+";
+
+
+
+int ls_if(char* name, int family , int options)
+{
+	struct ifreq ifr;
+	int s;
+	unsigned char* buf;
+	int r;
+	
+	
+	s=socket(family, SOCK_DGRAM, 0);
+	strncpy(ifr.ifr_name, name, IFNAMSIZ);
+	if (ioctl(s, SIOCGIFADDR, &ifr)==-1){
+		if(errno==EBADF) return 0; /* invalid descriptor => no address*/
+		fprintf(stderr, "ls_if: ioctl failed: %s\n", strerror(errno));
+		goto error;
+	};
+	
+	printf("%s:\n", ifr.ifr_name);
+	if (ifr.ifr_addr.sa_family==AF_INET){
+		buf=&((struct sockaddr_in*)(&ifr.ifr_addr))->sin_addr;
+		printf("        %d.%d.%d.%d\n", buf[0], buf[1], buf[2], buf[3]);
+	}else{
+		buf=&((struct sockaddr_in6*)(&ifr.ifr_addr))->sin6_addr;
+		printf("        ");
+		for(r=0; r<16; r++) printf("%02x%s", buf[r], (r%2)?":":"" );
+		printf("\n");
+	}
+	if (options & FLAGS){
+		if (ioctl(s, SIOCGIFFLAGS, &ifr)==-1){
+			fprintf(stderr, "ls_if: ioctl failed: %s\n", strerror(errno));
+			goto error;
+		}
+		printf("        ");
+		if (ifr.ifr_flags & IFF_UP) printf ("UP ");
+		if (ifr.ifr_flags & IFF_BROADCAST) printf ("BROADCAST ");
+		if (ifr.ifr_flags & IFF_DEBUG) printf ("DEBUG ");
+		if (ifr.ifr_flags & IFF_LOOPBACK) printf ("LOOPBACK ");
+		if (ifr.ifr_flags & IFF_POINTOPOINT) printf ("POINTOPOINT ");
+		if (ifr.ifr_flags & IFF_RUNNING) printf ("RUNNING ");
+		if (ifr.ifr_flags & IFF_NOARP) printf ("NOARP ");
+		if (ifr.ifr_flags & IFF_PROMISC) printf ("PROMISC ");
+		if (ifr.ifr_flags & IFF_NOTRAILERS) printf ("NOTRAILERS ");
+		if (ifr.ifr_flags & IFF_ALLMULTI) printf ("ALLMULTI ");
+		if (ifr.ifr_flags & IFF_MASTER) printf ("MASTER ");
+		if (ifr.ifr_flags & IFF_SLAVE) printf ("SLAVE ");
+		if (ifr.ifr_flags & IFF_MULTICAST) printf ("MULTICAST ");
+		if (ifr.ifr_flags & IFF_PORTSEL) printf ("PORTSEL ");
+		if (ifr.ifr_flags & IFF_AUTOMEDIA) printf ("AUTOMEDIA ");
+		/*if (ifr.ifr_flags & IFF_DYNAMIC ) printf ("DYNAMIC ");*/
+		printf ("\n");
+	};
+
+	return 0;
+error:
+	return -1;
+}
+
+
+
+int ls_all(int family, int options)
+{
+	struct ifconf ifc;
+	struct ifreq* ifr;
+	char*  last;
+	int size;
+	int s;
+	
+	/* ipv4 or ipv6 only*/
+	s=socket(family, SOCK_DGRAM, 0);
+	for (size=10; ; size*=2){
+		ifc.ifc_len=size*sizeof(struct ifreq);
+		ifc.ifc_req=(struct ifreq*) malloc(size*sizeof(struct ifreq));
+		if (ifc.ifc_req==0){
+			fprintf(stderr, "memory allocation failure\n");
+			goto error;
+		}
+		if (ioctl(s, SIOCGIFCONF, &ifc)==-1){
+			if(errno==EBADF) return 0; /* invalid descriptor => no such ifs*/
+			fprintf(stderr, "ioctl failed: %s\n", strerror(errno));
+			goto error;
+		}
+		if (ifc.ifc_len<size*sizeof(struct ifreq)) break;
+		/* try a bigger array*/
+		free(ifc.ifc_req);
+	}
+	
+	last=(char*)ifc.ifc_req+ifc.ifc_len;
+	for(ifr=ifc.ifc_req; (char*)ifr<last;
+			ifr=(struct ifreq*)((char*)ifr+sizeof(ifr->ifr_name)+
+				( (ifr->ifr_addr.sa_family==AF_INET)?
+					sizeof(struct sockaddr_in): sizeof(struct sockaddr_in6)) )
+		)
+	{
+		ls_if(ifr->ifr_name, family, options);
+	}
+	free(ifc.ifc_req); /*clean up*/
+	return  0;
+error:
+	return -1;
+}
+
+
+int main(int argc, char**argv)
+{
+	char** name;
+	int no;
+	int options;
+	int ipv6, ipv4;
+	int r;
+	char c;
+	
+	
+	options=0;
+	ipv6=ipv4=1;
+	name=0;
+	no=0;
+	opterr=0;
+	while((c=getopt(argc, argv, "a46fhV"))!=-1){
+		switch(c){
+			case 'a':
+				ipv6=ipv4=1;
+				break;
+			case '4':
+				ipv6=0;
+				ipv4=1;
+				break;
+			case '6':
+				ipv4=0;
+				ipv6=1;
+				break;
+			case 'f':
+				options|=FLAGS;
+				break;
+			case 'V':
+				printf("version: %s\n", version);
+				printf("%s\n", id);
+				exit(0);
+				break;
+			case 'h':
+				printf("version: %s\n", version);
+				printf("%s", help_msg);
+				exit(0);
+				break;
+			case '?':
+				if (isprint(optopt))
+					fprintf(stderr, "Unknow option `-%c´\n", optopt);
+				else
+					fprintf(stderr, "Unknown character `\\x%x´\n", optopt);
+				goto error;
+			case ':':
+				fprintf(stderr, "Option `-%c´ requires an argument\n",
+						optopt);
+				goto error;
+			default:
+				abort();
+		};
+	};
+	/* check if we have non-options */
+	if( optind < argc){
+		no=argc-optind;
+		name=&argv[optind];
+	}
+	
+	if (no==0){
+		/* list all interfaces */
+		if (ipv4) ls_all(AF_INET, options);
+		if (ipv6) ls_all(AF_INET6, options);
+	}else{
+		for(r=0; r<no; r++){
+			if (ipv4) ls_if(name[r], AF_INET, options);
+			if (ipv6) ls_if(name[r], AF_INET6, options);
+		}
+	};
+	
+	
+	exit(0);
+error:
+	exit(-1);
+};