Page 1 of 1

This pierce of code cause Segmentation fault at Pi

Posted: Sun Jan 19, 2014 6:42 pm
by lilzz
I have a pierce of code which runs fine on desktop and I adopt it for the pi but it causes segmentation fault on inet_ntop function. I changed to wlan0 for pi. You can try it on the Pi. I don' t know why is it Ok on desktop but segmentation fault at pi

Code: Select all

#include <arpa/inet.h>   
#include <sys/socket.h>
#include <netdb.h> 

#include <ifaddrs.h>


#include <netinet/in.h>

#include <sys/types.h>
 #include <errno.h>

struct ifaddrs *ifaddr, *ifa;
        int family;
        char *src;
        if (getifaddrs(&ifaddr) == -1) {
            perror("getifaddrs");
            exit(EXIT_FAILURE);
        }
        
        for (ifa = ifaddr; ifa != NULL; ifa = ifa->ifa_next) {
            if (ifa->ifa_addr == NULL)
                continue;
            
            family = ifa->ifa_addr->sa_family;
            //for pi
            if (0 == strcmp(ifa->ifa_name, "wlan0" ) && (family == AF_INET)) { // v4
                inet_ntop(
                          AF_INET,
                          &((struct sockaddr_in*)ifa->ifa_addr)->sin_addr,
                          src,
                          sizeof(struct sockaddr_in)
                          );
                
                break;
            }
        }
        
        freeifaddrs(ifaddr);

Re: This pierce of code cause Segmentation fault at Pi

Posted: Sun Jan 19, 2014 9:00 pm
by jamesh
I'd guess its going wrong on the strcmp line, and the ifa_name field is null. It's not checked before its used.

EDIT: Oh, I see you said it goes wrong in the function call? Print out all the parameters pass in (or debug), and check they all look sane.

ANOTHER EDIT : Your src parameter is passed in unset to anything. I think that's the dest parameters. Double check the parameters.

const char *inet_ntop(int af,
const void *restrict src,
char *restrict dst,
socklen_t size);

Re: This pierce of code cause Segmentation fault at Pi

Posted: Sun Jan 19, 2014 9:33 pm
by AndyD
I am not sure why it is working on you desktop. You have a char* pointer src that is not initialized. You are passing src as the third parameter of inet_ntop(). From the man page of inet_ntop:-

Code: Select all

       const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);

DESCRIPTION
       This  function  converts  the  network  address structure src in the af
       address family into a character string.  The resulting string is copied
       to the buffer pointed to by dst, which must be a non-NULL pointer.  The
       caller specifies the number of bytes available in this  buffer  in  the
       argument size.
declare src as

Code: Select all

char src[INET_ADDRSTRLEN];
and call inet_ntop as follows:

Code: Select all

                inet_ntop(
                          AF_INET,
                          &((struct sockaddr_in*)ifa->ifa_addr)->sin_addr,
                          src,
                          sizeof(src)
                          );
Here is some code that works using inet_ntop()

Code: Select all

#include <stdio.h>      
#include <sys/types.h>
#include <ifaddrs.h>
#include <netinet/in.h> 
#include <string.h> 
#include <arpa/inet.h>

int main (int argc, const char * argv[])
{
    struct ifaddrs *ifAddrStruct = NULL;
    struct ifaddrs *ifa = NULL;

    getifaddrs(&ifAddrStruct);

    for (ifa = ifAddrStruct ; ifa != NULL ; ifa = ifa->ifa_next)
    {
        if (ifa ->ifa_addr->sa_family == AF_INET)
        {
            // is a valid IP4 Address

            void *tmpAddrPtr=&((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
            char addressBuffer[INET_ADDRSTRLEN];
            inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, sizeof(addressBuffer));
            printf("%s IP Address %s\n", ifa->ifa_name, addressBuffer); 
        }
        else if (ifa->ifa_addr->sa_family == AF_INET6)
        {
            // is a valid IP6 Address

            void *tmpAddrPtr=&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr;
            char addressBuffer[INET6_ADDRSTRLEN];
            inet_ntop(AF_INET6, tmpAddrPtr, addressBuffer, sizeof(addressBuffer));
            printf("%s IP Address %s\n", ifa->ifa_name, addressBuffer); 
        } 
    }

    if (ifAddrStruct!=NULL)
    {
        freeifaddrs(ifAddrStruct);
    }

    return 0;
}

Re: This pierce of code cause Segmentation fault at Pi

Posted: Mon Jan 20, 2014 9:06 am
by jamesh
AndyD wrote:I am not sure why it is working on you desktop. You have a char* pointer src that is not initialized. You are passing src as the third parameter of inet_ntop(). From the man page of inet_ntop:-
It uninitialised, so could point to memory that is available (from a previous stack entry?). Hence it might work (wrongly) on a desktop. By luck only.

Re: This pierce of code cause Segmentation fault at Pi

Posted: Mon Jan 20, 2014 5:00 pm
by lilzz
initialized?

I have declared char *src="result". but it still not working.

Re: This pierce of code cause Segmentation fault at Pi

Posted: Mon Jan 20, 2014 5:20 pm
by scotty101
lilzz wrote:initialized?

I have declared char *src="result". but it still not working.
Look at that code... what does *src="result" actually do? (Does it even compile!?)

You need to define src as a array large enough to store the IP address, like so

Code: Select all

char src[INET_ADDRSTRLEN];

Re: This pierce of code cause Segmentation fault at Pi

Posted: Mon Jan 20, 2014 6:12 pm
by jamesh
lilzz wrote:initialized?

I have declared char *src="result". but it still not working.
That will declare src as a pointer to the 6 character (+null) string "result" which will be in the static (IIRC) data segment, and may even be in read only memory.

You need to declare a location large enough either using heap allocation or on the stack.

So, to use some stack space (128 bytes = I have no idea how many you really need)

char src[128];

or to use some heap space

char *src = (char*)malloc(128);

but dont forget to release the heap memory once used

free(src);

Re: This pierce of code cause Segmentation fault at Pi

Posted: Wed Jan 22, 2014 1:01 am
by AndyD
jamesh wrote:I have no idea how many you really need
There are defined constants for the amount of space needed for the IP address string. It is INET_ADDRSTRLEN for IPv4 addresses and INET6_ADDRSTRLEN fpr IPv6 addresses.