]>
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 | 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];
56 if (n
->nlmsg_type
!= RTM_NEWLINK
)
59 len
-= NLMSG_LENGTH(sizeof(*ifi
));
63 if (ifi
->ifi_family
!= AF_INET6
)
65 if (ifi
->ifi_index
== 0)
67 if (ifindex
> 0 && ifi
->ifi_index
!= ifindex
)
69 if (ifi
->ifi_flags
& (IFF_LOOPBACK
| IFF_NOARP
))
72 parse_rtattr(tb
, IFLA_MAX
, IFLA_RTA(ifi
), len
);
73 if (!tb
[IFLA_PROTINFO
])
76 parse_rtattr_nested(ltb
, IFLA_INET6_MAX
, tb
[IFLA_PROTINFO
]);
77 if (!ltb
[IFLA_INET6_TOKEN
]) {
78 fprintf(stderr
, "Seems there's no support for IPv6 token!\n");
82 fprintf(fp
, "token %s ",
83 format_host(ifi
->ifi_family
,
84 RTA_PAYLOAD(ltb
[IFLA_INET6_TOKEN
]),
85 RTA_DATA(ltb
[IFLA_INET6_TOKEN
]),
87 fprintf(fp
, "dev %s ", ll_index_to_name(ifi
->ifi_index
));
94 static int iptoken_list(int argc
, char **argv
)
97 struct rtnl_dump_args da
;
98 const struct rtnl_dump_filter_arg a
[2] = {
99 { .filter
= print_token
, .arg1
= &da
, },
100 { .filter
= NULL
, .arg1
= NULL
, },
103 memset(&da
, 0, sizeof(da
));
107 if (strcmp(*argv
, "dev") == 0) {
109 if ((da
.ifindex
= ll_name_to_index(*argv
)) == 0)
110 invarg("dev is invalid\n", *argv
);
116 if (rtnl_wilddump_request(&rth
, af
, RTM_GETLINK
) < 0) {
117 perror("Cannot send dump request");
121 if (rtnl_dump_filter_l(&rth
, a
) < 0) {
122 fprintf(stderr
, "Dump terminated\n");
129 static int iptoken_set(int argc
, char **argv
)
133 struct ifinfomsg ifi
;
136 struct rtattr
*afs
, *afs6
;
137 bool have_token
= false, have_dev
= false;
140 memset(&addr
, 0, sizeof(addr
));
141 memset(&req
, 0, sizeof(req
));
143 req
.n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifinfomsg
));
144 req
.n
.nlmsg_flags
= NLM_F_REQUEST
;
145 req
.n
.nlmsg_type
= RTM_SETLINK
;
146 req
.ifi
.ifi_family
= AF_INET6
;
149 if (strcmp(*argv
, "dev") == 0) {
152 if ((req
.ifi
.ifi_index
=
153 ll_name_to_index(*argv
)) == 0)
154 invarg("dev is invalid\n", *argv
);
158 if (matches(*argv
, "help") == 0)
161 afs
= addattr_nest(&req
.n
, sizeof(req
), IFLA_AF_SPEC
);
162 afs6
= addattr_nest(&req
.n
, sizeof(req
), AF_INET6
);
163 get_prefix(&addr
, *argv
, req
.ifi
.ifi_family
);
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
);
175 fprintf(stderr
, "Not enough information: token "
180 fprintf(stderr
, "Not enough information: \"dev\" "
181 "argument is required.\n");
185 if (rtnl_talk(&rth
, &req
.n
, NULL
, 0) < 0)
191 int do_iptoken(int argc
, char **argv
)
196 return iptoken_list(0, NULL
);
197 } else if (matches(argv
[0], "list") == 0 ||
198 matches(argv
[0], "lst") == 0 ||
199 matches(argv
[0], "show") == 0) {
200 return iptoken_list(argc
- 1, argv
+ 1);
201 } else if (matches(argv
[0], "set") == 0 ||
202 matches(argv
[0], "add") == 0) {
203 return iptoken_set(argc
- 1, argv
+ 1);
204 } else if (matches(argv
[0], "get") == 0) {
205 return iptoken_list(argc
- 1, argv
+ 1);
206 } else if (matches(argv
[0], "help") == 0)
209 fprintf(stderr
, "Command \"%s\" is unknown, try \"ip token help\".\n", *argv
);