From 2ed6bee0bce738395c940687438bfeee69f56c1f Mon Sep 17 00:00:00 2001 From: c vw Date: Sun, 9 Jan 2022 14:01:33 +0100 Subject: [PATCH] Finalized "routed UDP detection" feature --- new_discovery.c | 166 ++++++++++++++++++++++++++++++++---------------- old_discovery.c | 10 +-- 2 files changed, 116 insertions(+), 60 deletions(-) diff --git a/new_discovery.c b/new_discovery.c index 6039d34..7661377 100644 --- a/new_discovery.c +++ b/new_discovery.c @@ -34,7 +34,7 @@ #include #include "discovered.h" -//#include "discovery.h" +#include "discovery.h" static char interface_name[64]; @@ -46,7 +46,7 @@ static int interface_length; static int discovery_socket; static struct sockaddr_in discovery_addr; -void new_discover(struct ifaddrs* iface); +static void new_discover(struct ifaddrs* iface, int discflag); static GThread *discover_thread_id; gpointer new_discover_receive_thread(gpointer data); @@ -69,6 +69,7 @@ void print_device(int i) { void new_discovery() { struct ifaddrs *addrs,*ifa; + int i,is_local; getifaddrs(&addrs); ifa = addrs; while (ifa) { @@ -77,100 +78,139 @@ void new_discovery() { if(ifa->ifa_addr->sa_family == AF_INET && (ifa->ifa_flags&IFF_UP)==IFF_UP && (ifa->ifa_flags&IFF_RUNNING)==IFF_RUNNING) { - new_discover(ifa); + new_discover(ifa,1); } } ifa = ifa->ifa_next; } freeifaddrs(addrs); + // + // If an IP address has already been "discovered" via a + // METIS broadcast package, it makes no sense to re-discover + // it via a routed UDP packet. + // + is_local=0; + for (i=0; iifa_name); + fprintf(stderr,"new_discover: looking for HPSDR devices on %s\n",interface_name); + + // send a broadcast to locate metis boards on the network + discovery_socket=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP); + if(discovery_socket<0) { + perror("new_discover: create socket failed for discovery_socket\n"); + return; + } + + sa = (struct sockaddr_in *) iface->ifa_addr; + mask = (struct sockaddr_in *) iface->ifa_netmask; + interface_netmask.sin_addr.s_addr = mask->sin_addr.s_addr; + + // bind to this interface and the discovery port + interface_addr.sin_family = AF_INET; + interface_addr.sin_addr.s_addr = sa->sin_addr.s_addr; + interface_addr.sin_port = htons(0); // system assigned port + if(bind(discovery_socket,(struct sockaddr*)&interface_addr,sizeof(interface_addr))<0) { + perror("new_discover: bind socket failed for discovery_socket\n"); + close (discovery_socket); + return; + } + strcpy(addr,inet_ntoa(sa->sin_addr)); + strcpy(net_mask,inet_ntoa(mask->sin_addr)); + fprintf(stderr,"new_discover: bound to %s %s %s\n",interface_name,addr,net_mask); + + // allow broadcast on the socket + int on=1; + rc=setsockopt(discovery_socket, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)); + if(rc != 0) { + fprintf(stderr,"new_discover: cannot set SO_BROADCAST: rc=%d\n", rc); + close (discovery_socket); + return; + } - strcpy(interface_name,iface->ifa_name); - fprintf(stderr,"new_discover: looking for HPSDR devices on %s\n",interface_name); + // setup to address + to_addr.sin_family=AF_INET; + to_addr.sin_port=htons(DISCOVERY_PORT); + to_addr.sin_addr.s_addr=htonl(INADDR_BROADCAST); + break; + case 2: + // + // prepeare socket for sending an UPD packet to ipaddr_radio + // + memset(&to_addr, 0, sizeof(to_addr)); + to_addr.sin_family=AF_INET; + to_addr.sin_port=htons(DISCOVERY_PORT); + if (inet_aton(ipaddr_radio, &to_addr.sin_addr) == 0) { + return; + } + fprintf(stderr,"discover: looking for HPSDR device with IP %s\n", ipaddr_radio); - // send a broadcast to locate metis boards on the network - discovery_socket=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP); - if(discovery_socket<0) { - perror("new_discover: create socket failed for discovery_socket\n"); - exit(-1); + discovery_socket=socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP); + if(discovery_socket<0) { + perror("discover: create socket failed for discovery_socket:"); + return; + } + break; + default: + return; + break; } int optval = 1; setsockopt(discovery_socket, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); setsockopt(discovery_socket, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)); - sa = (struct sockaddr_in *) iface->ifa_addr; - mask = (struct sockaddr_in *) iface->ifa_netmask; - - interface_netmask.sin_addr.s_addr = mask->sin_addr.s_addr; - - // bind to this interface and the discovery port - interface_addr.sin_family = AF_INET; - interface_addr.sin_addr.s_addr = sa->sin_addr.s_addr; - interface_addr.sin_port = htons(0); - if(bind(discovery_socket,(struct sockaddr*)&interface_addr,sizeof(interface_addr))<0) { - perror("new_discover: bind socket failed for discovery_socket\n"); - exit(-1); - } - - strcpy(addr,inet_ntoa(sa->sin_addr)); - strcpy(net_mask,inet_ntoa(mask->sin_addr)); - - fprintf(stderr,"new_discover: bound to %s %s %s\n",interface_name,addr,net_mask); - - // allow broadcast on the socket - int on=1; - rc=setsockopt(discovery_socket, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)); - if(rc != 0) { - fprintf(stderr,"new_discover: cannot set SO_BROADCAST: rc=%d\n", rc); - exit(-1); - } - - // setup to address - struct sockaddr_in to_addr={0}; - to_addr.sin_family=AF_INET; - to_addr.sin_port=htons(DISCOVERY_PORT); - to_addr.sin_addr.s_addr=htonl(INADDR_BROADCAST); - + rc=devices; // start a receive thread to collect discovery response packets discover_thread_id = g_thread_new( "new discover receive", new_discover_receive_thread, NULL); - if( ! discover_thread_id ) - { - fprintf(stderr,"g_thread_new failed on new_discover_receive_thread\n"); - exit( -1 ); - } - fprintf(stderr,"new_disovery: thread_id=%p\n",discover_thread_id); - // send discovery packet - unsigned char buffer[60]; buffer[0]=0x00; buffer[1]=0x00; buffer[2]=0x00; buffer[3]=0x00; buffer[4]=0x02; - int i; for(i=5;i<60;i++) { buffer[i]=0x00; } if(sendto(discovery_socket,buffer,60,0,(struct sockaddr*)&to_addr,sizeof(to_addr))<0) { perror("new_discover: sendto socket failed for discovery_socket\n"); + close (discovery_socket); return; } @@ -179,7 +219,23 @@ void new_discover(struct ifaddrs* iface) { close(discovery_socket); - fprintf(stderr,"new_discover: exiting discover for %s\n",iface->ifa_name); + switch (discflag) { + case 1: + fprintf(stderr,"new_discover: exiting discover for %s\n",iface->ifa_name); + break; + case 2: + fprintf(stderr,"discover: exiting HPSDR discover for IP %s\n",ipaddr_radio); + if (devices == rc+1) { + // + // METIS detection UDP packet sent to fixed IP address got a valid response. + // + memcpy((void *)&discovered[rc].info.network.address, (void *)&to_addr,sizeof(to_addr)); + discovered[rc].info.network.address_length = sizeof(to_addr); + strcpy(discovered[rc].info.network.interface_name,"UDP"); + discovered[rc].use_routing=1; + } + break; + } } //void* new_discover_receive_thread(void* arg) { diff --git a/old_discovery.c b/old_discovery.c index 6d48f36..c38137f 100644 --- a/old_discovery.c +++ b/old_discovery.c @@ -95,6 +95,7 @@ static void discover(struct ifaddrs* iface, int discflag) { interface_addr.sin_port = htons(0); // system assigned port if(bind(discovery_socket,(struct sockaddr*)&interface_addr,sizeof(interface_addr))<0) { perror("discover: bind socket failed for discovery_socket:"); + close (discovery_socket); return; } @@ -105,6 +106,7 @@ static void discover(struct ifaddrs* iface, int discflag) { rc=setsockopt(discovery_socket, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)); if(rc != 0) { fprintf(stderr,"discover: cannot set SO_BROADCAST: rc=%d\n", rc); + close (discovery_socket); return; } @@ -238,6 +240,7 @@ static void discover(struct ifaddrs* iface, int discflag) { if(sendto(discovery_socket,buffer,len,0,(struct sockaddr*)&to_addr,sizeof(to_addr))<0) { perror("discover: sendto socket failed for discovery_socket:"); + close (discovery_socket); return; } @@ -272,9 +275,6 @@ static void discover(struct ifaddrs* iface, int discflag) { // memcpy((void*)&discovered[rc].info.network.address,(void*)&to_addr,sizeof(to_addr)); discovered[rc].info.network.address_length=sizeof(to_addr); - memcpy((void*)&discovered[rc].info.network.interface_address,(void*)&to_addr,sizeof(to_addr)); - memcpy((void*)&discovered[rc].info.network.interface_netmask,(void*)&to_addr,sizeof(to_addr)); - discovered[rc].info.network.interface_length=sizeof(to_addr); strcpy(discovered[rc].info.network.interface_name,"TCP"); discovered[rc].use_routing=1; discovered[rc].use_tcp=1; @@ -456,8 +456,8 @@ fprintf(stderr,"old_discovery\n"); // is_local=0; for (i=0; i