dect
/
libnl
Archived
13
0
Fork 0

New set of libnl tools

Converts all tools to the API changes and improves the useability by
introducing regular options and long options.
This commit is contained in:
Thomas Graf 2008-05-23 00:02:02 +02:00
parent 337fbd24ca
commit 10cf5a586c
62 changed files with 2149 additions and 1794 deletions

20
src/.gitignore vendored
View File

@ -1,13 +1,12 @@
genl-ctrl-dump
genl-ctrl-get
nf-ct-dump
genl-ctrl-list
nf-ct-list
nf-log
nf-monitor
nl-addr-add
nl-addr-delete
nl-addr-dump
nl-addr-list
nl-fib-lookup
nl-link-dump
nl-link-list
nl-link-ifindex2name
nl-link-name2ifindex
nl-link-set
@ -17,15 +16,16 @@ nl-list-sockets
nl-monitor
nl-neigh-add
nl-neigh-delete
nl-neigh-dump
nl-neightbl-dump
nl-neigh-list
nl-neightbl-list
nl-qdisc-add
nl-qdisc-delete
nl-qdisc-dump
nl-qdisc-list
nl-route-add
nl-route-delete
nl-route-list
nl-route-get
nl-rule-dump
nl-tctree-dump
nl-rule-list
nl-tctree-list
nl-util-addr
nf-queue

View File

@ -20,19 +20,35 @@ TOOLS := $(CIN:%.c=%)
all: $(TOOLS)
$(TOOLS): utils.o
nl-route-add nl-route-delete nl-route-list: route-utils.o
nl-addr-add nl-addr-delete nl-addr-list: addr-utils.o
nl-route-add nl-route-delete nl-route-list: route-utils.o rtnl-utils.o
nl-route-get: rtnl-utils.o
nl-addr-add nl-addr-delete nl-addr-list: addr-utils.o rtnl-utils.o
nl-link-list nl-link-set nl-link-stats: link-utils.o rtnl-utils.o
nl-link-ifindex2name nl-link-name2ifindex: rtnl-utils.o
nl-neigh-add nl-neigh-delete nl-neigh-list: neigh-utils.o rtnl-utils.o
nl-qdisc-delete nl-qdisc-list: qdisc-utils.o rtnl-utils.o
nl-rule-list: rule-utils.o rtnl-utils.o
nl-neightbl-list: rtnl-utils.o
nl-monitor: rtnl-utils.o
nl-tctree-list: rtnl-utils.o
genl-ctrl-list: ctrl-utils.o
nf-ct-list: ct-utils.o
nf-log: log-utils.o rtnl-utils.o
nf-queue: queue-utils.o rtnl-utils.o
nl-%: nl-%.c
@echo " LD $@"; \
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -lnl-route
genl-%: genl-%.c
@echo " LD $@"; \
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -lnl-genl
nf-%: nf-%.c
@echo " LD $@"; \
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) -lnl-nf
clean:
@echo " CLEAN src"; \

View File

@ -11,6 +11,17 @@
#include "addr-utils.h"
struct rtnl_addr *nlt_alloc_addr(void)
{
struct rtnl_addr *addr;
addr = rtnl_addr_alloc();
if (!addr)
fatal(ENOMEM, "Unable to allocate address object");
return addr;
}
void parse_family(struct rtnl_addr *addr, char *arg)
{
int family;

View File

@ -14,6 +14,7 @@
#include "utils.h"
extern struct rtnl_addr *nlt_alloc_addr(void);
extern void parse_family(struct rtnl_addr *, char *);
extern void parse_local(struct rtnl_addr *, char *);
extern void parse_dev(struct rtnl_addr *, struct nl_cache *, char *);

148
src/ct-utils.c Normal file
View File

@ -0,0 +1,148 @@
/*
* src/ct-utils.c Conntrack Helpers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
*/
#include "ct-utils.h"
struct nfnl_ct *nlt_alloc_ct(void)
{
struct nfnl_ct *ct;
ct = nfnl_ct_alloc();
if (!ct)
fatal(ENOMEM, "Unable to allocate conntrack object");
return ct;
}
struct nl_cache *nlt_alloc_ct_cache(struct nl_sock *sk)
{
return alloc_cache(sk, "conntrack", nfnl_ct_alloc_cache);
}
void parse_family(struct nfnl_ct *ct, char *arg)
{
int family;
if ((family = nl_str2af(arg)) == AF_UNSPEC)
fatal(EINVAL, "Unable to parse family \"%s\": %s",
arg, nl_geterror(NLE_INVAL));
nfnl_ct_set_family(ct, family);
}
void parse_protocol(struct nfnl_ct *ct, char *arg)
{
int proto;
if ((proto = nl_str2ip_proto(arg)) < 0)
fatal(proto, "Unable to parse protocol \"%s\": %s",
arg, nl_geterror(proto));
nfnl_ct_set_proto(ct, proto);
}
void parse_mark(struct nfnl_ct *ct, char *arg)
{
uint32_t mark = parse_u32(arg);
nfnl_ct_set_mark(ct, mark);
}
void parse_timeout(struct nfnl_ct *ct, char *arg)
{
uint32_t timeout = parse_u32(arg);
nfnl_ct_set_timeout(ct, timeout);
}
void parse_id(struct nfnl_ct *ct, char *arg)
{
uint32_t id = parse_u32(arg);
nfnl_ct_set_id(ct, id);
}
void parse_use(struct nfnl_ct *ct, char *arg)
{
uint32_t use = parse_u32(arg);
nfnl_ct_set_use(ct, use);
}
void parse_src(struct nfnl_ct *ct, int reply, char *arg)
{
int err;
struct nl_addr *a = nlt_addr_parse(arg, nfnl_ct_get_family(ct));
if ((err = nfnl_ct_set_src(ct, reply, a)) < 0)
fatal(err, "Unable to set source address: %s",
nl_geterror(err));
}
void parse_dst(struct nfnl_ct *ct, int reply, char *arg)
{
int err;
struct nl_addr *a = nlt_addr_parse(arg, nfnl_ct_get_family(ct));
if ((err = nfnl_ct_set_dst(ct, reply, a)) < 0)
fatal(err, "Unable to set destination address: %s",
nl_geterror(err));
}
void parse_src_port(struct nfnl_ct *ct, int reply, char *arg)
{
uint32_t port = parse_u32(arg);
nfnl_ct_set_src_port(ct, reply, port);
}
void parse_dst_port(struct nfnl_ct *ct, int reply, char *arg)
{
uint32_t port = parse_u32(arg);
nfnl_ct_set_dst_port(ct, reply, port);
}
void parse_tcp_state(struct nfnl_ct *ct, char *arg)
{
int state;
if ((state = nfnl_ct_str2tcp_state(arg)) < 0)
fatal(state, "Unable to parse tcp state \"%s\": %s",
arg, nl_geterror(state));
nfnl_ct_set_tcp_state(ct, state);
}
void parse_status(struct nfnl_ct *ct, char *arg)
{
int status;
if ((status = nfnl_ct_str2status(arg)) < 0)
fatal(status, "Unable to parse flags \"%s\": %s",
arg, nl_geterror(status));
nfnl_ct_set_status(ct, status);
}
#if 0
} else if (arg_match("origicmpid")) {
if (argc > ++idx)
nfnl_ct_set_icmp_id(ct, 0, strtoul(argv[idx++], NULL, 0));
} else if (arg_match("origicmptype")) {
if (argc > ++idx)
nfnl_ct_set_icmp_type(ct, 0, strtoul(argv[idx++], NULL, 0));
} else if (arg_match("origicmpcode")) {
if (argc > ++idx)
nfnl_ct_set_icmp_code(ct, 0, strtoul(argv[idx++], NULL, 0));
} else if (arg_match("replyicmpid")) {
if (argc > ++idx)
nfnl_ct_set_icmp_id(ct, 1, strtoul(argv[idx++], NULL, 0));
} else if (arg_match("replyicmptype")) {
if (argc > ++idx)
nfnl_ct_set_icmp_type(ct, 1, strtoul(argv[idx++], NULL, 0));
} else if (arg_match("replyicmpcode")) {
if (argc > ++idx)
nfnl_ct_set_icmp_code(ct, 1, strtoul(argv[idx++], NULL, 0));
}
#endif

34
src/ct-utils.h Normal file
View File

@ -0,0 +1,34 @@
/*
* src/ct-utils.h Conntrack Helper
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
*/
#ifndef __CT_UTILS_H_
#define __CT_UTILS_H_
#include "utils.h"
#include <netlink/netfilter/ct.h>
#include <linux/netfilter/nf_conntrack_common.h>
extern struct nfnl_ct *nlt_alloc_ct(void);
extern struct nl_cache *nlt_alloc_ct_cache(struct nl_sock *);
extern void parse_family(struct nfnl_ct *, char *);
extern void parse_protocol(struct nfnl_ct *, char *);
extern void parse_mark(struct nfnl_ct *, char *);
extern void parse_timeout(struct nfnl_ct *, char *);
extern void parse_id(struct nfnl_ct *, char *);
extern void parse_use(struct nfnl_ct *, char *);
extern void parse_src(struct nfnl_ct *, int, char *);
extern void parse_dst(struct nfnl_ct *, int, char *);
extern void parse_src_port(struct nfnl_ct *, int, char *);
extern void parse_dst_port(struct nfnl_ct *, int, char *);
extern void parse_tcp_state(struct nfnl_ct *, char *);
extern void parse_status(struct nfnl_ct *, char *);
#endif

18
src/ctrl-utils.c Normal file
View File

@ -0,0 +1,18 @@
/*
* src/ctrl-utils.c Generic Ctrl Netlink Helpers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
*/
#include "ctrl-utils.h"
struct nl_cache *nlt_alloc_genl_family_cache(struct nl_sock *sk)
{
return alloc_cache(sk, "generic netlink family",
genl_ctrl_alloc_cache);
}

19
src/ctrl-utils.h Normal file
View File

@ -0,0 +1,19 @@
/*
* src/ctrl-utils.h Generic Netlink Ctrl Helpers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
*/
#ifndef __SRC_CTRL_UTILS_H_
#define __SRC_CTRL_UTILS_H_
#include "utils.h"
extern struct nl_cache *nlt_alloc_genl_family_cache(struct nl_sock *);
#endif

View File

@ -1,170 +0,0 @@
/*
* src/f_ct.c Conntrack Filter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
*/
static void get_filter(struct nfnl_ct *ct, int argc, char **argv, int idx)
{
struct nl_addr *a;
while (argc > idx) {
if (arg_match("family")) {
if (argc > ++idx) {
int family = nl_str2af(argv[idx++]);
if (family == AF_UNSPEC)
goto err_invaf;
nfnl_ct_set_family(ct, family);
}
} else if (arg_match("proto")) {
if (argc > ++idx) {
int proto = nl_str2ip_proto(argv[idx++]);
if (proto < 0)
goto err_invproto;
nfnl_ct_set_proto(ct, proto);
}
} else if (arg_match("tcpstate")) {
if (argc > ++idx) {
int state = nfnl_ct_str2tcp_state(argv[idx++]);
if (state < 0)
goto err_invtcpstate;
nfnl_ct_set_tcp_state(ct, state);
}
} else if (arg_match("status")) {
if (argc > ++idx) {
int status = strtoul(argv[idx++], NULL, 0);
nfnl_ct_set_status(ct, status);
nfnl_ct_unset_status(ct, ~status);
}
} else if (arg_match("timeout")) {
if (argc > ++idx)
nfnl_ct_set_timeout(ct, strtoul(argv[idx++], NULL, 0));
} else if (arg_match("mark")) {
if (argc > ++idx)
nfnl_ct_set_mark(ct, strtoul(argv[idx++], NULL, 0));
} else if (arg_match("use")) {
if (argc > ++idx)
nfnl_ct_set_use(ct, strtoul(argv[idx++], NULL, 0));
} else if (arg_match("id")) {
if (argc > ++idx)
nfnl_ct_set_id(ct, strtoul(argv[idx++], NULL, 0));
} else if (arg_match("origsrc")) {
if (argc > ++idx) {
a = nl_addr_parse(argv[idx++],
nfnl_ct_get_family(ct));
if (!a)
goto err_invaddr;
nfnl_ct_set_src(ct, 0, a);
nl_addr_put(a);
}
} else if (arg_match("origdst")) {
if (argc > ++idx) {
a = nl_addr_parse(argv[idx++],
nfnl_ct_get_family(ct));
if (!a)
goto err_invaddr;
nfnl_ct_set_dst(ct, 0, a);
nl_addr_put(a);
}
} else if (arg_match("origsrcport")) {
if (argc > ++idx)
nfnl_ct_set_src_port(ct, 0, strtoul(argv[idx++], NULL, 0));
} else if (arg_match("origdstport")) {
if (argc > ++idx)
nfnl_ct_set_dst_port(ct, 0, strtoul(argv[idx++], NULL, 0));
} else if (arg_match("origicmpid")) {
if (argc > ++idx)
nfnl_ct_set_icmp_id(ct, 0, strtoul(argv[idx++], NULL, 0));
} else if (arg_match("origicmptype")) {
if (argc > ++idx)
nfnl_ct_set_icmp_type(ct, 0, strtoul(argv[idx++], NULL, 0));
} else if (arg_match("origicmpcode")) {
if (argc > ++idx)
nfnl_ct_set_icmp_code(ct, 0, strtoul(argv[idx++], NULL, 0));
} else if (arg_match("origpackets")) {
if (argc > ++idx)
nfnl_ct_set_packets(ct, 0, strtoul(argv[idx++], NULL, 0));
} else if (arg_match("origbytes")) {
if (argc > ++idx)
nfnl_ct_set_bytes(ct, 0, strtoul(argv[idx++], NULL, 0));
} else if (arg_match("replysrc")) {
if (argc > ++idx) {
a = nl_addr_parse(argv[idx++],
nfnl_ct_get_family(ct));
if (!a)
goto err_invaddr;
nfnl_ct_set_src(ct, 1, a);
nl_addr_put(a);
}
} else if (arg_match("replydst")) {
if (argc > ++idx) {
a = nl_addr_parse(argv[idx++],
nfnl_ct_get_family(ct));
if (!a)
goto err_invaddr;
nfnl_ct_set_dst(ct, 1, a);
nl_addr_put(a);
}
} else if (arg_match("replysrcport")) {
if (argc > ++idx)
nfnl_ct_set_src_port(ct, 1, strtoul(argv[idx++], NULL, 0));
} else if (arg_match("replydstport")) {
if (argc > ++idx)
nfnl_ct_set_dst_port(ct, 1, strtoul(argv[idx++], NULL, 0));
} else if (arg_match("replyicmpid")) {
if (argc > ++idx)
nfnl_ct_set_icmp_id(ct, 1, strtoul(argv[idx++], NULL, 0));
} else if (arg_match("replyicmptype")) {
if (argc > ++idx)
nfnl_ct_set_icmp_type(ct, 1, strtoul(argv[idx++], NULL, 0));
} else if (arg_match("replyicmpcode")) {
if (argc > ++idx)
nfnl_ct_set_icmp_code(ct, 1, strtoul(argv[idx++], NULL, 0));
} else if (arg_match("replypackets")) {
if (argc > ++idx)
nfnl_ct_set_packets(ct, 1, strtoul(argv[idx++], NULL, 0));
} else if (arg_match("replybytes")) {
if (argc > ++idx)
nfnl_ct_set_bytes(ct, 1, strtoul(argv[idx++], NULL, 0));
}
#define MSTATUS(STR, STATUS) \
else if (!strcasecmp(argv[idx], STR)) { \
nfnl_ct_set_status(ct, STATUS); idx++; }
#define MNOSTATUS(STR, STATUS) \
else if (!strcasecmp(argv[idx], STR)) { \
nfnl_ct_unset_status(ct, STATUS); idx++; }
MSTATUS("replied", IPS_SEEN_REPLY)
MNOSTATUS("unreplied", IPS_SEEN_REPLY)
MSTATUS("assured", IPS_ASSURED)
MNOSTATUS("unassured", IPS_ASSURED)
#undef MSTATUS
#undef MNOSTATUS
else {
fprintf(stderr, "What is '%s'?\n", argv[idx]);
exit(1);
}
}
return;
err_invproto:
fprintf(stderr, "Invalid IP protocol \"%s\".\n", argv[idx-1]);
exit(1);
err_invtcpstate:
fprintf(stderr, "Invalid TCP state \"%s\".\n", argv[idx-1]);
exit(1);
err_invaf:
fprintf(stderr, "Invalid address family \"%s\"\n", argv[idx-1]);
exit(1);
err_invaddr:
fprintf(stderr, "Invalid address \"%s\": %s\n", argv[idx-1], nl_geterror());
exit(1);
}

View File

