2 * OLSR ad-hoc routing table management protocol
3 * Copyright (C) 2003 Andreas Tønnesen (andreto@ifi.uio.no)
5 * This file is part of the olsr.org OLSR daemon.
7 * olsr.org is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * olsr.org is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with olsr.org; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *Andreas Tønnesen (andreto@ifi.uio.no)
26 *IPC - interprocess communication
27 *for the OLSRD - GUI front-end
31 #include "ipc_frontend.h"
35 #include "local_hna_set.h"
38 #define close(x) closesocket(x)
39 #define perror(x) WinSockPError(x)
40 #define MSG_NOSIGNAL 0
42 WinSockPError(char *);
45 pthread_t accept_thread;
48 *Create the socket to use for IPC to the
51 *@return the socket FD
57 struct sockaddr_in sin;
59 /* Add parser function */
60 olsr_parser_add_function(&frontend_msgparser, PROMISCUOUS, 0);
62 /* get an internet domain socket */
63 if ((ipc_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
66 olsr_exit("IPC socket", EXIT_FAILURE);
69 /* complete the socket structure */
70 memset(&sin, 0, sizeof(sin));
71 sin.sin_family = AF_INET;
72 sin.sin_addr.s_addr = INADDR_ANY;
73 sin.sin_port = htons(IPC_PORT);
75 /* bind the socket to the port number */
76 if (bind(ipc_sock, (struct sockaddr *) &sin, sizeof(sin)) == -1)
79 olsr_exit("IPC bind", EXIT_FAILURE);
82 /* show that we are willing to listen */
83 if (listen(ipc_sock, 5) == -1)
86 olsr_exit("IPC listen", EXIT_FAILURE);
90 /* Start the accept thread */
92 pthread_create(&accept_thread, NULL, (void *)&ipc_accept_thread, NULL);
102 struct sockaddr_in pin;
107 olsr_printf(2, "\nFront-end accept thread initiated(socket %d)\n\n", ipc_sock);
109 addrlen = sizeof (struct sockaddr_in);
111 if ((ipc_connection = accept(ipc_sock, (struct sockaddr *) &pin, &addrlen)) == -1)
113 perror("IPC accept");
114 olsr_exit("IPC accept", EXIT_FAILURE);
118 olsr_printf(1, "Front end connected\n");
119 addr = inet_ntoa(pin.sin_addr);
120 if(ntohl(pin.sin_addr.s_addr) != INADDR_LOOPBACK)
122 olsr_printf(1, "Front end-connection from foregin host(%s) not allowed!\n", addr);
123 olsr_syslog(OLSR_LOG_ERR, "OLSR: Front end-connection from foregin host(%s) not allowed!\n", addr);
124 close(ipc_connection);
130 ipc_send_all_routes();
131 olsr_printf(1, "Connection from %s\n",addr);
142 *Read input from the IPC socket. Not in use.
144 *@todo for future use
145 *@param sock the IPC socket
154 char buf[MAXPACKETSIZE+1];
159 if (recv(sock, dir, sizeof(dir), 0) == -1)
170 *Sends a olsr packet on the IPC socket.
172 *@param olsr the olsr struct representing the packet
174 *@return negative on error
177 frontend_msgparser(union olsr_message *msg, struct interface *in_if, union olsr_ip_addr *from_addr)
184 if(ipversion == AF_INET)
185 size = ntohs(msg->v4.olsr_msgsize);
187 size = ntohs(msg->v6.olsr_msgsize);
189 if (send(ipc_connection, (void *)msg, size, MSG_NOSIGNAL) < 0)
191 olsr_printf(1, "(OUTPUT)IPC connection lost!\n");
192 close(ipc_connection);
203 *Send a route table update to the front-end.
205 *@param kernel_route a rtentry describing the route update
206 *@param add 1 if the route is to be added 0 if it is to be deleted
207 *@param int_name the name of the interface the route is set to go by
209 *@return negative on error
212 ipc_route_send_rtentry(union olsr_kernel_route *kernel_route, int add, char *int_name)
214 struct ipcmsg packet;
221 packet.size = htons(IPC_PACK_SIZE);
222 packet.msgtype = ROUTE_IPC;
224 if(ipversion == AF_INET)
225 COPY_IP(&packet.target_addr, &((struct sockaddr_in *)&kernel_route->v4.rt_dst)->sin_addr.s_addr);
227 COPY_IP(&packet.target_addr, &kernel_route->v6.rtmsg_dst);
232 if(ipversion == AF_INET)
234 packet.metric = kernel_route->v4.rt_metric - 1;
235 COPY_IP(&packet.gateway_addr, &((struct sockaddr_in *)&kernel_route->v4.rt_gateway)->sin_addr.s_addr);
239 packet.metric = kernel_route->v6.rtmsg_metric;
240 COPY_IP(&packet.gateway_addr, &kernel_route->v6.rtmsg_gateway);
244 memcpy(&packet.device[0], int_name, 4);
246 memset(&packet.device[0], 0, 4);
250 memset(&packet.metric, 0, 1);
251 memset(&packet.gateway_addr, 0, 4);
252 memset(&packet.device[0], 0, 4);
256 tmp = (char *) &packet;
259 for(i = 0; i < IPC_PACK_SIZE;i++)
267 printf(" %03i", (u_char) tmp[i]);
273 if (send(ipc_connection, tmp, IPC_PACK_SIZE, MSG_NOSIGNAL) < 0) // MSG_NOSIGNAL to avoid sigpipe
275 olsr_printf(1, "(RT_ENTRY)IPC connection lost!\n");
276 close(ipc_connection);
288 ipc_send_all_routes()
290 struct rt_entry *destination;
291 struct interface *ifn;
293 struct ipcmsg packet;
300 for(index=0;index<HASHSIZE;index++)
302 for(destination = routingtable[index].next;
303 destination != &routingtable[index];
304 destination = destination->next)
306 ifn = get_interface_link_set(&destination->rt_router);
310 packet.size = htons(IPC_PACK_SIZE);
311 packet.msgtype = ROUTE_IPC;
313 COPY_IP(&packet.target_addr, &destination->rt_dst);
317 if(ipversion == AF_INET)
319 packet.metric = (olsr_u8_t)(destination->rt_metric - 1);
323 packet.metric = (olsr_u8_t)destination->rt_metric;
325 COPY_IP(&packet.gateway_addr, &destination->rt_router);
328 memcpy(&packet.device[0], ifn->int_name, 4);
330 memset(&packet.device[0], 0, 4);
333 tmp = (char *) &packet;
335 if (send(ipc_connection, tmp, IPC_PACK_SIZE, MSG_NOSIGNAL) < 0) // MSG_NOSIGNAL to avoid sigpipe
337 olsr_printf(1, "(RT_ENTRY)IPC connection lost!\n");
338 close(ipc_connection);
347 for(index=0;index<HASHSIZE;index++)
349 for(destination = hna_routes[index].next;
350 destination != &hna_routes[index];
351 destination = destination->next)
353 ifn = get_interface_link_set(&destination->rt_router);
355 packet.size = htons(IPC_PACK_SIZE);
356 packet.msgtype = ROUTE_IPC;
358 COPY_IP(&packet.target_addr, &destination->rt_dst);
362 if(ipversion == AF_INET)
364 packet.metric = (olsr_u8_t)(destination->rt_metric - 1);
368 packet.metric = (olsr_u8_t)destination->rt_metric;
370 COPY_IP(&packet.gateway_addr, &destination->rt_router);
373 memcpy(&packet.device[0], ifn->int_name, 4);
375 memset(&packet.device[0], 0, 4);
378 tmp = (char *) &packet;
380 if (send(ipc_connection, tmp, IPC_PACK_SIZE, MSG_NOSIGNAL) < 0) // MSG_NOSIGNAL to avoid sigpipe
382 olsr_printf(1, "(RT_ENTRY)IPC connection lost!\n");
383 close(ipc_connection);
399 *Sends OLSR info to the front-end. This info consists of
400 *the different time intervals and holding times, number
401 *of interfaces, HNA routes and main address.
403 *@return negative on error
408 struct ipc_net_msg *net_msg;
413 net_msg = olsr_malloc(sizeof(struct ipc_net_msg), "send net info");
415 msg = (char *)net_msg;
417 olsr_printf(1, "Sending net-info to front end...\n");
419 memset(net_msg, 0, sizeof(struct ipc_net_msg));
422 net_msg->size = htons(sizeof(struct ipc_net_msg));
424 net_msg->msgtype = NET_IPC;
427 net_msg->mids = nbinterf - 1;
430 if(ipversion == AF_INET6)
432 if(local_hna6_set.next == &local_hna6_set)
438 if(ipversion == AF_INET)
440 if(local_hna4_set.next == &local_hna4_set)
446 /* Different values */
447 net_msg->hello_int = htons((olsr_u16_t)hello_int);
448 net_msg->hello_lan_int = htons((olsr_u16_t)hello_int_nw);
449 net_msg->tc_int = htons((olsr_u16_t)tc_int);
450 net_msg->neigh_hold = htons((olsr_u16_t)neighbor_hold_time);
451 net_msg->topology_hold = htons((olsr_u16_t)topology_hold_time);
453 if(ipversion == AF_INET)
459 COPY_IP(&net_msg->main_addr, &main_addr);
465 for(i = 0; i < sizeof(struct ipc_net_msg);i++)
473 printf(" %03i", (u_char) msg[i]);
480 if (send(ipc_connection, (char *)net_msg, sizeof(struct ipc_net_msg), MSG_NOSIGNAL) < 0)
482 olsr_printf(1, "(NETINFO)IPC connection lost!\n");
483 close(ipc_connection);
498 pthread_kill(accept_thread, SIGTERM);
502 close(ipc_connection);