]> git.saurik.com Git - apple/network_cmds.git/blob - mnc.tproj/mnc_opts.c
network_cmds-596.tar.gz
[apple/network_cmds.git] / mnc.tproj / mnc_opts.c
1 /*
2 * $Id: mnc_opts.c,v 1.3 2004/09/22 16:02:26 colmmacc Exp $
3 *
4 * mnc_opts.c -- Multicast NetCat
5 *
6 * Colm MacCarthaigh, <colm@apache.org>
7 *
8 * Copyright (c) 2007, Colm MacCarthaigh.
9 * Copyright (c) 2004 - 2006, HEAnet Ltd.
10 *
11 * This software is an open source.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 *
17 * Redistributions of source code must retain the above copyright notice,
18 * this list of conditions and the following disclaimer.
19 *
20 * Redistributions in binary form must reproduce the above copyright notice,
21 * this list of conditions and the following disclaimer in the documentation
22 * and/or other materials provided with the distribution.
23 *
24 * Neither the name of the HEAnet Ltd. nor the names of its contributors may
25 * be used to endorse or promote products derived from this software without
26 * specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
32 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 *
40 */
41
42 #include <stdlib.h>
43 #include <stdio.h>
44 #include <string.h>
45
46 #ifndef WINDOWS
47
48 /* UNIX-y includes */
49 #include <sys/types.h>
50 #include <sys/socket.h>
51 #include <netdb.h>
52 #else
53
54 /* WINDOWS-y includes */
55 #include <winsock2.h>
56 #include <ws2tcpip.h>
57 #endif
58
59 #include "mnc.h"
60
61 /* Display a usage statement */
62 void usage(void)
63 {
64 fprintf(stderr,
65 "Usage: mnc [-l] [-i interface] [-p port] group-id "
66 "[source-address]\n\n"
67 "-l : listen mode\n"
68 "-i : specify interface to listen\n"
69 "-p : specify port to listen/send on\n\n");
70 exit(1);
71 }
72
73 struct mnc_configuration * parse_arguments(int argc, char **argv)
74 {
75 /* Utility variables */
76 int optind,
77 errorcode;
78 struct addrinfo hints;
79
80 /* Our persisting configuration */
81 static struct mnc_configuration config;
82
83 /* Set some defaults */
84 config.mode = SENDER;
85 config.port = MNC_DEFAULT_PORT;
86 config.iface = NULL;
87 config.source = NULL;
88
89 /* Loop through the arguments */
90 for (optind = 1; optind < (argc - 1); optind++)
91 {
92 if ( (argv[optind][0] == '-') || (argv[optind][0] == '/') )
93 {
94 switch(argv[optind][1])
95 {
96 /* Set listening mode */
97 case 'l': config.mode = LISTENER;
98 break;
99
100 /* Set port */
101 case 'p': config.port = argv[++optind];
102 break;
103
104 /* Set an interface */
105 case 'i': config.iface = argv[++optind];
106 break;
107
108 /* Unrecognised option */
109 default: usage();
110 break;
111 }
112 }
113 else
114 {
115 /* assume we've ran out of options */
116 break;
117 }
118 }
119
120 /* There's a chance we were passed one option */
121 if (optind >= argc || argv[optind][0] == '-')
122 {
123 usage();
124 }
125
126 /* Now make sure we have either exactly 1 or 2 more arguments */
127 if ( (argc - optind) != 1 && (argc - optind) != 2 )
128 {
129 /* We have not been given the right ammount of
130 arguments */
131 usage();
132 }
133
134 /* You can't have an interface without also listening */
135 if (config.mode == SENDER && config.iface != NULL)
136 {
137 mnc_error("You may only specify the interface when in"
138 " listening mode\n");
139 }
140
141 /* Set some hints for getaddrinfo */
142 memset(&hints, 0, sizeof(hints));
143
144 /* We want a UDP socket */
145 hints.ai_socktype = SOCK_DGRAM;
146
147 /* Don't do any name-lookups */
148 hints.ai_flags = AI_NUMERICHOST;
149
150 /* Get the group-id information */
151 if ( (errorcode =
152 getaddrinfo(argv[optind], config.port, &hints, &config.group)) != 0)
153 {
154 mnc_error("Error getting group-id address information: %s\n",
155 gai_strerror(errorcode));
156 }
157
158 /* Move on to next argument */
159 optind++;
160
161 /* Get the source information */
162 if ( (argc - optind) == 1)
163 {
164
165 if ( (errorcode =
166 getaddrinfo(argv[optind], config.port, &hints, &config.source))
167 != 0)
168 {
169 mnc_error("Error getting source-address information: %s\n",
170 gai_strerror(errorcode));
171 }
172
173 /* Confirm that the source and group are in the same Address Family */
174 if ( config.source->ai_family != config.group->ai_family )
175 {
176 mnc_error("Group ID and Source address are not of "
177 "the same type\n");
178 }
179 }
180
181 return &config;
182 }