Да, с 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);
}
}