mirror_iproute2/ip/iptoken.c
Phil Sutter d17b136f7d Use C99 style initializers everywhere
This big patch was compiled by vimgrepping for memset calls and changing
to C99 initializer if applicable. One notable exception is the
initialization of union bpf_attr in tc/tc_bpf.c: changing it would break
for older gcc versions (at least <=3.4.6).

Calls to memset for struct rtattr pointer fields for parse_rtattr*()
were just dropped since they are not needed.

The changes here allowed the compiler to discover some unused variables,
so get rid of them, too.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: David Ahern <dsa@cumulusnetworks.com>
2016-07-20 12:05:24 -07:00

198 lines
4.6 KiB
C

/*
* iptoken.c "ip token"
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*
* Authors: Daniel Borkmann, <borkmann@redhat.com>
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <syslog.h>
#include <fcntl.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <linux/types.h>
#include <linux/if.h>
#include "rt_names.h"
#include "utils.h"
#include "ip_common.h"
extern struct rtnl_handle rth;
struct rtnl_dump_args {
FILE *fp;
int ifindex;
};
static void usage(void) __attribute__((noreturn));
static void usage(void)
{
fprintf(stderr, "Usage: ip token [ list | set | del | get ] [ TOKEN ] [ dev DEV ]\n");
exit(-1);
}
static int print_token(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
{
struct rtnl_dump_args *args = arg;
FILE *fp = args->fp;
int ifindex = args->ifindex;
struct ifinfomsg *ifi = NLMSG_DATA(n);
int len = n->nlmsg_len;
struct rtattr *tb[IFLA_MAX + 1];
struct rtattr *ltb[IFLA_INET6_MAX + 1];
if (n->nlmsg_type != RTM_NEWLINK)
return -1;
len -= NLMSG_LENGTH(sizeof(*ifi));
if (len < 0)
return -1;
if (ifi->ifi_family != AF_INET6)
return -1;
if (ifi->ifi_index == 0)
return -1;
if (ifindex > 0 && ifi->ifi_index != ifindex)
return 0;
if (ifi->ifi_flags & (IFF_LOOPBACK | IFF_NOARP))
return 0;
parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
if (!tb[IFLA_PROTINFO])
return -1;
parse_rtattr_nested(ltb, IFLA_INET6_MAX, tb[IFLA_PROTINFO]);
if (!ltb[IFLA_INET6_TOKEN]) {
fprintf(stderr, "Seems there's no support for IPv6 token!\n");
return -1;
}
fprintf(fp, "token %s dev %s\n",
format_host_rta(ifi->ifi_family, ltb[IFLA_INET6_TOKEN]),
ll_index_to_name(ifi->ifi_index));
fflush(fp);
return 0;
}
static int iptoken_list(int argc, char **argv)
{
int af = AF_INET6;
struct rtnl_dump_args da = { .fp = stdout };
while (argc > 0) {
if (strcmp(*argv, "dev") == 0) {
NEXT_ARG();
if ((da.ifindex = ll_name_to_index(*argv)) == 0)
invarg("dev is invalid\n", *argv);
break;
}
argc--; argv++;
}
if (rtnl_wilddump_request(&rth, af, RTM_GETLINK) < 0) {
perror("Cannot send dump request");
return -1;
}
if (rtnl_dump_filter(&rth, print_token, &da) < 0) {
fprintf(stderr, "Dump terminated\n");
return -1;
}
return 0;
}
static int iptoken_set(int argc, char **argv, bool delete)
{
struct {
struct nlmsghdr n;
struct ifinfomsg ifi;
char buf[512];
} req = {
.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
.n.nlmsg_flags = NLM_F_REQUEST,
.n.nlmsg_type = RTM_SETLINK,
.ifi.ifi_family = AF_INET6,
};
struct rtattr *afs, *afs6;
bool have_token = delete, have_dev = false;
inet_prefix addr = { .bytelen = 16, };
while (argc > 0) {
if (strcmp(*argv, "dev") == 0) {
NEXT_ARG();
if (!have_dev) {
if ((req.ifi.ifi_index =
ll_name_to_index(*argv)) == 0)
invarg("dev is invalid\n", *argv);
have_dev = true;
}
} else {
if (matches(*argv, "help") == 0)
usage();
if (!have_token) {
get_prefix(&addr, *argv, req.ifi.ifi_family);
have_token = true;
}
}
argc--; argv++;
}
if (!have_token) {
fprintf(stderr, "Not enough information: token is required.\n");
return -1;
}
if (!have_dev) {
fprintf(stderr, "Not enough information: \"dev\" argument is required.\n");
return -1;
}
afs = addattr_nest(&req.n, sizeof(req), IFLA_AF_SPEC);
afs6 = addattr_nest(&req.n, sizeof(req), AF_INET6);
addattr_l(&req.n, sizeof(req), IFLA_INET6_TOKEN,
&addr.data, addr.bytelen);
addattr_nest_end(&req.n, afs6);
addattr_nest_end(&req.n, afs);
if (rtnl_talk(&rth, &req.n, NULL, 0) < 0)
return -2;
return 0;
}
int do_iptoken(int argc, char **argv)
{
ll_init_map(&rth);
if (argc < 1) {
return iptoken_list(0, NULL);
} else if (matches(argv[0], "list") == 0 ||
matches(argv[0], "lst") == 0 ||
matches(argv[0], "show") == 0) {
return iptoken_list(argc - 1, argv + 1);
} else if (matches(argv[0], "set") == 0 ||
matches(argv[0], "add") == 0) {
return iptoken_set(argc - 1, argv + 1, false);
} else if (matches(argv[0], "delete") == 0) {
return iptoken_set(argc - 1, argv + 1, true);
} else if (matches(argv[0], "get") == 0) {
return iptoken_list(argc - 1, argv + 1);
} else if (matches(argv[0], "help") == 0)
usage();
fprintf(stderr, "Command \"%s\" is unknown, try \"ip token help\".\n", *argv);
exit(-1);
}