1 /* $NetBSD: srtconfig.c,v 1.2 2006/12/29 10:39:59 wiz Exp $ */
2 /* This file is in the public domain. */
10 #include <arpa/inet.h>
11 #include <net/if_srt.h>
13 extern const char *__progname
;
15 #define ACT_ERROR 1 /* none of the below */
16 #define ACT_QUERYALL 2 /* srtX */
17 #define ACT_QUERYONE 3 /* srtX N */
18 #define ACT_DEL 4 /* srtX del N */
19 #define ACT_ADD 5 /* srtX add srcaddr mask dstif dstaddr */
20 #define ACT_SET 6 /* srtX set N srcaddr mask dstif dstaddr */
21 #define ACT_FLAGS 7 /* srtX flags */
22 #define ACT_SFLAG 8 /* srtX flags [+|-]flag */
23 #define ACT_DEBUG 9 /* srtX debug */
24 static int action
= ACT_ERROR
;
29 static char *txt_addr
;
30 static char *txt_mask
;
31 static char *txt_dstif
;
32 static char *txt_dstaddr
;
39 } flagbits
[] = { { "mtulock", SSF_MTULOCK
},
42 static void handleargs(int ac
, char **av
)
46 { action
= ACT_QUERYALL
;
48 else if ((ac
== 3) && !strcmp(av
[2],"debug"))
51 else if ((ac
== 3) && !strcmp(av
[2],"flags"))
55 { action
= ACT_QUERYONE
;
58 else if ((ac
== 4) && !strcmp(av
[2],"del"))
62 else if ((ac
== 4) && !strcmp(av
[2],"flags"))
66 else if ((ac
== 7) && !strcmp(av
[2],"add"))
73 else if ((ac
== 8) && !strcmp(av
[2],"set"))
81 if (action
== ACT_ERROR
)
82 { fprintf(stderr
,"Usage: %s srtX\n",__progname
);
83 fprintf(stderr
," %s srtX N\n",__progname
);
84 fprintf(stderr
," %s srtX del N\n",__progname
);
85 fprintf(stderr
," %s srtX add addr mask dstif dstaddr\n",__progname
);
86 fprintf(stderr
," %s srtX set N addr mask dstif dstaddr\n",__progname
);
87 fprintf(stderr
," %s srtX flags {[+|-]flag}\n",__progname
);
88 fprintf(stderr
," %s srtX debug\n",__progname
);
93 static void open_dev(int how
)
95 if (! index(txt_dev
,'/'))
97 asprintf(&tmp
,"/dev/%s",txt_dev
);
100 devfd
= open(txt_dev
,how
,0);
102 { fprintf(stderr
,"%s; can't open %s: %s\n",__progname
,txt_dev
,strerror(errno
));
107 static void query_n(int n
)
113 if (ioctl(devfd
,SRT_GETRT
,&r
) < 0)
114 { fprintf(stderr
,"%s: can't get rt #%d: %s\n",__progname
,n
,strerror(errno
));
118 printf(" %s",inet_ntop(r
.af
,&r
.srcmatch
,&obuf
[0],sizeof(obuf
)));
119 printf(" /%d",r
.srcmask
);
120 printf(" %.*s",(int)sizeof(r
.u
.dstifn
),&r
.u
.dstifn
[0]);
123 printf(" %s",inet_ntoa(r
.dst
.sin
.sin_addr
));
126 printf(" %s",inet_ntop(AF_INET6
,&r
.dst
.sin6
.sin6_addr
,&obuf
[0],sizeof(obuf
)));
129 printf(" ?af%d",r
.af
);
135 static void do_query(int narg
)
145 { if (ioctl(devfd
,SRT_GETNRT
,&n
) < 0)
146 { fprintf(stderr
,"%s: can't get count: %s\n",__progname
,strerror(errno
));
149 for (i
=0;i
<n
;i
++) query_n(i
);
153 static void do_del(unsigned int n
)
156 if (ioctl(devfd
,SRT_DELRT
,&n
) < 0)
157 { fprintf(stderr
,"%s: can't delete #%u: %s\n",__progname
,n
,strerror(errno
));
162 static void do_set(int n
)
172 if (ioctl(devfd
,SRT_GETNRT
,&v
) < 0)
173 { fprintf(stderr
,"%s: can't get count: %s\n",__progname
,strerror(errno
));
178 bzero(&r
.dst
,sizeof(r
.dst
));
180 if (inet_pton(AF_INET
,txt_addr
,&r
.srcmatch
.v4
) == 1)
182 r
.dst
.sin
.sin_family
= AF_INET
;
183 r
.dst
.sin
.sin_len
= sizeof(r
.dst
.sin
);
184 dp
= &r
.dst
.sin
.sin_addr
;
187 else if (inet_pton(AF_INET6
,txt_addr
,&r
.srcmatch
.v6
) == 1)
189 r
.dst
.sin6
.sin6_family
= AF_INET6
;
190 r
.dst
.sin6
.sin6_len
= sizeof(r
.dst
.sin6
);
191 dp
= &r
.dst
.sin6
.sin6_addr
;
195 { fprintf(stderr
,"%s: %s: invalid match address\n",__progname
,txt_addr
);
198 if (txt_mask
[0] == '/') txt_mask
++;
200 if ((w
< 0) || (w
> maxw
))
201 { fprintf(stderr
,"%s: %s: out-of-range CIDR width\n",__progname
,txt_mask
);
205 if (strlen(txt_dstif
) > sizeof(r
.u
.dstifn
)-1)
206 { fprintf(stderr
,"%s: %s: too long\n",__progname
,txt_dstif
);
209 strncpy(&r
.u
.dstifn
[0],txt_dstif
,sizeof(r
.u
.dstifn
));
210 if (inet_pton(r
.af
,txt_dstaddr
,dp
) != 1)
211 { fprintf(stderr
,"%s: %s: invalid destination address\n",__progname
,txt_dstaddr
);
214 if (ioctl(devfd
,SRT_SETRT
,&r
) < 0)
215 { fprintf(stderr
,"%s: can't set route: %s\n",__progname
,strerror(errno
));
220 static void do_flags(void)
226 if (ioctl(devfd
,SRT_GFLAGS
,&f
) < 0)
227 { fprintf(stderr
,"%s: can't get flags: %s\n",__progname
,strerror(errno
));
230 for (i
=0;flagbits
[i
].name
;i
++)
231 { printf(" %c%s",(f
&flagbits
[i
].bit
)?'+':'-',flagbits
[i
].name
);
232 f
&= ~flagbits
[i
].bit
;
234 if (f
) printf(" +0x%x",f
);
238 static void do_sflag(void)
245 { case '+': case '-': break;
247 fprintf(stderr
,"%s: last argument must be +flag or -flag\n",__progname
);
251 for (i
=0;flagbits
[i
].name
;i
++) if (!strcmp(flagbits
[i
].name
,txt_flg
+1)) break;
252 if (! flagbits
[i
].name
)
253 { fprintf(stderr
,"%s: unrecognized flag bit `%s'\n",__progname
,txt_flg
+1);
258 if (ioctl(devfd
,SRT_GFLAGS
,&f
) < 0)
259 { fprintf(stderr
,"%s: can't get flags: %s\n",__progname
,strerror(errno
));
262 if (txt_flg
[0] == '+') f
|= b
; else f
&= ~b
;
263 if (ioctl(devfd
,SRT_SFLAGS
,&f
) < 0)
264 { fprintf(stderr
,"%s: can't set flags: %s\n",__progname
,strerror(errno
));
269 static void do_debug(void)
275 if (ioctl(devfd
,SRT_DEBUG
,&vp
) < 0)
276 { fprintf(stderr
,"%s: can't SRT_DEBUG: %s\n",__progname
,strerror(errno
));
281 int main(int, char **);
282 int main(int ac
, char **av
)
290 do_query(atoi(txt_n
));