Ignore:
Timestamp:
Nov 17, 2007 10:27:34 AM (16 years ago)
Author:
bennylp
Message:

Ticket #414: Implement IP interface enumeration on Linux/Unix? with SIOCGIFCONF ioctl() call to a socket

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib/src/pj/ip_helper_generic.c

    r1104 r1584  
    2222#include <pj/errno.h> 
    2323#include <pj/string.h> 
     24#include <pj/compat/socket.h> 
    2425 
    25 /* 
    26  * Enumerate the local IP interface currently active in the host. 
    27  */ 
    28 PJ_DEF(pj_status_t) pj_enum_ip_interface(unsigned *p_cnt, 
    29                                          pj_in_addr ifs[]) 
     26static pj_status_t dummy_enum_ip_interface(unsigned *p_cnt, 
     27                                          pj_in_addr ifs[]) 
    3028{ 
    3129    pj_status_t status; 
     
    4240    *p_cnt = 1; 
    4341    return PJ_SUCCESS; 
     42} 
     43 
     44#ifdef SIOCGIFCONF 
     45static pj_status_t sock_enum_ip_interface(unsigned *p_cnt, 
     46                                          pj_in_addr ifs[]) 
     47{ 
     48    pj_sock_t sock; 
     49    char buf[512]; 
     50    struct ifconf ifc; 
     51    struct ifreq *ifr; 
     52    int i, count; 
     53    pj_status_t status; 
     54 
     55    status = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &sock); 
     56    if (status != PJ_SUCCESS) 
     57        return status; 
     58 
     59    /* Query available interfaces */ 
     60    ifc.ifc_len = sizeof(buf); 
     61    ifc.ifc_buf = buf; 
     62 
     63    if (ioctl(sock, SIOCGIFCONF, &ifc) < 0) { 
     64        int oserr = pj_get_netos_error(); 
     65        pj_sock_close(sock); 
     66        return PJ_RETURN_OS_ERROR(oserr); 
     67    } 
     68 
     69    /* Done with socket */ 
     70    pj_sock_close(sock); 
     71 
     72    /* Interface interfaces */ 
     73    ifr = (struct ifreq*) ifc.ifc_req; 
     74    count = ifc.ifc_len / sizeof(struct ifreq); 
     75    if (count > *p_cnt) 
     76        count = *p_cnt; 
     77    else 
     78        *p_cnt = count; 
     79    for (i=0; i<count; ++i) { 
     80        struct ifreq *itf = &ifr[i]; 
     81        ifs[i].s_addr = ((struct sockaddr_in *)&itf->ifr_addr)->sin_addr.s_addr; 
     82    } 
     83 
     84    return PJ_SUCCESS; 
     85} 
     86#endif /* SIOCGIFCONF */ 
     87 
     88/* 
     89 * Enumerate the local IP interface currently active in the host. 
     90 */ 
     91PJ_DEF(pj_status_t) pj_enum_ip_interface(unsigned *p_cnt, 
     92                                         pj_in_addr ifs[]) 
     93{ 
     94#ifdef SIOCGIFCONF 
     95    if (sock_enum_ip_interface(p_cnt, ifs) == PJ_SUCCESS) 
     96        return PJ_SUCCESS; 
     97#endif 
     98    return dummy_enum_ip_interface(p_cnt, ifs); 
    4499} 
    45100 
Note: See TracChangeset for help on using the changeset viewer.