xinetd自定义服务如何获取连接客户端的IP地址
How to Obtain IP Address of Connected Client in xinetd Custom Service
问题:
xinetd(扩展 Internet 服务守护进程)将输入映射到服务的标准输入,将输出映射到服务的标准输出。
换句话说,假设一个用 C 编写的自定义 TCP 服务,进入端口 X 的数据映射到服务的标准输入,服务的标准输出映射到传入的数据出港 Y。
同样,假设一个用 C 编写的自定义 TCP 服务,该服务是否有办法确定连接客户端的 IP 地址?
网络研究:
截至post提出这个问题,在 Stack Exchange(或其他地方)上没有其他问题专门处理用 C 编写的 xinetd TCP 服务,试图确定连接客户端的 IP 地址。
还有类似问题:
- 正在处理 PHP (Xinetd obtain remote IP with PHP)。
- 处理泛型 client/server (Determining the IP address of a connected client on the server)
但是 none 回答了这个 post 中详述的具体问题。
后续注意: xinetd 使用与 TCP 端口 X 关联的 套接字描述符 和将其映射到服务的标准输入。
认识到这一事实可以进行更好的网络搜索,从而得到以下答案:
- Recovering IP/Port from Socket Descriptor
- Can you determine the source IP and port from a connected TCP socket?
是的,在其标准输入 (0) 或标准输出 (1) 文件描述符上有 getpeername(2)
。
示例:当 运行 来自 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);
}
}
问题: xinetd(扩展 Internet 服务守护进程)将输入映射到服务的标准输入,将输出映射到服务的标准输出。
换句话说,假设一个用 C 编写的自定义 TCP 服务,进入端口 X 的数据映射到服务的标准输入,服务的标准输出映射到传入的数据出港 Y。
同样,假设一个用 C 编写的自定义 TCP 服务,该服务是否有办法确定连接客户端的 IP 地址?
网络研究: 截至post提出这个问题,在 Stack Exchange(或其他地方)上没有其他问题专门处理用 C 编写的 xinetd TCP 服务,试图确定连接客户端的 IP 地址。
还有类似问题:
- 正在处理 PHP (Xinetd obtain remote IP with PHP)。
- 处理泛型 client/server (Determining the IP address of a connected client on the server)
但是 none 回答了这个 post 中详述的具体问题。
后续注意: xinetd 使用与 TCP 端口 X 关联的 套接字描述符 和将其映射到服务的标准输入。
认识到这一事实可以进行更好的网络搜索,从而得到以下答案:
- Recovering IP/Port from Socket Descriptor
- Can you determine the source IP and port from a connected TCP socket?
是的,在其标准输入 (0) 或标准输出 (1) 文件描述符上有 getpeername(2)
。
示例:当 运行 来自 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);
}
}