如何在xinetd自定义服务中获取已连接客户端的IP地址

时间:2019-04-19 18:32:12

标签: c linux xinetd

问题: xinetd(扩展的Internet服务守护程序)将输入映射到服务的标准输入,并将输出映射到服务的标准输出。

换句话说,假设使用C语言编写的自定义TCP服务,则将进入端口 X 的数据映射到该服务的stdin,并将该服务的stdout映射到来自端口 Y 。

再次假设使用C语言编写的自定义TCP服务,该服务是否可以确定连接客户端的IP地址?

网络研究: 在发布此问题时,Stack Exchange(或其他地方)上没有其他问题专门处理用C编写的xinetd TCP服务,试图确定连接客户端的IP地址。

还有类似的问题:

但是没有人回答这篇文章中详述的具体问题。

后续操作注意: xinetd接受与TCP端口 X 关联的套接字描述符,并将其映射到服务的标准输入。

认识到这一事实将有助于进行更好的网络搜索,从而产生以下答案:

1 个答案:

答案 0 :(得分:3)

是的,在其stdin(0)或stdout(1)文件描述符上带有getpeername(2)

示例:从xinetdinetd运行时,这将打印连接到其stdin的客户端的地址:

#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);
        }
}