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

📄 iproute.c

📁 sloedgy open sip stack source code
💻 C
📖 第 1 页 / 共 4 页
字号:
		} 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 (strcmp(*argv, "via") == 0) {
			NEXT_ARG();
			get_prefix(&filter.rvia, *argv, do_ipv6);
		} else if (strcmp(*argv, "src") == 0) {
			NEXT_ARG();
			get_prefix(&filter.rprefsrc, *argv, do_ipv6);
		} else if (matches(*argv, "realms") == 0) {
			__u32 realm;
			NEXT_ARG();
			if (get_rt_realms(&realm, *argv))
				invarg("invalid realms\n", *argv);
			filter.realm = realm;
			filter.realmmask = ~0U;
			if ((filter.realm&0xFFFF) == 0 &&
			    (*argv)[strlen(*argv) - 1] == '/')
				filter.realmmask &= ~0xFFFF;
			if ((filter.realm&0xFFFF0000U) == 0 &&
			    (strchr(*argv, '/') == NULL ||
			     (*argv)[0] == '/'))
				filter.realmmask &= ~0xFFFF0000U;
		} 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, "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;

	ll_init_map(&rth);

	if (id || od)  {
		int idx;

		if (id) {
			if ((idx = ll_name_to_index(id)) == 0) {
				fprintf(stderr, "Cannot find device \"%s\"\n", id);
				return -1;
			}
			filter.iif = idx;
			filter.iifmask = -1;
		}
		if (od) {
			if ((idx = ll_name_to_index(od)) == 0) {
				fprintf(stderr, "Cannot find device \"%s\"\n", od);
				return -1;
			}
			filter.oif = idx;
			filter.oifmask = -1;
		}
	}

	if (flush) {
		int round = 0;
		char flushb[4096-512];
		time_t start = time(0);

		if (filter.cloned) {
			if (do_ipv6 != AF_INET6) {
				iproute_flush_cache();
				if (show_stats)
					printf("*** IPv4 routing cache is flushed.\n");
			}
			if (do_ipv6 == AF_INET)
				return 0;
		}

		filter.flushb = flushb;
		filter.flushp = 0;
		filter.flushe = sizeof(flushb);

		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) {
				fprintf(stderr, "Flush terminated\n");
				return(1);
			}
			if (filter.flushed == 0) {
				if (round == 0) {
					if (!filter.cloned || do_ipv6 == AF_INET6)
						fprintf(stderr, "Nothing to flush.\n");
				} else if (show_stats)
					printf("*** Flush is complete after %d round%s ***\n", round, round>1?"s":"");
				fflush(stdout);
				return 0;
			}
			round++;
			if (flush_update() < 0)
				return(1);

			if (time(0) - start > 30) {
				printf("\n*** Flush not completed after %ld seconds, %d entries remain ***\n",
				       time(0) - start, filter.flushed);
				return(1);
			}

			if (show_stats) {
				printf("\n*** Round %d, deleting %d entries ***\n", round, filter.flushed);
				fflush(stdout);
			}
		}
	}

	if (!filter.cloned) {
		if (rtnl_wilddump_request(&rth, do_ipv6, RTM_GETROUTE) < 0) {
			perror("Cannot send dump request");
			return(1);
		}
	} else {
		if (rtnl_rtcache_request(&rth, do_ipv6) < 0) {
			perror("Cannot send dump request");
			return(1);
		}
	}

	if (rtnl_dump_filter(&rth, print_route, stdout, NULL, NULL) < 0) {
		fprintf(stderr, "Dump terminated\n");
		return(1);
	}

	return(0);
}
*/

int iproute_get(int argc, char **argv)
{
	struct {
		struct nlmsghdr 	n;
		struct rtmsg 		r;
		char   			buf[1024];
	} req;
	char  *idev = NULL;
	char  *odev = NULL;
	int connected = 0;
	int from_ok = 0;
	int ng = 0;
	
	for( ng = 0; ng < argc; ng++ )
		printf( "%s\n", argv[ng] );

	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) {
		if (strcmp(*argv, "tos") == 0 ||
		    matches(*argv, "dsfield") == 0) {
			__u32 tos;
			NEXT_ARG();
			if (rtnl_dsfield_a2n(&tos, *argv))
				invarg("TOS value is invalid\n", *argv);
			req.r.rtm_tos = tos;
		} else if (matches(*argv, "from") == 0) {
			inet_prefix addr;
			NEXT_ARG();
			if (matches(*argv, "help") == 0)
				usage();
			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;
		} else if (matches(*argv, "iif") == 0) {
			NEXT_ARG();
			idev = *argv;
		} else if (matches(*argv, "oif") == 0 ||
			   strcmp(*argv, "dev") == 0) {
			NEXT_ARG();
			odev = *argv;
		} else if (matches(*argv, "notify") == 0) {
			req.r.rtm_flags |= RTM_F_NOTIFY;
		} else if (matches(*argv, "connected") == 0) {
			connected = 1;
		} else {
			inet_prefix addr;
			if (strcmp(*argv, "to") == 0) {
				NEXT_ARG();
			}
			if (matches(*argv, "help") == 0)
				usage();
			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) {
		fprintf(stderr, "need at least destination address\n");
		return(1);
	}

	ll_init_map(&rth);

	if (idev || odev)  {
		int idx;

		if (idev) {
			if ((idx = ll_name_to_index(idev)) == 0) {
				fprintf(stderr, "Cannot find device \"%s\"\n", idev);
				return -1;
			}
			addattr32(&req.n, sizeof(req), RTA_IIF, idx);
		}
		if (odev) {
			if ((idx = ll_name_to_index(odev)) == 0) {
				fprintf(stderr, "Cannot find device \"%s\"\n", 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)
		return(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) {
			fprintf(stderr, "An error :-)\n");
			return(1);
		}

		if (req.n.nlmsg_type != RTM_NEWROUTE) {
			fprintf(stderr, "Not a route?\n");
			return -1;
		}
		len -= NLMSG_LENGTH(sizeof(*r));
		if (len < 0) {
			fprintf(stderr, "Wrong len %d\n", len);
			return -1;
		}

		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]) {
			fprintf(stderr, "Failed to connect the route\n");
			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)
			return(2);
	}

	if (print_route(NULL, &req.n, (void*)stdout) < 0) {
		fprintf(stderr, "An error :-)\n");
		return(1);
	}

	return(0);
}


int iproute_get_ex(int argc, char **argv, route_params * hparams)
{
	struct {
		struct nlmsghdr 	n;
		struct rtmsg 		r;
		char   			buf[1024];
	} req;
	char  *idev = NULL;
	char  *odev = NULL;
	int connected = 0;
	int from_ok = 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) {
		if (strcmp(*argv, "tos") == 0 ||
		    matches(*argv, "dsfield") == 0) {
			__u32 tos;
			NEXT_ARG();
			if (rtnl_dsfield_a2n(&tos, *argv))
				invarg("TOS value is invalid\n", *argv);
			req.r.rtm_tos = tos;
		} else if (matches(*argv, "from") == 0) {
			inet_prefix addr;
			NEXT_ARG();
			if (matches(*argv, "help") == 0)
				usage();
			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;
		} else if (matches(*argv, "iif") == 0) {
			NEXT_ARG();
			idev = *argv;
		} else if (matches(*argv, "oif") == 0 ||
			   strcmp(*argv, "dev") == 0) {
			NEXT_ARG();
			odev = *argv;
		} else if (matches(*argv, "notify") == 0) {
			req.r.rtm_flags |= RTM_F_NOTIFY;
		} else if (matches(*argv, "connected") == 0) {
			connected = 1;
		} else {
			inet_prefix addr;
			if (strcmp(*argv, "to") == 0) {
				NEXT_ARG();
			}
			if (matches(*argv, "help") == 0)
				usage();
			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) {
		fprintf(stderr, "need at least destination address\n");
		return 1;
	}

	ll_init_map(&rth);

	if (idev || odev)  {
		int idx;

		if (idev) {
			if ((idx = ll_name_to_index(idev)) == 0) {
				fprintf(stderr, "Cannot find device \"%s\"\n", idev);
				return -1;
			}
			addattr32(&req.n, sizeof(req), RTA_IIF, idx);
		}
		if (odev) {
			if ((idx = ll_name_to_index(odev)) == 0) {
				fprintf(stderr, "Cannot find device \"%s\"\n", 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)
	{
		return 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_ex(NULL, &req.n, (void*)stdout, hparams) < 0) {
			fprintf(stderr, "An error :-)\n");
			return 1;
		}

		if (req.n.nlmsg_type != RTM_NEWROUTE) {
			fprintf(stderr, "Not a route?\n");
			return -1;
		}
		len -= NLMSG_LENGTH(sizeof(*r));
		if (len < 0) {
			fprintf(stderr, "Wrong len %d\n", len);
			return -1;
		}

		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]) {
			fprintf(stderr, "Failed to connect the route\n");
			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)
			return 2;
	}

	if (print_route_ex(NULL, &req.n, (void*)stdout, hparams)< 0) {
		fprintf(stderr, "An error :-)\n");
		return 1;
	}

	return 0;
}

void iproute_reset_filter()
{
	memset(&filter, 0, sizeof(filter));
	filter.mdst.bitlen = -1;
	filter.msrc.bitlen = -1;
}

int do_iproute(int argc, char **argv, void * hparams)
{
	//if (argc < 1)
	//	return iproute_list_or_flush(0, NULL, 0);

	//if (matches(*argv, "add") == 0)
	//	return iproute_modify(RTM_NEWROUTE, NLM_F_CREATE|NLM_F_EXCL,
	//			      argc-1, argv+1);
	//if (matches(*argv, "change") == 0 || strcmp(*argv, "chg") == 0)
	//	return iproute_modify(RTM_NEWROUTE, NLM_F_REPLACE,
	//			      argc-1, argv+1);
	//if (matches(*argv, "replace") == 0)
	//	return iproute_modify(RTM_NEWROUTE, NLM_F_CREATE|NLM_F_REPLACE,
	//			      argc-1, argv+1);
	//if (matches(*argv, "prepend") == 0)
	//	return iproute_modify(RTM_NEWROUTE, NLM_F_CREATE,
	//			      argc-1, argv+1);
	//if (matches(*argv, "append") == 0)
	//	return iproute_modify(RTM_NEWROUTE, NLM_F_CREATE|NLM_F_APPEND,
	//			      argc-1, argv+1);
	//if (matches(*argv, "test") == 0)
	//	return iproute_modify(RTM_NEWROUTE, NLM_F_EXCL,
	//			      argc-1, argv+1);
	//if (matches(*argv, "delete") == 0)
	//	return iproute_modify(RTM_DELROUTE, 0,
	//			      argc-1, argv+1);
	//if (matches(*argv, "list") == 0 || matches(*argv, "show") == 0
	 //   || matches(*argv, "lst") == 0)
	//	return iproute_list_or_flush(argc-1, argv+1, 0);
	if (matches(*argv, "get") == 0)
		return iproute_get_ex(argc-1, argv+1, (route_params*)hparams);
	//if (matches(*argv, "flush") == 0)
	//	return iproute_list_or_flush(argc-1, argv+1, 1);
	//if (matches(*argv, "help") == 0)
	//	usage();
	fprintf(stderr, "Command \"%s\" is unknown, try \"ip route help\".\n", *argv);
	return(-1);
}

⌨️ 快捷键说明

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