Add in a first pass at ifconfig status reporting. It took a long while
hacking on the mess in net-tools-1.59, but it currently adds 12k and supports ethernet, loop, ppp, and treats everything else as a generic interface. Works ok for me. -Erik
This commit is contained in:
		
							
								
								
									
										10
									
								
								Config.h
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								Config.h
									
									
									
									
									
								
							| @@ -284,6 +284,8 @@ | ||||
| // Support for Minix filesystem, version 2 | ||||
| //#define BB_FEATURE_MINIX2 | ||||
| // | ||||
| // Enable ifconfig status reporting output -- this feature adds 12k. | ||||
| //#define BB_FEATURE_IFCONFIG_STATUS | ||||
| // | ||||
| // Enable busybox --install [-s] | ||||
| // to create links (or symlinks) for all the commands that are  | ||||
| @@ -393,6 +395,14 @@ | ||||
| #endif | ||||
| #endif | ||||
| // | ||||
| #if defined BB_IFCONFIG | ||||
| #ifdef BB_FEATURE_IFCONFIG_STATUS | ||||
| #define BB_INTERFACE | ||||
| #endif | ||||
| #else | ||||
| #undef BB_INTERFACE | ||||
| #endif	 | ||||
| // | ||||
| #if defined BB_FEATURE_AUTOWIDTH | ||||
| #ifndef BB_FEATURE_USE_TERMIOS | ||||
| #define BB_FEATURE_USE_TERMIOS | ||||
|   | ||||
							
								
								
									
										455
									
								
								ifconfig.c
									
									
									
									
									
								
							
							
						
						
									
										455
									
								
								ifconfig.c
									
									
									
									
									
								
							| @@ -15,16 +15,19 @@ | ||||
