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
22 * $Id: ipc_frontend.c,v 1.10 2004/11/05 02:06:13 tlopatic Exp $
27 *Andreas Tønnesen (andreto@ifi.uio.no)
29 *IPC - interprocess communication
30 *for the OLSRD - GUI front-end
34 #include "ipc_frontend.h"
38 #include "local_hna_set.h"
41 #define close(x) closesocket(x)
42 #define perror(x) WinSockPError(x)
43 #define MSG_NOSIGNAL 0
45 WinSockPError(char *);
46 #elif defined __FreeBSD__
47 #define MSG_NOSIGNAL 0
50 pthread_t accept_thread;
53 *Create the socket to use for IPC to the
56 *@return the socket FD
62 struct sockaddr_in sin;
64 /* Add parser function */
65 olsr_parser_add_function(&frontend_msgparser, PROMISCUOUS, 0);
67 /* get an internet domain socket */
68 if ((ipc_sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
71 olsr_exit("IPC socket", EXIT_FAILURE);
74 /* complete the socket structure */
75 memset(&sin, 0, sizeof(sin));
76 sin.sin_family = AF_INET;
77 sin.sin_addr.s_addr = INADDR_ANY;
78 sin.sin_port = htons(IPC_PORT);
80 /* bind the socket to the port number */
81 if (bind(ipc_sock, (struct sockaddr *) &sin, sizeof(sin)) == -1)
84 olsr_exit("IPC bind", EXIT_FAILURE);
87 /* show that we are willing to listen */
88 if (listen(ipc_sock, 5) == -1)
91 olsr_exit("IPC listen", EXIT_FAILURE);
95 /* Start the accept thread */
97 pthread_create(&accept_thread, NULL, (void *)&ipc_accept_thread, NULL);
104 * XXX - the socket should just be registered with the socket parser.
105 * Should NOT spawn this listen thread!
111 struct sockaddr_in pin;
114 while(olsr_cnf->open_ipc)
116 olsr_printf(2, "\nFront-end accept thread initiated(socket %d)\n\n", ipc_sock);
118 addrlen = sizeof (struct sockaddr_in);
120 if ((ipc_connection = accept(ipc_sock, (struct sockaddr *) &pin, &addrlen)) == -1)
122 perror("IPC accept");
123 olsr_exit("IPC accept", EXIT_FAILURE);
127 olsr_printf(1, "Front end connected\n");
128 addr = inet_ntoa(pin.sin_addr);
129 if(ntohl(pin.sin_addr.s_addr) != INADDR_LOOPBACK)
131 olsr_printf(1, "Front end-connection from foregin host(%s) not allowed!\n", addr);
132 olsr_syslog(OLSR_LOG_ERR, "OLSR: Front end-connection from foregin host(%s) not allowed!\n", addr);
133 close(ipc_connection);
139 ipc_send_all_routes();
140 olsr_printf(1, "Connection from %s\n",addr);
151 *Read input from the IPC socket. Not in use.
153 *@todo for future use
154 *@param sock the IPC socket
163 char buf[MAXPACKETSIZE+1];
168 if (recv(sock, dir, sizeof(dir), 0) == -1)
179 *Sends a olsr packet on the IPC socket.
181 *@param olsr the olsr struct representing the packet
183 *@return negative on error
186 frontend_msgparser(union olsr_message *msg, struct interface *in_if, union olsr_ip_addr *from_addr)
193 if(olsr_cnf->ip_version == AF_INET)
194 size = ntohs(msg->v4.olsr_msgsize);
196 size = ntohs(msg->v6.olsr_msgsize);
198 if (send(ipc_connection, (void *)msg, size, MSG_NOSIGNAL) < 0)
200 olsr_printf(1, "(OUTPUT)IPC connection lost!\n");
201 close(ipc_connection);
202 //olsr_cnf->open_ipc = 0;
212 *Send a route table update to the front-end.
214 *@param kernel_route a rtentry describing the route update
215 *@param add 1 if the route is to be added 0 if it is to be deleted
216 *@param int_name the name of the interface the route is set to go by
218 *@return negative on error
221 ipc_route_send_rtentry(union olsr_kernel_route *kernel_route, int add, char *int_name)
223 struct ipcmsg packet;
230 packet.size = htons(IPC_PACK_SIZE);
231 packet.msgtype = ROUTE_IPC;
233 if(olsr_cnf->ip_version == AF_INET)
234 COPY_IP(&packet.target_addr, &((struct sockaddr_in *)&kernel_route->v4.rt_dst)->sin_addr.s_addr);
236 COPY_IP(&packet.target_addr, &kernel_route->v6.rtmsg_dst);
241 if(olsr_cnf->ip_version == AF_INET)
243 packet.metric = kernel_route->v4.rt_metric - 1;
244 COPY_IP(&packet.gateway_addr, &((struct sockaddr_in *)&kernel_route->v4.rt_gateway)->sin_addr.s_addr);
248 packet.metric = kernel_route->v6.rtmsg_metric;
249 COPY_IP(&packet.gateway_addr, &kernel_route->v6.rtmsg_gateway);
253 memcpy(&packet.device[0], int_name, 4);
255 memset(&packet.device[0], 0, 4);
259 memset(&packet.metric, 0, 1);
260 memset(&packet.gateway_addr, 0, 4);
261 memset(&packet.device[0], 0, 4);
265 tmp = (char *) &packet;
268 for(i = 0; i < IPC_PACK_SIZE;i++)
276 printf(" %03i", (u_char) tmp[i]);
282 if (send(ipc_connection, tmp, IPC_PACK_SIZE, MSG_NOSIGNAL) < 0) // MSG_NOSIGNAL to avoid sigpipe
284 olsr_printf(1, "(RT_ENTRY)IPC connection lost!\n");
285 close(ipc_connection);
286 //olsr_cnf->open_ipc = 0;
297 ipc_send_all_routes()
299 struct rt_entry *destination;
300 struct interface *ifn;
302 struct ipcmsg packet;
309 for(index=0;index<HASHSIZE;index++)
311 for(destination = routingtable[index].next;
312 destination != &routingtable[index];
313 destination = destination->next)
315 ifn = get_interface_link_set(&destination->rt_router);
319 packet.size = htons(IPC_PACK_SIZE);
320 packet.msgtype = ROUTE_IPC;
322 COPY_IP(&packet.target_addr, &destination->rt_dst);
326 if(olsr_cnf->ip_version == AF_INET)
328 packet.metric = (olsr_u8_t)(destination->rt_metric - 1);
332 packet.metric = (olsr_u8_t)destination->rt_metric;
334 COPY_IP(&packet.gateway_addr, &destination->rt_router);
337 memcpy(&packet.device[0], ifn->int_name, 4);
339 memset(&packet.device[0], 0, 4);
342 tmp = (char *) &packet;
344 if (send(ipc_connection, tmp, IPC_PACK_SIZE, MSG_NOSIGNAL) < 0) // MSG_NOSIGNAL to avoid sigpipe
346 olsr_printf(1, "(RT_ENTRY)IPC connection lost!\n");
347 close(ipc_connection);
348 //olsr_cnf->open_ipc = 0;
356 for(index=0;index<HASHSIZE;index++)
358 for(destination = hna_routes[index].next;
359 destination != &hna_routes[index];
360 destination = destination->next)
362 ifn = get_interface_link_set(&destination->rt_router);
364 packet.size = htons(IPC_PACK_SIZE);
365 packet.msgtype = ROUTE_IPC;
367 COPY_IP(&packet.target_addr, &destination->rt_dst);
371 if(olsr_cnf->ip_version == AF_INET)
373 packet.metric = (olsr_u8_t)(destination->rt_metric - 1);
377 packet.metric = (olsr_u8_t)destination->rt_metric;
379 COPY_IP(&packet.gateway_addr, &destination->rt_router);
382 memcpy(&packet.device[0], ifn->int_name, 4);
384 memset(&packet.device[0], 0, 4);
387 tmp = (char *) &packet;
389 if (send(ipc_connection, tmp, IPC_PACK_SIZE, MSG_NOSIGNAL) < 0) // MSG_NOSIGNAL to avoid sigpipe
391 olsr_printf(1, "(RT_ENTRY)IPC connection lost!\n");
392 close(ipc_connection);
393 //olsr_cnf->open_ipc = 0;
408 *Sends OLSR info to the front-end. This info consists of
409 *the different time intervals and holding times, number
410 *of interfaces, HNA routes and main address.
412 *@return negative on error
417 struct ipc_net_msg *net_msg;
422 net_msg = olsr_malloc(sizeof(struct ipc_net_msg), "send net info");
424 msg = (char *)net_msg;
426 olsr_printf(1, "Sending net-info to front end...\n");
428 memset(net_msg, 0, sizeof(struct ipc_net_msg));
431 net_msg->size = htons(sizeof(struct ipc_net_msg));
433 net_msg->msgtype = NET_IPC;
436 #warning fix IPC MIDcnt
437 net_msg->mids = (ifnet != NULL && ifnet->int_next != NULL) ? 1 : 0;
440 if(olsr_cnf->ip_version == AF_INET6)
442 if(olsr_cnf->hna6_entries == NULL)
448 if(olsr_cnf->ip_version == AF_INET)
450 if(olsr_cnf->hna4_entries == NULL)
456 /* Different values */
457 /* Temporary fixes */
458 #warning fix IPC intervals
459 net_msg->hello_int = 0;//htons((olsr_u16_t)hello_int);
460 net_msg->hello_lan_int = 0;//htons((olsr_u16_t)hello_int_nw);
461 net_msg->tc_int = 0;//htons((olsr_u16_t)tc_int);
462 net_msg->neigh_hold = 0;//htons((olsr_u16_t)neighbor_hold_time);
463 net_msg->topology_hold = 0;//htons((olsr_u16_t)topology_hold_time);
465 if(olsr_cnf->ip_version == AF_INET)
471 COPY_IP(&net_msg->main_addr, &main_addr);
477 for(i = 0; i < sizeof(struct ipc_net_msg);i++)
485 printf(" %03i", (u_char) msg[i]);
492 if (send(ipc_connection, (char *)net_msg, sizeof(struct ipc_net_msg), MSG_NOSIGNAL) < 0)
494 olsr_printf(1, "(NETINFO)IPC connection lost!\n");
495 close(ipc_connection);
496 olsr_cnf->open_ipc = 0;
510 pthread_kill(accept_thread, SIGTERM);
514 close(ipc_connection);