Help on commands added. Link list function added. Bugfixes
[olsrd.git] / src / olsr_switch / ohs_cmd.c
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon(olsrd)
4  * Copyright (c) 2005, Andreas T√łnnesen(andreto@olsr.org)
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without 
8  * modification, are permitted provided that the following conditions 
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright 
12  *   notice, this list of conditions and the following disclaimer.
13  * * 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 
16  *   distribution.
17  * * Neither the name of olsr.org, olsrd 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.
20  *
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 OWNER 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 
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * Visit http://www.olsr.org for more information.
35  *
36  * If you find this software useful feel free to make a donation
37  * to the project. For more information see the website or contact
38  * the copyright holders.
39  *
40  * $Id: ohs_cmd.c,v 1.9 2005/05/31 16:40:45 kattemat Exp $
41  */
42
43 #include "olsr_host_switch.h"
44 #include "olsr_types.h"
45 #include "commands.h"
46 #include "link_rules.h"
47 #include <string.h>
48 #include <stdlib.h>
49 #include <sys/socket.h>
50 #include <netinet/in.h>
51 #include <arpa/inet.h>
52
53
54 #define ARG_BUF_SIZE 500
55 static char arg_buf[ARG_BUF_SIZE];
56
57 #define TOK_BUF_SIZE 500
58 static char tok_buf[TOK_BUF_SIZE];
59
60 static void
61 get_arg_buf(FILE *handle, char *buf, size_t size)
62 {
63   char c = 0;
64   int pos = 0;
65
66   while(((c = fgetc(handle)) != '\n') &&
67         pos < (size - 2))
68     {
69       buf[pos] = c;
70       pos++;
71     }
72
73   buf[pos] = 0;
74 }
75
76 static int
77 get_next_token(char *src, char *dst, size_t buflen)
78 {
79   int i = 0, j = 0;
80
81   dst[0] = 0;
82   /* Skip leading spaces */
83   while(src[j] == ' ' && src[j] != 0)
84     {
85       j++;
86     }
87
88   src += j;
89   i = 0;
90   while((src[i] != ' ') && (src[i] != 0) && (i < (buflen - 1)))
91     {
92       dst[i] = src[i];
93       i++;
94     }
95   dst[i] = 0;
96
97   if(strlen(dst))
98     printf("Extracted token: %s\n", dst);
99   return i + j;
100 }
101
102 int
103 ohs_cmd_link(FILE *handle, char *args)
104 {
105   olsr_u8_t bi = 0;
106   struct ohs_connection *src, *dst;
107   struct in_addr iaddr;
108   int qual;
109   struct ohs_ip_link *link, *inv_link;
110
111   if(strlen(args) < strlen("bi"))
112     goto print_usage;
113
114   args += get_next_token(args, tok_buf, TOK_BUF_SIZE);
115
116   if(!strlen(tok_buf))
117     goto print_usage;
118
119   if(!strncmp(tok_buf, "bi", strlen("bi")))
120     {
121       bi = 1;
122       args += get_next_token(args, tok_buf, TOK_BUF_SIZE);
123
124       if(!strlen(tok_buf))
125         goto print_usage;
126     }
127
128   if(!inet_aton(tok_buf, &iaddr))
129     {
130       printf("Invalid src IP %s\n", tok_buf);
131       return -1;
132     }
133
134   src = get_client_by_addr((union olsr_ip_addr *)&iaddr.s_addr);
135
136   if(!src)
137     {
138       printf("No such client: %s!\n", tok_buf);
139       return -1;
140     }
141
142   args += get_next_token(args, tok_buf, TOK_BUF_SIZE);
143   
144   if(!strlen(tok_buf))
145     goto print_usage;
146
147   if(!inet_aton(tok_buf, &iaddr))
148     {
149       printf("Invalid src IP %s\n", tok_buf);
150       return -1;
151     }
152
153   dst = get_client_by_addr((union olsr_ip_addr *)&iaddr.s_addr);
154
155   if(!dst)
156     {
157       printf("No such client: %s!\n", tok_buf);
158       return -1;
159     }
160
161   args += get_next_token(args, tok_buf, TOK_BUF_SIZE);
162   
163   if(!strlen(tok_buf))
164     goto print_usage;
165
166   qual = atoi(tok_buf);
167
168   if(qual < 0 || qual > 100)
169     {
170       printf("Link quality out of range(0-100)\n");
171       return -1;
172     }
173   
174   printf("%s %sdirectional link %s %c=> %s quality %d\n", 
175          (qual == 100) ? "Removing" : "Setting", bi ? "bi" : "uni",
176          olsr_ip_to_string(&src->ip_addr), bi ? '<' : '=', 
177          olsr_ip_to_string(&dst->ip_addr), qual);
178
179   link = get_link(src, &dst->ip_addr);
180   if(bi)
181     inv_link = get_link(dst, &src->ip_addr);
182   else
183     inv_link = NULL;
184
185   if(qual == 100)
186     {
187       /* Remove link entry */
188       if(link)
189         remove_link(src, link);
190       if(inv_link)
191         remove_link(dst, inv_link);
192     }
193   else 
194     {
195       if(!link)
196         {
197           /* Create new link */
198             link = malloc(sizeof(struct ohs_ip_link));
199             if(!link)
200               OHS_OUT_OF_MEMORY("New link");
201             /* Queue */
202             link->next = src->links;
203             src->links = link;
204             COPY_IP(&link->dst, &dst->ip_addr);
205             src->linkcnt++;
206         }
207
208       link->quality = qual;
209
210       if(bi)
211         {
212           if(!inv_link)
213             {
214               /* Create new link */
215               inv_link = malloc(sizeof(struct ohs_ip_link));
216               if(!inv_link)
217                 OHS_OUT_OF_MEMORY("New link");
218               /* Queue */
219               inv_link->next = dst->links;
220               dst->links = inv_link;
221               COPY_IP(&inv_link->dst, &src->ip_addr);
222               dst->linkcnt++;
223             }
224           inv_link->quality = qual;
225         }
226     }
227
228   return 1;
229  print_usage:
230   printf("link <bi> srcIP dstIP [0-100]");
231   return -1;
232 }
233
234 int
235 ohs_cmd_list(FILE *handle, char *args)
236 {
237   struct ohs_connection *oc = ohs_conns;
238
239   args += get_next_token(args, tok_buf, TOK_BUF_SIZE);
240   
241   if(!strlen(tok_buf) || 
242      !strncmp(tok_buf, "clients", strlen("clients")))
243     {
244       printf("All connected clients:\n");
245       
246       while(oc)
247         {
248           printf("\t%s - Rx: %d Tx: %d LinkCnt: %d\n", olsr_ip_to_string(&oc->ip_addr), 
249                  oc->rx, oc->tx, oc->linkcnt);
250           oc = oc->next;
251         }
252     }
253   else if(!strncmp(tok_buf, "links", strlen("links")))
254     {
255       printf("All configured links:\n");
256       
257       while(oc)
258         {
259           struct ohs_ip_link *links = oc->links;
260
261           while(links)
262             {
263               printf("\t%s => %s Quality: %d\n", 
264                      olsr_ip_to_string(&oc->ip_addr),
265                      olsr_ip_to_string(&links->dst),
266                      links->quality);
267
268               links = links->next;
269             }
270           oc = oc->next;
271         }
272     }
273   else
274     {
275
276       printf("list [clients|links]");
277       return -1;
278     }
279
280   return 1;
281 }
282
283 int
284 ohs_cmd_help(FILE *handle, char *args)
285 {
286   int i;
287
288   args += get_next_token(args, tok_buf, TOK_BUF_SIZE);
289   
290   if(!strlen(tok_buf))
291     {
292       printf("Olsrd host switch version %s\n", OHS_VERSION);
293       printf("Available commands:\n");
294       
295       for(i = 0; ohs_commands[i].cmd; i++)
296         {
297           if(ohs_commands[i].helptext_brief)
298             printf("\t%s - %s\n", 
299                    ohs_commands[i].cmd,
300                    ohs_commands[i].helptext_brief);
301         }
302       printf("\nType 'help cmd' for help on a specific command\n");
303     }
304   else
305     {
306       for(i = 0; ohs_commands[i].cmd; i++)
307         {
308           if(!strncmp(tok_buf, ohs_commands[i].cmd, strlen(ohs_commands[i].cmd)))
309             {
310               printf("Usage: %s\nDescription:\n%s\n", 
311                      ohs_commands[i].syntax,
312                      ohs_commands[i].helptext_long);
313               return 1;
314             }
315         }
316
317       printf("Usage: help <command>\n");
318     }
319
320   return i;
321 }
322
323 int
324 ohs_cmd_log(FILE *handle, char *args)
325 {
326   olsr_u8_t set = 0;
327
328   args += get_next_token(args, tok_buf, TOK_BUF_SIZE);
329   
330   if(strlen(tok_buf) &&
331      ((set = !strncmp(tok_buf, "set", strlen("set"))) || 
332       !strncmp(tok_buf, "unset", strlen("unset"))))
333     {
334         olsr_u32_t new_bit = 0;
335         
336         args += get_next_token(args, tok_buf, TOK_BUF_SIZE);
337   
338         if(!strlen(tok_buf))
339             goto print_usage;
340         
341         
342         if(!strncmp(tok_buf, "CON", strlen("CON")))
343             new_bit = LOG_CONNECT;
344         else if(!strncmp(tok_buf, "FOR", strlen("FOR")))
345             new_bit = LOG_FORWARD;
346         else if(!strncmp(tok_buf, "LIN", strlen("LIN")))
347             new_bit = LOG_LINK;
348           
349         if(!new_bit)
350             goto print_usage;
351
352         if(set)
353             logbits |= new_bit;
354         else
355             logbits &= ~new_bit;
356
357         printf("%s log bit: 0x%08x, new log: 0x%08x\n", set ? "Setting" : "Removing",
358                new_bit, logbits);
359
360     }
361   else
362     {
363       if(strlen(tok_buf))
364         goto print_usage;
365
366       printf("Log: (0x%08x) ", logbits);
367       if(logbits & LOG_CONNECT)
368         printf("CONNECT ");
369       if(logbits & LOG_FORWARD)
370         printf("FORWARD ");
371       if(logbits & LOG_LINK)
372         printf("LINK ");
373
374       printf("\n");
375     }
376   return 1;
377
378  print_usage:
379   printf("Usage: log <[set|unset] [CONNECT|FORWARD|LINK]>\n");
380   return 0;
381
382 }
383
384 int
385 ohs_cmd_exit(FILE *handle, char *args)
386 {
387
388   printf("Exitting... bye-bye!\n");
389
390 #ifdef WIN32
391   SignalHandler(0);
392 #else
393   ohs_close(0);
394 #endif
395
396   return 0;
397 }
398
399 int
400 ohs_parse_command(FILE *handle)
401 {
402   char input_data[100];
403   int i;
404
405   fscanf(handle, "%s", input_data);
406
407   get_arg_buf(handle, arg_buf, ARG_BUF_SIZE);
408
409   for(i = 0; ohs_commands[i].cmd; i++)
410     {
411       if(!strcmp(input_data, ohs_commands[i].cmd))
412         {
413           if(ohs_commands[i].cmd_cb)
414             {
415               ohs_commands[i].cmd_cb(handle, arg_buf);
416             }
417           else
418             {
419               printf("No action registered on cmd %s!\n", input_data);
420             }
421           break;
422         }
423     }
424   
425   if(!ohs_commands[i].cmd)
426     {
427       printf("%s: no such cmd!\n", input_data);
428     }
429
430
431   return 0;
432 }