#1
  1. Cast down
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2003
    Location
    Sweden
    Posts
    321
    Rep Power
    12

    hostent structure, looping h_addr_list


    I want to display all the ip's of a host. h_addr_list[x] works, but this loop does not:

    Code:
    	while(*hostess->h_addr_list)
    		printf("IP: %s\n", inet_ntoa(*((struct in_addr *)hostess->h_addr_list++)));
    I get no warnings/errors, runs and shows ip's, but they are not right, last 3 octets for all ip's are always the same.
  2. #2
  3. not a fan of fascism (n00b)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Feb 2003
    Location
    ct
    Posts
    2,756
    Rep Power
    95
    your pointer math is faulty. the pointer should be dereferenced twice. .this is how i usually do it:
    Code:
            struct hostent  *hp;
            struct in_addr  **pptr;
            pptr = (struct in_addr **)hp->h_addr_list;
    
            while( *pptr != NULL ){
                    printf("ip address: %s\n", inet_ntoa(**(pptr++)));
            }
    the compiler shoudl warn you, but you casted the pointer to a single dimensional pointer before you dereferenced it, so you tricked it basically, ;) you casted your double pointer to a single pionter. if you do it your way, you need to cast it do a (in_addr **) and the dereference it twice, ** to get the in_addr.
    Last edited by infamous41md; October 11th, 2003 at 12:16 AM.
  4. #3
  5. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,255
    Rep Power
    2222
    It's been a while since I've played with hostent (code once, reuse forever).

    I don't get a very warm fuzzy feeling about incrementing that entry in the hostent struct. How's about trying one of two alternative methods to see whether they will work:
    1. Declare a char** pointer and point it to h_addr_list:
    Code:
    // coded off the top of my head
    char **hp = hostess->h_addr_list;
    
    for ( ; *hp != NULL; hp++)
        printf("IP: %s\n", inet_ntoa(*((struct in_addr *)hp)) );
    2. Treat h_addr_list as an array of char*:
    Code:
    // coded off the top of my head
    int i;
    
    for (i=0; hostess->h_addr_list[i] != NULL; i++)
        printf("IP: %s\n", inet_ntoa(*((struct in_addr *)hostess->h_addr_list[i])) );
    My thought on this is that expressing it differently might undo some pointer confusion that may have sneaked into your code, which is very easy to do and can be hard to spot.

    EDIT:
    This reply was delayed by a server problem. I looked at a program I wrote which collects and displays host information on the PC it runs on. The pertinent part of the code looks like this:
    Code:
        if (he->h_addr_list == NULL)
            printf("No h_addr_list present.\n");
        else
        {
            printf("h_addr_list:\n");
            for (i = 0; he->h_addr_list[i] != 0; i++) 
            {
                memcpy(&addr, he->h_addr_list[i], sizeof(struct in_addr));
                printf("  Addr #%d: %s\n",i,inet_ntoa(addr));
            }
        }
    My Win2k box has two NICs, one to the LAN and the other to the DSL modem, and three IP addresses (one's a PPP adapter). This code lists all three addresses accurately.
    Last edited by dwise1_aol; October 11th, 2003 at 12:28 AM.
  6. #4
  7. not a fan of fascism (n00b)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Feb 2003
    Location
    ct
    Posts
    2,756
    Rep Power
    95
    the problem is the level of pointer indirection. h_addr_list is a pointer to a pointer. dereferencing it once will give the address of the in_addr structure, dereferencing it twice will give the value.

    Originally posted by dwise1_aol

    1. Declare a char** pointer and point it to h_addr_list:
    Code:
    // coded off the top of my head
    char **hp = hostess->h_addr_list;
    
    for ( ; *hp != NULL; hp++)
        printf("IP: %s\n", inet_ntoa(*((struct in_addr *)hp)) );
    i.e. this has the same problem as the above. it should be,
    printf("IP: %s\n", inet_ntoa(**((struct in_addr **)hp))

IMN logo majestic logo threadwatch logo seochat tools logo