static VALUE
ancillary_inspect(VALUE self)
{
VALUE ret;
int family, level, type;
VALUE data;
ID family_id, level_id, type_id;
VALUE vtype;
int inspected;
family = ancillary_family(self);
level = ancillary_level(self);
type = ancillary_type(self);
data = ancillary_data(self);
ret = rb_sprintf("#<%s:", rb_obj_classname(self));
family_id = rsock_intern_family_noprefix(family);
if (family_id)
rb_str_catf(ret, " %s", rb_id2name(family_id));
else
rb_str_catf(ret, " family:%d", family);
if (level == SOL_SOCKET) {
rb_str_cat2(ret, " SOCKET");
type_id = rsock_intern_scm_optname(type);
if (type_id)
rb_str_catf(ret, " %s", rb_id2name(type_id));
else
rb_str_catf(ret, " cmsg_type:%d", type);
}
else if (IS_IP_FAMILY(family)) {
level_id = rsock_intern_iplevel(level);
if (level_id)
rb_str_catf(ret, " %s", rb_id2name(level_id));
else
rb_str_catf(ret, " cmsg_level:%d", level);
vtype = ip_cmsg_type_to_sym(level, type);
if (SYMBOL_P(vtype))
rb_str_catf(ret, " %s", rb_id2name(SYM2ID(vtype)));
else
rb_str_catf(ret, " cmsg_type:%d", type);
}
else {
rb_str_catf(ret, " cmsg_level:%d", level);
rb_str_catf(ret, " cmsg_type:%d", type);
}
inspected = 0;
if (level == SOL_SOCKET)
family = AF_UNSPEC;
switch (family) {
case AF_UNSPEC:
switch (level) {
case SOL_SOCKET:
switch (type) {
case SCM_TIMESTAMP: inspected = inspect_timeval_as_abstime(level, type, data, ret); break;
case SCM_TIMESTAMPNS: inspected = inspect_timespec_as_abstime(level, type, data, ret); break;
case SCM_BINTIME: inspected = inspect_bintime_as_abstime(level, type, data, ret); break;
case SCM_RIGHTS: inspected = anc_inspect_socket_rights(level, type, data, ret); break;
case SCM_CREDENTIALS: inspected = anc_inspect_passcred_credentials(level, type, data, ret); break;
case SCM_CREDS: inspected = anc_inspect_socket_creds(level, type, data, ret); break;
}
break;
}
break;
case AF_INET:
case AF_INET6:
switch (level) {
case IPPROTO_IP:
switch (type) {
case IP_RECVDSTADDR: inspected = anc_inspect_ip_recvdstaddr(level, type, data, ret); break;
case IP_PKTINFO: inspected = anc_inspect_ip_pktinfo(level, type, data, ret); break;
}
break;
case IPPROTO_IPV6:
switch (type) {
case IPV6_PKTINFO: inspected = anc_inspect_ipv6_pktinfo(level, type, data, ret); break;
}
break;
}
break;
}
if (!inspected) {
rb_str_cat2(ret, " ");
rb_str_append(ret, rb_str_dump(data));
}
rb_str_cat2(ret, ">");
return ret;
}