@ -1,106 +0,0 @@
/*
* src/f_link.c Link Filter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
*/
#include <linux/if.h>
static void get_filter(struct rtnl_link *l, int ac, char **av, int idx,
struct nl_cache *cache)
{
while (ac > idx) {
if (!strcasecmp(av[idx], "dev")) {
if (ac > ++idx) {
int ifindex = rtnl_link_name2i(cache, av[idx++]);
if (ifindex == RTNL_LINK_NOT_FOUND)
goto err_notfound;
rtnl_link_set_ifindex(l, ifindex);
}
} else if (!strcasecmp(av[idx], "mtu")) {
if (ac > ++idx)
rtnl_link_set_mtu(l, strtoul(av[idx++], NULL, 0));
} else if (!strcasecmp(av[idx], "txqlen")) {
if (ac > ++idx)
rtnl_link_set_txqlen(l, strtoul(av[idx++], NULL, 0));
} else if (!strcasecmp(av[idx], "weight")) {
if (ac > ++idx)
rtnl_link_set_weight(l, strtoul(av[idx++], NULL, 0));
} else if (!strcasecmp(av[idx], "link")) {
if (ac > ++idx) {
int ifindex = rtnl_link_name2i(cache, av[idx++]);
if (ifindex == RTNL_LINK_NOT_FOUND)
goto err_notfound;
rtnl_link_set_link(l, ifindex);
}
} else if (!strcasecmp(av[idx], "master")) {
if (ac > ++idx) {
int ifindex = rtnl_link_name2i(cache, av[idx++]);
if (ifindex == RTNL_LINK_NOT_FOUND)
goto err_notfound;
rtnl_link_set_master(l, ifindex);
}
} else if (!strcasecmp(av[idx], "qdisc")) {
if (ac > ++idx)
rtnl_link_set_qdisc(l, av[idx++]);
} else if (!strcasecmp(av[idx], "name")) {
if (ac > ++idx)
rtnl_link_set_name(l, av[idx++]);
} else if (!strcasecmp(av[idx], "addr")) {
if (ac > ++idx) {
struct nl_addr *a = nl_addr_parse(av[idx++], AF_UNSPEC);
if (a == NULL)
goto err;
rtnl_link_set_addr(l, a);
nl_addr_put(a);
}
} else if (!strcasecmp(av[idx], "broadcast")) {
if (ac > ++idx) {
struct nl_addr *a = nl_addr_parse(av[idx++], AF_UNSPEC);
if (a == NULL)
goto err;
rtnl_link_set_broadcast(l, a);
nl_addr_put(a);
}
}
#define MFLAG(STR, FLAG) \
else if (!strcasecmp(av[idx], STR)) { \
rtnl_link_set_flags(l, FLAG); idx++; }
#define MNOFLAG(STR, FLAG) \
else if (!strcasecmp(av[idx], STR)) { \
rtnl_link_unset_flags(l, FLAG); idx++; }
MFLAG("up", IFF_UP)
MNOFLAG("down", IFF_UP)
MFLAG("noarp", IFF_NOARP)
MNOFLAG("arp", IFF_NOARP)
MFLAG("promisc", IFF_PROMISC)
MNOFLAG("nopromisc", IFF_PROMISC)
MFLAG("dynamic", IFF_DYNAMIC)
MNOFLAG("nodynamic", IFF_DYNAMIC)
MFLAG("multicast", IFF_MULTICAST)
MNOFLAG("nomulticast", IFF_MULTICAST)
MFLAG("allmulticast", IFF_ALLMULTI)
MNOFLAG("noallmulticast", IFF_ALLMULTI)
#undef MFLAG
#undef MNOFLAG
else {
fprintf(stderr, "What is '%s'?\n", av[idx]);
exit(1);
}
}
return;
err_notfound:
fprintf(stderr, "Unknown link %s\n", av[idx-1]);
exit(1);
err:
fprintf(stderr, "%s\n", nl_geterror());
exit(1);
}

View File

@ -1,51 +0,0 @@
/*
* src/f_neigh.c Neighbour Filter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
*/
static void get_filter(struct rtnl_neigh *n, int ac, char **av, int idx,
struct nl_cache *cache)
{
struct nl_cache *lc = nl_cache_mngt_require("route/link");
while (ac > idx) {
if (!strcasecmp(av[idx], "dev")) {
if (ac > ++idx) {
int ifindex = rtnl_link_name2i(lc, av[idx++]);
if (ifindex == RTNL_LINK_NOT_FOUND)
goto err_notfound;
rtnl_neigh_set_ifindex(n, ifindex);
}
} else if (!strcasecmp(av[idx], "dst")) {
if (ac > ++idx) {
struct nl_addr *a = nl_addr_parse(av[idx++], AF_UNSPEC);
if (a == NULL)
goto err;
rtnl_neigh_set_dst(n, a);
nl_addr_put(a);
}
} else if (!strcasecmp(av[idx], "lladdr")) {
if (ac > ++idx) {
struct nl_addr *a = nl_addr_parse(av[idx++], AF_UNSPEC);
if (a == NULL)
goto err;
rtnl_neigh_set_lladdr(n, a);
nl_addr_put(a);
}
}
}
return;
err_notfound:
fprintf(stderr, "Unable to find interface %s\n", av[idx-1]);
exit(1);
err:
fprintf(stderr, "%s\n", nl_geterror());
exit(1);
}

View File

@ -1,65 +0,0 @@
/*
* src/genl-ctrl-dump.c Dump Generic Netlink Controller
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
*/
#include "utils.h"
static void print_usage(void)
{
printf(
"Usage: genl-ctrl-dump <mode> [<filter>]\n"
" mode := { brief | detailed | stats }\n"
" filter := \n");
exit(1);
}
int main(int argc, char *argv[])
{
struct nl_handle *nlh;
struct nl_cache *family_cache;
struct nl_dump_params params = {
.dp_fd = stdout,
.dp_type = NL_DUMP_BRIEF
};
int err = 1;
if (nltool_init(argc, argv) < 0)
return -1;
if (argc < 2 || !strcmp(argv[1], "-h"))
print_usage();
nlh = nltool_alloc_handle();
if (!nlh)
return -1;
if (genl_connect(nlh) < 0) {
fprintf(stderr, "Unable to connect generic netlink socket%s\n",
nl_geterror());
goto errout;
}
family_cache = nltool_alloc_genl_family_cache(nlh);
if (!family_cache)
goto errout;
params.dp_type = nltool_parse_dumptype(argv[1]);
if (params.dp_type < 0)
goto errout;
//get_filter(link, argc, argv, 2, link_cache);
nl_cache_dump(family_cache, &params);
nl_cache_free(family_cache);
err = 0;
errout:
nl_close(nlh);
nl_handle_destroy(nlh);
return err;
}

63
src/genl-ctrl-list.c Normal file
View File

@ -0,0 +1,63 @@
/*
* src/genl-ctrl-list.c List Generic Netlink Controller
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
#include "ctrl-utils.h"
static void print_usage(void)
{
printf(
"Usage: genl-ctrl-list [OPTION]...\n"
"\n"
"Options\n"
" -f, --format=TYPE Output format { brief | details | stats }\n"
" -h, --help Show this help\n"
" -v, --version Show versioning information\n"
);
exit(0);
}
int main(int argc, char *argv[])
{
struct nl_sock *sock;
struct nl_cache *family_cache;
struct nl_dump_params params = {
.dp_type = NL_DUMP_ONELINE,
.dp_fd = stdout,
};
sock = nlt_alloc_socket();
nlt_connect(sock, NETLINK_GENERIC);
family_cache = nlt_alloc_genl_family_cache(sock);
for (;;) {
int c, optidx = 0;
static struct option long_opts[] = {
{ "format", 1, 0, 'f' },
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'v' },
{ 0, 0, 0, 0 }
};
c = getopt_long(argc, argv, "f:hv", long_opts, &optidx);
if (c == -1)
break;
switch (c) {
case 'f': params.dp_type = nlt_parse_dumptype(optarg); break;
case 'h': print_usage(); break;
case 'v': nlt_print_version(); break;
}
}
nl_cache_dump(family_cache, &params);
return 0;
}

62
src/link-utils.c Normal file
View File

@ -0,0 +1,62 @@
/*
* src/link-utils.c Link Helpers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
*/
#include "link-utils.h"
struct rtnl_link *nlt_alloc_link(void)
{
struct rtnl_link *link;
link = rtnl_link_alloc();
if (!link)
fatal(ENOMEM, "Unable to allocate link object");
return link;
}
void parse_family(struct rtnl_link *link, char *arg)
{
int family;
if ((family = nl_str2af(arg)) == AF_UNSPEC)
fatal(EINVAL, "Unable to translate address family \"%s\"", arg);
rtnl_link_set_family(link, family);
}
void parse_name(struct rtnl_link *link, char *arg)
{
rtnl_link_set_name(link, arg);
}
void parse_mtu(struct rtnl_link *link, char *arg)
{
uint32_t mtu = parse_u32(arg);
rtnl_link_set_mtu(link, mtu);
}
void parse_ifindex(struct rtnl_link *link, char *arg)
{
uint32_t index = parse_u32(arg);
rtnl_link_set_ifindex(link, index);
}
void parse_txqlen(struct rtnl_link *link, char *arg)
{
uint32_t qlen = parse_u32(arg);
rtnl_link_set_txqlen(link, qlen);
}
void parse_weight(struct rtnl_link *link, char *arg)
{
uint32_t weight = parse_u32(arg);
rtnl_link_set_weight(link, weight);
}

25
src/link-utils.h Normal file
View File

@ -0,0 +1,25 @@
/*
* src/link-utils.h Link Helpers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
*/
#ifndef __LINK_UTILS_H_
#define __LINK_UTILS_H_
#include "utils.h"
extern struct rtnl_link *nlt_alloc_link(void);
extern void parse_family(struct rtnl_link *, char *);
extern void parse_name(struct rtnl_link *, char *);
extern void parse_mtu(struct rtnl_link *, char *);
extern void parse_ifindex(struct rtnl_link *, char *);
extern void parse_txqlen(struct rtnl_link *, char *);
extern void parse_weight(struct rtnl_link *, char *);
#endif

23
src/log-utils.c Normal file
View File

@ -0,0 +1,23 @@
/*
* src/ct-utils.c Conntrack Helpers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
*/
#include "log-utils.h"
struct nfnl_log *nlt_alloc_log(void)
{
struct nfnl_log *log;
log = nfnl_log_alloc();
if (!log)
fatal(ENOMEM, "Unable to allocate log object");
return log;
}

22
src/log-utils.h Normal file
View File

@ -0,0 +1,22 @@
/*
* src/log-utils.h Log Helper
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
*/
#ifndef __LOG_UTILS_H_
#define __LOG_UTILS_H_
#include "utils.h"
#include <linux/netfilter/nfnetlink_log.h>
#include <netlink/netfilter/nfnl.h>
#include <netlink/netfilter/log.h>
extern struct nfnl_log *nlt_alloc_log(void);
#endif

76
src/neigh-utils.c Normal file
View File

@ -0,0 +1,76 @@
/*
* src/neigh-utils.c Neighbour Helpers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
*/
#include "neigh-utils.h"
struct rtnl_neigh *nlt_alloc_neigh(void)
{
struct rtnl_neigh *neigh;
neigh = rtnl_neigh_alloc();
if (!neigh)
fatal(ENOMEM, "Unable to allocate neighbout object");
return neigh;
}
void parse_dst(struct rtnl_neigh *neigh, char *arg)
{
struct nl_addr *a;
int err;
a = nlt_addr_parse(arg, rtnl_neigh_get_family(neigh));
if ((err = rtnl_neigh_set_dst(neigh, a)) < 0)
fatal(err, "Unable to set local address: %s",
nl_geterror(err));
nl_addr_put(a);
}
void parse_lladdr(struct rtnl_neigh *neigh, char *arg)
{
struct nl_addr *a;
a = nlt_addr_parse(arg, AF_UNSPEC);
rtnl_neigh_set_lladdr(neigh, a);
nl_addr_put(a);
}
void parse_dev(struct rtnl_neigh *neigh, struct nl_cache *link_cache, char *arg)
{
int ival;
if (!(ival = rtnl_link_name2i(link_cache, arg)))
fatal(ENOENT, "Link \"%s\" does not exist", arg);
rtnl_neigh_set_ifindex(neigh, ival);
}
void parse_family(struct rtnl_neigh *neigh, char *arg)
{
int family;
if ((family = nl_str2af(arg)) == AF_UNSPEC)
fatal(EINVAL, "Unable to translate address family \"%s\"", arg);
rtnl_neigh_set_family(neigh, family);
}
void parse_state(struct rtnl_neigh *neigh, char *arg)
{
int state;
if ((state = rtnl_neigh_str2state(arg)) < 0)
fatal(state, "Unable to translate state \"%s\": %s",
arg, state);
rtnl_neigh_set_state(neigh, state);
}

24
src/neigh-utils.h Normal file
View File

@ -0,0 +1,24 @@
/*
* src/neigh-utils.h Neighbour Helpers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
*/
#ifndef __NEIGH_UTILS_H_
#define __NEIGH_UTILS_H_
#include "utils.h"
extern struct rtnl_neigh *nlt_alloc_neigh(void);
extern void parse_dst(struct rtnl_neigh *, char *);
extern void parse_lladdr(struct rtnl_neigh *, char *);
extern void parse_dev(struct rtnl_neigh *, struct nl_cache *, char *);
extern void parse_family(struct rtnl_neigh *, char *);
extern void parse_state(struct rtnl_neigh *, char *);
#endif

View File

@ -1,91 +0,0 @@
/*
* src/nf-ct-dump.c Dump conntrack attributes
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
*/
#include "utils.h"
#include <netlink/netfilter/ct.h>
#include <linux/netfilter/nf_conntrack_common.h>
#include "f_ct.c"
static void print_usage(void)
{
printf(
"Usage: nf-ct-dump <mode> [<filter>]\n"
" mode := { brief | detailed | stats | xml }\n"
" filter := [family FAMILY] [proto PROTO] [tcpstate TCPSTATE]\n"
" [status STATUS] [timeout TIMEOUT] [mark MARK] [use USE] [id ID]\n"
" [origsrc ADDR] [origdst ADDR] [origsrcport PORT] [origdstport PORT]\n"
" [origicmpid ID] [origicmptype TYPE] [origicmpcode CODE]\n"
" [origpackets PACKETS] [origbytes BYTES]\n"
" [replysrc ADDR] [replydst ADDR] [replysrcport PORT] [replydstport PORT]\n"
" [replyicmpid ID] [replyicmptype TYPE] [replyicmpcode CODE]\n"
" [replypackets PACKETS] [replybytes BYTES]\n"
" [{ replied | unreplied }] [{ assured | unassured }]\n"
);
exit(1);
}
int main(int argc, char *argv[])
{
struct nl_handle *nlh;
struct nl_cache *ct_cache;
struct nfnl_ct *ct;
struct nl_dump_params params = {
.dp_fd = stdout,
.dp_type = NL_DUMP_BRIEF
};
int err = 1;
if (nltool_init(argc, argv) < 0)
return -1;
if (argc < 2 || !strcmp(argv[1], "-h"))
print_usage();
nlh = nltool_alloc_handle();
if (!nlh)
return -1;
ct = nfnl_ct_alloc();
if (!ct)
goto errout;
if (nltool_connect(nlh, NETLINK_NETFILTER) < 0)
goto errout_free;
ct_cache = nfnl_ct_alloc_cache(nlh);
if (!ct_cache) {
fprintf(stderr, "Unable to retrieve ct cache: %s\n",
nl_geterror());
goto errout_close;
}
nl_cache_mngt_provide(ct_cache);
params.dp_type = nltool_parse_dumptype(argv[1]);
if (params.dp_type < 0)
goto errout_ct_cache;
get_filter(ct, argc, argv, 2);
nl_cache_dump_filter(ct_cache, &params, (struct nl_object *) ct);
err = 0;
errout_ct_cache:
nl_cache_free(ct_cache);
errout_close:
nl_close(nlh);
errout_free:
nfnl_ct_put(ct);
errout:
return err;
}

135
src/nf-ct-list.c Normal file
View File

