olsrd_pgraph.c

来自「wifi 无线网络路由协议OLSR linux下C代码」· C语言 代码 · 共 494 行

C
494
字号
/* * The olsr.org Optimized Link-State Routing daemon(olsrd) * Copyright (c) 2004, Andreas T鴑nesen(andreto@olsr.org) *                     includes code by Bruno Randolf * 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: olsrd_pgraph.c,v 1.8 2007/09/13 15:31:59 bernd67 Exp $ *//* * Dynamic linked library for the olsr.org olsr daemon */#include "olsrd_pgraph.h"#include "socket_parser.h"#include "olsrd_plugin.h"#include "plugin_util.h"#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#ifdef WIN32#define close(x) closesocket(x)#endif#define PLUGIN_NAME    "OLSRD pgraph plugin"#define PLUGIN_VERSION "0.1"#define PLUGIN_AUTHOR   "Richard Gopaul"#define MOD_DESC PLUGIN_NAME " " PLUGIN_VERSION " by " PLUGIN_AUTHOR#define PLUGIN_INTERFACE_VERSION 5static union olsr_ip_addr ipc_accept_ip;static int ipc_port;static int ipc_socket;static int ipc_connection;void my_init(void) __attribute__((constructor));void my_fini(void) __attribute__((destructor));/* * Defines the version of the plugin interface that is used * THIS IS NOT THE VERSION OF YOUR PLUGIN! * Do not alter unless you know what you are doing! */int olsrd_plugin_interface_version(void){   return PLUGIN_INTERFACE_VERSION;}/** *Constructor */voidmy_init(void){  /* Print plugin info to stdout */  printf("%s\n", MOD_DESC);  /* defaults for parameters */  ipc_port = 2004;  if (olsr_cnf->ip_version == AF_INET) {    ipc_accept_ip.v4 = htonl(INADDR_LOOPBACK);  } else {    ipc_accept_ip.v6 = in6addr_loopback;  }  ipc_socket = -1;  ipc_connection = -1;}/** *Destructor */voidmy_fini(void){  if(ipc_socket >= 0) {    close(ipc_socket);    ipc_socket = -1;  }  if(ipc_connection >= 0) {    close(ipc_connection);    ipc_connection = -1;  }}static const struct olsrd_plugin_parameters plugin_parameters[] = {    { .name = "port",   .set_plugin_parameter = &set_plugin_port,      .data = &ipc_port },    { .name = "accept", .set_plugin_parameter = &set_plugin_ipaddress, .data = &ipc_accept_ip },};void olsrd_get_plugin_parameters(const struct olsrd_plugin_parameters **params, int *size){    *params = plugin_parameters;    *size = sizeof(plugin_parameters)/sizeof(*plugin_parameters);}/* Event function to register with the sceduler */static int pcf_event(int, int, int);static void ipc_action(int);#if 0static struct link_entry *olsr_neighbor_best_link(union olsr_ip_addr *main);#endifstatic void ipc_print_neigh_link(struct neighbor_entry *neighbor);static void ipc_print_tc_link(struct tc_entry *entry, struct tc_edge_entry *dst_entry);#if 0static void ipc_print_net(union olsr_ip_addr *, union olsr_ip_addr *, union hna_netmask *);#endifstatic int ipc_send(const char *, int);static void ipc_print_neigh_link(struct neighbor_entry *);static int plugin_ipc_init(void);static void ipc_print_neigh_link(struct neighbor_entry *neighbor){  char buf[256];  int len;  const char* main_adr;  const char* adr;//  double etx=0.0;//  char* style = "solid";//  struct link_entry* link;  main_adr = olsr_ip_to_string(&olsr_cnf->main_addr);  adr = olsr_ip_to_string(&neighbor->neighbor_main_addr);  len = sprintf( buf, "add link %s %s\n", main_adr, adr );  ipc_send(buf, len);  //  if (neighbor->status == 0) { // non SYM//  	style = "dashed";//  }//  else {    /* find best link to neighbor for the ETX */    //? why cant i just get it one time at fetch_olsrd_data??? (br1)//    if(olsr_plugin_io(GETD__LINK_SET, &link, sizeof(link)) && link)//    {//      link_set = link; // for olsr_neighbor_best_link    //      link = olsr_neighbor_best_link(&neighbor->neighbor_main_addr);//      if (link) {//        etx = calc_etx( link->loss_link_quality, link->neigh_link_quality);//      }//    }//  }      //len = sprintf( buf, "\"%s\"[label=\"%.2f\", style=%s];\n", adr, etx, style );  //len = sprintf( buf, "%s\n", adr );  //ipc_send(buf, len);     //if (neighbor->is_mpr) {   //	len = sprintf( buf, "\"%s\"[shape=box];\n", adr );   //	ipc_send(buf, len);   //}}/** *Do initialization here * *This function is called by the my_init *function in uolsrd_plugin.c */int olsrd_plugin_init(void){  /* Initial IPC value */  ipc_socket = -1;  /* Register the "ProcessChanges" function */  register_pcf(&pcf_event);  return 1;}static int plugin_ipc_init(void){  struct sockaddr_in sin;  olsr_u32_t yes = 1;  /* Init ipc socket */  if ((ipc_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1)     {      olsr_printf(1, "(DOT DRAW)IPC socket %s\n", strerror(errno));      return 0;    }  else    {      if (setsockopt(ipc_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes)) < 0)       {	perror("SO_REUSEADDR failed");	return 0;      }#ifdef __FreeBSD__      if (setsockopt(ipc_socket, SOL_SOCKET, SO_NOSIGPIPE, (char *)&yes, sizeof(yes)) < 0)       {	perror("SO_NOSIGPIPE failed");	return 0;      }#endif      /* Bind the socket */            /* complete the socket structure */      memset(&sin, 0, sizeof(sin));      sin.sin_family = AF_INET;      sin.sin_addr.s_addr = INADDR_ANY;      sin.sin_port = htons(ipc_port);            /* bind the socket to the port number */      if (bind(ipc_socket, (struct sockaddr *) &sin, sizeof(sin)) == -1) 	{	  olsr_printf(1, "(DOT DRAW)IPC bind %s\n", strerror(errno));	  return 0;	}            /* show that we are willing to listen */      if (listen(ipc_socket, 1) == -1) 	{	  olsr_printf(1, "(DOT DRAW)IPC listen %s\n", strerror(errno));	  return 0;	}      /* Register with olsrd */      add_olsr_socket(ipc_socket, &ipc_action);    }  return 1;}static void ipc_action(int fd __attribute__((unused))){  struct sockaddr_in pin;  socklen_t addrlen;  char *addr;    char buf[256] ;  int len ;     addrlen = sizeof(struct sockaddr_in);  if ((ipc_connection = accept(ipc_socket, (struct sockaddr *)  &pin, &addrlen)) == -1)    {      olsr_printf(1, "(DOT DRAW)IPC accept: %s\n", strerror(errno));      exit(1);    }  else    {      addr = inet_ntoa(pin.sin_addr);/*      if(ntohl(pin.sin_addr.s_addr) != ntohl(ipc_accept_ip.s_addr))	{	  olsr_printf(1, "Front end-connection from foregin host(%s) not allowed!\n", addr);	  close(ipc_connection);	  return;	}      else	{*/	  olsr_printf(1, "(DOT DRAW)IPC: Connection from %s\n",addr);          len = sprintf(buf, "add node %s\n", olsr_ip_to_string(&olsr_cnf->main_addr));  	  ipc_send(buf, len);	  pcf_event(1, 1, 1);//	}    }}/** *Scheduled event */static int pcf_event(int changes_neighborhood,                     int changes_topology,                     int changes_hna __attribute__((unused))){  int res;  olsr_u8_t index;  struct neighbor_entry *neighbor_table_tmp;  struct tc_entry *tc;  struct tc_edge_entry *tc_edge;  res = 0;  //if(changes_neighborhood || changes_topology || changes_hna)  if(changes_neighborhood || changes_topology)    {      /* Print tables to IPC socket */      //ipc_send("start ", strlen("start "));      /* Neighbors */      for(index=0;index<HASHSIZE;index++)	{	  	  for(neighbor_table_tmp = neighbortable[index].next;	      neighbor_table_tmp != &neighbortable[index];	      neighbor_table_tmp = neighbor_table_tmp->next)	    {	      ipc_print_neigh_link( neighbor_table_tmp );	    }	}      /* Topology */        OLSR_FOR_ALL_TC_ENTRIES(tc) {          OLSR_FOR_ALL_TC_EDGE_ENTRIES(tc, tc_edge) {              ipc_print_tc_link(tc, tc_edge);          } OLSR_FOR_ALL_TC_EDGE_ENTRIES_END(tc, tc_edge);      } OLSR_FOR_ALL_TC_ENTRIES_END(tc);      ipc_send(" end ", strlen(" end "));      /* HNA entries *///      for(index=0;index<HASHSIZE;index++)//	{//	  tmp_hna = hna_set[index].next;//	  /* Check all entrys *///	  while(tmp_hna != &hna_set[index])//	    {//	      /* Check all networks *///	      tmp_net = tmp_hna->networks.next;//	      //	      while(tmp_net != &tmp_hna->networks)//		{//		  ipc_print_net(&tmp_hna->A_gateway_addr, //				&tmp_net->A_network_addr, //				&tmp_net->A_netmask);//		  tmp_net = tmp_net->next;//		}//	      //	      tmp_hna = tmp_hna->next;//	    }//	}//      ipc_send("}\n\n", strlen("}\n\n"));      res = 1;    }  if(ipc_socket == -1)    plugin_ipc_init();  return res;}#if 0#define MIN_LINK_QUALITY 0.01static double calc_etx(double loss, double neigh_loss) {  if (loss < MIN_LINK_QUALITY || neigh_loss < MIN_LINK_QUALITY)    return 0.0;  else    return 1.0 / (loss * neigh_loss);}#endifstatic void ipc_print_tc_link(struct tc_entry *entry, struct tc_edge_entry *dst_entry){  char buf[256];  int len;  const char* main_adr;  const char* adr;//  double etx = calc_etx( dst_entry->link_quality, dst_entry->inverse_link_quality );  main_adr = olsr_ip_to_string(&entry->addr);  adr = olsr_ip_to_string(&dst_entry->T_dest_addr);  len = sprintf( buf, "add link %s %s\n", main_adr, adr );  ipc_send(buf, len);}#if 0static voidipc_print_net(union olsr_ip_addr *gw, union olsr_ip_addr *net, union hna_netmask *mask){  const char *adr;  adr = olsr_ip_to_string(gw);  ipc_send("\"", 1);  ipc_send(adr, strlen(adr));  ipc_send("\" -> \"", strlen("\" -> \""));  adr = olsr_ip_to_string(net);  ipc_send(adr, strlen(adr));  ipc_send("/", 1);  adr = olsr_netmask_to_string(mask);  ipc_send(adr, strlen(adr));  ipc_send("\"[label=\"HNA\"];\n", strlen("\"[label=\"HNA\"];\n"));  ipc_send("\"", 1);  adr = olsr_ip_to_string(net);  ipc_send(adr, strlen(adr));  ipc_send("/", 1);  adr = olsr_netmask_to_string(mask);  ipc_send(adr, strlen(adr));  ipc_send("\"", 1);  ipc_send("[shape=diamond];\n", strlen("[shape=diamond];\n"));}#endifstatic int ipc_send(const char *data, int size){  if(ipc_connection == -1)    return 0;#if defined __FreeBSD__ || defined __MacOSX__#define FLAG 0#else#define FLAG MSG_NOSIGNAL#endif  if (send(ipc_connection, data, size, FLAG) < 0)     {      olsr_printf(1, "(DOT DRAW)IPC connection lost!\n");      close(ipc_connection);      ipc_connection = -1;      return -1;    }  return 1;}#if 0static struct link_entry *olsr_neighbor_best_link(union olsr_ip_addr *main){  struct link_entry *walker;  double best = 0.0;  double curr;  struct link_entry *res = NULL;  // loop through all links  for (walker = link_set; walker != NULL; walker = walker->next)  {    // check whether it's a link to the requested neighbor and    // whether the link's quality is better than what we have    if(COMP_IP(main, &walker->neighbor->neighbor_main_addr))    {      curr = walker->loss_link_quality * walker->neigh_link_quality;      if (curr >= best)      {        best = curr;        res = walker;      }    }  }  return res;}#endif

⌨️ 快捷键说明

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