1
0
Fork 0
mirror of https://repo.or.cz/socat.git synced 2025-07-10 06:06:33 +00:00

Corrected handling of IP_RECVERR

This commit is contained in:
Gerhard Rieger 2021-10-28 21:21:07 +02:00
parent bc32acb5fe
commit d84c22be7a
6 changed files with 177 additions and 28 deletions

View file

@ -464,16 +464,16 @@ int xiogetaddrinfo(const char *node, const char *service,
#if defined(HAVE_STRUCT_CMSGHDR) && defined(CMSG_DATA)
/* converts the ancillary message in *cmsg into a form useable for further
/* Converts the ancillary message in *cmsg into a form useable for further
processing. knows the specifics of common message types.
these are valid for IPv4 and IPv6
returns the number of resulting syntax elements in *num
returns a sequence of \0 terminated type strings in *typbuff
returns a sequence of \0 terminated name strings in *nambuff
returns a sequence of \0 terminated value strings in *valbuff
the respective len parameters specify the available space in the buffers
returns STAT_OK on success
returns STAT_WARNING if a buffer was too short and data truncated.
These are valid for IPv4 and IPv6
Returns the number of resulting syntax elements in *num
Returns a sequence of \0 terminated type strings in *typbuff
Returns a sequence of \0 terminated name strings in *nambuff
Returns a sequence of \0 terminated value strings in *valbuff
The respective len parameters specify the available space in the buffers
Returns STAT_OK on success
Returns STAT_WARNING if a buffer was too short and data truncated.
*/
int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
char *typbuff, int typlen,
@ -519,14 +519,31 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
'\0',
inet4addr_info(ntohl(pktinfo->ipi_addr.s_addr),
scratch3, sizeof(scratch3)));
Notice3("Ancillary message: interface \"%s\", locaddr=%s, dstaddr=%s",
xiogetifname(pktinfo->ipi_ifindex, scratch1, -1),
#if HAVE_PKTINFO_IPI_SPEC_DST
inet4addr_info(ntohl(pktinfo->ipi_spec_dst.s_addr),
scratch2, sizeof(scratch2)),
#else
"",
#endif
inet4addr_info(ntohl(pktinfo->ipi_addr.s_addr),
scratch3, sizeof(scratch3)));
}
return STAT_OK;
#endif /* defined(IP_PKTINFO) && HAVE_STRUCT_IN_PKTINFO */
#endif /* WITH_IP4 */
#if defined(IP_RECVERR) && HAVE_STRUCT_SOCK_EXTENDED_ERR
case IP_RECVERR: {
struct sock_extended_err *err =
(struct sock_extended_err *)CMSG_DATA(cmsg);
struct xio_extended_err {
struct sock_extended_err see;
__u32 data0;
__u32 data1;
__u32 data2;
__u32 data3;
} ;
struct xio_extended_err *err =
(struct xio_extended_err *)CMSG_DATA(cmsg);
*num = 6;
typbuff[0] = '\0'; strncat(typbuff, "IP_RECVERR", typlen-1);
snprintf(nambuff, namlen, "%s%c%s%c%s%c%s%c%s%c%s",
@ -537,8 +554,33 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
"IP_RECVERR_TYPE", '\0', "IP_RECVERR_CODE", '\0',
"IP_RECVERR_INFO", '\0', "IP_RECVERR_DATA");
snprintf(valbuff, vallen, "%u%c%u%c%u%c%u%c%u%c%u",
err->ee_errno, '\0', err->ee_origin, '\0', err->ee_type, '\0',
err->ee_code, '\0', err->ee_info, '\0', err->ee_data);
err->see.ee_errno, '\0', err->see.ee_origin, '\0', err->see.ee_type, '\0',
err->see.ee_code, '\0', err->see.ee_info, '\0', err->see.ee_data);
/* semantic part */
switch (err->see.ee_origin) {
char addrbuff[40];
#if WITH_IP4
case SO_EE_ORIGIN_ICMP:
if (1) {
inet4addr_info(ntohl(err->data1), addrbuff, sizeof(addrbuff));
Notice6("received ICMP from %s, type %d, code %d, info %d, data %d, resulting in errno %d",
addrbuff, err->see.ee_type, err->see.ee_code, err->see.ee_info, err->see.ee_data, err->see.ee_errno);
}
break;
#endif /* WITH_IP4 */
#if WITH_IP6
case SO_EE_ORIGIN_ICMP6:
if (1) {
Notice5("received ICMP type %d, code %d, info %d, data %d, resulting in errno %d",
err->see.ee_type, err->see.ee_code, err->see.ee_info, err->see.ee_data, err->see.ee_errno);
}
break;
#endif /* WITH_IP6 */
default:
Notice6("received error message origin %d, type %d, code %d, info %d, data %d, generating errno %d",
err->see.ee_origin, err->see.ee_type, err->see.ee_code, err->see.ee_info, err->see.ee_data, err->see.ee_errno);
break;
}
return STAT_OK;
}
#endif /* defined(IP_RECVERR) && HAVE_STRUCT_SOCK_EXTENDED_ERR */
@ -553,6 +595,7 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
valbuff[0] = '\0';
strncat(valbuff,
xiosubstr(scratch1, sadl->sdl_data, 0, sadl->sdl_nlen), vallen-1);
Notice1("IP_RECVIF: %s", valbuff);
return STAT_OK;
}
#endif /* defined(IP_RECVIF) */
@ -564,6 +607,7 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
nambuff[0] = '\0'; strncat(nambuff, "dstaddr", namlen-1);
envbuff[0] = '\0'; strncat(envbuff, "IP_DSTADDR", envlen-1);
inet4addr_info(ntohl(*(uint32_t *)CMSG_DATA(cmsg)), valbuff, vallen);
Notice1("IP_RECVDSTADDR: %s", valbuff);
return STAT_OK;
#endif
#endif /* WITH_IP4 */
@ -571,9 +615,12 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
#ifdef IP_RECVOPTS
case IP_RECVOPTS:
#endif
cmsgtype = "IP_OPTIONS"; cmsgname = "options"; cmsgctr = -1; break;
cmsgtype = "IP_OPTIONS"; cmsgname = "options"; cmsgctr = -1;
/*!!!*/
break;
case IP_TOS:
cmsgtype = "IP_TOS"; cmsgname = "tos"; cmsgctr = msglen; break;
cmsgtype = "IP_TOS"; cmsgname = "tos"; cmsgctr = msglen;
break;
case IP_TTL: /* Linux */
#ifdef IP_RECVTTL
case IP_RECVTTL: /* FreeBSD */
@ -581,7 +628,7 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
cmsgtype = "IP_TTL"; cmsgname = "ttl"; cmsgctr = msglen; break;
}
/* when we come here we provide a single parameter
with type in cmsgtype, name in cmsgname, value length in msglen */
with name in cmsgname, value length in msglen */
*num = 1;
if (strlen(cmsgtype) >= typlen) rc = STAT_WARNING;
typbuff[0] = '\0'; strncat(typbuff, cmsgtype, typlen-1);
@ -595,9 +642,13 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
}
switch (cmsgctr) {
case sizeof(char):
snprintf(valbuff, vallen, "%u", *(unsigned char *)CMSG_DATA(cmsg)); break;
snprintf(valbuff, vallen, "%u", *(unsigned char *)CMSG_DATA(cmsg));
Notice2("Ancillary message: %s=%u", cmsgname, *(unsigned char *)CMSG_DATA(cmsg));
break;
case sizeof(int):
snprintf(valbuff, vallen, "%u", (*(unsigned int *)CMSG_DATA(cmsg))); break;
snprintf(valbuff, vallen, "%u", (*(unsigned int *)CMSG_DATA(cmsg)));
Notice2("Ancillary message: %s=%u", cmsgname, *(unsigned int *)CMSG_DATA(cmsg));
break;
case 0:
xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); break;
default: break;