@ -0,0 +1,135 @@
/*
* src/nf-ct-list.c List Conntrack Entries
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
*/
#include "ct-utils.h"
static void print_usage(void)
{
printf(
"Usage: nf-ct-list [OPTION]... [CONNTRACK ENTRY]\n"
"\n"
"Options\n"
" -f, --format=TYPE Output format { brief | details | stats }\n"
" -h, --help Show this help\n"
" -v, --version Show versioning information\n"
"\n"
"Conntrack Selection\n"
" -i, --id=NUM Identifier\n"
" -p, --proto=PROTOCOL Protocol\n"
" --tcp-state=STATE TCP connection state\n"
" --orig-src=ADDR Original source address\n"
" --orig-sport=PORT Original source port\n"
" --orig-dst=ADDR Original destination address\n"
" --orig-dport=PORT Original destination port\n"
" --reply-src=ADDR Reply source address\n"
" --reply-sport=PORT Reply source port\n"
" --reply-dst=ADDR Reply destination address\n"
" --reply-dport=PORT Reply destination port\n"
" -F, --family=FAMILY Address family\n"
" --mark=NUM Mark value\n"
" --timeout=NUM Timeout value\n"
" --refcnt=NUM Use counter value\n"
" --flags Flags\n"
);
exit(0);
}
int main(int argc, char *argv[])
{
struct nl_sock *sock;
struct nl_cache *ct_cache;
struct nfnl_ct *ct;
struct nl_dump_params params = {
.dp_type = NL_DUMP_ONELINE,
.dp_fd = stdout,
};
ct = nlt_alloc_ct();
for (;;) {
int c, optidx = 0;
enum {
ARG_MARK = 257,
ARG_TCP_STATE = 258,
ARG_ORIG_SRC,
ARG_ORIG_SPORT,
ARG_ORIG_DST,
ARG_ORIG_DPORT,
ARG_REPLY_SRC,
ARG_REPLY_SPORT,
ARG_REPLY_DST,
ARG_REPLY_DPORT,
ARG_TIMEOUT,
ARG_REFCNT,
ARG_FLAGS,
};
static struct option long_opts[] = {
{ "format", 1, 0, 'f' },
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'v' },
{ "id", 1, 0, 'i' },
{ "proto", 1, 0, 'p' },
{ "tcp-state", 1, 0, ARG_TCP_STATE },
{ "orig-src", 1, 0, ARG_ORIG_SRC },
{ "orig-sport", 1, 0, ARG_ORIG_SPORT },
{ "orig-dst", 1, 0, ARG_ORIG_DST },
{ "orig-dport", 1, 0, ARG_ORIG_DPORT },
{ "reply-src", 1, 0, ARG_REPLY_SRC },
{ "reply-sport", 1, 0, ARG_REPLY_SPORT },
{ "reply-dst", 1, 0, ARG_REPLY_DST },
{ "reply-dport", 1, 0, ARG_REPLY_DPORT },
{ "family", 1, 0, 'F' },
{ "mark", 1, 0, ARG_MARK },
{ "timeout", 1, 0, ARG_TIMEOUT },
{ "refcnt", 1, 0, ARG_REFCNT },
{ 0, 0, 0, 0 }
};
c = getopt_long(argc, argv, "46f:hvi:p:F:", long_opts, &optidx);
if (c == -1)
break;
switch (c) {
case '?': exit(NLE_INVAL);
case '4': nfnl_ct_set_family(ct, AF_INET); break;
case '6': nfnl_ct_set_family(ct, AF_INET6); break;
case 'f': params.dp_type = nlt_parse_dumptype(optarg); break;
case 'h': print_usage(); break;
case 'v': nlt_print_version(); break;
case 'i': parse_id(ct, optarg); break;
case 'p': parse_protocol(ct, optarg); break;
case ARG_TCP_STATE: parse_tcp_state(ct, optarg); break;
case ARG_ORIG_SRC: parse_src(ct, 0, optarg); break;
case ARG_ORIG_SPORT: parse_src_port(ct, 0, optarg); break;
case ARG_ORIG_DST: parse_dst(ct, 0, optarg); break;
case ARG_ORIG_DPORT: parse_dst_port(ct, 0, optarg); break;
case ARG_REPLY_SRC: parse_src(ct, 1, optarg); break;
case ARG_REPLY_SPORT: parse_src_port(ct, 1, optarg); break;
case ARG_REPLY_DST: parse_dst(ct, 1, optarg); break;
case ARG_REPLY_DPORT: parse_dst_port(ct, 1, optarg); break;
case 'F': parse_family(ct, optarg); break;
case ARG_MARK: parse_mark(ct, optarg); break;
case ARG_TIMEOUT: parse_timeout(ct, optarg); break;
case ARG_REFCNT: parse_use(ct, optarg); break;
case ARG_FLAGS: parse_status(ct, optarg); break;
}
}
sock = nlt_alloc_socket();
nlt_connect(sock, NETLINK_NETFILTER);
ct_cache = nlt_alloc_ct_cache(sock);
nl_cache_dump_filter(ct_cache, &params, OBJ_CAST(ct));
return 0;
}

View File

