3 1998-07-01 - Arnaldo Carvalho de Melo - GNU gettext instead of catgets
10 #include <sys/param.h>
11 #include <sys/types.h>
12 #include <sys/socket.h>
13 #include <netinet/in.h>
14 #include <arpa/inet.h>
15 #include <arpa/nameser.h>
17 #include <sys/ioctl.h>
27 #include <net/route.h>
29 #include <netinet6/ipv6_route.h> /* glibc does not have this */
32 #include "net-support.h"
33 #include "pathnames.h"
35 #include "net-features.h"
39 extern struct aftype inet6_aftype
;
44 static int usage(void)
46 fprintf(stderr
, _("Usage: inet6_route [-vF] del Target\n"));
47 fprintf(stderr
, _(" inet6_route [-vF] add Target [gw Gw] [metric M] [[dev] If]\n"));
48 fprintf(stderr
, _(" inet6_route [-FC] flush NOT supported\n"));
53 static int INET6_setroute(int action
, int options
, char **args
)
57 struct sockaddr_in6 sa6
;
58 char target
[128], gateway
[128] = "NONE";
59 int metric
, prefix_len
;
66 strcpy(target
, *args
++);
67 if (!strcmp(target
, "default")) {
69 memset(&sa6
, 0, sizeof(sa6
));
71 if ((cp
= strchr(target
, '/'))) {
72 prefix_len
= atol(cp
+ 1);
73 if ((prefix_len
< 0) || (prefix_len
> 128))
79 if (inet6_aftype
.input(1, target
, (struct sockaddr
*) &sa6
) < 0
80 && inet6_aftype
.input(0, target
, (struct sockaddr
*) &sa6
) < 0) {
81 inet6_aftype
.herror(target
);
86 /* Clean out the RTREQ structure. */
87 memset((char *) &rt
, 0, sizeof(struct in6_rtmsg
));
89 memcpy(&rt
.rtmsg_dst
, sa6
.sin6_addr
.s6_addr
, sizeof(struct in6_addr
));
91 /* Fill in the other fields. */
92 rt
.rtmsg_flags
= RTF_UP
;
93 if (prefix_len
== 128)
94 rt
.rtmsg_flags
|= RTF_HOST
;
96 rt
.rtmsg_dst_len
= prefix_len
;
99 if (!strcmp(*args
, "metric")) {
102 if (!*args
|| !isdigit(**args
))
104 metric
= atoi(*args
);
105 rt
.rtmsg_metric
= metric
;
109 if (!strcmp(*args
, "gw") || !strcmp(*args
, "gateway")) {
113 if (rt
.rtmsg_flags
& RTF_GATEWAY
)
115 strcpy(gateway
, *args
);
116 if (inet6_aftype
.input(1, gateway
,
117 (struct sockaddr
*) &sa6
) < 0) {
118 inet6_aftype
.herror(gateway
);
121 memcpy(&rt
.rtmsg_gateway
, sa6
.sin6_addr
.s6_addr
,
122 sizeof(struct in6_addr
));
123 rt
.rtmsg_flags
|= RTF_GATEWAY
;
127 if (!strcmp(*args
, "mod")) {
129 rt
.rtmsg_flags
|= RTF_MODIFIED
;
132 if (!strcmp(*args
, "dyn")) {
134 rt
.rtmsg_flags
|= RTF_DYNAMIC
;
137 if (!strcmp(*args
, "device") || !strcmp(*args
, "dev")) {
148 /* Create a socket to the INET6 kernel. */
149 if ((skfd
= socket(AF_INET6
, SOCK_DGRAM
, 0)) < 0) {
154 memset(&ifr
, 0, sizeof(ifr
));
155 strcpy(ifr
.ifr_name
, devname
);
157 if (ioctl(skfd
, SIOGIFINDEX
, &ifr
) < 0) {
158 perror("SIOGIFINDEX");
161 rt
.rtmsg_ifindex
= ifr
.ifr_ifindex
;
163 rt
.rtmsg_ifindex
= 0;
165 /* Tell the kernel to accept this route. */
166 if (action
== RTACTION_DEL
) {
167 if (ioctl(skfd
, SIOCDELRT
, &rt
) < 0) {
173 if (ioctl(skfd
, SIOCADDRT
, &rt
) < 0) {
180 /* Close the socket. */
185 int INET6_rinput(int action
, int options
, char **args
)
187 if (action
== RTACTION_FLUSH
) {
188 fprintf(stderr
, _("Flushing `inet6' routing table not supported\n"));
191 if ((*args
== NULL
) || (action
== RTACTION_HELP
))
194 return (INET6_setroute(action
, options
, args
));
196 #endif /* HAVE_AFINET6 */