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