mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-04-13 22:03:09 +00:00
Add manually triggered network scan command
This commit is contained in:
parent
0ca9612a96
commit
3dfd64f4da
@ -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.
|
||||
"<anystring>" marks an arg that can take any value.
|
||||
"[<anystring>]" 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","[<address>]",NULL},0,
|
||||
"Scan the network for serval peers. If no argument is supplied, all local addresses will be scanned."},
|
||||
{app_node_info,{"node","info","<sid>",NULL},0,
|
||||
"Return routing information about a SID"},
|
||||
{app_count_peers,{"peer","count",NULL},0,
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
10
mdp_client.h
10
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();
|
||||
|
@ -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.
|
||||
|
@ -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;i<OVERLAY_MAX_INTERFACES;i++){
|
||||
// skip any interface that is already being scanned
|
||||
if (scans[i].interface)
|
||||
continue;
|
||||
|
||||
struct overlay_interface *interface = &overlay_interfaces[i];
|
||||
if (interface->state!=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);
|
||||
|
6
serval.h
6
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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user