Выяснение IP-адреса sr c и порта, связанного с сокетом, используемым в функции sendto - PullRequest
3 голосов
/ 14 апреля 2020

В приведенной ниже функции после использования sendto () я хочу узнать IP-адрес источника и порт, используемый для отправки сообщения. Можно ли это выяснить?

void sendMsg(char* payload, size_t payloadLength, const char* ip6Addr, short port)
{
        int sock;
        size_t size;
        socklen_t clilen;
        struct sockaddr_in6 server_addr, client_addr;

        sock = socket(PF_INET6, SOCK_DGRAM, 0);

        if (sock < 0) {
                perror("creating socket");
                exit(1);
        }

        memset(&server_addr, 0, sizeof(server_addr));
        server_addr.sin6_family = AF_INET6;
        inet_pton(AF_INET6, ip6Addr, &server_addr.sin6_addr);
        server_addr.sin6_port = htons(port);

        size = sendto(sock, payload, payloadLength, 0 , (const struct sockaddr *) &server_addr,sizeof(server_addr));
        if(size < 0)
                printf("Error in sending message\n");
        else
                printf("[%d] bytes written to network\n",size);
}

Ответы [ 2 ]

1 голос
/ 14 апреля 2020

Из справочной страницы Linux для udp (7)

Для получения пакетов сокет может быть сначала привязан к локальному адресу с помощью bind(2) , В противном случае уровень сокетов автоматически назначит свободный локальный порт из диапазона, определенного /proc/sys/net/ipv4/ip_local_port_range, и свяжет сокет с INADDR_ANY.

Несвязанные сокеты UDP IPv6 обрабатываются одинаково. Таким образом, вы можете получить локальный порт, используемый сокетом после отправки первого пакета, используя getsockname(), как уже продемонстрировано, но вы не можете получить указанный c локальный адрес, потому что его нет - пакет отправляется любому будут получены адреса машин на этом порту (правила брандмауэра Modulo и т.д. c. конечно).


Однако есть надежда.

Команда оболочки ip route get ADDRESS покажет вам сетевой интерфейс и IP-адрес, используемый для отправки пакетов на ADDRESS. См. rtnetlink(7) для получения программного доступа к таблицам маршрутизации.

1 голос
/ 14 апреля 2020

Вот как вы получаете порт. Привязать к адресу INADDR_ANY (IN6ADDR_ANY_INIT). Тогда используйте getsockname.

sockaddr_in6 addr = {0};
sockaddr_in6 addrLocal = {0};
socklen_t addrSize = sizeof(addrLocal);
unsigned short port = 0;

addr.sin6_family = AF_INET6;
sock = socket(AF_INET6, SOCK_DGRAM,0);
bind(sock, (sockaddr*)&addr, sizeof(addr)); // bind to the INADDR_ANY address for IPV6

getsockname(sock, (sockaddr*)&addrLocal, &addrSize);

port = addrLocal.sin6_port;

Я не уверен насчет IP-адреса. IP-адрес, встроенный в addrLocal, по-прежнему будет иметь все нули. Не уверен, как вы получаете IP-адрес, используемый для отправки определенного пакета. В худшем случае вы перечисляете таблицу маршрутизации, чтобы определить, какой интерфейс и адрес наиболее вероятно будут использоваться для конкретного целевого IP-адреса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...