aboutsummaryrefslogtreecommitdiff
path: root/networking
diff options
context:
space:
mode:
authorBjørn Mork <bjorn@mork.no>2015-05-15 10:25:21 +0200
committerBjørn Mork <bjorn@mork.no>2015-05-15 10:25:21 +0200
commitb8c5c3b44362778c099531f7a905c56a0423bcef (patch)
treee9ccaff5d19f39e7bc58734e1b5babf4025a3a9c /networking
parentb1b227fa5e00d08af047ab9a012211b66c6b0f13 (diff)
ripe-atlas-fw: imported version 46504650
Signed-off-by: Bjørn Mork <bjorn@mork.no>
Diffstat (limited to 'networking')
-rw-r--r--networking/Config.in6
-rw-r--r--networking/Kbuild2
-rw-r--r--networking/atlasinit.c740
-rw-r--r--networking/rptaddrs.c775
-rw-r--r--networking/rptra6.c2
5 files changed, 1520 insertions, 5 deletions
diff --git a/networking/Config.in b/networking/Config.in
index cdf067a..84c89ad 100644
--- a/networking/Config.in
+++ b/networking/Config.in
@@ -705,11 +705,11 @@ config RPTRA6
help
Report received IPv6 router advertisements
-config RPTADDR6
- bool "rptaddr6"
+config RPTADDRS
+ bool "rptaddrs"
default n
help
- Report IPv6 addresses and routes
+ Report addresses, routes, dns both static and dynamic
config RXTXRPT
bool "rxtxrpt"
diff --git a/networking/Kbuild b/networking/Kbuild
index ddb143a..d550ed4 100644
--- a/networking/Kbuild
+++ b/networking/Kbuild
@@ -32,7 +32,7 @@ lib-$(CONFIG_PING6) += ping.o
lib-$(CONFIG_PSCAN) += pscan.o
lib-$(CONFIG_ROUTE) += route.o
lib-$(CONFIG_RPTRA6) += rptra6.o
-lib-$(CONFIG_RPTADDR6) += rptaddr6.o
+lib-$(CONFIG_RPTADDRS) += rptaddrs.o
lib-$(CONFIG_RXTXRPT) += rxtxrpt.o
lib-$(CONFIG_SLATTACH) += slattach.o
lib-$(CONFIG_SSLGETCERT) += sslgetcert.o
diff --git a/networking/atlasinit.c b/networking/atlasinit.c
new file mode 100644
index 0000000..121b508
--- /dev/null
+++ b/networking/atlasinit.c
@@ -0,0 +1,740 @@
+/* RIPEAtlas
+ * All the configurable variables - and some non configurables too
+ * Usage1: ./init_resp_parse < init_messagefile
+ * Usage2: ./init_resp_parse init_messagefile
+ * $Id: $
+ */
+
+
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+#include <stdarg.h>
+#include "atlasinit.h"
+
+//#ifndef NOTBUSYBOX
+/* compiled to busybox. tested on 1.13 */
+#include "libbb.h"
+//#endif
+
+#define ERROR 1
+#define INFO 2
+#define ATLAS_DEFAULT_WAIT 100
+#define OPT_STRING "rcdsi:I:"
+#define ATLAS_WAIT 0
+
+enum
+{
+ OPT_REG_INIT = (1 << 0), /* r */
+ OPT_CNT_INIT = (1 << 1), /* c */
+ OPT_CNT_HELLO = (1 << 2), /* d */
+ OPT_SINCELAST = (1 << 3), /* s */
+ OPT_P_TO_R_INIT = (1 << 4), /* i */
+};
+
+#define DBQ(str) "\"" #str "\""
+
+/*********************************************************************
+ * Set these constants to your liking
+ */
+static int read_wait (FILE *read_from, const char *type, int waittime);
+static int reg_init_main( int argc, char *argv[] );
+static int con_hello_main( int argc, char *argv[] );
+static int con_init_main( int argc, char *argv[] );
+static void since_last_main (int argc, char *argv[]);
+static void print_token_ver (FILE * write_to, int flag_rereg);
+
+const char atlas_log_file[]="./probe.log";
+const int atlas_log_level=INFO;
+
+const char atlas_contr_known_hosts[]="./known_hosts_controllers";
+const char atlas_rereg_timestamp[]="./rereg_time.sh";
+const char atlas_con_hello[]="./con_hello.txt";
+const char atlas_con_session_id[]="./con_session_id.txt";
+const char atlas_force_reg[] = "./force_reg.sh";
+const char atlas_netconfig_v4[] = "./netconfig_v4.vol";
+const char atlas_netconfig_v6[] = "./netconfig_v6.vol";
+const char atlas_resolv_conf[] = "./resolv.conf.vol";
+const char atlas_network_v4_info[] = "/home/atlas/status/network_v4_info.txt";
+const char atlas_network_v4_static_info[] = "/home/atlas/status/network_v4_static_info.txt";
+const char atlas_network_v4_static_info_json[] = "/home/atlas/status/network_v4_static_info.json";
+const char atlas_network_v6_static_info[] = "/home/atlas/status/network_v6_static_info.txt";
+const char atlas_network_v6_static_info_json[] = "/home/atlas/status/network_v6_static_info.json";
+const char atlas_network_dns_static_info[] = "/home/atlas/status/network_dns_static_info.txt";
+const char atlas_network_dns_static_info_json[] = "/home/atlas/status/network_dns_static_info.json";
+
+const int max_lines = 16; /* maximum lines we'll process */
+const int min_rereg_time = 100;
+const int max_rereg_time = 28*24*3600; /* 28d */
+const int default_rereg_time = 7*24*3600; /* 7d */
+char *str_reason;
+const char *str_device;
+
+/**********************************************************************/
+
+static char line[ATLAS_BUF_SIZE];
+
+#ifdef NOTBUSYBOX
+int main( int argc, char *argv[] )
+#else
+int atlasinit_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int atlasinit_main( int argc, char *argv[] )
+#endif
+{
+ int opt = 0;
+
+ if(argc > 1)
+ {
+ str_device= NULL;
+ opt = getopt32(argv, OPT_STRING, &str_reason, &str_device);
+ argv += optind;
+ argc -= optind;
+ argc++; // AA Hack
+ }
+ else
+ { // AA improve
+ // we are called without an option decide which is default
+ reg_init_main( argc, argv);
+ }
+
+ if(opt & OPT_REG_INIT)
+ {
+ reg_init_main( argc, argv);
+ }
+ else if(opt & OPT_CNT_HELLO)
+ {
+ con_hello_main(argc, argv);
+ }
+ else if ( opt & OPT_CNT_INIT)
+ {
+ con_init_main(argc, argv);
+
+ }
+ else if (opt & OPT_SINCELAST)
+ {
+ since_last_main(argc, argv);
+ }
+ else if(opt & OPT_P_TO_R_INIT)
+ {
+ print_token_ver(stdout, 1);
+ }
+
+ return 0;
+}
+
+static void print_token_ver (FILE * write_to, int flag_rereg)
+{
+float root_fs_ver = 0;
+FILE *fp = xfopen_for_read("/proc/version");
+FILE *fpv = fopen("/home/atlas/state/FIRMWARE_APPS_VERSION", "r");
+ char *my_mac ;
+
+bzero( line, ATLAS_BUF_SIZE );
+fscanf (fp, "%s", line);
+fscanf (fp, "%s", line);
+fscanf (fp, "%s", line);
+if(fpv)
+ fscanf (fpv, "%f", &root_fs_ver);
+ else
+ root_fs_ver=3100;
+ if(flag_rereg > 0)
+ fprintf(write_to, "P_TO_R_INIT\n");
+ my_mac = getenv("ETHER_SCANNED");
+ fprintf(write_to, "TOKEN_SPECS probev1 %s", line);
+ if (my_mac != NULL)
+ fprintf(write_to, "-%s ", my_mac );
+ fprintf(write_to, " %d\n", (int)root_fs_ver);
+ if(flag_rereg > 0)
+ fprintf(write_to, "REASON_FOR_REGISTRATION %s\n", str_reason);
+ fclose(fp);
+}
+
+static void since_last_main (int argc, char *argv[])
+{
+ FILE *thenfile;
+ int then;
+ time_t mytime;
+
+ mytime = time(0);
+
+ if ( argc == 1) {
+ printf("%d\n", (int)mytime);
+ }
+ else {
+ if ((thenfile = fopen(argv[0], "r")) == NULL) {
+ printf("%d\n", (int)mytime);
+ }
+ else {
+ fscanf(thenfile, "%d", &then);
+ printf("%d\n", (int)(mytime - then));
+ }
+ }
+}
+
+static int con_hello_main( int argc, char *argv[] )
+{
+ /* read response from P_TO_C_HELLO */
+ FILE *read_from = stdin;
+ int ret = 0;
+ long tmp_long;
+
+ time_t mytime = time(0);
+ time_t con_time;
+ if( argc > 1 ) {
+ read_from = fopen( argv[0], "rt" );
+ if( read_from==NULL ) {
+ atlas_log( ERROR, "Cannot read from file %s\n", argv[1] );
+ return 1;
+ }
+ }
+ /* read OK */
+ bzero( line, ATLAS_BUF_SIZE );
+ fgets( line, MAX_READ, read_from );
+
+ if( strncmp(line,"OK\n",3) == 0 ) {
+ int l=1;
+ bzero( line, ATLAS_BUF_SIZE );
+ fgets( line, MAX_READ, read_from );
+ while( !feof(read_from) && l<=max_lines ) {
+ if( strncmp(line,"CONTROLLER_TIMESTAMP ", 21)==0 ) {
+ int timediff2 ;
+
+ sscanf( line+21, "%ld", &tmp_long);
+ con_time= tmp_long;
+ timediff2 = ( mytime - con_time ) * ( mytime - con_time );
+ printf ("Mytime %d controller time %d\n",(int)mytime , (int)con_time);
+ if( timediff2 > 4 ) {
+ struct timeval tval;
+
+ atlas_log( INFO, "Time difference is %d seconds, set time ?\n", timediff2);
+ printf ("Set mytime \n");
+ tval.tv_sec = con_time;
+ tval.tv_usec = 0;
+ settimeofday( &tval, NULL);
+ }
+
+ }
+ bzero( line, ATLAS_BUF_SIZE );
+ fgets( line, MAX_READ, read_from );
+ l++;
+ }
+ }
+ else {
+ fprintf (stderr, "P_TO_C_HELLO response is unexptedte %s\n", line);
+ }
+
+ if (argc > 1 )
+ fclose (read_from);
+ return ret;
+}
+static int con_init_main( int argc, char *argv[] )
+{
+ FILE *read_from = stdin;
+ int ret = 0;
+
+ int remote_port;
+ if( argc > 1 ) {
+ read_from = fopen( argv[0], "rt" );
+ if( read_from==NULL ) {
+ atlas_log( ERROR, "Cannot read from file %s\n", argv[1] );
+ return 1;
+ }
+ }
+ /* read OK */
+ bzero( line, ATLAS_BUF_SIZE );
+ fgets( line, MAX_READ, read_from );
+
+ if( strncmp(line,"OK\n",3) == 0 ) {
+ int l=1;
+ bzero( line, ATLAS_BUF_SIZE );
+ fgets( line, MAX_READ, read_from );
+ while( !feof(read_from) && l<=max_lines ) {
+ if( strncmp(line,"REMOTE_PORT", 11)==0 ) {
+ sscanf( line+11, "%d", &remote_port);
+ printf ("REMOTE_PORT=%d\n", remote_port);
+ }
+ else if ( strncmp(line,"SESSION_ID", 10)==0 )
+ {
+ FILE *f = fopen( atlas_con_hello, "wt" );
+ FILE *f1 = fopen( atlas_con_session_id, "wt" );
+
+ fprintf (f, "P_TO_C_HELLO\nSESSION_ID %s", line+11);
+ fprintf (f1, "\nSESSION_ID %s\n", line+11);
+ print_token_ver (f, 0 );
+ fclose (f);
+ fclose (f1);
+
+ }
+ bzero( line, ATLAS_BUF_SIZE );
+ fgets( line, MAX_READ, read_from );
+ l++;
+ }
+ }
+ else if (strncmp(line,"WAIT\n",5) == 0 )
+ {
+ read_wait(read_from, "CON_WAIT_TIMER", ATLAS_WAIT);
+ }
+ else if (strncmp(line,"REFUSED\n",8) == 0 )
+ {
+ FILE *f = fopen( atlas_force_reg, "wt" );
+
+ unlink(atlas_con_hello);
+ bzero( line, ATLAS_BUF_SIZE );
+ fgets( line, MAX_READ, read_from );
+ fprintf (f,"REASON=%s\n", line+8);
+ fclose(f);
+
+ }
+ else {
+ char *p = strchr(line,'\n');
+ if( p!=NULL ) *p = '\0';
+ atlas_log( ERROR, "OK expected, got \"%s\" instead\n", line );
+ read_wait(read_from, "CON_WAIT_TIMER", ATLAS_DEFAULT_WAIT); /* we got error the only action from probe is wait. so force it*/
+ ret = 1;
+ }
+
+ if (argc > 1 )
+ fclose (read_from);
+ return ret;
+
+}
+static int read_wait (FILE *read_from, const char *type, int waittime)
+{
+ unsigned delay;
+ time_t mytime = time(0);
+ if(waittime < 1)
+ {
+ bzero( line, ATLAS_BUF_SIZE );
+ fgets( line, MAX_READ, read_from );
+ if( strncmp(line,"TIMEOUT", 7)==0 ) {
+ sscanf( line+7, "%d", &delay);
+ }
+ else
+ {
+ delay = ATLAS_DEFAULT_WAIT;
+ }
+ }
+ else
+ {
+ delay = waittime;
+ }
+ mytime = time(0);
+ if(delay > max_rereg_time ) {
+ atlas_log( ERROR, "Reregister time %d is too high\n", delay );
+ delay = max_rereg_time;
+ }
+ if(delay < min_rereg_time ) {
+ atlas_log( ERROR, "Reregister time %d is too high\n", delay );
+ delay = min_rereg_time;
+ }
+ printf ("%s=%u\n", type, (uint)(mytime + delay));
+ return (delay);
+}
+
+static int reg_init_main( int argc, char *argv[] )
+{
+
+ time_t mytime;
+ FILE *read_from = stdin;
+
+ char *token;
+ const char *search = " ";
+ const char *search_nl = " \n";
+ int ret = 0;
+ int first;
+
+ int reregister_time = default_rereg_time;
+ mytime = time(NULL);
+
+ if (!str_device)
+ str_device= "eth0";
+
+ if( argc >1 ) {
+ read_from = fopen( argv[0], "rt" );
+ if( read_from==NULL ) {
+ atlas_log( ERROR, "Cannot read from file %s\n", argv[1] );
+ return 1;
+ }
+ }
+
+ /* read OK */
+ bzero( line, ATLAS_BUF_SIZE );
+ fgets( line, MAX_READ, read_from );
+
+ if( strncmp(line,"OK\n",3) == 0 ) {
+ int l=1;
+ int n_controller = 0;
+ char *host_name;
+ char *type;
+ char *key;
+ int do_rm_v4_static_info;
+ int do_rm_v6_static_info;
+ int do_rm_dns_static_info;
+
+ bzero( line, ATLAS_BUF_SIZE );
+ fgets( line, MAX_READ, read_from );
+
+ do_rm_v4_static_info= 1;
+ do_rm_v6_static_info= 1;
+ do_rm_dns_static_info= 1;
+ while( !feof(read_from) && l<=max_lines ) {
+ if( strncmp(line,"CONTROLLER ", 11)==0 ) {
+ FILE *f;
+ char *ptr;
+
+ n_controller++;
+ /* TODO: one can check whether it's about the right length and syntax */
+
+ ptr = strchr( line+11, ' ' );
+ if( ptr==NULL ) {
+ atlas_log( ERROR, "CONTROLLER line is suspicious (line %d)\n", l );
+ return 1;
+ }
+ f = fopen( atlas_contr_known_hosts, "wt" );
+ if( f==NULL ) {
+ atlas_log( ERROR, "Unable to append to file %s\n", atlas_contr_known_hosts );
+ return 1;
+ }
+ //fprintf( f, "%s\n", line+11 );
+ token = strtok(line+11, search);
+ /* host name */
+ printf ("CONTROLLER_%d_HOST=%s\n", n_controller, token);
+ fprintf( f, "%s ", token);
+ host_name = token;
+
+ token = strtok(NULL, search);
+ printf ("CONTROLLER_%d_PORT=%s\n", n_controller, token);
+ token = strtok(NULL, search);
+ fprintf( f, "%s ", token);
+ type = token;
+ token = strtok(NULL, search);
+ fprintf( f, "%s\n", token);
+ key = token;
+ fprintf (f, "ipv4.%s %s %s\n", host_name, type, key);
+ fprintf (f, "ipv6.%s %s %s\n", host_name, type, key);
+ fclose(f);
+
+ }
+ else if( strncmp(line,"REREGISTER ", 11)==0 )
+ {
+ sscanf( line+11, "%d", &reregister_time );
+ read_wait(read_from, "REREG_TIMER", reregister_time);
+
+ }
+ else if( strncmp(line,"REGSERVER_TIMESTAMP ", 20)==0 ) {
+ int regserver_time;
+ int timediff2 ;
+
+ sscanf( line+20, "%d", &regserver_time );
+ timediff2 = ( mytime - regserver_time ) * ( mytime - regserver_time );
+ if( timediff2 > 4 ) {
+ struct timeval tval;
+
+ atlas_log( INFO, "Time difference is %d seconds, what to do now?\n", (int)(mytime-regserver_time) );
+
+ tval.tv_sec = regserver_time;
+ tval.tv_usec = 0;
+ settimeofday( &tval, NULL);
+ }
+ }
+ else if( strncmp(line,"FIRMWARE_KERNEL ", 16)==0 )
+ {
+ unsigned root_fs_ver = 0;
+ token = strtok (line+16, search); // version
+ sscanf (token, "%u", &root_fs_ver);
+ printf("FIRMWARE_KERNEL_VERSION=%u\n",
+ root_fs_ver);
+ token = strtok(NULL, search); // alg
+ printf("FIRMWARE_KERNEL_CS_ALG=%s\n", token);
+
+ token = strtok(NULL, search); // comp hash
+ printf("FIRMWARE_KERNEL_CS_COMP=%s\n", token);
+
+ token = strtok(NULL, search); // uncomp hash
+
+ printf("FIRMWARE_KERNEL_CS_UNCOMP=%s\n", token);
+ token = strtok(NULL, search); // url hash
+ printf( "FIRMWARE_KERNEL=%s\n", token) ;
+
+ }
+ else if( strncmp(line,"FIRMWARE_APPS ", 14)==0 )
+ {
+ unsigned root_fs_ver = 0;
+ token = strtok (line+14, search); // version
+ sscanf (token, "%u", &root_fs_ver);
+ printf("FIRMWARE_APPS_VERSION=%u\n",
+ root_fs_ver);
+ token = strtok(NULL, search); // alg
+ printf("FIRMWARE_APPS_CS_ALG=%s\n", token);
+
+ token = strtok(NULL, search); // comp hash
+ printf("FIRMWARE_APPS_CS_COMP=%s\n", token);
+
+ token = strtok(NULL, search); // uncomp hash
+
+ printf("FIRMWARE_APPS_CS_UNCOMP=%s\n", token);
+ token = strtok(NULL, search); // url hash
+ printf( "FIRMWARE_APPS=%s\n", token) ;
+
+ }
+
+ else if( strncmp(line,"DHCPV4 False ", 13)==0 )
+ {
+ FILE *f = fopen(atlas_netconfig_v4, "wt");
+ char *ipv4_address;
+ char *netmask;
+ char *broadcast;
+ char *ipv4_gw;
+
+ if( f==NULL ) {
+ atlas_log( ERROR, "Unable to create %s\n", atlas_netconfig_v4 );
+ return 1;
+ }
+
+ // Statically configured probe.
+//DHCPV4 False IPV4ADDRESS 10.0.0.151 IPV4NETMASK 255.255.255.0 IPV4NETWORK 10.0.0.0 IPV4BROADCAST 10.0.0.255 IPV4GATEWAY 10.0.0.137
+ // fprintf (f, "%s\n", line);
+ token = strtok(line+13, search); //IPV4ADDRESS
+ token = strtok(NULL, search); // <address>
+ fprintf (f, "/sbin/ifconfig %s 0.0.0.0\n",
+ str_device);
+ fprintf (f, "/sbin/ifconfig %s:1 %s ",
+ str_device, token);
+ ipv4_address = token;
+ token = strtok(NULL, search); // IPV4NETMASK
+ token = strtok(NULL, search); //
+ fprintf (f, "netmask %s ", token);
+ netmask = token;
+ token = strtok(NULL, search); // IPV4NETWORK
+ token = strtok(NULL, search); //
+ token = strtok(NULL, search); // IPV4BROADCAST
+ token = strtok(NULL, search); //
+ fprintf (f, "broadcast %s \n", token);
+ broadcast = token;
+ token = strtok(NULL, search); // IPV4GATEWAY
+ token = strtok(NULL, search); //
+ fprintf (f, "/sbin/route add default gw %s\n", token);
+ ipv4_gw = token;
+ ipv4_gw[(strlen(ipv4_gw) - 1)] = '\0';
+
+ // put parts in the shell script to make network info file
+
+ fprintf (f, "echo \"P_TO_C_NETWORK_UPDATE\" > %s \n", atlas_network_v4_info );
+ fprintf (f, "echo \"IPV4_LOCAL_ADDR %s\" >> %s \n", ipv4_address, atlas_network_v4_info );
+ fprintf (f, "echo \"IPV4_NETMASK %s\" >> %s \n", netmask, atlas_network_v4_info );
+ fprintf (f, "echo \"IPV4_BROADCAST %s\" >> %s \n", broadcast, atlas_network_v4_info );
+ fprintf (f, "echo \"IPV4_GW %s\" >> %s \n",ipv4_gw , atlas_network_v4_info );
+ fprintf (f, "echo \"DHCP False \" >> %s \n", atlas_network_v4_info );
+
+
+ // second file for static
+ fprintf (f, "echo \"STATIC_IPV4_LOCAL_ADDR %s\" > %s \n", ipv4_address, atlas_network_v4_static_info );
+ fprintf (f, "echo \"STATIC_IPV4_NETMASK %s\" >> %s \n", netmask, atlas_network_v4_static_info );
+ fprintf (f, "echo \"STATIC_IPV4_BROADCAST %s\" >> %s \n", broadcast, atlas_network_v4_static_info );
+ fprintf (f, "echo \"STATIC_IPV4_GW %s\" >> %s \n",ipv4_gw , atlas_network_v4_static_info );
+ fprintf(f, "echo '"
+ DBQ(static-inet-addresses) " : [ { "
+ DBQ(inet-addr) ": " DBQ(%s) ", "
+ DBQ(netmask) ": " DBQ(%s) ", "
+ DBQ(interface) ": " DBQ(%s)
+ " } ], "
+ DBQ(static-inet-routes) " : [ { "
+ DBQ(destination) ": " DBQ(0.0.0.0) ", "
+ DBQ(netmask) ": " DBQ(0.0.0.0) ", "
+ DBQ(next-hop) ": " DBQ(%s) ", "
+ DBQ(interface) ": " DBQ(%s)
+ " } ]' > %s\n",
+ ipv4_address,
+ netmask,
+ str_device,
+ ipv4_gw,
+ str_device,
+ atlas_network_v4_static_info_json);
+ // ping the gateway
+ fprintf (f, "ping -c 2 -q %s \n", ipv4_gw);
+ fprintf (f, "IPV4_GW=%s; export IPV4_GW\n", ipv4_gw);
+
+ fclose(f);
+
+ do_rm_v4_static_info= 0;
+ }
+ //DHCPV6 False IPV6ADDRESS <address> IPV6PREFIXLEN <prefix> IPV6GATEWAY <gateway>]| [DHCPV6 True ]
+ else if( strncmp(line,"DHCPV6 False ", 13)==0 )
+ {
+ FILE *f = fopen(atlas_netconfig_v6, "wt");
+ char *ipv6_address;
+ char *prefixlen;
+ char *ipv6_gw;
+
+ if( f==NULL ) {
+ atlas_log( ERROR, "Unable to create %s\n", atlas_netconfig_v6 );
+ return 1;
+ }
+
+ // Statically configured probe.
+
+ //fprintf (f, "%s\n", line);
+ token = strtok(line+13, search); //IPV6ADDRESS
+ token = strtok(NULL, search); // <address>
+ ipv6_address = token;
+ token = strtok(NULL, search); // IPV6PREFIXLEN
+ token = strtok(NULL, search); //
+ prefixlen = token;
+ fprintf (f, "/sbin/ifconfig %s 0.0.0.0\n",
+ str_device);
+ fprintf (f, "/sbin/ifconfig %s %s/%s\n",
+ str_device, ipv6_address, prefixlen);
+
+ token = strtok(NULL, search); // IPV6GATEWAY
+ token = strtok(NULL, search); //
+ ipv6_gw = token;
+ ipv6_gw[(strlen(ipv6_gw) - 1)] = '\0';
+ ///sbin/route -A inet6 add default gw fe80::13:0:0:1 dev eth0
+ fprintf (f,
+ "/sbin/route -A inet6 add default gw %s dev %s\n",
+ ipv6_gw, str_device);
+ // second file for static network info
+ fprintf (f, "echo \"STATIC_IPV6_LOCAL_ADDR %s/%s\" > %s \n", ipv6_address, prefixlen, atlas_network_v6_static_info );
+ fprintf (f, "echo \"STATIC_IPV6_GW %s\" >> %s \n",ipv6_gw , atlas_network_v6_static_info );
+
+ fprintf(f, "echo '"
+ DBQ(static-inet6-addresses) ": [ { "
+ DBQ(inet6-addr) ": " DBQ(%s) ", "
+ DBQ(prefix-length) ": %s, "
+ DBQ(interface) ": " DBQ(%s) " } ], "
+ DBQ(static-inet6-routes) ": [ { "
+ DBQ(destination) ": " DBQ(::) ", "
+ DBQ(prefix-length) " : 0, "
+ DBQ(next-hop) ": " DBQ(%s) ", "
+ DBQ(interface) ": " DBQ(%s) " } ]"
+ "' > %s\n",
+ ipv6_address, prefixlen, str_device,
+ ipv6_gw, str_device,
+ atlas_network_v6_static_info_json);
+
+
+ fclose(f);
+ do_rm_v6_static_info= 0;
+ }
+ else if( strncmp(line,"DNS_SERVERS ", 11)==0 )
+ {
+ FILE *f, *f1, *f2;
+
+ f = fopen(atlas_resolv_conf, "wt");
+ if( f==NULL ) {
+ atlas_log(ERROR,
+ "Unable to create %s\n",
+ atlas_resolv_conf );
+ return 1;
+ }
+
+ f1 = fopen(atlas_network_dns_static_info, "wt");
+ if( f1==NULL ) {
+ atlas_log(ERROR,
+ "Unable to create %s\n",
+ atlas_network_dns_static_info);
+ fclose(f);
+ return 1;
+ }
+ f2 = fopen(atlas_network_dns_static_info_json,
+ "wt");
+ if( f2==NULL ) {
+ atlas_log(ERROR,
+ "Unable to create %s\n",
+ atlas_network_dns_static_info_json);
+ fclose(f);
+ fclose(f1);
+ return 1;
+ }
+
+
+ // Statically configured probe.
+ //DNS_SERVERS 8.8.8.8 194.109.6.66
+ // fprintf (f, "%s\n", line);
+ token = strtok(line+11, search_nl); //
+ fprintf (f1, "STATIC_DNS");
+ fprintf(f2, DBQ(static-dns) ": [ ");
+
+ first= 1;
+ while (token != NULL)
+ {
+ fprintf (f, "nameserver %s\n", token);
+ fprintf (f1, " %s", token);
+ fprintf(f2, "%s{ " DBQ(nameserver) ": "
+ DBQ(%s) " }",
+ first ? "" : ", ", token);
+ token = strtok(NULL, search_nl);
+ first= 0;
+ }
+ fprintf (f1, "\n");
+ fprintf(f2, " ]\n");
+
+ fclose(f);
+ fclose(f1);
+ fclose(f2);
+
+ do_rm_dns_static_info= 0;
+ }
+ else if( strncmp(line,"FIRMWARE_KERNEL ", 16)==0 )
+ {
+ }
+ bzero( line, ATLAS_BUF_SIZE );
+ fgets( line, MAX_READ, read_from );
+ l++;
+ }
+ if(do_rm_v4_static_info)
+ {
+ // delete the static configuration
+ unlink(atlas_netconfig_v4);
+ unlink(atlas_network_v4_static_info);
+ unlink(atlas_network_v4_static_info_json);
+ }
+ if(do_rm_v6_static_info)
+ {
+ // delete the static configuration
+ unlink(atlas_netconfig_v6);
+ unlink(atlas_network_v6_static_info);
+ unlink(atlas_network_v6_static_info_json);
+ }
+ if (do_rm_dns_static_info)
+ {
+ unlink(atlas_network_dns_static_info);
+ unlink(atlas_network_dns_static_info_json);
+ }
+ }
+ else if (strncmp(line,"WAIT\n",5) == 0 )
+ {
+ read_wait(read_from, "REG_WAIT_UNTIL", ATLAS_WAIT );
+
+ }
+ else {
+ char *p = strchr(line,'\n');
+ if( p!=NULL ) *p = '\0';
+ atlas_log( ERROR, "OK expected, got \"%s\" instead\n", line );
+ read_wait(read_from, "REG_WAIT_UNTIL", ATLAS_DEFAULT_WAIT); /* we got error the only action from probe is wait. so force it*/
+ ret = 1;
+ }
+ return ret;
+}
+
+
+void atlas_log( int level UNUSED_PARAM, const char *msg UNUSED_PARAM, ... )
+{
+/*
+ if( atlas_log_level<=level )
+ {
+ va_list arg;
+ va_start ( arg, msg );
+
+ FILE *lf = fopen( atlas_log_file, "at" );
+ if( lf==NULL )
+ return; // not much we can do
+
+ fprintf( lf, "%d\t%d\t", (int)time(NULL), level );
+ vfprintf( lf, msg, arg );
+ fclose(lf);
+
+ va_end( arg );
+ }
+*/
+}
diff --git a/networking/rptaddrs.c b/networking/rptaddrs.c
new file mode 100644
index 0000000..1115559
--- /dev/null
+++ b/networking/rptaddrs.c
@@ -0,0 +1,775 @@
+/*
+ * rptaddrs.c
+ * Copyright (c) 2013 RIPE NCC <atlas@ripe.net>
+ * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
+ */
+
+#include <errno.h>
+#include <resolv.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <net/route.h>
+#include <net/if.h>
+#include <inet_common.h>
+#include "../eperd/eperd.h"
+#include "../eperd/readresolv.h"
+
+#include "libbb.h"
+
+#define IPV4_ROUTE_FILE "/proc/net/route"
+#define IF_INET6_FILE "/proc/net/if_inet6"
+#define IPV6_ROUTE_FILE "/proc/net/ipv6_route"
+#define SUFFIX ".new"
+
+#define IPV4_STATIC ATLAS_STATUS "/network_v4_static_info.json"
+#define IPV6_STATIC ATLAS_STATUS "/network_v6_static_info.json"
+#define DNS_STATIC ATLAS_STATUS "/network_dns_static_info.json"
+#define NETWORK_INFO ATLAS_STATUS "/network_info.txt"
+
+#define SAFE_PREFIX_N ATLAS_DATA_NEW
+
+#define OPT_STRING "A:O:c:"
+
+#define DBQ(str) "\"" #str "\""
+#define JS(key, val) fprintf(fh, "\"" #key"\" : \"%s\" , ", val);
+#define JS1(key, fmt, val) fprintf(fh, "\"" #key"\" : "#fmt" , ", val);
+
+#ifndef IPV6_MASK
+#define IPV6_MASK (RTF_GATEWAY|RTF_HOST|RTF_DEFAULT|RTF_ADDRCONF|RTF_CACHE)
+#endif
+
+#define IPV6_ADDR_LOOPBACK 0x0010U
+#define IPV6_ADDR_LINKLOCAL 0x0020U
+#define IPV6_ADDR_SITELOCAL 0x0040U
+
+#define IPV6_ADDR_COMPATv4 0x0080U
+
+#define IPV6_ADDR_SCOPE_MASK 0x00f0U
+
+enum {
+ OPT_a = (1 << 0),
+};
+
+static FILE *setup_cache(char *cache_name);
+static int setup_ipv4_rpt(FILE *of);
+static int setup_dhcpv4(FILE *of);
+static int setup_ipv6_rpt(FILE *of);
+static int setup_dns(FILE *of);
+static int setup_static_rpt(FILE *of);
+static int report_line(FILE *of, const char *fn);
+static int check_cache(char *cache_name);
+static int rpt_ipv6(char *cache_name, char *out_name, char *opt_atlas, int opt_append);
+static void report(const char *fmt, ...);
+static void report_err(const char *fmt, ...);
+
+int rptaddrs_main(int argc, char *argv[])
+{
+ int r, need_report;
+ unsigned opt;
+ char *opt_atlas;
+ char *cache_name; /* temp file in an intermediate format */
+ char *out_name; /* output file in json: timestamp opt_atlas */
+ int opt_append;
+ FILE *cf;
+
+ opt_atlas= NULL;
+ out_name = NULL;
+ cache_name = NULL;
+ opt_atlas = NULL;
+ opt_complementary= NULL;
+ opt_append = FALSE;
+
+ opt= getopt32(argv, OPT_STRING, &opt_atlas, &out_name, &cache_name);
+
+ if (out_name && !validate_filename(out_name, SAFE_PREFIX_N))
+ {
+ crondlog(LVL8 "insecure file '%s' : allowed '%s'", out_name,
+ SAFE_PREFIX_N);
+ return 1;
+ }
+ if (cache_name && !validate_filename(cache_name, SAFE_PREFIX_N))
+ {
+ crondlog(LVL8 "insecure file '%s' allowed %s", cache_name,
+ SAFE_PREFIX_N);
+ return 1;
+ }
+
+ if (!cache_name) {
+ crondlog(LVL8 "missing requried option, -c <cache_file>");
+ return 1;
+ }
+
+ if (opt & OPT_a)
+ opt_append = TRUE;
+
+ cf= setup_cache(cache_name);
+ if (cf == NULL)
+ return 1;
+
+ r= setup_ipv4_rpt(cf);
+ if (r == -1)
+ {
+ fclose(cf);
+ return 1;
+ }
+
+ r= setup_dhcpv4(cf);
+ if (r == -1)
+ {
+ fclose(cf);
+ return 1;
+ }
+
+ r= setup_ipv6_rpt(cf);
+ if (r == -1)
+ {
+ fclose(cf);
+ return 1;
+ }
+
+ r= setup_dns(cf);
+ if (r == -1)
+ {
+ fclose(cf);
+ return 1;
+ }
+
+ r= setup_static_rpt(cf);
+ if (r == -1)
+ {
+ fclose(cf);
+ return 1;
+ }
+ fclose(cf);
+
+ need_report= check_cache(cache_name);
+ if (need_report)
+ {
+ r = rpt_ipv6(cache_name, out_name, opt_atlas, opt_append);
+ if (r != 0)
+ return r;
+ }
+
+ return 0;
+}
+
+static FILE *setup_cache(char *cache_name)
+{
+ FILE *out_file;
+ char filename[80];
+
+ if (strlen(cache_name) + strlen(SUFFIX) + 1 > sizeof(filename))
+ {
+ report("cache name '%s' too long", cache_name);
+ return NULL;
+ }
+
+ strlcpy(filename, cache_name, sizeof(filename));
+ strlcat(filename, SUFFIX, sizeof(filename));
+
+ out_file= fopen(filename, "w");
+ if (out_file == NULL)
+ {
+ report_err("unable to create '%s'", filename);
+ return NULL;
+ }
+
+ return out_file;
+}
+
+#define MAX_INF 10
+
+static int setup_ipv4_rpt(FILE *of)
+{
+ int i, r, s, first;
+ unsigned dest, gateway, flags, refcnt, use, metric, mask;
+ FILE *in_file;
+ struct in_addr in_addr;
+ struct ifconf ifconf;
+ struct ifreq ifreq1;
+ struct ifreq ifreq[MAX_INF];
+ char infname[20];
+ char line[256];
+
+ s= socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
+ if (s == -1)
+ {
+ report_err("socket failed");
+ return -1;
+ }
+ ifconf.ifc_len= sizeof(ifreq);
+ ifconf.ifc_req= ifreq;
+ r= ioctl(s, SIOCGIFCONF, &ifconf);
+ if (r == -1)
+ {
+ report_err("SIOCGIFCONF failed");
+ close(s);
+ return -1;
+ }
+
+ fprintf(of, DBQ(inet-addresses) ": [ ");
+ for (i= 0; i<ifconf.ifc_len/sizeof(ifreq[0]); i++)
+ {
+ memcpy(ifreq1.ifr_name, ifreq[i].ifr_name,
+ sizeof(ifreq1.ifr_name));
+ r= ioctl(s, SIOCGIFNETMASK, &ifreq1);
+ if (r == -1)
+ {
+ report_err("SIOCGIFNETMASK failed");
+ close(s);
+ return -1;
+ }
+ fprintf(of, "%s{ " DBQ(inet-addr) ": " DBQ(%s) ", ",
+ i == 0 ? "" : ", ",
+ inet_ntoa(((struct sockaddr_in *)(&ifreq[i].ifr_addr))
+ ->sin_addr));
+ fprintf(of, DBQ(netmask) ": " DBQ(%s) ", "
+ DBQ(interface) ": " DBQ(%s) " }",
+ inet_ntoa(((struct sockaddr_in *)(&ifreq1.ifr_addr))->
+ sin_addr),
+ ifreq[i].ifr_name);
+ }
+
+ close(s);
+
+ fprintf(of, " ]");
+
+ in_file= fopen(IPV4_ROUTE_FILE, "r");
+ if (in_file == NULL)
+ {
+ report_err("unable to open '%s'", IPV4_ROUTE_FILE);
+ return -1;
+ }
+
+ /* Skip first line */
+ fgets(line, sizeof(line), in_file);
+
+ fprintf(of, ", " DBQ(inet-routes) ": [ ");
+ first= 1;
+
+ while (fgets(line, sizeof(line), in_file) != NULL)
+ {
+ sscanf(line, "%16s %x %x %x %d %d %d %x",
+ infname, &dest, &gateway, &flags, &refcnt, &use,
+ &metric, &mask);
+ in_addr.s_addr= dest;
+ fprintf(of, "%s{ " DBQ(destination) ": " DBQ(%s) ", ",
+ first ? "" : ", ", inet_ntoa(in_addr));
+ in_addr.s_addr= mask;
+ fprintf(of, DBQ(netmask) ": " DBQ(%s) ", ",
+ inet_ntoa(in_addr));
+ in_addr.s_addr= gateway;
+ fprintf(of, DBQ(next-hop) ": " DBQ(%s) ", "
+ DBQ(interface) ": " DBQ(%s) " }",
+ inet_ntoa(in_addr), infname);
+ first= 0;
+ }
+
+ fprintf(of, " ]");
+
+ fclose(in_file);
+
+ return 0;
+}
+
+static int setup_dhcpv4(FILE *of)
+{
+ int found;
+ FILE *in_file;
+ char *value;
+ char line[128];
+
+ in_file= fopen(NETWORK_INFO, "r");
+ if (in_file == NULL)
+ {
+ report_err("unable to open '%s'", NETWORK_INFO);
+ return -1;
+ }
+ found= 0;
+ while (fgets(line, sizeof(line), in_file) != NULL)
+ {
+ if (strncmp(line, "DHCP ", 5) == 0)
+ {
+ value= NULL;
+ if (strncmp(line+5, "True", 4) == 0)
+ value= "true";
+ else if (strncmp(line+5, "False", 5) == 0)
+ value= "false";
+ if (value)
+ {
+ fprintf(of, ", " DBQ(inet-dhcp) ": %s",
+ value);
+ found= 1;
+ break;
+ }
+ }
+ }
+
+ fclose(in_file);
+ if (found)
+ return 0;
+ report("setup_dhcpv4: DHCP field not found");
+ return -1;
+}
+
+static int setup_ipv6_rpt(FILE *of)
+{
+ int r, n;
+ char filename[80];
+ char dst6in[INET6_ADDRSTRLEN];
+ char nh6in[INET6_ADDRSTRLEN]; /* next hop */
+ char *dst6out = NULL;
+ char *nh6out = NULL;
+ char dst6p[8][5];
+ char nh6p[8][5];
+ char iface[16], flags[16];
+ char Scope[32];
+ int scope, dad_status, if_idx;
+ int iflags, metric, refcnt, use, prefix_len, slen;
+ struct sockaddr_in6 sdst6, snh6;
+ char buf2[1024];
+
+ FILE *in_file;
+
+ /* Copy IF_INET6_FILE */
+ in_file= fopen(IF_INET6_FILE, "r");
+ if (in_file == NULL)
+ {
+ report_err("unable to open '%s'", IF_INET6_FILE);
+ return -1;
+ }
+ n = 0;
+ while ((r = fscanf(in_file, "%4s%4s%4s%4s%4s%4s%4s%4s %08x %02x %02x %02x %20s\n",
+ dst6p[0], dst6p[1], dst6p[2]
+ , dst6p[3], dst6p[4], dst6p[5]
+ , dst6p[6], dst6p[7], &if_idx, &prefix_len
+ , &scope, &dad_status, iface)) != EOF) {
+
+ snprintf(dst6in, sizeof(dst6in), "%s:%s:%s:%s:%s:%s:%s:%s",
+ dst6p[0], dst6p[1], dst6p[2], dst6p[3],
+ dst6p[4], dst6p[5], dst6p[6], dst6p[7]);
+
+ inet_pton(AF_INET6, dst6in, (struct sockaddr *) &sdst6.sin6_addr);
+ sdst6.sin6_family = AF_INET6;
+ dst6out = INET6_rresolve((struct sockaddr_in6 *) &sdst6, 0x0fff);
+
+ switch (scope & IPV6_ADDR_SCOPE_MASK) {
+ case 0:
+ snprintf(Scope, sizeof(Scope), "Global");
+ break;
+ case IPV6_ADDR_LINKLOCAL:
+ snprintf(Scope, sizeof(Scope), "Link");
+ break;
+ case IPV6_ADDR_SITELOCAL:
+ snprintf(Scope, sizeof(Scope), "Site");
+ break;
+ case IPV6_ADDR_COMPATv4:
+ snprintf(Scope, sizeof(Scope), "Compat");
+ break;
+ case IPV6_ADDR_LOOPBACK:
+ snprintf(Scope, sizeof(Scope), "Host");
+ break;
+ default:
+ snprintf(Scope, sizeof(Scope), "Unknown %d", scope);
+ }
+ r = snprintf(buf2, sizeof(buf2), "%s %s{" DBQ(inet6-addr) " : "
+ DBQ(%s) ", " DBQ(prefix-length) " : %d,"
+ DBQ(scope) " : " DBQ(%s) ", " DBQ(interface)
+ " : " DBQ(%s) "}",
+ n ? "" : ", \"inet6-addresses\" : [", n ? ", " : ""
+ , dst6out, prefix_len, Scope, iface);
+
+ /* printf("%s\n", buf2); */
+
+ if(dst6out) {
+ free(dst6out);
+ dst6out=NULL;
+ }
+ n++;
+ if (fwrite(buf2, 1, r, of) != r)
+ {
+ report_err("error writing to '%s'", filename);
+ fclose(in_file);
+ return -1;
+ }
+
+ if (ferror(in_file))
+ {
+ report_err("error reading from '%s'", IF_INET6_FILE);
+ fclose(in_file);
+ return -1;
+ }
+ }
+ if ( n > 0 ) {
+ r = snprintf(buf2, 2, "]");
+ }
+ if (fwrite(buf2, 1, r, of) != r)
+ {
+ report_err("error writing to '%s'", filename);
+ fclose(in_file);
+ return -1;
+ }
+
+ fclose(in_file);
+
+ /* Copy IPV6_ROUTE_FILE */
+ in_file= fopen(IPV6_ROUTE_FILE, "r");
+ if (in_file == NULL)
+ {
+ report_err("unable to open '%s'", IPV6_ROUTE_FILE);
+ return -1;
+ }
+
+ n = 0;
+ while ((r = fscanf (in_file, "%4s%4s%4s%4s%4s%4s%4s%4s%x%*s%x%4s%4s%4s%4s%4s%4s%4s%4s%x%x%x%x%s\n",
+ dst6p[0], dst6p[1], dst6p[2], dst6p[3], dst6p[4],
+ dst6p[5], dst6p[6], dst6p[7], &prefix_len, &slen,
+ nh6p[0], nh6p[1], nh6p[2], nh6p[3], nh6p[4],
+ nh6p[5], nh6p[6], nh6p[7], &metric, &use, &refcnt, &iflags, iface)) != EOF) {
+
+ if (r != 23) {
+ if ((r < 0) && feof(in_file)) { /* EOF with no (nonspace) chars read. */
+ break;
+ }
+ report_err("reading '%s'", IF_INET6_FILE);
+ fclose(in_file);
+ return -1;
+ }
+
+ /* skip some the stuff we don't want to report */
+ if (!(iflags & RTF_UP)) { /* Skip interfaces that are down. */
+ continue;
+ }
+ if ((iflags & RTF_ADDRCONF) && (iflags & RTF_CACHE)) { /* Skip interfaces that are down. */
+ continue;
+ }
+
+ if ( strncmp (dst6p[0], "ff02", strlen("ff02")) == 0 ) {
+ continue;
+ }
+ if ( strncmp (dst6p[0], "ff00", strlen("ff00")) == 0 ) {
+ continue;
+ }
+
+ snprintf(dst6in, sizeof(dst6in), "%s:%s:%s:%s:%s:%s:%s:%s",
+ dst6p[0], dst6p[1], dst6p[2], dst6p[3],
+ dst6p[4], dst6p[5], dst6p[6], dst6p[7]);
+
+ snprintf(nh6in, sizeof(nh6in), "%s:%s:%s:%s:%s:%s:%s:%s",
+ nh6p[0], nh6p[1], nh6p[2], nh6p[3],
+ nh6p[4], nh6p[5], nh6p[6], nh6p[7]);
+
+
+ set_flags(flags, (iflags & IPV6_MASK));
+ inet_pton(AF_INET6, dst6in, (struct sockaddr *) &sdst6.sin6_addr);
+ sdst6.sin6_family = AF_INET6;
+ dst6out = INET6_rresolve((struct sockaddr_in6 *) &sdst6, 0x0fff);
+
+ inet_pton(AF_INET6, nh6in, (struct sockaddr *) &snh6.sin6_addr);
+ snh6.sin6_family = AF_INET6;
+ nh6out = INET6_rresolve((struct sockaddr_in6 *) &snh6, 0x0fff);
+
+
+ r = snprintf(buf2, sizeof(buf2), "%s %s{" DBQ(destination) " : "
+ DBQ(%s) ", " DBQ(prefix-length) " : %d,"
+ DBQ(next-hop) " : " DBQ(%s) ", " DBQ(flags)
+ " : " DBQ(%s) ", " DBQ(metric) " : %d , "
+ DBQ(interface) " : " DBQ(%s) "}",
+ n ? "" : ", \"inet6-routes\" : [", n ? ", " : ""
+ , dst6out, prefix_len, nh6out, flags, metric
+ , iface);
+
+ /*
+ r = snprintf(buf2, sizeof(buf2), "%s %s{" DBQ(destination) " : "
+ DBQ(%s) ", " DBQ(prefix-length) " : %d,"
+ DBQ(next-hop) " : " DBQ(%s) ", " DBQ(flags)
+ " : " DBQ(%s) ", " DBQ(metric) " : %d , "
+ DBQ(interface) " : " DBQ(%s) "}",
+ n ? " " : '"inet6-routes" ['
+ , n ? ", " : ""
+ , dst6out, prefix_len, nh6out, flags, metric
+ , iface);
+ */
+
+ /* printf("%s\n", buf2); */
+
+ if(dst6out) {
+ free(dst6out);
+ dst6out=NULL;
+ }
+ if(nh6out) {
+ free(nh6out);
+ nh6out=NULL;
+ }
+
+ if (fwrite(buf2, 1, r, of) != r)
+ {
+ report_err("error writing to '%s'", filename);
+ fclose(in_file);
+ return -1;
+ }
+ n++;
+ }
+ if ( n > 0 ) {
+ r = snprintf(buf2, 2, "]");
+ }
+ if (fwrite(buf2, 1, r, of) != r)
+ {
+ report_err("error writing to '%s'", filename);
+ fclose(in_file);
+ return -1;
+ }
+
+
+ if (ferror(in_file))
+ {
+ report_err("error reading from '%s'", IPV6_ROUTE_FILE);
+ fclose(in_file);
+ return -1;
+ }
+ fclose(in_file);
+
+ return 0;
+}
+
+static int setup_dns(FILE *of)
+{
+ int i, resolv_max;
+ char nslist[MAXNS][INET6_ADDRSTRLEN * 2];
+
+ resolv_max= 0;
+
+ get_local_resolvers_nocache(nslist, &resolv_max);
+
+ fprintf(of, ", " DBQ(dns) ": [ ");
+ for (i= 0; i<resolv_max; i++)
+ {
+ fprintf(of, "%s{ " DBQ(nameserver) ": " DBQ(%s) " }",
+ i == 0 ? "" : ", ",
+ nslist[i]);
+ }
+
+ fprintf(of, " ]");
+
+ return 0;
+}
+
+static int setup_static_rpt(FILE *of)
+{
+ int r;
+
+ r= report_line(of, IPV4_STATIC);
+ if (r == -1)
+ return -1;
+ r= report_line(of, IPV6_STATIC);
+ if (r == -1)
+ return -1;
+ r= report_line(of, DNS_STATIC);
+ if (r == -1)
+ return -1;
+ return 0;
+}
+
+static int report_line(FILE *of, const char *fn)
+{
+ FILE *f;
+ char *nl;
+ char line[256];
+
+ f= fopen(fn, "r");
+ if (f == NULL)
+ {
+ if (errno != ENOENT)
+ {
+ report_err("open '%s' failed", fn);
+ return -1;
+ }
+ }
+ else
+ {
+ if (fgets(line, sizeof(line), f) == NULL)
+ {
+ if (ferror(f))
+ {
+ report_err("error reading from '%s'", fn);
+ }
+ else
+ report("error reading from '%s': EOF");
+ fclose(f);
+ return -1;
+ }
+ fclose(f);
+ nl= strchr(line, '\n');
+ if (nl == NULL)
+ {
+ report("line too long in '%s'", fn);
+ return -1;
+ }
+ *nl= '\0';
+ fprintf(of, ", %s", line);
+ }
+
+ return 0;
+}
+
+static int check_cache(char *cache_name)
+{
+ int r, need_report;
+ char filename[80];
+
+ char buf1[1024];
+ char buf2[1024];
+ FILE *in_file, *cache_file;
+
+ strlcpy(filename, cache_name, sizeof(filename));
+ strlcat(filename, SUFFIX, sizeof(filename));
+
+ need_report= 0;
+
+ /* Now check if the new file is different from the cache one */
+ cache_file= fopen(cache_name, "r");
+ if (cache_file == NULL)
+ {
+ /* Assume that any kind of error here calls for reporting */
+ need_report= 1;
+ }
+
+ if (cache_file)
+ {
+ in_file= fopen(filename, "r");
+ if (in_file == NULL)
+ {
+ report_err("unable to open '%s'", filename);
+ fclose(cache_file);
+ return 1;
+ }
+
+ /* Compare them */
+ while (r= fread(buf1, 1, sizeof(buf1), cache_file), r > 0)
+ {
+ if (fread(buf2, 1, sizeof(buf2), in_file) != r)
+ {
+ /* Ignore errors, just report */
+ need_report= 1;
+ break;
+ }
+
+ if (memcmp(buf1, buf2, r) != 0)
+ {
+ /* Something changed, report */
+ need_report= 1;
+ break;
+ }
+ }
+
+ /* Maybe something got added */
+ if (!need_report)
+ {
+ if (fread(buf2, 1, sizeof(buf2), in_file) != 0)
+ {
+ need_report= 1;
+ }
+ }
+ fclose(cache_file);
+ fclose(in_file);
+ }
+
+ if (need_report)
+ {
+ if (rename(filename, cache_name) == -1)
+ {
+ report_err("renaming '%s' to '%s' failed",
+ filename, cache_name);
+ return 0;
+ }
+ }
+ else
+ {
+ if (unlink(filename) == -1)
+ {
+ report_err("unlinking '%s' failed",
+ filename);
+ }
+ }
+
+ return need_report;
+}
+
+static int rpt_ipv6(char *cache_name, char *out_name, char *opt_atlas, int opt_append)
+{
+ FILE *file;
+ FILE *fh;
+ char buf[256];
+ struct timeval now;
+
+ file= fopen(cache_name, "r");
+ if (!file)
+ {
+ report_err("unable to open cache file '%s'", cache_name);
+ return 1;
+ }
+
+ if (out_name) {
+ if(opt_append)
+ fh= fopen(out_name, "a");
+ else
+ fh= fopen(out_name, "w");
+
+ if (!fh)
+ {
+ report_err("unable to append to '%s'", out_name);
+ return 1;
+ }
+ }
+ else
+ fh = stdout;
+
+ fprintf(fh, "RESULT { ");
+ if(opt_atlas)
+ {
+ JS(id, opt_atlas);
+ }
+ gettimeofday(&now, NULL);
+ JS1(time, %ld, now.tv_sec);
+
+ /* Copy all lines */
+ while (fgets(buf, sizeof(buf), file) != NULL)
+ {
+ fputs(buf, fh);
+ }
+ fprintf(fh, "}\n");
+ fclose(file);
+ fclose(fh);
+
+ return 0;
+}
+
+static void report(const char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+
+ fprintf(stderr, "rptaddrs: ");
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, "\n");
+
+ va_end(ap);
+}
+
+static void report_err(const char *fmt, ...)
+{
+ int t_errno;
+ va_list ap;
+
+ t_errno= errno;
+
+ va_start(ap, fmt);
+
+ fprintf(stderr, "rptaddrs: ");
+ vfprintf(stderr, fmt, ap);
+ fprintf(stderr, ": %s\n", strerror(t_errno));
+
+ va_end(ap);
+}
diff --git a/networking/rptra6.c b/networking/rptra6.c
index 8b45e72..b481252 100644
--- a/networking/rptra6.c
+++ b/networking/rptra6.c
@@ -35,7 +35,7 @@ static void usage(void)
exit(1);
}
-int rptaddr6_main(int argc, char *argv[]) MAIN_EXTERNALLY_VISIBLE;
+int rptra6_main(int argc, char *argv[]) MAIN_EXTERNALLY_VISIBLE;
int rptra6_main(int argc, char *argv[])
{
int i, r, first, sock, on, nrecv, rcvd_ttl, olen;