Как получить IP-адрес подключенного клиента в пользовательской службе xinetd - PullRequest
0 голосов
/ 19 апреля 2019

Вопрос: xinetd (демон расширенных интернет-служб) отображает входной сигнал на стандартный вход службы и вывод на стандартный выход службы.

Другими словами, предполагая, что пользовательская служба TCP написана на C, данные, поступающие в порт X , сопоставляются со стандартным вводом службы, а стандартный вывод службы сопоставляется с данными, поступающими из порта. Y .

Опять же, предполагая, что пользовательская служба TCP, написанная на C, может ли эта служба определить IP-адрес подключающегося клиента?

Веб-исследование: По состоянию напосле публикации этого вопроса на Stack Exchange (или где-либо еще) НЕТ других вопросов, которые конкретно касаются TCP-сервисов xinetd, написанных на C, пытающихся определить IP-адрес подключающегося клиента.

Есть похожие вопросы:

Но ни один из них не отвечает на конкретный вопрос, подробно описанный в этом сообщении.

СЛЕДУЙТЕ ЗАМЕЧАНИЕ: xinetd принимает дескриптор сокета связан с портом TCP X и сопоставляет его со стандартным входом службы.

Знание этого факта позволило бы улучшить поиск в Интернете, что привело бы к следующим ответам:

1 Ответ

3 голосов
/ 19 апреля 2019

Да, с getpeername(2) в дескрипторе файла stdin (0) или stdout (1).

Пример: при запуске с xinetd или inetd будет напечатан адрес клиента, подключенного к его стандартному стандартному входу:

#define _DEFAULT_SOURCE
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/in.h>
#include <stdio.h>
#include <err.h>
#include <netdb.h>

int main(void){
        union {
                struct sockaddr a;
                struct sockaddr_in in;
                struct sockaddr_in6 in6;
        } na;
        char host[NI_MAXHOST], port[NI_MAXSERV]; int e;
        socklen_t nl = sizeof na;
        if(getpeername(0, &na.a, &nl)) err(1, "getpeername");
        if(e = getnameinfo(&na.a, nl, host, sizeof host, port, sizeof port,
                        NI_NUMERICHOST|NI_NUMERICSERV))
                errx(1, "getnameinfo: %s", gai_strerror(e));
        switch(na.a.sa_family){
        case AF_INET:
                errx(0, "connection from %s:%s", host, port);
        case AF_INET6:
                errx(0, "connection from [%s]:%s", host, port);
        default:
                errx(0, "connection from unknown address family %d",
                        na.a.sa_family);
        }
}
...