⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netdev.c

📁 klibc精简化的c程序库
💻 C
字号:
/* * ioctl-based device configuration */#include <sys/types.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <errno.h>#include <stdio.h>#include <string.h>#include <unistd.h>#include <net/if.h>#include <net/if_arp.h>#include <netinet/in.h>#include <linux/route.h>#include "netdev.h"static int cfd = -1;static void copy_name(struct netdev *dev, struct ifreq *ifr){	strncpy(ifr->ifr_name, dev->name, sizeof(ifr->ifr_name));	ifr->ifr_name[sizeof(ifr->ifr_name) - 1] = '\0';}int netdev_getflags(struct netdev *dev, short *flags){	struct ifreq ifr;	copy_name(dev, &ifr);	if (ioctl(cfd, SIOCGIFFLAGS, &ifr) == -1) {		perror("SIOCGIFFLAGS");		return -1;	}	*flags = ifr.ifr_flags;	return 0;}static int netdev_sif_addr(struct ifreq *ifr, int cmd, uint32_t addr){	struct sockaddr_in *sin = (struct sockaddr_in *)&ifr->ifr_addr;	sin->sin_family = AF_INET;	sin->sin_addr.s_addr = addr;	return ioctl(cfd, cmd, ifr);}int netdev_setaddress(struct netdev *dev){	struct ifreq ifr;	copy_name(dev, &ifr);	if (dev->ip_addr != INADDR_ANY &&	    netdev_sif_addr(&ifr, SIOCSIFADDR, dev->ip_addr) == -1) {		perror("SIOCSIFADDR");		return -1;	}	if (dev->ip_broadcast != INADDR_ANY &&	    netdev_sif_addr(&ifr, SIOCSIFBRDADDR, dev->ip_broadcast) == -1) {		perror("SIOCSIFBRDADDR");		return -1;	}	if (dev->ip_netmask != INADDR_ANY &&	    netdev_sif_addr(&ifr, SIOCSIFNETMASK, dev->ip_netmask) == -1) {		perror("SIOCSIFNETMASK");		return -1;	}	return 0;}int netdev_setdefaultroute(struct netdev *dev){	struct rtentry r;	if (dev->ip_gateway == INADDR_ANY)		return 0;	memset(&r, 0, sizeof(r));	((struct sockaddr_in *)&r.rt_dst)->sin_family = AF_INET;	((struct sockaddr_in *)&r.rt_dst)->sin_addr.s_addr = INADDR_ANY;	((struct sockaddr_in *)&r.rt_gateway)->sin_family = AF_INET;	((struct sockaddr_in *)&r.rt_gateway)->sin_addr.s_addr =	    dev->ip_gateway;	((struct sockaddr_in *)&r.rt_genmask)->sin_family = AF_INET;	((struct sockaddr_in *)&r.rt_genmask)->sin_addr.s_addr = INADDR_ANY;	r.rt_flags = RTF_UP | RTF_GATEWAY;	if (ioctl(cfd, SIOCADDRT, &r) == -1 && errno != EEXIST) {		perror("SIOCADDRT");		return -1;	}	return 0;}int netdev_setmtu(struct netdev *dev){	struct ifreq ifr;	copy_name(dev, &ifr);	ifr.ifr_mtu = dev->mtu;	return ioctl(cfd, SIOCSIFMTU, &ifr);}static int netdev_gif_addr(struct ifreq *ifr, int cmd, uint32_t * ptr){	struct sockaddr_in *sin = (struct sockaddr_in *)&ifr->ifr_addr;	if (ioctl(cfd, cmd, ifr) == -1)		return -1;	*ptr = sin->sin_addr.s_addr;	return 0;}int netdev_up(struct netdev *dev){	struct ifreq ifr;	copy_name(dev, &ifr);	if (ioctl(cfd, SIOCGIFFLAGS, &ifr) == -1) {		perror("SIOCGIFFLAGS");		return -1;	}	ifr.ifr_flags |= IFF_UP;	if (ioctl(cfd, SIOCSIFFLAGS, &ifr) == -1) {		perror("SIOCSIFFLAGS");		return -1;	}	return 0;}int netdev_down(struct netdev *dev){	struct ifreq ifr;	copy_name(dev, &ifr);	if (ioctl(cfd, SIOCGIFFLAGS, &ifr) == -1) {		perror("SIOCGIFFLAGS");		return -1;	}	ifr.ifr_flags &= ~IFF_UP;	if (ioctl(cfd, SIOCSIFFLAGS, &ifr) == -1) {		perror("SIOCSIFFLAGS");		return -1;	}	return 0;}int netdev_init_if(struct netdev *dev){	struct ifreq ifr;	if (cfd == -1)		cfd = socket(AF_INET, SOCK_DGRAM, 0);	if (cfd == -1) {		fprintf(stderr, "ipconfig: %s: socket(AF_INET): %s\n",			dev->name, strerror(errno));		return -1;	}	copy_name(dev, &ifr);	if (ioctl(cfd, SIOCGIFINDEX, &ifr) == -1) {		fprintf(stderr, "ipconfig: %s: SIOCGIFINDEX: %s\n",			dev->name, strerror(errno));		return -1;	}	dev->ifindex = ifr.ifr_ifindex;	if (ioctl(cfd, SIOCGIFMTU, &ifr) == -1) {		fprintf(stderr, "ipconfig: %s: SIOCGIFMTU: %s\n",			dev->name, strerror(errno));		return -1;	}	dev->mtu = ifr.ifr_mtu;	if (ioctl(cfd, SIOCGIFHWADDR, &ifr) == -1) {		fprintf(stderr, "ipconfig: %s: SIOCGIFHWADDR: %s\n",			dev->name, strerror(errno));		return -1;	}	dev->hwtype = ifr.ifr_hwaddr.sa_family;	dev->hwlen  = 0;	switch (dev->hwtype) {	case ARPHRD_ETHER:		dev->hwlen = 6;		break;	case ARPHRD_EUI64:		dev->hwlen = 8;		break;	case ARPHRD_LOOPBACK:		dev->hwlen = 0;		break;	default:		return -1;	}	memcpy(dev->hwaddr, ifr.ifr_hwaddr.sa_data, dev->hwlen);	memset(dev->hwbrd, 0xff, dev->hwlen);	/*	 * Try to get the current interface information.	 */	if (dev->ip_addr == INADDR_NONE &&	    netdev_gif_addr(&ifr, SIOCGIFADDR, &dev->ip_addr) == -1) {		fprintf(stderr, "ipconfig: %s: SIOCGIFADDR: %s\n",			dev->name, strerror(errno));		dev->ip_addr = 0;		dev->ip_broadcast = 0;		dev->ip_netmask = 0;		return 0;	}	if (dev->ip_broadcast == INADDR_NONE &&	    netdev_gif_addr(&ifr, SIOCGIFBRDADDR, &dev->ip_broadcast) == -1) {		fprintf(stderr, "ipconfig: %s: SIOCGIFBRDADDR: %s\n",			dev->name, strerror(errno));		dev->ip_broadcast = 0;	}	if (dev->ip_netmask == INADDR_NONE &&	    netdev_gif_addr(&ifr, SIOCGIFNETMASK, &dev->ip_netmask) == -1) {		fprintf(stderr, "ipconfig: %s: SIOCGIFNETMASK: %s\n",			dev->name, strerror(errno));		dev->ip_netmask = 0;	}	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -