cmemset

warning: 'memset' will always overflow [-Wfortify-source]


Trying to manipulate IPv6 addresses in struct sin6_addr, e.g. cleaning it:

struct sockaddr a;
memset(&(((struct sockaddr_in6 *)&a)->sin6_addr.s6_addr), 0, 16);
printf("SIZEOF: %lu\n", sizeof((((struct sockaddr_in6 *)&a)->sin6_addr.s6_addr)));

And facing the warning:

1.c:34:2: warning: 'memset' will always overflow; destination buffer has size 8, but size argument is 16 [-Wfortify-source]
        memset(&(((struct sockaddr_in6 *)&a)->sin6_addr.s6_addr), 0, 16);

The same time, printf("SIZEOF...") returns 16 bytes, so should be enough space?

Also, if I do it like this:

struct sockaddr a;
struct in6_addr aa;
aa = ((struct sockaddr_in6 *)&a)->sin6_addr.s6_addr;
memset(&aa, 0, 16);

There are no warnings shown. What do I do wrong?

UPD. Fixed a in printf()


Solution

  • There is already complete answer from Attie, but this gives an alternative for storing socket addresses:

    struct sockaddr_storage
    

    Man page of socket(7) says the following:

    the sockets API provides the data type struct sockaddr_storage.
    This type is suitable to accommodate all
    supported domain-specific socket address structures; it is large
    enough and is aligned properly.

    The sockaddr_storage structure is useful in programs that must
    handle socket addresses in a generic way (e.g., programs that must deal with both IPv4 and IPv6 socket addresses).

    So instead of this:

    struct sockaddr a;
    

    You should use this:

    struct sockaddr_storage a;
    

    for getting enough space for the most of different address types.