From b43c30b6b9171da61156495d38d0e2c49bb04421 Mon Sep 17 00:00:00 2001 From: Gerhard Rieger Date: Sun, 22 Jan 2017 18:48:07 +0100 Subject: [PATCH] Data extraction from ancillary messages might have failed on big-endian --- CHANGES | 4 ++++ xio-ip.c | 23 ++++++++++++++--------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/CHANGES b/CHANGES index d2e2c68..8c20c72 100644 --- a/CHANGES +++ b/CHANGES @@ -69,6 +69,10 @@ corrections: On systems with predefined bool type whose size differs from int some 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: Type conflict between int and sig_atomic_t between declaration and definition of diag_immediate_type and diag_immediate_exit broke diff --git a/xio-ip.c b/xio-ip.c index cd28f35..67fcd75 100644 --- a/xio-ip.c +++ b/xio-ip.c @@ -465,7 +465,8 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num, char *nambuff, int namlen, char *envbuff, int envlen, 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; char scratch1[16]; /* can hold an IPv4 address in ASCII */ #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 case IP_RECVOPTS: #endif - cmsgtype = "IP_OPTIONS"; cmsgname = "options"; cmsgfmt = NULL; break; + cmsgtype = "IP_OPTIONS"; cmsgname = "options"; cmsgctr = -1; break; case IP_TOS: - cmsgtype = "IP_TOS"; cmsgname = "tos"; cmsgfmt = "%u"; break; + cmsgtype = "IP_TOS"; cmsgname = "tos"; cmsgctr = msglen; break; case IP_TTL: /* Linux */ #ifdef IP_RECVTTL case IP_RECVTTL: /* FreeBSD */ #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 - with type in cmsgtype, name in cmsgname, printf format in cmsgfmt */ + with type in cmsgtype, name in cmsgname, value length in msglen */ *num = 1; if (strlen(cmsgtype) >= typlen) rc = STAT_WARNING; typbuff[0] = '\0'; strncat(typbuff, cmsgtype, typlen-1); @@ -577,10 +578,14 @@ int xiolog_ancillary_ip(struct cmsghdr *cmsg, int *num, } else { envbuff[0] = '\0'; } - if (cmsgfmt != NULL) { - snprintf(valbuff, vallen, cmsgfmt, *(unsigned char *)CMSG_DATA(cmsg)); - } else { - xiodump(CMSG_DATA(cmsg), msglen, valbuff, vallen, 0); + switch (cmsgctr) { + case sizeof(char): + snprintf(valbuff, vallen, "%u", *(unsigned char *)CMSG_DATA(cmsg)); break; + 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; }