Data extraction from ancillary messages might have failed on big-endian

This commit is contained in:
Gerhard Rieger 2017-01-22 18:48:07 +01:00
parent 31192e3498
commit b43c30b6b9
2 changed files with 18 additions and 9 deletions

View file

@ -69,6 +69,10 @@ corrections:
On systems with predefined bool type whose size differs from int some On systems with predefined bool type whose size differs from int some
IPv6 and TCP options (per setsockopt()) failed. IPv6 and TCP options (per setsockopt()) failed.
Length of integral data in ancillary messages varies (TOS: 1 byte,
TTL: 4 bytes), the old implementation failed for TTL on big-endian
hosts.
porting: porting:
Type conflict between int and sig_atomic_t between declaration and Type conflict between int and sig_atomic_t between declaration and
definition of diag_immediate_type and diag_immediate_exit broke definition of diag_immediate_type and diag_immediate_exit broke

View file

@ -465,7 +465,8 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
char *nambuff, int namlen, char *nambuff, int namlen,
char *envbuff, int envlen, char *envbuff, int envlen,
char *valbuff, int vallen) { char *valbuff, int vallen) {
const char *cmsgtype, *cmsgname = NULL, *cmsgenvn = NULL, *cmsgfmt = NULL; int cmsgctr = 0;
const char *cmsgtype, *cmsgname = NULL, *cmsgenvn = NULL;
size_t msglen; size_t msglen;
char scratch1[16]; /* can hold an IPv4 address in ASCII */ char scratch1[16]; /* can hold an IPv4 address in ASCII */
#if WITH_IP4 && defined(IP_PKTINFO) && HAVE_STRUCT_IN_PKTINFO #if WITH_IP4 && defined(IP_PKTINFO) && HAVE_STRUCT_IN_PKTINFO
@ -555,17 +556,17 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
#ifdef IP_RECVOPTS #ifdef IP_RECVOPTS
case IP_RECVOPTS: case IP_RECVOPTS:
#endif #endif
cmsgtype = "IP_OPTIONS"; cmsgname = "options"; cmsgfmt = NULL; break; cmsgtype = "IP_OPTIONS"; cmsgname = "options"; cmsgctr = -1; break;
case IP_TOS: case IP_TOS:
cmsgtype = "IP_TOS"; cmsgname = "tos"; cmsgfmt = "%u"; break; cmsgtype = "IP_TOS"; cmsgname = "tos"; cmsgctr = msglen; break;
case IP_TTL: /* Linux */ case IP_TTL: /* Linux */
#ifdef IP_RECVTTL #ifdef IP_RECVTTL
case IP_RECVTTL: /* FreeBSD */ case IP_RECVTTL: /* FreeBSD */
#endif #endif
cmsgtype = "IP_TTL"; cmsgname = "ttl"; cmsgfmt = "%u"; break; cmsgtype = "IP_TTL"; cmsgname = "ttl"; cmsgctr = msglen; break;
} }
/* when we come here we provide a single parameter /* when we come here we provide a single parameter
with type in cmsgtype, name in cmsgname, printf format in cmsgfmt */ with type in cmsgtype, name in cmsgname, value length in msglen */
*num = 1; *num = 1;
if (strlen(cmsgtype) >= typlen) rc = STAT_WARNING; if (strlen(cmsgtype) >= typlen) rc = STAT_WARNING;
typbuff[0] = '\0'; strncat(typbuff, cmsgtype, typlen-1); typbuff[0] = '\0'; strncat(typbuff, cmsgtype, typlen-1);
@ -577,10 +578,14 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num,
} else { } else {
envbuff[0] = '\0'; envbuff[0] = '\0';
} }
if (cmsgfmt != NULL) { switch (cmsgctr) {
snprintf(valbuff, vallen, cmsgfmt, *(unsigned char *)CMSG_DATA(cmsg)); case sizeof(char):
} else { snprintf(valbuff, vallen, "%u", *(unsigned char *)CMSG_DATA(cmsg)); break;
xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); case sizeof(int):
snprintf(valbuff, vallen, "%u", (*(unsigned int *)CMSG_DATA(cmsg))); break;
case 0:
xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); break;
default: break;
} }
return rc; return rc;
} }