]>
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>
18 #include <sys/socket.h>
19 #include <netinet/in.h>
20 #include <netinet/ip.h>
21 #include <arpa/inet.h>
22 #include <linux/types.h>
27 #include "ip_common.h"
28 #include "json_print.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 open_json_object(NULL
);
82 print_string(PRINT_FP
, NULL
, "token ", NULL
);
83 print_color_string(PRINT_ANY
,
84 ifa_family_color(ifi
->ifi_family
),
86 format_host_rta(ifi
->ifi_family
, ltb
[IFLA_INET6_TOKEN
]));
87 print_string(PRINT_FP
, NULL
, " dev ", NULL
);
88 print_color_string(PRINT_ANY
, COLOR_IFNAME
,
90 ll_index_to_name(ifi
->ifi_index
));
97 static int iptoken_list(int argc
, char **argv
)
100 struct rtnl_dump_args da
= { .fp
= stdout
};
103 if (strcmp(*argv
, "dev") == 0) {
105 if ((da
.ifindex
= ll_name_to_index(*argv
)) == 0)
106 invarg("dev is invalid\n", *argv
);
112 if (rtnl_wilddump_request(&rth
, af
, RTM_GETLINK
) < 0) {
113 perror("Cannot send dump request");
118 if (rtnl_dump_filter(&rth
, print_token
, &da
) < 0) {
120 fprintf(stderr
, "Dump terminated\n");
128 static int iptoken_set(int argc
, char **argv
, bool delete)
132 struct ifinfomsg ifi
;
135 .n
.nlmsg_len
= NLMSG_LENGTH(sizeof(struct ifinfomsg
)),
136 .n
.nlmsg_flags
= NLM_F_REQUEST
,
137 .n
.nlmsg_type
= RTM_SETLINK
,
138 .ifi
.ifi_family
= AF_INET6
,
140 struct rtattr
*afs
, *afs6
;
141 bool have_token
= delete, have_dev
= false;
142 inet_prefix addr
= { .bytelen
= 16, };
145 if (strcmp(*argv
, "dev") == 0) {
148 if ((req
.ifi
.ifi_index
=
149 ll_name_to_index(*argv
)) == 0)
150 invarg("dev is invalid\n", *argv
);
154 if (matches(*argv
, "help") == 0)
157 get_prefix(&addr
, *argv
, req
.ifi
.ifi_family
);
165 fprintf(stderr
, "Not enough information: token is required.\n");
169 fprintf(stderr
, "Not enough information: \"dev\" argument is required.\n");
173 afs
= addattr_nest(&req
.n
, sizeof(req
), IFLA_AF_SPEC
);
174 afs6
= addattr_nest(&req
.n
, sizeof(req
), AF_INET6
);
175 addattr_l(&req
.n
, sizeof(req
), IFLA_INET6_TOKEN
,
176 &addr
.data
, addr
.bytelen
);
177 addattr_nest_end(&req
.n
, afs6
);
178 addattr_nest_end(&req
.n
, afs
);
180 if (rtnl_talk(&rth
, &req
.n
, NULL
) < 0)
186 int do_iptoken(int argc
, char **argv
)
191 return iptoken_list(0, NULL
);
192 } else if (matches(argv
[0], "list") == 0 ||
193 matches(argv
[0], "lst") == 0 ||
194 matches(argv
[0], "show") == 0) {
195 return iptoken_list(argc
- 1, argv
+ 1);
196 } else if (matches(argv
[0], "set") == 0 ||
197 matches(argv
[0], "add") == 0) {
198 return iptoken_set(argc
- 1, argv
+ 1, false);
199 } else if (matches(argv
[0], "delete") == 0) {
200 return iptoken_set(argc
- 1, argv
+ 1, true);
201 } else if (matches(argv
[0], "get") == 0) {
202 return iptoken_list(argc
- 1, argv
+ 1);
203 } else if (matches(argv
[0], "help") == 0)
206 fprintf(stderr
, "Command \"%s\" is unknown, try \"ip token help\".\n", *argv
);