@ -6,17 +6,12 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
*/
#include <sys/types.h>
#include <linux/netfilter/nfnetlink_log.h>
#include "utils.h"
#include <netlink/netfilter/nfnl.h>
#include <netlink/netfilter/log.h>
#include "log-utils.h"
static void obj_input(struct nl_object *obj, void *arg)
{
@ -40,25 +35,18 @@ static int event_input(struct nl_msg *msg, void *arg)
int main(int argc, char *argv[])
{
struct nl_handle *nfnlh;
struct nl_handle *rtnlh;
struct nl_sock *nf_sock;
struct nl_sock *rt_sock;
struct nl_cache *link_cache;
struct nfnl_log *log;
enum nfnl_log_copy_mode copy_mode;
uint32_t copy_range;
int err = 1;
int err;
int family;
if (nltool_init(argc, argv) < 0)
return -1;
nfnlh = nltool_alloc_handle();
if (nfnlh == NULL)
return -1;
nl_disable_sequence_check(nfnlh);
nl_socket_modify_cb(nfnlh, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL);
nf_sock = nlt_alloc_socket();
nl_disable_sequence_check(nf_sock);
nl_socket_modify_cb(nf_sock, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL);
if ((argc > 1 && !strcasecmp(argv[1], "-h")) || argc < 3) {
printf("Usage: nf-log family group [ copy_mode ] "
@ -66,38 +54,26 @@ int main(int argc, char *argv[])
return 2;
}
if (nfnl_connect(nfnlh) < 0) {
fprintf(stderr, "%s\n", nl_geterror());
goto errout;
}
nlt_connect(nf_sock, NETLINK_NETFILTER);
family = nl_str2af(argv[1]);
if (family == AF_UNSPEC) {
fprintf(stderr, "Unknown family: %s\n", argv[1]);
goto errout;
}
if (family == AF_UNSPEC)
fatal(NLE_INVAL, "Unknown family \"%s\": %s",
argv[1], nl_geterror(family));
nfnl_log_pf_unbind(nfnlh, family);
if (nfnl_log_pf_bind(nfnlh, family) < 0) {
fprintf(stderr, "%s\n", nl_geterror());
goto errout;
}
log = nfnl_log_alloc();
if (log == NULL) {
fprintf(stderr, "%s\n", nl_geterror());
goto errout;
}
nfnl_log_pf_unbind(nf_sock, family);
if ((err = nfnl_log_pf_bind(nf_sock, family)) < 0)
fatal(err, "Unable to bind logger: %s", nl_geterror(err));
log = nlt_alloc_log();
nfnl_log_set_group(log, atoi(argv[2]));
copy_mode = NFNL_LOG_COPY_META;
if (argc > 3) {
copy_mode = nfnl_log_str2copy_mode(argv[3]);
if (copy_mode < 0) {
fprintf(stderr, "%s\n", nl_geterror());
goto errout;
}
if (copy_mode < 0)
fatal(copy_mode, "Unable to parse copy mode \"%s\": %s",
argv[3], nl_geterror(copy_mode));
}
nfnl_log_set_copy_mode(log, copy_mode);
@ -106,10 +82,8 @@ int main(int argc, char *argv[])
copy_mode = atoi(argv[4]);
nfnl_log_set_copy_range(log, copy_range);
if (nfnl_log_create(nfnlh, log) <0) {
fprintf(stderr, "%s\n", nl_geterror());
goto errout;
}
if ((err = nfnl_log_create(nf_sock, log)) < 0)
fatal(err, "Unable to bind instance: %s", nl_geterror(err));
{
struct nl_dump_params dp = {
@ -122,22 +96,9 @@ int main(int argc, char *argv[])
nl_object_dump((struct nl_object *) log, &dp);
}
rtnlh = nltool_alloc_handle();
if (rtnlh == NULL) {
goto errout_close;
}
if (nl_connect(rtnlh, NETLINK_ROUTE) < 0) {
fprintf(stderr, "%s\n", nl_geterror());
goto errout;
}
if ((link_cache = rtnl_link_alloc_cache(rtnlh)) == NULL) {
fprintf(stderr, "%s\n", nl_geterror());
goto errout_close;
}
nl_cache_mngt_provide(link_cache);
rt_sock = nlt_alloc_socket();
nlt_connect(rt_sock, NETLINK_ROUTE);
link_cache = nlt_alloc_link_cache(rt_sock);
while (1) {
fd_set rfds;
@ -145,35 +106,24 @@ int main(int argc, char *argv[])
FD_ZERO(&rfds);
maxfd = nffd = nl_socket_get_fd(nfnlh);
maxfd = nffd = nl_socket_get_fd(nf_sock);
FD_SET(nffd, &rfds);
rtfd = nl_socket_get_fd(rtnlh);
rtfd = nl_socket_get_fd(rt_sock);
FD_SET(rtfd, &rfds);
if (maxfd < rtfd)
maxfd = rtfd;
/* wait for an incoming message on the netlink socket */
/* wait for an incoming message on the netlink nf_socket */
retval = select(maxfd+1, &rfds, NULL, NULL, NULL);
if (retval) {
if (FD_ISSET(nffd, &rfds))
nl_recvmsgs_default(nfnlh);
nl_recvmsgs_default(nf_sock);
if (FD_ISSET(rtfd, &rfds))
nl_recvmsgs_default(rtnlh);
nl_recvmsgs_default(rt_sock);
}
}
nl_cache_mngt_unprovide(link_cache);
nl_cache_free(link_cache);
nfnl_log_put(log);
nl_close(rtnlh);
nl_handle_destroy(rtnlh);
errout_close:
nl_close(nfnlh);
nl_handle_destroy(nfnlh);
errout:
return err;
return 0;
}

View File

@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2007 Philip Craig <philipc@snapgear.com>
* Copyright (c) 2007 Secure Computing Corporation
*/
@ -36,67 +36,58 @@ static int event_input(struct nl_msg *msg, void *arg)
int main(int argc, char *argv[])
{
struct nl_handle *nlh;
int err = 1;
struct nl_sock *sock;
int err;
int i, idx;
static const struct {
enum nfnetlink_groups gr_id;
const char* gr_name;
} known_groups[] = {
} groups[] = {
{ NFNLGRP_CONNTRACK_NEW, "ct-new" },
{ NFNLGRP_CONNTRACK_UPDATE, "ct-update" },
{ NFNLGRP_CONNTRACK_DESTROY, "ct-destroy" },
{ NFNLGRP_NONE, NULL }
};
if (nltool_init(argc, argv) < 0)
return -1;
nlh = nltool_alloc_handle();
if (nlh == NULL)
return -1;
nl_disable_sequence_check(nlh);
nl_socket_modify_cb(nlh, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL);
sock = nlt_alloc_socket();
nl_disable_sequence_check(sock);
nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL);
if (argc > 1 && !strcasecmp(argv[1], "-h")) {
printf("Usage: nf-monitor [<groups>]\n");
printf("Known groups:");
for (i = 0; known_groups[i].gr_id != NFNLGRP_NONE; i++)
printf(" %s", known_groups[i].gr_name);
for (i = 0; groups[i].gr_id != NFNLGRP_NONE; i++)
printf(" %s", groups[i].gr_name);
printf("\n");
return 2;
}
if (nfnl_connect(nlh) < 0) {
fprintf(stderr, "%s\n", nl_geterror());
goto errout;
}
nlt_connect(sock, NETLINK_NETFILTER);
for (idx = 1; argc > idx; idx++) {
for (i = 0; known_groups[i].gr_id != NFNLGRP_NONE; i++) {
if (!strcmp(argv[idx], known_groups[i].gr_name)) {
for (i = 0; groups[i].gr_id != NFNLGRP_NONE; i++) {
if (strcmp(argv[idx], groups[i].gr_name))
continue;
if (nl_socket_add_membership(nlh, known_groups[i].gr_id) < 0) {
fprintf(stderr, "%s: %s\n", argv[idx], nl_geterror());
goto errout;
}
break;
}
err = nl_socket_add_membership(sock, groups[i].gr_id);
if (err < 0)
fatal(err, "Unable to add membership: %s",
nl_geterror(err));
break;
}
if (known_groups[i].gr_id == NFNLGRP_NONE)
fprintf(stderr, "Warning: Unknown group: %s\n", argv[idx]);
if (groups[i].gr_id == NFNLGRP_NONE)
fatal(NLE_OBJ_NOTFOUND, "Unknown group: \"%s\"",
argv[idx]);
}
while (1) {
fd_set rfds;
int fd, retval;
fd = nl_socket_get_fd(nlh);
fd = nl_socket_get_fd(sock);
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
@ -105,11 +96,9 @@ int main(int argc, char *argv[])
if (retval) {
/* FD_ISSET(fd, &rfds) will be true */
nl_recvmsgs_default(nlh);
nl_recvmsgs_default(sock);
}
}
nl_close(nlh);
errout:
return err;
return 0;
}

View File

@ -9,16 +9,10 @@
* Copyright (c) 2007, 2008 Patrick McHardy <kaber@trash.net>
*/
#include <sys/types.h>
#include <linux/netfilter.h>
#include <linux/netfilter/nfnetlink_queue.h>
#include "utils.h"
#include <netlink/netfilter/nfnl.h>
#include <netlink/netfilter/queue.h>
#include <netlink/netfilter/queue_msg.h>
#include "queue-utils.h"
static struct nl_handle *nfnlh;
static struct nl_sock *nf_sock;
static void obj_input(struct nl_object *obj, void *arg)
{
@ -31,7 +25,7 @@ static void obj_input(struct nl_object *obj, void *arg)
nfnl_queue_msg_set_verdict(msg, NF_ACCEPT);
nl_object_dump(obj, &dp);
nfnl_queue_msg_send_verdict(nfnlh, msg);
nfnl_queue_msg_send_verdict(nf_sock, msg);
}
static int event_input(struct nl_msg *msg, void *arg)
@ -45,7 +39,7 @@ static int event_input(struct nl_msg *msg, void *arg)
int main(int argc, char *argv[])
{
struct nl_handle *rtnlh;
struct nl_sock *rt_sock;
struct nl_cache *link_cache;
struct nfnl_queue *queue;
enum nfnl_queue_copy_mode copy_mode;
@ -53,16 +47,9 @@ int main(int argc, char *argv[])
int err = 1;
int family;
if (nltool_init(argc, argv) < 0)
return -1;
nfnlh = nltool_alloc_handle();
if (nfnlh == NULL)
return -1;
nl_disable_sequence_check(nfnlh);
nl_socket_modify_cb(nfnlh, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL);
nf_sock = nlt_alloc_socket();
nl_disable_sequence_check(nf_sock);
nl_socket_modify_cb(nf_sock, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL);
if ((argc > 1 && !strcasecmp(argv[1], "-h")) || argc < 3) {
printf("Usage: nf-queue family group [ copy_mode ] "
@ -70,38 +57,24 @@ int main(int argc, char *argv[])
return 2;
}
if (nfnl_connect(nfnlh) < 0) {
fprintf(stderr, "%s\n", nl_geterror());
goto errout;
}
nlt_connect(nf_sock, NETLINK_NETFILTER);
family = nl_str2af(argv[1]);
if (family == AF_UNSPEC) {
fprintf(stderr, "Unknown family: %s\n", argv[1]);
goto errout;
}
if ((family = nl_str2af(argv[1])) == AF_UNSPEC)
fatal(NLE_INVAL, "Unknown family \"%s\"", argv[1]);
nfnl_queue_pf_unbind(nfnlh, family);
if (nfnl_queue_pf_bind(nfnlh, family) < 0) {
fprintf(stderr, "%s\n", nl_geterror());
goto errout;
}
queue = nfnl_queue_alloc();
if (queue == NULL) {
fprintf(stderr, "%s\n", nl_geterror());
goto errout;
}
nfnl_queue_pf_unbind(nf_sock, family);
if ((err = nfnl_queue_pf_bind(nf_sock, family)) < 0)
fatal(err, "Unable to bind logger: %s", nl_geterror(err));
queue = nlt_alloc_queue();
nfnl_queue_set_group(queue, atoi(argv[2]));
copy_mode = NFNL_QUEUE_COPY_PACKET;
if (argc > 3) {
copy_mode = nfnl_queue_str2copy_mode(argv[3]);
if (copy_mode < 0) {
fprintf(stderr, "%s\n", nl_geterror());
goto errout;
}
if (copy_mode < 0)
fatal(copy_mode, "Unable to parse copy mode \"%s\": %s",
argv[3], nl_geterror(copy_mode));
}
nfnl_queue_set_copy_mode(queue, copy_mode);
@ -110,27 +83,12 @@ int main(int argc, char *argv[])
copy_range = atoi(argv[4]);
nfnl_queue_set_copy_range(queue, copy_range);
if (nfnl_queue_create(nfnlh, queue) < 0) {
fprintf(stderr, "%s\n", nl_geterror());
goto errout;
}
if ((err = nfnl_queue_create(nf_sock, queue)) < 0)
fatal(err, "Unable to bind queue: %s", nl_geterror(err));
rtnlh = nltool_alloc_handle();
if (rtnlh == NULL) {
goto errout_close;
}
if (nl_connect(rtnlh, NETLINK_ROUTE) < 0) {
fprintf(stderr, "%s\n", nl_geterror());
goto errout;
}
if ((link_cache = rtnl_link_alloc_cache(rtnlh)) == NULL) {
fprintf(stderr, "%s\n", nl_geterror());
goto errout_close;
}
nl_cache_mngt_provide(link_cache);
rt_sock = nlt_alloc_socket();
nlt_connect(rt_sock, NETLINK_ROUTE);
link_cache = nlt_alloc_link_cache(rt_sock);
while (1) {
fd_set rfds;
@ -138,10 +96,10 @@ int main(int argc, char *argv[])
FD_ZERO(&rfds);
maxfd = nffd = nl_socket_get_fd(nfnlh);
maxfd = nffd = nl_socket_get_fd(nf_sock);
FD_SET(nffd, &rfds);
rtfd = nl_socket_get_fd(rtnlh);
rtfd = nl_socket_get_fd(rt_sock);
FD_SET(rtfd, &rfds);
if (maxfd < rtfd)
maxfd = rtfd;
@ -151,22 +109,11 @@ int main(int argc, char *argv[])
if (retval) {
if (FD_ISSET(nffd, &rfds))
nl_recvmsgs_default(nfnlh);
nl_recvmsgs_default(nf_sock);
if (FD_ISSET(rtfd, &rfds))
nl_recvmsgs_default(rtnlh);
nl_recvmsgs_default(rt_sock);
}
}
nl_cache_mngt_unprovide(link_cache);
nl_cache_free(link_cache);
nfnl_queue_put(queue);
nl_close(rtnlh);
nl_handle_destroy(rtnlh);
errout_close:
nl_close(nfnlh);
nl_handle_destroy(nfnlh);
errout:
return err;
return 0;
}

View File

@ -37,9 +37,6 @@ int main(int argc, char *argv[])
int tos = 0, err = 1;
uint64_t fwmark = 0;
if (nltool_init(argc, argv) < 0)
return -1;
while (1) {
static struct option long_opts[] = {
{"table", 1, 0, 't'},
@ -76,24 +73,19 @@ int main(int argc, char *argv[])
if (optind >= argc)
print_usage();
nlh = nltool_alloc_handle();
if (!nlh)
return -1;
nlh = nlt_alloc_socket();
addr = nl_addr_parse(argv[optind], AF_INET);
if (!addr) {
fprintf(stderr, "Unable to parse address \"%s\": %s\n",
argv[optind], nl_geterror());
goto errout;
}
if ((err = nl_addr_parse(argv[optind], AF_INET, &addr)) < 0)
fatal(err, "Unable to parse address \"%s\": %s\n",
argv[optind], nl_geterror(err));
result = flnl_result_alloc_cache();
if (!result)
goto errout_addr;
fatal(ENOMEM, "Unable to allocate cache");
request = flnl_request_alloc();
if (!request)
goto errout_result;
fatal(ENOMEM, "Unable to allocate request");
flnl_request_set_table(request, table);
flnl_request_set_fwmark(request, fwmark);
@ -103,28 +95,15 @@ int main(int argc, char *argv[])
err = flnl_request_set_addr(request, addr);
nl_addr_put(addr);
if (err < 0)
goto errout_put;
fatal(err, "Unable to send request: %s", nl_geterror(err));
if (nltool_connect(nlh, NETLINK_FIB_LOOKUP) < 0)
goto errout_put;
nlt_connect(nlh, NETLINK_FIB_LOOKUP);
err = flnl_lookup(nlh, request, result);
if (err < 0) {
fprintf(stderr, "Unable to lookup: %s\n", nl_geterror());
goto errout_put;
}
if (err < 0)
fatal(err, "Unable to lookup: %s\n", nl_geterror(err));
nl_cache_dump(result, &params);
err = 0;
errout_put:
nl_object_put(OBJ_CAST(request));
errout_result:
nl_cache_free(result);
errout_addr:
nl_addr_put(addr);
errout:
nl_close(nlh);
nl_handle_destroy(nlh);
return err;
return 0;
}

View File

@ -1,75 +0,0 @@
/*
* src/nl-link-dump.c Dump link attributes
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
*/
#include "utils.h"
static void print_usage(void)
{
printf(
"Usage: nl-link-dump <mode> [<filter>]\n"
" mode := { brief | detailed | stats | xml }\n"
" filter := [dev DEV] [mtu MTU] [txqlen TXQLEN] [weight WEIGHT] [link LINK]\n"
" [master MASTER] [qdisc QDISC] [addr ADDR] [broadcast BRD]\n"
" [{ up | down }] [{ arp | noarp }] [{ promisc | nopromisc }]\n"
" [{ dynamic | nodynamic }] [{ multicast | nomulticast }]\n"
" [{ trailers | notrailers }] [{ allmulticast | noallmulticast }]\n");
exit(1);
}
#include "f_link.c"
int main(int argc, char *argv[])
{
struct nl_handle *nlh;
struct nl_cache *link_cache;
struct rtnl_link *link;
struct nl_dump_params params = {
.dp_fd = stdout,
.dp_type = NL_DUMP_BRIEF
};
int err = 1;
if (nltool_init(argc, argv) < 0)
return -1;
if (argc < 2 || !strcmp(argv[1], "-h"))
print_usage();
nlh = nltool_alloc_handle();
if (!nlh)
return -1;
link = rtnl_link_alloc();
if (!link)
goto errout;
if (nltool_connect(nlh, NETLINK_ROUTE) < 0)
goto errout_put;
link_cache = nltool_alloc_link_cache(nlh);
if (!link_cache)
goto errout_put;
params.dp_type = nltool_parse_dumptype(argv[1]);
if (params.dp_type < 0)
goto errout_put;
get_filter(link, argc, argv, 2, link_cache);
nl_cache_dump_filter(link_cache, &params, (struct nl_object *) link);
nl_cache_free(link_cache);
err = 0;
errout_put:
rtnl_link_put(link);
errout:
nl_close(nlh);
nl_handle_destroy(nlh);
return err;
}

View File

@ -6,50 +6,37 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
#include "utils.h"
int main(int argc, char **argv)
static void print_usage(void)
{
struct nl_handle *nlh;
struct nl_cache *link_cache;
int err = -1, ifindex;
char dst[32] = {0};
const char *name;
if (nltool_init(argc, argv) < 0)
return -1;
if (argc < 2 || !strcmp(argv[1], "-h")) {
fprintf(stderr, "Usage: nl-link-ifindex2name <ifindex>\n");
return -1;
}
nlh = nltool_alloc_handle();
if (!nlh)
return -1;
if (nltool_connect(nlh, NETLINK_ROUTE) < 0)
goto errout;
link_cache = nltool_alloc_link_cache(nlh);
if (!link_cache)
goto errout;
ifindex = strtoul(argv[1], NULL, 0);
if (!(name = rtnl_link_i2name(link_cache, ifindex, dst, sizeof(dst))))
fprintf(stderr, "Interface index %d does not exist\n", ifindex);
else
printf("%s\n", name);
nl_cache_free(link_cache);
err = 0;
errout:
nl_close(nlh);
nl_handle_destroy(nlh);
return err;
printf("Usage: nl-link-ifindex2name <ifindex>\n");
exit(0);
}
int main(int argc, char *argv[])
{
struct nl_sock *sock;
struct nl_cache *link_cache;
char name[IFNAMSIZ];
uint32_t ifindex;
if (argc < 2)
print_usage();
sock = nlt_alloc_socket();
nlt_connect(sock, NETLINK_ROUTE);
link_cache = nlt_alloc_link_cache(sock);
ifindex = parse_u32(argv[1]);
if (!rtnl_link_i2name(link_cache, ifindex, name, sizeof(name)))
fatal(ENOENT, "Interface index %d does not exist", ifindex);
printf("%s\n", name);
return 0;
}

105
src/nl-link-list.c Normal file
View File

@ -0,0 +1,105 @@
/*
* src/nl-link-dump.c Dump link attributes
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
#if 0
static void print_usage(void)
{
printf(
"Usage: nl-link-dump <mode> [<filter>]\n"
" mode := { brief | detailed | stats | xml }\n"
" filter := [dev DEV] [mtu MTU] [txqlen TXQLEN] [weight WEIGHT] [link LINK]\n"
" [master MASTER] [qdisc QDISC] [addr ADDR] [broadcast BRD]\n"
" [{ up | down }] [{ arp | noarp }] [{ promisc | nopromisc }]\n"
" [{ dynamic | nodynamic }] [{ multicast | nomulticast }]\n"
" [{ trailers | notrailers }] [{ allmulticast | noallmulticast }]\n");
exit(1);
}
#endif
#include "link-utils.h"
static void print_usage(void)
{
printf(
"Usage: nl-link-list [OPTION]... [Link]\n"
"\n"
"Options\n"
" -f, --format=TYPE Output format { brief | details | stats }\n"
" -h, --help Show this help\n"
" -v, --version Show versioning information\n"
"\n"
"Link Options\n"
" -n, --name=NAME link name\n"
" -i, --index interface index\n"
" --mtu=NUM MTU value\n"
" --txqlen=NUM TX queue length\n"
" --weight=NUM weight\n"
);
exit(0);
}
int main(int argc, char *argv[])
{
struct nl_sock *sock;
struct nl_cache *link_cache;
struct rtnl_link *link;
struct nl_dump_params params = {
.dp_type = NL_DUMP_ONELINE,
.dp_fd = stdout,
};
sock = nlt_alloc_socket();
nlt_connect(sock, NETLINK_ROUTE);
link_cache = nlt_alloc_link_cache(sock);
link = nlt_alloc_link();
for (;;) {
int c, optidx = 0;
enum {
ARG_FAMILY = 257,
ARG_MTU = 258,
ARG_TXQLEN,
ARG_WEIGHT,
};
static struct option long_opts[] = {
{ "format", 1, 0, 'f' },
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'v' },
{ "name", 1, 0, 'n' },
{ "index", 1, 0, 'i' },
{ "family", 1, 0, ARG_FAMILY },
{ "mtu", 1, 0, ARG_MTU },
{ "txqlen", 1, 0, ARG_TXQLEN },
{ "weight", 1, 0, ARG_WEIGHT },
{ 0, 0, 0, 0 }
};
c = getopt_long(argc, argv, "f:hvn:i:", long_opts, &optidx);
if (c == -1)
break;
switch (c) {
case 'f': params.dp_type = nlt_parse_dumptype(optarg); break;
case 'h': print_usage(); break;
case 'v': nlt_print_version(); break;
case 'n': parse_name(link, optarg); break;
case 'i': parse_ifindex(link, optarg); break;
case ARG_FAMILY: parse_family(link, optarg); break;
case ARG_MTU: parse_mtu(link, optarg); break;
case ARG_TXQLEN: parse_txqlen(link, optarg); break;
case ARG_WEIGHT: parse_weight(link, optarg); break;
}
}
nl_cache_dump_filter(link_cache, &params, OBJ_CAST(link));
return 0;
}

View File

@ -6,46 +6,34 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
#include "utils.h"
static void print_usage(void)
{
printf("Usage: nl-link-ifindex2name <ifindex>\n");
exit(0);
}
int main(int argc, char *argv[])
{
struct nl_handle *nlh;
struct nl_sock *sock;
struct nl_cache *link_cache;
int err = -1, ifindex;
uint32_t ifindex;
if (nltool_init(argc, argv) < 0)
return -1;
if (argc < 2)
print_usage();
if (argc < 2 || !strcmp(argv[1], "-h")) {
printf("Usage: nl-link-name2ifindex <name>\n");
return -1;
}
sock = nlt_alloc_socket();
nlt_connect(sock, NETLINK_ROUTE);
link_cache = nlt_alloc_link_cache(sock);
nlh = nltool_alloc_handle();
if (!nlh)
return -1;
if (!(ifindex = rtnl_link_name2i(link_cache, argv[1])))
fatal(ENOENT, "Interface \"%s\" does not exist", argv[1]);
if (nltool_connect(nlh, NETLINK_ROUTE) < 0)
goto errout;
printf("%u\n", ifindex);
link_cache = nltool_alloc_link_cache(nlh);
if (!link_cache)
goto errout;
if ((ifindex = rtnl_link_name2i(link_cache, argv[1])) == RTNL_LINK_NOT_FOUND)
fprintf(stderr, "Interface %s does not exist\n", argv[1]);
else
printf("%d\n", ifindex);
nl_cache_free(link_cache);
err = 0;
errout:
nl_close(nlh);
nl_handle_destroy(nlh);
return err;
return 0;
}

View File

@ -6,78 +6,117 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
#include "utils.h"
#include "link-utils.h"
static void print_usage(void)
{
printf(
"Usage: nl-link-set <ifindex> <changes>\n"
" changes := [dev DEV] [mtu MTU] [txqlen TXQLEN] [weight WEIGHT] [link LINK]\n"
static struct nl_sock *sock;
static int quiet = 0;
#if 0
" changes := [link LINK]\n"
" [master MASTER] [qdisc QDISC] [addr ADDR] [broadcast BRD]\n"
" [{ up | down }] [{ arp | noarp }] [{ promisc | nopromisc }]\n"
" [{ dynamic | nodynamic }] [{ multicast | nomulticast }]\n"
" [{ trailers | notrailers }] [{ allmulticast | noallmulticast }]\n");
exit(1);
#endif
static void print_usage(void)
{
printf(
"Usage: nl-link-set [OPTION]... [LINK]\n"
"\n"
"Options\n"
" -q, --quiet Do not print informal notifications\n"
" -h, --help Show this help\n"
" -v, --version Show versioning information\n"
"\n"
"Selecting the Link\n"
" -n, --name=NAME link name\n"
" -i, --index interface index\n"
"Change Options\n"
" --rename=NAME rename interface\n"
" --mtu=NUM MTU value\n"
" --txqlen=NUM TX queue length\n"
" --weight=NUM weight\n"
);
exit(0);
}
#include "f_link.c"
static void set_cb(struct nl_object *obj, void *arg)
{
struct rtnl_link *link = nl_object_priv(obj);
struct rtnl_link *change = arg;
struct nl_dump_params params = {
.dp_type = NL_DUMP_ONELINE,
.dp_fd = stdout,
};
int err;
if ((err = rtnl_link_change(sock, link, change, 0) < 0))
fatal(err, "Unable to change link: %s", nl_geterror(err));
if (!quiet) {
printf("Changed ");
nl_object_dump(OBJ_CAST(link), &params);
}
}
int main(int argc, char *argv[])
{
struct nl_handle *nlh;
struct nl_cache *link_cache;
struct rtnl_link *link, *orig;
int err = 1, ifindex;
struct rtnl_link *link, *change;
int ok = 0;
if (nltool_init(argc, argv) < 0)
return -1;
sock = nlt_alloc_socket();
nlt_connect(sock, NETLINK_ROUTE);
link_cache = nlt_alloc_link_cache(sock);
link = nlt_alloc_link();
change = nlt_alloc_link();
if (argc < 2 || !strcmp(argv[1], "-h"))
for (;;) {
int c, optidx = 0;
enum {
ARG_RENAME = 257,
ARG_MTU = 258,
ARG_TXQLEN,
ARG_WEIGHT,
};
static struct option long_opts[] = {
{ "quiet", 0, 0, 'q' },
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'v' },
{ "name", 1, 0, 'n' },
{ "index", 1, 0, 'i' },
{ "rename", 1, 0, ARG_RENAME },
{ "mtu", 1, 0, ARG_MTU },
{ "txqlen", 1, 0, ARG_TXQLEN },
{ "weight", 1, 0, ARG_WEIGHT },
{ 0, 0, 0, 0 }
};
c = getopt_long(argc, argv, "qhvn:i:", long_opts, &optidx);
if (c == -1)
break;
switch (c) {
case 'q': quiet = 1; break;
case 'h': print_usage(); break;
case 'v': nlt_print_version(); break;
case 'n': ok++; parse_name(link, optarg); break;
case 'i': ok++; parse_ifindex(link, optarg); break;
case ARG_RENAME: parse_name(change, optarg); break;
case ARG_MTU: parse_mtu(link, optarg); break;
case ARG_TXQLEN: parse_txqlen(link, optarg); break;
case ARG_WEIGHT: parse_weight(link, optarg); break;
}
}
if (!ok)
print_usage();
nlh = nltool_alloc_handle();
if (!nlh)
return -1;
nl_cache_foreach_filter(link_cache, OBJ_CAST(link), set_cb, change);
link = rtnl_link_alloc();
if (!link)
goto errout;
if (nltool_connect(nlh, NETLINK_ROUTE) < 0)
goto errout_free;
link_cache = nltool_alloc_link_cache(nlh);
if (!link_cache)
goto errout_close;
ifindex = strtoul(argv[1], NULL, 0);
if (!(orig = rtnl_link_get(link_cache, ifindex))) {
fprintf(stderr, "Interface index %d does not exist\n", ifindex);
goto errout_cache;
}
get_filter(link, argc, argv, 2, link_cache);
if (rtnl_link_change(nlh, orig, link, 0) < 0) {
fprintf(stderr, "Unable to change link: %s\n", nl_geterror());
goto errout_put;
}
err = 0;
errout_put:
rtnl_link_put(orig);
errout_cache:
nl_cache_free(link_cache);
errout_close:
nl_close(nlh);
errout_free:
rtnl_link_put(link);
errout:
nl_handle_destroy(nlh);
return err;
return 0;
}

View File

@ -6,31 +6,45 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
#include "utils.h"
#include "link-utils.h"
static void print_usage(void)
{
printf(
"Usage: nl-link-stats <ifindex> [<statistic> ...]\n"
" ifindex := { all | number }\n"
" statistic := { (rx|tx)_packets | (rx|tx)_bytes | (rx|tx)_errors |\n"
" (rx|tx)_dropped | (rx|tx)_compressed | (rx|tx)_fifo_err |\n" \
" rx_len_err | rx_over_err | rx_crc_err | rx_frame_err |\n"
" rx_missed_err | tx_abort_err | tx_carrier_err |\n"
" tx_hbeat_err | tx_win_err | tx_collision | multicast }\n");
exit(1);
"Usage: nl-link-stats [OPTION]... [LINK] [ListOfStats]\n"
"\n"
"Options\n"
" -l, --list List available statistic names\n"
" -h, --help Show this help\n"
" -v, --version Show versioning information\n"
"\n"
"Link Options\n"
" -n, --name=NAME link name\n"
" -i, --index=NUM interface index\n"
);
exit(0);
}
static void list_stat_names(void)
{
char buf[64];
int i;
for (i = 0; i < RTNL_LINK_STATS_MAX; i++)
printf("%s\n", rtnl_link_stat2str(i, buf, sizeof(buf)));
exit(0);
}
static char **gargv;
static int gargc;
static void dump_stat(struct rtnl_link *link, int id)
{
uint64_t st = rtnl_link_get_stat(link, id);
char buf[62];
char buf[64];
printf("%s.%s %" PRIu64 "\n", rtnl_link_get_name(link),
rtnl_link_stat2str(id, buf, sizeof(buf)), st);
@ -38,72 +52,67 @@ static void dump_stat(struct rtnl_link *link, int id)
static void dump_stats(struct nl_object *obj, void *arg)
{
int i;
struct rtnl_link *link = (struct rtnl_link *) obj;
char **argv = arg;
if (optind >= gargc) {
int i;
if (!strcasecmp(gargv[0], "all")) {
for (i = 0; i < RTNL_LINK_STATS_MAX; i++)
dump_stat(link, i);
} else {
for (i = 0; i < gargc; i++) {
int id = rtnl_link_str2stat(gargv[i]);
while (optind < gargc) {
int id = rtnl_link_str2stat(argv[optind]);
if (id < 0)
fprintf(stderr, "Warning: Unknown statistic "
"\"%s\"\n", gargv[i]);
"\"%s\"\n", argv[optind]);
else
dump_stat(link, id);
optind++;
}
}
}
int main(int argc, char *argv[])
{
struct nl_handle *nlh;
struct nl_sock *sock;
struct nl_cache *link_cache;
int err = 1;
struct rtnl_link *link;
if (nltool_init(argc, argv) < 0)
return -1;
sock = nlt_alloc_socket();
nlt_connect(sock, NETLINK_ROUTE);
link_cache = nlt_alloc_link_cache(sock);
link = nlt_alloc_link();
if (argc < 3 || !strcmp(argv[1], "-h"))
print_usage();
for (;;) {
int c, optidx = 0;
static struct option long_opts[] = {
{ "list", 0, 0, 'l' },
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'v' },
{ "name", 1, 0, 'n' },
{ "index", 1, 0, 'i' },
{ 0, 0, 0, 0 }
};
nlh = nltool_alloc_handle();
if (!nlh)
return -1;
c = getopt_long(argc, argv, "lhvn:i:", long_opts, &optidx);
if (c == -1)
break;
if (nltool_connect(nlh, NETLINK_ROUTE) < 0)
goto errout;
link_cache = nltool_alloc_link_cache(nlh);
if (!link_cache)
goto errout_close;
gargv = &argv[2];
gargc = argc - 2;
if (!strcasecmp(argv[1], "all"))
nl_cache_foreach(link_cache, dump_stats, NULL);
else {
int ifindex = strtoul(argv[1], NULL, 0);
struct rtnl_link *link = rtnl_link_get(link_cache, ifindex);
if (!link) {
fprintf(stderr, "Could not find ifindex %d\n", ifindex);
goto errout_link_cache;
switch (c) {
case 'l': list_stat_names(); break;
case 'h': print_usage(); break;
case 'v': nlt_print_version(); break;
case 'n': parse_name(link, optarg); break;
case 'i': parse_ifindex(link, optarg); break;
}
dump_stats((struct nl_object *) link, NULL);
rtnl_link_put(link);
}
err = 0;
errout_link_cache:
nl_cache_free(link_cache);
errout_close:
nl_close(nlh);
errout:
nl_handle_destroy(nlh);
return err;
gargc = argc;
nl_cache_foreach_filter(link_cache, OBJ_CAST(link), dump_stats, argv);
return 0;
}

View File

@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
#include "utils.h"
@ -35,7 +35,7 @@ static int event_input(struct nl_msg *msg, void *arg)
int main(int argc, char *argv[])
{
struct nl_handle *nlh;
struct nl_sock *sock;
struct nl_cache *link_cache;
int err = 1;
int i, idx;
@ -61,16 +61,9 @@ int main(int argc, char *argv[])
{ RTNLGRP_NONE, NULL }
};
if (nltool_init(argc, argv) < 0)
return -1;
nlh = nltool_alloc_handle();
if (nlh == NULL)
return -1;
nl_disable_sequence_check(nlh);
nl_socket_modify_cb(nlh, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL);
sock = nlt_alloc_socket();
nl_disable_sequence_check(sock);
nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, event_input, NULL);
if (argc > 1 && !strcasecmp(argv[1], "-h")) {
printf("Usage: nl-monitor [<groups>]\n");
@ -82,18 +75,14 @@ int main(int argc, char *argv[])
return 2;
}
if (nl_connect(nlh, NETLINK_ROUTE) < 0) {
fprintf(stderr, "%s\n", nl_geterror());
goto errout;
}
nlt_connect(sock, NETLINK_ROUTE);
for (idx = 1; argc > idx; idx++) {
for (i = 0; known_groups[i].gr_id != RTNLGRP_NONE; i++) {
if (!strcmp(argv[idx], known_groups[i].gr_name)) {
if (nl_socket_add_membership(nlh, known_groups[i].gr_id) < 0) {
fprintf(stderr, "%s: %s\n", argv[idx], nl_geterror());
goto errout;
if ((err = nl_socket_add_membership(sock, known_groups[i].gr_id)) < 0) {
fatal(err, "%s: %s\n", argv[idx], nl_geterror(err));
}
break;
@ -103,18 +92,13 @@ int main(int argc, char *argv[])
fprintf(stderr, "Warning: Unknown group: %s\n", argv[idx]);
}
if ((link_cache = rtnl_link_alloc_cache(nlh)) == NULL) {
fprintf(stderr, "%s\n", nl_geterror());
goto errout_close;
}
nl_cache_mngt_provide(link_cache);
link_cache = nlt_alloc_link_cache(sock);
while (1) {
fd_set rfds;
int fd, retval;
fd = nl_socket_get_fd(nlh);
fd = nl_socket_get_fd(sock);
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
@ -123,13 +107,9 @@ int main(int argc, char *argv[])
if (retval) {
/* FD_ISSET(fd, &rfds) will be true */
nl_recvmsgs_default(nlh);
nl_recvmsgs_default(sock);
}
}
nl_cache_free(link_cache);
errout_close:
nl_close(nlh);
errout:
return err;
return 0;
}

View File

@ -6,74 +6,102 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
#include "utils.h"
#include "neigh-utils.h"
static int quiet = 0;
static void print_usage(void)
{
printf(
"Usage: nl-neigh-add [OPTION]... NEIGHBOUR\n"
"\n"
"Options\n"
" --update-only Do not create neighbour, updates exclusively\n"
" --create-only Do not update neighbour if it exists already.\n"
" -q, --quiet Do not print informal notifications\n"
" -h, --help Show this help\n"
" -v, --version Show versioning information\n"
"\n"
"Neighbour Options\n"
" -a, --addr=ADDR Destination address of neighbour\n"
" -l, --lladdr=ADDR Link layer address of neighbour\n"
" -d, --dev=DEV Device the neighbour is connected to\n"
" --state=STATE Neighbour state, (default = permanent)\n"
"\n"
"Example\n"
" nl-neigh-add --create-only --addr=10.0.0.1 --dev=eth0 \\\n"
" --lladdr=AA:BB:CC:DD:EE:FF\n"
);
exit(0);
}
int main(int argc, char *argv[])
{
struct nl_handle *nlh;
struct nl_sock *sock;
struct rtnl_neigh *neigh;
struct nl_addr *addr;
int err = 1;
struct nl_cache *link_cache;
struct nl_dump_params dp = {
.dp_type = NL_DUMP_ONELINE,
.dp_fd = stdout,
};
int err, ok = 0, nlflags = NLM_F_REPLACE | NLM_F_CREATE;
sock = nlt_alloc_socket();
nlt_connect(sock, NETLINK_ROUTE);
link_cache = nlt_alloc_link_cache(sock);
neigh = nlt_alloc_neigh();
for (;;) {
int c, optidx = 0;
enum {
ARG_UPDATE_ONLY = 257,
ARG_CREATE_ONLY = 258,
ARG_STATE,
};
static struct option long_opts[] = {
{ "update-only", 0, 0, ARG_UPDATE_ONLY },
{ "create-only", 0, 0, ARG_CREATE_ONLY },
{ "quiet", 0, 0, 'q' },
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'v' },
{ "addr", 1, 0, 'a' },
{ "lladdr", 1, 0, 'l' },
{ "dev", 1, 0, 'd' },
{ "state", 1, 0, ARG_STATE },
{ 0, 0, 0, 0 }
};
c = getopt_long(argc, argv, "qhva:l:d:", long_opts, &optidx);
if (c == -1)
break;
if (nltool_init(argc, argv) < 0)
return -1;
if (argc < 4 || !strcmp(argv[1], "-h")) {
printf("Usage: nl-neigh-add <addr> <lladdr> "
"<ifindex> [<state>]\n");
return 1;
}
nlh = nltool_alloc_handle();
if (!nlh)
return -1;
neigh = rtnl_neigh_alloc();
if (!neigh)
goto errout;
if (nltool_connect(nlh, NETLINK_ROUTE) < 0)
goto errout_free;
addr = nltool_addr_parse(argv[1]);
if (!addr)
goto errout_close;
rtnl_neigh_set_dst(neigh, addr);
nl_addr_put(addr);
addr = nltool_addr_parse(argv[2]);
if (!addr)
goto errout_close;
rtnl_neigh_set_lladdr(neigh, addr);
nl_addr_put(addr);
rtnl_neigh_set_ifindex(neigh, strtoul(argv[3], NULL, 0));
if (argc > 4) {
int state = rtnl_neigh_str2state(argv[4]);
if (state < 0) {
fprintf(stderr, "Unknown state \"%s\"\n", argv[4]);
goto errout_close;
switch (c) {
case ARG_UPDATE_ONLY: nlflags &= ~NLM_F_CREATE; break;
case ARG_CREATE_ONLY: nlflags |= NLM_F_EXCL; break;
case 'q': quiet = 1; break;
case 'h': print_usage(); break;
case 'v': nlt_print_version(); break;
case 'a': ok++; parse_dst(neigh, optarg); break;
case 'l': parse_lladdr(neigh, optarg); break;
case 'd': parse_dev(neigh, link_cache, optarg); break;
case ARG_STATE: parse_state(neigh, optarg); break;
}
rtnl_neigh_set_state(neigh, state);
} else
rtnl_neigh_set_state(neigh, NUD_PERMANENT);
}
if (rtnl_neigh_add(nlh, neigh, 0) < 0) {
fprintf(stderr, "Unable to add address: %s\n", nl_geterror());
goto errout_close;
}
if (!ok)
print_usage();
err = 0;
if ((err = rtnl_neigh_add(sock, neigh, nlflags)) < 0)
fatal(err, "Unable to add neighbour: %s", nl_geterror(err));
errout_close:
nl_close(nlh);
errout_free:
rtnl_neigh_put(neigh);
errout:
nl_handle_destroy(nlh);
return err;
if (!quiet) {
printf("Added ");
nl_object_dump(OBJ_CAST(neigh), &dp);
}
return 0;
}

View File

@ -6,61 +6,114 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
#include "utils.h"
#include "neigh-utils.h"
static int quiet = 0, default_yes = 0, deleted = 0, interactive = 0;
struct nl_sock *sock;
static void print_usage(void)
{
printf(
"Usage: nl-neigh-delete [OPTION]... [NEIGHBOUR]\n"
"\n"
"Options\n"
" -i, --interactive Run interactively\n"
" --yes Set default answer to yes\n"
" -q, --quiet Do not print informal notifications\n"
" -h, --help Show this help\n"
" -v, --version Show versioning information\n"
"\n"
"Neighbour Options\n"
" -a, --addr=ADDR Destination address of neighbour\n"
" -l, --lladdr=ADDR Link layer address of neighbour\n"
" -d, --dev=DEV Device the neighbour is connected to\n"
" --family=FAMILY Destination address family\n"
" --state=STATE Neighbour state, (default = permanent)\n"
);
exit(0);
}
static void delete_cb(struct nl_object *obj, void *arg)
{
struct rtnl_neigh *neigh = nl_object_priv(obj);
struct nl_dump_params params = {
.dp_type = NL_DUMP_ONELINE,
.dp_fd = stdout,
};
int err;
if (interactive && !nlt_confirm(obj, &params, default_yes))
return;
if ((err = rtnl_neigh_delete(sock, neigh, 0)) < 0)
fatal(err, "Unable to delete neighbour: %s\n", nl_geterror(err));
if (!quiet) {
printf("Deleted ");
nl_object_dump(obj, &params);
}
deleted++;
}
int main(int argc, char *argv[])
{
struct nl_handle *nlh;
struct rtnl_neigh *neigh;
struct nl_addr *addr;
int err = 1;
struct nl_cache *link_cache, *neigh_cache;
sock = nlt_alloc_socket();
nlt_connect(sock, NETLINK_ROUTE);
link_cache = nlt_alloc_link_cache(sock);
neigh_cache = nlt_alloc_neigh_cache(sock);
neigh = nlt_alloc_neigh();
for (;;) {
int c, optidx = 0;
enum {
ARG_FAMILY = 257,
ARG_STATE = 258,
ARG_YES,
};
static struct option long_opts[] = {
{ "interactive", 0, 0, 'i' },
{ "yes", 0, 0, ARG_YES },
{ "quiet", 0, 0, 'q' },
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'v' },
{ "addr", 1, 0, 'a' },
{ "lladdr", 1, 0, 'l' },
{ "dev", 1, 0, 'd' },
{ "family", 1, 0, ARG_FAMILY },
{ "state", 1, 0, ARG_STATE },
{ 0, 0, 0, 0 }
};
c = getopt_long(argc, argv, "qhva:l:d:", long_opts, &optidx);
if (c == -1)
break;
if (nltool_init(argc, argv) < 0)
return -1;
switch (c) {
case 'i': interactive = 1; break;
case ARG_YES: default_yes = 1; break;
case 'q': quiet = 1; break;
case 'h': print_usage(); break;
case 'v': nlt_print_version(); break;
case 'a': parse_dst(neigh, optarg); break;
case 'l': parse_lladdr(neigh, optarg); break;
case 'd': parse_dev(neigh, link_cache, optarg); break;
case ARG_FAMILY: parse_family(neigh, optarg); break;
case ARG_STATE: parse_state(neigh, optarg); break;
}
}
if (argc < 3 || !strcmp(argv[1], "-h")) {
printf("Usage: nl-neigh-delete <addr> <ifindex>\n");
return 2;
}
nl_cache_foreach_filter(neigh_cache, OBJ_CAST(neigh), delete_cb, NULL);
nlh = nltool_alloc_handle();
if (!nlh)
return -1;
if (!quiet)
printf("Deleted %d neighbours\n", deleted);
neigh = rtnl_neigh_alloc();
if (neigh == NULL)
goto errout;
if (nl_connect(nlh, NETLINK_ROUTE) < 0) {
fprintf(stderr, "%s\n", nl_geterror());
goto errout_free;
}
addr = nl_addr_parse(argv[1], AF_UNSPEC);
if (addr == NULL) {
fprintf(stderr, "Invalid address \"%s\"\n", argv[1]);
goto errout_close;
}
rtnl_neigh_set_dst(neigh, addr);
nl_addr_put(addr);
rtnl_neigh_set_ifindex(neigh, strtoul(argv[2], NULL, 0));
if (rtnl_neigh_delete(nlh, neigh, 0) < 0) {
fprintf(stderr, "%s\n", nl_geterror());
goto errout_close;
}
err = 0;
errout_close:
nl_close(nlh);
errout_free:
rtnl_neigh_put(neigh);
errout:
nl_handle_destroy(nlh);
return err;
return 0;
}

View File

@ -1,82 +0,0 @@
/*
* src/nl-neigh-dump.c Dump neighbour attributes
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
*/
#include "utils.h"
static void print_usage(void)
{
printf(
"Usage: nl-neigh-dump <mode> [<filter>]\n"
" mode := { brief | detailed | stats | xml }\n"
" filter := [dev DEV] [dst ADDR] [lladdr ADDR]\n");
exit(1);
}
#include "f_neigh.c"
int main(int argc, char *argv[])
{
struct nl_handle *nlh;
struct nl_cache *link_cache, *neigh_cache;
struct rtnl_neigh *neigh;
struct nl_dump_params params = {
.dp_fd = stdout,
.dp_type = NL_DUMP_BRIEF
};
int err = 1;
if (nltool_init(argc, argv) < 0)
return -1;
if (argc < 2 || !strcmp(argv[1], "-h"))
print_usage();
nlh = nltool_alloc_handle();
if (!nlh)
return -1;
neigh = rtnl_neigh_alloc();
if (neigh == NULL)
goto errout;
if (nltool_connect(nlh, NETLINK_ROUTE) < 0)
goto errout_free;
link_cache = nltool_alloc_link_cache(nlh);
if (!link_cache)
goto errout_close;
neigh_cache = nltool_alloc_neigh_cache(nlh);
if (!neigh_cache)
goto errout_link_cache;
params.dp_type = nltool_parse_dumptype(argv[1]);
if (params.dp_type < 0)
goto errout_neigh_cache;
get_filter(neigh, argc, argv, 2, neigh_cache);
nl_cache_dump_filter(neigh_cache, &params, (struct nl_object *) neigh);
err = 0;
errout_neigh_cache:
nl_cache_free(neigh_cache);
errout_link_cache:
nl_cache_free(link_cache);
errout_close:
nl_close(nlh);
errout_free:
rtnl_neigh_put(neigh);
errout:
nl_handle_destroy(nlh);
return err;
}

87
src/nl-neigh-list.c Normal file
View File

@ -0,0 +1,87 @@
/*
* src/nl-neigh-list.c List Neighbours
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
#include "neigh-utils.h"
static void print_usage(void)
{
printf(
"Usage: nl-neigh-list [OPTION]... [NEIGHBOUR]\n"
"\n"
"Options\n"
" -f, --format=TYPE Output format { brief | details | stats }\n"
" -h, --help Show this help\n"
" -v, --version Show versioning information\n"
"\n"
"Neighbour Options\n"
" -a, --addr=ADDR Destination address of neighbour\n"
" -l, --lladdr=ADDR Link layer address of neighbour\n"
" -d, --dev=DEV Device the neighbour is connected to\n"
" --family=FAMILY Destination address family\n"
" --state=STATE Neighbour state, (default = permanent)\n"
);
exit(0);
}
int main(int argc, char *argv[])
{
struct nl_sock *sock;
struct rtnl_neigh *neigh;
struct nl_cache *link_cache, *neigh_cache;
struct nl_dump_params params = {
.dp_type = NL_DUMP_ONELINE,
.dp_fd = stdout,
};
sock = nlt_alloc_socket();
nlt_connect(sock, NETLINK_ROUTE);
link_cache = nlt_alloc_link_cache(sock);
neigh_cache = nlt_alloc_neigh_cache(sock);
neigh = nlt_alloc_neigh();
for (;;) {
int c, optidx = 0;
enum {
ARG_FAMILY = 257,
ARG_STATE = 258,
};
static struct option long_opts[] = {
{ "format", 1, 0, 'f' },
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'v' },
{ "addr", 1, 0, 'a' },
{ "lladdr", 1, 0, 'l' },
{ "dev", 1, 0, 'd' },
{ "family", 1, 0, ARG_FAMILY },
{ "state", 1, 0, ARG_STATE },
{ 0, 0, 0, 0 }
};
c = getopt_long(argc, argv, "f:hva:l:d:", long_opts, &optidx);
if (c == -1)
break;
switch (c) {
case 'f': params.dp_type = nlt_parse_dumptype(optarg); break;
case 'h': print_usage(); break;
case 'v': nlt_print_version(); break;
case 'a': parse_dst(neigh, optarg); break;
case 'l': parse_lladdr(neigh, optarg); break;
case 'd': parse_dev(neigh, link_cache, optarg); break;
case ARG_FAMILY: parse_family(neigh, optarg); break;
case ARG_STATE: parse_state(neigh, optarg); break;
}
}
nl_cache_dump_filter(neigh_cache, &params, OBJ_CAST(neigh));
return 0;
}

View File

@ -1,70 +0,0 @@
/*
* src/nl-neightbl-dump.c Dump neighbour tables
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
*/
#include "utils.h"
static void print_usage(void)
{
printf(
"Usage: nl-neightbl-dump <mode> [<filter>]\n"
" mode := { brief | detailed | stats | xml }\n"
" filter :=\n");
exit(1);
}
int main(int argc, char *argv[])
{
int err = -1;
struct nl_handle *nlh;
struct nl_cache *ntc, *lc;
struct nl_dump_params params = {
.dp_fd = stdout,
.dp_type = NL_DUMP_BRIEF,
};
if (argc < 2)
print_usage();
if (nltool_init(argc, argv) < 0)
return -1;
nlh = nltool_alloc_handle();
if (!nlh)
return -1;
if (nltool_connect(nlh, NETLINK_ROUTE) < 0)
goto errout;
ntc = nltool_alloc_neightbl_cache(nlh);
if (!ntc)
goto errout_close;
lc = nltool_alloc_link_cache(nlh);
if (!lc)
goto errout_ntbl_cache;
params.dp_type = nltool_parse_dumptype(argv[1]);
if (params.dp_type < 0)
goto errout_link_cache;
nl_cache_dump(ntc, &params);
err = 0;
errout_link_cache:
nl_cache_free(lc);
errout_ntbl_cache:
nl_cache_free(ntc);
errout_close:
nl_close(nlh);
errout:
nl_handle_destroy(nlh);
return err;
}

64
src/nl-neightbl-list.c Normal file
View File

@ -0,0 +1,64 @@
/*
* src/nl-neightbl-list.c Dump neighbour tables
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
#include "utils.h"
static void print_usage(void)
{
printf(
"Usage: nl-neightbl-list [OPTION]...\n"
"\n"
"Options\n"
" -f, --format=TYPE Output format { brief | details | stats }\n"
" -h, --help Show this help\n"
" -v, --version Show versioning information\n"
);
exit(0);
}
int main(int argc, char *argv[])
{
struct nl_sock *sock;
struct nl_cache *link_cache, *neightbl_cache;
struct nl_dump_params params = {
.dp_type = NL_DUMP_ONELINE,
.dp_fd = stdout,
};
sock = nlt_alloc_socket();
nlt_connect(sock, NETLINK_ROUTE);
link_cache = nlt_alloc_link_cache(sock);
neightbl_cache = nlt_alloc_neightbl_cache(sock);
for (;;) {
int c, optidx = 0;
static struct option long_opts[] = {
{ "format", 1, 0, 'f' },
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'v' },
{ 0, 0, 0, 0 }
};
c = getopt_long(argc, argv, "f:hv", long_opts, &optidx);
if (c == -1)
break;
switch (c) {
case 'f': params.dp_type = nlt_parse_dumptype(optarg); break;
case 'h': print_usage(); break;
case 'v': nlt_print_version(); break;
}
}
nl_cache_dump(neightbl_cache, &params);
return 0;
}

View File

@ -1,76 +1,114 @@
/*
* src/nl-qdisc-delete.c Delete Qdiscs
* src/nl-qdisc-delete.c Delete Queuing Disciplines
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
#include "utils.h"
#include "qdisc-utils.h"
static int quiet = 0, default_yes = 0, deleted = 0, interactive = 0;
struct nl_sock *sock;
static void print_usage(void)
{
printf("Usage: nl-qdisc-delete <ifindex> <parent> <handle>\n");
exit(1);
printf(
"Usage: nl-qdisc-delete [OPTION]... [QDISC]\n"
"\n"
"Options\n"
" -i, --interactive Run interactively\n"
" --yes Set default answer to yes\n"
" -q, --quiet Do not print informal notifications\n"
" -h, --help Show this help\n"
" -v, --version Show versioning information\n"
"\n"
"QDisc Options\n"
" -d, --dev=DEV Device the qdisc is attached to\n"
" -p, --parent=HANDLE Identifier of parent qdisc\n"
" -H, --handle=HANDLE Identifier\n"
" -k, --kind=NAME Kind of qdisc (e.g. pfifo_fast)\n"
);
exit(0);
}
static void delete_cb(struct nl_object *obj, void *arg)
{
struct rtnl_qdisc *qdisc = nl_object_priv(obj);
struct nl_dump_params params = {
.dp_type = NL_DUMP_ONELINE,
.dp_fd = stdout,
};
int err;
if (interactive && !nlt_confirm(obj, &params, default_yes))
return;
if ((err = rtnl_qdisc_delete(sock, qdisc)) < 0)
fatal(err, "Unable to delete qdisc: %s\n", nl_geterror(err));
if (!quiet) {
printf("Deleted ");
nl_object_dump(obj, &params);
}
deleted++;
}
int main(int argc, char *argv[])
{
struct nl_handle *nlh;
struct rtnl_qdisc *qdisc;
uint32_t handle, parent;
int err = 1;
struct nl_cache *link_cache, *qdisc_cache;
sock = nlt_alloc_socket();
nlt_connect(sock, NETLINK_ROUTE);
link_cache = nlt_alloc_link_cache(sock);
qdisc_cache = nlt_alloc_qdisc_cache(sock);
qdisc = nlt_alloc_qdisc();
for (;;) {
int c, optidx = 0;
enum {
ARG_YES = 257,
};
static struct option long_opts[] = {
{ "interactive", 0, 0, 'i' },
{ "yes", 0, 0, ARG_YES },
{ "quiet", 0, 0, 'q' },
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'v' },
{ "dev", 1, 0, 'd' },
{ "parent", 1, 0, 'p' },
{ "handle", 1, 0, 'H' },
{ "kind", 1, 0, 'k' },
{ 0, 0, 0, 0 }
};
c = getopt_long(argc, argv, "iqhvd:p:H:k:", long_opts, &optidx);
if (c == -1)
break;
if (nltool_init(argc, argv) < 0)
return -1;
if (argc < 3 || !strcmp(argv[1], "-h"))
print_usage();
nlh = nltool_alloc_handle();
if (!nlh)
goto errout;
qdisc = rtnl_qdisc_alloc();
if (!qdisc)
goto errout_free_handle;
rtnl_qdisc_set_ifindex(qdisc, strtoul(argv[1], NULL, 0));
if (rtnl_tc_str2handle(argv[2], &parent) < 0) {
fprintf(stderr, "%s\n", nl_geterror());
goto errout_free_qdisc;
}
if (argc > 3) {
if (rtnl_tc_str2handle(argv[3], &handle) < 0) {
fprintf(stderr, "%s\n", nl_geterror());
goto errout_free_qdisc;
switch (c) {
case 'i': interactive = 1; break;
case ARG_YES: default_yes = 1; break;
case 'q': quiet = 1; break;
case 'h': print_usage(); break;
case 'v': nlt_print_version(); break;
case 'd': parse_dev(qdisc, link_cache, optarg); break;
case 'p': parse_parent(qdisc, optarg); break;
case 'H': parse_handle(qdisc, optarg); break;
case 'k': parse_kind(qdisc, optarg); break;
}
}
rtnl_qdisc_set_handle(qdisc, handle);
}
nl_cache_foreach_filter(qdisc_cache, OBJ_CAST(qdisc), delete_cb, NULL);
rtnl_qdisc_set_parent(qdisc, parent);
if (!quiet)
printf("Deleted %d qdiscs\n", deleted);
if (nltool_connect(nlh, NETLINK_ROUTE) < 0)
goto errout_free_qdisc;
if (rtnl_qdisc_delete(nlh, qdisc) < 0) {
fprintf(stderr, "Unable to delete Qdisc: %s\n", nl_geterror());
goto errout_close;
}
err = 0;
errout_close:
nl_close(nlh);
errout_free_qdisc:
rtnl_qdisc_put(qdisc);
errout_free_handle:
nl_handle_destroy(nlh);
errout:
return err;
return 0;
}

View File

@ -1,74 +0,0 @@
/*
* src/nl-qdisc-dump.c Dump qdisc attributes
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
*/
#include "utils.h"
static void print_usage(void)
{
printf(
"Usage: nl-qdisc-dump <mode>\n"
" mode := { brief | detailed | stats | xml }\n");
exit(1);
}
int main(int argc, char *argv[])
{
struct nl_handle *nlh;
struct nl_cache *link_cache, *qdisc_cache;
struct rtnl_qdisc *qdisc;
struct nl_dump_params params = {
.dp_fd = stdout,
.dp_type = NL_DUMP_BRIEF
};
int err = 1;
if (nltool_init(argc, argv) < 0)
return -1;
if (argc < 2 || !strcmp(argv[1], "-h"))
print_usage();
params.dp_type = nltool_parse_dumptype(argv[1]);
if (params.dp_type < 0)
return -1;
nlh = nltool_alloc_handle();
if (!nlh)
return -1;
qdisc = rtnl_qdisc_alloc();
if (!qdisc)
goto errout_no_put;
if (nltool_connect(nlh, NETLINK_ROUTE) < 0)
goto errout;
link_cache = nltool_alloc_link_cache(nlh);
if (!link_cache)
goto errout;
qdisc_cache = nltool_alloc_qdisc_cache(nlh);
if (!qdisc_cache)
goto errout_link_cache;
nl_cache_dump_filter(qdisc_cache, &params, (struct nl_object *) qdisc);
nl_cache_free(qdisc_cache);
err = 0;
errout_link_cache:
nl_cache_free(link_cache);
errout:
rtnl_qdisc_put(qdisc);
errout_no_put:
nl_close(nlh);
nl_handle_destroy(nlh);
return err;
}

88
src/nl-qdisc-list.c Normal file
View File

@ -0,0 +1,88 @@
/*
* src/nl-qdisc-list.c List Qdiscs
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
#include "qdisc-utils.h"
static int quiet = 0;
static void print_usage(void)
{
printf(
"Usage: nl-qdisc-list [OPTION]... [QDISC]\n"
"\n"
"Options\n"
" -f, --format=TYPE Output format { brief | details | stats }\n"
" -h, --help Show this help\n"
" -v, --version Show versioning information\n"
"\n"
"QDisc Options\n"
" -d, --dev=DEV Device the qdisc is attached to\n"
" -p, --parent=HANDLE Identifier of parent qdisc\n"
" -H, --handle=HANDLE Identifier\n"
" -k, --kind=NAME Kind of qdisc (e.g. pfifo_fast)\n"
);
exit(0);
}
int main(int argc, char *argv[])
{
struct nl_sock *sock;
struct rtnl_qdisc *qdisc;
struct nl_cache *link_cache, *qdisc_cache;
struct nl_dump_params params = {
.dp_type = NL_DUMP_ONELINE,
.dp_fd = stdout,
};
sock = nlt_alloc_socket();
nlt_connect(sock, NETLINK_ROUTE);
link_cache = nlt_alloc_link_cache(sock);
qdisc_cache = nlt_alloc_qdisc_cache(sock);
qdisc = nlt_alloc_qdisc();
for (;;) {
int c, optidx = 0;
enum {
ARG_YES = 257,
};
static struct option long_opts[] = {
{ "format", 1, 0, 'f' },
{ "quiet", 0, 0, 'q' },
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'v' },
{ "dev", 1, 0, 'd' },
{ "parent", 1, 0, 'p' },
{ "handle", 1, 0, 'H' },
{ "kind", 1, 0, 'k' },
{ 0, 0, 0, 0 }
};
c = getopt_long(argc, argv, "f:qhvd:p:H:k:",
long_opts, &optidx);
if (c == -1)
break;
switch (c) {
case 'f': params.dp_type = nlt_parse_dumptype(optarg); break;
case 'q': quiet = 1; break;
case 'h': print_usage(); break;
case 'v': nlt_print_version(); break;
case 'd': parse_dev(qdisc, link_cache, optarg); break;
case 'p': parse_parent(qdisc, optarg); break;
case 'H': parse_handle(qdisc, optarg); break;
case 'k': parse_kind(qdisc, optarg); break;
}
}
nl_cache_dump_filter(qdisc_cache, &params, OBJ_CAST(qdisc));
return 0;
}

View File

@ -14,12 +14,6 @@
static int quiet = 0;
static struct nl_cache *link_cache, *route_cache;
static void print_version(void)
{
fprintf(stderr, "%s\n", LIBNL_STRING);
exit(0);
}
static void print_usage(void)
{
printf(
@ -55,7 +49,7 @@ static void print_usage(void)
int main(int argc, char *argv[])
{
struct nl_handle *nlh;
struct nl_handle *sock;
struct rtnl_route *route;
struct nl_dump_params dp = {
.dp_type = NL_DUMP_ONELINE,
@ -63,14 +57,11 @@ int main(int argc, char *argv[])
};
int err = 1;
nlh = nltool_alloc_handle();
nltool_connect(nlh, NETLINK_ROUTE);
link_cache = nltool_alloc_link_cache(nlh);
route_cache = nltool_alloc_route_cache(nlh, 0);
route = rtnl_route_alloc();
if (!route)
goto errout;
sock = nlt_alloc_socket();
nlt_connect(sock, NETLINK_ROUTE);
link_cache = nlt_alloc_link_cache(sock);
route_cache = nlt_alloc_route_cache(sock, 0);
route = nlt_alloc_route();
for (;;) {
int c, optidx = 0;
@ -111,7 +102,7 @@ int main(int argc, char *argv[])
switch (c) {
case 'q': quiet = 1; break;
case 'h': print_usage(); break;
case 'v': print_version(); break;
case 'v': nlt_print_version(); break;
case 'd': parse_dst(route, optarg); break;
case 'n': parse_nexthop(route, optarg, link_cache); break;
case 't': parse_table(route, optarg); break;
@ -127,24 +118,13 @@ int main(int argc, char *argv[])
}
}
if (rtnl_route_add(nlh, route, 0) < 0) {
fprintf(stderr, "rtnl_route_add failed: %s\n", nl_geterror());
goto errout_free;
}
if ((err = rtnl_route_add(sock, route, 0)) < 0)
fatal(err, "Unable to add route: %s", nl_geterror(err));
if (!quiet) {
printf("Added ");
nl_object_dump(OBJ_CAST(route), &dp);
}
err = 0;
errout_free:
rtnl_route_put(route);
errout:
nl_cache_free(route_cache);
nl_cache_free(link_cache);
nl_close(nlh);
nl_handle_destroy(nlh);
return err;
return 0;
}

View File

@ -13,7 +13,7 @@
static int interactive = 0, default_yes = 0, quiet = 0;
static int deleted = 0;
static struct nl_handle *nlh;
static struct nl_handle *sock;
static void print_version(void)
{
@ -59,36 +59,21 @@ static void print_usage(void)
static void delete_cb(struct nl_object *obj, void *arg)
{
struct rtnl_route *route = (struct rtnl_route *) obj;
struct nl_dump_params dp = {
struct nl_dump_params params = {
.dp_type = NL_DUMP_ONELINE,
.dp_fd = stdout,
};
int err;
if (interactive) {
int answer;
if (interactive && !nlt_confirm(obj, &params, default_yes))
return;
nl_object_dump(obj, &dp);
printf("Delete? (%c/%c) ",
default_yes ? 'Y' : 'y',
default_yes ? 'n' : 'N');
do {
answer = tolower(getchar());
if (answer == '\n')
answer = default_yes ? 'y' : 'n';
} while (answer != 'y' && answer != 'n');
if (answer == 'n')
return;
}
if ((err = rtnl_route_delete(nlh, route, 0)) < 0)
fatal(err, "rtnl_route_del failed: %s\n", nl_geterror());
if ((err = rtnl_route_delete(sock, route, 0)) < 0)
fatal(err, "Unable to delete route: %s", nl_geterror(err));
if (!quiet) {
printf("Deleted ");
nl_object_dump(obj, &dp);
nl_object_dump(obj, &params);
}
deleted++;
@ -98,16 +83,13 @@ int main(int argc, char *argv[])
{
struct nl_cache *link_cache, *route_cache;
struct rtnl_route *route;
int err = 1, nf = 0;
int nf = 0;
nlh = nltool_alloc_handle();
nltool_connect(nlh, NETLINK_ROUTE);
link_cache = nltool_alloc_link_cache(nlh);
route_cache = nltool_alloc_route_cache(nlh, 0);
route = rtnl_route_alloc();
if (!route)
goto errout;
sock = nlt_alloc_socket();
nlt_connect(sock, NETLINK_ROUTE);
link_cache = nlt_alloc_link_cache(sock);
route_cache = nlt_alloc_route_cache(sock, 0);
route = nlt_alloc_route();
for (;;) {
int c, optidx = 0;
@ -180,14 +162,5 @@ int main(int argc, char *argv[])
if (!quiet)
printf("Deleted %d routes\n", deleted);
err = 0;
rtnl_route_put(route);
errout:
nl_cache_free(route_cache);
nl_cache_free(link_cache);
nl_close(nlh);
nl_handle_destroy(nlh);
return err;
return 0;
}

View File

@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
#include "utils.h"
@ -17,48 +17,43 @@ static void print_usage(void)
exit(1);
}
static void parse_cb(struct nl_object *obj, void *arg)
{
//struct rtnl_route *route = (struct rtnl_route *) obj;
struct nl_dump_params params = {
.dp_fd = stdout,
.dp_type = NL_DUMP_DETAILS,
};
nl_object_dump(obj, &params);
}
static int cb(struct nl_msg *msg, void *arg)
{
nl_cache_parse_and_add(arg, msg);
int err;
if ((err = nl_msg_parse(msg, &parse_cb, NULL)) < 0)
fatal(err, "Unable to parse object: %s", nl_geterror(err));
return 0;
}
int main(int argc, char *argv[])
{
struct nl_handle *nlh;
struct nl_sock *sock;
struct nl_cache *link_cache, *route_cache;
struct nl_addr *dst;
struct nl_dump_params params = {
.dp_fd = stdout,
.dp_type = NL_DUMP_BRIEF
};
int err = 1;
if (argc < 2 || !strcmp(argv[1], "-h"))
print_usage();
if (nltool_init(argc, argv) < 0)
goto errout;
sock = nlt_alloc_socket();
nlt_connect(sock, NETLINK_ROUTE);
link_cache = nlt_alloc_link_cache(sock);
route_cache = nlt_alloc_route_cache(sock, 0);
nlh = nltool_alloc_handle();
if (!nlh)
goto errout;
if (nltool_connect(nlh, NETLINK_ROUTE) < 0)
goto errout_free_handle;
link_cache = nltool_alloc_link_cache(nlh);
if (!link_cache)
goto errout_close;
dst = nltool_addr_parse(argv[1]);
if (!dst)
goto errout_link_cache;
route_cache = nltool_alloc_route_cache(nlh, 0);
if (!route_cache)
goto errout_addr_put;
dst = nlt_addr_parse(argv[1], AF_INET);
{
struct nl_msg *m;
@ -71,36 +66,18 @@ int main(int argc, char *argv[])
nlmsg_append(m, &rmsg, sizeof(rmsg), NLMSG_ALIGNTO);
nla_put_addr(m, RTA_DST, dst);
if ((err = nl_send_auto_complete(nlh, m)) < 0) {
nlmsg_free(m);
fprintf(stderr, "%s\n", nl_geterror());
goto errout_route_cache;
}
err = nl_send_auto_complete(sock, m);
nlmsg_free(m);
if (err < 0)
fatal(err, "%s", nl_geterror(err));
nl_socket_modify_cb(nlh, NL_CB_VALID, NL_CB_CUSTOM, cb,
route_cache);
nl_socket_modify_cb(sock, NL_CB_VALID, NL_CB_CUSTOM, cb, NULL);
if (nl_recvmsgs_default(nlh) < 0) {
fprintf(stderr, "%s\n", nl_geterror());
goto errout_route_cache;
}
if (nl_recvmsgs_default(sock) < 0)
fatal(err, "%s", nl_geterror(err));
}
nl_cache_dump(route_cache, &params);
//nl_cache_dump(route_cache, &params);
err = 0;
errout_route_cache:
nl_cache_free(route_cache);
errout_addr_put:
nl_addr_put(dst);
errout_link_cache:
nl_cache_free(link_cache);
errout_close:
nl_close(nlh);
errout_free_handle:
nl_handle_destroy(nlh);
errout:
return err;
return 0;
}

View File

@ -11,12 +11,6 @@
#include "route-utils.h"
static void print_version(void)
{
fprintf(stderr, "%s\n", LIBNL_STRING);
exit(0);
}
static void print_usage(void)
{
printf(
@ -53,22 +47,19 @@ static void print_usage(void)
int main(int argc, char *argv[])
{
struct nl_handle *nlh;
struct nl_sock *sock;
struct nl_cache *link_cache, *route_cache;
struct rtnl_route *route;
struct nl_dump_params params = {
.dp_fd = stdout,
.dp_type = NL_DUMP_BRIEF
};
int err = 1, print_cache = 0;
int print_cache = 0;
nlh = nltool_alloc_handle();
nltool_connect(nlh, NETLINK_ROUTE);
link_cache = nltool_alloc_link_cache(nlh);
route = rtnl_route_alloc();
if (!route)
goto errout;
sock = nlt_alloc_socket();
nlt_connect(sock, NETLINK_ROUTE);
link_cache = nlt_alloc_link_cache(sock);
route = nlt_alloc_route();
for (;;) {
int c, optidx = 0;
@ -109,9 +100,9 @@ int main(int argc, char *argv[])
switch (c) {
case 'c': print_cache = 1; break;
case 'f': params.dp_type = nltool_parse_dumptype(optarg); break;
case 'f': params.dp_type = nlt_parse_dumptype(optarg); break;
case 'h': print_usage(); break;
case 'v': print_version(); break;
case 'v': nlt_print_version(); break;
case 'd': parse_dst(route, optarg); break;
case 'n': parse_nexthop(route, optarg, link_cache); break;
case 't': parse_table(route, optarg); break;
@ -127,19 +118,10 @@ int main(int argc, char *argv[])
}
}
route_cache = nltool_alloc_route_cache(nlh,
route_cache = nlt_alloc_route_cache(sock,
print_cache ? ROUTE_CACHE_CONTENT : 0);
nl_cache_dump_filter(route_cache, &params, OBJ_CAST(route));
err = 0;
rtnl_route_put(route);
nl_cache_free(route_cache);
errout:
nl_cache_free(link_cache);
nl_close(nlh);
nl_handle_destroy(nlh);
return err;
return 0;
}

View File

@ -1,78 +0,0 @@
/*
* src/nl-rule-dump.c Dump rule attributes
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
*/
#include "utils.h"
static void print_usage(void)
{
printf(
"Usage: nl-rule-dump <mode> [<filter>]\n"
" mode := { brief | detailed | stats | xml }\n");
exit(1);
}
int main(int argc, char *argv[])
{
struct nl_handle *nlh;
struct nl_cache *link_cache, *rule_cache;
struct rtnl_rule *rule;
struct nl_dump_params params = {
.dp_fd = stdout,
.dp_type = NL_DUMP_BRIEF
};
int err = 1;
if (nltool_init(argc, argv) < 0)
return -1;
if (argc < 2 || !strcmp(argv[1], "-h"))
print_usage();
nlh = nltool_alloc_handle();
if (!nlh)
return -1;
rule = rtnl_rule_alloc();
if (!rule)
goto errout;
if (nltool_connect(nlh, NETLINK_ROUTE) < 0)
goto errout_free;
link_cache = nltool_alloc_link_cache(nlh);
if (!link_cache)
goto errout_close;
rule_cache = nltool_alloc_rule_cache(nlh);
if (!rule_cache)
goto errout_link_cache;
params.dp_type = nltool_parse_dumptype(argv[1]);
if (params.dp_type < 0)
goto errout_rule_cache;
//get_filter(route, argc, argv, 2, route_cache);
nl_cache_dump_filter(rule_cache, &params, (struct nl_object *) rule);
err = 0;
errout_rule_cache:
nl_cache_free(rule_cache);
errout_link_cache:
nl_cache_free(link_cache);
errout_close:
nl_close(nlh);
errout_free:
nl_object_put((struct nl_object *) rule);
errout:
return err;
}

75
src/nl-rule-list.c Normal file
View File

@ -0,0 +1,75 @@
/*
* src/nl-rule-dump.c Dump rule attributes
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
#include "rule-utils.h"
static void print_usage(void)
{
printf(
"Usage: nl-rule-list [OPTION]... [ROUTE]\n"
"\n"
"Options\n"
" -c, --cache List the contents of the route cache\n"
" -f, --format=TYPE Output format { brief | details | stats }\n"
" -h, --help Show this help\n"
" -v, --version Show versioning information\n"
"\n"
"Rule Options\n"
" --family Address family\n"
);
exit(0);
}
int main(int argc, char *argv[])
{
struct nl_sock *sock;
struct rtnl_rule *rule;
struct nl_cache *link_cache, *rule_cache;
struct nl_dump_params params = {
.dp_fd = stdout,
.dp_type = NL_DUMP_BRIEF
};
sock = nlt_alloc_socket();
nlt_connect(sock, NETLINK_ROUTE);
link_cache = nlt_alloc_link_cache(sock);
rule_cache = nlt_alloc_rule_cache(sock);
rule = nlt_alloc_rule();
for (;;) {
int c, optidx = 0;
enum {
ARG_FAMILY = 257,
};
static struct option long_opts[] = {
{ "format", 1, 0, 'f' },
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'v' },
{ "family", 1, 0, ARG_FAMILY },
{ 0, 0, 0, 0 }
};
c = getopt_long(argc, argv, "f:hv", long_opts, &optidx);
if (c == -1)
break;
switch (c) {
case 'f': params.dp_type = nlt_parse_dumptype(optarg); break;
case 'h': print_usage(); break;
case 'v': nlt_print_version(); break;
case ARG_FAMILY: parse_family(rule, optarg); break;
}
}
nl_cache_dump_filter(rule_cache, &params, OBJ_CAST(rule));
return 0;
}

View File

@ -1,26 +1,39 @@
/*
* src/nl-tctree-dump.c Dump Traffic Control Tree
* src/nl-tctree-list.c List Traffic Control Tree
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
#include "utils.h"
#include <linux/pkt_sched.h>
static struct nl_handle *nl_handle;
static struct nl_sock *sock;
static struct nl_cache *qdisc_cache, *class_cache;
static struct nl_dump_params dump_params = {
.dp_type = NL_DUMP_FULL,
static struct nl_dump_params params = {
.dp_type = NL_DUMP_DETAILS,
};
static int ifindex;
static void print_qdisc(struct nl_object *, void *);
static void print_usage(void)
{
printf(
"Usage: nl-tctree-list [OPTION]...\n"
"\n"
"Options\n"
" -f, --format=TYPE Output format { brief | details | stats }\n"
" -h, --help Show this help\n"
" -v, --version Show versioning information\n"
);
exit(0);
}
static void print_class(struct nl_object *obj, void *arg)
{
struct rtnl_qdisc *leaf;
@ -28,8 +41,8 @@ static void print_class(struct nl_object *obj, void *arg)
struct nl_cache *cls_cache;
uint32_t parent = rtnl_class_get_handle(class);
dump_params.dp_prefix = (int)(long) arg;
nl_object_dump(obj, &dump_params);
params.dp_prefix = (int)(long) arg;
nl_object_dump(obj, &params);
leaf = rtnl_class_leaf_qdisc(class, qdisc_cache);
if (leaf)
@ -37,12 +50,11 @@ static void print_class(struct nl_object *obj, void *arg)
rtnl_class_foreach_child(class, class_cache, &print_class, arg + 2);
cls_cache = rtnl_cls_alloc_cache(nl_handle, ifindex, parent);
if (!cls_cache)
if (rtnl_cls_alloc_cache(sock, ifindex, parent, &cls_cache) < 0)
return;
dump_params.dp_prefix = (int)(long) arg + 2;
nl_cache_dump(cls_cache, &dump_params);
params.dp_prefix = (int)(long) arg + 2;
nl_cache_dump(cls_cache, &params);
nl_cache_free(cls_cache);
}
@ -52,17 +64,16 @@ static void print_qdisc(struct nl_object *obj, void *arg)
struct nl_cache *cls_cache;
uint32_t parent = rtnl_qdisc_get_handle(qdisc);
dump_params.dp_prefix = (int)(long) arg;
nl_object_dump(obj, &dump_params);
params.dp_prefix = (int)(long) arg;
nl_object_dump(obj, &params);
rtnl_qdisc_foreach_child(qdisc, class_cache, &print_class, arg + 2);
cls_cache = rtnl_cls_alloc_cache(nl_handle, ifindex, parent);
if (!cls_cache)
if (rtnl_cls_alloc_cache(sock, ifindex, parent, &cls_cache) < 0)
return;
dump_params.dp_prefix = (int)(long) arg + 2;
nl_cache_dump(cls_cache, &dump_params);
params.dp_prefix = (int)(long) arg + 2;
nl_cache_dump(cls_cache, &params);
nl_cache_free(cls_cache);
}
@ -72,11 +83,10 @@ static void print_link(struct nl_object *obj, void *arg)
struct rtnl_qdisc *qdisc;
ifindex = rtnl_link_get_ifindex(link);
dump_params.dp_prefix = 0;
nl_object_dump(obj, &dump_params);
params.dp_prefix = 0;
nl_object_dump(obj, &params);
class_cache = rtnl_class_alloc_cache(nl_handle, ifindex);
if (!class_cache)
if (rtnl_class_alloc_cache(sock, ifindex, &class_cache) < 0)
return;
qdisc = rtnl_qdisc_get_by_parent(qdisc_cache, ifindex, TC_H_ROOT);
@ -104,41 +114,34 @@ int main(int argc, char *argv[])
{
struct nl_cache *link_cache;
if (nltool_init(argc, argv) < 0)
return -1;
sock = nlt_alloc_socket();
nlt_connect(sock, NETLINK_ROUTE);
link_cache = nlt_alloc_link_cache(sock);
qdisc_cache = nlt_alloc_qdisc_cache(sock);
dump_params.dp_fd = stdout;
params.dp_fd = stdout;
if (argc > 1) {
if (!strcasecmp(argv[1], "brief"))
dump_params.dp_type = NL_DUMP_BRIEF;
else if (!strcasecmp(argv[1], "full"))
dump_params.dp_type = NL_DUMP_FULL;
else if (!strcasecmp(argv[1], "stats"))
dump_params.dp_type = NL_DUMP_STATS;
for (;;) {
int c, optidx = 0;
static struct option long_opts[] = {
{ "format", 1, 0, 'f' },
{ "help", 0, 0, 'h' },
{ "version", 0, 0, 'v' },
{ 0, 0, 0, 0 }
};
c = getopt_long(argc, argv, "f:hv", long_opts, &optidx);
if (c == -1)
break;
switch (c) {
case 'f': params.dp_type = nlt_parse_dumptype(optarg); break;
case 'h': print_usage(); break;
case 'v': nlt_print_version(); break;
}
}
nl_handle = nltool_alloc_handle();
if (!nl_handle)
return 1;
if (nltool_connect(nl_handle, NETLINK_ROUTE) < 0)
return 1;
link_cache = nltool_alloc_link_cache(nl_handle);
if (!link_cache)
return 1;
qdisc_cache = nltool_alloc_qdisc_cache(nl_handle);
if (!qdisc_cache)
return 1;
nl_cache_foreach(link_cache, &print_link, NULL);
nl_cache_free(qdisc_cache);
nl_cache_free(link_cache);
nl_close(nl_handle);
nl_handle_destroy(nl_handle);
return 0;
}

View File

@ -6,7 +6,7 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
* Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch>
*/
#include "utils.h"
@ -21,19 +21,12 @@ int main(int argc, char *argv[])
fprintf(stderr, "Usage: nl-util-addr <address>\n");
return -1;
}
a = nl_addr_parse(argv[1], AF_UNSPEC);
if (a == NULL) {
fprintf(stderr, "Cannot parse address \"%s\"\n", argv[1]);
return -1;
}
a = nlt_addr_parse(argv[1], AF_UNSPEC);
err = nl_addr_resolve(a, host, sizeof(host));
if (err != 0) {
fprintf(stderr, "Cannot resolve address \"%s\": %d\n",
argv[1], err);
return -1;
}
if (err != 0)
fatal(err, "Unable to resolve address \"%s\": %s",
argv[1], nl_geterror(err));
printf("%s\n", host);

