From 3dfd64f4dae123de510561de6cbc94be26e7832c Mon Sep 17 00:00:00 2001 From: Jeremy Lakeman Date: Wed, 5 Dec 2012 15:13:47 +1030 Subject: [PATCH] Add manually triggered network scan command --- commandline.c | 29 ++++++++++++++++ constants.h | 1 + mdp_client.c | 3 ++ mdp_client.h | 10 ++++++ overlay_interface.c | 3 ++ overlay_mdp.c | 81 ++++++++++++++++++++++++++++++++++++++++++++- serval.h | 6 ---- 7 files changed, 126 insertions(+), 7 deletions(-) diff --git a/commandline.c b/commandline.c index e2534409..03155f6f 100644 --- a/commandline.c +++ b/commandline.c @@ -1874,6 +1874,33 @@ int app_reverse_lookup(int argc, const char *const *argv, struct command_line_op return 0; } +int app_network_scan(int argc, const char *const *argv, struct command_line_option *o, void *context) +{ + overlay_mdp_frame mdp; + bzero(&mdp,sizeof(mdp)); + + mdp.packetTypeAndFlags=MDP_SCAN; + + struct overlay_mdp_scan *scan = (struct overlay_mdp_scan *)&mdp.raw; + const char *address; + if (cli_arg(argc, argv, o, "address", &address, NULL, NULL) == -1) + return -1; + + if (address){ + DEBUGF("Parsing arg %s", address); + if (!inet_aton(address, &scan->addr)) + return WHY("Unable to parse the address"); + }else + DEBUGF("Scanning local networks"); + + overlay_mdp_send(&mdp,MDP_AWAITREPLY,5000); + if (mdp.packetTypeAndFlags!=MDP_ERROR) + return -1; + cli_puts(mdp.error.message); + cli_delim("\n"); + return mdp.error.error; +} + /* NULL marks ends of command structure. "" marks an arg that can take any value. "[]" marks an optional arg that can take any value. @@ -1963,6 +1990,8 @@ struct command_line_option command_line_options[]={ "Return identity of all known peers as URIs"}, {app_route_print, {"route","print",NULL},0, "Print the routing table"}, + {app_network_scan, {"scan","[
]",NULL},0, + "Scan the network for serval peers. If no argument is supplied, all local addresses will be scanned."}, {app_node_info,{"node","info","",NULL},0, "Return routing information about a SID"}, {app_count_peers,{"peer","count",NULL},0, diff --git a/constants.h b/constants.h index e50c3416..3fc0d295 100644 --- a/constants.h +++ b/constants.h @@ -147,6 +147,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #define MDP_ROUTING_TABLE 7 #define MDP_NODEINFO 8 #define MDP_GOODBYE 9 +#define MDP_SCAN 10 // These are back-compatible with the old values of 'mode' when it was 'selfP' #define MDP_ADDRLIST_MODE_ROUTABLE_PEERS 0 diff --git a/mdp_client.c b/mdp_client.c index 781036ed..c2f3e001 100644 --- a/mdp_client.c +++ b/mdp_client.c @@ -294,6 +294,9 @@ int overlay_mdp_relevant_bytes(overlay_mdp_frame *mdp) case MDP_BIND: len=(&mdp->raw[0] - (char *)mdp) + sizeof(sockaddr_mdp); break; + case MDP_SCAN: + len=(&mdp->raw[0] - (char *)mdp) + sizeof(struct overlay_mdp_scan); + break; case MDP_ERROR: /* This formulation is used so that we don't copy any bytes after the end of the string, to avoid information leaks */ diff --git a/mdp_client.h b/mdp_client.h index 2459d28f..3e2cb56f 100644 --- a/mdp_client.h +++ b/mdp_client.h @@ -21,6 +21,16 @@ #include "serval.h" +struct overlay_route_record{ + unsigned char sid[SID_SIZE]; + int reachable; + unsigned char neighbour[SID_SIZE]; +}; + +struct overlay_mdp_scan{ + struct in_addr addr; +}; + /* Client-side MDP function */ extern int mdp_client_socket; int overlay_mdp_client_init(); diff --git a/overlay_interface.c b/overlay_interface.c index 60f6cedc..ae3ca621 100644 --- a/overlay_interface.c +++ b/overlay_interface.c @@ -484,6 +484,9 @@ overlay_interface_init(char *name, struct in_addr src_addr, struct in_addr netma char option_name[64]; snprintf(option_name, sizeof(option_name), "mdp.%s.tick_ms", (*name=='>'?name+1:name)); interface->tick_ms = confValueGetInt64Range(option_name, interface->tick_ms, 1LL, 3600000LL); + + snprintf(option_name, sizeof(option_name), "interface.%s.default_route", (*name=='>'?name+1:name)); + interface->default_route=confValueGetBoolean(option_name,0); } // disable announcements and other broadcasts if tick_ms=0. diff --git a/overlay_mdp.c b/overlay_mdp.c index e9a441c6..35d59a4c 100644 --- a/overlay_mdp.c +++ b/overlay_mdp.c @@ -859,6 +859,39 @@ static int routing_table(struct subscriber *subscriber, void *context){ return 0; } +struct scan_state{ + struct sched_ent alarm; + overlay_interface *interface; + uint32_t current; + uint32_t last; +}; +struct scan_state scans[OVERLAY_MAX_INTERFACES]; + +static void overlay_mdp_scan(struct sched_ent *alarm) +{ + struct sockaddr_in addr={ + .sin_family=AF_INET, + .sin_port=htons(PORT_DNA), + }; + struct scan_state *state = (struct scan_state *)alarm; + + while(state->current <= state->last){ + addr.sin_addr.s_addr=htonl(state->current); + if (overlay_send_probe(NULL, addr, state->interface)) + break; + state->current++; + } + + if (state->current <= state->last){ + alarm->alarm=gettime_ms()+500; + schedule(alarm); + }else{ + state->interface=NULL; + state->current=0; + state->last=0; + } +} + void overlay_mdp_poll(struct sched_ent *alarm) { if (alarm->poll.revents & POLLIN) { @@ -905,7 +938,7 @@ void overlay_mdp_poll(struct sched_ent *alarm) } return; - + case MDP_GETADDRS: { overlay_mdp_frame mdpreply; @@ -955,6 +988,52 @@ void overlay_mdp_poll(struct sched_ent *alarm) } break; + case MDP_SCAN: + { + struct overlay_mdp_scan *scan = (struct overlay_mdp_scan *)&mdp->raw; + time_ms_t start=gettime_ms(); + + if (scan->addr.s_addr==0){ + int i=0; + for (i=0;istate!=INTERFACE_STATE_UP) + continue; + + scans[i].interface = interface; + scans[i].current = ntohl(interface->address.sin_addr.s_addr & interface->netmask.s_addr); + scans[i].last = ntohl(interface->broadcast_address.sin_addr.s_addr); + scans[i].alarm.alarm=start; + scans[i].alarm.function=overlay_mdp_scan; + start+=100; + schedule(&scans[i].alarm); + } + }else{ + struct overlay_interface *interface = overlay_interface_find(scan->addr); + if (!interface){ + overlay_mdp_reply_error(alarm->poll.fd,recvaddr_un,recvaddrlen, 1, "Unable to find matching interface"); + return; + } + int i = interface - overlay_interfaces; + + if (!scans[i].interface){ + scans[i].interface = interface; + scans[i].current = ntohl(scan->addr.s_addr); + scans[i].last = ntohl(scan->addr.s_addr); + scans[i].alarm.alarm=start; + scans[i].alarm.function=overlay_mdp_scan; + schedule(&scans[i].alarm); + } + } + + overlay_mdp_reply_ok(alarm->poll.fd,recvaddr_un,recvaddrlen,"Scan initiated"); + } + break; + default: /* Client is not allowed to send any other frame type */ WARNF("Unsupported MDP frame type: %d", mdp_type); diff --git a/serval.h b/serval.h index c6e772bd..b81ada20 100644 --- a/serval.h +++ b/serval.h @@ -560,12 +560,6 @@ typedef struct overlay_mdp_addrlist { unsigned char sids[MDP_MAX_SID_REQUEST][SID_SIZE]; } overlay_mdp_addrlist; -struct overlay_route_record{ - unsigned char sid[SID_SIZE]; - int reachable; - unsigned char neighbour[SID_SIZE]; -}; - typedef struct overlay_mdp_nodeinfo { unsigned char sid[SID_SIZE]; int sid_prefix_length; /* must be long enough to be unique */