|  * Foundation;  either  version 2 of the License, or  (at | ||||
|  * your option) any later version. | ||||
|  * | ||||
|  * $Id: ifconfig.c,v 1.3 2001/02/20 06:14:07 andersen Exp $ | ||||
|  * $Id: ifconfig.c,v 1.4 2001/03/06 00:48:59 andersen Exp $ | ||||
|  * | ||||
|  * Majorly hacked up by Larry Doolittle <ldoolitt@recycle.lbl.gov>  | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include "busybox.h" | ||||
| #include <sys/types.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <errno.h> | ||||
| #include <string.h>   // strcmp and friends | ||||
| #include <ctype.h>    // isdigit and friends | ||||
| #include <sys/types.h> | ||||
| #include <sys/socket.h> | ||||
| #include <sys/ioctl.h> | ||||
| #include <netinet/in.h> | ||||
| @@ -32,10 +35,50 @@ | ||||
| #include <net/if.h> | ||||
| #include <net/if_arp.h> | ||||
| #include <linux/if_ether.h> | ||||
| #include "busybox.h" | ||||
|  | ||||
| static int sockfd;  /* socket fd we use to manipulate stuff with */ | ||||
|  | ||||
| #define TESTME 0 | ||||
| #if TESTME | ||||
| #define ioctl test_ioctl | ||||
| char *saddr_to_a(struct sockaddr *s) | ||||
| { | ||||
| 	if (s->sa_family == ARPHRD_ETHER) { | ||||
| 		static char hw[18]; | ||||
| 		sprintf(hw, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", | ||||
| 			s->sa_data[0], s->sa_data[1], s->sa_data[2], | ||||
| 			s->sa_data[3], s->sa_data[4], s->sa_data[5]); | ||||
| 		return hw; | ||||
| 	} else if (s->sa_family == AF_INET) { | ||||
| 		struct sockaddr_in *ss = (struct sockaddr_in *) s; | ||||
| 		return inet_ntoa(ss->sin_addr); | ||||
| 	} else { | ||||
| 		return NULL; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int test_ioctl(int __fd, unsigned long int __request, void *param) | ||||
| { | ||||
| 	struct ifreq *i=(struct ifreq *)param; | ||||
| 	printf("ioctl fd=%d, request=%ld\n", __fd, __request); | ||||
| 	 | ||||
| 	switch(__request) { | ||||
| 		case SIOCGIFFLAGS:   printf("  SIOCGIFFLAGS\n");       i->ifr_flags = 0;   break; | ||||
| 		case SIOCSIFFLAGS:   printf("  SIOCSIFFLAGS, %x\n",    i->ifr_flags);     break; | ||||
| 		case SIOCSIFMETRIC:  printf("  SIOCSIFMETRIC, %d\n",   i->ifr_metric);    break; | ||||
| 		case SIOCSIFMTU:     printf("  SIOCSIFMTU, %d\n",      i->ifr_mtu);       break; | ||||
| 		case SIOCSIFBRDADDR: printf("  SIOCSIFBRDADDR, %s\n",  saddr_to_a(&(i->ifr_broadaddr))); break; | ||||
| 		case SIOCSIFDSTADDR: printf("  SIOCSIFDSTADDR, %s\n",  saddr_to_a(&(i->ifr_dstaddr  ))); break; | ||||
| 		case SIOCSIFNETMASK: printf("  SIOCSIFNETMASK, %s\n",  saddr_to_a(&(i->ifr_netmask  ))); break; | ||||
| 		case SIOCSIFADDR:    printf("  SIOCSIFADDR, %s\n",     saddr_to_a(&(i->ifr_addr     ))); break; | ||||
| 		case SIOCSIFHWADDR:  printf("  SIOCSIFHWADDR, %s\n",   saddr_to_a(&(i->ifr_hwaddr   ))); break;  /* broken */ | ||||
| 		default: | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* print usage and exit */ | ||||
|  | ||||
| #define _(x) x | ||||
| @@ -49,7 +92,7 @@ set_flag(char *ifname, short flag) | ||||
| 	strcpy(ifr.ifr_name, ifname); | ||||
| 	if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { | ||||
| 		perror("SIOCGIFFLAGS");  | ||||
| 		return (-1); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	strcpy(ifr.ifr_name, ifname); | ||||
| 	ifr.ifr_flags |= flag; | ||||
| @@ -57,7 +100,7 @@ set_flag(char *ifname, short flag) | ||||
| 		perror("SIOCSIFFLAGS"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	return (0); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -78,9 +121,62 @@ clr_flag(char *ifname, short flag) | ||||
| 		perror("SIOCSIFFLAGS"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	return (0); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* which element in struct ifreq to frob */ | ||||
| enum frob { | ||||
| 	L_METRIC, | ||||
| 	L_MTU, | ||||
| 	L_DATA, | ||||
| 	L_BROAD, | ||||
| 	L_DEST, | ||||
| 	L_MASK, | ||||
| 	L_HWAD, | ||||
| }; | ||||
|  | ||||
|  | ||||
| struct flag_map { | ||||
| 	char *name; | ||||
| 	enum frob frob; | ||||
| 	int flag; | ||||
| 	int sflag; | ||||
| 	int action; | ||||
| }; | ||||
|  | ||||
| /* action: | ||||
|  *  2   set | ||||
|  *  4   clear | ||||
|  *  6   set/clear | ||||
|  *  8   clear/set | ||||
|  *  10  numeric | ||||
|  *  12  address | ||||
|  *  14  address/clear | ||||
|  */ | ||||
| const static struct flag_map flag_table[] = { | ||||
| 	{"arp",         0,  IFF_NOARP,             0, 6}, | ||||
| 	{"trailers",    0,  IFF_NOTRAILERS,        0, 6}, | ||||
| 	{"promisc",     0,  IFF_PROMISC,           0, 8}, | ||||
| 	{"multicast",   0,  IFF_MULTICAST,         0, 8}, | ||||
| 	{"allmulti",    0,  IFF_ALLMULTI,          0, 8}, | ||||
| 	{"up",          0, (IFF_UP | IFF_RUNNING), 0, 2}, | ||||
| 	{"down",        0,  IFF_UP,                0, 4}, | ||||
| 	{"metric",      L_METRIC,              0, SIOCSIFMETRIC,  10}, | ||||
| 	{"mtu",         L_MTU,                 0, SIOCSIFMTU,     10}, | ||||
| #ifdef SIOCSKEEPALIVE | ||||
| 	{"keepalive",   L_DATA,                0, SIOCSKEEPALIVE, 10}, | ||||
| #endif | ||||
| #ifdef SIOCSOUTFILL | ||||
| 	{"outfill",     L_DATA,                0, SIOCSOUTFILL,   10}, | ||||
| #endif | ||||
| 	{"broadcast",   L_BROAD, IFF_BROADCAST,   SIOCSIFBRDADDR, 14}, | ||||
| 	{"dstaddr",     L_DEST,                0, SIOCSIFDSTADDR, 12}, | ||||
| 	{"netmask",     L_MASK,                0, SIOCSIFNETMASK, 12}, | ||||
| 	{"pointopoint", L_DEST,  IFF_POINTOPOINT, SIOCSIFDSTADDR, 14}, | ||||
| 	{"hw",          L_HWAD,                0, SIOCSIFHWADDR,  14}, | ||||
| }; | ||||
|  | ||||
|  | ||||
| /* resolve XXX.YYY.ZZZ.QQQ -> binary */ | ||||
|  | ||||
| static int | ||||
| @@ -90,15 +186,16 @@ INET_resolve(char *name, struct sockaddr_in *sin) | ||||
| 	sin->sin_port = 0; | ||||
|  | ||||
| 	/* Default is special, meaning 0.0.0.0. */ | ||||
| 	if (!strcmp(name, "default")) { | ||||
| 	if (strcmp(name, "default")==0) { | ||||
| 		sin->sin_addr.s_addr = INADDR_ANY; | ||||
| 		return (1); | ||||
| 		return 1; | ||||
| 	} | ||||
| 	/* Look to see if it's a dotted quad. */ | ||||
| 	if (inet_aton(name, &sin->sin_addr)) { | ||||
| 		return 0; | ||||
| 	} | ||||
| 	/* guess not.. */ | ||||
| 	errno = EINVAL; | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| @@ -127,12 +224,12 @@ in_ether(char *bufp, struct sockaddr *sap) | ||||
| 			val = c - 'A' + 10; | ||||
| 		else { | ||||
| #ifdef DEBUG | ||||
| 			fprintf(stderr, | ||||
| 				_("in_ether(%s): invalid ether address!\n"), | ||||
| 			error_msg( | ||||
| 				_("in_ether(%s): invalid ether address!"), | ||||
| 				orig); | ||||
| #endif | ||||
| 			errno = EINVAL; | ||||
| 			return (-1); | ||||
| 			return -1; | ||||
| 		} | ||||
| 		val <<= 4; | ||||
| 		c = *bufp; | ||||
| @@ -146,22 +243,19 @@ in_ether(char *bufp, struct sockaddr *sap) | ||||
| 			val >>= 4; | ||||
| 		else { | ||||
| #ifdef DEBUG | ||||
| 			fprintf(stderr, | ||||
| 				_("in_ether(%s): invalid ether address!\n"), | ||||
| 			error_msg( | ||||
| 				_("in_ether(%s): invalid ether address!"), | ||||
| 				orig); | ||||
| #endif | ||||
| 			errno = EINVAL; | ||||
| 			return (-1); | ||||
| 			return -1; | ||||
| 		} | ||||
| 		if (c != 0) | ||||
| 			bufp++; | ||||
| 		*ptr++ = (unsigned char) (val & 0377); | ||||
| 		i++; | ||||
| 		 | ||||
| 		/* We might get a semicolon here - not required. */ | ||||
| 		if (*bufp == ':') | ||||
| 			bufp++; | ||||
| 		 | ||||
| 		/* optional colon already handled, don't swallow a second */ | ||||
| 	} | ||||
|  | ||||
| 	if(i != ETH_ALEN) { | ||||
| @@ -171,25 +265,37 @@ in_ether(char *bufp, struct sockaddr *sap) | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
| 		 | ||||
| #ifdef BB_FEATURE_IFCONFIG_STATUS | ||||
| extern int display_interfaces(void); | ||||
| #else | ||||
| int display_interfaces(void) | ||||
| { | ||||
|     show_usage(); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| int ifconfig_main(int argc, char **argv) | ||||
| { | ||||
| 	struct ifreq ifr; | ||||
| 	struct sockaddr_in sa; | ||||
| 	struct sockaddr sa2; | ||||
| 	char **spp; | ||||
| 	char **spp, *cmd; | ||||
| 	int goterr = 0; | ||||
| 	int r, didnetmask = 0; | ||||
| 	int r; | ||||
| 	/* int didnetmask = 0;   special case input error detection no longer implemented */ | ||||
| 	char host[128]; | ||||
| 	const struct flag_map *ft; | ||||
| 	int i, sense; | ||||
| 	int a, ecode; | ||||
| 	struct sockaddr *d; | ||||
|  | ||||
| 	if(argc < 2) { | ||||
| 		show_usage(); | ||||
| 		return(display_interfaces()); | ||||
| 	} | ||||
|  | ||||
| 	/* Create a channel to the NET kernel. */ | ||||
| 	if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { | ||||
| 		perror("socket"); | ||||
| 		exit(1); | ||||
| 		perror_msg_and_die("socket"); | ||||
| 	} | ||||
|  | ||||
| 	/* skip argv[0] */ | ||||
| @@ -205,235 +311,84 @@ int ifconfig_main(int argc, char **argv) | ||||
|  | ||||
| 	/* Process the remaining arguments. */ | ||||
| 	while (*spp != (char *) NULL) { | ||||
| 		if (!strcmp(*spp, "arp")) { | ||||
| 			goterr |= clr_flag(ifr.ifr_name, IFF_NOARP); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		cmd = *spp; | ||||
| 		sense=0; | ||||
| 		if (*cmd=='-') { | ||||
| 			sense=1; | ||||
| 			cmd++; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "-arp")) { | ||||
| 			goterr |= set_flag(ifr.ifr_name, IFF_NOARP); | ||||
| 			spp++; | ||||
| 		ft = NULL; | ||||
| 		for (i=0; i<(sizeof(flag_table)/sizeof(struct flag_map)); i++) { | ||||
| 			if (strcmp(cmd, flag_table[i].name)==0) { | ||||
| 				ft=flag_table+i; | ||||
| 				spp++; | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		if (ft) { | ||||
| 			switch (ft->action+sense) { | ||||
| 			case 4: | ||||
| 			case 7: | ||||
| 			case 8: | ||||
| 			case 15: | ||||
| 				goterr |= clr_flag(ifr.ifr_name, ft->flag); | ||||
| 				break; | ||||
| 			case 2: | ||||
| 			case 6: | ||||
| 			case 9: | ||||
| 				goterr |= set_flag(ifr.ifr_name, ft->flag); | ||||
| 				break; | ||||
| 			case 10: | ||||
| 				if (*spp == NULL) | ||||
| 					show_usage(); | ||||
| 				a = atoi(*spp++); | ||||
| 				switch (ft->frob) { | ||||
| 					case L_METRIC: ifr.ifr_metric = a; break; | ||||
| 					case L_MTU:    ifr.ifr_mtu    = a; break; | ||||
| 					case L_DATA:   ifr.ifr_data   = (caddr_t) a; break; | ||||
| 					default: error_msg_and_die("bugaboo"); | ||||
| 				} | ||||
|  | ||||
| 				if (ioctl(sockfd, ft->sflag, &ifr) < 0) { | ||||
| 					perror(ft->name);  /* imperfect */ | ||||
| 					goterr++; | ||||
| 				} | ||||
| 				break; | ||||
| 			case 12: | ||||
| 			case 14: | ||||
| 				if (ft->action+sense==10 && *spp == NULL) { | ||||
| 					show_usage(); | ||||
| 					break; | ||||
| 				} | ||||
| 				if (*spp != NULL) { | ||||
| 					safe_strncpy(host, *spp, (sizeof host)); | ||||
| 					spp++; | ||||
| 					if (ft->frob == L_HWAD) { | ||||
| 						ecode = in_ether(host, &ifr.ifr_hwaddr); | ||||
| 					} else { | ||||
| 						switch (ft->frob) { | ||||
| 							case L_BROAD: d = &ifr.ifr_broadaddr; break; | ||||
| 							case L_DEST:  d = &ifr.ifr_dstaddr;   break; | ||||
| 							case L_MASK:  d = &ifr.ifr_netmask;   break; | ||||
| 							default: error_msg_and_die("bugaboo"); | ||||
| 						} | ||||
| 						ecode = INET_resolve(host, (struct sockaddr_in *) d); | ||||
| 					} | ||||
| 					if (ecode < 0 || ioctl(sockfd, ft->sflag, &ifr) < 0) { | ||||
| 						perror(ft->name);  /* imperfect */ | ||||
| 						goterr++; | ||||
| 					} | ||||
| 				} | ||||
| 				if (ft->flag != 0) { | ||||
| 					goterr |= set_flag(ifr.ifr_name, ft->flag); | ||||
| 				} | ||||
| 				break; | ||||
| 			default: | ||||
| 				show_usage(); | ||||
| 			} /* end of switch */ | ||||
| 			continue; | ||||
| 		} | ||||
| 		 | ||||
| 		if (!strcmp(*spp, "trailers")) { | ||||
| 			goterr |= clr_flag(ifr.ifr_name, IFF_NOTRAILERS); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "-trailers")) { | ||||
| 			goterr |= set_flag(ifr.ifr_name, IFF_NOTRAILERS); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "promisc")) { | ||||
| 			goterr |= set_flag(ifr.ifr_name, IFF_PROMISC); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "-promisc")) { | ||||
| 			goterr |= clr_flag(ifr.ifr_name, IFF_PROMISC); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "multicast")) { | ||||
| 			goterr |= set_flag(ifr.ifr_name, IFF_MULTICAST); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "-multicast")) { | ||||
| 			goterr |= clr_flag(ifr.ifr_name, IFF_MULTICAST); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "allmulti")) { | ||||
| 			goterr |= set_flag(ifr.ifr_name, IFF_ALLMULTI); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "-allmulti")) { | ||||
| 			goterr |= clr_flag(ifr.ifr_name, IFF_ALLMULTI); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "up")) { | ||||
| 			goterr |= set_flag(ifr.ifr_name, (IFF_UP | IFF_RUNNING)); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "down")) { | ||||
| 			goterr |= clr_flag(ifr.ifr_name, IFF_UP); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		if (!strcmp(*spp, "metric")) { | ||||
| 			if (*++spp == NULL) | ||||
| 				show_usage(); | ||||
| 			ifr.ifr_metric = atoi(*spp); | ||||
| 			if (ioctl(sockfd, SIOCSIFMETRIC, &ifr) < 0) { | ||||
| 				fprintf(stderr, "SIOCSIFMETRIC: %s\n", strerror(errno)); | ||||
| 				goterr++; | ||||
| 			} | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "mtu")) { | ||||
| 			if (*++spp == NULL) | ||||
| 				show_usage(); | ||||
| 			ifr.ifr_mtu = atoi(*spp); | ||||
| 			if (ioctl(sockfd, SIOCSIFMTU, &ifr) < 0) { | ||||
| 				fprintf(stderr, "SIOCSIFMTU: %s\n", strerror(errno)); | ||||
| 				goterr++; | ||||
| 			} | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| #ifdef SIOCSKEEPALIVE | ||||
| 		if (!strcmp(*spp, "keepalive")) { | ||||
| 			if (*++spp == NULL) | ||||
| 				show_usage(); | ||||
| 			ifr.ifr_data = (caddr_t) atoi(*spp); | ||||
| 			if (ioctl(sockfd, SIOCSKEEPALIVE, &ifr) < 0) { | ||||
| 				fprintf(stderr, "SIOCSKEEPALIVE: %s\n", strerror(errno)); | ||||
| 				goterr++; | ||||
| 			} | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| #endif | ||||
|  | ||||
| #ifdef SIOCSOUTFILL | ||||
| 		if (!strcmp(*spp, "outfill")) { | ||||
| 			if (*++spp == NULL) | ||||
| 				show_usage(); | ||||
| 			ifr.ifr_data = (caddr_t) atoi(*spp); | ||||
| 			if (ioctl(sockfd, SIOCSOUTFILL, &ifr) < 0) { | ||||
| 				fprintf(stderr, "SIOCSOUTFILL: %s\n", strerror(errno)); | ||||
| 				goterr++; | ||||
| 			} | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| #endif | ||||
|  | ||||
| 		if (!strcmp(*spp, "-broadcast")) { | ||||
| 			goterr |= clr_flag(ifr.ifr_name, IFF_BROADCAST); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "broadcast")) { | ||||
| 			if (*++spp != NULL) { | ||||
| 				safe_strncpy(host, *spp, (sizeof host)); | ||||
| 				if (INET_resolve(host, &sa) < 0) { | ||||
| 					goterr++; | ||||
| 					spp++; | ||||
| 					continue; | ||||
| 				} | ||||
| 				memcpy((char *) &ifr.ifr_broadaddr, | ||||
| 				       (char *) &sa, | ||||
| 				       sizeof(struct sockaddr)); | ||||
| 				if (ioctl(sockfd, SIOCSIFBRDADDR, &ifr) < 0) { | ||||
| 					perror("SIOCSIFBRDADDR"); | ||||
| 					goterr++; | ||||
| 				} | ||||
| 				spp++; | ||||
| 			} | ||||
| 			goterr |= set_flag(ifr.ifr_name, IFF_BROADCAST); | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "dstaddr")) { | ||||
| 			if (*++spp == NULL) | ||||
| 				show_usage(); | ||||
| 			safe_strncpy(host, *spp, (sizeof host)); | ||||
| 			if (INET_resolve(host, &sa) < 0) { | ||||
| 				goterr++; | ||||
| 				spp++; | ||||
| 				continue; | ||||
| 			} | ||||
| 			memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa, | ||||
| 			       sizeof(struct sockaddr)); | ||||
| 			if (ioctl(sockfd, SIOCSIFDSTADDR, &ifr) < 0) { | ||||
| 				fprintf(stderr, "SIOCSIFDSTADDR: %s\n", | ||||
| 					strerror(errno)); | ||||
| 				goterr++; | ||||
| 			} | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "netmask")) { | ||||
| 			if (*++spp == NULL || didnetmask) | ||||
| 				show_usage(); | ||||
| 			safe_strncpy(host, *spp, (sizeof host)); | ||||
| 			if (INET_resolve(host, &sa) < 0) { | ||||
| 				goterr++; | ||||
| 				spp++; | ||||
| 				continue; | ||||
| 			} | ||||
| 			didnetmask++; | ||||
| 			memcpy((char *) &ifr.ifr_netmask, (char *) &sa, | ||||
| 			       sizeof(struct sockaddr)); | ||||
| 			if (ioctl(sockfd, SIOCSIFNETMASK, &ifr) < 0) { | ||||
| 				perror("SIOCSIFNETMASK"); | ||||
| 				goterr++; | ||||
| 			} | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		if (!strcmp(*spp, "-pointopoint")) { | ||||
| 			goterr |= clr_flag(ifr.ifr_name, IFF_POINTOPOINT); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "pointopoint")) { | ||||
| 			if (*(spp + 1) != NULL) { | ||||
| 				spp++; | ||||
| 				safe_strncpy(host, *spp, (sizeof host)); | ||||
| 				if (INET_resolve(host, &sa)) { | ||||
| 					goterr++; | ||||
| 					spp++; | ||||
| 					continue; | ||||
| 				} | ||||
| 				memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa, | ||||
| 				       sizeof(struct sockaddr)); | ||||
| 				if (ioctl(sockfd, SIOCSIFDSTADDR, &ifr) < 0) { | ||||
| 					perror("SIOCSIFDSTADDR"); | ||||
| 					goterr++; | ||||
| 				} | ||||
| 			} | ||||
| 			goterr |= set_flag(ifr.ifr_name, IFF_POINTOPOINT); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		}; | ||||
|  | ||||
| 		if (!strcmp(*spp, "hw")) { | ||||
| 			if (*++spp == NULL || strcmp("ether", *spp)) { | ||||
| 				show_usage(); | ||||
| 			} | ||||
| 				 | ||||
| 			if (*++spp == NULL) { | ||||
| 				/* silently ignore it if no address */ | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			safe_strncpy(host, *spp, (sizeof host)); | ||||
| 			if (in_ether(host, &sa2) < 0) { | ||||
| 				fprintf(stderr, "invalid hw-addr %s\n", host); | ||||
| 				goterr++; | ||||
| 				spp++; | ||||
| 				continue; | ||||
| 			} | ||||
| 			memcpy((char *) &ifr.ifr_hwaddr, (char *) &sa2, | ||||
| 			       sizeof(struct sockaddr)); | ||||
| 			if (ioctl(sockfd, SIOCSIFHWADDR, &ifr) < 0) { | ||||
| 				perror("SIOCSIFHWADDR"); | ||||
| 				goterr++; | ||||
| 			} | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		/* If the next argument is a valid hostname, assume OK. */ | ||||
| 		safe_strncpy(host, *spp, (sizeof host)); | ||||
|  | ||||
| @@ -471,6 +426,6 @@ int ifconfig_main(int argc, char **argv) | ||||
|  | ||||
| 	} /* end of while-loop */ | ||||
|  | ||||
|         exit(0); | ||||
|         return goterr; | ||||
| } | ||||
|  | ||||
|   | ||||
							
								
								
									
										2080
									
								
								interface.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2080
									
								
								interface.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -15,16 +15,19 @@ | ||||
|  * Foundation;  either  version 2 of the License, or  (at | ||||
|  * your option) any later version. | ||||
|  * | ||||
|  * $Id: ifconfig.c,v 1.3 2001/02/20 06:14:07 andersen Exp $ | ||||
|  * $Id: ifconfig.c,v 1.4 2001/03/06 00:48:59 andersen Exp $ | ||||
|  * | ||||
|  * Majorly hacked up by Larry Doolittle <ldoolitt@recycle.lbl.gov>  | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include "busybox.h" | ||||
| #include <sys/types.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <errno.h> | ||||
| #include <string.h>   // strcmp and friends | ||||
| #include <ctype.h>    // isdigit and friends | ||||
| #include <sys/types.h> | ||||
| #include <sys/socket.h> | ||||
| #include <sys/ioctl.h> | ||||
| #include <netinet/in.h> | ||||
| @@ -32,10 +35,50 @@ | ||||
| #include <net/if.h> | ||||
| #include <net/if_arp.h> | ||||
| #include <linux/if_ether.h> | ||||
| #include "busybox.h" | ||||
|  | ||||
| static int sockfd;  /* socket fd we use to manipulate stuff with */ | ||||
|  | ||||
| #define TESTME 0 | ||||
| #if TESTME | ||||
| #define ioctl test_ioctl | ||||
| char *saddr_to_a(struct sockaddr *s) | ||||
| { | ||||
| 	if (s->sa_family == ARPHRD_ETHER) { | ||||
| 		static char hw[18]; | ||||
| 		sprintf(hw, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x", | ||||
| 			s->sa_data[0], s->sa_data[1], s->sa_data[2], | ||||
| 			s->sa_data[3], s->sa_data[4], s->sa_data[5]); | ||||
| 		return hw; | ||||
| 	} else if (s->sa_family == AF_INET) { | ||||
| 		struct sockaddr_in *ss = (struct sockaddr_in *) s; | ||||
| 		return inet_ntoa(ss->sin_addr); | ||||
| 	} else { | ||||
| 		return NULL; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| int test_ioctl(int __fd, unsigned long int __request, void *param) | ||||
| { | ||||
| 	struct ifreq *i=(struct ifreq *)param; | ||||
| 	printf("ioctl fd=%d, request=%ld\n", __fd, __request); | ||||
| 	 | ||||
| 	switch(__request) { | ||||
| 		case SIOCGIFFLAGS:   printf("  SIOCGIFFLAGS\n");       i->ifr_flags = 0;   break; | ||||
| 		case SIOCSIFFLAGS:   printf("  SIOCSIFFLAGS, %x\n",    i->ifr_flags);     break; | ||||
| 		case SIOCSIFMETRIC:  printf("  SIOCSIFMETRIC, %d\n",   i->ifr_metric);    break; | ||||
| 		case SIOCSIFMTU:     printf("  SIOCSIFMTU, %d\n",      i->ifr_mtu);       break; | ||||
| 		case SIOCSIFBRDADDR: printf("  SIOCSIFBRDADDR, %s\n",  saddr_to_a(&(i->ifr_broadaddr))); break; | ||||
| 		case SIOCSIFDSTADDR: printf("  SIOCSIFDSTADDR, %s\n",  saddr_to_a(&(i->ifr_dstaddr  ))); break; | ||||
| 		case SIOCSIFNETMASK: printf("  SIOCSIFNETMASK, %s\n",  saddr_to_a(&(i->ifr_netmask  ))); break; | ||||
| 		case SIOCSIFADDR:    printf("  SIOCSIFADDR, %s\n",     saddr_to_a(&(i->ifr_addr     ))); break; | ||||
| 		case SIOCSIFHWADDR:  printf("  SIOCSIFHWADDR, %s\n",   saddr_to_a(&(i->ifr_hwaddr   ))); break;  /* broken */ | ||||
| 		default: | ||||
| 	} | ||||
| 	return 0; | ||||
| } | ||||
| #endif | ||||
|  | ||||
|  | ||||
| /* print usage and exit */ | ||||
|  | ||||
| #define _(x) x | ||||
| @@ -49,7 +92,7 @@ set_flag(char *ifname, short flag) | ||||
| 	strcpy(ifr.ifr_name, ifname); | ||||
| 	if (ioctl(sockfd, SIOCGIFFLAGS, &ifr) < 0) { | ||||
| 		perror("SIOCGIFFLAGS");  | ||||
| 		return (-1); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	strcpy(ifr.ifr_name, ifname); | ||||
| 	ifr.ifr_flags |= flag; | ||||
| @@ -57,7 +100,7 @@ set_flag(char *ifname, short flag) | ||||
| 		perror("SIOCSIFFLAGS"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	return (0); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  | ||||
| @@ -78,9 +121,62 @@ clr_flag(char *ifname, short flag) | ||||
| 		perror("SIOCSIFFLAGS"); | ||||
| 		return -1; | ||||
| 	} | ||||
| 	return (0); | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| /* which element in struct ifreq to frob */ | ||||
| enum frob { | ||||
| 	L_METRIC, | ||||
| 	L_MTU, | ||||
| 	L_DATA, | ||||
| 	L_BROAD, | ||||
| 	L_DEST, | ||||
| 	L_MASK, | ||||
| 	L_HWAD, | ||||
| }; | ||||
|  | ||||
|  | ||||
| struct flag_map { | ||||
| 	char *name; | ||||
| 	enum frob frob; | ||||
| 	int flag; | ||||
| 	int sflag; | ||||
| 	int action; | ||||
| }; | ||||
|  | ||||
| /* action: | ||||
|  *  2   set | ||||
|  *  4   clear | ||||
|  *  6   set/clear | ||||
|  *  8   clear/set | ||||
|  *  10  numeric | ||||
|  *  12  address | ||||
|  *  14  address/clear | ||||
|  */ | ||||
| const static struct flag_map flag_table[] = { | ||||
| 	{"arp",         0,  IFF_NOARP,             0, 6}, | ||||
| 	{"trailers",    0,  IFF_NOTRAILERS,        0, 6}, | ||||
| 	{"promisc",     0,  IFF_PROMISC,           0, 8}, | ||||
| 	{"multicast",   0,  IFF_MULTICAST,         0, 8}, | ||||
| 	{"allmulti",    0,  IFF_ALLMULTI,          0, 8}, | ||||
| 	{"up",          0, (IFF_UP | IFF_RUNNING), 0, 2}, | ||||
| 	{"down",        0,  IFF_UP,                0, 4}, | ||||
| 	{"metric",      L_METRIC,              0, SIOCSIFMETRIC,  10}, | ||||
| 	{"mtu",         L_MTU,                 0, SIOCSIFMTU,     10}, | ||||
| #ifdef SIOCSKEEPALIVE | ||||
| 	{"keepalive",   L_DATA,                0, SIOCSKEEPALIVE, 10}, | ||||
| #endif | ||||
| #ifdef SIOCSOUTFILL | ||||
| 	{"outfill",     L_DATA,                0, SIOCSOUTFILL,   10}, | ||||
| #endif | ||||
| 	{"broadcast",   L_BROAD, IFF_BROADCAST,   SIOCSIFBRDADDR, 14}, | ||||
| 	{"dstaddr",     L_DEST,                0, SIOCSIFDSTADDR, 12}, | ||||
| 	{"netmask",     L_MASK,                0, SIOCSIFNETMASK, 12}, | ||||
| 	{"pointopoint", L_DEST,  IFF_POINTOPOINT, SIOCSIFDSTADDR, 14}, | ||||
| 	{"hw",          L_HWAD,                0, SIOCSIFHWADDR,  14}, | ||||
| }; | ||||
|  | ||||
|  | ||||
| /* resolve XXX.YYY.ZZZ.QQQ -> binary */ | ||||
|  | ||||
| static int | ||||
| @@ -90,15 +186,16 @@ INET_resolve(char *name, struct sockaddr_in *sin) | ||||
| 	sin->sin_port = 0; | ||||
|  | ||||
| 	/* Default is special, meaning 0.0.0.0. */ | ||||
| 	if (!strcmp(name, "default")) { | ||||
| 	if (strcmp(name, "default")==0) { | ||||
| 		sin->sin_addr.s_addr = INADDR_ANY; | ||||
| 		return (1); | ||||
| 		return 1; | ||||
| 	} | ||||
| 	/* Look to see if it's a dotted quad. */ | ||||
| 	if (inet_aton(name, &sin->sin_addr)) { | ||||
| 		return 0; | ||||
| 	} | ||||
| 	/* guess not.. */ | ||||
| 	errno = EINVAL; | ||||
| 	return -1; | ||||
| } | ||||
|  | ||||
| @@ -127,12 +224,12 @@ in_ether(char *bufp, struct sockaddr *sap) | ||||
| 			val = c - 'A' + 10; | ||||
| 		else { | ||||
| #ifdef DEBUG | ||||
| 			fprintf(stderr, | ||||
| 				_("in_ether(%s): invalid ether address!\n"), | ||||
| 			error_msg( | ||||
| 				_("in_ether(%s): invalid ether address!"), | ||||
| 				orig); | ||||
| #endif | ||||
| 			errno = EINVAL; | ||||
| 			return (-1); | ||||
| 			return -1; | ||||
| 		} | ||||
| 		val <<= 4; | ||||
| 		c = *bufp; | ||||
| @@ -146,22 +243,19 @@ in_ether(char *bufp, struct sockaddr *sap) | ||||
| 			val >>= 4; | ||||
| 		else { | ||||
| #ifdef DEBUG | ||||
| 			fprintf(stderr, | ||||
| 				_("in_ether(%s): invalid ether address!\n"), | ||||
| 			error_msg( | ||||
| 				_("in_ether(%s): invalid ether address!"), | ||||
| 				orig); | ||||
| #endif | ||||
| 			errno = EINVAL; | ||||
| 			return (-1); | ||||
| 			return -1; | ||||
| 		} | ||||
| 		if (c != 0) | ||||
| 			bufp++; | ||||
| 		*ptr++ = (unsigned char) (val & 0377); | ||||
| 		i++; | ||||
| 		 | ||||
| 		/* We might get a semicolon here - not required. */ | ||||
| 		if (*bufp == ':') | ||||
| 			bufp++; | ||||
| 		 | ||||
| 		/* optional colon already handled, don't swallow a second */ | ||||
| 	} | ||||
|  | ||||
| 	if(i != ETH_ALEN) { | ||||
| @@ -171,25 +265,37 @@ in_ether(char *bufp, struct sockaddr *sap) | ||||
|  | ||||
| 	return 0; | ||||
| } | ||||
| 		 | ||||
| #ifdef BB_FEATURE_IFCONFIG_STATUS | ||||
| extern int display_interfaces(void); | ||||
| #else | ||||
| int display_interfaces(void) | ||||
| { | ||||
|     show_usage(); | ||||
| } | ||||
| #endif | ||||
|  | ||||
| int ifconfig_main(int argc, char **argv) | ||||
| { | ||||
| 	struct ifreq ifr; | ||||
| 	struct sockaddr_in sa; | ||||
| 	struct sockaddr sa2; | ||||
| 	char **spp; | ||||
| 	char **spp, *cmd; | ||||
| 	int goterr = 0; | ||||
| 	int r, didnetmask = 0; | ||||
| 	int r; | ||||
| 	/* int didnetmask = 0;   special case input error detection no longer implemented */ | ||||
| 	char host[128]; | ||||
| 	const struct flag_map *ft; | ||||
| 	int i, sense; | ||||
| 	int a, ecode; | ||||
| 	struct sockaddr *d; | ||||
|  | ||||
| 	if(argc < 2) { | ||||
| 		show_usage(); | ||||
| 		return(display_interfaces()); | ||||
| 	} | ||||
|  | ||||
| 	/* Create a channel to the NET kernel. */ | ||||
| 	if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { | ||||
| 		perror("socket"); | ||||
| 		exit(1); | ||||
| 		perror_msg_and_die("socket"); | ||||
| 	} | ||||
|  | ||||
| 	/* skip argv[0] */ | ||||
| @@ -205,235 +311,84 @@ int ifconfig_main(int argc, char **argv) | ||||
|  | ||||
| 	/* Process the remaining arguments. */ | ||||
| 	while (*spp != (char *) NULL) { | ||||
| 		if (!strcmp(*spp, "arp")) { | ||||
| 			goterr |= clr_flag(ifr.ifr_name, IFF_NOARP); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		cmd = *spp; | ||||
| 		sense=0; | ||||
| 		if (*cmd=='-') { | ||||
| 			sense=1; | ||||
| 			cmd++; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "-arp")) { | ||||
| 			goterr |= set_flag(ifr.ifr_name, IFF_NOARP); | ||||
| 			spp++; | ||||
| 		ft = NULL; | ||||
| 		for (i=0; i<(sizeof(flag_table)/sizeof(struct flag_map)); i++) { | ||||
| 			if (strcmp(cmd, flag_table[i].name)==0) { | ||||
| 				ft=flag_table+i; | ||||
| 				spp++; | ||||
| 				break; | ||||
| 			} | ||||
| 		} | ||||
| 		if (ft) { | ||||
| 			switch (ft->action+sense) { | ||||
| 			case 4: | ||||
| 			case 7: | ||||
| 			case 8: | ||||
| 			case 15: | ||||
| 				goterr |= clr_flag(ifr.ifr_name, ft->flag); | ||||
| 				break; | ||||
| 			case 2: | ||||
| 			case 6: | ||||
| 			case 9: | ||||
| 				goterr |= set_flag(ifr.ifr_name, ft->flag); | ||||
| 				break; | ||||
| 			case 10: | ||||
| 				if (*spp == NULL) | ||||
| 					show_usage(); | ||||
| 				a = atoi(*spp++); | ||||
| 				switch (ft->frob) { | ||||
| 					case L_METRIC: ifr.ifr_metric = a; break; | ||||
| 					case L_MTU:    ifr.ifr_mtu    = a; break; | ||||
| 					case L_DATA:   ifr.ifr_data   = (caddr_t) a; break; | ||||
| 					default: error_msg_and_die("bugaboo"); | ||||
| 				} | ||||
|  | ||||
| 				if (ioctl(sockfd, ft->sflag, &ifr) < 0) { | ||||
| 					perror(ft->name);  /* imperfect */ | ||||
| 					goterr++; | ||||
| 				} | ||||
| 				break; | ||||
| 			case 12: | ||||
| 			case 14: | ||||
| 				if (ft->action+sense==10 && *spp == NULL) { | ||||
| 					show_usage(); | ||||
| 					break; | ||||
| 				} | ||||
| 				if (*spp != NULL) { | ||||
| 					safe_strncpy(host, *spp, (sizeof host)); | ||||
| 					spp++; | ||||
| 					if (ft->frob == L_HWAD) { | ||||
| 						ecode = in_ether(host, &ifr.ifr_hwaddr); | ||||
| 					} else { | ||||
| 						switch (ft->frob) { | ||||
| 							case L_BROAD: d = &ifr.ifr_broadaddr; break; | ||||
| 							case L_DEST:  d = &ifr.ifr_dstaddr;   break; | ||||
| 							case L_MASK:  d = &ifr.ifr_netmask;   break; | ||||
| 							default: error_msg_and_die("bugaboo"); | ||||
| 						} | ||||
| 						ecode = INET_resolve(host, (struct sockaddr_in *) d); | ||||
| 					} | ||||
| 					if (ecode < 0 || ioctl(sockfd, ft->sflag, &ifr) < 0) { | ||||
| 						perror(ft->name);  /* imperfect */ | ||||
| 						goterr++; | ||||
| 					} | ||||
| 				} | ||||
| 				if (ft->flag != 0) { | ||||
| 					goterr |= set_flag(ifr.ifr_name, ft->flag); | ||||
| 				} | ||||
| 				break; | ||||
| 			default: | ||||
| 				show_usage(); | ||||
| 			} /* end of switch */ | ||||
| 			continue; | ||||
| 		} | ||||
| 		 | ||||
| 		if (!strcmp(*spp, "trailers")) { | ||||
| 			goterr |= clr_flag(ifr.ifr_name, IFF_NOTRAILERS); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "-trailers")) { | ||||
| 			goterr |= set_flag(ifr.ifr_name, IFF_NOTRAILERS); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "promisc")) { | ||||
| 			goterr |= set_flag(ifr.ifr_name, IFF_PROMISC); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "-promisc")) { | ||||
| 			goterr |= clr_flag(ifr.ifr_name, IFF_PROMISC); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "multicast")) { | ||||
| 			goterr |= set_flag(ifr.ifr_name, IFF_MULTICAST); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "-multicast")) { | ||||
| 			goterr |= clr_flag(ifr.ifr_name, IFF_MULTICAST); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "allmulti")) { | ||||
| 			goterr |= set_flag(ifr.ifr_name, IFF_ALLMULTI); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "-allmulti")) { | ||||
| 			goterr |= clr_flag(ifr.ifr_name, IFF_ALLMULTI); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "up")) { | ||||
| 			goterr |= set_flag(ifr.ifr_name, (IFF_UP | IFF_RUNNING)); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "down")) { | ||||
| 			goterr |= clr_flag(ifr.ifr_name, IFF_UP); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		if (!strcmp(*spp, "metric")) { | ||||
| 			if (*++spp == NULL) | ||||
| 				show_usage(); | ||||
| 			ifr.ifr_metric = atoi(*spp); | ||||
| 			if (ioctl(sockfd, SIOCSIFMETRIC, &ifr) < 0) { | ||||
| 				fprintf(stderr, "SIOCSIFMETRIC: %s\n", strerror(errno)); | ||||
| 				goterr++; | ||||
| 			} | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "mtu")) { | ||||
| 			if (*++spp == NULL) | ||||
| 				show_usage(); | ||||
| 			ifr.ifr_mtu = atoi(*spp); | ||||
| 			if (ioctl(sockfd, SIOCSIFMTU, &ifr) < 0) { | ||||
| 				fprintf(stderr, "SIOCSIFMTU: %s\n", strerror(errno)); | ||||
| 				goterr++; | ||||
| 			} | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| #ifdef SIOCSKEEPALIVE | ||||
| 		if (!strcmp(*spp, "keepalive")) { | ||||
| 			if (*++spp == NULL) | ||||
| 				show_usage(); | ||||
| 			ifr.ifr_data = (caddr_t) atoi(*spp); | ||||
| 			if (ioctl(sockfd, SIOCSKEEPALIVE, &ifr) < 0) { | ||||
| 				fprintf(stderr, "SIOCSKEEPALIVE: %s\n", strerror(errno)); | ||||
| 				goterr++; | ||||
| 			} | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| #endif | ||||
|  | ||||
| #ifdef SIOCSOUTFILL | ||||
| 		if (!strcmp(*spp, "outfill")) { | ||||
| 			if (*++spp == NULL) | ||||
| 				show_usage(); | ||||
| 			ifr.ifr_data = (caddr_t) atoi(*spp); | ||||
| 			if (ioctl(sockfd, SIOCSOUTFILL, &ifr) < 0) { | ||||
| 				fprintf(stderr, "SIOCSOUTFILL: %s\n", strerror(errno)); | ||||
| 				goterr++; | ||||
| 			} | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| #endif | ||||
|  | ||||
| 		if (!strcmp(*spp, "-broadcast")) { | ||||
| 			goterr |= clr_flag(ifr.ifr_name, IFF_BROADCAST); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "broadcast")) { | ||||
| 			if (*++spp != NULL) { | ||||
| 				safe_strncpy(host, *spp, (sizeof host)); | ||||
| 				if (INET_resolve(host, &sa) < 0) { | ||||
| 					goterr++; | ||||
| 					spp++; | ||||
| 					continue; | ||||
| 				} | ||||
| 				memcpy((char *) &ifr.ifr_broadaddr, | ||||
| 				       (char *) &sa, | ||||
| 				       sizeof(struct sockaddr)); | ||||
| 				if (ioctl(sockfd, SIOCSIFBRDADDR, &ifr) < 0) { | ||||
| 					perror("SIOCSIFBRDADDR"); | ||||
| 					goterr++; | ||||
| 				} | ||||
| 				spp++; | ||||
| 			} | ||||
| 			goterr |= set_flag(ifr.ifr_name, IFF_BROADCAST); | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "dstaddr")) { | ||||
| 			if (*++spp == NULL) | ||||
| 				show_usage(); | ||||
| 			safe_strncpy(host, *spp, (sizeof host)); | ||||
| 			if (INET_resolve(host, &sa) < 0) { | ||||
| 				goterr++; | ||||
| 				spp++; | ||||
| 				continue; | ||||
| 			} | ||||
| 			memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa, | ||||
| 			       sizeof(struct sockaddr)); | ||||
| 			if (ioctl(sockfd, SIOCSIFDSTADDR, &ifr) < 0) { | ||||
| 				fprintf(stderr, "SIOCSIFDSTADDR: %s\n", | ||||
| 					strerror(errno)); | ||||
| 				goterr++; | ||||
| 			} | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "netmask")) { | ||||
| 			if (*++spp == NULL || didnetmask) | ||||
| 				show_usage(); | ||||
| 			safe_strncpy(host, *spp, (sizeof host)); | ||||
| 			if (INET_resolve(host, &sa) < 0) { | ||||
| 				goterr++; | ||||
| 				spp++; | ||||
| 				continue; | ||||
| 			} | ||||
| 			didnetmask++; | ||||
| 			memcpy((char *) &ifr.ifr_netmask, (char *) &sa, | ||||
| 			       sizeof(struct sockaddr)); | ||||
| 			if (ioctl(sockfd, SIOCSIFNETMASK, &ifr) < 0) { | ||||
| 				perror("SIOCSIFNETMASK"); | ||||
| 				goterr++; | ||||
| 			} | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		if (!strcmp(*spp, "-pointopoint")) { | ||||
| 			goterr |= clr_flag(ifr.ifr_name, IFF_POINTOPOINT); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
| 		if (!strcmp(*spp, "pointopoint")) { | ||||
| 			if (*(spp + 1) != NULL) { | ||||
| 				spp++; | ||||
| 				safe_strncpy(host, *spp, (sizeof host)); | ||||
| 				if (INET_resolve(host, &sa)) { | ||||
| 					goterr++; | ||||
| 					spp++; | ||||
| 					continue; | ||||
| 				} | ||||
| 				memcpy((char *) &ifr.ifr_dstaddr, (char *) &sa, | ||||
| 				       sizeof(struct sockaddr)); | ||||
| 				if (ioctl(sockfd, SIOCSIFDSTADDR, &ifr) < 0) { | ||||
| 					perror("SIOCSIFDSTADDR"); | ||||
| 					goterr++; | ||||
| 				} | ||||
| 			} | ||||
| 			goterr |= set_flag(ifr.ifr_name, IFF_POINTOPOINT); | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		}; | ||||
|  | ||||
| 		if (!strcmp(*spp, "hw")) { | ||||
| 			if (*++spp == NULL || strcmp("ether", *spp)) { | ||||
| 				show_usage(); | ||||
| 			} | ||||
| 				 | ||||
| 			if (*++spp == NULL) { | ||||
| 				/* silently ignore it if no address */ | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			safe_strncpy(host, *spp, (sizeof host)); | ||||
| 			if (in_ether(host, &sa2) < 0) { | ||||
| 				fprintf(stderr, "invalid hw-addr %s\n", host); | ||||
| 				goterr++; | ||||
| 				spp++; | ||||
| 				continue; | ||||
| 			} | ||||
| 			memcpy((char *) &ifr.ifr_hwaddr, (char *) &sa2, | ||||
| 			       sizeof(struct sockaddr)); | ||||
| 			if (ioctl(sockfd, SIOCSIFHWADDR, &ifr) < 0) { | ||||
| 				perror("SIOCSIFHWADDR"); | ||||
| 				goterr++; | ||||
| 			} | ||||
| 			spp++; | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		/* If the next argument is a valid hostname, assume OK. */ | ||||
| 		safe_strncpy(host, *spp, (sizeof host)); | ||||
|  | ||||
| @@ -471,6 +426,6 @@ int ifconfig_main(int argc, char **argv) | ||||
|  | ||||
| 	} /* end of while-loop */ | ||||
|  | ||||
|         exit(0); | ||||
|         return goterr; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user