added a new header file to encapsulate compiler-specific stuff.
[newos.git] / apps / netcfg / main.c
blobb06aa2754164eb77c6ae347045575caa287fd1a7
1 /*
2 ** Copyright 2003, Travis Geiselbrecht. All rights reserved.
3 ** Distributed under the terms of the NewOS License.
4 */
5 #include <stdlib.h>
6 #include <stdio.h>
7 #include <string.h>
8 #include <newos/errors.h>
9 #include <newos/net.h>
10 #include <sys/syscalls.h>
11 #include <unistd.h>
13 static int usage(const char *argv[])
15 printf("usage:\n");
16 printf("%s\n", argv[0]);
17 printf("\tif create <interface>\n");
18 printf("\tif delete <interface>\n");
19 printf("\tif addaddr <interface> ipv4 addr <ip address> mask <netmask> broadcast <broadcast>\n");
20 printf("\tif rmaddr <interface> ipv4 addr <ip address>\n");
21 printf("\tif list\n");
22 printf("\n");
23 printf("\troute add default ipv4 addr <ip address> if <interface> ipv4 addr <ip address>\n");
24 printf("\troute add net ipv4 addr <ip address> mask <netmask> if <interface> ipv4 addr <ip address>\n");
25 printf("\troute delete ipv4 addr <ip address>\n");
26 printf("\troute list\n");
28 return -1;
31 static int parse_ipv4_addr_string(ipv4_addr *ip_addr, const char *_ip_addr_string)
33 int a, b;
34 char ip_addr_string[128];
36 strlcpy(ip_addr_string, _ip_addr_string, sizeof(ip_addr_string));
38 *ip_addr = 0;
40 // walk through the first number
41 a = 0;
42 b = 0;
43 for(; ip_addr_string[b] != 0 && ip_addr_string[b] != '.'; b++)
45 if(ip_addr_string[b] == 0)
46 return ERR_NOT_FOUND;
47 ip_addr_string[b] = 0;
48 *ip_addr = atoi(&ip_addr_string[a]) << 24;
49 b++;
51 // second digit
52 a = b;
53 for(; ip_addr_string[b] != 0 && ip_addr_string[b] != '.'; b++)
55 if(ip_addr_string[b] == 0)
56 return ERR_NOT_FOUND;
57 ip_addr_string[b] = 0;
58 *ip_addr |= atoi(&ip_addr_string[a]) << 16;
59 b++;
61 // third digit
62 a = b;
63 for(; ip_addr_string[b] != 0 && ip_addr_string[b] != '.'; b++)
65 if(ip_addr_string[b] == 0)
66 return ERR_NOT_FOUND;
67 ip_addr_string[b] = 0;
68 *ip_addr |= atoi(&ip_addr_string[a]) << 8;
69 b++;
71 // last digit
72 a = b;
73 for(; ip_addr_string[b] != 0 && ip_addr_string[b] != '.'; b++)
75 ip_addr_string[b] = 0;
76 *ip_addr |= atoi(&ip_addr_string[a]);
78 return NO_ERROR;
81 static int do_if(int argc, const char *argv[], int curr_arg)
83 int op;
84 const char *interface_name = NULL;
85 ipv4_addr if_addr = 0;
86 ipv4_addr mask_addr = 0;
87 ipv4_addr broadcast_addr = 0;
88 struct _ioctl_net_if_control_struct control;
90 if(curr_arg >= argc)
91 return usage(argv);
93 /* parse the args for the various commands */
94 if(!strncasecmp(argv[curr_arg], "create", sizeof("create"))) {
95 if(curr_arg + 1 >= argc)
96 return usage(argv);
97 op = IOCTL_NET_CONTROL_IF_CREATE;
98 interface_name = argv[curr_arg + 1];
99 } else if(!strncasecmp(argv[curr_arg], "delete", sizeof("delete"))) {
100 if(curr_arg + 1 >= argc)
101 return usage(argv);
102 op = IOCTL_NET_CONTROL_IF_DELETE;
103 interface_name = argv[curr_arg + 1];
104 } else if(!strncasecmp(argv[curr_arg], "addaddr", sizeof("addaddr"))) {
105 if(curr_arg + 8 >= argc)
106 return usage(argv);
107 op = IOCTL_NET_CONTROL_IF_ADDADDR;
108 interface_name = argv[curr_arg + 1];
109 if(strncasecmp(argv[curr_arg + 2], "ipv4", sizeof("ipv4")) ||
110 strncasecmp(argv[curr_arg + 3], "addr", sizeof("addr")) ||
111 strncasecmp(argv[curr_arg + 5], "mask", sizeof("mask")) ||
112 strncasecmp(argv[curr_arg + 7], "broadcast", sizeof("broadcast")))
113 return usage(argv);
114 parse_ipv4_addr_string(&if_addr, argv[curr_arg + 4]);
115 parse_ipv4_addr_string(&mask_addr, argv[curr_arg + 6]);
116 parse_ipv4_addr_string(&broadcast_addr, argv[curr_arg + 8]);
117 } else if(!strncasecmp(argv[curr_arg], "rmaddr", sizeof("rmaddr"))) {
118 if(curr_arg + 4 >= argc)
119 return usage(argv);
120 op = IOCTL_NET_CONTROL_IF_RMADDR;
121 interface_name = argv[curr_arg + 1];
122 if(strncasecmp(argv[curr_arg + 2], "ipv4", sizeof("ipv4")) ||
123 strncasecmp(argv[curr_arg + 3], "addr", sizeof("addr")))
124 return usage(argv);
125 parse_ipv4_addr_string(&if_addr, argv[curr_arg + 4]);
126 } else if(!strncasecmp(argv[curr_arg], "list", sizeof("list"))) {
127 op = IOCTL_NET_CONTROL_IF_LIST;
128 } else {
129 return usage(argv);
132 // printf("do_if: op %d, interface_name '%s', if_addr 0x%x, mask_addr 0x%x, broadcast_addr 0x%x\n",
133 // op, interface_name, if_addr, mask_addr, broadcast_addr);
135 // fill out the control structure
136 memset(&control, 0, sizeof(control));
137 control.if_name[0] = 0;
138 if(interface_name)
139 strlcpy(control.if_name, interface_name, sizeof(control.if_name));
140 control.if_addr.len = 4;
141 control.if_addr.type = ADDR_TYPE_IP;
142 NETADDR_TO_IPV4(control.if_addr) = if_addr;
143 control.mask_addr.len = 4;
144 control.mask_addr.type = ADDR_TYPE_IP;
145 NETADDR_TO_IPV4(control.mask_addr) = mask_addr;
146 control.broadcast_addr.len = 4;
147 control.broadcast_addr.type = ADDR_TYPE_IP;
148 NETADDR_TO_IPV4(control.broadcast_addr) = broadcast_addr;
150 // call the ioctl
152 int fd;
153 int err;
155 fd = open(NET_CONTROL_DEV, 0);
156 if(fd < 0) {
157 printf("error opening network control device\n");
158 return fd;
160 err = ioctl(fd, op, &control, sizeof(control));
161 close(fd);
163 if(err < 0) {
164 printf("error calling ioctl %d (%s)\n", err, strerror(err));
167 // printf("do_if: ioctl returned %d\n", err);
168 return err;
172 static int do_route(int argc, const char *argv[], int curr_arg)
174 int op;
175 ipv4_addr net_addr = 0;
176 ipv4_addr mask_addr = 0;
177 ipv4_addr if_addr = 0;
178 const char *interface_name = NULL;
179 struct _ioctl_net_route_struct control;
181 if(curr_arg >= argc)
182 return usage(argv);
184 /* parse the args for the various commands */
185 if(!strncasecmp(argv[curr_arg], "add", sizeof("add"))) {
186 curr_arg++;
187 if(curr_arg >= argc)
188 return usage(argv);
189 if(!strncasecmp(argv[curr_arg], "default", sizeof("default"))) {
190 if(curr_arg + 8 >= argc)
191 return usage(argv);
192 if(strncasecmp(argv[curr_arg + 1], "ipv4", sizeof("ipv4")) ||
193 strncasecmp(argv[curr_arg + 2], "addr", sizeof("addr")) ||
194 strncasecmp(argv[curr_arg + 4], "if", sizeof("if")) ||
195 strncasecmp(argv[curr_arg + 6], "ipv4", sizeof("ipv4")) ||
196 strncasecmp(argv[curr_arg + 7], "addr", sizeof("addr")))
197 return usage(argv);
198 op = IOCTL_NET_CONTROL_ROUTE_ADD;
199 parse_ipv4_addr_string(&net_addr, argv[curr_arg + 3]);
200 interface_name = argv[curr_arg + 5];
201 parse_ipv4_addr_string(&if_addr, argv[curr_arg + 8]);
202 } else if(!strncasecmp(argv[curr_arg], "net", sizeof("net"))) {
203 if(curr_arg + 10 >= argc)
204 return usage(argv);
205 if(strncasecmp(argv[curr_arg + 1], "ipv4", sizeof("ipv4")) ||
206 strncasecmp(argv[curr_arg + 2], "addr", sizeof("addr")) ||
207 strncasecmp(argv[curr_arg + 4], "mask", sizeof("mask")) ||
208 strncasecmp(argv[curr_arg + 6], "if", sizeof("if")) ||
209 strncasecmp(argv[curr_arg + 8], "ipv4", sizeof("ipv4")) ||
210 strncasecmp(argv[curr_arg + 9], "addr", sizeof("addr")))
211 return usage(argv);
212 op = IOCTL_NET_CONTROL_ROUTE_ADD;
213 parse_ipv4_addr_string(&net_addr, argv[curr_arg + 3]);
214 parse_ipv4_addr_string(&mask_addr, argv[curr_arg + 5]);
215 interface_name = argv[curr_arg + 7];
216 parse_ipv4_addr_string(&if_addr, argv[curr_arg + 10]);
217 } else {
218 return usage(argv);
220 } else if(!strncasecmp(argv[curr_arg], "delete", sizeof("delete"))) {
221 if(curr_arg + 3 >= argc)
222 return usage(argv);
223 if(strncasecmp(argv[curr_arg + 1], "ipv4", sizeof("ipv4")) ||
224 strncasecmp(argv[curr_arg + 2], "addr", sizeof("addr")))
225 return usage(argv);
226 op = IOCTL_NET_CONTROL_ROUTE_DELETE;
227 parse_ipv4_addr_string(&net_addr, argv[curr_arg + 3]);
228 } else if(!strncasecmp(argv[curr_arg], "list", sizeof("list"))) {
229 op = IOCTL_NET_CONTROL_ROUTE_LIST;
230 } else {
231 return usage(argv);
234 // printf("do_route: op %d, net_addr 0x%x, mask_addr 0x%x, if_addr 0x%x, interface_name '%s'\n",
235 // op, net_addr, mask_addr, if_addr, interface_name);
237 // fill out the control structure
238 memset(&control, 0, sizeof(control));
239 control.net_addr.len = 4;
240 control.net_addr.type = ADDR_TYPE_IP;
241 NETADDR_TO_IPV4(control.net_addr) = net_addr;
242 control.if_addr.len = 4;
243 control.if_addr.type = ADDR_TYPE_IP;
244 NETADDR_TO_IPV4(control.if_addr) = if_addr;
245 control.mask_addr.len = 4;
246 control.mask_addr.type = ADDR_TYPE_IP;
247 NETADDR_TO_IPV4(control.mask_addr) = mask_addr;
248 control.if_name[0] = 0;
249 if(interface_name)
250 strlcpy(control.if_name, interface_name, sizeof(control.if_name));
252 // call the ioctl
254 int fd;
255 int err;
257 fd = open(NET_CONTROL_DEV, 0);
258 if(fd < 0) {
259 printf("error opening network control device\n");
260 return fd;
262 err = ioctl(fd, op, &control, sizeof(control));
263 close(fd);
265 if(err < 0) {
266 printf("error calling ioctl %d (%s)\n", err, strerror(err));
269 // printf("do_if: ioctl returned %d\n", err);
270 return err;
273 return 0;
276 int main(int argc, const char *argv[])
278 int curr_arg;
280 /* start processing args */
281 if(argc < 2)
282 return usage(argv);
284 curr_arg = 1;
285 if(!strncasecmp(argv[curr_arg], "if", sizeof("if"))) {
286 return do_if(argc, argv, curr_arg + 1);
287 } else if(!strncasecmp(argv[curr_arg], "route", sizeof("route"))) {
288 return do_route(argc, argv, curr_arg + 1);
289 } else {
290 return usage(argv);
293 return 0;