static void print_cmsg_type_data(struct tcb *tcp, const int cmsg_level, const int cmsg_type, const void *cmsg_data, const size_t data_len) { switch (cmsg_level) { case SOL_SOCKET: printxval(scmvals, cmsg_type, "SCM_???"); switch (cmsg_type) { case SCM_RIGHTS: print_scm_rights(tcp, cmsg_data, data_len); break; case SCM_CREDENTIALS: print_scm_creds(tcp, cmsg_data, data_len); break; case SCM_SECURITY: print_scm_security(tcp, cmsg_data, data_len); break; } break; case SOL_IP: printxval(ip_cmsg_types, cmsg_type, "IP_???"); switch (cmsg_type) { case IP_PKTINFO: print_cmsg_ip_pktinfo(tcp, cmsg_data, data_len); break; case IP_TTL: print_cmsg_ip_ttl(tcp, cmsg_data, data_len); break; case IP_TOS: print_cmsg_ip_tos(tcp, cmsg_data, data_len); break; case IP_RECVOPTS: case IP_RETOPTS: print_cmsg_ip_opts(tcp, cmsg_data, data_len); break; case IP_RECVERR: print_cmsg_ip_recverr(tcp, cmsg_data, data_len); break; case IP_ORIGDSTADDR: print_cmsg_ip_origdstaddr(tcp, cmsg_data, data_len); break; case IP_CHECKSUM: print_cmsg_ip_checksum(tcp, cmsg_data, data_len); break; case SCM_SECURITY: print_scm_security(tcp, cmsg_data, data_len); break; } break; default: tprintf("%u", cmsg_type); } }
static void printcmsghdr(struct tcb *tcp, unsigned long addr, size_t len) { const size_t cmsg_size = #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4 (current_wordsize < sizeof(long)) ? sizeof(struct cmsghdr32) : #endif sizeof(struct cmsghdr); char *buf = len < cmsg_size ? NULL : malloc(len); if (!buf || umoven(tcp, addr, len, buf) < 0) { tprintf(", msg_control=%#lx", addr); free(buf); return; } union_cmsghdr u = { .ptr = buf }; tprints(", ["); while (len >= cmsg_size) { size_t cmsg_len = #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4 (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_len : #endif u.cmsg->cmsg_len; int cmsg_level = #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4 (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_level : #endif u.cmsg->cmsg_level; int cmsg_type = #if SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4 (current_wordsize < sizeof(long)) ? u.cmsg32->cmsg_type : #endif u.cmsg->cmsg_type; if (u.ptr != buf) tprints(", "); tprintf("{cmsg_len=%lu, cmsg_level=", (unsigned long) cmsg_len); printxval(socketlayers, cmsg_level, "SOL_???"); tprints(", cmsg_type="); if (cmsg_len > len) cmsg_len = len; if (cmsg_level == SOL_SOCKET) { printxval(scmvals, cmsg_type, "SCM_???"); switch (cmsg_type) { case SCM_RIGHTS: if (print_scm_rights(tcp, cmsg_size, u.ptr, cmsg_len)) goto next_cmsg; break; case SCM_CREDENTIALS: if (print_scm_creds(tcp, cmsg_size, u.ptr, cmsg_len)) goto next_cmsg; break; case SCM_SECURITY: if (print_scm_security(tcp, cmsg_size, u.ptr, cmsg_len)) goto next_cmsg; break; } } else { tprintf("%u", cmsg_type); } tprints(", ...}"); next_cmsg: if (cmsg_len < cmsg_size) { len -= cmsg_size; break; } cmsg_len = (cmsg_len + current_wordsize - 1) & (size_t) ~(current_wordsize - 1); if (cmsg_len >= len) { len = 0; break; } u.ptr += cmsg_len; len -= cmsg_len; } if (len) tprints(", ..."); tprints("]"); free(buf); }