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

📄 iproute.c

📁 busybox-1.2.0,标准的Linux工具集[最新].对linux下软件的开发有着非常大的作用.
💻 C
📖 第 1 页 / 共 2 页
字号:
		struct rtmsg rtm;	} req;	struct sockaddr_nl nladdr;	memset(&nladdr, 0, sizeof(nladdr));	memset(&req, 0, sizeof(req));	nladdr.nl_family = AF_NETLINK;	req.nlh.nlmsg_len = sizeof(req);	req.nlh.nlmsg_type = RTM_GETROUTE;	req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_REQUEST;	req.nlh.nlmsg_pid = 0;	req.nlh.nlmsg_seq = rth->dump = ++rth->seq;	req.rtm.rtm_family = family;	req.rtm.rtm_flags |= RTM_F_CLONED;	return sendto(rth->fd, (void*)&req, sizeof(req), 0, (struct sockaddr*)&nladdr, sizeof(nladdr));}static int iproute_flush_cache(void){#define ROUTE_FLUSH_PATH "/proc/sys/net/ipv4/route/flush"	int len;	int flush_fd = open (ROUTE_FLUSH_PATH, O_WRONLY);	char *buffer = "-1";	if (flush_fd < 0) {		fprintf (stderr, "Cannot open \"%s\"\n", ROUTE_FLUSH_PATH);		return -1;	}	len = strlen (buffer);	if ((write (flush_fd, (void *)buffer, len)) < len) {		fprintf (stderr, "Cannot flush routing cache\n");		return -1;	}	close(flush_fd);	return 0;}static void iproute_reset_filter(void){	memset(&filter, 0, sizeof(filter));	filter.mdst.bitlen = -1;	filter.msrc.bitlen = -1;}static int iproute_list_or_flush(int argc, char **argv, int flush){	int do_ipv6 = preferred_family;	struct rtnl_handle rth;	char *id = NULL;	char *od = NULL;	iproute_reset_filter();	filter.tb = RT_TABLE_MAIN;	if (flush && argc <= 0) {		bb_error_msg(bb_msg_requires_arg, "\"ip route flush\"");		return -1;	}	while (argc > 0) {		if (matches(*argv, "protocol") == 0) {			uint32_t prot = 0;			NEXT_ARG();			filter.protocolmask = -1;			if (rtnl_rtprot_a2n(&prot, *argv)) {				if (strcmp(*argv, "all") != 0) {					invarg(*argv, "protocol");				}				prot = 0;				filter.protocolmask = 0;			}			filter.protocol = prot;		} else if (strcmp(*argv, "dev") == 0 ||			   strcmp(*argv, "oif") == 0) {			NEXT_ARG();			od = *argv;		} else if (strcmp(*argv, "iif") == 0) {			NEXT_ARG();			id = *argv;		} else if (matches(*argv, "from") == 0) {			NEXT_ARG();			if (matches(*argv, "root") == 0) {				NEXT_ARG();				get_prefix(&filter.rsrc, *argv, do_ipv6);			} else if (matches(*argv, "match") == 0) {				NEXT_ARG();				get_prefix(&filter.msrc, *argv, do_ipv6);			} else {				if (matches(*argv, "exact") == 0) {					NEXT_ARG();				}				get_prefix(&filter.msrc, *argv, do_ipv6);				filter.rsrc = filter.msrc;			}		} else {			if (matches(*argv, "to") == 0) {				NEXT_ARG();			}			if (matches(*argv, "root") == 0) {				NEXT_ARG();				get_prefix(&filter.rdst, *argv, do_ipv6);			} else if (matches(*argv, "match") == 0) {				NEXT_ARG();				get_prefix(&filter.mdst, *argv, do_ipv6);			} else if (matches(*argv, "table") == 0) {				NEXT_ARG();				if (matches(*argv, "cache") == 0) {					filter.tb = -1;				} else if (matches(*argv, "main") != 0) {					invarg(*argv, "table");				}			} else if (matches(*argv, "cache") == 0) {				filter.tb = -1;			} else {				if (matches(*argv, "exact") == 0) {					NEXT_ARG();				}				get_prefix(&filter.mdst, *argv, do_ipv6);				filter.rdst = filter.mdst;			}		}		argc--; argv++;	}	if (do_ipv6 == AF_UNSPEC && filter.tb) {		do_ipv6 = AF_INET;	}	if (rtnl_open(&rth, 0) < 0) {		exit(1);	}	ll_init_map(&rth);	if (id || od)  {		int idx;		if (id) {			if ((idx = ll_name_to_index(id)) == 0) {				bb_error_msg("Cannot find device \"%s\"", id);				return -1;			}			filter.iif = idx;			filter.iifmask = -1;		}		if (od) {			if ((idx = ll_name_to_index(od)) == 0) {				bb_error_msg("Cannot find device \"%s\"", od);			}			filter.oif = idx;			filter.oifmask = -1;		}	}	if (flush) {		char flushb[4096-512];		if (filter.tb == -1) {			if (do_ipv6 != AF_INET6)				iproute_flush_cache();			if (do_ipv6 == AF_INET)				return 0;		}		filter.flushb = flushb;		filter.flushp = 0;		filter.flushe = sizeof(flushb);		filter.rth = &rth;		for (;;) {			if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) {				perror("Cannot send dump request");				return -1;			}			filter.flushed = 0;			if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) {				bb_error_msg("Flush terminated\n");				return -1;			}			if (filter.flushed == 0) {				fflush(stdout);				return 0;			}			if (flush_update() < 0)				exit(1);		}	}	if (filter.tb != -1) {		if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) {			bb_perror_msg_and_die("Cannot send dump request");		}	} else {		if (rtnl_rtcache_request(&rth, do_ipv6) < 0) {			bb_perror_msg_and_die("Cannot send dump request");		}	}	if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) {		bb_error_msg_and_die("Dump terminated");	}	exit(0);}static int iproute_get(int argc, char **argv){	struct rtnl_handle rth;	struct {		struct nlmsghdr		n;		struct rtmsg		r;		char			buf[1024];	} req;	char  *idev = NULL;	char  *odev = NULL;	int connected = 0;	int from_ok = 0;	static const char * const options[] =		{ "from", "iif", "oif", "dev", "notify", "connected", "to", 0 };	memset(&req, 0, sizeof(req));	iproute_reset_filter();	req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg));	req.n.nlmsg_flags = NLM_F_REQUEST;	req.n.nlmsg_type = RTM_GETROUTE;	req.r.rtm_family = preferred_family;	req.r.rtm_table = 0;	req.r.rtm_protocol = 0;	req.r.rtm_scope = 0;	req.r.rtm_type = 0;	req.r.rtm_src_len = 0;	req.r.rtm_dst_len = 0;	req.r.rtm_tos = 0;	while (argc > 0) {		switch (compare_string_array(options, *argv)) {			case 0: /* from */			{				inet_prefix addr;				NEXT_ARG();				from_ok = 1;				get_prefix(&addr, *argv, req.r.rtm_family);				if (req.r.rtm_family == AF_UNSPEC) {					req.r.rtm_family = addr.family;				}				if (addr.bytelen) {					addattr_l(&req.n, sizeof(req), RTA_SRC, &addr.data, addr.bytelen);				}				req.r.rtm_src_len = addr.bitlen;				break;			}			case 1: /* iif */				NEXT_ARG();				idev = *argv;				break;			case 2: /* oif */			case 3: /* dev */				NEXT_ARG();				odev = *argv;				break;			case 4: /* notify */				req.r.rtm_flags |= RTM_F_NOTIFY;				break;			case 5: /* connected */				connected = 1;				break;			case 6: /* to */				NEXT_ARG();			default:			{				inet_prefix addr;				get_prefix(&addr, *argv, req.r.rtm_family);				if (req.r.rtm_family == AF_UNSPEC) {					req.r.rtm_family = addr.family;				}				if (addr.bytelen) {					addattr_l(&req.n, sizeof(req), RTA_DST, &addr.data, addr.bytelen);				}				req.r.rtm_dst_len = addr.bitlen;			}			argc--; argv++;		}	}	if (req.r.rtm_dst_len == 0) {		bb_error_msg_and_die("need at least destination address");	}	if (rtnl_open(&rth, 0) < 0)		exit(1);	ll_init_map(&rth);	if (idev || odev)  {		int idx;		if (idev) {			if ((idx = ll_name_to_index(idev)) == 0) {				bb_error_msg("Cannot find device \"%s\"", idev);				return -1;			}			addattr32(&req.n, sizeof(req), RTA_IIF, idx);		}		if (odev) {			if ((idx = ll_name_to_index(odev)) == 0) {				bb_error_msg("Cannot find device \"%s\"", odev);				return -1;			}			addattr32(&req.n, sizeof(req), RTA_OIF, idx);		}	}	if (req.r.rtm_family == AF_UNSPEC) {		req.r.rtm_family = AF_INET;	}	if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) {		exit(2);	}	if (connected && !from_ok) {		struct rtmsg *r = NLMSG_DATA(&req.n);		int len = req.n.nlmsg_len;		struct rtattr * tb[RTA_MAX+1];		if (print_route(NULL, &req.n, (void*)stdout) < 0) {			bb_error_msg_and_die("An error :-)");		}		if (req.n.nlmsg_type != RTM_NEWROUTE) {			bb_error_msg("Not a route?");			return -1;		}		len -= NLMSG_LENGTH(sizeof(*r));		if (len < 0) {			bb_error_msg("Wrong len %d", len);			return -1;		}		memset(tb, 0, sizeof(tb));		parse_rtattr(tb, RTA_MAX, RTM_RTA(r), len);		if (tb[RTA_PREFSRC]) {			tb[RTA_PREFSRC]->rta_type = RTA_SRC;			r->rtm_src_len = 8*RTA_PAYLOAD(tb[RTA_PREFSRC]);		} else if (!tb[RTA_SRC]) {			bb_error_msg("Failed to connect the route");			return -1;		}		if (!odev && tb[RTA_OIF]) {			tb[RTA_OIF]->rta_type = 0;		}		if (tb[RTA_GATEWAY]) {			tb[RTA_GATEWAY]->rta_type = 0;		}		if (!idev && tb[RTA_IIF]) {			tb[RTA_IIF]->rta_type = 0;		}		req.n.nlmsg_flags = NLM_F_REQUEST;		req.n.nlmsg_type = RTM_GETROUTE;		if (rtnl_talk(&rth, &req.n, 0, 0, &req.n, NULL, NULL) < 0) {			exit(2);		}	}	if (print_route(NULL, &req.n, (void*)stdout) < 0) {		bb_error_msg_and_die("An error :-)");	}	exit(0);}int do_iproute(int argc, char **argv){	static const char * const ip_route_commands[] =		{ "add", "append", "change", "chg", "delete", "del", "get",		"list", "show", "prepend", "replace", "test", "flush", 0 };	int command_num = 7;	unsigned int flags = 0;	int cmd = RTM_NEWROUTE;	if (*argv) {		command_num = compare_string_array(ip_route_commands, *argv);	}	switch(command_num) {		case 0: /* add*/			flags = NLM_F_CREATE|NLM_F_EXCL;			break;		case 1: /* append */			flags = NLM_F_CREATE|NLM_F_APPEND;			break;		case 2: /* change */		case 3: /* chg */			flags = NLM_F_REPLACE;			break;		case 4: /* delete */		case 5: /* del */			cmd = RTM_DELROUTE;			break;		case 6: /* get */			return iproute_get(argc-1, argv+1);		case 7: /* list */		case 8: /* show */			return iproute_list_or_flush(argc-1, argv+1, 0);		case 9: /* prepend */			flags = NLM_F_CREATE;		case 10: /* replace */			flags = NLM_F_CREATE|NLM_F_REPLACE;		case 11: /* test */			flags = NLM_F_EXCL;		case 12: /* flush */			return iproute_list_or_flush(argc-1, argv+1, 1);		default:			bb_error_msg_and_die("Unknown command %s", *argv);	}	return iproute_modify(cmd, flags, argc-1, argv+1);}

⌨️ 快捷键说明

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