⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slp_iface.c

📁 SLP协议在linux下的实现。此版本为1.2.1版。官方网站为www.openslp.org
💻 C
字号:
/***************************************************************************//*                                                                         *//* Project:     OpenSLP - OpenSource implementation of Service Location    *//*              Protocol                                                   *//*                                                                         *//* File:        slp_iface.c                                                *//*                                                                         *//* Abstract:    Common code to obtain network interface information        *//*                                                                         *//*-------------------------------------------------------------------------*//*                                                                         *//*     Please submit patches to http://www.openslp.org                     *//*                                                                         *//*-------------------------------------------------------------------------*//*                                                                         *//* Copyright (C) 2000 Caldera Systems, Inc                                 *//* All rights reserved.                                                    *//*                                                                         *//* Redistribution and use in source and binary forms, with or without      *//* modification, are permitted provided that the following conditions are  *//* met:                                                                    */ /*                                                                         *//*      Redistributions of source code must retain the above copyright     *//*      notice, this list of conditions and the following disclaimer.      *//*                                                                         *//*      Redistributions in binary form must reproduce the above copyright  *//*      notice, this list of conditions and the following disclaimer in    *//*      the documentation and/or other materials provided with the         *//*      distribution.                                                      *//*                                                                         *//*      Neither the name of Caldera Systems nor the names of its           *//*      contributors may be used to endorse or promote products derived    *//*      from this software without specific prior written permission.      *//*                                                                         *//* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS     *//* `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT      *//* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR   *//* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CALDERA      *//* SYSTEMS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *//* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT        *//* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE,  *//* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON       *//* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *//* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   *//* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    *//*                                                                         *//***************************************************************************/#include "slp_iface.h"#include "slp_xmalloc.h"#include "slp_compare.h"#include "slp_net.h"#include <errno.h>#include <stdio.h>#include <string.h>#ifdef SOLARIS#include <sys/sockio.h>#endif#ifndef _WIN32#include <sys/ioctl.h>#include <net/if.h>#include <arpa/inet.h>#else#ifndef UINT32_T_DEFINED#define UINT32_T_DEFINEDtypedef unsigned int uint32_t; #endif#endif#if defined(LINUX) || defined(AIX) || defined(SOLARIS) || defined(HPUX)/*=========================================================================*/int SLPIfaceGetInfo(const char* useifaces,                    SLPIfaceInfo* ifaceinfo)/* Description: *    Get the network interface addresses for this host.  Exclude the *    loopback interface * * Parameters: *     useifaces (IN) Pointer to comma delimited string of interface IPv4 *                    addresses to get interface information for.  Pass *                    NULL or empty string to get all interfaces (except  *                    loopback) *     ifaceinfo (OUT) Information about requested interfaces. * * Returns: *     zero on success, non-zero (with errno set) on error. *=========================================================================*/{    struct sockaddr* sa;    struct sockaddr_in* sin;    struct ifreq ifrlist[SLP_MAX_IFACES];    struct ifreq ifrflags;    struct ifconf ifc;    int fd;    int i;    int useifaceslen;    #ifdef DEBUG    if(ifaceinfo == NULL )    {        errno = EINVAL;        /* bad parameters */        return 1;    }    #endif    ifc.ifc_len = sizeof(struct ifreq) * SLP_MAX_IFACES ;    ifc.ifc_req = ifrlist;        fd = socket(AF_INET,SOCK_STREAM,0);    if(fd == -1)    {        /* failed to create socket */        #ifdef DEBUG        fprintf(stderr,"%s:%i Failed to created socket\n",__FILE__,__LINE__);        #endif        return 1;    }    #ifdef AIX    if (ioctl(fd,OSIOCGIFCONF,&ifc) == -1)    #else    if (ioctl(fd,SIOCGIFCONF,&ifc) == -1)    #endif    {        perror("ioctl failed");        #ifdef _WIN32        closesocket(fd);        #else        close(fd);        #endif        return 1;    }    if(useifaces && *useifaces)    {        useifaceslen = strlen(useifaces);    }    else    {        useifaceslen = 0;    }    memset(ifaceinfo,0,sizeof(SLPIfaceInfo));    for (i = 0; i < ifc.ifc_len/sizeof(struct ifreq); i++)    {        sa = (struct sockaddr *)&(ifrlist[i].ifr_addr);        if(sa->sa_family == AF_INET)        {            /* Get interface flags */            memcpy(&ifrflags,&(ifrlist[i]),sizeof(struct ifreq));            if(ioctl(fd,SIOCGIFFLAGS, &ifrflags) == 0)            {                /* skip the loopback interfaces */                if((ifrflags.ifr_flags & IFF_LOOPBACK) == 0)                {                    /* Only include those interfaces in the requested list */                    sin = (struct sockaddr_in*)sa;                    if(useifaceslen == 0 ||                       SLPContainsStringList(useifaceslen,                                             useifaces,                                             strlen(inet_ntoa(sin->sin_addr)),                                             inet_ntoa(sin->sin_addr)))                    {                        memcpy(&(ifaceinfo->iface_addr[ifaceinfo->iface_count]),                               sin,                               sizeof(struct sockaddr_in));                                            #ifdef AIX                        if(ioctl(fd,OSIOCGIFBRDADDR,&(ifrlist[i])) == 0)                        #else                        if(ioctl(fd,SIOCGIFBRDADDR,&(ifrlist[i])) == 0)                        #endif                        {                            sin = (struct sockaddr_in *)&(ifrlist[i].ifr_broadaddr);                            memcpy(&(ifaceinfo->bcast_addr[ifaceinfo->iface_count]),                                   sin,                                   sizeof(struct sockaddr_in));                        }                                ifaceinfo->iface_count ++;                    }                }            }        }    }    #ifdef _WIN32    closesocket(fd);    #else    close(fd);    #endif    return 0;}#else/*=========================================================================*/int SLPIfaceGetInfo(const char* useifaces,                    SLPIfaceInfo* ifaceinfo)/* Description: *    Get the network interface addresses for this host.  Exclude the *    loopback interface * * Parameters: *     useifaces (IN) Pointer to comma delimited string of interface IPv4 *                    addresses to get interface information for.  Pass *                    NULL or empty string to get all interfaces (except  *                    loopback) *     ifaceinfo (OUT) Information about requested interfaces. * * Returns: *     zero on success, non-zero (with errno set) on error. *=========================================================================*/{    /*---------------------------------------------------*/    /* Use gethostbyname(). Not necessarily the best way */    /*---------------------------------------------------*/    struct hostent* myhostent;    char*           myname;    struct in_addr  ifaddr;    uint32_t**      haddr;    int             useifaceslen;        if(SLPNetGetThisHostname(&myname,0) == 0)    {        myhostent = gethostbyname(myname);        if(myhostent != 0)        {            if(myhostent->h_addrtype == AF_INET)            {                if(useifaces && *useifaces)                {                    useifaceslen = strlen(useifaces);                }                else                {                    useifaceslen = 0;                }                ifaceinfo->iface_count = 0;                haddr = (uint32_t**)(myhostent->h_addr_list);                                /* count the interfaces */                while(*haddr)                {                    ifaddr.s_addr = **haddr;                    if(useifaceslen == 0 ||                       SLPContainsStringList(useifaceslen,                                             useifaces,                                             strlen(inet_ntoa(ifaddr)),                                             inet_ntoa(ifaddr)))                    {                        memcpy(&(ifaceinfo->iface_addr[ifaceinfo->iface_count].sin_addr),                               &ifaddr,                               sizeof(ifaddr));                                                                    /* There is no way to deterine the broadcast address */                        /* Set it to global broadcast                        */                        ifaceinfo->bcast_addr[ifaceinfo->iface_count].sin_addr.s_addr = INADDR_BROADCAST;                        ifaceinfo->iface_count ++;                    }                     haddr ++;                }            }        }        xfree(myname);        }    return 0;}#endif/*=========================================================================*/int SLPIfaceSockaddrsToString(const struct sockaddr_in* addrs,                              int addrcount,                              char** addrstr)/* Description: *    Get the comma delimited string of addresses from an array of sockaddrs * * Parameters: *     addrs (IN) Pointer to array of sockaddrs to convert *     addrcount (IN) Number of sockaddrs in addrs. *     addrstr (OUT) pointer to receive malloc() allocated address string. *                   Caller must free() addrstr when no longer needed. * * Returns: *     zero on success, non-zero (with errno set) on error. *=========================================================================*/{    int i;        #ifdef DEBUG    if(addrs == NULL ||       addrcount == 0 ||       addrstr == NULL)    {        /* invalid paramaters */        errno = EINVAL;        return 1;    }    #endif    /* 16 is the maximum size of a string representation of     * an IPv4 address (including the comman for the list)     */    *addrstr = (char *)xmalloc(addrcount * 16);    *addrstr[0] = 0;        for (i=0;i<addrcount;i++)    {        strcat(*addrstr,inet_ntoa(addrs[i].sin_addr));        if (i != addrcount-1)        {            strcat(*addrstr,",");        }    }    return 0;}  /*=========================================================================*/int SLPIfaceStringToSockaddrs(const char* addrstr,                              struct sockaddr_in* addrs,                              int* addrcount)/* Description: *    Fill an array of struct sockaddrs from the comma delimited string of *    addresses. * * Parameters: *     addrstr (IN) Address string to convert. *     addrcount (OUT) sockaddr array to fill. *     addrcount (INOUT) The number of sockaddr stuctures in the addr array *                       on successful return will contain the number of *                       sockaddrs that were filled in the addr array * * Returns: *     zero on success, non-zero (with errno set) on error. *=========================================================================*/{    int i;    char* str;    char* slider1;    char* slider2;    #ifdef DEBUG    if(addrstr == NULL ||       addrs == NULL ||       addrcount == 0)    {        /* invalid parameters */        errno = EINVAL;        return 1;    }    #endif    str = xstrdup(addrstr);    if(str == NULL)    {        /* out of memory */        return 1;    }        i=0;    slider1 = str;    while(1)    {        slider2 = strchr(slider1,',');                /* check for empty string */        if(slider2 == slider1)        {            break;        }        /* stomp the comma and null terminate address */        if(slider2)        {            *slider2 = 0;        }                inet_aton(slider1, &(addrs[i].sin_addr));        i++;        if(i == *addrcount)        {            break;        }        /* are we done? */        if(slider2 == 0)        {            break;        }        slider1 = slider2 + 1;    }    *addrcount = i;    xfree(str);    return 0;}/*=========================================================================== * TESTING CODE enabled by removing #define comment and compiling with the  * following command line: * * $ gcc -g -DDEBUG slp_iface.c slp_xmalloc.c slp_linkedlist.c slp_compare.c *==========================================================================*//* #define SLP_IFACE_TEST  */#ifdef SLP_IFACE_TEST int main(int argc, char* argv[]){    int i;    int addrscount =  10;    struct sockaddr_in* addrs[10];    SLPIfaceInfo ifaceinfo;    char* addrstr;    if(SLPIfaceGetInfo(NULL,&ifaceinfo) == 0)    {        for(i=0;i<ifaceinfo.iface_count;i++)        {            printf("found iface = %s\n",inet_ntoa(ifaceinfo.iface_addr[i].sin_addr));            printf("bcast addr = %s\n",inet_ntoa(ifaceinfo.bcast_addr[i].sin_addr));        }    }    if(SLPIfaceStringToSockaddrs("192.168.100.1,192.168.101.1",                                 (struct sockaddr_in*)&addrs,                                 &addrscount) == 0)    {        if(SLPIfaceSockaddrsToString((struct sockaddr_in*)&addrs,                                          addrscount,                                         &addrstr) == 0)        {            printf("sock addr string = %s\n",addrstr);            xfree(addrstr);        }    }}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -