/*
* OLSR ad-hoc routing table management protocol GUI front-end
* Copyright (C) 2003 Andreas Tønnesen (andreto@ifi.uio.no)
*
* This file is part of olsr.org.
*
* uolsrGUI is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* uolsrGUI is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with olsr.org; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "common.h"
#include "ipc.h"
#include "packet.h"
#include "routes.h"
#ifdef WIN32
#define close(x) closesocket(x)
#undef errno
#define errno WSAGetLastError()
#undef strerror
#define strerror(x) StrError(x)
#define perror(x) WinSockPError(x)
#endif
int ipc_socket = 0;
int
ipc_close()
{
if(close(ipc_socket))
return 1;
return 0;
}
int
ipc_connect(struct sockaddr_in *pin)
{
#ifdef WIN32
int On = 1;
unsigned long Len;
#else
int flags;
#endif
connected = 0;
if(!ipc_socket)
if((ipc_socket = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("socket");
exit(1);
}
printf("Attempting connect...");
/* connect to PORT on HOST */
if (connect(ipc_socket,(struct sockaddr *) pin, sizeof(*pin)) < 0)
{
fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno));
set_net_info_offline();
printf("connection refused\n");
}
else
{
set_net_info("Connected!", FALSE);
printf("Connected!!\n");
/* Setting socket non-blocking */
#ifdef WIN32
if (WSAIoctl(ipc_socket, FIONBIO, &On, sizeof (On), NULL, 0, &Len,
NULL, NULL) < 0)
{
fprintf(stderr, "Error while making socket non-blocking!\n");
exit(1);
}
#else
if ((flags = fcntl(ipc_socket, F_GETFL, 0)) < 0)
{
fprintf(stderr,"Error getting socket flags!\n");
exit(1);
}
if (fcntl(ipc_socket, F_SETFL, flags | O_NONBLOCK) < 0)
{
fprintf(stderr,"Error setting socket flags!\n");
exit(1);
}
#endif
connected = 1;
return 1;
}
return 0;
}
int
ipc_read()
{
//int x, i;
int bytes, tmp_len;
char *tmp;
union olsr_message *msg;
union
{
char buf[BUFFSIZE+1];
union olsr_message olsr_msg;
} inbuf;
//char buf[BUFFSIZE+1];
//printf(".");fflush(stdout);
memset(&inbuf, 0, sizeof(BUFFSIZE+1));
//buf[0] = '\0';
if(connected)
{
bytes = recv(ipc_socket, (char *)&inbuf, BUFFSIZE, 0);
if (bytes == 0)
{
shutdown(ipc_socket, SHUT_RDWR);
set_net_info("Disconnected from server...", TRUE);
connected = 0;
close(ipc_socket);
}
if(bytes > 0)
{
tmp = (char *) &inbuf.olsr_msg;
/*
x = 0;
printf("\n\t");
for(i = 0; i < bytes;i++)
{
if(x == 4)
{
x = 0;
printf("\n\t");
}
x++;
printf(" %03i", (u_char) tmp[i]);
}
printf("\n\nBytes read: %d - msg_size: %d\n", bytes, ntohs(inbuf.olsr.v4.olsr_packlen));
*/
msg = &inbuf.olsr_msg;
/* There can be(there probably are!) several packets in the buffer */
/* Should be the same for v4 and v6 */
if(ntohs(inbuf.olsr_msg.v4.olsr_msgsize) < bytes)
{
//printf("chomping...\n");
while(ntohs(msg->v4.olsr_msgsize) < bytes)
{
ipc_evaluate_message(msg);
tmp_len = ntohs(msg->v4.olsr_msgsize);
msg = (union olsr_message *) &tmp[tmp_len];
tmp = &tmp[tmp_len];
if(tmp_len == 0)
break;
bytes = bytes - tmp_len;
tmp_len = ntohs(msg->v4.olsr_msgsize);
//printf("%d/%d ", tmp_len, bytes);
/* Copy to start of buffer */
if(tmp_len > bytes)
{
/* Copy the buffer */
//printf("READING END OF MESSAGE. %d bytes\n", tmp_len-bytes);
//printf("\tCopying %d bytes\n", bytes);
memcpy(&inbuf, tmp, bytes);
//printf("\tRecieving %d bytes to buffer[%d]\n", tmp_len-bytes, bytes);
bytes = recv(ipc_socket, (char *)&inbuf.buf[bytes], tmp_len-bytes, 0);
//printf("\tBytes: %d Size: %d\n", bytes, ntohs(msgs->v4.olsr_packlen));
tmp = (char *)&inbuf.olsr_msg;
msg = (union olsr_message *) tmp;
}
}
//printf("\n");
}
/* Only one (or the last) message */
ipc_evaluate_message(msg);
}
}
return 1;
}
int
ipc_send()
{
return 1;
}
int
ipc_evaluate_message(union olsr_message *olsr_in)
{
int ipc_pack = 0;
olsr_u8_t type;
int msgsize;
char itoa_buf[10];
olsr_u8_t vtime;
union olsr_ip_addr *originator;
/* Find size, vtime, originator and type - same for IPv4 and 6 */
type = olsr_in->v4.olsr_msgtype;
msgsize = ntohs(olsr_in->v4.olsr_msgsize);
vtime = olsr_in->v4.olsr_vtime;
originator = (union olsr_ip_addr *)&olsr_in->v4.originator;
gui_itoa(msgsize, itoa_buf);
switch(type)
{
case HELLO_MESSAGE:
//printf("Recieved HELLO packet\n");
if(!freeze_packets)
packet_list_add("HELLO", ip_to_string(originator), itoa_buf);
if(ipversion == AF_INET)
{
process_hello(msgsize, vtime, originator, (union hello_message *)&olsr_in->v4.message.hello);
}
else
{
process_hello(msgsize, vtime, originator, (union hello_message *)&olsr_in->v6.message.hello);
}
break;
case TC_MESSAGE:
if(!freeze_packets)
packet_list_add("TC", ip_to_string(originator), itoa_buf);
if(ipversion == AF_INET)
{
process_tc(msgsize, vtime, originator, (union tc_message *)&olsr_in->v4.message.tc);
//printf("Recieved TC packet from %s\n", ip_to_string(&m->olsr_tc->tc_origaddr));
}
else
{
process_tc(msgsize, vtime, originator, (union tc_message *)&olsr_in->v6.message.tc);
//printf("Recieved TC packet from %s\n", ip_to_string(&m->olsr_tc->tc_origaddr));
}
break;
case MID_MESSAGE:
if(!freeze_packets)
packet_list_add("MID", ip_to_string(originator), itoa_buf);
if(ipversion == AF_INET)
{
process_mid(msgsize, vtime, originator, (union mid_message *)&olsr_in->v4.message.mid);
//printf("Recieved MID packet from %s\n", ip_to_string(&m->olsr_mid->mid_origaddr));
}
else
{
process_mid(msgsize, vtime, originator, (union mid_message *)&olsr_in->v6.message.mid);
//printf("Recieved MID packet from %s\n", ip_to_string(&m->olsr_mid->mid_origaddr));
}
break;
case HNA_MESSAGE:
if(!freeze_packets)
packet_list_add("HNA", ip_to_string(originator), itoa_buf);
if(ipversion == AF_INET)
{
process_hna(msgsize, vtime, originator, (union hna_message *)&olsr_in->v4.message.hna);
//printf("Recieved HNA packet\n");
}
else
{
process_hna(msgsize, vtime, originator, (union hna_message *)&olsr_in->v6.message.hna);
//printf("Recieved HNA packet\n");
}
break;
case IPC_MESSAGE:
//printf("Recieved IPC packet\n");
ipc_pack = 1; /* Don't add to buffer */
ipc_eval_route_packet((struct routemsg *) olsr_in);
break;
case IPC_NET:
//printf("Recieved IPC packet\n");
ipc_pack = 1; /* Don't add to buffer */
ipc_eval_net_info((struct netmsg *) olsr_in);
break;
default:
if(!freeze_packets)
{
char unk_label[8];
sprintf(unk_label, "%d", type);
packet_list_add(unk_label, ip_to_string(originator), itoa_buf);
}
printf("Unknown packet type %d\n", type);
}
if(!freeze_packets && !ipc_pack)
{
add_packet_to_buffer(olsr_in, msgsize);
}
return 1;
}
int
ipc_eval_net_info(struct netmsg *msg)
{
char info[256];
printf("Evaluating NET info...\n");
/*
printf("\tMain address: %s\n", ip_to_string(&msg->main_addr));
printf("\tMid adresses: %d\n", msg->mids);
printf("\tHna adresses: %d\n", msg->hnas);
printf("\tHELLO interval: %f\n", (float)(ntohs(msg->hello_int)));
printf("\tHELLO LAN interval: %f\n", (float)(ntohs(msg->hello_lan_int)));
printf("\tTC interval: %d\n", ntohs(msg->tc_int));
printf("\tNeighbor hold time: %d\n", ntohs(msg->neigh_hold));
printf("\tTopology hold: %d\n", ntohs(msg->topology_hold));
*/
if(msg->ipv6 == 0)
{
ipversion = AF_INET;
ipsize = sizeof(struct in_addr);
sprintf(&info[0],"IP version 4\nMain address: %s\nMid addresses: %d\nHna addresses: %d\nHELLO interval: %d\nHELLO LAN interval: %d\nTC interval: %d\nNeighbor hold time: %d\nTopology hold: %d\n", ip_to_string(&msg->main_addr), msg->mids, msg->hnas, ntohs(msg->hello_int), ntohs(msg->hello_lan_int), ntohs(msg->tc_int), ntohs(msg->neigh_hold), ntohs(msg->topology_hold));
}
else
{
ipversion = AF_INET6;
ipsize = sizeof(struct in6_addr);
sprintf(&info[0],"IP version 6\nMain address: %s\nMid addresses: %d\nHna addresses: %d\nHELLO interval: %d\nHELLO LAN interval: %d\nTC interval: %d\nNeighbor hold time: %d\nTopology hold: %d\n", ip_to_string(&msg->main_addr), msg->mids, msg->hnas, ntohs(msg->hello_int), ntohs(msg->hello_lan_int), ntohs(msg->tc_int), ntohs(msg->neigh_hold), ntohs(msg->topology_hold));
}
memcpy(&main_addr, &msg->main_addr, ipsize);
set_net_info(&info[0], 0);
return 0;
}
int
ipc_eval_route_packet(struct routemsg *msg)
{
struct route_entry rt_ent;
char dev[5];
char gw[16];
char itoa_buf[10];
dev[4] = '\0';
memset(&gw[0], 0, 16);
printf("Processing route packet\n");
memset(rt_ent.if_name, 0, MAX_IF_NAMESIZ);
/* Fill struct */
memcpy(&rt_ent.gw, &msg->gateway_addr, ipsize);
memcpy(&rt_ent.dst, &msg->target_addr, ipsize);
memcpy(rt_ent.if_name, msg->device, 4);
rt_ent.hopcnt = msg->metric;
if(msg->add)
{
memcpy(&dev[0], &msg->device[0], 4);
/*Add node to node list */
memcpy(&gw[0], ip_to_string(&msg->gateway_addr), 16);
gui_itoa(msg->metric, itoa_buf);
route_list_add(ip_to_string(&msg->target_addr),
gw,
dev,
itoa_buf);
printf("\tRoute to %s(hc %d) added\n", ip_to_string(&msg->target_addr), rt_ent.hopcnt);
/*
printf("\tRoute to %s added\n", ip_to_string(&msg->target_addr));
printf("\tGateway %s\n", gw);
printf("\tInterface %s\n", msg->device);
printf("\tMetric %d\n", msg->metric);
*/
}
else
{
if(route_list_del(ip_to_string(&msg->target_addr)) < 1)
printf("COULD NOT FIND ROUTE TO DELETE!\n\n");
printf("\tRoute to %s deleted\n", ip_to_string(&msg->target_addr));
}
return 1;
}
int
process_hello(int size, olsr_u8_t vtime, union olsr_ip_addr *originator, union hello_message *m)
{
struct hellinfo *neigh;
struct hellinfo6 *neigh6;
int i;
int nsize;
int type, link;
printf("Processing HELLO from %s size = %d\n", ip_to_string(originator), size);
if(!update_timer_node(originator, vtime))
add_node(originator, vtime);
/* Add neighbors if any */
size = size - 4 - 8 - ipsize; /* size of neighbors(size - olsrheder- helloheader) */
if(!size)
return 0;
/* Get the neighbortype-blocks start */
neigh = m->v4.hell_info;
neigh6 = m->v6.hell_info;
//printf("HELLO Size: %d\n", size);
while(size > 0)
{
//printf("\tNEIGH: 0x%x\n", (int)neigh);
if(ipversion == AF_INET)
{
nsize = ntohs(neigh->size);
type = EXTRACT_STATUS(ntohs(neigh->link_code));
link = EXTRACT_LINK(ntohs(neigh->link_code));
//printf("TYPE: %d\n", neigh->link_code);
}
else
{
nsize = ntohs(neigh6->size);
type = EXTRACT_STATUS(ntohs(neigh6->link_code));
link = EXTRACT_LINK(ntohs(neigh6->link_code));
}
size -= nsize;
nsize = nsize - 4; /* - hellinfo header */
//printf("Size left: %d Current hellinfo: %d\n", size, nsize);
i = 0;
while(nsize > 0)
{
//printf("Adding neighbor %s...\n", ip_to_string((union olsr_ip_addr *)&neigh->neigh_addr[i]));
/*
if(MPR)
update_timer_mpr((union olsr_ip_addr *)&mprsinfo->addr, originator);
*/
if(ipversion == AF_INET) /* Update MPRs */
{
if(type == MPR_NEIGH)
{
//printf("MPR from HELLO\n");
update_timer_mpr((union olsr_ip_addr *)&neigh->neigh_addr[i], originator, vtime);
}
add_node((union olsr_ip_addr *)&neigh->neigh_addr[i++], vtime);
}
else
{
if(type == MPR_NEIGH) /* Update MPRs */
{
//printf("MPR from HELLO\n");
update_timer_mpr((union olsr_ip_addr *)&neigh6->neigh_addr[i], originator, vtime);
}
add_node((union olsr_ip_addr *)&neigh6->neigh_addr[i++], vtime);
}
nsize = nsize - ipsize;
//printf("Nsize: %d\n", nsize);
}
neigh = (struct hellinfo *) &neigh->neigh_addr[i];
neigh6 = (struct hellinfo6 *) &neigh6->neigh_addr[i];
}
//printf("DONE\n");
return 0;
}
int
process_tc(int size, olsr_u8_t vtime, union olsr_ip_addr *originator, union tc_message *m)
{
struct neigh_info *mprsinfo;
struct neigh_info6 *mprsinfo6;
printf("Processing TC from %s size = %d\n", ip_to_string(originator), size);
/* Updating timer */
if(!update_timer_node(originator, vtime))
add_node(originator, vtime);
/* Calculate size of the mprsinfo */
size = size - 4 - 8 - ipsize;
//printf("TC Size: %d\n", size);
if(ipversion == AF_INET)
mprsinfo = &m->v4.neigh[0];
else
mprsinfo6 = &m->v6.neigh[0];
while(size > 0)
{
if(ipversion == AF_INET)
{
//printf("\tprocessing TC: %s\n", ip_to_string((union olsr_ip_addr *)&mprsinfo->addr));
add_node((union olsr_ip_addr *)&mprsinfo->addr, vtime);
update_timer_mpr((union olsr_ip_addr *)&mprsinfo->addr, originator, vtime);
mprsinfo++;
}
else
{
//printf("\tprocessing TC: %s\n", ip_to_string((union olsr_ip_addr *)&mprsinfo6->addr));
//printf("TC: add node %s\n", ip_to_string((union olsr_ip_addr *)&mprsinfo6->addr));
add_node((union olsr_ip_addr *)&mprsinfo6->addr, vtime);
update_timer_mpr((union olsr_ip_addr *)&mprsinfo6->addr, originator, vtime);
mprsinfo6++;
}
size = size - ipsize;
//printf("\tsize: %d\n", size);
}
//printf("DONE\n");
return 0;
}
int
process_mid(int size, olsr_u8_t vtime, union olsr_ip_addr *originator, union mid_message *m)
{
struct midaddr *midaddr;
struct midaddr6 *midaddr6;
printf("Processing MID from %s size = %d\n", ip_to_string(originator), size);
/* Calculate size of the midinfo */
size = size - 4 - 4 - ipsize;
if(ipversion == AF_INET)
midaddr = &m->v4.mid_addr[0];
else
midaddr6 = &m->v6.mid_addr[0];
//printf("MID size: %d\n", size);
while(size > 0)
{
if(ipversion == AF_INET)
{
//printf("MID: add node %s\n", ip_to_string((union olsr_ip_addr *)&midaddr->addr));
add_mid_node(originator, (union olsr_ip_addr *)&midaddr->addr, vtime);
midaddr++;
}
else
{
add_mid_node(originator, (union olsr_ip_addr *)&midaddr6->addr, vtime);
//printf("MID: add node %s\n", ip_to_string((union olsr_ip_addr *)&midaddr6->addr));
midaddr6++;
}
size = size - ipsize;
}
//printf("DONE\n");
return 0;
}
int
process_hna(int size, olsr_u8_t vtime, union olsr_ip_addr *originator, union hna_message *m)
{
printf("Processing HNA size = %d\n", size);
struct hnapair *hnapairs;
struct hnapair6 *hnapairs6;
/* Calculate size of the hnainfo */
size = size - 4 - 4 - ipsize;
if(ipversion == AF_INET)
hnapairs = &m->v4.hna_net[0];
else
hnapairs6 = &m->v6.hna_net[0];
while(size > 0)
{
if(ipversion == AF_INET)
{
//printf("\tHNA:%s\n", ip_to_string((union olsr_ip_addr *)&hnapairs->addr));
add_hna_node(originator, (union olsr_ip_addr *)&hnapairs->addr, (union olsr_ip_addr *)&hnapairs->netmask, vtime);
hnapairs++;
}
else
{
add_hna_node(originator, (union olsr_ip_addr *)&hnapairs6->addr, (union olsr_ip_addr *)&hnapairs6->netmask, vtime);
hnapairs6++;
}
size = size - ipsize - ipsize;
}
return 0;
}
char *
ip_to_string(union olsr_ip_addr *addr)
{
char *ret;
struct in_addr in;
if(ipversion == AF_INET)
{
in.s_addr=addr->v4;
ret = inet_ntoa(in);
}
else
{
/* IPv6 */
ret = (char *)inet_ntop(AF_INET6, &addr->v6, ipv6_buf, sizeof(ipv6_buf));
}
return ret;
}
int
gui_itoa(int i, char *buf)
{
char tmp[10];
if(sprintf(buf, "%hd", i))
{
/* This shitty string needs to be converted to UTF-8 */
strcpy(tmp, g_locale_to_utf8(buf, -1, NULL, NULL, NULL));
strcpy(buf, tmp);
return 1;
//return ret;
}
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1