"Fossies" - the Fresh Open Source Software Archive

Member "sysdig-0.26.1/userspace/libscap/scap_iflist.c" (24 May 2019, 6394 Bytes) of package /linux/misc/sysdig-0.26.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "scap_iflist.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2 Copyright (C) 2013-2018 Draios Inc dba Sysdig.
    3 
    4 This file is part of sysdig.
    5 
    6 Licensed under the Apache License, Version 2.0 (the "License");
    7 you may not use this file except in compliance with the License.
    8 You may obtain a copy of the License at
    9 
   10     http://www.apache.org/licenses/LICENSE-2.0
   11 
   12 Unless required by applicable law or agreed to in writing, software
   13 distributed under the License is distributed on an "AS IS" BASIS,
   14 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   15 See the License for the specific language governing permissions and
   16 limitations under the License.
   17 
   18 */
   19 
   20 #include <stdio.h>
   21 
   22 #include "scap.h"
   23 #include "scap-int.h"
   24 
   25 #if defined(HAS_CAPTURE)
   26 #include <sys/types.h>
   27 #include <sys/socket.h>
   28 #include <arpa/inet.h>
   29 #include <netinet/in.h>
   30 #include <net/if.h>
   31 #include <ifaddrs.h>
   32 #include <errno.h>
   33 
   34 //
   35 // Allocate and return the list of interfaces on this system
   36 //
   37 int32_t scap_create_iflist(scap_t* handle)
   38 {
   39     struct ifaddrs *interfaceArray = NULL, *tempIfAddr = NULL;
   40     void *tempAddrPtr = NULL;
   41     int rc = 0;
   42     uint32_t ifcnt4 = 0;
   43     uint32_t ifcnt6 = 0;
   44 
   45     //
   46     // If the list of interfaces was already allocated for this handle (for example because this is
   47     // not the first interface list block), free it
   48     //
   49     if(handle->m_addrlist != NULL)
   50     {
   51         scap_free_iflist(handle->m_addrlist);
   52         handle->m_addrlist = NULL;
   53     }
   54 
   55     rc = getifaddrs(&interfaceArray);  /* retrieve the current interfaces */
   56     if(rc != 0)
   57     {
   58         snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "getifaddrs failed");
   59         return SCAP_FAILURE;
   60     }
   61 
   62     //
   63     // First pass: count the number of interfaces
   64     //
   65     for(tempIfAddr = interfaceArray; tempIfAddr != NULL; tempIfAddr = tempIfAddr->ifa_next)
   66     {
   67         if(tempIfAddr->ifa_addr == NULL)
   68         {
   69             // "eql" interface like on EC2
   70             continue;
   71         }
   72         
   73         if(tempIfAddr->ifa_addr->sa_family == AF_INET)
   74         {
   75             ifcnt4++;
   76         }
   77         else if(tempIfAddr->ifa_addr->sa_family == AF_INET6)
   78         {
   79             ifcnt6++;
   80         }
   81     }
   82 
   83     //
   84     // Allocate the handle and the arrays
   85     //
   86     handle->m_addrlist = (scap_addrlist*)malloc(sizeof(scap_addrlist));
   87     if(!handle->m_addrlist)
   88     {
   89         snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "getifaddrs allocation failed(1)");
   90         return SCAP_FAILURE;
   91     }
   92 
   93     if(ifcnt4 != 0)
   94     {
   95         handle->m_addrlist->v4list = (scap_ifinfo_ipv4*)malloc(ifcnt4 * sizeof(scap_ifinfo_ipv4));
   96         if(!handle->m_addrlist->v4list)
   97         {
   98             snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "getifaddrs allocation failed(2)");
   99             free(handle->m_addrlist);
  100             return SCAP_FAILURE;
  101         }
  102     }
  103     else
  104     {
  105         handle->m_addrlist->v4list = NULL;
  106     }
  107 
  108     if(ifcnt6 != 0)
  109     {
  110         handle->m_addrlist->v6list = (scap_ifinfo_ipv6*)malloc(ifcnt6 * sizeof(scap_ifinfo_ipv6));
  111         if(!handle->m_addrlist->v6list)
  112         {
  113             snprintf(handle->m_lasterr, SCAP_LASTERR_SIZE, "getifaddrs allocation failed(3)");
  114             if(handle->m_addrlist->v4list)
  115             {
  116                 free(handle->m_addrlist->v4list);
  117             }
  118             free(handle->m_addrlist);
  119             return SCAP_FAILURE;
  120         }
  121     }
  122     else
  123     {
  124         handle->m_addrlist->v6list = NULL;
  125     }
  126 
  127     handle->m_addrlist->n_v4_addrs = ifcnt4;
  128     handle->m_addrlist->n_v6_addrs = ifcnt6;
  129 
  130     //
  131     // Second pass: populate the arrays
  132     //
  133     handle->m_addrlist->totlen = 0;
  134     ifcnt4 = 0;
  135     ifcnt6 = 0;
  136 
  137     for(tempIfAddr = interfaceArray; tempIfAddr != NULL; tempIfAddr = tempIfAddr->ifa_next)
  138     {
  139         if(tempIfAddr->ifa_addr == NULL)
  140         {
  141             // "eql" interface like on EC2
  142             continue;
  143         }
  144 
  145         if(tempIfAddr->ifa_addr->sa_family == AF_INET)
  146         {
  147             handle->m_addrlist->v4list[ifcnt4].type = SCAP_II_IPV4;
  148 
  149             tempAddrPtr = &((struct sockaddr_in *)tempIfAddr->ifa_addr)->sin_addr;
  150             handle->m_addrlist->v4list[ifcnt4].addr = *(uint32_t*)tempAddrPtr;
  151 
  152             if(tempIfAddr->ifa_netmask != NULL)
  153             {
  154                 handle->m_addrlist->v4list[ifcnt4].netmask = *(uint32_t*)&(((struct sockaddr_in *)tempIfAddr->ifa_netmask)->sin_addr);
  155             }
  156             else
  157             {
  158                 handle->m_addrlist->v4list[ifcnt4].netmask = 0;
  159             }
  160 
  161 #ifndef CYGWING_AGENT
  162             if(tempIfAddr->ifa_ifu.ifu_broadaddr != NULL)
  163             {
  164                 handle->m_addrlist->v4list[ifcnt4].bcast = *(uint32_t*)&(((struct sockaddr_in *)tempIfAddr->ifa_ifu.ifu_broadaddr)->sin_addr);
  165             }
  166             else
  167             {
  168                 handle->m_addrlist->v4list[ifcnt4].bcast = 0;
  169             }
  170 #else
  171             handle->m_addrlist->v4list[ifcnt4].bcast = 0;
  172 #endif
  173             strncpy(handle->m_addrlist->v4list[ifcnt4].ifname, tempIfAddr->ifa_name, SCAP_MAX_PATH_SIZE);
  174             handle->m_addrlist->v4list[ifcnt4].ifnamelen = strlen(tempIfAddr->ifa_name);
  175 
  176             handle->m_addrlist->v4list[ifcnt4].linkspeed = 0;
  177 
  178             handle->m_addrlist->totlen += (sizeof(scap_ifinfo_ipv4) + handle->m_addrlist->v4list[ifcnt4].ifnamelen - SCAP_MAX_PATH_SIZE);
  179             ifcnt4++;
  180         }
  181         else if(tempIfAddr->ifa_addr->sa_family == AF_INET6)
  182         {
  183             handle->m_addrlist->v6list[ifcnt6].type = SCAP_II_IPV6;
  184 
  185             tempAddrPtr = &((struct sockaddr_in6 *)tempIfAddr->ifa_addr)->sin6_addr;
  186 
  187             memcpy(handle->m_addrlist->v6list[ifcnt6].addr, tempAddrPtr, 16);
  188 
  189             if(tempIfAddr->ifa_netmask != NULL)
  190             {
  191                 memcpy(handle->m_addrlist->v6list[ifcnt6].netmask,
  192                         &(((struct sockaddr_in6 *)tempIfAddr->ifa_netmask)->sin6_addr),
  193                         16);
  194             }
  195             else
  196             {
  197                 memset(handle->m_addrlist->v6list[ifcnt6].netmask, 0, 16);
  198             }
  199 
  200 #ifndef CYGWING_AGENT
  201             if(tempIfAddr->ifa_ifu.ifu_broadaddr != NULL)
  202             {
  203                 memcpy(handle->m_addrlist->v6list[ifcnt6].bcast,
  204                         &(((struct sockaddr_in6 *)tempIfAddr->ifa_ifu.ifu_broadaddr)->sin6_addr),
  205                         16);
  206             }
  207             else
  208             {
  209                 memset(handle->m_addrlist->v6list[ifcnt6].bcast, 0, 16);
  210             }
  211 #else
  212             handle->m_addrlist->v4list[ifcnt4].bcast = 0;
  213 #endif
  214 
  215             strncpy(handle->m_addrlist->v6list[ifcnt6].ifname, tempIfAddr->ifa_name, SCAP_MAX_PATH_SIZE);
  216             handle->m_addrlist->v6list[ifcnt6].ifnamelen = strlen(tempIfAddr->ifa_name);
  217 
  218             handle->m_addrlist->v6list[ifcnt6].linkspeed = 0;
  219 
  220             handle->m_addrlist->totlen += (sizeof(scap_ifinfo_ipv6) + handle->m_addrlist->v6list[ifcnt6].ifnamelen - SCAP_MAX_PATH_SIZE);
  221             ifcnt6++;
  222         }
  223         else
  224         {
  225             continue;
  226         }
  227     }
  228 
  229     //
  230     // Memory cleanup
  231     //
  232     freeifaddrs(interfaceArray);
  233 
  234     return SCAP_SUCCESS;
  235 }
  236 
  237 void scap_refresh_iflist(scap_t* handle)
  238 {
  239     scap_free_iflist(handle->m_addrlist);
  240     handle->m_addrlist = NULL;
  241     scap_create_iflist(handle);
  242 }
  243 #endif // HAS_CAPTURE
  244 
  245 //
  246 // Free a previously allocated list of interfaces
  247 //
  248 void scap_free_iflist(scap_addrlist* ifhandle)
  249 {
  250     if(ifhandle)
  251     {
  252         if(ifhandle->v6list)
  253         {
  254             free(ifhandle->v6list);
  255         }
  256 
  257         if(ifhandle->v4list)
  258         {
  259             free(ifhandle->v4list);
  260         }
  261 
  262         free(ifhandle);
  263     }
  264 }