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 + -
显示快捷键?