Fixed bi bug when using wildcards
[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.14 2005/06/02 19:06:24 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 < ((int)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 < ((int)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, wildc_src = 0, wildc_dst = 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   args += get_next_token(args, tok_buf, TOK_BUF_SIZE);
112
113   if(!strlen(tok_buf))
114     goto print_usage;
115
116   if(!strncmp(tok_buf, "bi", strlen("bi")))
117     {
118       bi = 1;
119       args += get_next_token(args, tok_buf, TOK_BUF_SIZE);
120
121       if(!strlen(tok_buf))
122         goto print_usage;
123     }
124
125   if(tok_buf[0] == '*')
126     {
127       wildc_src = 1;
128       src = ohs_conns;
129     }
130   else
131     {
132       if(!inet_aton(tok_buf, &iaddr))
133         {
134           printf("Invalid src IP %s\n", tok_buf);
135           return -1;
136         }
137
138       src = get_client_by_addr((union olsr_ip_addr *)&iaddr.s_addr);
139
140       if(!src)
141         {
142           printf("No such client: %s!\n", tok_buf);
143           return -1;
144         }
145     }
146
147   args += get_next_token(args, tok_buf, TOK_BUF_SIZE);
148   
149   if(!strlen(tok_buf))
150     goto print_usage;
151
152   if(tok_buf[0] == '*')
153     {
154       wildc_dst = 1;
155       dst = ohs_conns;
156     }
157   else
158     {
159       
160       if(!inet_aton(tok_buf, &iaddr))
161         {
162           printf("Invalid src IP %s\n", tok_buf);
163           return -1;
164         }
165       
166       dst = get_client_by_addr((union olsr_ip_addr *)&iaddr.s_addr);
167       if(!dst)
168         {
169           printf("No such client: %s!\n", tok_buf);
170           return -1;
171         }
172     }
173
174   args += get_next_token(args, tok_buf, TOK_BUF_SIZE);
175   
176   if(!strlen(tok_buf))
177     goto print_usage;
178
179   /* No use for bi if both src and dst are widcards */
180   if(wildc_src && wildc_dst)
181     {
182       bi = 0;
183     }
184
185   qual = atoi(tok_buf);
186
187   if(qual < 0 || qual > 100)
188     {
189       printf("Link quality out of range(0-100)\n");
190       return -1;
191     }
192
193   while(src)
194     {
195
196       while(dst)
197         {
198
199           if(src == dst)
200             goto next_iteration;
201
202           link = get_link(src, &dst->ip_addr);
203           
204           inv_link = bi ? get_link(dst, &src->ip_addr) : NULL;
205           
206           if(qual == 100)
207             {
208               /* Remove link entry */
209               if(link)
210                 remove_link(src, link);
211               if(inv_link)
212                 remove_link(dst, inv_link);
213             }
214           else 
215             {
216               if(!link)
217                 {
218                   /* Create new link */
219                   link = add_link(src, dst);
220                 }
221               
222               link->quality = qual;
223               
224               if(bi)
225                 {
226                   if(!inv_link)
227                     {
228                       /* Create new link */
229                       inv_link = add_link(dst, src);
230                     }
231                   inv_link->quality = qual;
232                 }
233             }
234
235           printf("%s %sdirectional link(s) %s %c=> %s quality %d\n", 
236                  (qual == 100) ? "Removing" : "Setting", bi ? "bi" : "uni",
237                  olsr_ip_to_string(&src->ip_addr), bi ? '<' : '=', 
238                  olsr_ip_to_string(&dst->ip_addr), qual);
239
240         next_iteration:
241           if(wildc_dst)
242             dst = dst->next;
243           else
244             break;
245         }
246       dst = wildc_dst ? ohs_conns : dst;
247       src = wildc_src ? src->next : NULL;
248     }
249
250   return 1;
251  print_usage:
252   printf("link <bi> srcIP dstIP [0-100]");
253   return -1;
254 }
255
256 int
257 ohs_cmd_list(FILE *handle, char *args)
258 {
259   struct ohs_connection *oc = ohs_conns;
260
261   args += get_next_token(args, tok_buf, TOK_BUF_SIZE);
262   
263   if(!strlen(tok_buf) || 
264      !strncmp(tok_buf, "clients", strlen("clients")))
265     {
266       printf("All connected clients:\n");
267       
268       while(oc)
269         {
270           printf("\t%s - Rx: %d Tx: %d LinkCnt: %d\n", olsr_ip_to_string(&oc->ip_addr), 
271                  oc->rx, oc->tx, oc->linkcnt);
272           oc = oc->next;
273         }
274     }
275   else if(!strncmp(tok_buf, "links", strlen("links")))
276     {
277       printf("All configured links:\n");
278       
279       while(oc)
280         {
281           struct ohs_ip_link *links = oc->links;
282
283           while(links)
284             {
285               printf("\t%s => %s Quality: %d\n", 
286                      olsr_ip_to_string(&oc->ip_addr),
287                      olsr_ip_to_string(&links->dst),
288                      links->quality);
289
290               links = links->next;
291             }
292           oc = oc->next;
293         }
294     }
295   else
296     {
297
298       printf("list [clients|links]");
299       return -1;
300     }
301
302   return 1;
303 }
304
305 int
306 ohs_cmd_help(FILE *handle, char *args)
307 {
308   int i;
309
310   args += get_next_token(args, tok_buf, TOK_BUF_SIZE);
311   
312   if(!strlen(tok_buf))
313     {
314       printf("Olsrd host switch version %s\n", OHS_VERSION);
315       printf("Available commands:\n");
316       
317       for(i = 0; ohs_commands[i].cmd; i++)
318         {
319           if(ohs_commands[i].helptext_brief)
320             printf("\t%s - %s\n", 
321                    ohs_commands[i].cmd,
322                    ohs_commands[i].helptext_brief);
323         }
324       printf("\nType 'help cmd' for help on a specific command\n");
325     }
326   else
327     {
328       for(i = 0; ohs_commands[i].cmd; i++)
329         {
330           if(!strncmp(tok_buf, ohs_commands[i].cmd, strlen(ohs_commands[i].cmd)))
331             {
332               printf("Usage: %s\nDescription:\n%s\n", 
333                      ohs_commands[i].syntax,
334                      ohs_commands[i].helptext_long);
335               return 1;
336             }
337         }
338
339       printf("Usage: help <command>\n");
340     }
341
342   return i;
343 }
344
345 int
346 ohs_cmd_log(FILE *handle, char *args)
347 {
348   olsr_u8_t set = 0;
349
350   args += get_next_token(args, tok_buf, TOK_BUF_SIZE);
351   
352   if(strlen(tok_buf) &&
353      ((set = !strncmp(tok_buf, "set", strlen("set"))) || 
354       !strncmp(tok_buf, "unset", strlen("unset"))))
355     {
356         olsr_u32_t new_bit = 0;
357         
358         args += get_next_token(args, tok_buf, TOK_BUF_SIZE);
359   
360         if(!strlen(tok_buf))
361             goto print_usage;
362         
363         
364         if(!strncmp(tok_buf, "CON", strlen("CON")))
365             new_bit = LOG_CONNECT;
366         else if(!strncmp(tok_buf, "FOR", strlen("FOR")))
367             new_bit = LOG_FORWARD;
368         else if(!strncmp(tok_buf, "LIN", strlen("LIN")))
369             new_bit = LOG_LINK;
370           
371         if(!new_bit)
372             goto print_usage;
373
374         if(set)
375             logbits |= new_bit;
376         else
377             logbits &= ~new_bit;
378
379         printf("%s log bit: 0x%08x, new log: 0x%08x\n", set ? "Setting" : "Removing",
380                new_bit, logbits);
381
382     }
383   else
384     {
385       if(strlen(tok_buf))
386         goto print_usage;
387
388       printf("Log: (0x%08x) ", logbits);
389       if(logbits & LOG_CONNECT)
390         printf("CONNECT ");
391       if(logbits & LOG_FORWARD)
392         printf("FORWARD ");
393       if(logbits & LOG_LINK)
394         printf("LINK ");
395
396       printf("\n");
397     }
398   return 1;
399
400  print_usage:
401   printf("Usage: log <[set|unset] [CONNECT|FORWARD|LINK]>\n");
402   return 0;
403
404 }
405
406 int
407 ohs_cmd_exit(FILE *handle, char *args)
408 {
409
410   printf("Exitting... bye-bye!\n");
411
412   ohs_close(0);
413   return 0;
414 }
415
416 int
417 ohs_parse_command(FILE *handle)
418 {
419   char input_data[100];
420   int i;
421
422   fscanf(handle, "%s", input_data);
423
424   get_arg_buf(handle, arg_buf, ARG_BUF_SIZE);
425
426   for(i = 0; ohs_commands[i].cmd; i++)
427     {
428       if(!strcmp(input_data, ohs_commands[i].cmd))
429         {
430           if(ohs_commands[i].cmd_cb)
431             {
432               ohs_commands[i].cmd_cb(handle, arg_buf);
433             }
434           else
435             {
436               printf("No action registered on cmd %s!\n", input_data);
437             }
438           break;
439         }
440     }
441   
442   if(!ohs_commands[i].cmd)
443     {
444       printf("%s: no such cmd!\n", input_data);
445     }
446
447
448   return 0;
449 }