2 * The olsr.org Optimized Link-State Routing daemon (olsrd)
4 * (c) by the OLSR project
6 * See our Git repository to find out who worked on this file
7 * and thus is a copyright holder on it.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
15 * * Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * * Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in
19 * the documentation and/or other materials provided with the
21 * * Neither the name of olsr.org, olsrd nor the names of its
22 * contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
38 * Visit http://www.olsr.org for more information.
40 * If you find this software useful feel free to make a donation
41 * to the project. For more information see the website or contact
42 * the copyright holders.
52 #include "lq_packet.h"
59 #define perror(x) WinSockPError(x)
60 void WinSockPError(const char *);
63 struct deny_address_entry {
64 union olsr_ip_addr addr;
65 struct deny_address_entry *next;
68 /* Packet transform functions */
71 packet_transform_function function;
75 static struct ptf *ptf_list;
77 static struct deny_address_entry *deny_entries;
79 static const char *const deny_ipv4_defaults[] = {
85 static const char *const deny_ipv6_defaults[] = {
92 * Converts each invalid IP-address from string to network byte order
93 * and adds it to the invalid list.
95 * TODO: rename function
100 const char *const *defaults = (olsr_cnf->ip_version == AF_INET) ? deny_ipv4_defaults : deny_ipv6_defaults;
102 for (; *defaults != NULL; defaults++) {
103 union olsr_ip_addr addr;
104 if (inet_pton(olsr_cnf->ip_version, *defaults, &addr) <= 0) {
105 fprintf(stderr, "Error converting fixed IP %s for deny rule!!\n", *defaults);
108 olsr_add_invalid_address(&addr);
113 * Create an outputbuffer for the given interface. This
114 * function will allocate the needed storage according
115 * to the MTU of the interface.
117 * @param ifp the interface to create a buffer for
119 * @return 0 on success, negative if a buffer already existed
120 * for the given interface
123 net_add_buffer(struct interface_olsr *ifp)
125 /* Can the interfaces MTU actually change? If not, we can elimiate
126 * the "bufsize" field in "struct olsr_netbuf".
128 if (ifp->netbuf.bufsize != ifp->int_mtu && ifp->netbuf.buff != NULL) {
129 free(ifp->netbuf.buff);
130 ifp->netbuf.buff = NULL;
133 if (ifp->netbuf.buff == NULL) {
134 ifp->netbuf.buff = olsr_malloc(ifp->int_mtu, "add_netbuff");
138 ifp->netbuf.bufsize = ifp->int_mtu;
139 ifp->netbuf.maxsize = ifp->int_mtu - OLSR_HEADERSIZE;
141 ifp->netbuf.pending = 0;
142 ifp->netbuf.reserved = 0;
148 * Remove a outputbuffer. Frees the allocated memory.
150 * @param ifp the interface corresponding to the buffer
153 * @return 0 on success, negative if no buffer is found
156 net_remove_buffer(struct interface_olsr *ifp)
158 /* Flush pending data */
159 if (ifp->netbuf.pending)
162 free(ifp->netbuf.buff);
163 ifp->netbuf.buff = NULL;
169 * Reserve space in a outputbuffer. This should only be needed
170 * in very special cases. This will decrease the reported size
171 * of the buffer so that there is always <i>size</i> bytes
172 * of data available in the buffer. To add data in the reserved
173 * area one must use the net_outbuffer_push_reserved function.
175 * @param ifp the interface corresponding to the buffer
176 * to reserve space on
177 * @param size the number of bytes to reserve
179 * @return 0 on success, negative if there was not enough
183 net_reserve_bufspace(struct interface_olsr *ifp, int size)
185 if (size > ifp->netbuf.maxsize)
188 ifp->netbuf.reserved = size;
189 ifp->netbuf.maxsize -= size;
195 * Returns the number of bytes pending in the buffer. That
196 * is the number of bytes added but not sent.
198 * @param ifp the interface corresponding to the buffer
200 * @return the number of bytes currently pending
203 net_output_pending(const struct interface_olsr * ifp)
205 return ifp->netbuf.pending;
209 * Add data to a buffer.
211 * @param ifp the interface corresponding to the buffer
212 * @param data a pointer to the data to add
213 * @param size the number of byte to copy from data
215 * @return -1 if no buffer was found, 0 if there was not
216 * enough room in buffer or the number of bytes added on
220 net_outbuffer_push(struct interface_olsr *ifp, const void *data, const uint16_t size)
222 if ((ifp->netbuf.pending + size) > ifp->netbuf.maxsize)
225 memcpy(&ifp->netbuf.buff[ifp->netbuf.pending + OLSR_HEADERSIZE], data, size);
226 ifp->netbuf.pending += size;
232 * Add data to the reserved part of a buffer
234 * @param ifp the interface corresponding to the buffer
235 * @param data a pointer to the data to add
236 * @param size the number of byte to copy from data
238 * @return -1 if no buffer was found, 0 if there was not
239 * enough room in buffer or the number of bytes added on
243 net_outbuffer_push_reserved(struct interface_olsr *ifp, const void *data, const uint16_t size)
245 if ((ifp->netbuf.pending + size) > (ifp->netbuf.maxsize + ifp->netbuf.reserved))
248 memcpy(&ifp->netbuf.buff[ifp->netbuf.pending + OLSR_HEADERSIZE], data, size);
249 ifp->netbuf.pending += size;
255 * Report the number of bytes currently available in the buffer
256 * (not including possible reserved bytes)
258 * @param ifp the interface corresponding to the buffer
260 * @return the number of bytes available in the buffer or
263 net_outbuffer_bytes_left(const struct interface_olsr *ifp)
265 /* IPv6 minimum MTU - IPv6 header - UDP header - VLAN-Tag */
266 static int MAX_REMAINING = 1280 - 40 - 8 - 4;
267 int remaining = ifp->netbuf.maxsize - ifp->netbuf.pending;
269 if (remaining > MAX_REMAINING) {
270 return MAX_REMAINING;
276 * Add a packet transform function. Theese are functions
277 * called just prior to sending data in a buffer.
279 * @param f the function pointer
284 add_ptf(packet_transform_function f)
289 new_ptf = olsr_malloc(sizeof(struct ptf), "Add PTF");
291 new_ptf->next = ptf_list;
292 new_ptf->function = f;
300 * Remove a packet transform function
302 * @param f the function pointer
304 * @returns 1 if a functionpointer was removed
308 del_ptf(packet_transform_function f)
310 struct ptf *prev = NULL;
311 struct ptf *tmp_ptf = ptf_list;
313 if (tmp_ptf->function == f) {
316 ptf_list = tmp_ptf->next;
318 prev->next = tmp_ptf->next;
323 tmp_ptf = tmp_ptf->next;
330 *Sends a packet on a given interface.
332 *@param ifp the interface to send on.
334 *@return negative on error
337 net_output(struct interface_olsr *ifp)
339 struct sockaddr_in *sin = NULL;
340 struct sockaddr_in6 *sin6 = NULL;
341 struct sockaddr_in dst;
342 struct sockaddr_in6 dst6;
343 struct ptf *tmp_ptf_list;
344 union olsr_packet *outmsg;
347 if (!ifp->netbuf.pending)
350 ifp->netbuf.pending += OLSR_HEADERSIZE;
352 retval = ifp->netbuf.pending;
354 outmsg = (union olsr_packet *)ifp->netbuf.buff;
355 /* Add the Packet seqno */
356 outmsg->v4.olsr_seqno = htons(ifp->olsr_seqnum++);
357 /* Set the packetlength */
358 outmsg->v4.olsr_packlen = htons(ifp->netbuf.pending);
360 if (olsr_cnf->ip_version == AF_INET) {
362 sin = (struct sockaddr_in *)&ifp->int_broadaddr;
368 if (sin->sin_port == 0)
369 sin->sin_port = htons(olsr_cnf->olsrport);
372 sin6 = (struct sockaddr_in6 *)&ifp->int6_multaddr;
379 *Call possible packet transform functions registered by plugins
381 for (tmp_ptf_list = ptf_list; tmp_ptf_list != NULL; tmp_ptf_list = tmp_ptf_list->next) {
382 tmp_ptf_list->function(ifp->netbuf.buff, &ifp->netbuf.pending);
385 if (olsr_cnf->ip_version == AF_INET) {
387 if (olsr_sendto(ifp->send_socket, ifp->netbuf.buff, ifp->netbuf.pending, MSG_DONTROUTE, (struct sockaddr *)sin, sizeof(*sin)) <
389 perror("sendto(v4)");
391 olsr_syslog(OLSR_LOG_ERR, "OLSR: sendto IPv4 '%s' on interface %s", strerror(errno), ifp->int_name);
397 if (olsr_sendto(ifp->send_socket, ifp->netbuf.buff, ifp->netbuf.pending, MSG_DONTROUTE, (struct sockaddr *)sin6, sizeof(*sin6))
399 struct ipaddr_str buf;
400 perror("sendto(v6)");
402 olsr_syslog(OLSR_LOG_ERR, "OLSR: sendto IPv6 '%s' on interface %s", strerror(errno), ifp->int_name);
404 fprintf(stderr, "Socket: %d interface: %d\n", ifp->olsr_socket, ifp->if_index);
405 fprintf(stderr, "To: %s (size: %u)\n", ip6_to_string(&buf, &sin6->sin6_addr), (unsigned int)sizeof(*sin6));
406 fprintf(stderr, "Outputsize: %d\n", ifp->netbuf.pending);
411 ifp->netbuf.pending = 0;
414 * if we've just transmitted a TC message, let Dijkstra use the current
415 * link qualities for the links to our neighbours
418 lq_tc_pending = false;
424 * Adds the given IP-address to the invalid list.
427 olsr_add_invalid_address(const union olsr_ip_addr *adr)
429 struct ipaddr_str buf;
430 struct deny_address_entry *new_entry = olsr_malloc(sizeof(struct deny_address_entry), "Add deny address");
432 new_entry->addr = *adr;
433 new_entry->next = deny_entries;
434 deny_entries = new_entry;
435 OLSR_PRINTF(1, "Added %s to IP deny set\n", olsr_ip_to_string(&buf, &new_entry->addr));
439 olsr_validate_address(const union olsr_ip_addr *adr)
441 const struct deny_address_entry *deny_entry;
443 for (deny_entry = deny_entries; deny_entry != NULL; deny_entry = deny_entry->next) {
444 if (ipequal(adr, &deny_entry->addr)) {
445 struct ipaddr_str buf;
446 OLSR_PRINTF(1, "Validation of address %s failed!\n", olsr_ip_to_string(&buf, adr));
449 if (&deny_entry->addr == &olsr_cnf->main_addr)
458 * indent-tabs-mode: nil