3 * The olsr.org Optimized Link-State Routing daemon(olsrd)
4 * Copyright (c) 2004, Andreas Tonnesen(andreto@olsr.org)
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
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.
34 * Visit http://www.olsr.org for more information.
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.
48 #include "lq_packet.h"
55 #define perror(x) WinSockPError(x)
56 void WinSockPError(const char *);
59 struct deny_address_entry {
60 union olsr_ip_addr addr;
61 struct deny_address_entry *next;
64 /* Packet transform functions */
67 packet_transform_function function;
71 static struct ptf *ptf_list;
73 static struct deny_address_entry *deny_entries;
75 static const char *const deny_ipv4_defaults[] = {
81 static const char *const deny_ipv6_defaults[] = {
88 * Converts each invalid IP-address from string to network byte order
89 * and adds it to the invalid list.
91 * TODO: rename function
96 const char *const *defaults = (olsr_cnf->ip_version == AF_INET) ? deny_ipv4_defaults : deny_ipv6_defaults;
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);
104 olsr_add_invalid_address(&addr);
109 * Create an outputbuffer for the given interface. This
110 * function will allocate the needed storage according
111 * to the MTU of the interface.
113 * @param ifp the interface to create a buffer for
115 * @return 0 on success, negative if a buffer already existed
116 * for the given interface
119 net_add_buffer(struct interface_olsr *ifp)
121 /* Can the interfaces MTU actually change? If not, we can elimiate
122 * the "bufsize" field in "struct olsr_netbuf".
124 if (ifp->netbuf.bufsize != ifp->int_mtu && ifp->netbuf.buff != NULL) {
125 free(ifp->netbuf.buff);
126 ifp->netbuf.buff = NULL;
129 if (ifp->netbuf.buff == NULL) {
130 ifp->netbuf.buff = olsr_malloc(ifp->int_mtu, "add_netbuff");
134 ifp->netbuf.bufsize = ifp->int_mtu;
135 ifp->netbuf.maxsize = ifp->int_mtu - OLSR_HEADERSIZE;
137 ifp->netbuf.pending = 0;
138 ifp->netbuf.reserved = 0;
144 * Remove a outputbuffer. Frees the allocated memory.
146 * @param ifp the interface corresponding to the buffer
149 * @return 0 on success, negative if no buffer is found
152 net_remove_buffer(struct interface_olsr *ifp)
154 /* Flush pending data */
155 if (ifp->netbuf.pending)
158 free(ifp->netbuf.buff);
159 ifp->netbuf.buff = NULL;
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.
171 * @param ifp the interface corresponding to the buffer
172 * to reserve space on
173 * @param size the number of bytes to reserve
175 * @return 0 on success, negative if there was not enough
179 net_reserve_bufspace(struct interface_olsr *ifp, int size)
181 if (size > ifp->netbuf.maxsize)
184 ifp->netbuf.reserved = size;
185 ifp->netbuf.maxsize -= size;
191 * Returns the number of bytes pending in the buffer. That
192 * is the number of bytes added but not sent.
194 * @param ifp the interface corresponding to the buffer
196 * @return the number of bytes currently pending
199 net_output_pending(const struct interface_olsr * ifp)
201 return ifp->netbuf.pending;
205 * Add data to a buffer.
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
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
216 net_outbuffer_push(struct interface_olsr *ifp, const void *data, const uint16_t size)
218 if ((ifp->netbuf.pending + size) > ifp->netbuf.maxsize)
221 memcpy(&ifp->netbuf.buff[ifp->netbuf.pending + OLSR_HEADERSIZE], data, size);
222 ifp->netbuf.pending += size;
228 * Add data to the reserved part of a buffer
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
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
239 net_outbuffer_push_reserved(struct interface_olsr *ifp, const void *data, const uint16_t size)
241 if ((ifp->netbuf.pending + size) > (ifp->netbuf.maxsize + ifp->netbuf.reserved))
244 memcpy(&ifp->netbuf.buff[ifp->netbuf.pending + OLSR_HEADERSIZE], data, size);
245 ifp->netbuf.pending += size;
251 * Report the number of bytes currently available in the buffer
252 * (not including possible reserved bytes)
254 * @param ifp the interface corresponding to the buffer
256 * @return the number of bytes available in the buffer or
259 net_outbuffer_bytes_left(const struct interface_olsr *ifp)
261 /* IPv6 minimum MTU - IPv6 header - UDP header - VLAN-Tag */
262 static int MAX_REMAINING = 1280 - 40 - 8 - 4;
263 int remaining = ifp->netbuf.maxsize - ifp->netbuf.pending;
265 if (remaining > MAX_REMAINING) {
266 return MAX_REMAINING;
272 * Add a packet transform function. Theese are functions
273 * called just prior to sending data in a buffer.
275 * @param f the function pointer
280 add_ptf(packet_transform_function f)
285 new_ptf = olsr_malloc(sizeof(struct ptf), "Add PTF");
287 new_ptf->next = ptf_list;
288 new_ptf->function = f;
296 * Remove a packet transform function
298 * @param f the function pointer
300 * @returns 1 if a functionpointer was removed
304 del_ptf(packet_transform_function f)
306 struct ptf *prev = NULL;
307 struct ptf *tmp_ptf = ptf_list;
309 if (tmp_ptf->function == f) {
312 ptf_list = tmp_ptf->next;
314 prev->next = tmp_ptf->next;
319 tmp_ptf = tmp_ptf->next;
326 *Sends a packet on a given interface.
328 *@param ifp the interface to send on.
330 *@return negative on error
333 net_output(struct interface_olsr *ifp)
335 struct sockaddr_in *sin = NULL;
336 struct sockaddr_in6 *sin6 = NULL;
337 struct sockaddr_in dst;
338 struct sockaddr_in6 dst6;
339 struct ptf *tmp_ptf_list;
340 union olsr_packet *outmsg;
343 if (!ifp->netbuf.pending)
346 ifp->netbuf.pending += OLSR_HEADERSIZE;
348 retval = ifp->netbuf.pending;
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);
356 if (olsr_cnf->ip_version == AF_INET) {
358 sin = (struct sockaddr_in *)&ifp->int_broadaddr;
364 if (sin->sin_port == 0)
365 sin->sin_port = htons(olsr_cnf->olsrport);
368 sin6 = (struct sockaddr_in6 *)&ifp->int6_multaddr;
375 *Call possible packet transform functions registered by plugins
377 for (tmp_ptf_list = ptf_list; tmp_ptf_list != NULL; tmp_ptf_list = tmp_ptf_list->next) {
378 tmp_ptf_list->function(ifp->netbuf.buff, &ifp->netbuf.pending);
381 if (olsr_cnf->ip_version == AF_INET) {
383 if (olsr_sendto(ifp->send_socket, ifp->netbuf.buff, ifp->netbuf.pending, MSG_DONTROUTE, (struct sockaddr *)sin, sizeof(*sin)) <
385 perror("sendto(v4)");
387 olsr_syslog(OLSR_LOG_ERR, "OLSR: sendto IPv4 %m");
393 if (olsr_sendto(ifp->send_socket, ifp->netbuf.buff, ifp->netbuf.pending, MSG_DONTROUTE, (struct sockaddr *)sin6, sizeof(*sin6))
395 struct ipaddr_str buf;
396 perror("sendto(v6)");
398 olsr_syslog(OLSR_LOG_ERR, "OLSR: sendto IPv6 %m");
400 fprintf(stderr, "Socket: %d interface: %d\n", ifp->olsr_socket, ifp->if_index);
401 fprintf(stderr, "To: %s (size: %u)\n", ip6_to_string(&buf, &sin6->sin6_addr), (unsigned int)sizeof(*sin6));
402 fprintf(stderr, "Outputsize: %d\n", ifp->netbuf.pending);
407 ifp->netbuf.pending = 0;
410 * if we've just transmitted a TC message, let Dijkstra use the current
411 * link qualities for the links to our neighbours
414 lq_tc_pending = false;
420 * Adds the given IP-address to the invalid list.
423 olsr_add_invalid_address(const union olsr_ip_addr *adr)
425 struct ipaddr_str buf;
426 struct deny_address_entry *new_entry = olsr_malloc(sizeof(struct deny_address_entry), "Add deny address");
428 new_entry->addr = *adr;
429 new_entry->next = deny_entries;
430 deny_entries = new_entry;
431 OLSR_PRINTF(1, "Added %s to IP deny set\n", olsr_ip_to_string(&buf, &new_entry->addr));
435 olsr_validate_address(const union olsr_ip_addr *adr)
437 const struct deny_address_entry *deny_entry;
439 for (deny_entry = deny_entries; deny_entry != NULL; deny_entry = deny_entry->next) {
440 if (ipequal(adr, &deny_entry->addr)) {
441 struct ipaddr_str buf;
442 OLSR_PRINTF(1, "Validation of address %s failed!\n", olsr_ip_to_string(&buf, adr));
445 if (deny_entry == (struct deny_address_entry *)&olsr_cnf->main_addr)
454 * indent-tabs-mode: nil