📄 olsrd_dot_draw.c
字号:
/* * 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_dot_draw.c,v 1.27 2007/09/13 15:31:58 bernd67 Exp $ *//* * Dynamic linked library for the olsr.org olsr daemon */ #include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/time.h>#include <time.h>#include <math.h>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include "olsr.h"#include "olsr_types.h"#include "neighbor_table.h"#include "two_hop_neighbor_table.h"#include "tc_set.h"#include "hna_set.h"#include "mid_set.h"#include "link_set.h"#include "socket_parser.h"#include "olsrd_dot_draw.h"#include "olsrd_plugin.h"#ifdef WIN32#define close(x) closesocket(x)#endifstatic int ipc_socket;static int ipc_open;static int ipc_connection;static int ipc_socket_up;/* IPC initialization function */static intplugin_ipc_init(void);static char*olsr_netmask_to_string(union hna_netmask *mask);/* Event function to register with the sceduler */static intpcf_event(int, int, int);static voidipc_action(int);static voidipc_print_neigh_link(struct neighbor_entry *neighbor);static voidipc_print_tc_link(struct tc_entry *entry, struct tc_edge_entry *dst_entry);static voidipc_print_net(union olsr_ip_addr *, union olsr_ip_addr *, union hna_netmask *);static intipc_send(const char *, int);static intipc_send_str(const char *);static double calc_etx(double, double);/** *Do initialization here * *This function is called by the my_init *function in uolsrd_plugin.c */intolsrd_plugin_init(void){ /* Initial IPC value */ ipc_open = 0; ipc_socket_up = 0; ipc_socket = -1; ipc_connection = -1; /* Register the "ProcessChanges" function */ register_pcf(&pcf_event); plugin_ipc_init(); return 1;}/** * destructor - called at unload */voidolsr_plugin_exit(void){ if(ipc_open) close(ipc_socket);}static voidipc_print_neigh_link(struct neighbor_entry *neighbor){ char buf[256]; const char* adr; double etx = 0.0; char* style = "solid"; struct link_entry* link; adr = olsr_ip_to_string(&olsr_cnf->main_addr); sprintf( buf, "\"%s\" -> ", adr ); ipc_send_str(buf); adr = olsr_ip_to_string(&neighbor->neighbor_main_addr); if (neighbor->status == 0) { // non SYM style = "dashed"; } else { link = get_best_link_to_neighbor(&neighbor->neighbor_main_addr); if (link) { etx = calc_etx( link->loss_link_quality, link->neigh_link_quality); } } sprintf( buf, "\"%s\"[label=\"%.2f\", style=%s];\n", adr, etx, style ); ipc_send_str(buf); if (neighbor->is_mpr) { sprintf( buf, "\"%s\"[shape=box];\n", adr ); ipc_send_str(buf); }}static intplugin_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; }#if defined __FreeBSD__ && defined SO_NOSIGPIPE if (setsockopt(ipc_socket, SOL_SOCKET, SO_NOSIGPIPE, (char *)&yes, sizeof(yes)) < 0) { perror("SO_REUSEADDR 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 */ //printf("Adding socket with olsrd\n"); add_olsr_socket(ipc_socket, &ipc_action); ipc_socket_up = 1; } return 1;}static voidipc_action(int fd __attribute__((unused))){ struct sockaddr_in pin; socklen_t addrlen = sizeof(struct sockaddr_in); if (ipc_open) { int rc; do { rc = close(ipc_connection); } while (rc == -1 && (errno == EINTR || errno == EAGAIN)); if (rc == -1) { olsr_printf(1, "(DOT DRAW) Error on closing previously active TCP connection on fd %d: %s\n", ipc_connection, strerror(errno)); } ipc_open = 0; } if ((ipc_connection = accept(ipc_socket, (struct sockaddr *) &pin, &addrlen)) == -1) { olsr_printf(1, "(DOT DRAW)IPC accept: %s\n", strerror(errno)); } else { if(ntohl(pin.sin_addr.s_addr) != ntohl(ipc_accept_ip.v4)) { olsr_printf(0, "Front end-connection from foreign host (%s) not allowed!\n", inet_ntoa(pin.sin_addr)); close(ipc_connection); ipc_connection = -1; } else { ipc_open = 1; olsr_printf(1, "(DOT DRAW)IPC: Connection from %s\n",inet_ntoa(pin.sin_addr)); pcf_event(1, 1, 1); } }}/** *Scheduled event */static intpcf_event(int changes_neighborhood, int changes_topology, int changes_hna){ int res; olsr_u8_t index; struct neighbor_entry *neighbor_table_tmp; struct tc_entry *tc; struct tc_edge_entry *tc_edge; struct hna_entry *tmp_hna; struct hna_net *tmp_net; res = 0; if(changes_neighborhood || changes_topology || changes_hna) { /* Print tables to IPC socket */ ipc_send_str("digraph topology\n{\n"); /* 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); /* 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_str("}\n\n"); res = 1; } if(!ipc_socket_up) plugin_ipc_init(); return res;}#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);}static voidipc_print_tc_link(struct tc_entry *entry, struct tc_edge_entry *dst_entry){ char buf[256]; const char* adr; double etx = calc_etx( dst_entry->link_quality, dst_entry->inverse_link_quality ); adr = olsr_ip_to_string(&entry->addr); sprintf( buf, "\"%s\" -> ", adr ); ipc_send_str(buf); adr = olsr_ip_to_string(&dst_entry->T_dest_addr); sprintf( buf, "\"%s\"[label=\"%.2f\"];\n", adr, etx ); ipc_send_str(buf);}static 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_str("\""); ipc_send_str(adr); ipc_send_str("\" -> \""); adr = olsr_ip_to_string(net); ipc_send_str(adr); ipc_send_str("/"); adr = olsr_netmask_to_string(mask); ipc_send_str(adr); ipc_send_str("\"[label=\"HNA\"];\n"); ipc_send_str("\""); adr = olsr_ip_to_string(net); ipc_send_str(adr); ipc_send_str("/"); adr = olsr_netmask_to_string(mask); ipc_send_str(adr); ipc_send_str("\""); ipc_send_str("[shape=diamond];\n");}static intipc_send_str(const char *data){ if(!ipc_open) return 0; return ipc_send(data, strlen(data));}static intipc_send(const char *data, int size){ if(!ipc_open) return 0;#if defined __FreeBSD__ || defined __NetBSD__ || defined __OpenBSD__ || defined __MacOSX__#define FLAGS 0#else#define FLAGS MSG_NOSIGNAL#endif if (send(ipc_connection, data, size, FLAGS) == -1) { olsr_printf(1, "(DOT DRAW)IPC connection lost!\n"); close(ipc_connection); ipc_open = 0; return -1; } return 1;}static char*olsr_netmask_to_string(union hna_netmask *mask){ char *ret; struct in_addr in; if(olsr_cnf->ip_version == AF_INET) { in.s_addr = mask->v4; ret = inet_ntoa(in); } else { /* IPv6 */ static char netmask[5]; sprintf(netmask, "%d", mask->v6); ret = netmask; } return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -