Add message types for traffic steering anomaly messages
[ric-plt/lib/rmr.git] / src / rmr / common / src / tools_static.c
index 67adc85..df49dd8 100644 (file)
        Mnemonic:       tools_static.c
        Abstract:       A small set of very simple tools to support Uta == RMR.
                                        uta_tokenise -- simple string tokeniser
+                                       uta_rmip_tokenise -- tokenise and remove ip addresses from the list
                                        uta_h2ip        -- look up host name and return an ip address
                                        uta_lookup_rtg  -- looks in env for rtg host:port
                                        uta_has_str     -- searches buffer of tokens for a string
 
                                        uta_link2       -- establish a nanomsg connection to a host
 
+                                       uta_dump_env -- dump the environment variables to stdout that are
+                                                               of importance to RMR.
+
        Author:         E. Scott Daniels
        Date:           30 November 2018
 */
 #include <sys/socket.h>
 #include <netdb.h>
 
+// --- some protos needed for better organisation --------
+int is_this_myip( if_addrs_t* l, char* addr );
+
+
+// ----------------------------------------------------------------------------------
 
 /*
        Simple tokeniser. Split a null terminated string into tokens recording the
@@ -77,6 +86,43 @@ static int uta_tokenise( char* buf, char** tokens, int max, char sep ) {
        return n;
 }
 
+/*
+       Tokenise and remove matches.
+       Given a buffer of 'sep' separated tokens, and a list of things,
+       return up to max tokens with any tokens that matched things in
+       the list. Toks is the user supplied array of char* which we will
+       fill in (up to max) with pointers to tokens from buf.  This
+       damages buf, so the caller must dup the string if it must be
+       preserved for later, original, use.  The pointers returned in
+       toks will reference portions of bufs.
+
+       Returns the number of tokens referenced by toks.
+*/
+static int uta_rmip_tokenise( char* buf, if_addrs_t* iplist, char** toks, int max, char sep ) {
+       int     ntoks = 0;                      // total toks in the original buffer
+       int             pcount = 0;                     // count after prune
+       char**  all_toks;
+       int i;
+       int j;
+
+
+       all_toks = malloc( sizeof( char * ) * max );                                    // refernce to all tokens; we'll prune
+       pcount = ntoks = uta_tokenise( buf, all_toks, max, sep );               // split them up
+       j = 0;
+       if( ntoks > 0 ) {
+               for( i = 0; i < ntoks; i++ ) {
+                       if( is_this_myip( iplist, all_toks[i] ) ) {
+                               pcount--;                                                                       // ours, prune
+                       } else {
+                               toks[j++] = all_toks[i];                                        // not one of ours, keep it
+                       }
+               }
+       }
+
+       free( all_toks );
+       return pcount;
+}
+
 /*
        Xlate hostname (expected to be name:port) to an IP address that nano will tolerate.
        We'll use the first address from the list to keep it simple. If the first character
@@ -107,7 +153,7 @@ static char* uta_h2ip( char const* hname ) {
 
        hent = gethostbyname( dname );
        if( hent == NULL || hent->h_addr_list == NULL ) {
-               //fprintf( stderr, "[WARN] h2ip: dns lookup failed for: %s\n", dname );
+               //rmr_vlog( RMR_VL_WARN, "h2ip: dns lookup failed for: %s\n", dname );
                free( dname );
                return NULL;
        }
@@ -241,7 +287,7 @@ static int uta_has_str( char const* buf, char const* str, char sep, int max ) {
        to the list so that we don't pick up entries from the rtable that are for other
        processes listening on different interfaces.
 
-       The ENV_BIN_IF environment variable may be either an IP address (v6 must be in 
+       The ENV_BIN_IF environment variable may be either an IP address (v6 must be in
        square braces), or an interface name (e.g. eth0).
 */
 if_addrs_t*  mk_ip_list( char* port ) {
@@ -271,7 +317,7 @@ if_addrs_t*  mk_ip_list( char* port ) {
                        snprintf( wbuf, sizeof( wbuf ), "%s:%s", envp, port );          // smash port onto the addr as is
                        l->addrs[l->naddrs] = strdup( wbuf );
                        l->naddrs++;
-                       if( DEBUG ) fprintf( stderr, "[INFO] rmr: using only specific bind interface when searching specific RT entries: %s\n", wbuf );
+                       if( DEBUG ) rmr_vlog( RMR_VL_INFO, "rmr: using only specific bind interface when searching specific RT entries: %s\n", wbuf );
                        return l;
                }
 
@@ -284,13 +330,15 @@ if_addrs_t*  mk_ip_list( char* port ) {
                if( ele && strcmp( ele->ifa_name, "lo" ) &&                                                                     // do NOT capture the loopback interface address
                        (target_if == NULL || strcmp( ele->ifa_name, target_if ) == 0 ) ) {             // no target, or matches ENV_BIND_IF target
 
-                       if( ele->ifa_addr->sa_family == AF_INET ) {
-                               getnameinfo( ele->ifa_addr, sizeof( struct sockaddr_in ),  octs, NI_MAXHOST, NULL, 0, NI_NUMERICHOST );
-                               fmt = "%s:%s";
-                       } else {
-                               if( ele->ifa_addr->sa_family == AF_INET6 ) {
-                                       getnameinfo( ele->ifa_addr, sizeof( struct sockaddr_in6 ),  octs, NI_MAXHOST, NULL, 0, NI_NUMERICHOST );
-                                       fmt = "[%s]:%s";
+                       if( ele->ifa_addr != NULL ) {                                           // possible for some interfaces to not have an address
+                               if( ele->ifa_addr->sa_family == AF_INET ) {
+                                       getnameinfo( ele->ifa_addr, sizeof( struct sockaddr_in ),  octs, NI_MAXHOST, NULL, 0, NI_NUMERICHOST );
+                                       fmt = "%s:%s";
+                               } else {
+                                       if( ele->ifa_addr->sa_family == AF_INET6 ) {
+                                               getnameinfo( ele->ifa_addr, sizeof( struct sockaddr_in6 ),  octs, NI_MAXHOST, NULL, 0, NI_NUMERICHOST );
+                                               fmt = "[%s]:%s";
+                                       }
                                }
                        }
 
@@ -299,7 +347,7 @@ if_addrs_t*  mk_ip_list( char* port ) {
                                        *tok = 0;
                                }
                                if( l->naddrs < 128 ) {
-                                       if( DEBUG ) fprintf( stderr, "[DBUG] capture address: %s: %s\n", ele->ifa_name, octs );
+                                       if( DEBUG ) rmr_vlog( RMR_VL_DEBUG, "capture address: %s: %s\n", ele->ifa_name, octs );
 
                                        snprintf( wbuf, sizeof( wbuf ), fmt, octs, port );              // smash port onto the addr
                                        l->addrs[l->naddrs] = strdup( wbuf );
@@ -330,8 +378,12 @@ int is_this_myip( if_addrs_t* l, char* addr ) {
                return 0;
        }
 
+       if( addr == NULL ) {
+               return 0;
+       }
+
        for( i = 0; i < l->naddrs; i++ ) {
-               if( strcmp( addr, l->addrs[i] ) == 0 ) {
+               if( l->addrs[i] != NULL  &&  strcmp( addr, l->addrs[i] ) == 0 ) {
                        return 1;
                }
        }
@@ -411,4 +463,37 @@ static char* get_default_ip( if_addrs_t* iplist ) {
        return NULL;
 }
 
+/*
+       Write all environment variables that we consider to be important to stderr.
+*/
+static void uta_dump_env( ) {
+       char* token;
+       char* elist[] = {
+                       ENV_BIND_IF,
+                       ENV_RTG_PORT,
+                       ENV_RTG_ADDR,
+                       ENV_SEED_RT,
+                       ENV_SEED_MEMAP,
+                       ENV_RTG_RAW,
+                       ENV_VERBOSE_FILE,
+                       ENV_NAME_ONLY,
+                       ENV_WARNINGS,
+                       ENV_SRC_ID,
+                       ENV_LOG_HR,
+                       ENV_LOG_VLEVEL,
+                       ENV_CTL_PORT,
+                       ENV_RTREQ_FREA
+       };
+       int i;
+
+       for( i = 0; i < sizeof( elist ) / sizeof( char *); i ++ ) {
+               token = getenv( elist[i] );
+               if( token != NULL ) {
+                       rmr_vlog( RMR_VL_INFO, "dump_env: %s = '%s'\n", elist[i], token );
+               } else {
+                       rmr_vlog( RMR_VL_INFO, "dump_env: %s = <unset>\n", elist[i] );
+               }
+       }
+}
+
 #endif