2 * The olsr.org Optimized Link-State Routing daemon(olsrd)
3 * Copyright (c) 2004-2009, the olsr.org team - see HISTORY file
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
16 * * Neither the name of olsr.org, olsrd nor the names of its
17 * contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
33 * Visit http://www.olsr.org for more information.
35 * If you find this software useful feel free to make a donation
36 * to the project. For more information see the website or contact
37 * the copyright holders.
43 *IPC - interprocess communication
44 *for the OLSRD - GUI front-end
48 #include "ipc_frontend.h"
53 #include "scheduler.h"
56 #include "olsr_ip_prefix_list.h"
62 #define perror(x) WinSockPError(x)
64 WinSockPError(const char *);
68 #define MSG_NOSIGNAL 0
72 *IPC message sent to the front-end
73 *at every route update. Both delete
81 union olsr_ip_addr target_addr;
82 union olsr_ip_addr gateway_addr;
90 uint8_t mids; /* No. of extra interfaces */
91 uint8_t hnas; /* No. of HNA nets */
94 uint16_t hello_lan_int;
97 uint16_t topology_hold;
99 union olsr_ip_addr main_addr;
102 static int ipc_sock = -1;
103 static int ipc_conn = -1;
106 ipc_send_all_routes(int fd);
109 ipc_send_net_info(int fd);
112 ipc_accept(int, void *, unsigned int);
120 ipc_check_allowed_ip(union olsr_ip_addr *);
123 frontend_msgparser(union olsr_message *, struct interface *, union olsr_ip_addr *);
127 *Create the socket to use for IPC to the
130 *@return the socket FD
135 struct sockaddr_in sin4;
138 /* Add parser function */
139 olsr_parser_add_function(&frontend_msgparser, PROMISCUOUS);
141 /* get an internet domain socket */
142 ipc_sock = socket(AF_INET, SOCK_STREAM, 0);
143 if (ipc_sock == -1) {
144 perror("IPC socket");
145 olsr_exit(EXIT_FAILURE);
149 if (setsockopt(ipc_sock, SOL_SOCKET, SO_REUSEADDR, (char *)&yes, sizeof(yes)) < 0) {
150 perror("SO_REUSEADDR failed");
154 /* complete the socket structure */
155 memset(&sin4, 0, sizeof(sin4));
156 sin4.sin_family = AF_INET;
157 sin4.sin_addr.s_addr = INADDR_ANY;
158 sin4.sin_port = htons(IPC_PORT);
160 /* bind the socket to the port number */
161 if (bind(ipc_sock, (struct sockaddr *)&sin4, sizeof(sin4)) == -1) {
163 OLSR_PRINTF(1, "Will retry in 10 seconds...\n");
165 if (bind(ipc_sock, (struct sockaddr *)&sin4, sizeof(sin4)) == -1) {
167 olsr_exit(EXIT_FAILURE);
169 OLSR_PRINTF(1, "OK\n");
172 /* show that we are willing to listen */
173 if (listen(ipc_sock, olsr_cnf->ipc_connections) == -1) {
174 perror("IPC listen");
175 olsr_exit(EXIT_FAILURE);
178 /* Register the socket with the socket parser */
179 add_olsr_socket(ipc_sock, &ipc_accept, NULL, NULL, SP_PR_READ);
185 ipc_check_allowed_ip(union olsr_ip_addr *addr)
187 if (addr->v4.s_addr == ntohl(INADDR_LOOPBACK)) {
192 return ip_acl_acceptable(&olsr_cnf->ipc_nets, addr, olsr_cnf->ip_version);
196 ipc_accept(int fd, void *data __attribute__((unused)), unsigned int flags __attribute__((unused)))
198 struct sockaddr_in pin;
200 socklen_t addrlen = sizeof (struct sockaddr_in);
202 ipc_conn = accept(fd, (struct sockaddr *)&pin, &addrlen);
203 if (ipc_conn == -1) {
204 perror("IPC accept");
205 olsr_exit(EXIT_FAILURE);
207 OLSR_PRINTF(1, "Front end connected\n");
208 addr = inet_ntoa(pin.sin_addr);
209 if (ipc_check_allowed_ip((union olsr_ip_addr *)&pin.sin_addr.s_addr)) {
210 ipc_send_net_info(ipc_conn);
211 ipc_send_all_routes(ipc_conn);
212 OLSR_PRINTF(1, "Connection from %s\n",addr);
214 OLSR_WARN(LOG_IPC, "Front end-connection from foregin host(%s) not allowed!\n", addr);
215 CLOSESOCKET(ipc_conn);
222 *Read input from the IPC socket. Not in use.
224 *@todo for future use
225 *@param sock the IPC socket
232 char buf[MAXPACKETSIZE+1];
236 if (recv(sock, dir, sizeof(dir), 0) == -1) {
245 *Sends a olsr packet on the IPC socket.
247 *@param olsr the olsr struct representing the packet
249 *@return true for not preventing forwarding
252 frontend_msgparser(union olsr_message *msg,
253 struct interface *in_if __attribute__((unused)),
254 union olsr_ip_addr *from_addr __attribute__((unused)))
257 const size_t len = olsr_cnf->ip_version == AF_INET ? ntohs(msg->v4.olsr_msgsize) : ntohs(msg->v6.olsr_msgsize);
258 if (send(ipc_conn, (void *)msg, len, MSG_NOSIGNAL) < 0) {
259 OLSR_PRINTF(1, "(OUTPUT)IPC connection lost!\n");
260 CLOSESOCKET(ipc_conn);
268 *Send a route table update to the front-end.
270 *@param kernel_route a rtentry describing the route update
271 *@param add 1 if the route is to be added 0 if it is to be deleted
272 *@param int_name the name of the interface the route is set to go by
274 *@return negative on error
277 ipc_route_send_rtentry(const union olsr_ip_addr *dst,
278 const union olsr_ip_addr *gw,
281 const char *int_name)
283 struct ipcmsg packet;
285 if (olsr_cnf->ipc_connections <= 0) {
292 memset(&packet, 0, sizeof(packet));
293 packet.size = htons(IPC_PACK_SIZE);
294 packet.msgtype = ROUTE_IPC;
296 packet.target_addr = *dst;
301 packet.gateway_addr = *gw;
304 if (int_name != NULL) {
305 memcpy(&packet.device[0], int_name, 4);
307 memset(&packet.device[0], 0, 4);
312 for(i = 0; i < IPC_PACK_SIZE;i++)
320 printf(" %03i", (u_char) tmp[i]);
326 if (send(ipc_conn, (void *)&packet, IPC_PACK_SIZE, MSG_NOSIGNAL) < 0) { // MSG_NOSIGNAL to avoid sigpipe
327 OLSR_PRINTF(1, "(RT_ENTRY)IPC connection lost!\n");
328 CLOSESOCKET(ipc_conn);
338 ipc_send_all_routes(int fd)
346 OLSR_FOR_ALL_RT_ENTRIES(rt) {
347 struct ipcmsg packet;
349 memset(&packet, 0, sizeof(packet));
350 packet.size = htons(IPC_PACK_SIZE);
351 packet.msgtype = ROUTE_IPC;
353 packet.target_addr = rt->rt_dst.prefix;
356 packet.metric = rt->rt_best->rtp_metric.hops;
358 packet.gateway_addr = rt->rt_nexthop.gateway;
360 memcpy(&packet.device[0], rt->rt_nexthop.interface->int_name, 4);
362 /* MSG_NOSIGNAL to avoid sigpipe */
363 if (send(fd, (void *)&packet, IPC_PACK_SIZE, MSG_NOSIGNAL) < 0) {
364 OLSR_PRINTF(1, "(RT_ENTRY)IPC connection lost!\n");
365 CLOSESOCKET(ipc_conn);
368 } OLSR_FOR_ALL_RT_ENTRIES_END(rt);
375 *Sends OLSR info to the front-end. This info consists of
376 *the different time intervals and holding times, number
377 *of interfaces, HNA routes and main address.
379 *@return negative on error
382 ipc_send_net_info(int fd)
385 struct ipc_net_msg net_msg;
387 OLSR_PRINTF(1, "Sending net-info to front end...\n");
389 memset(&net_msg, 0, sizeof(net_msg));
392 net_msg.size = htons(sizeof(net_msg));
394 net_msg.msgtype = NET_IPC;
397 /* XXX fix IPC MIDcnt */
398 net_msg.mids = (!list_is_empty(&interface_head)) ? 1 : 0;
401 net_msg.hnas = list_is_empty(&olsr_cnf->hna_entries) ? 0 : 1;
403 /* Different values */
404 /* Temporary fixes */
405 /* XXX fix IPC intervals */
406 net_msg.hello_int = 0;//htons((uint16_t)hello_int);
407 net_msg.hello_lan_int = 0;//htons((uint16_t)hello_int_nw);
408 net_msg.tc_int = 0;//htons((uint16_t)tc_int);
409 net_msg.neigh_hold = 0;//htons((uint16_t)neighbor_hold_time);
410 net_msg.topology_hold = 0;//htons((uint16_t)topology_hold_time);
412 net_msg.ipv6 = olsr_cnf->ip_version == AF_INET ? 0 : 1;
415 net_msg.main_addr = olsr_cnf->router_id;
420 for(i = 0; i < sizeof(struct ipc_net_msg);i++)
428 printf(" %03i", (u_char) msg[i]);
434 if (send(fd, (void *)&net_msg, sizeof(net_msg), MSG_NOSIGNAL) < 0) {
435 OLSR_PRINTF(1, "(NETINFO)IPC connection lost!\n");
436 CLOSESOCKET(ipc_conn);
447 OLSR_PRINTF(1, "Shutting down IPC...\n");
448 CLOSESOCKET(ipc_conn);
454 * indent-tabs-mode: nil