62
src/qdisc-utils.c Normal file
View File

@ -0,0 +1,62 @@
/*
* src/qdisc-utils.c QDisc Helpers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
*/
#include "qdisc-utils.h"
struct rtnl_qdisc *nlt_alloc_qdisc(void)
{
struct rtnl_qdisc *qdisc;
qdisc = rtnl_qdisc_alloc();
if (!qdisc)
fatal(ENOMEM, "Unable to allocate qdisc object");
return qdisc;
}
void parse_dev(struct rtnl_qdisc *qdisc, struct nl_cache *link_cache, char *arg)
{
int ival;
if (!(ival = rtnl_link_name2i(link_cache, arg)))
fatal(ENOENT, "Link \"%s\" does not exist", arg);
rtnl_qdisc_set_ifindex(qdisc, ival);
}
void parse_parent(struct rtnl_qdisc *qdisc, char *arg)
{
uint32_t parent;
int err;
if ((err = rtnl_tc_str2handle(arg, &parent)) < 0)
fatal(err, "Unable to parse handle \"%s\": %s",
arg, nl_geterror(err));
rtnl_qdisc_set_parent(qdisc, parent);
}
void parse_handle(struct rtnl_qdisc *qdisc, char *arg)
{
uint32_t handle;
int err;
if ((err = rtnl_tc_str2handle(arg, &handle)) < 0)
fatal(err, "Unable to parse handle \"%s\": %s",
arg, nl_geterror(err));
rtnl_qdisc_set_handle(qdisc, handle);
}
void parse_kind(struct rtnl_qdisc *qdisc, char *arg)
{
rtnl_qdisc_set_kind(qdisc, arg);
}

