]>
git.proxmox.com Git - mirror_iproute2.git/blob - ip/iptoken.c
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
9 * Authors: Daniel Borkmann, <borkmann@redhat.com>
19 #include <sys/socket.h>
20 #include <netinet/in.h>
21 #include <netinet/ip.h>
22 #include <arpa/inet.h>
23 #include <linux/types.h>
28 #include "ip_common.h"
30 extern struct rtnl_handle rth
;
32 struct rtnl_dump_args
{
37 static void usage(void) __attribute__((noreturn
));
39 static void usage(void)
41 fprintf(stderr
, "Usage: ip token [ list | set | del | get ] [ TOKEN ] [ dev DEV ]\n");
45 static int print_token(const struct sockaddr_nl
*who
, struct nlmsghdr
*n
, void *arg
)
47 struct rtnl_dump_args
*args
= arg
;
49 int ifindex
= args
->ifindex
;
50 struct ifinfomsg
*ifi
= NLMSG_DATA(n
);
51 int len
= n
->nlmsg_len
;
52 struct rtattr
*tb
[IFLA_MAX
+ 1];
53 struct rtattr
*ltb
[IFLA_INET6_MAX
+ 1];
55 if (n
->nlmsg_type
!= RTM_NEWLINK
)
58 len
-= NLMSG_LENGTH(sizeof(*ifi
));
62 if (ifi
->ifi_family
!= AF_INET6
)
64 if (ifi
->ifi_index
== 0)
66 if (ifindex
> 0 && ifi
->ifi_index
!= ifindex
)
68 if (ifi
->ifi_flags
& (IFF_LOOPBACK
| IFF_NOARP
))
71 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
);
72 if (!tb
[IFLA_PROTINFO
])
75 parse_rtattr_nested(ltb
, IFLA_INET6_MAX
, tb
[IFLA_PROTINFO
]);
76 if (!ltb
[IFLA_INET6_TOKEN
]) {
77 fprintf(stderr
, "Seems there's no support for IPv6 token!\n");
81 fprintf(fp
, "token %s dev %s\n",
82 format_host_rta(ifi
->ifi_family
, ltb
[IFLA_INET6_TOKEN
]),
83 ll_index_to_name(ifi
->ifi_index
));
89 static int iptoken_list(int argc
, char **argv
)
92 struct rtnl_dump_args da
= { .fp
= stdout
};
95 if (strcmp(*argv
, "dev") == 0) {
97 if ((da
.ifindex
= ll_name_to_index(*argv
)) == 0)
98 invarg("dev is invalid\n", *argv
);
104 if (rtnl_wilddump_request(&rth
, af
, RTM_GETLINK
) < 0) {
105 perror("Cannot send dump request");
109 if (rtnl_dump_filter(&rth
, print_token
, &da
) < 0) {
110 fprintf(stderr
, "Dump terminated\n");
117 static int iptoken_set(int argc
, char **argv
, bool delete)
121 struct ifinfomsg ifi
;
124 .n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifinfomsg
)),
125 .n
.nlmsg_flags
= NLM_F_REQUEST
,
126 .n
.nlmsg_type
= RTM_SETLINK
,
127 .ifi
.ifi_family
= AF_INET6
,
129 struct rtattr
*afs
, *afs6
;
130 bool have_token
= delete, have_dev
= false;
131 inet_prefix addr
= { .bytelen
= 16, };
134 if (strcmp(*argv
, "dev") == 0) {
137 if ((req
.ifi
.ifi_index
=
138 ll_name_to_index(*argv
)) == 0)
139 invarg("dev is invalid\n", *argv
);
143 if (matches(*argv
, "help") == 0)
146 get_prefix(&addr
, *argv
, req
.ifi
.ifi_family
);
154 fprintf(stderr
, "Not enough information: token is required.\n");
158 fprintf(stderr
, "Not enough information: \"dev\" argument is required.\n");
162 afs
= addattr_nest(&req
.n
, sizeof(req
), IFLA_AF_SPEC
);
163 afs6
= addattr_nest(&req
.n
, sizeof(req
), AF_INET6
);
164 addattr_l(&req
.n
, sizeof(req
), IFLA_INET6_TOKEN
,
165 &addr
.data
, addr
.bytelen
);
166 addattr_nest_end(&req
.n
, afs6
);
167 addattr_nest_end(&req
.n
, afs
);
169 if (rtnl_talk(&rth
, &req
.n
, NULL
) < 0)
175 int do_iptoken(int argc
, char **argv
)
180 return iptoken_list(0, NULL
);
181 } else if (matches(argv
[0], "list") == 0 ||
182 matches(argv
[0], "lst") == 0 ||
183 matches(argv
[0], "show") == 0) {
184 return iptoken_list(argc
- 1, argv
+ 1);
185 } else if (matches(argv
[0], "set") == 0 ||
186 matches(argv
[0], "add") == 0) {
187 return iptoken_set(argc
- 1, argv
+ 1, false);
188 } else if (matches(argv
[0], "delete") == 0) {
189 return iptoken_set(argc
- 1, argv
+ 1, true);
190 } else if (matches(argv
[0], "get") == 0) {
191 return iptoken_list(argc
- 1, argv
+ 1);
192 } else if (matches(argv
[0], "help") == 0)
195 fprintf(stderr
, "Command \"%s\" is unknown, try \"ip token help\".\n", *argv
);