casting sockaddr_storage as sockaddr_in for inet_ntop

前端 未结 2 1090
孤街浪徒
孤街浪徒 2020-12-18 12:14

I am trying to cast a sockaddr_storage to a sockadd_in, so that i can print out the source ip address of a datagram packet, i do not seem to be able to get the cast correct,

相关标签:
2条回答
  • 2020-12-18 12:33
    struct sockaddr_storage  *  peer_addr;
    
    
    getnameinfo((struct sockaddr *) &peer_add
                    peer_addrlen,
                    hostbuff, sizeof(hostbuff),
                    NULL, 0, NI_NAMEREQD);
    

    Here you are mixing up stuff.

    getnameinfo() indeed takes a struct sockaddr* as its first parameter, but what you try to do here won't work: peer_addr is a struct sockaddr_storage *, you take its address - which is a struct sockaddr_storage **, and try to cast this. That won't work.

    I don't know where your peer_addr comes from, but

    • either it should be a struct sockaddr_storage (I don't think there is a need to have a pointer to a struct sockaddr_storage somewhere)
    • or it is really a pointer, and you should pass (struct sockaddr *) peer_addr - without the & - to getnameinfo().

    Another point: The second parameter for getnameinfo() is supposed to be the "real" size of the address struct you are inputting.

    0 讨论(0)
  • 2020-12-18 12:50
    inet_ntop(peer_addr->ss_family, &(((struct sockaddr_in *)peer_addr)->sin_addr), ipbuff, INET_ADDRSTRLEN);
    

    should work. But consider to use getnameinfo() instead, which is the more modern interface:

    char host[NI_MAXHOST];
    getnameinfo((struct sockaddr *)peer_addr, peer_addr->ss_len, host, sizeof(host), NULL, 0, NI_NUMERICHOST);
    

    works for both IPv4 and IPv6 addresses.


    Update according to the changed types in the question: This is a complete example that should compile without warnings:

    int socket = ...;
    
    struct sockaddr_storage peer_addr;
    socklen_t peer_addrlen;
    char host[NI_MAXHOST];
    
    ssize_t amount;
    char buffer[1000];
    amount = recvfrom(socket, buffer, sizeof(buffer), 0, (struct sockaddr *)&peer_addr, &peer_addrlen);
    getnameinfo((struct sockaddr *)&peer_addr, peer_addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST);
    

    Or, using inet_ntop():

    char ipbuff[INET_ADDRSTRLEN];
    inet_ntop(peer_addr.ss_family, &(((struct sockaddr_in *)&peer_addr)->sin_addr), ipbuff, INET_ADDRSTRLEN);
    
    0 讨论(0)
提交回复
热议问题