mirror of
https://repo.or.cz/socat.git
synced 2025-07-14 07:23:23 +00:00
Fixed filan -s, added -S
This commit is contained in:
parent
d1b809b4ab
commit
6635e159c4
7 changed files with 212 additions and 55 deletions
196
fdname.c
196
fdname.c
|
@ -25,14 +25,15 @@ struct sockopt {
|
|||
};
|
||||
|
||||
|
||||
int statname(const char *file, int fd, int filetype, FILE *outfile);
|
||||
int statname(const char *file, int fd, int filetype, FILE *outfile, char style);
|
||||
int cdevname(int fd, FILE *outfile);
|
||||
int sockname(int fd, FILE *outfile);
|
||||
int sockname(int fd, FILE *outfile, char style);
|
||||
int unixame(int fd, FILE *outfile);
|
||||
int tcpname(int fd, FILE *outfile);
|
||||
|
||||
|
||||
int fdname(const char *file, int fd, FILE *outfile, const char *numform) {
|
||||
int fdname(const char *file, int fd, FILE *outfile, const char *numform,
|
||||
char style) {
|
||||
struct stat buf = {0};
|
||||
int filetype;
|
||||
Debug1("checking file descriptor %u", fd);
|
||||
|
@ -49,13 +50,13 @@ int fdname(const char *file, int fd, FILE *outfile, const char *numform) {
|
|||
if (numform != NULL) {
|
||||
fprintf(outfile, numform, fd);
|
||||
}
|
||||
return statname(file, fd, filetype, outfile);
|
||||
return statname(file, fd, filetype, outfile, style);
|
||||
} else {
|
||||
if (Stat(file, &buf) < 0) {
|
||||
Error2("stat(\"%s\"): %s", file, strerror(errno));
|
||||
}
|
||||
filetype = (buf.st_mode&S_IFMT)>>12;
|
||||
return statname(file, -1, filetype, outfile);
|
||||
return statname(file, -1, filetype, outfile, style);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,7 +102,8 @@ static int procgetfdname(int fd, char *filepath, size_t pathsize) {
|
|||
}
|
||||
#endif /* HAVE_PROC_DIR_FD */
|
||||
|
||||
int statname(const char *file, int fd, int filetype, FILE *outfile) {
|
||||
int statname(const char *file, int fd, int filetype, FILE *outfile,
|
||||
char style) {
|
||||
char filepath[PATH_MAX];
|
||||
|
||||
filepath[0] = '\0';
|
||||
|
@ -143,7 +145,7 @@ int statname(const char *file, int fd, int filetype, FILE *outfile) {
|
|||
case (S_IFSOCK>>12): /* 12, socket */
|
||||
#if _WITH_SOCKET
|
||||
if (fd >= 0) {
|
||||
sockname(fd, outfile);
|
||||
sockname(fd, outfile, style);
|
||||
} else if (file) {
|
||||
fprintf(outfile, "socket %s", file);
|
||||
} else {
|
||||
|
@ -186,138 +188,264 @@ int cdevname(int fd, FILE *outfile) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int sockettype(int socktype, char *typename, size_t typenamemax) {
|
||||
switch (socktype) {
|
||||
case SOCK_STREAM: strncpy(typename, "stream", typenamemax); break;
|
||||
case SOCK_DGRAM: strncpy(typename, "dgram", typenamemax); break;
|
||||
case SOCK_SEQPACKET: strncpy(typename, "seqpacket", typenamemax); break;
|
||||
case SOCK_RAW: strncpy(typename, "raw", typenamemax); break;
|
||||
case SOCK_RDM: strncpy(typename, "rdm", typenamemax); break;
|
||||
#ifdef SOCK_PACKET
|
||||
case SOCK_PACKET: strncpy(typename, "packet", typenamemax); break;
|
||||
#endif
|
||||
default: snprintf(typename, typenamemax, "socktype%u", socktype); break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if _WITH_SOCKET
|
||||
int sockname(int fd, FILE *outfile) {
|
||||
int sockname(int fd, FILE *outfile, char style) {
|
||||
#define FDNAME_OPTLEN 256
|
||||
#define FDNAME_NAMELEN 256
|
||||
socklen_t optlen;
|
||||
#if HAVE_GETPROTOBYNUMBER || HAVE_GETPROTOBYNUMBER_R
|
||||
struct protoent protoent, *protoentp;
|
||||
#endif
|
||||
#define PROTONAMEMAX 1024
|
||||
char protoname[PROTONAMEMAX];
|
||||
#if defined(SO_PROTOCOL) || defined(SO_PROTOTYPE)
|
||||
int proto;
|
||||
#endif
|
||||
int opttype;
|
||||
#ifdef SO_ACCEPTCONN
|
||||
int optacceptconn;
|
||||
#endif
|
||||
int result /*0, i*/;
|
||||
char namebuff[FDNAME_NAMELEN];
|
||||
char peerbuff[FDNAME_NAMELEN];
|
||||
char socknamebuff[FDNAME_NAMELEN];
|
||||
char peernamebuff[FDNAME_NAMELEN];
|
||||
/* in Linux these optcodes are 'enum', but on AIX they are bits! */
|
||||
union sockaddr_union sockname, peername; /* the longest I know of */
|
||||
socklen_t namelen;
|
||||
socklen_t socknamelen, peernamelen;
|
||||
# define TYPENAMEMAX 16
|
||||
char typename[TYPENAMEMAX];
|
||||
#if 0 && defined(SIOCGIFNAME)
|
||||
/*Linux struct ifreq ifc = {{{ 0 }}};*/
|
||||
struct ifreq ifc = {{ 0 }};
|
||||
#endif
|
||||
int rc;
|
||||
|
||||
optlen = FDNAME_OPTLEN;
|
||||
#if defined(SO_PROTOCOL) || defined(SO_PROTOTYPE)
|
||||
optlen = sizeof(proto);
|
||||
#ifdef SO_PROTOCOL
|
||||
Getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &proto, &optlen);
|
||||
#elif defined(SO_PROTOTYPE)
|
||||
Getsockopt(fd, SOL_SOCKET, SO_PROTOTYPE, &proto, &optlen);
|
||||
#endif
|
||||
#endif /* defined(SO_PROTOCOL) || defined(SO_PROTOTYPE) */
|
||||
|
||||
optlen = sizeof(opttype);
|
||||
Getsockopt(fd, SOL_SOCKET, SO_TYPE, &opttype, &optlen);
|
||||
sockettype(opttype, typename, sizeof(typename));
|
||||
|
||||
optlen = sizeof(optacceptconn);
|
||||
#ifdef SO_ACCEPTCONN
|
||||
Getsockopt(fd, SOL_SOCKET, SO_ACCEPTCONN, &optacceptconn, &optlen);
|
||||
#endif
|
||||
|
||||
namelen = sizeof(sockname);
|
||||
result = Getsockname(fd, &sockname.soa, &namelen);
|
||||
#if defined(SO_PROTOCOL) || defined(SO_PROTOTYPE)
|
||||
#if HAVE_GETPROTOBYNUMBER_R
|
||||
rc = getprotobynumber_r(proto, &protoent, protoname, sizeof(protoname), &protoentp);
|
||||
if (protoentp == NULL) {
|
||||
Warn2("sockname(): getprotobynumber_r(proto=%d, ...): %s",
|
||||
proto, strerror(rc));
|
||||
}
|
||||
strncpy(protoname, protoentp->p_name, sizeof(protoname));
|
||||
#elif HAVE_GETPROTOBYNUMBER
|
||||
protoentp = getprotobynumber(proto);
|
||||
strncpy(protoname, protoentp->p_name, sizeof(protoname));
|
||||
#else
|
||||
switch (proto) {
|
||||
case IPPROTO_TCP: strcpy(protoname, "tcp"); break;
|
||||
case IPPROTO_UDP: strcpy(protoname, "udp"); break;
|
||||
case IPPROTO_SCTP: strcpy(protoname, "sctp"); break;
|
||||
default: sprintf(protoname, "proto%d", proto); break;
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
if (opttype == SOCK_STREAM) {
|
||||
strcpy(protoname, "tcp");
|
||||
} else if (opttype == SOCK_DGRAM) {
|
||||
strcpy(protoname, "udp");
|
||||
} else {
|
||||
strcpy(protoname, "socket");
|
||||
}
|
||||
#endif /* defined(SO_PROTOCOL) || defined(SO_PROTOTYPE) */
|
||||
socknamelen = sizeof(sockname);
|
||||
result = Getsockname(fd, &sockname.soa, &socknamelen);
|
||||
if (result < 0) {
|
||||
Error2("getsockname(%d): %s", fd, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
namelen = sizeof(peername);
|
||||
result = Getpeername(fd, (struct sockaddr *)&peername, &namelen);
|
||||
peernamelen = sizeof(peername);
|
||||
result = Getpeername(fd, (struct sockaddr *)&peername, &peernamelen);
|
||||
if (result < 0) {
|
||||
Error2("getpeername(%d): %s", fd, strerror(errno));
|
||||
Warn2("getpeername(%d): %s", fd, strerror(errno));
|
||||
}
|
||||
|
||||
switch (sockname.soa.sa_family) {
|
||||
#if WITH_UNIX
|
||||
case AF_UNIX:
|
||||
switch (style) {
|
||||
case 's':
|
||||
fprintf(outfile, "unix%s%s %s",
|
||||
opttype==SOCK_DGRAM?"datagram":"",
|
||||
#ifdef SO_ACCEPTCONN
|
||||
optacceptconn?"(listening)":
|
||||
#endif
|
||||
"",
|
||||
sockaddr_unix_info(&sockname.un, namelen,
|
||||
namebuff, sizeof(namebuff)));
|
||||
sockaddr_unix_info(&sockname.un, socknamelen,
|
||||
socknamebuff, sizeof(socknamebuff)));
|
||||
break;
|
||||
case 'S':
|
||||
//sockettype(opttype, typename, TYPENAMEMAX);
|
||||
fprintf(outfile, "unix %s-%s %s %s",
|
||||
sockaddr_unix_info(&sockname.un, socknamelen,
|
||||
socknamebuff, sizeof(socknamebuff)),
|
||||
sockaddr_unix_info(&peername.un, peernamelen,
|
||||
peernamebuff, sizeof(peernamebuff)),
|
||||
typename,
|
||||
#ifdef SO_ACCEPTCONN
|
||||
optacceptconn?"(listening)":
|
||||
#endif
|
||||
"");
|
||||
#endif /* WITH_UNIX */
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#if WITH_IP4
|
||||
case AF_INET:
|
||||
switch (style) {
|
||||
case 's':
|
||||
switch (opttype) {
|
||||
#if WITH_TCP
|
||||
case SOCK_STREAM:
|
||||
fprintf(outfile, "tcp%s %s %s",
|
||||
fprintf(outfile, "%s%s %s %s",
|
||||
protoname,
|
||||
#ifdef SO_ACCEPTCONN
|
||||
optacceptconn?"(listening)":
|
||||
#endif
|
||||
"",
|
||||
sockaddr_inet4_info(&sockname.ip4,
|
||||
namebuff, sizeof(namebuff)),
|
||||
socknamebuff, sizeof(socknamebuff)),
|
||||
sockaddr_inet4_info(&peername.ip4,
|
||||
peerbuff, sizeof(peerbuff)));
|
||||
peernamebuff, sizeof(peernamebuff)));
|
||||
break;
|
||||
#endif
|
||||
#if WITH_UDP
|
||||
case SOCK_DGRAM:
|
||||
fprintf(outfile, "udp%s %s %s",
|
||||
fprintf(outfile, "%s%s %s %s",
|
||||
protoname,
|
||||
#ifdef SO_ACCEPTCONN
|
||||
optacceptconn?"(listening)":
|
||||
#endif
|
||||
"",
|
||||
sockaddr_inet4_info(&sockname.ip4,
|
||||
namebuff, sizeof(namebuff)),
|
||||
socknamebuff, sizeof(socknamebuff)),
|
||||
sockaddr_inet4_info(&peername.ip4,
|
||||
peerbuff, sizeof(peerbuff)));
|
||||
peernamebuff, sizeof(peernamebuff)));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
fprintf(outfile, "ip %s",
|
||||
sockaddr_inet4_info(&sockname.ip4,
|
||||
namebuff, sizeof(namebuff)));
|
||||
socknamebuff, sizeof(socknamebuff)));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
fprintf(outfile, "%s %s-%s (%s) %s",
|
||||
protoname,
|
||||
sockaddr_inet4_info(&sockname.ip4,
|
||||
socknamebuff, sizeof(socknamebuff)),
|
||||
sockaddr_inet4_info(&peername.ip4,
|
||||
peernamebuff, sizeof(peernamebuff)),
|
||||
typename,
|
||||
#ifdef SO_ACCEPTCONN
|
||||
optacceptconn?"(listening)":
|
||||
#endif
|
||||
"");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#endif /* WITH_IP4 */
|
||||
|
||||
#if WITH_IP6
|
||||
case AF_INET6:
|
||||
switch (style) {
|
||||
case 's':
|
||||
switch (opttype) {
|
||||
#if WITH_TCP
|
||||
case SOCK_STREAM:
|
||||
fprintf(outfile, "tcp6%s %s %s",
|
||||
fprintf(outfile, "%s6%s %s %s",
|
||||
protoname,
|
||||
#ifdef SO_ACCEPTCONN
|
||||
optacceptconn?"(listening)":
|
||||
#endif
|
||||
"",
|
||||
sockaddr_inet6_info(&sockname.ip6,
|
||||
namebuff, sizeof(namebuff)),
|
||||
socknamebuff, sizeof(socknamebuff)),
|
||||
sockaddr_inet6_info(&peername.ip6,
|
||||
peerbuff, sizeof(peerbuff)));
|
||||
peernamebuff, sizeof(peernamebuff)));
|
||||
break;
|
||||
#endif
|
||||
#if WITH_UDP
|
||||
case SOCK_DGRAM:
|
||||
fprintf(outfile, "udp6%s %s %s",
|
||||
fprintf(outfile, "%s6%s %s %s",
|
||||
protoname,
|
||||
#ifdef SO_ACCEPTCONN
|
||||
optacceptconn?"(listening)":
|
||||
#endif
|
||||
"",
|
||||
sockaddr_inet6_info(&sockname.ip6,
|
||||
namebuff, sizeof(namebuff)),
|
||||
socknamebuff, sizeof(socknamebuff)),
|
||||
sockaddr_inet6_info(&peername.ip6,
|
||||
peerbuff, sizeof(peerbuff)));
|
||||
peernamebuff, sizeof(peernamebuff)));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
fprintf(outfile, "ip6 %s",
|
||||
sockaddr_inet6_info(&sockname.ip6,
|
||||
namebuff, sizeof(namebuff)));
|
||||
socknamebuff, sizeof(socknamebuff)));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'S':
|
||||
fprintf(outfile, "%s6 %s-%s (%s) %s",
|
||||
protoname,
|
||||
sockaddr_inet6_info(&sockname.ip6,
|
||||
socknamebuff, sizeof(socknamebuff)),
|
||||
sockaddr_inet6_info(&peername.ip6,
|
||||
peernamebuff, sizeof(peernamebuff)),
|
||||
typename,
|
||||
#ifdef SO_ACCEPTCONN
|
||||
optacceptconn?"(listening)":
|
||||
#endif
|
||||
"");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
#endif /* WITH_IP6 */
|
||||
|
||||
default:
|
||||
fputs("socket", outfile);
|
||||
fprintf(outfile, "socket(family/domain=%d)", sockname.soa.sa_family);
|
||||
}
|
||||
|
||||
#if HAVE_GETPROTOENT
|
||||
if (ipproto >= 0) {
|
||||
endprotoent();
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
#undef FDNAME_OPTLEN
|
||||
#undef FDNAME_NAMELEN
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue