Chinaunix首页 | 论坛 | 博客
  • 博客访问: 285146
  • 博文数量: 65
  • 博客积分: 3091
  • 博客等级: 中校
  • 技术积分: 705
  • 用 户 组: 普通用户
  • 注册时间: 2005-01-25 09:44
文章存档

2013年(2)

2012年(11)

2011年(12)

2010年(13)

2009年(15)

2008年(12)

分类: 系统运维

2010-11-25 00:03:05

/* Copyright (C) 1998,99,2000,01 Free Software Foundation, Inc.
   This file is part of the GNU C Library.
   Contributed by Andreas Jaeger , 1998.

   The GNU C Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 2.1 of the License, or (at your option) any later version.

   The GNU C Library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General Public
   License along with the GNU C Library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
   02111-1307 USA.  */

/*
  Testing of some network related lookup functions.
  The system databases looked up are:
  - /etc/services
  - /etc/hosts
    ::1             localhost
    127.0.0.1       localhost linuxhost
    192.168.1.86    linuxhost
    192.100.100.101 linuxhost
    192.168.1.96    sunhost
  - /etc/networks
    default         0.0.0.0
    loopback        127.0.0.0
    link-local      169.254.0.0
    DANETA          192.168.1.0      daneta
    DANETB          192.100.100.0    danetb
  - /etc/protocols
  - /etc/rpc
  The tests try to be fairly generic and simple so that they work on
  every possible setup (and might therefore not detect some possible
  errors).
*/

#include
#include
#include
#include
#include

#include
#include
#include
#include
#include
#include
#include
#include
/* #include */
#include

#if defined(__sun) /* solaris */
#include
#include
#endif

/*
  The following define is necessary for glibc 2.0.6
*/
#ifndef INET6_ADDRSTRLEN
# define INET6_ADDRSTRLEN 46
#endif

int error_count;

static void
output_servent (const char *call, struct servent *sptr)
{
    char **pptr;

    if (sptr == NULL)
        printf ("Call: %s returned NULL\n", call);
    else
    {
        printf ("Call: %s, returned: s_name: %s, s_port: %d, s_proto: %s\n",
                call, sptr->s_name, ntohs(sptr->s_port), sptr->s_proto);
        for (pptr = sptr->s_aliases; *pptr != NULL; pptr++)
            printf ("  alias: %s\n", *pptr);
    }
    return;
}


static void
test_services (void)
{
    struct servent *sptr;

    sptr = getservbyname ("domain", "tcp");
    output_servent ("getservbyname (\"domain\", \"tcp\")", sptr);

    sptr = getservbyname ("domain", "udp");
    output_servent ("getservbyname (\"domain\", \"udp\")", sptr);

    sptr = getservbyname ("domain", NULL);
    output_servent ("getservbyname (\"domain\", NULL)", sptr);

    sptr = getservbyname ("not-existant", NULL);
    output_servent ("getservbyname (\"not-existant\", NULL)", sptr);

    /* This shouldn't return anything.  */
    sptr = getservbyname ("", "");
    output_servent ("getservbyname (\"\", \"\")", sptr);

    sptr = getservbyname ("", "tcp");
    output_servent ("getservbyname (\"\", \"tcp\")", sptr);

    sptr = getservbyport (htons(53), "tcp");
    output_servent ("getservbyport (htons(53), \"tcp\")", sptr);

    sptr = getservbyport (htons(53), NULL);
    output_servent ("getservbyport (htons(53), NULL)", sptr);

    sptr = getservbyport (htons(1), "udp"); /* shouldn't exist */
    output_servent ("getservbyport (htons(1), \"udp\")", sptr);

    setservent (0);
    do
    {
        sptr = getservent ();
        output_servent ("getservent ()", sptr);
    }while (sptr != NULL);
    endservent ();

    return;
}


static void
output_hostent (const char *call, struct hostent *hptr)
{
    char **pptr;
    char buf[INET6_ADDRSTRLEN];

    if (hptr == NULL)
        printf ("Call: %s returned NULL\n", call);
    else
    {
        printf ("Call: %s returned: name: %s, addr_type: %d\n",
                call, hptr->h_name, hptr->h_addrtype);
        if (hptr->h_aliases)
            for (pptr = hptr->h_aliases; *pptr != NULL; pptr++)
                printf ("  alias: %s\n", *pptr);

        for (pptr = hptr->h_addr_list; *pptr != NULL; pptr++)
            printf ("  ip: %s\n",
                    inet_ntop (hptr->h_addrtype, *pptr, buf, sizeof (buf)));
    }
    return;
}

static void
test_hosts (void)
{
    struct hostent *hptr1, *hptr2;
    char *name = NULL;
    size_t namelen = 0;
    struct in_addr ip;

    hptr1 = gethostbyname ("localhost");
    hptr2 = gethostbyname ("LocalHost");
    if (hptr1 != NULL || hptr2 != NULL)
    {
        if (hptr1 == NULL)
        {
            printf ("localhost not found - but LocalHost found:-(\n");
            ++error_count;
        }
        else if (hptr2 == NULL)
        {
            printf ("LocalHost not found - but localhost found:-(\n");
            ++error_count;
        }
        else if (strcmp (hptr1->h_name, hptr2->h_name) != 0)
        {
            printf ("localhost and LocalHost have different canoncial name\n");
            printf ("gethostbyname (\"localhost\")->%s\n", hptr1->h_name);
            printf ("gethostbyname (\"LocalHost\")->%s\n", hptr2->h_name);
            ++error_count;
        }
        else
            output_hostent ("gethostbyname(\"localhost\")", hptr1);
    }

    hptr1 = gethostbyname ("127.0.0.1");
    output_hostent ("gethostbyname (\"127.0.0.1\")", hptr1);

#if defined(__linux)
    hptr1 = gethostbyname ("10.1234");
    output_hostent ("gethostbyname (\"10.1234\")", hptr1);

    hptr1 = gethostbyname2 ("localhost", AF_INET);
    output_hostent ("gethostbyname2 (\"localhost\", AF_INET)", hptr1);
#endif

    namelen = 64;
    name = (char *)malloc(namelen);
    if (gethostname (name, namelen) == 0)
    {
        printf ("Hostname: %s\n", name);
        if (name != NULL)
        {
            hptr1 = gethostbyname (name);
            output_hostent ("gethostbyname (gethostname(...))", hptr1);
        }
    }

    ip.s_addr = htonl (INADDR_LOOPBACK);
    hptr1 = gethostbyaddr ((char *) &ip, sizeof(ip), AF_INET);
    if (hptr1 != NULL)
    {
        printf ("official name of 127.0.0.1: %s\n", hptr1->h_name);
    }

    sethostent (0);
    do
    {
        hptr1 = gethostent ();
        output_hostent ("gethostent ()", hptr1);
    }while (hptr1 != NULL);
    endhostent ();

    if (name != NULL) free(name);
    return;
}


static void
output_netent (const char *call, struct netent *nptr)
{
    char **pptr;

    if (nptr == NULL)
        printf ("Call: %s returned NULL\n", call);
    else
    {
        struct in_addr ip;

        ip.s_addr = htonl(nptr->n_net);
        printf ("Call: %s, returned: n_name: %s, network_number: %s\n",
                call, nptr->n_name, inet_ntoa (ip));

        for (pptr = nptr->n_aliases; *pptr != NULL; pptr++)
            printf ("  alias: %s\n", *pptr);
    }
    return;
}

static void
test_network (void)
{
    struct netent *nptr;
    uint32_t ip;

    /*
       This test needs the following line in /etc/networks:
       loopback        127.0.0.0
    */
    nptr = getnetbyname ("loopback");
    output_netent ("getnetbyname (\"loopback\")",nptr);

    nptr = getnetbyname ("LoopBACK");
    output_netent ("getnetbyname (\"LoopBACK\")",nptr);

    ip = inet_network ("127.0.0.0");
    nptr = getnetbyaddr (ip, AF_INET);
    output_netent ("getnetbyaddr (inet_network (\"127.0.0.0\"), AF_INET)",nptr);

    setnetent (0);
    do
    {
        nptr = getnetent ();
        output_netent ("getnetent ()", nptr);
    }while (nptr != NULL);
    endnetent ();

    return;
}


static void
output_protoent (const char *call, struct protoent *prptr)
{
    char **pptr;

    if (prptr == NULL)
        printf ("Call: %s returned NULL\n", call);
    else
    {
        printf ("Call: %s, returned: p_name: %s, p_proto: %d\n",
                call, prptr->p_name, prptr->p_proto);
        for (pptr = prptr->p_aliases; *pptr != NULL; pptr++)
            printf ("  alias: %s\n", *pptr);
    }
    return;
}


static void
test_protocols (void)
{
    struct protoent *prptr;

    prptr = getprotobyname ("IP");
    output_protoent ("getprotobyname (\"IP\")", prptr);

    prptr = getprotobynumber (1);
    output_protoent ("getprotobynumber (1)", prptr);

    setprotoent (0);
    do
    {
        prptr = getprotoent ();
        output_protoent ("getprotoent ()", prptr);
    }while (prptr != NULL);
    endprotoent ();

    return;
}


static void
output_rpcent (const char *call, struct rpcent *rptr)
{
    char **pptr;

    if (rptr == NULL)
        printf ("Call: %s returned NULL\n", call);
    else
    {
        printf ("Call: %s, returned: r_name: %s, r_number: %d\n",
                call, rptr->r_name, rptr->r_number);
        for (pptr = rptr->r_aliases; *pptr != NULL; pptr++)
            printf ("  alias: %s\n", *pptr);
    }
    return;
}

static void
test_rpc (void)
{
    struct rpcent *rptr;

    rptr = getrpcbyname ("portmap");
    output_rpcent ("getrpcyname (\"portmap\")", rptr);

    rptr = getrpcbynumber (100000);
    output_rpcent ("getrpcbynumber (100000)", rptr);

    setrpcent (0);
    do
    {
        rptr = getrpcent ();
        output_rpcent ("getrpcent ()", rptr);
    }while (rptr != NULL);
    endrpcent ();

    return;
}

#if defined(__linux)
/* Override /etc/nsswitch.conf for this program.  This is mainly
   useful for developers. */
static void  __attribute__ ((unused))
setdb (const char *dbname)
{
    if (strcmp ("db", dbname))
    {
        /*
          db is not implemented for hosts, networks
        */
        __nss_configure_lookup ("hosts", dbname);
        __nss_configure_lookup ("networks", dbname);
    }
    __nss_configure_lookup ("protocols", dbname);
    __nss_configure_lookup ("rpc", dbname);
    __nss_configure_lookup ("services", dbname);

    return;
}
#endif

int main (int argc, char **argv)
{
    int  ret;
    int  csock, tsock, dsock;
    int  i, size;
    int  namelen, salen;
    char *ptr = NULL, **pptr = NULL;
    char *hostname = NULL, *str = NULL;
    struct ifconf ifc;
    struct ifreq  ifr, *pifr;
    struct hostent *pHostEntry = NULL;
    struct sockaddr saddr, tsaddr;
    struct sockaddr_in si_addr, *psa;
    struct in_addr addr, inaddr;
    struct netent *nptr = NULL;

    /* struct sockaddr { */
    /*     unsigned short sa_family; */     /* Protocal Family, PF_xxx */
    /*     char sa_data[14]; */              /* 14 bytes of protocol address */
    /* } */
    /* struct sockaddr_in { */
    /*     short int sin_family; */         /* Address Family, AF_XXX */
    /*     unsigned short int sin_port; */ /* Port number */
    /*     struct in_addr sin_addr;   */   /* Internet address */
    /*     unsigned char sin_zero[8]; */   /* Same size as struct sockaddr */
    /* }; */
    /* typedef uint32_t in_addr_t; */
    /* struct in_addr { */
    /*     in_addr_t s_addr; */
    /* }; */
#define TCP_PORT 4321
#define UDP_PORT 4321

    /* Protocal Family: PF_INET Type: stream Protocal:  IPPROTO_TCP*/
    /* csock = socket(PF_INET, SOCK_STREAM, 0); */
    csock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    psa = (struct sockaddr_in *)&saddr;
    psa->sin_family = AF_INET; /* Address Family */
    psa->sin_port = htons(TCP_PORT);
    psa->sin_addr.s_addr = htonl(INADDR_ANY);
    ret = bind(csock, &saddr, sizeof (struct sockaddr));
    /* ret = listen(csock, 5); */
    /* tsock = accept(csock, &tsaddr, &salen); */
    /* if (tsock >= 0) */
    /* { */
    /*     salen = sizeof(struct sockaddr); */
    /*     ret = getpeername(csock, &saddr, &salen); */
    /*     inaddr.s_addr = psa->sin_addr.s_addr; */
    /*     printf("TCPSocket is connected on %s : %d\n", \ */
    /*            inet_ntoa(psa->sin_addr), ntohs(psa->sin_port)); */
    /* } */

    /* Protocal Family: PF_INET Type: datagram Protocal:  IPPROTO_UDP*/
    /* dsock = socket(PF_INET, SOCK_DGRAM, 0); */
    dsock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
    psa = (struct sockaddr_in *)&saddr;
    psa->sin_family = AF_INET; /* Address Family */
    psa->sin_port = htons(0);  /* any one */
    psa->sin_addr.s_addr = htonl(INADDR_ANY);
    ret = bind(dsock, &saddr, sizeof (struct sockaddr));
    if (ret == 0)
    {
        salen = sizeof(struct sockaddr);
        ret = getsockname(csock, &saddr, &salen);
        inaddr.s_addr = psa->sin_addr.s_addr;
        printf("UDPSocket is created and bound on %s : %d\n", \
               inet_ntoa(psa->sin_addr), ntohs(psa->sin_port));

        /* ret = ioctl(dsock, SIOCGSIZIFCONF, &size); */
        ifc.ifc_len = sizeof(struct ifreq) * 16;  /* size */
        ifc.ifc_buf = (char *)malloc(ifc.ifc_len);
        ret = ioctl(dsock, SIOCGIFCONF, &ifc);
#if defined(GETIFS_LOOP)
        size = sizeof(struct ifreq);
        ifc.ifc_len = size;
        ifc.ifc_buf = (char *)malloc(ifc.ifc_len);
        while(0 == ioctl(dsock, SIOCGIFCONF, &ifc))
        {
            if (size == ifc.ifc_len)
            {
                size += size;
                ifc.ifc_len = size;
                ifc.ifc_buf = (char *)realloc(ifc.ifc_buf, ifc.ifc_len);
                continue;
            }
            break;
        }
#endif
        printf("ifcount = %d\n", (ifc.ifc_len)/sizeof(struct ifreq));
        ptr = ifc.ifc_buf;
        while (ptr < (ifc.ifc_buf + ifc.ifc_len))
        {
            /* Debug stuff: struct sockaddr_in *psa; */
            pifr = (struct ifreq *)ptr;
            psa = (struct sockaddr_in *) &pifr->ifr_addr;
            printf("interface: %s, address: %s\n", \
                pifr->ifr_name, inet_ntoa(psa->sin_addr));
            /* End debug stuff */

            /* memcpy(&ifr, ptr, sizeof(struct ifreq)) */
            strcpy(ifr.ifr_name, pifr->ifr_name);
            ret = ioctl(dsock, SIOCGIFFLAGS, &ifr);
            printf("\tflags = 0x%x\n", ifr.ifr_flags);

            if ((0 == (ifr.ifr_flags & IFF_LOOPBACK)) \
                    && (ifr.ifr_flags & IFF_UP) \
                    && (ifr.ifr_flags & IFF_BROADCAST) \
                    && (0 == (ifr.ifr_flags & IFF_SLAVE)))
            {
                ret = ioctl(dsock, SIOCGIFADDR, &ifr);
                psa = (struct sockaddr_in *) &ifr.ifr_addr;
                printf("\taddr: %s\n", inet_ntoa(psa->sin_addr));
                ret = ioctl(dsock, SIOCGIFHWADDR, &ifr);
                saddr = ifr.ifr_hwaddr;
                printf("\thwad: %02x:%02x:%02x:%02x:%02x:%02x\n", \
                    (unsigned char)saddr.sa_data[0], (unsigned char)saddr.sa_data[1], \
                    (unsigned char)saddr.sa_data[2], (unsigned char)saddr.sa_data[3], \
                    (unsigned char)saddr.sa_data[4], (unsigned char)saddr.sa_data[5]);
                ret = ioctl(dsock, SIOCGIFBRDADDR, &ifr);
                psa = (struct sockaddr_in *) &ifr.ifr_broadaddr;
                printf("\tbroad: %s\n", inet_ntoa(psa->sin_addr));
                ret = ioctl(dsock, SIOCGIFNETMASK, &ifr);
                psa = (struct sockaddr_in *) &ifr.ifr_addr;
                printf("\tmask: %s\n", inet_ntoa(psa->sin_addr));
                ret = ioctl(dsock, SIOCGIFMTU, &ifr);
                printf("\tmtu: %d\n", ifr.ifr_mtu);
                ret = ioctl(dsock, SIOCGIFMETRIC, &ifr);
                printf("\tmetric: %d\n", ifr.ifr_metric);
            }
            ptr += sizeof(struct ifreq);
        }
    }

    namelen = 16;
    hostname = (char *)malloc(namelen);
    while ((ret = gethostname(hostname, namelen)) < 0 && errno == ENAMETOOLONG)
    {
        namelen += namelen;
        hostname = (char *)realloc(hostname, namelen);
    }
    if (ret == 0)
    {
        str = strchr(hostname, '.');
        if (str != NULL)
        {
            *str = '\0';
            printf("Short");
        }
        printf("Hostname: %s\n", hostname);
    }
    else
    {
        printf("Unknown host!\n");
        return 0;
    }

    pHostEntry = gethostbyname(hostname);
    if (pHostEntry->h_addrtype == AF_INET)
    {
        for (i = 0; (pHostEntry->h_addr_list[i]) != NULL; i++)
        {
            /* inet_ntop (pHostEntry->h_addrtype, pHostEntry->h_addr_list[i], buf, sizeof (buf))); */
            inaddr.s_addr = *(long *)(pHostEntry->h_addr_list[i]);
            printf("  ip4: %s\n", inet_ntoa(inaddr));
        }
        for (i = 0; (pHostEntry->h_aliases[i]) != NULL; i++)
        {
            printf("  alias: %s\n", pHostEntry->h_aliases[i]);
        }
    }

    /* addr.s_addr = ntohl(inet_addr("192.168.1.0")); */
    addr.s_addr = inet_network("192.168.1.0");
    nptr = getnetbyaddr(addr.s_addr, AF_INET);
    if (nptr == NULL)
    {
        inaddr.s_addr = htonl(addr.s_addr);
        printf("Get nothing of net %s!\n", \
               inet_ntoa (inaddr));
    }
    else
    {
        inaddr.s_addr = htonl(nptr->n_net);
        printf ("n_name: %s, network_number: %s\n",
                nptr->n_name, inet_ntoa (inaddr));

        for (pptr = nptr->n_aliases; *pptr != NULL; pptr++)
            printf ("  alias: %s\n", *pptr);
    }

    /*
      setdb ("db");
    */

    test_hosts ();
    test_network ();
    test_protocols ();
    test_rpc ();
    test_services ();

    if (error_count)
        printf ("\n %d errors occurred!\n", error_count);
    else
        printf ("No visible errors occurred!\n");

    if (hostname != NULL) free(hostname);
    return error_count;
}

阅读(752) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~