144d362409d5469aed47d19e7908d19bd194493aThomas Graf/*
244d362409d5469aed47d19e7908d19bd194493aThomas Graf * src/nl-fib-lookup.c		FIB Route Lookup
344d362409d5469aed47d19e7908d19bd194493aThomas Graf *
444d362409d5469aed47d19e7908d19bd194493aThomas Graf *	This library is free software; you can redistribute it and/or
544d362409d5469aed47d19e7908d19bd194493aThomas Graf *	modify it under the terms of the GNU Lesser General Public
644d362409d5469aed47d19e7908d19bd194493aThomas Graf *	License as published by the Free Software Foundation version 2.1
744d362409d5469aed47d19e7908d19bd194493aThomas Graf *	of the License.
844d362409d5469aed47d19e7908d19bd194493aThomas Graf *
98808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf * Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
1044d362409d5469aed47d19e7908d19bd194493aThomas Graf */
1144d362409d5469aed47d19e7908d19bd194493aThomas Graf
128808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf#include <netlink/cli/utils.h>
1344d362409d5469aed47d19e7908d19bd194493aThomas Graf
1444d362409d5469aed47d19e7908d19bd194493aThomas Grafstatic void print_usage(void)
1544d362409d5469aed47d19e7908d19bd194493aThomas Graf{
1644d362409d5469aed47d19e7908d19bd194493aThomas Graf	printf(
1744d362409d5469aed47d19e7908d19bd194493aThomas Graf	"Usage: nl-fib-lookup [options] <addr>\n"
1844d362409d5469aed47d19e7908d19bd194493aThomas Graf	"Options:\n"
1944d362409d5469aed47d19e7908d19bd194493aThomas Graf	"   -t, --table <table>		Table id\n"
2044d362409d5469aed47d19e7908d19bd194493aThomas Graf	"   -f, --fwmark <int>		Firewall mark\n"
2144d362409d5469aed47d19e7908d19bd194493aThomas Graf	"   -s, --scope <scope>		Routing scope\n"
2244d362409d5469aed47d19e7908d19bd194493aThomas Graf	"   -T, --tos <int>		Type of Service\n");
2344d362409d5469aed47d19e7908d19bd194493aThomas Graf	exit(1);
2444d362409d5469aed47d19e7908d19bd194493aThomas Graf}
2544d362409d5469aed47d19e7908d19bd194493aThomas Graf
2644d362409d5469aed47d19e7908d19bd194493aThomas Grafint main(int argc, char *argv[])
2744d362409d5469aed47d19e7908d19bd194493aThomas Graf{
28b624b9ed936f4c23bc4f30d8dce34da49775dd15Thomas Graf	struct nl_sock *nlh;
2944d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct nl_cache *result;
3044d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct flnl_request *request;
3144d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct nl_addr *addr;
3244d362409d5469aed47d19e7908d19bd194493aThomas Graf	struct nl_dump_params params = {
3344d362409d5469aed47d19e7908d19bd194493aThomas Graf		.dp_fd = stdout,
34d84430702496f617c01c5e2d27d0e82e02390bb7Thomas Graf		.dp_type = NL_DUMP_DETAILS,
3544d362409d5469aed47d19e7908d19bd194493aThomas Graf	};
3644d362409d5469aed47d19e7908d19bd194493aThomas Graf	int table = RT_TABLE_UNSPEC, scope = RT_SCOPE_UNIVERSE;
3744d362409d5469aed47d19e7908d19bd194493aThomas Graf	int tos = 0, err = 1;
3844d362409d5469aed47d19e7908d19bd194493aThomas Graf	uint64_t fwmark = 0;
3944d362409d5469aed47d19e7908d19bd194493aThomas Graf
4044d362409d5469aed47d19e7908d19bd194493aThomas Graf	while (1) {
4144d362409d5469aed47d19e7908d19bd194493aThomas Graf		static struct option long_opts[] = {
4244d362409d5469aed47d19e7908d19bd194493aThomas Graf			{"table", 1, 0, 't'},
4344d362409d5469aed47d19e7908d19bd194493aThomas Graf			{"fwmark", 1, 0, 'f'},
4444d362409d5469aed47d19e7908d19bd194493aThomas Graf			{"scope", 1, 0, 's'},
4544d362409d5469aed47d19e7908d19bd194493aThomas Graf			{"tos", 1, 0, 'T'},
4644d362409d5469aed47d19e7908d19bd194493aThomas Graf			{"help", 0, 0, 'h'},
4744d362409d5469aed47d19e7908d19bd194493aThomas Graf			{0, 0, 0, 0},
4844d362409d5469aed47d19e7908d19bd194493aThomas Graf		};
4944d362409d5469aed47d19e7908d19bd194493aThomas Graf		int c, idx = 0;
5044d362409d5469aed47d19e7908d19bd194493aThomas Graf
5144d362409d5469aed47d19e7908d19bd194493aThomas Graf		c = getopt_long(argc, argv, "t:f:s:T:h", long_opts, &idx);
5244d362409d5469aed47d19e7908d19bd194493aThomas Graf		if (c == -1)
5344d362409d5469aed47d19e7908d19bd194493aThomas Graf			break;
5444d362409d5469aed47d19e7908d19bd194493aThomas Graf
5544d362409d5469aed47d19e7908d19bd194493aThomas Graf		switch (c) {
5644d362409d5469aed47d19e7908d19bd194493aThomas Graf		case 't':
5744d362409d5469aed47d19e7908d19bd194493aThomas Graf			table = strtoul(optarg, NULL, 0);
5844d362409d5469aed47d19e7908d19bd194493aThomas Graf			break;
5944d362409d5469aed47d19e7908d19bd194493aThomas Graf		case 'f':
6044d362409d5469aed47d19e7908d19bd194493aThomas Graf			fwmark = strtoul(optarg, NULL, 0);
6144d362409d5469aed47d19e7908d19bd194493aThomas Graf			break;
6244d362409d5469aed47d19e7908d19bd194493aThomas Graf		case 's':
6344d362409d5469aed47d19e7908d19bd194493aThomas Graf			scope = strtoul(optarg, NULL, 0);
6444d362409d5469aed47d19e7908d19bd194493aThomas Graf			break;
6544d362409d5469aed47d19e7908d19bd194493aThomas Graf		case 'T':
6644d362409d5469aed47d19e7908d19bd194493aThomas Graf			tos = strtoul(optarg, NULL, 0);
6744d362409d5469aed47d19e7908d19bd194493aThomas Graf			break;
6844d362409d5469aed47d19e7908d19bd194493aThomas Graf		default:
6944d362409d5469aed47d19e7908d19bd194493aThomas Graf			print_usage();
7044d362409d5469aed47d19e7908d19bd194493aThomas Graf		}
7144d362409d5469aed47d19e7908d19bd194493aThomas Graf	}
7244d362409d5469aed47d19e7908d19bd194493aThomas Graf
7344d362409d5469aed47d19e7908d19bd194493aThomas Graf	if (optind >= argc)
7444d362409d5469aed47d19e7908d19bd194493aThomas Graf		print_usage();
7544d362409d5469aed47d19e7908d19bd194493aThomas Graf
768808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf	nlh = nl_cli_alloc_socket();
7744d362409d5469aed47d19e7908d19bd194493aThomas Graf
7810cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	if ((err = nl_addr_parse(argv[optind], AF_INET, &addr)) < 0)
798808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		nl_cli_fatal(err, "Unable to parse address \"%s\": %s\n",
8010cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf			argv[optind], nl_geterror(err));
8144d362409d5469aed47d19e7908d19bd194493aThomas Graf
8244d362409d5469aed47d19e7908d19bd194493aThomas Graf	result = flnl_result_alloc_cache();
8344d362409d5469aed47d19e7908d19bd194493aThomas Graf	if (!result)
848808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		nl_cli_fatal(ENOMEM, "Unable to allocate cache");
8544d362409d5469aed47d19e7908d19bd194493aThomas Graf
8644d362409d5469aed47d19e7908d19bd194493aThomas Graf	request = flnl_request_alloc();
8744d362409d5469aed47d19e7908d19bd194493aThomas Graf	if (!request)
888808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		nl_cli_fatal(ENOMEM, "Unable to allocate request");
8944d362409d5469aed47d19e7908d19bd194493aThomas Graf
9044d362409d5469aed47d19e7908d19bd194493aThomas Graf	flnl_request_set_table(request, table);
9144d362409d5469aed47d19e7908d19bd194493aThomas Graf	flnl_request_set_fwmark(request, fwmark);
9244d362409d5469aed47d19e7908d19bd194493aThomas Graf	flnl_request_set_scope(request, scope);
9344d362409d5469aed47d19e7908d19bd194493aThomas Graf	flnl_request_set_tos(request, tos);
9444d362409d5469aed47d19e7908d19bd194493aThomas Graf
9544d362409d5469aed47d19e7908d19bd194493aThomas Graf	err = flnl_request_set_addr(request, addr);
9644d362409d5469aed47d19e7908d19bd194493aThomas Graf	nl_addr_put(addr);
9744d362409d5469aed47d19e7908d19bd194493aThomas Graf	if (err < 0)
988808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		nl_cli_fatal(err, "Unable to send request: %s", nl_geterror(err));
9944d362409d5469aed47d19e7908d19bd194493aThomas Graf
1008808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf	nl_cli_connect(nlh, NETLINK_FIB_LOOKUP);
10144d362409d5469aed47d19e7908d19bd194493aThomas Graf
10244d362409d5469aed47d19e7908d19bd194493aThomas Graf	err = flnl_lookup(nlh, request, result);
10310cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	if (err < 0)
1048808743839b0f459394ecd00cb0f7c1896c0ab7aThomas Graf		nl_cli_fatal(err, "Unable to lookup: %s\n", nl_geterror(err));
10544d362409d5469aed47d19e7908d19bd194493aThomas Graf
10644d362409d5469aed47d19e7908d19bd194493aThomas Graf	nl_cache_dump(result, &params);
10744d362409d5469aed47d19e7908d19bd194493aThomas Graf
10810cf5a586c149fdb7e2639000dbfae5e6f8522a5Thomas Graf	return 0;
10944d362409d5469aed47d19e7908d19bd194493aThomas Graf}
110