3 * OLSR ad-hoc routing table management protocol
4 * Copyright (C) 2003 Andreas Tønnesen (andreto@ifi.uio.no)
6 * This file is part of the olsr.org OLSR daemon.
8 * olsr.org is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * olsr.org is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with olsr.org; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
30 #define perror(x) WinSockPError(x)
32 WinSockPError(char *);
45 *Sends a packet on a given interface.
47 *@param ifp the interface to send on.
49 *@return negative on error
52 net_output(struct interface *ifp)
54 struct sockaddr_in *sin;
55 struct sockaddr_in dst;
56 struct sockaddr_in6 *sin6;
57 struct sockaddr_in6 dst6;
58 struct ptf *tmp_ptf_list;
67 /* Add the Packet seqno */
68 ((struct olsr*)packet)->olsr_seqno = htons(ifp->olsr_seqnum++);
69 /* Set the packetlength */
70 #warning 0.4.8 net_output now sets packetsize itself
71 ((struct olsr*)packet)->olsr_packlen = htons(outputsize);
73 if(ipversion == AF_INET)
76 sin = (struct sockaddr_in *)&ifp->int_broadaddr;
82 /* Set user defined broadcastaddr */
84 memcpy(&dst.sin_addr.s_addr, &bcastaddr.sin_addr, sizeof(olsr_u32_t));
86 if (sin->sin_port == 0)
87 sin->sin_port = olsr_udp_port;
92 sin6 = (struct sockaddr_in6 *)&ifp->int6_multaddr;
99 *if the '-disp- option was given
100 *we print her decimal contetnt of the packets
107 case(HELLO_MESSAGE):printf("\n\tHELLO ");break;
108 case(TC_MESSAGE):printf("\n\tTC ");break;
109 case(MID_MESSAGE):printf("\n\tMID ");break;
110 case(HNA_MESSAGE):printf("\n\tHNA ");break;
112 if(ipversion == AF_INET)
113 printf("to %s size: %d\n\t", ip_to_string(&sin->sin_addr.s_addr), outputsize);
115 printf("to %s size: %d\n\t", ip6_to_string(&sin6->sin6_addr), outputsize);
119 for(i = 0; i < outputsize;i++)
127 if(ipversion == AF_INET)
128 printf(" %3i", (u_char) packet[i]);
130 printf(" %2x", (u_char) packet[i]);
138 *Call possible packet transform functions registered by plugins
140 tmp_ptf_list = ptf_list;
141 while(tmp_ptf_list != NULL)
143 tmp_ptf_list->function(packet, &outputsize);
144 tmp_ptf_list = tmp_ptf_list->next;
148 *if the '-disp- option was given
149 *we print her decimal contetnt of the packets
155 case(HELLO_MESSAGE):printf("\n\tHELLO ");break;
156 case(TC_MESSAGE):printf("\n\tTC ");break;
157 case(MID_MESSAGE):printf("\n\tMID ");break;
158 case(HNA_MESSAGE):printf("\n\tHNA ");break;
159 default:printf("\n\tTYPE: %d ", packet[4]); break;
161 if(ipversion == AF_INET)
162 printf("to %s size: %d\n\t", ip_to_string((olsr_u32_t *)&sin->sin_addr.s_addr), outputsize);
164 printf("to %s size: %d\n\t", ip6_to_string(&sin6->sin6_addr), outputsize);
168 for(i = 0; i < outputsize;i++)
176 if(ipversion == AF_INET)
177 printf(" %3i", (u_char) packet[i]);
179 printf(" %2x", (u_char) packet[i]);
186 *packet points to the same memory area as the *msg pointer
187 *used when building packets.
190 if(ipversion == AF_INET)
193 if(sendto(ifp->olsr_socket, packet, outputsize, MSG_DONTROUTE, (struct sockaddr *)sin, sizeof (*sin)) < 0)
195 perror("sendto(v4)");
196 olsr_syslog(OLSR_LOG_ERR, "OLSR: sendto IPv4 %m");
204 if(sendto(ifp->olsr_socket, packet, outputsize, MSG_DONTROUTE, (struct sockaddr *)sin6, sizeof (*sin6)) < 0)
206 perror("sendto(v6)");
207 olsr_syslog(OLSR_LOG_ERR, "OLSR: sendto IPv6 %m");
208 fprintf(stderr, "Socket: %d interface: %d\n", ifp->olsr_socket, ifp->if_nr);
209 fprintf(stderr, "To: %s (size: %d)\n", ip6_to_string(&sin6->sin6_addr), sizeof(*sin6));
210 fprintf(stderr, "Outputsize: %d\n", outputsize);
227 *Forward a message on all interfaces
229 *@return negative on error
234 struct sockaddr_in *sin;
235 struct sockaddr_in dst;
236 struct sockaddr_in6 *sin6;
237 struct sockaddr_in6 dst6;
238 struct interface *ifn;
239 struct ptf *tmp_ptf_list;
245 for (ifn = ifnet; ifn; ifn = ifn->int_next)
248 /* Add the Packet seqno */
249 ((struct olsr*)fwd_packet)->olsr_seqno = htons(ifn->olsr_seqnum++);
250 /* Set the packetlength */
251 #warning 0.4.8 net_forward now sets packetsize itself
252 ((struct olsr*)fwd_packet)->olsr_packlen = htons(fwdsize);
254 if(ipversion == AF_INET)
257 sin = (struct sockaddr_in *)&ifn->int_broadaddr;
263 /* Set user defined broadcastaddr */
265 memcpy(&dst.sin_addr.s_addr, &bcastaddr.sin_addr, sizeof(olsr_u32_t));
267 if (sin->sin_port == 0)
268 sin->sin_port = olsr_udp_port;
273 sin6 = (struct sockaddr_in6 *)&ifn->int6_multaddr;
280 *if the '-disp- option was given
281 *we print her decimal contetnt of the packets
285 if(ipversion == AF_INET)
286 printf("FORWARDING to %s size: %d\n\t", ip_to_string((olsr_u32_t *)&sin->sin_addr.s_addr), fwdsize);
288 printf("FORWARDING to %s size: %d\n\t", ip6_to_string(&sin6->sin6_addr), fwdsize);
292 for(i = 0; i < fwdsize;i++)
300 if(ipversion == AF_INET)
301 printf(" %3i", (u_char) fwd_packet[i]);
303 printf(" %2x", (u_char) fwd_packet[i]);
311 *Call possible packet transform functions registered by plugins
313 tmp_ptf_list = ptf_list;
314 while(tmp_ptf_list != NULL)
316 tmp_ptf_list->function(fwd_packet, &fwdsize);
317 tmp_ptf_list = tmp_ptf_list->next;
321 if(ipversion == AF_INET)
324 if(sendto(ifn->olsr_socket, fwd_packet, fwdsize, MSG_DONTROUTE, (struct sockaddr *)sin, sizeof (*sin)) < 0)
326 perror("sendto(v4)");
327 olsr_syslog(OLSR_LOG_ERR, "OLSR: forward sendto IPv4 %m");
334 if(sendto(ifn->olsr_socket, fwd_packet, fwdsize, MSG_DONTROUTE, (struct sockaddr *)sin6, sizeof (*sin6)) < 0)
336 perror("sendto(v6)");
337 olsr_syslog(OLSR_LOG_ERR, "OLSR: forward sendto IPv6 %m");
338 fprintf(stderr, "Socket: %d interface: %d\n", ifn->olsr_socket, ifn->if_nr);
339 fprintf(stderr, "To: %s (size: %d)\n", ip6_to_string(&sin6->sin6_addr), sizeof(*sin6));
340 fprintf(stderr, "Outputsize: %d\n", fwdsize);
350 * Add a packet transform function
353 add_ptf(int (*f)(char *, int *))
358 new_ptf = olsr_malloc(sizeof(struct ptf), "Add PTF");
360 new_ptf->next = ptf_list;
361 new_ptf->function = f;
369 * Remove a packet transform function
372 del_ptf(int (*f)(char *, int *))
374 struct ptf *tmp_ptf, *prev;
381 if(tmp_ptf->function == f)
386 ptf_list = tmp_ptf->next;
391 prev->next = tmp_ptf->next;
397 tmp_ptf = tmp_ptf->next;
405 join_mcast(struct interface *ifs, int sock)
407 /* See linux/in6.h */
409 struct ipv6_mreq mcastreq;
411 COPY_IP(&mcastreq.ipv6mr_multiaddr, &ifs->int6_multaddr.sin6_addr);
412 mcastreq.ipv6mr_interface = ifs->if_index;
414 olsr_printf(3, "Interface %s joining multicast %s...", ifs->int_name, olsr_ip_to_string((union olsr_ip_addr *)&ifs->int6_multaddr.sin6_addr));
420 sizeof(struct ipv6_mreq))
423 perror("Join multicast");
428 /* Join reciever group */
433 sizeof(struct ipv6_mreq))
436 perror("Join multicast send");
444 (char *)&mcastreq.ipv6mr_interface,
445 sizeof(mcastreq.ipv6mr_interface))
448 perror("Set multicast if");
453 olsr_printf(3, "OK\n");
459 * Create a IPv6 netmask based on a prefix length
463 olsr_prefix_to_netmask(union olsr_ip_addr *adr, olsr_u16_t prefix)
473 memset(adr, 0, ipsize);
477 adr->v6.s6_addr[i] = (p < 8) ? 0xff ^ (0xff << p) : 0xff;
482 olsr_printf(3, "Prefix %d = Netmask: %s\n", prefix, olsr_ip_to_string(adr));
491 * Calculate prefix length based on a netmask
495 olsr_netmask_to_prefix(union olsr_ip_addr *adr)
502 memset(adr, 0, ipsize);
504 for(i = 0; i < 16; i++)
506 if(adr->v6.s6_addr[i] == 0xff)
512 for(tmp = adr->v6.s6_addr[i];
520 olsr_printf(3, "Netmask: %s = Prefix %d\n", olsr_ip_to_string(adr), prefix);
529 *Converts a sockaddr struct to a string representing
530 *the IP address from the sockaddr struct
532 *<b>NON REENTRANT!!!!</b>
534 *@param address_to_convert the sockaddr struct to "convert"
535 *@return a char pointer to the string containing the IP
538 sockaddr_to_string(struct sockaddr *address_to_convert)
540 struct sockaddr_in *address;
542 address=(struct sockaddr_in *)address_to_convert;
543 return(inet_ntoa(address->sin_addr));
549 *Converts the 32bit olsr_u32_t datatype to
552 *<b>NON REENTRANT!!!!</b>
554 *@param address the olsr_u32_t to "convert"
555 *@return a char pointer to the string containing the IP
559 ip_to_string(olsr_u32_t *address)
564 return(inet_ntoa(in));
572 *Converts the 32bit olsr_u32_t datatype to
575 *<b>NON REENTRANT!!!!</b>
577 *@param addr6 the address to "convert"
578 *@return a char pointer to the string containing the IP
582 ip6_to_string(struct in6_addr *addr6)
584 return (char *)inet_ntop(AF_INET6, addr6, ipv6_buf, sizeof(ipv6_buf));
589 olsr_ip_to_string(union olsr_ip_addr *addr)
595 if(ipversion == AF_INET)
603 ret = (char *)inet_ntop(AF_INET6, &addr->v6, ipv6_buf, sizeof(ipv6_buf));