23
src/qdisc-utils.h Normal file
View File

@ -0,0 +1,23 @@
/*
* src/qdisc-utils.h QDisc Helpers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
*/
#ifndef __QDISC_UTILS_H_
#define __QDISC_UTILS_H_
#include "utils.h"
extern struct rtnl_qdisc *nlt_alloc_qdisc(void);
extern void parse_dev(struct rtnl_qdisc *, struct nl_cache *, char *);
extern void parse_parent(struct rtnl_qdisc *, char *);
extern void parse_handle(struct rtnl_qdisc *, char *);
extern void parse_kind(struct rtnl_qdisc *, char *);
#endif

24
src/queue-utils.c Normal file
View File

@ -0,0 +1,24 @@
/*
* src/queue-utils.c Queue Helpers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
*/
#include "queue-utils.h"
struct nfnl_queue *nlt_alloc_queue(void)
{
struct nfnl_queue *queue;
queue = nfnl_queue_alloc();
if (!queue)
fatal(ENOMEM, "Unable to allocate queue object");
return queue;
}

24
src/queue-utils.h Normal file
View File

@ -0,0 +1,24 @@
/*
* src/queue-utils.h Queue Helper
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
*/
#ifndef __QUEUE_UTILS_H_
#define __QUEUE_UTILS_H_
#include "utils.h"
#include <linux/netfilter.h>
#include <linux/netfilter/nfnetlink_queue.h>
#include <netlink/netfilter/nfnl.h>
#include <netlink/netfilter/queue.h>
#include <netlink/netfilter/queue_msg.h>
extern struct nfnl_queue *nlt_alloc_queue(void);
#endif

