Use two sockets, one for input and one for output bound to the outgoing IP.
[olsrd.git] / src / net_olsr.c
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon(olsrd)
4  * Copyright (c) 2004, Andreas Tonnesen(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  */
41
42 #include "net_olsr.h"
43 #include "ipcalc.h"
44 #include "log.h"
45 #include "olsr.h"
46 #include "net_os.h"
47 #include "print_packet.h"
48 #include "link_set.h"
49 #include "lq_packet.h"
50
51 #include <stdlib.h>
52 #include <assert.h>
53 #include <limits.h>
54
55 static bool disp_pack_out = false;
56
57 #ifdef WIN32
58 #define perror(x) WinSockPError(x)
59 void WinSockPError(const char *);
60 #endif
61
62 struct deny_address_entry {
63   union olsr_ip_addr addr;
64   struct deny_address_entry *next;
65 };
66
67 /* Packet transform functions */
68
69 struct ptf {
70   packet_transform_function function;
71   struct ptf *next;
72 };
73
74 static struct ptf *ptf_list;
75
76 static struct deny_address_entry *deny_entries;
77
78 static const char *const deny_ipv4_defaults[] = {
79   "0.0.0.0",
80   "127.0.0.1",
81   NULL
82 };
83
84 static const char *const deny_ipv6_defaults[] = {
85   "0::0",
86   "0::1",
87   NULL
88 };
89
90 void
91 net_set_disp_pack_out(bool val)
92 {
93   disp_pack_out = val;
94 }
95
96 /*
97  * Converts each invalid IP-address from string to network byte order
98  * and adds it to the invalid list.
99  *
100  * TODO: rename function
101  */
102 void
103 init_net(void)
104 {
105   const char *const *defaults = (olsr_cnf->ip_version == AF_INET) ? deny_ipv4_defaults : deny_ipv6_defaults;
106
107   for (; *defaults != NULL; defaults++) {
108     union olsr_ip_addr addr;
109     if (inet_pton(olsr_cnf->ip_version, *defaults, &addr) <= 0) {
110       fprintf(stderr, "Error converting fixed IP %s for deny rule!!\n", *defaults);
111       continue;
112     }
113     olsr_add_invalid_address(&addr);
114   }
115 }
116
117 /**
118  * Create an outputbuffer for the given interface. This
119  * function will allocate the needed storage according
120  * to the MTU of the interface.
121  *
122  * @param ifp the interface to create a buffer for
123  *
124  * @return 0 on success, negative if a buffer already existed
125  *  for the given interface
126  */
127 int
128 net_add_buffer(struct interface *ifp)
129 {
130   /* Can the interfaces MTU actually change? If not, we can elimiate
131    * the "bufsize" field in "struct olsr_netbuf".
132    */
133   if (ifp->netbuf.bufsize != ifp->int_mtu && ifp->netbuf.buff != NULL) {
134     free(ifp->netbuf.buff);
135     ifp->netbuf.buff = NULL;
136   }
137
138   if (ifp->netbuf.buff == NULL) {
139     ifp->netbuf.buff = olsr_malloc(ifp->int_mtu, "add_netbuff");
140   }
141
142   /* Fill struct */
143   ifp->netbuf.bufsize = ifp->int_mtu;
144   ifp->netbuf.maxsize = ifp->int_mtu - OLSR_HEADERSIZE;
145
146   ifp->netbuf.pending = 0;
147   ifp->netbuf.reserved = 0;
148
149   return 0;
150 }
151
152 /**
153  * Remove a outputbuffer. Frees the allocated memory.
154  *
155  * @param ifp the interface corresponding to the buffer
156  * to remove
157  *
158  * @return 0 on success, negative if no buffer is found
159  */
160 int
161 net_remove_buffer(struct interface *ifp)
162 {
163   /* Flush pending data */
164   if (ifp->netbuf.pending)
165     net_output(ifp);
166
167   free(ifp->netbuf.buff);
168   ifp->netbuf.buff = NULL;
169
170   return 0;
171 }
172
173 /**
174  * Reserve space in a outputbuffer. This should only be needed
175  * in very special cases. This will decrease the reported size
176  * of the buffer so that there is always <i>size</i> bytes
177  * of data available in the buffer. To add data in the reserved
178  * area one must use the net_outbuffer_push_reserved function.
179  *
180  * @param ifp the interface corresponding to the buffer
181  * to reserve space on
182  * @param size the number of bytes to reserve
183  *
184  * @return 0 on success, negative if there was not enough
185  *  bytes to reserve
186  */
187 int
188 net_reserve_bufspace(struct interface *ifp, int size)
189 {
190   if (size > ifp->netbuf.maxsize)
191     return -1;
192
193   ifp->netbuf.reserved = size;
194   ifp->netbuf.maxsize -= size;
195
196   return 0;
197 }
198
199 /**
200  * Returns the number of bytes pending in the buffer. That
201  * is the number of bytes added but not sent.
202  *
203  * @param ifp the interface corresponding to the buffer
204  *
205  * @return the number of bytes currently pending
206  */
207 uint16_t
208 net_output_pending(const struct interface * ifp)
209 {
210   return ifp->netbuf.pending;
211 }
212
213 /**
214  * Add data to a buffer.
215  *
216  * @param ifp the interface corresponding to the buffer
217  * @param data a pointer to the data to add
218  * @param size the number of byte to copy from data
219  *
220  * @return -1 if no buffer was found, 0 if there was not
221  *  enough room in buffer or the number of bytes added on
222  *  success
223  */
224 int
225 net_outbuffer_push(struct interface *ifp, const void *data, const uint16_t size)
226 {
227   if ((ifp->netbuf.pending + size) > ifp->netbuf.maxsize)
228     return 0;
229
230   memcpy(&ifp->netbuf.buff[ifp->netbuf.pending + OLSR_HEADERSIZE], data, size);
231   ifp->netbuf.pending += size;
232
233   return size;
234 }
235
236 /**
237  * Add data to the reserved part of a buffer
238  *
239  * @param ifp the interface corresponding to the buffer
240  * @param data a pointer to the data to add
241  * @param size the number of byte to copy from data
242  *
243  * @return -1 if no buffer was found, 0 if there was not
244  *  enough room in buffer or the number of bytes added on
245  *  success
246  */
247 int
248 net_outbuffer_push_reserved(struct interface *ifp, const void *data, const uint16_t size)
249 {
250   if ((ifp->netbuf.pending + size) > (ifp->netbuf.maxsize + ifp->netbuf.reserved))
251     return 0;
252
253   memcpy(&ifp->netbuf.buff[ifp->netbuf.pending + OLSR_HEADERSIZE], data, size);
254   ifp->netbuf.pending += size;
255
256   return size;
257 }
258
259 /**
260  * Report the number of bytes currently available in the buffer
261  * (not including possible reserved bytes)
262  *
263  * @param ifp the interface corresponding to the buffer
264  *
265  * @return the number of bytes available in the buffer or
266  */
267 int
268 net_outbuffer_bytes_left(const struct interface *ifp)
269 {
270   return ifp->netbuf.maxsize - ifp->netbuf.pending;
271 }
272
273 /**
274  * Add a packet transform function. Theese are functions
275  * called just prior to sending data in a buffer.
276  *
277  * @param f the function pointer
278  *
279  * @returns 1
280  */
281 int
282 add_ptf(packet_transform_function f)
283 {
284
285   struct ptf *new_ptf;
286
287   new_ptf = olsr_malloc(sizeof(struct ptf), "Add PTF");
288
289   new_ptf->next = ptf_list;
290   new_ptf->function = f;
291
292   ptf_list = new_ptf;
293
294   return 1;
295 }
296
297 /**
298  * Remove a packet transform function
299  *
300  * @param f the function pointer
301  *
302  * @returns 1 if a functionpointer was removed
303  *  0 if not
304  */
305 int
306 del_ptf(packet_transform_function f)
307 {
308   struct ptf *prev = NULL;
309   struct ptf *tmp_ptf = ptf_list;
310   while (tmp_ptf) {
311     if (tmp_ptf->function == f) {
312       /* Remove entry */
313       if (prev == NULL)
314         ptf_list = tmp_ptf->next;
315       else
316         prev->next = tmp_ptf->next;
317       free(tmp_ptf);
318       return 1;
319     }
320     prev = tmp_ptf;
321     tmp_ptf = tmp_ptf->next;
322   }
323
324   return 0;
325 }
326
327 /**
328  *Sends a packet on a given interface.
329  *
330  *@param ifp the interface to send on.
331  *
332  *@return negative on error
333  */
334 int
335 net_output(struct interface *ifp)
336 {
337   struct sockaddr_in *sin = NULL;
338   struct sockaddr_in6 *sin6 = NULL;
339   struct ptf *tmp_ptf_list;
340   union olsr_packet *outmsg;
341   int retval;
342
343   if (!ifp->netbuf.pending)
344     return 0;
345
346   ifp->netbuf.pending += OLSR_HEADERSIZE;
347
348   retval = ifp->netbuf.pending;
349
350   outmsg = (union olsr_packet *)ifp->netbuf.buff;
351   /* Add the Packet seqno */
352   outmsg->v4.olsr_seqno = htons(ifp->olsr_seqnum++);
353   /* Set the packetlength */
354   outmsg->v4.olsr_packlen = htons(ifp->netbuf.pending);
355
356   if (olsr_cnf->ip_version == AF_INET) {
357     struct sockaddr_in dst;
358     /* IP version 4 */
359     sin = (struct sockaddr_in *)&ifp->int_broadaddr;
360
361     /* Copy sin */
362     dst = *sin;
363     sin = &dst;
364
365     if (sin->sin_port == 0)
366       sin->sin_port = htons(olsr_cnf->olsrport);
367   } else {
368     struct sockaddr_in6 dst6;
369     /* IP version 6 */
370     sin6 = (struct sockaddr_in6 *)&ifp->int6_multaddr;
371     /* Copy sin */
372     dst6 = *sin6;
373     sin6 = &dst6;
374   }
375
376   /*
377    *Call possible packet transform functions registered by plugins
378    */
379   for (tmp_ptf_list = ptf_list; tmp_ptf_list != NULL; tmp_ptf_list = tmp_ptf_list->next) {
380     tmp_ptf_list->function(ifp->netbuf.buff, &ifp->netbuf.pending);
381   }
382
383   /*
384    *if the -dispout option was given
385    *we print the content of the packets
386    */
387   if (disp_pack_out)
388     print_olsr_serialized_packet(stdout, (union olsr_packet *)ifp->netbuf.buff, ifp->netbuf.pending, &ifp->ip_addr);
389
390   if (olsr_cnf->ip_version == AF_INET) {
391     /* IP version 4 */
392     if (olsr_sendto(ifp->send_socket, ifp->netbuf.buff, ifp->netbuf.pending, MSG_DONTROUTE, (struct sockaddr *)sin, sizeof(*sin)) <
393         0) {
394       perror("sendto(v4)");
395       olsr_syslog(OLSR_LOG_ERR, "OLSR: sendto IPv4 %m");
396       retval = -1;
397     }
398   } else {
399     /* IP version 6 */
400     if (olsr_sendto(ifp->send_socket, ifp->netbuf.buff, ifp->netbuf.pending, MSG_DONTROUTE, (struct sockaddr *)sin6, sizeof(*sin6))
401         < 0) {
402       struct ipaddr_str buf;
403       perror("sendto(v6)");
404       olsr_syslog(OLSR_LOG_ERR, "OLSR: sendto IPv6 %m");
405       fprintf(stderr, "Socket: %d interface: %d\n", ifp->olsr_socket, ifp->if_index);
406       fprintf(stderr, "To: %s (size: %u)\n", ip6_to_string(&buf, &sin6->sin6_addr), (unsigned int)sizeof(*sin6));
407       fprintf(stderr, "Outputsize: %d\n", ifp->netbuf.pending);
408       retval = -1;
409     }
410   }
411
412   ifp->netbuf.pending = 0;
413
414   /*
415    * if we've just transmitted a TC message, let Dijkstra use the current
416    * link qualities for the links to our neighbours
417    */
418
419   lq_tc_pending = false;
420
421   return retval;
422 }
423
424 /*
425  * Adds the given IP-address to the invalid list.
426  */
427 void
428 olsr_add_invalid_address(const union olsr_ip_addr *adr)
429 {
430   struct ipaddr_str buf;
431   struct deny_address_entry *new_entry = olsr_malloc(sizeof(struct deny_address_entry), "Add deny address");
432
433   new_entry->addr = *adr;
434   new_entry->next = deny_entries;
435   deny_entries = new_entry;
436   OLSR_PRINTF(1, "Added %s to IP deny set\n", olsr_ip_to_string(&buf, &new_entry->addr));
437 }
438
439 bool
440 olsr_validate_address(const union olsr_ip_addr *adr)
441 {
442   const struct deny_address_entry *deny_entry;
443
444   for (deny_entry = deny_entries; deny_entry != NULL; deny_entry = deny_entry->next) {
445     if (ipequal(adr, &deny_entry->addr)) {
446       struct ipaddr_str buf;
447       OLSR_PRINTF(1, "Validation of address %s failed!\n", olsr_ip_to_string(&buf, adr));
448       return false;
449     }
450     if (deny_entry == (struct deny_address_entry *)&olsr_cnf->main_addr)
451       break;
452   }
453   return true;
454 }
455
456 /*
457  * Local Variables:
458  * c-basic-offset: 2
459  * indent-tabs-mode: nil
460  * End:
461  */