⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 net_olsr.c

📁 wifi 无线网络路由协议OLSR linux下C代码
💻 C
字号:
/* * The olsr.org Optimized Link-State Routing daemon(olsrd) * Copyright (c) 2004, Andreas T鴑nesen(andreto@olsr.org) * All rights reserved. * * Redistribution and use in source and binary forms, with or without  * modification, are permitted provided that the following conditions  * are met: * * * Redistributions of source code must retain the above copyright  *   notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright  *   notice, this list of conditions and the following disclaimer in  *   the documentation and/or other materials provided with the  *   distribution. * * Neither the name of olsr.org, olsrd nor the names of its  *   contributors may be used to endorse or promote products derived  *   from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE  * POSSIBILITY OF SUCH DAMAGE. * * Visit http://www.olsr.org for more information. * * If you find this software useful feel free to make a donation * to the project. For more information see the website or contact * the copyright holders. * * $Id: net_olsr.c,v 1.30 2007/09/16 21:20:16 bernd67 Exp $ */#include "net_olsr.h"#include "log.h"#include "olsr.h"#include "net_os.h"#include "print_packet.h"#include "link_set.h"#include "lq_packet.h"#include <stdlib.h>#include <assert.h>static olsr_bool disp_pack_out = OLSR_FALSE;#ifdef WIN32#define perror(x) WinSockPError(x)voidWinSockPError(char *);#endifstruct deny_address_entry{  union olsr_ip_addr        addr;  struct deny_address_entry *next;};/* Packet transform functions */struct ptf{  packet_transform_function function;  struct ptf *next;};static struct ptf *ptf_list;static struct deny_address_entry *deny_entries;static const char * const deny_ipv4_defaults[] =  {    "0.0.0.0",    "127.0.0.1",    NULL  };static const char * const deny_ipv6_defaults[] =  {    "0::0",    "0::1",    NULL  };voidnet_set_disp_pack_out(olsr_bool val){  disp_pack_out = val;}voidinit_net(void){  const char * const *defaults = olsr_cnf->ip_version == AF_INET ? deny_ipv4_defaults : deny_ipv6_defaults;    for (; *defaults != NULL; defaults++) {    union olsr_ip_addr addr;    if(inet_pton(olsr_cnf->ip_version, *defaults, &addr) <= 0){      fprintf(stderr, "Error converting fixed IP %s for deny rule!!\n", *defaults);      continue;    }    olsr_add_invalid_address(&addr);  }}/** * Create a outputbuffer for the given interface. This * function will allocate the needed storage according  * to the MTU of the interface. * * @param ifp the interface to create a buffer for * * @return 0 on success, negative if a buffer already existed *  for the given interface */ intnet_add_buffer(struct interface *ifp){  /* Can the interfaces MTU actually change? If not, we can elimiate   * the "bufsize" field in "struct olsr_netbuf".   */  if (ifp->netbuf.bufsize != ifp->int_mtu && ifp->netbuf.buff != NULL) {    free(ifp->netbuf.buff);    ifp->netbuf.buff = NULL;  }    if (ifp->netbuf.buff == NULL) {    ifp->netbuf.buff = olsr_malloc(ifp->int_mtu, "add_netbuff");  }  /* Fill struct */  ifp->netbuf.bufsize = ifp->int_mtu;  ifp->netbuf.maxsize = ifp->int_mtu - OLSR_HEADERSIZE;  ifp->netbuf.pending = 0;  ifp->netbuf.reserved = 0;  return 0;}/** * Remove a outputbuffer. Frees the allocated memory. * * @param ifp the interface corresponding to the buffer * to remove * * @return 0 on success, negative if no buffer is found */intnet_remove_buffer(struct interface *ifp){  /* Flush pending data */  if(ifp->netbuf.pending)    net_output(ifp);  free(ifp->netbuf.buff);  ifp->netbuf.buff = NULL;  return 0;}/** * Reserve space in a outputbuffer. This should only be needed * in very special cases. This will decrease the reported size * of the buffer so that there is always <i>size</i> bytes * of data available in the buffer. To add data in the reserved * area one must use the net_outbuffer_push_reserved function. * * @param ifp the interface corresponding to the buffer * to reserve space on * @param size the number of bytes to reserve * * @return 0 on success, negative if there was not enough *  bytes to reserve */intnet_reserve_bufspace(struct interface *ifp, int size){  if(size > ifp->netbuf.maxsize)    return -1;    ifp->netbuf.reserved = size;  ifp->netbuf.maxsize -= size;    return 0;}/** * Returns the number of bytes pending in the buffer. That * is the number of bytes added but not sent. * * @param ifp the interface corresponding to the buffer * * @return the number of bytes currently pending */olsr_u16_tnet_output_pending(struct interface *ifp){  return ifp->netbuf.pending;}/** * Add data to a buffer. * * @param ifp the interface corresponding to the buffer * @param data a pointer to the data to add * @param size the number of byte to copy from data * * @return -1 if no buffer was found, 0 if there was not  *  enough room in buffer or the number of bytes added on  *  success */intnet_outbuffer_push(struct interface *ifp, const void *data, const olsr_u16_t size){  if((ifp->netbuf.pending + size) > ifp->netbuf.maxsize)    return 0;  memcpy(&ifp->netbuf.buff[ifp->netbuf.pending + OLSR_HEADERSIZE], data, size);  ifp->netbuf.pending += size;  return size;}/** * Add data to the reserved part of a buffer * * @param ifp the interface corresponding to the buffer * @param data a pointer to the data to add * @param size the number of byte to copy from data * * @return -1 if no buffer was found, 0 if there was not  *  enough room in buffer or the number of bytes added on  *  success */intnet_outbuffer_push_reserved(struct interface *ifp, const void *data, const olsr_u16_t size){  if((ifp->netbuf.pending + size) > (ifp->netbuf.maxsize + ifp->netbuf.reserved))    return 0;  memcpy(&ifp->netbuf.buff[ifp->netbuf.pending + OLSR_HEADERSIZE], data, size);  ifp->netbuf.pending += size;  return size;}/** * Report the number of bytes currently available in the buffer * (not including possible reserved bytes) * * @param ifp the interface corresponding to the buffer * * @return the number of bytes available in the buffer or */intnet_outbuffer_bytes_left(const struct interface *ifp){  return ifp->netbuf.maxsize - ifp->netbuf.pending;}/** * Add a packet transform function. Theese are functions * called just prior to sending data in a buffer. * * @param f the function pointer * * @returns 1 */intadd_ptf(packet_transform_function f){  struct ptf *new_ptf;  new_ptf = olsr_malloc(sizeof(struct ptf), "Add PTF");  new_ptf->next = ptf_list;  new_ptf->function = f;  ptf_list = new_ptf;  return 1;}/** * Remove a packet transform function * * @param f the function pointer * * @returns 1 if a functionpointer was removed *  0 if not */intdel_ptf(packet_transform_function f){  struct ptf *tmp_ptf, *prev;  tmp_ptf = ptf_list;  prev = NULL;  while(tmp_ptf)    {      if(tmp_ptf->function == f)	{	  /* Remove entry */	  if(prev == NULL)	      ptf_list = tmp_ptf->next;	  else	      prev->next = tmp_ptf->next;          free(tmp_ptf);	  return 1;	}      prev = tmp_ptf;      tmp_ptf = tmp_ptf->next;    }  return 0;}/** *Sends a packet on a given interface. * *@param ifp the interface to send on. * *@return negative on error */intnet_output(struct interface *ifp){  struct sockaddr_in *sin;    struct sockaddr_in dst;  struct sockaddr_in6 *sin6;    struct sockaddr_in6 dst6;  struct ptf *tmp_ptf_list;  union olsr_packet *outmsg;  int retval;  sin = NULL;  sin6 = NULL;  if(!ifp->netbuf.pending)    return 0;  ifp->netbuf.pending += OLSR_HEADERSIZE;  retval = ifp->netbuf.pending;  outmsg = (union olsr_packet *)ifp->netbuf.buff;  /* Add the Packet seqno */  outmsg->v4.olsr_seqno = htons(ifp->olsr_seqnum++);  /* Set the packetlength */  outmsg->v4.olsr_packlen = htons(ifp->netbuf.pending);  if(olsr_cnf->ip_version == AF_INET)    {      /* IP version 4 */      sin = (struct sockaddr_in *)&ifp->int_broadaddr;      /* Copy sin */      dst = *sin;      sin = &dst;      if (sin->sin_port == 0)	sin->sin_port = htons(OLSRPORT);    }  else    {      /* IP version 6 */      sin6 = (struct sockaddr_in6 *)&ifp->int6_multaddr;      /* Copy sin */      dst6 = *sin6;      sin6 = &dst6;    }  /*   *Call possible packet transform functions registered by plugins     */  for (tmp_ptf_list = ptf_list; tmp_ptf_list != NULL; tmp_ptf_list = tmp_ptf_list->next)    {      tmp_ptf_list->function(ifp->netbuf.buff, &ifp->netbuf.pending);    }  /*   *if the -dispout option was given   *we print the content of the packets   */  if(disp_pack_out)    print_olsr_serialized_packet(stdout, (union olsr_packet *)ifp->netbuf.buff, 				 ifp->netbuf.pending, &ifp->ip_addr);     if(olsr_cnf->ip_version == AF_INET)    {      /* IP version 4 */      if(olsr_sendto(ifp->olsr_socket,                      ifp->netbuf.buff, 		     ifp->netbuf.pending, 		     MSG_DONTROUTE, 		     (struct sockaddr *)sin, 		     sizeof (*sin))	 < 0)	{	  perror("sendto(v4)");	  olsr_syslog(OLSR_LOG_ERR, "OLSR: sendto IPv4 %m");	  retval = -1;	}    }  else    {      /* IP version 6 */      if(olsr_sendto(ifp->olsr_socket, 		     ifp->netbuf.buff,		     ifp->netbuf.pending, 		     MSG_DONTROUTE, 		     (struct sockaddr *)sin6, 		     sizeof (*sin6))	 < 0)	{	  perror("sendto(v6)");	  olsr_syslog(OLSR_LOG_ERR, "OLSR: sendto IPv6 %m");	  fprintf(stderr, "Socket: %d interface: %d\n", ifp->olsr_socket, ifp->if_index);	  fprintf(stderr, "To: %s (size: %d)\n", ip6_to_string(&sin6->sin6_addr), (int)sizeof(*sin6));	  fprintf(stderr, "Outputsize: %d\n", ifp->netbuf.pending);	  retval = -1;	}    }    ifp->netbuf.pending = 0;  // if we've just transmitted a TC message, let Dijkstra use the current  // link qualities for the links to our neighbours  olsr_update_dijkstra_link_qualities();  lq_tc_pending = OLSR_FALSE;  return retval;}/** * Create a IPv6 netmask based on a prefix length * * @param allocated address to build the netmask in * @param prefix the prefix length * * @returns 1 on success 0 on failure */intolsr_prefix_to_netmask(union olsr_ip_addr *adr, olsr_u16_t prefix){  int p, i;  if(adr == NULL)    return 0;  p = prefix;  i = 0;  memset(adr, 0, olsr_cnf->ipsize);  for(;p > 0; p -= 8)    {      adr->v6.s6_addr[i] = (p < 8) ? 0xff ^ (0xff >> p) : 0xff;      i++;    }#ifdef DEBUG  OLSR_PRINTF(3, "Prefix %d = Netmask: %s\n", prefix, olsr_ip_to_string(adr));#endif  return 1;}/** * Calculate prefix length based on a netmask * * @param adr the address to use to calculate the prefix length * * @return the prefix length */olsr_u16_tolsr_netmask_to_prefix(const union olsr_ip_addr *adr){  olsr_u16_t prefix = 0;  unsigned int i;  prefix = 0;  for(i = 0; i < olsr_cnf->ipsize; i++)    {      if(adr->v6.s6_addr[i] == 0xff)	{	  prefix += 8;	}      else	{          int tmp;	  for(tmp = adr->v6.s6_addr[i];	      tmp > 0;	      tmp = (tmp << 1) & 0xff)	    prefix++;	}    }#ifdef DEBUG  OLSR_PRINTF(3, "Netmask: %s = Prefix %d\n", olsr_ip_to_string(adr), prefix);#endif  return prefix;}/** *Converts a sockaddr struct to a string representing *the IP address from the sockaddr struct * *<b>NON REENTRANT!!!!</b> * *@param address_to_convert the sockaddr struct to "convert" *@return a char pointer to the string containing the IP */char *sockaddr_to_string(const struct sockaddr *address_to_convert){  const struct sockaddr_in *address = (const struct sockaddr_in *)address_to_convert;   return inet_ntoa(address->sin_addr);  }/** *Converts the 32bit olsr_u32_t datatype to *a char array. * *<b>NON REENTRANT!!!!</b> * *@param address the olsr_u32_t to "convert" *@return a char pointer to the string containing the IP */const char *ip_to_string(const olsr_u32_t *address){  struct in_addr in;  in.s_addr=*address;  return(inet_ntoa(in));  }/** *Converts the 32bit olsr_u32_t datatype to *a char array. * *<b>NON REENTRANT</b> * *@param addr6 the address to "convert" *@return a char pointer to the string containing the IP */const char *ip6_to_string(const struct in6_addr *addr6){  static char ipv6_buf[INET6_ADDRSTRLEN]; /* for address coversion */  return inet_ntop(AF_INET6, addr6, ipv6_buf, sizeof(ipv6_buf));}const char *olsr_ip_to_string(const union olsr_ip_addr *addr){  static int idx = 0;  static char buff[4][INET6_ADDRSTRLEN > INET_ADDRSTRLEN ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN];  const char *ret;  if (!addr) {      return "null";  }    if(olsr_cnf->ip_version == AF_INET)    {#if 0      struct in_addr in;      in.s_addr = addr->v4;      ret = inet_ntop(AF_INET, &in, buff[idx], sizeof(buff[idx]));#else      ret = inet_ntop(AF_INET, &addr->v4, buff[idx], sizeof(buff[idx]));#endif    }  else    {      /* IPv6 */      ret = inet_ntop(AF_INET6, &addr->v6, buff[idx], sizeof(buff[idx]));    }  idx = (idx + 1) & 3;  return ret;}voidolsr_add_invalid_address(const union olsr_ip_addr *adr){  struct deny_address_entry *new_entry;  new_entry = olsr_malloc(sizeof(struct deny_address_entry), "Add deny address");  new_entry->next = deny_entries;  COPY_IP(&new_entry->addr, adr);  deny_entries = new_entry;  OLSR_PRINTF(1, "Added %s to IP deny set\n", olsr_ip_to_string(&new_entry->addr));  return;}/** *Converts the 32bit olsr_u32_t datatype to *a char array. * *<b>NON REENTRANT</b> * *@param addr6 the address to "convert" *@return a char pointer to the string containing the IP */olsr_boololsr_validate_address(const union olsr_ip_addr *adr){  const struct deny_address_entry *deny_entry = deny_entries;  while(deny_entry)    {      if(COMP_IP(adr, &deny_entry->addr))	{	  OLSR_PRINTF(1, "Validation of address %s failed!\n",		      olsr_ip_to_string(adr));	  return OLSR_FALSE;	}      deny_entry = deny_entry->next;    }  return OLSR_TRUE;}/* * Local Variables: * c-basic-offset: 2 * End: */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -