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

📄 ifenslave.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		dstaddr = ifr.ifr_dstaddr;	strcpy(ifr.ifr_name, ifname);	if (ioctl(skfd, SIOCGIFBRDADDR, &ifr) < 0) {		memset(&broadaddr, 0, sizeof(struct sockaddr));	} else		broadaddr = ifr.ifr_broadaddr;	strcpy(ifr.ifr_name, ifname);	if (ioctl(skfd, SIOCGIFNETMASK, &ifr) < 0) {		memset(&netmask, 0, sizeof(struct sockaddr));	} else		netmask = ifr.ifr_netmask;	return 0;}static void if_print(char *ifname){	char buff[1024];	struct ifconf ifc;	struct ifreq *ifr;	int i;	if (ifname == (char *)NULL) {		ifc.ifc_len = sizeof(buff);		ifc.ifc_buf = buff;		if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) {			perror("SIOCGIFCONF failed");			return;		}		ifr = ifc.ifc_req;		for (i = ifc.ifc_len / sizeof(struct ifreq); --i >= 0; ifr++) {			if (if_getconfig(ifr->ifr_name) < 0) {				fprintf(stderr,					"%s: unknown interface.\n",					ifr->ifr_name);				continue;			}			if (((mif_flags & IFF_UP) == 0) && !opt_a) continue;			/*ife_print(&ife);*/		}	} else {		if (if_getconfig(ifname) < 0) {			fprintf(stderr,				"%s: unknown interface.\n", ifname);		}	}}static int get_drv_info(char *master_ifname){	struct ifreq ifr;	struct ethtool_drvinfo info;	char *endptr;	memset(&ifr, 0, sizeof(ifr));	strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);	ifr.ifr_data = (caddr_t)&info;	info.cmd = ETHTOOL_GDRVINFO;	strncpy(info.driver, "ifenslave", 32);	snprintf(info.fw_version, 32, "%d", BOND_ABI_VERSION);	if (ioctl(skfd, SIOCETHTOOL, &ifr) < 0) {		if (errno == EOPNOTSUPP) {			goto out;		}		saved_errno = errno;		v_print("Master '%s': Error: get bonding info failed %s\n",			master_ifname, strerror(saved_errno));		return 1;	}	abi_ver = strtoul(info.fw_version, &endptr, 0);	if (*endptr) {                v_print("Master '%s': Error: got invalid string as an ABI "			"version from the bonding module\n",			master_ifname);		return 1;	}out:	v_print("ABI ver is %d\n", abi_ver);	return 0;}static int change_active(char *master_ifname, char *slave_ifname){	struct ifreq ifr;	int res = 0;	if (!(slave_flags.ifr_flags & IFF_SLAVE)) {		fprintf(stderr,			"Illegal operation: The specified slave interface "			"'%s' is not a slave\n",			slave_ifname);		return 1;	}	strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);	strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ);	if ((ioctl(skfd, SIOCBONDCHANGEACTIVE, &ifr) < 0) &&	    (ioctl(skfd, BOND_CHANGE_ACTIVE_OLD, &ifr) < 0)) {		saved_errno = errno;		v_print("Master '%s': Error: SIOCBONDCHANGEACTIVE failed: "			"%s\n",			master_ifname, strerror(saved_errno));		res = 1;	}	return res;}static int enslave(char *master_ifname, char *slave_ifname){	struct ifreq ifr;	int res = 0;	if (slave_flags.ifr_flags & IFF_SLAVE) {		fprintf(stderr,			"Illegal operation: The specified slave interface "			"'%s' is already a slave\n",			slave_ifname);		return 1;	}	res = set_if_down(slave_ifname, slave_flags.ifr_flags);	if (res) {		fprintf(stderr,			"Slave '%s': Error: bring interface down failed\n",			slave_ifname);		return res;	}	if (abi_ver < 2) {		/* Older bonding versions would panic if the slave has no IP		 * address, so get the IP setting from the master.		 */		set_if_addr(master_ifname, slave_ifname);	} else {		res = clear_if_addr(slave_ifname);		if (res) {			fprintf(stderr,				"Slave '%s': Error: clear address failed\n",				slave_ifname);			return res;		}	}	if (master_mtu.ifr_mtu != slave_mtu.ifr_mtu) {		res = set_slave_mtu(slave_ifname, master_mtu.ifr_mtu);		if (res) {			fprintf(stderr,				"Slave '%s': Error: set MTU failed\n",				slave_ifname);			return res;		}	}	if (hwaddr_set) {		/* Master already has an hwaddr		 * so set it's hwaddr to the slave		 */		if (abi_ver < 1) {			/* The driver is using an old ABI, so			 * the application sets the slave's			 * hwaddr			 */			res = set_slave_hwaddr(slave_ifname,					       &(master_hwaddr.ifr_hwaddr));			if (res) {				fprintf(stderr,					"Slave '%s': Error: set hw address "					"failed\n",					slave_ifname);				goto undo_mtu;			}			/* For old ABI the application needs to bring the			 * slave back up			 */			res = set_if_up(slave_ifname, slave_flags.ifr_flags);			if (res) {				fprintf(stderr,					"Slave '%s': Error: bring interface "					"down failed\n",					slave_ifname);				goto undo_slave_mac;			}		}		/* The driver is using a new ABI,		 * so the driver takes care of setting		 * the slave's hwaddr and bringing		 * it up again		 */	} else {		/* No hwaddr for master yet, so		 * set the slave's hwaddr to it		 */		if (abi_ver < 1) {			/* For old ABI, the master needs to be			 * down before setting it's hwaddr			 */			res = set_if_down(master_ifname, master_flags.ifr_flags);			if (res) {				fprintf(stderr,					"Master '%s': Error: bring interface "					"down failed\n",					master_ifname);				goto undo_mtu;			}		}		res = set_master_hwaddr(master_ifname,					&(slave_hwaddr.ifr_hwaddr));		if (res) {			fprintf(stderr,				"Master '%s': Error: set hw address "				"failed\n",				master_ifname);			goto undo_mtu;		}		if (abi_ver < 1) {			/* For old ABI, bring the master			 * back up			 */			res = set_if_up(master_ifname, master_flags.ifr_flags);			if (res) {				fprintf(stderr,					"Master '%s': Error: bring interface "					"up failed\n",					master_ifname);				goto undo_master_mac;			}		}		hwaddr_set = 1;	}	/* Do the real thing */	strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);	strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ);	if ((ioctl(skfd, SIOCBONDENSLAVE, &ifr) < 0) &&	    (ioctl(skfd, BOND_ENSLAVE_OLD, &ifr) < 0)) {		saved_errno = errno;		v_print("Master '%s': Error: SIOCBONDENSLAVE failed: %s\n",			master_ifname, strerror(saved_errno));		res = 1;	}	if (res) {		goto undo_master_mac;	}	return 0;/* rollback (best effort) */undo_master_mac:	set_master_hwaddr(master_ifname, &(master_hwaddr.ifr_hwaddr));	hwaddr_set = 0;	goto undo_mtu;undo_slave_mac:	set_slave_hwaddr(slave_ifname, &(slave_hwaddr.ifr_hwaddr));undo_mtu:	set_slave_mtu(slave_ifname, slave_mtu.ifr_mtu);	return res;}static int release(char *master_ifname, char *slave_ifname){	struct ifreq ifr;	int res = 0;	if (!(slave_flags.ifr_flags & IFF_SLAVE)) {		fprintf(stderr,			"Illegal operation: The specified slave interface "			"'%s' is not a slave\n",			slave_ifname);		return 1;	}	strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);	strncpy(ifr.ifr_slave, slave_ifname, IFNAMSIZ);	if ((ioctl(skfd, SIOCBONDRELEASE, &ifr) < 0) &&	    (ioctl(skfd, BOND_RELEASE_OLD, &ifr) < 0)) {		saved_errno = errno;		v_print("Master '%s': Error: SIOCBONDRELEASE failed: %s\n",			master_ifname, strerror(saved_errno));		return 1;	} else if (abi_ver < 1) {		/* The driver is using an old ABI, so we'll set the interface		 * down to avoid any conflicts due to same MAC/IP		 */		res = set_if_down(slave_ifname, slave_flags.ifr_flags);		if (res) {			fprintf(stderr,				"Slave '%s': Error: bring interface "				"down failed\n",				slave_ifname);		}	}	/* set to default mtu */	set_slave_mtu(slave_ifname, 1500);	return res;}static int get_if_settings(char *ifname, struct dev_ifr ifra[]){	int i;	int res = 0;	for (i = 0; ifra[i].req_ifr; i++) {		strncpy(ifra[i].req_ifr->ifr_name, ifname, IFNAMSIZ);		res = ioctl(skfd, ifra[i].req_type, ifra[i].req_ifr);		if (res < 0) {			saved_errno = errno;			v_print("Interface '%s': Error: %s failed: %s\n",				ifname, ifra[i].req_name,				strerror(saved_errno));			return saved_errno;		}	}	return 0;}static int get_slave_flags(char *slave_ifname){	int res = 0;	strncpy(slave_flags.ifr_name, slave_ifname, IFNAMSIZ);	res = ioctl(skfd, SIOCGIFFLAGS, &slave_flags);	if (res < 0) {		saved_errno = errno;		v_print("Slave '%s': Error: SIOCGIFFLAGS failed: %s\n",			slave_ifname, strerror(saved_errno));	} else {		v_print("Slave %s: flags %04X.\n",			slave_ifname, slave_flags.ifr_flags);	}	return res;}static int set_master_hwaddr(char *master_ifname, struct sockaddr *hwaddr){	unsigned char *addr = (unsigned char *)hwaddr->sa_data;	struct ifreq ifr;	int res = 0;	strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);	memcpy(&(ifr.ifr_hwaddr), hwaddr, sizeof(struct sockaddr));	res = ioctl(skfd, SIOCSIFHWADDR, &ifr);	if (res < 0) {		saved_errno = errno;		v_print("Master '%s': Error: SIOCSIFHWADDR failed: %s\n",			master_ifname, strerror(saved_errno));		return res;	} else {		v_print("Master '%s': hardware address set to "			"%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n",			master_ifname, addr[0], addr[1], addr[2],			addr[3], addr[4], addr[5]);	}	return res;}static int set_slave_hwaddr(char *slave_ifname, struct sockaddr *hwaddr){	unsigned char *addr = (unsigned char *)hwaddr->sa_data;	struct ifreq ifr;	int res = 0;	strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ);	memcpy(&(ifr.ifr_hwaddr), hwaddr, sizeof(struct sockaddr));	res = ioctl(skfd, SIOCSIFHWADDR, &ifr);	if (res < 0) {		saved_errno = errno;		v_print("Slave '%s': Error: SIOCSIFHWADDR failed: %s\n",			slave_ifname, strerror(saved_errno));		if (saved_errno == EBUSY) {			v_print("  The device is busy: it must be idle "				"before running this command.\n");		} else if (saved_errno == EOPNOTSUPP) {			v_print("  The device does not support setting "				"the MAC address.\n"				"  Your kernel likely does not support slave "				"devices.\n");		} else if (saved_errno == EINVAL) {			v_print("  The device's address type does not match "				"the master's address type.\n");		}		return res;	} else {		v_print("Slave '%s': hardware address set to "			"%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n",			slave_ifname, addr[0], addr[1], addr[2],			addr[3], addr[4], addr[5]);	}	return res;}static int set_slave_mtu(char *slave_ifname, int mtu){	struct ifreq ifr;	int res = 0;	ifr.ifr_mtu = mtu;	strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ);	res = ioctl(skfd, SIOCSIFMTU, &ifr);	if (res < 0) {		saved_errno = errno;		v_print("Slave '%s': Error: SIOCSIFMTU failed: %s\n",			slave_ifname, strerror(saved_errno));	} else {		v_print("Slave '%s': MTU set to %d.\n", slave_ifname, mtu);	}	return res;}static int set_if_flags(char *ifname, short flags){	struct ifreq ifr;	int res = 0;	ifr.ifr_flags = flags;	strncpy(ifr.ifr_name, ifname, IFNAMSIZ);	res = ioctl(skfd, SIOCSIFFLAGS, &ifr);	if (res < 0) {		saved_errno = errno;		v_print("Interface '%s': Error: SIOCSIFFLAGS failed: %s\n",			ifname, strerror(saved_errno));	} else {		v_print("Interface '%s': flags set to %04X.\n", ifname, flags);	}	return res;}static int set_if_up(char *ifname, short flags){	return set_if_flags(ifname, flags | IFF_UP);}static int set_if_down(char *ifname, short flags){	return set_if_flags(ifname, flags & ~IFF_UP);}static int clear_if_addr(char *ifname){	struct ifreq ifr;	int res = 0;	strncpy(ifr.ifr_name, ifname, IFNAMSIZ);	ifr.ifr_addr.sa_family = AF_INET;	memset(ifr.ifr_addr.sa_data, 0, sizeof(ifr.ifr_addr.sa_data));	res = ioctl(skfd, SIOCSIFADDR, &ifr);	if (res < 0) {		saved_errno = errno;		v_print("Interface '%s': Error: SIOCSIFADDR failed: %s\n",			ifname, strerror(saved_errno));	} else {		v_print("Interface '%s': address cleared\n", ifname);	}	return res;}static int set_if_addr(char *master_ifname, char *slave_ifname){	struct ifreq ifr;	int res;	unsigned char *ipaddr;	int i;	struct {		char *req_name;		char *desc;		int g_ioctl;		int s_ioctl;	} ifra[] = {		{"IFADDR", "addr", SIOCGIFADDR, SIOCSIFADDR},		{"DSTADDR", "destination addr", SIOCGIFDSTADDR, SIOCSIFDSTADDR},		{"BRDADDR", "broadcast addr", SIOCGIFBRDADDR, SIOCSIFBRDADDR},		{"NETMASK", "netmask", SIOCGIFNETMASK, SIOCSIFNETMASK},		{NULL, NULL, 0, 0},	};	for (i = 0; ifra[i].req_name; i++) {		strncpy(ifr.ifr_name, master_ifname, IFNAMSIZ);		res = ioctl(skfd, ifra[i].g_ioctl, &ifr);		if (res < 0) {			int saved_errno = errno;			v_print("Interface '%s': Error: SIOCG%s failed: %s\n",				master_ifname, ifra[i].req_name,				strerror(saved_errno));			ifr.ifr_addr.sa_family = AF_INET;			memset(ifr.ifr_addr.sa_data, 0,			       sizeof(ifr.ifr_addr.sa_data));		}		strncpy(ifr.ifr_name, slave_ifname, IFNAMSIZ);		res = ioctl(skfd, ifra[i].s_ioctl, &ifr);		if (res < 0) {			int saved_errno = errno;			v_print("Interface '%s': Error: SIOCS%s failed: %s\n",				slave_ifname, ifra[i].req_name,				strerror(saved_errno));		}		ipaddr = ifr.ifr_addr.sa_data;		v_print("Interface '%s': set IP %s to %d.%d.%d.%d\n",			slave_ifname, ifra[i].desc,			ipaddr[0], ipaddr[1], ipaddr[2], ipaddr[3]);	}	return 0;}/* * Local variables: *  version-control: t *  kept-new-versions: 5 *  c-indent-level: 4 *  c-basic-offset: 4 *  tab-width: 4 *  compile-command: "gcc -Wall -Wstrict-prototypes -O -I/usr/src/linux/include ifenslave.c -o ifenslave" * End: */

⌨️ 快捷键说明

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