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