2 * Copyright (c) 2007 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * $DragonFly: src/sbin/syslink/syslink.c,v 1.1 2007/04/16 17:36:04 dillon Exp $
39 enum cmd
{ CMD_NONE
, CMD_LIST
, CMD_ADD
, CMD_DEL
, CMD_MOD
};
41 static int parse_add(const char *base
);
42 static int run_cmd(enum cmd commandopt
);
43 static void usage(const char *av0
);
51 enum proto Protocol
; /* filled in by parse_add() */
54 const char *TargetPath
;
55 struct sockaddr_in TargetSin
;
58 main(int ac
, char **av
)
60 const char *pidfile
= NULL
;
61 const char *av0
= av
[0];
67 commandopt
= CMD_NONE
;
69 while ((ch
= getopt(ac
, av
, "fnlvp:")) != -1) {
78 commandopt
= CMD_LIST
;
87 fprintf(stderr
, "unknown option: -%c\n", optopt
);
95 * -l with no arguments dumps all syslink routers. This is the
96 * only command that does not require further arguments.
98 if (commandopt
== CMD_LIST
&& ac
== 0)
99 exit(run_cmd(commandopt
));
104 * Parse sysid[:linkid]
108 if ((ptr
= strchr(ptr
, ':')) != NULL
) {
116 * Handle options that are actually commands (-l only at the moment).
117 * There should be no more arguments if we have a command-as-option.
119 if (commandopt
!= CMD_NONE
) {
122 exit(run_cmd(commandopt
));
126 * Parse keyword commands, set commandopt as an earmark.
129 fprintf(stderr
, "Missing command directive\n");
135 if (strcmp(av
[-1], "add") == 0) {
137 * add [protocol:]target[/bits]
139 commandopt
= CMD_ADD
;
142 if (parse_add(av
[0]))
146 } else if (strcmp(av
[-1], "del") == 0) {
147 commandopt
= CMD_DEL
;
148 } else if (strcmp(av
[-1], "delete") == 0) {
149 commandopt
= CMD_DEL
;
150 } else if (strcmp(av
[-1], "mod") == 0) {
151 commandopt
= CMD_MOD
;
152 } else if (strcmp(av
[-1], "modify") == 0) {
153 commandopt
= CMD_MOD
;
155 fprintf(stderr
, "Unknown command directive: %s\n", av
[-1]);
160 * Parse supplementary info
162 for (i
= 0; i
< ac
; ++i
) {
163 if (strcmp(av
[i
], "label") == 0) {
166 } else if (strcmp(av
[i
], "port") == 0) {
168 TargetSin
.sin_port
= htons(strtol(ptr
, &ptr
, 0));
170 fprintf(stderr
, "Non-numeric port specified\n");
175 fprintf(stderr
, "Unknown directive: %s\n", av
[i
]);
180 fprintf(stderr
, "Expected argument for last directive\n");
184 exit(run_cmd(commandopt
));
188 * Parse [protocol:]target[/bits]
192 parse_add(const char *base
)
201 * Split out the protocol from the protocol:target/subnet string,
202 * leave target/subnet in targ_str.
204 if (strchr(base
, ':')) {
205 prot_str
= strdup(base
);
206 targ_str
= strchr(prot_str
, ':');
210 targ_str
= strdup(base
);
214 * Parse the /subnet out of the target string, if present.
216 if ((bits_str
= strchr(targ_str
, '/')) != NULL
) {
218 NumBits
= strtol(bits_str
, &ptr
, NULL
);
220 fprintf(stderr
, "Malformed /subnet\n");
223 if (NumBits
< 2 || NumBits
> 24) {
224 fprintf(stderr
, "Subnet must be 2-24 bits\n");
230 * Figure out the protocol
232 if (prot_str
== NULL
) {
234 Protocol
= PROTO_TCP
;
236 Protocol
= PROTO_UDP
;
237 } else if (strcmp(prot_str
, "tcp") == 0) {
238 Protocol
= PROTO_TCP
;
239 } else if (strcmp(prot_str
, "udp") == 0) {
240 Protocol
= PROTO_UDP
;
241 } else if (strcmp(prot_str
, "udp_ptp") == 0) {
242 Protocol
= PROTO_UDP_PTP
;
243 } else if (strcmp(prot_str
, "pipe") == 0) {
244 Protocol
= PROTO_PIPE
;
245 } else if (strcmp(prot_str
, "fifo") == 0) {
246 Protocol
= PROTO_FIFO
;
247 } else if (strcmp(prot_str
, "listen") == 0) {
248 Protocol
= PROTO_LISTEN
;
250 fprintf(stderr
, "Unknown protocol: %s\n", prot_str
);
255 * Process the host, file, or descriptor specification
262 TargetSin
.sin_len
= sizeof(TargetSin
);
263 TargetSin
.sin_family
= AF_INET
;
264 if (inet_aton(targ_str
, &TargetSin
.sin_addr
) != 0) {
265 } else if ((he
= gethostbyname2(targ_str
, AF_INET
)) != NULL
) {
266 bcopy(he
->h_addr
, &TargetSin
.sin_addr
, he
->h_length
);
268 fprintf(stderr
, "Cannot resolve target %s\n", targ_str
);
273 TargetFd
= strtol(targ_str
, &ptr
, 0);
275 fprintf(stderr
, "non-numeric file descriptor "
276 "number in target\n");
281 TargetPath
= targ_str
;
289 run_cmd(enum cmd commandopt
)
317 usage(const char *av0
)
320 "syslink -l [-nv] [sysid[:linkid]]\n"
321 "syslink [-fnv] [-p pidfile] sysid add [protocol:]target[/bits]\n"
322 " [label name] [port num]\n"
323 "syslink [-fnv] sysid[:linkid] delete\n"
324 "syslink [-fnv] sysid[:linkid] modify\n"
325 " [label name] [port num]\n"