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

📄 ipaddress.c

📁 busybox最新版的源码:学习和应用的好东东,多的不说了,大家看后再说吧
💻 C
📖 第 1 页 / 共 2 页
字号:
	h->next = NULL;	for (lp = linfo; *lp; lp = &(*lp)->next) /* NOTHING */;	*lp = h;	ll_remember_index(who, n, NULL);	return 0;}static void ipaddr_reset_filter(int _oneline){	memset(&filter, 0, sizeof(filter));	filter.oneline = _oneline;}/* Return value becomes exitcode. It's okay to not return at all */int ipaddr_list_or_flush(int argc, char **argv, int flush){	static const char option[] ALIGN1 = "to\0""scope\0""up\0""label\0""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_and_die(bb_msg_requires_arg, "flush");		}		if (filter.family == AF_PACKET) {			bb_error_msg_and_die("cannot flush link addresses");		}	}	while (argc > 0) {		const int option_num = index_in_strings(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--;	}	xrtnl_open(&rth);	xrtnl_wilddump_request(&rth, preferred_family, RTM_GETLINK);	xrtnl_dump_filter(&rth, store_nlmsg, &linfo);	if (filter_dev) {		filter.ifindex = xll_name_to_index(filter_dev);	}	if (flush) {		char flushb[4096-512];		filter.flushb = flushb;		filter.flushp = 0;		filter.flushe = sizeof(flushb);		filter.rth = &rth;		for (;;) {			xrtnl_wilddump_request(&rth, filter.family, RTM_GETADDR);			filter.flushed = 0;			xrtnl_dump_filter(&rth, print_addrinfo, stdout);			if (filter.flushed == 0) {				return 0;			}			if (flush_update() < 0)				return 1;		}	}	if (filter.family != AF_PACKET) {		xrtnl_wilddump_request(&rth, filter.family, RTM_GETADDR);		xrtnl_dump_filter(&rth, store_nlmsg, &ainfo);	}	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); /* why? */	}	return 0;}static int default_scope(inet_prefix *lcl){	if (lcl->family == AF_INET) {		if (lcl->bytelen >= 1 && *(uint8_t*)&lcl->data == 127)			return RT_SCOPE_HOST;	}	return 0;}/* Return value becomes exitcode. It's okay to not return at all */static int ipaddr_modify(int cmd, int argc, char **argv){	static const char option[] ALIGN1 =		"peer\0""remote\0""broadcast\0""brd\0"		"anycast\0""scope\0""dev\0""label\0""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;	bool 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 = index_in_strings(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 (LONE_CHAR(*argv, '+')) {					brd_len = -1;				}				else if (LONE_DASH(*argv)) {					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 && strncmp(d, l, strlen(d)) != 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_and_die("broadcast can be set only for IPv4 addresses");		}		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);	xrtnl_open(&rth);	ll_init_map(&rth);	req.ifa.ifa_index = xll_name_to_index(d);	if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)		return 2;	return 0;}/* Return value becomes exitcode. It's okay to not return at all */int do_ipaddr(int argc, char **argv){	static const char commands[] ALIGN1 =		"add\0""delete\0""list\0""show\0""lst\0""flush\0";	int command_num = 2; /* default command is list */	if (*argv) {		command_num = index_in_substrings(commands, *argv);	}	if (command_num < 0 || command_num > 5)		bb_error_msg_and_die("unknown command %s", *argv);	--argc;	++argv;	if (command_num == 0) /* add */		return ipaddr_modify(RTM_NEWADDR, argc, argv);	else if (command_num == 1) /* delete */		return ipaddr_modify(RTM_DELADDR, argc, argv);	else if (command_num == 5) /* flush */		return ipaddr_list_or_flush(argc, argv, 1);	else /* 2 == list, 3 == show, 4 == lst */		return ipaddr_list_or_flush(argc, argv, 0);}

⌨️ 快捷键说明

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