View File

@ -11,6 +11,17 @@
#include "route-utils.h"
struct rtnl_route *nlt_alloc_route(void)
{
struct rtnl_route *route;
route = rtnl_route_alloc();
if (!route)
fatal(ENOMEM, "Unable to allocate route object");
return route;
}
void parse_family(struct rtnl_route *route, char *arg)
{
int family;
@ -24,12 +35,10 @@ void parse_dst(struct rtnl_route *route, char *arg)
struct nl_addr *addr;
int err;
addr = nl_addr_parse(arg, rtnl_route_get_family(route));
if (addr == NULL)
fatal(nl_get_errno(), nl_geterror());
addr = nlt_addr_parse(arg, rtnl_route_get_family(route));
if ((err = rtnl_route_set_dst(route, addr)) < 0)
fatal(err, nl_geterror());
fatal(err, "Unable to set destination address: %s",
nl_geterror(err));
nl_addr_put(addr);
}
@ -39,12 +48,10 @@ void parse_src(struct rtnl_route *route, char *arg)
struct nl_addr *addr;
int err;
addr = nl_addr_parse(arg, rtnl_route_get_family(route));
if (addr == NULL)
fatal(nl_get_errno(), nl_geterror());
addr = nlt_addr_parse(arg, rtnl_route_get_family(route));
if ((err = rtnl_route_set_src(route, addr)) < 0)
fatal(err, nl_geterror());
fatal(err, "Unable to set source address: %s",
nl_geterror(err));
nl_addr_put(addr);
}
@ -54,12 +61,10 @@ void parse_pref_src(struct rtnl_route *route, char *arg)
struct nl_addr *addr;
int err;
addr = nl_addr_parse(arg, rtnl_route_get_family(route));
if (addr == NULL)
fatal(nl_get_errno(), nl_geterror());
addr = nlt_addr_parse(arg, rtnl_route_get_family(route));
if ((err = rtnl_route_set_pref_src(route, addr)) < 0)
fatal(err, nl_geterror());
fatal(err, "Unable to set preferred source address: %s",
nl_geterror(err));
nl_addr_put(addr);
}
@ -102,7 +107,8 @@ void parse_metric(struct rtnl_route *route, char *subopts)
fatal(EINVAL, "Metric \"%s\", value not numeric", tokens[ret]);
if ((ret = rtnl_route_set_metric(route, ret, lval)) < 0)
fatal(ret, nl_geterror());
fatal(ret, "Unable to set metric: %s",
nl_geterror(ret));
}
}
@ -140,18 +146,14 @@ void parse_nexthop(struct rtnl_route *route, char *subopts,
switch (ret) {
case NH_DEV:
ival = rtnl_link_name2i(link_cache, arg);
if (ival == RTNL_LINK_NOT_FOUND)
fatal(ENOENT, "Link \"%s\" does not exist", arg);
if (!(ival = rtnl_link_name2i(link_cache, arg)))
fatal(ENOENT,"Link \"%s\" does not exist", arg);
rtnl_route_nh_set_ifindex(nh, ival);
break;
case NH_VIA:
addr = nl_addr_parse(arg, rtnl_route_get_family(route));
if (addr == NULL)
fatal(nl_get_errno(), nl_geterror());
addr = nlt_addr_parse(arg,rtnl_route_get_family(route));
rtnl_route_nh_set_gateway(nh, addr);
nl_addr_put(addr);
break;
@ -226,15 +228,15 @@ void parse_type(struct rtnl_route *route, char *arg)
fatal(EINVAL, "Unknown routing type \"%s\"", arg);
if ((ival = rtnl_route_set_type(route, ival)) < 0)
fatal(ival, nl_geterror());
fatal(ival, "Unable to set routing type: %s",
nl_geterror(ival));
}
void parse_iif(struct rtnl_route *route, char *arg, struct nl_cache *link_cache)
{
int ival;
ival = rtnl_link_name2i(link_cache, arg);
if (ival == RTNL_LINK_NOT_FOUND)
if (!(ival = rtnl_link_name2i(link_cache, arg)))
fatal(ENOENT, "Link \"%s\" does not exist", arg);
rtnl_route_set_iif(route, ival);

View File

@ -14,6 +14,7 @@
#include "utils.h"
extern struct rtnl_route *nlt_alloc_route(void);
extern void parse_family(struct rtnl_route *, char *);
extern void parse_dst(struct rtnl_route *, char *);
extern void parse_src(struct rtnl_route *, char *);

66
src/rtnl-utils.c Normal file
View File

@ -0,0 +1,66 @@
/*
* src/rtnl-utils.c rtnetlink helpers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
*/
#include "rtnl-utils.h"
struct nl_cache *nlt_alloc_link_cache(struct nl_sock *sk)
{
return alloc_cache(sk, "link", rtnl_link_alloc_cache);
}
struct nl_cache *nlt_alloc_addr_cache(struct nl_sock *sk)
{
return alloc_cache(sk, "address", rtnl_addr_alloc_cache);
}
struct nl_cache *nlt_alloc_neigh_cache(struct nl_sock *sk)
{
return alloc_cache(sk, "neighbour", rtnl_neigh_alloc_cache);
}
struct nl_cache *nlt_alloc_neightbl_cache(struct nl_sock *sk)
{
return alloc_cache(sk, "neighbour table", rtnl_neightbl_alloc_cache);
}
struct nl_cache *nlt_alloc_route_cache(struct nl_sock *sk, int flags)
{
struct nl_cache *cache;
int err;
if ((err = rtnl_route_alloc_cache(sk, AF_UNSPEC, flags, &cache)) < 0)
fatal(err, "Unable to allocate route cache: %s\n",
nl_geterror(err));
nl_cache_mngt_provide(cache);
return cache;
}
struct nl_cache *nlt_alloc_rule_cache(struct nl_sock *sk)
{
struct nl_cache *cache;
int err;
if ((err = rtnl_rule_alloc_cache(sk, AF_UNSPEC, &cache)) < 0)
fatal(err, "Unable to allocate routing rule cache: %s\n",
nl_geterror(err));
nl_cache_mngt_provide(cache);
return cache;
}
struct nl_cache *nlt_alloc_qdisc_cache(struct nl_sock *sk)
{
return alloc_cache(sk, "queueing disciplines", rtnl_qdisc_alloc_cache);
}

25
src/rtnl-utils.h Normal file
View File

@ -0,0 +1,25 @@
/*
* src/rtnl-utils.h rtnetlink helpers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
*/
#ifndef __SRC_RTNL_UTILS_H_
#define __SRC_RTNL_UTILS_H_
#include "utils.h"
extern struct nl_cache *nlt_alloc_link_cache(struct nl_sock *);
extern struct nl_cache *nlt_alloc_addr_cache(struct nl_sock *);
extern struct nl_cache *nlt_alloc_neigh_cache(struct nl_sock *);
extern struct nl_cache *nlt_alloc_neightbl_cache(struct nl_sock *);
extern struct nl_cache *nlt_alloc_qdisc_cache(struct nl_sock *);
extern struct nl_cache *nlt_alloc_route_cache(struct nl_sock *, int);
extern struct nl_cache *nlt_alloc_rule_cache(struct nl_sock *);
#endif

31
src/rule-utils.c Normal file
View File

@ -0,0 +1,31 @@
/*
* src/rule-utils.c Routing Rule Helpers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
*/
#include "rule-utils.h"
struct rtnl_rule *nlt_alloc_rule(void)
{
struct rtnl_rule *rule;
rule = rtnl_rule_alloc();
if (!rule)
fatal(ENOMEM, "Unable to allocate rule object");
return rule;
}
void parse_family(struct rtnl_rule *rule, char *arg)
{
int family;
if ((family = nl_str2af(arg)) != AF_UNSPEC)
rtnl_rule_set_family(rule, family);
}

20
src/rule-utils.h Normal file
View File

@ -0,0 +1,20 @@
/*
* src/rule-utils.h Routing Rule Helpers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation version 2.1
* of the License.
*
* Copyright (c) 2008 Thomas Graf <tgraf@suug.ch>
*/
#ifndef __RULE_UTILS_H_
#define __RULE_UTILS_H_
#include "utils.h"
extern struct rtnl_rule *nlt_alloc_rule(void);
extern void parse_family(struct rtnl_rule *, char *);
#endif

View File

@ -13,6 +13,18 @@
#include <stdlib.h>
uint32_t parse_u32(const char *arg)
{
unsigned long lval;
char *endptr;
lval = strtoul(arg, &endptr, 0);
if (endptr == arg || lval == ULONG_MAX)
fatal(EINVAL, "Unable to parse \"%s\", not a number.", arg);
return (uint32_t) lval;
}
void nlt_print_version(void)
{
printf("libnl tools version %s\n", LIBNL_VERSION);
@ -112,8 +124,8 @@ int nlt_confirm(struct nl_object *obj, struct nl_dump_params *params,
return answer == 'y';
}
static struct nl_cache *alloc_cache(struct nl_sock *sock, const char *name,
int (*ac)(struct nl_sock *, struct nl_cache **))
struct nl_cache *alloc_cache(struct nl_sock *sock, const char *name,
int (*ac)(struct nl_sock *, struct nl_cache **))
{
struct nl_cache *cache;
int err;
@ -127,67 +139,3 @@ static struct nl_cache *alloc_cache(struct nl_sock *sock, const char *name,
return cache;
}
struct nl_cache *nlt_alloc_link_cache(struct nl_sock *sk)
{
return alloc_cache(sk, "link", rtnl_link_alloc_cache);
}
struct nl_cache *nlt_alloc_addr_cache(struct nl_sock *sk)
{
return alloc_cache(sk, "address", rtnl_addr_alloc_cache);
}
struct rtnl_addr *nlt_alloc_addr(void)
{
struct rtnl_addr *addr;
addr = rtnl_addr_alloc();
if (!addr)
fatal(ENOMEM, "Unable to allocate address object");
return addr;
}
struct nl_cache *nltool_alloc_neigh_cache(struct nl_sock *sk)
{
return alloc_cache(sk, "neighbour", rtnl_neigh_alloc_cache);
}
struct nl_cache *nltool_alloc_neightbl_cache(struct nl_sock *sk)
{
return alloc_cache(sk, "neighbour table", rtnl_neightbl_alloc_cache);
}
struct nl_cache *nltool_alloc_route_cache(struct nl_sock *sk, int flags)
{
struct nl_cache *cache;
int err;
if ((err = rtnl_route_alloc_cache(sk, AF_UNSPEC, flags, &cache)) < 0)
fatal(err, "Unable to allocate route cache: %s\n",
nl_geterror(err));
nl_cache_mngt_provide(cache);
return cache;
}
struct nl_cache *nltool_alloc_rule_cache(struct nl_sock *sk)
{
struct nl_cache *cache;
int err;
if ((err = rtnl_rule_alloc_cache(sk, AF_UNSPEC, &cache)) < 0)
fatal(err, "Unable to allocate routing rule cache: %s\n",
nl_geterror(err));
nl_cache_mngt_provide(cache);
return cache;
}
struct nl_cache *nltool_alloc_qdisc_cache(struct nl_sock *sk)
{
return alloc_cache(sk, "queueing disciplines", rtnl_qdisc_alloc_cache);
}

View File

@ -44,6 +44,8 @@
#include <netlink/genl/mngt.h>
#include <netlink/netfilter/ct.h>
extern uint32_t parse_u32(const char *);
extern void nlt_print_version(void);
extern void fatal(int err, const char *fmt, ...);
extern struct nl_addr * nlt_addr_parse(const char *, int);
@ -55,15 +57,13 @@ extern int nlt_parse_dumptype(const char *str);
extern int nlt_confirm(struct nl_object *, struct nl_dump_params *, int);
extern struct nl_cache *nlt_alloc_link_cache(struct nl_sock *);
extern struct nl_cache *nlt_alloc_addr_cache(struct nl_sock *);
extern struct rtnl_addr *nlt_alloc_addr(void);
extern struct nl_cache *nltool_alloc_neigh_cache(struct nl_sock *nlh);
extern struct nl_cache *nltool_alloc_neightbl_cache(struct nl_sock *nlh);
extern struct nl_cache *nltool_alloc_route_cache(struct nl_sock *nlh, int);
extern struct nl_cache *nltool_alloc_rule_cache(struct nl_sock *nlh);
extern struct nl_cache *nltool_alloc_qdisc_cache(struct nl_sock *nlh);
extern struct nl_cache *nltool_alloc_genl_family_cache(struct nl_sock *nlh);
extern struct nl_cache *nlt_alloc_neigh_cache(struct nl_sock *);
extern struct nl_cache *nlt_alloc_neightbl_cache(struct nl_sock *);
extern struct nl_cache *nlt_alloc_qdisc_cache(struct nl_sock *);
extern struct nl_cache *nlt_alloc_route_cache(struct nl_sock *, int);
extern struct nl_cache *nlt_alloc_rule_cache(struct nl_sock *);
extern struct nl_cache *alloc_cache(struct nl_sock *, const char *,
int (*ac)(struct nl_sock *, struct nl_cache **));
#endif