📄 ipc_frontend.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: ipc_frontend.c,v 1.36 2007/10/13 12:31:04 bernd67 Exp $ *//* * *IPC - interprocess communication *for the OLSRD - GUI front-end * */#include "ipc_frontend.h"#include "link_set.h"#include "olsr.h"#include "log.h"#include "parser.h"#include "socket_parser.h"#include "local_hna_set.h"#ifdef WIN32#define close(x) closesocket(x)#define perror(x) WinSockPError(x)void WinSockPError(char *);#endif#ifndef linux#define MSG_NOSIGNAL 0#endifstatic int ipc_sock = -1;static int ipc_conn = -1;static int ipc_active = OLSR_FALSE;static intipc_send_all_routes(int fd);static intipc_send_net_info(int fd);/** *Create the socket to use for IPC to the *GUI front-end * *@return the socket FD */intipc_init(void){ //int flags; struct sockaddr_in sin; int yes = 1; /* Add parser function */ olsr_parser_add_function(&frontend_msgparser, PROMISCUOUS, 0); /* get an internet domain socket */ if ((ipc_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("IPC socket"); olsr_exit("IPC socket", EXIT_FAILURE); } if(setsockopt(ipc_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes)) < 0) { perror("SO_REUSEADDR failed"); return 0; } /* 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_sock, (struct sockaddr *) &sin, sizeof(sin)) == -1) { perror("IPC bind"); OLSR_PRINTF(1, "Will retry in 10 seconds...\n"); sleep(10); if(bind(ipc_sock, (struct sockaddr *) &sin, sizeof(sin)) == -1) { perror("IPC bind"); olsr_exit("IPC bind", EXIT_FAILURE); } OLSR_PRINTF(1, "OK\n"); } /* show that we are willing to listen */ if(listen(ipc_sock, olsr_cnf->ipc_connections) == -1) { perror("IPC listen"); olsr_exit("IPC listen", EXIT_FAILURE); } /* Register the socket with the socket parser */ add_olsr_socket(ipc_sock, &ipc_accept); return ipc_sock;}voidipc_accept(int fd){ socklen_t addrlen; struct sockaddr_in pin; char *addr; addrlen = sizeof (struct sockaddr_in); if ((ipc_conn = accept(fd, (struct sockaddr *) &pin, &addrlen)) == -1) { perror("IPC accept"); olsr_exit("IPC accept", EXIT_FAILURE); } else { OLSR_PRINTF(1, "Front end connected\n"); addr = inet_ntoa(pin.sin_addr); if(ipc_check_allowed_ip((union olsr_ip_addr *)&pin.sin_addr.s_addr)) { ipc_active = OLSR_TRUE; ipc_send_net_info(ipc_conn); ipc_send_all_routes(ipc_conn); OLSR_PRINTF(1, "Connection from %s\n",addr); } else { OLSR_PRINTF(1, "Front end-connection from foregin host(%s) not allowed!\n", addr); olsr_syslog(OLSR_LOG_ERR, "OLSR: Front end-connection from foregin host(%s) not allowed!\n", addr); CLOSE(ipc_conn); } }}olsr_boolipc_check_allowed_ip(union olsr_ip_addr *addr){ struct ipc_host *ipch = olsr_cnf->ipc_hosts; struct ipc_net *ipcn = olsr_cnf->ipc_nets; if(addr->v4 == ntohl(INADDR_LOOPBACK)) return OLSR_TRUE; /* check hosts */ while(ipch) { if(addr->v4 == ipch->host.v4) return OLSR_TRUE; ipch = ipch->next; } /* check nets */ while(ipcn) { if((addr->v4 & ipcn->mask.v4) == (ipcn->net.v4 & ipcn->mask.v4)) return OLSR_TRUE; ipcn = ipcn->next; } return OLSR_FALSE;}#if 0/** *Read input from the IPC socket. Not in use. * *@todo for future use *@param sock the IPC socket *@return 1 */intipc_input(int sock __attribute__((unused))){ union { char buf[MAXPACKETSIZE+1]; struct olsr olsr; } inbuf; if (recv(sock, dir, sizeof(dir), 0) == -1) { perror("recv"); exit(1); } return 1;}#endif/** *Sends a olsr packet on the IPC socket. * *@param olsr the olsr struct representing the packet * *@return negative on error */voidfrontend_msgparser(union olsr_message *msg, struct interface *in_if __attribute__((unused)), union olsr_ip_addr *from_addr __attribute__((unused))){ int size; if(!ipc_active) return; if(olsr_cnf->ip_version == AF_INET) size = ntohs(msg->v4.olsr_msgsize); else size = ntohs(msg->v6.olsr_msgsize); if (send(ipc_conn, (void *)msg, size, MSG_NOSIGNAL) < 0) { OLSR_PRINTF(1, "(OUTPUT)IPC connection lost!\n"); CLOSE(ipc_conn); //olsr_cnf->open_ipc = 0; ipc_active = OLSR_FALSE; }}/** *Send a route table update to the front-end. * *@param kernel_route a rtentry describing the route update *@param add 1 if the route is to be added 0 if it is to be deleted *@param int_name the name of the interface the route is set to go by * *@return negative on error */intipc_route_send_rtentry(union olsr_ip_addr *dst, union olsr_ip_addr *gw, int met, int add, const char *int_name){ struct ipcmsg packet; char *tmp; if(!olsr_cnf->open_ipc) { return -1; } if(!ipc_active) return 0; memset(&packet, 0, sizeof(struct ipcmsg)); packet.size = htons(IPC_PACK_SIZE); packet.msgtype = ROUTE_IPC; COPY_IP(&packet.target_addr, dst); packet.add = add; if(add && gw) { packet.metric = met; COPY_IP(&packet.gateway_addr, gw); } if(int_name != NULL) memcpy(&packet.device[0], int_name, 4); else memset(&packet.device[0], 0, 4); tmp = (char *) &packet; /* x = 0; for(i = 0; i < IPC_PACK_SIZE;i++) { if(x == 4) { x = 0; printf("\n\t"); } x++; printf(" %03i", (u_char) tmp[i]); } printf("\n"); */ if (send(ipc_conn, tmp, IPC_PACK_SIZE, MSG_NOSIGNAL) < 0) // MSG_NOSIGNAL to avoid sigpipe { OLSR_PRINTF(1, "(RT_ENTRY)IPC connection lost!\n"); CLOSE(ipc_conn); //olsr_cnf->open_ipc = 0; ipc_active = OLSR_FALSE; return -1; } return 1;}static intipc_send_all_routes(int fd){ struct rt_entry *rt; struct ipcmsg packet; char *tmp; if(!ipc_active) return 0; OLSR_FOR_ALL_RT_ENTRIES(rt) { memset(&packet, 0, sizeof(struct ipcmsg)); packet.size = htons(IPC_PACK_SIZE); packet.msgtype = ROUTE_IPC; COPY_IP(&packet.target_addr, &rt->rt_dst.prefix); packet.add = 1; packet.metric = (olsr_u8_t)(rt->rt_best->rtp_metric.hops); COPY_IP(&packet.gateway_addr, &rt->rt_nexthop.gateway); memcpy(&packet.device[0], if_ifwithindex_name(rt->rt_nexthop.iif_index), 4); tmp = (char *) &packet; /* MSG_NOSIGNAL to avoid sigpipe */ if (send(fd, tmp, IPC_PACK_SIZE, MSG_NOSIGNAL) < 0) { OLSR_PRINTF(1, "(RT_ENTRY)IPC connection lost!\n"); CLOSE(ipc_conn); ipc_active = OLSR_FALSE; return -1; } } OLSR_FOR_ALL_RT_ENTRIES_END(rt); return 1;}/** *Sends OLSR info to the front-end. This info consists of *the different time intervals and holding times, number *of interfaces, HNA routes and main address. * *@return negative on error */static intipc_send_net_info(int fd){ struct ipc_net_msg *net_msg; //int x, i; char *msg; net_msg = olsr_malloc(sizeof(struct ipc_net_msg), "send net info"); msg = (char *)net_msg; OLSR_PRINTF(1, "Sending net-info to front end...\n"); memset(net_msg, 0, sizeof(struct ipc_net_msg)); /* Message size */ net_msg->size = htons(sizeof(struct ipc_net_msg)); /* Message type */ net_msg->msgtype = NET_IPC; /* MIDs */ /* XXX fix IPC MIDcnt */ net_msg->mids = (ifnet != NULL && ifnet->int_next != NULL) ? 1 : 0; /* HNAs */ if(olsr_cnf->ip_version == AF_INET6) { if(olsr_cnf->hna6_entries == NULL) net_msg->hnas = 0; else net_msg->hnas = 1; } if(olsr_cnf->ip_version == AF_INET) { if(olsr_cnf->hna4_entries == NULL) net_msg->hnas = 0; else net_msg->hnas = 1; } /* Different values */ /* Temporary fixes */ /* XXX fix IPC intervals */ net_msg->hello_int = 0;//htons((olsr_u16_t)hello_int); net_msg->hello_lan_int = 0;//htons((olsr_u16_t)hello_int_nw); net_msg->tc_int = 0;//htons((olsr_u16_t)tc_int); net_msg->neigh_hold = 0;//htons((olsr_u16_t)neighbor_hold_time); net_msg->topology_hold = 0;//htons((olsr_u16_t)topology_hold_time); if(olsr_cnf->ip_version == AF_INET) net_msg->ipv6 = 0; else net_msg->ipv6 = 1; /* Main addr */ COPY_IP(&net_msg->main_addr, &olsr_cnf->main_addr); /* printf("\t"); x = 0; for(i = 0; i < sizeof(struct ipc_net_msg);i++) { if(x == 4) { x = 0; printf("\n\t"); } x++; printf(" %03i", (u_char) msg[i]); } printf("\n"); */ if (send(fd, (char *)net_msg, sizeof(struct ipc_net_msg), MSG_NOSIGNAL) < 0) { OLSR_PRINTF(1, "(NETINFO)IPC connection lost!\n"); CLOSE(ipc_conn); //olsr_cnf->open_ipc = 0; return -1; } free(net_msg); return 0;}intshutdown_ipc(void){ OLSR_PRINTF(1, "Shutting down IPC...\n"); CLOSE(ipc_sock); CLOSE(ipc_conn); return 1;}/* * Local Variables: * c-basic-offset: 2 * End: */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -