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

📄 ipaddress.c

📁 busybox-1.2.0,标准的Linux工具集[最新].对linux下软件的开发有着非常大的作用.
💻 C
📖 第 1 页 / 共 2 页
字号:
int ipaddr_list_or_flush(int argc, char **argv, int flush){	static const char *const option[] = { "to", "scope", "up", "label", "dev", 0 };	struct nlmsg_list *linfo = NULL;	struct nlmsg_list *ainfo = NULL;	struct nlmsg_list *l;	struct rtnl_handle rth;	char *filter_dev = NULL;	int no_link = 0;	ipaddr_reset_filter(oneline);	filter.showqueue = 1;	if (filter.family == AF_UNSPEC)		filter.family = preferred_family;	if (flush) {		if (argc <= 0) {			bb_error_msg(bb_msg_requires_arg, "flush");			return -1;		}		if (filter.family == AF_PACKET) {			bb_error_msg("Cannot flush link addresses.");			return -1;		}	}	while (argc > 0) {		const int option_num = compare_string_array(option, *argv);		switch (option_num) {			case 0: /* to */				NEXT_ARG();				get_prefix(&filter.pfx, *argv, filter.family);				if (filter.family == AF_UNSPEC) {					filter.family = filter.pfx.family;				}				break;			case 1: /* scope */			{				uint32_t scope = 0;				NEXT_ARG();				filter.scopemask = -1;				if (rtnl_rtscope_a2n(&scope, *argv)) {					if (strcmp(*argv, "all") != 0) {						invarg(*argv, "scope");					}					scope = RT_SCOPE_NOWHERE;					filter.scopemask = 0;				}				filter.scope = scope;				break;			}			case 2: /* up */				filter.up = 1;				break;			case 3: /* label */				NEXT_ARG();				filter.label = *argv;				break;			case 4: /* dev */				NEXT_ARG();			default:				if (filter_dev) {					duparg2("dev", *argv);				}				filter_dev = *argv;		}		argv++;		argc--;	}	if (rtnl_open(&rth, 0) < 0)		exit(1);	if (rtnl_wilddump_request(&rth, preferred_family, RTM_GETLINK) < 0) {		bb_perror_msg_and_die("Cannot send dump request");	}	if (rtnl_dump_filter(&rth, store_nlmsg, &linfo, NULL, NULL) < 0) {		bb_error_msg_and_die("Dump terminated");	}	if (filter_dev) {		filter.ifindex = ll_name_to_index(filter_dev);		if (filter.ifindex <= 0) {			bb_error_msg("Device \"%s\" does not exist", filter_dev);			return -1;		}	}	if (flush) {		char flushb[4096-512];		filter.flushb = flushb;		filter.flushp = 0;		filter.flushe = sizeof(flushb);		filter.rth = &rth;		for (;;) {			if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) {				perror("Cannot send dump request");				exit(1);			}			filter.flushed = 0;			if (rtnl_dump_filter(&rth, print_addrinfo, stdout, NULL, NULL) < 0) {				fprintf(stderr, "Flush terminated\n");				exit(1);			}			if (filter.flushed == 0) {				fflush(stdout);				return 0;			}			if (flush_update() < 0)				exit(1);		}	}	if (filter.family != AF_PACKET) {		if (rtnl_wilddump_request(&rth, filter.family, RTM_GETADDR) < 0) {			bb_perror_msg_and_die("Cannot send dump request");		}		if (rtnl_dump_filter(&rth, store_nlmsg, &ainfo, NULL, NULL) < 0) {			bb_error_msg_and_die("Dump terminated");		}	}	if (filter.family && filter.family != AF_PACKET) {		struct nlmsg_list **lp;		lp=&linfo;		if (filter.oneline)			no_link = 1;		while ((l=*lp)!=NULL) {			int ok = 0;			struct ifinfomsg *ifi = NLMSG_DATA(&l->h);			struct nlmsg_list *a;			for (a=ainfo; a; a=a->next) {				struct nlmsghdr *n = &a->h;				struct ifaddrmsg *ifa = NLMSG_DATA(n);				if (ifa->ifa_index != ifi->ifi_index ||				    (filter.family && filter.family != ifa->ifa_family))					continue;				if ((filter.scope^ifa->ifa_scope)&filter.scopemask)					continue;				if ((filter.flags^ifa->ifa_flags)&filter.flagmask)					continue;				if (filter.pfx.family || filter.label) {					struct rtattr *tb[IFA_MAX+1];					memset(tb, 0, sizeof(tb));					parse_rtattr(tb, IFA_MAX, IFA_RTA(ifa), IFA_PAYLOAD(n));					if (!tb[IFA_LOCAL])						tb[IFA_LOCAL] = tb[IFA_ADDRESS];					if (filter.pfx.family && tb[IFA_LOCAL]) {						inet_prefix dst;						memset(&dst, 0, sizeof(dst));						dst.family = ifa->ifa_family;						memcpy(&dst.data, RTA_DATA(tb[IFA_LOCAL]), RTA_PAYLOAD(tb[IFA_LOCAL]));						if (inet_addr_match(&dst, &filter.pfx, filter.pfx.bitlen))							continue;					}					if (filter.label) {						SPRINT_BUF(b1);						const char *label;						if (tb[IFA_LABEL])							label = RTA_DATA(tb[IFA_LABEL]);						else							label = ll_idx_n2a(ifa->ifa_index, b1);						if (fnmatch(filter.label, label, 0) != 0)							continue;					}				}				ok = 1;				break;			}			if (!ok)				*lp = l->next;			else				lp = &l->next;		}	}	for (l=linfo; l; l = l->next) {		if (no_link || print_linkinfo(NULL, &l->h, stdout) == 0) {			struct ifinfomsg *ifi = NLMSG_DATA(&l->h);			if (filter.family != AF_PACKET)				print_selected_addrinfo(ifi->ifi_index, ainfo, stdout);		}		fflush(stdout);	}	exit(0);}static int default_scope(inet_prefix *lcl){	if (lcl->family == AF_INET) {		if (lcl->bytelen >= 1 && *(__u8*)&lcl->data == 127)			return RT_SCOPE_HOST;	}	return 0;}static int ipaddr_modify(int cmd, int argc, char **argv){	static const char *const option[] = {		"peer", "remote", "broadcast", "brd",		"anycast", "scope", "dev", "label", "local", 0	};	struct rtnl_handle rth;	struct {		struct nlmsghdr		n;		struct ifaddrmsg	ifa;		char			buf[256];	} req;	char  *d = NULL;	char  *l = NULL;	inet_prefix lcl;	inet_prefix peer;	int local_len = 0;	int peer_len = 0;	int brd_len = 0;	int any_len = 0;	int scoped = 0;	memset(&req, 0, sizeof(req));	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));	req.n.nlmsg_flags = NLM_F_REQUEST;	req.n.nlmsg_type = cmd;	req.ifa.ifa_family = preferred_family;	while (argc > 0) {		const int option_num = compare_string_array(option, *argv);		switch (option_num) {			case 0: /* peer */			case 1: /* remote */				NEXT_ARG();				if (peer_len) {					duparg("peer", *argv);				}				get_prefix(&peer, *argv, req.ifa.ifa_family);				peer_len = peer.bytelen;				if (req.ifa.ifa_family == AF_UNSPEC) {					req.ifa.ifa_family = peer.family;				}				addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &peer.data, peer.bytelen);				req.ifa.ifa_prefixlen = peer.bitlen;				break;			case 2: /* broadcast */			case 3: /* brd */			{				inet_prefix addr;				NEXT_ARG();				if (brd_len) {					duparg("broadcast", *argv);				}				if (strcmp(*argv, "+") == 0) {					brd_len = -1;				}				else if (strcmp(*argv, "-") == 0) {					brd_len = -2;				} else {					get_addr(&addr, *argv, req.ifa.ifa_family);					if (req.ifa.ifa_family == AF_UNSPEC)						req.ifa.ifa_family = addr.family;					addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &addr.data, addr.bytelen);					brd_len = addr.bytelen;				}				break;			}			case 4: /* anycast */			{				inet_prefix addr;				NEXT_ARG();				if (any_len) {					duparg("anycast", *argv);				}				get_addr(&addr, *argv, req.ifa.ifa_family);				if (req.ifa.ifa_family == AF_UNSPEC) {					req.ifa.ifa_family = addr.family;				}				addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen);				any_len = addr.bytelen;				break;			}			case 5: /* scope */			{				uint32_t scope = 0;				NEXT_ARG();				if (rtnl_rtscope_a2n(&scope, *argv)) {					invarg(*argv, "scope");				}				req.ifa.ifa_scope = scope;				scoped = 1;				break;			}			case 6: /* dev */				NEXT_ARG();				d = *argv;				break;			case 7: /* label */				NEXT_ARG();				l = *argv;				addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l)+1);				break;			case 8:	/* local */				NEXT_ARG();			default:				if (local_len) {					duparg2("local", *argv);				}				get_prefix(&lcl, *argv, req.ifa.ifa_family);				if (req.ifa.ifa_family == AF_UNSPEC) {					req.ifa.ifa_family = lcl.family;				}				addattr_l(&req.n, sizeof(req), IFA_LOCAL, &lcl.data, lcl.bytelen);				local_len = lcl.bytelen;		}		argc--;		argv++;	}	if (d == NULL) {		bb_error_msg(bb_msg_requires_arg,"\"dev\"");		return -1;	}	if (l && matches(d, l) != 0) {		bb_error_msg_and_die("\"dev\" (%s) must match \"label\" (%s)", d, l);	}	if (peer_len == 0 && local_len && cmd != RTM_DELADDR) {		peer = lcl;		addattr_l(&req.n, sizeof(req), IFA_ADDRESS, &lcl.data, lcl.bytelen);	}	if (req.ifa.ifa_prefixlen == 0)		req.ifa.ifa_prefixlen = lcl.bitlen;	if (brd_len < 0 && cmd != RTM_DELADDR) {		inet_prefix brd;		int i;		if (req.ifa.ifa_family != AF_INET) {			bb_error_msg("Broadcast can be set only for IPv4 addresses");			return -1;		}		brd = peer;		if (brd.bitlen <= 30) {			for (i=31; i>=brd.bitlen; i--) {				if (brd_len == -1)					brd.data[0] |= htonl(1<<(31-i));				else					brd.data[0] &= ~htonl(1<<(31-i));			}			addattr_l(&req.n, sizeof(req), IFA_BROADCAST, &brd.data, brd.bytelen);			brd_len = brd.bytelen;		}	}	if (!scoped && cmd != RTM_DELADDR)		req.ifa.ifa_scope = default_scope(&lcl);	if (rtnl_open(&rth, 0) < 0)		exit(1);	ll_init_map(&rth);	if ((req.ifa.ifa_index = ll_name_to_index(d)) == 0) {		bb_error_msg("Cannot find device \"%s\"", d);		return -1;	}	if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)		exit(2);	exit(0);}int do_ipaddr(int argc, char **argv){	static const char *const commands[] = {		"add", "delete", "list", "show", "lst", "flush", 0	};	int command_num = 2;	if (*argv) {		command_num = compare_string_array(commands, *argv);	}	switch (command_num) {		case 0: /* add */			return ipaddr_modify(RTM_NEWADDR, argc-1, argv+1);		case 1: /* delete */			return ipaddr_modify(RTM_DELADDR, argc-1, argv+1);		case 2: /* list */		case 3: /* show */		case 4: /* lst */			return ipaddr_list_or_flush(argc-1, argv+1, 0);		case 5: /* flush */			return ipaddr_list_or_flush(argc-1, argv+1, 1);	}	bb_error_msg_and_die("Unknown command %s", *argv);}

⌨️ 快捷键说明

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