Start merging linux-ip-routing fork
diff --git a/net.c b/net.c
index 7e5c4b9..ba6c2bf 100644
--- a/net.c
+++ b/net.c
@@ -46,11 +46,23 @@
#endif /* LINUX */
#if defined(LINUX) && defined(MIPS)
-#if defined( HAVE_LINUX_IN6_H)
+#if defined(HAVE_LINUX_IN6_H)
#include <linux/in6.h>
#endif
#endif
+#if defined(HAVE_SYS_UIO_H)
+#include <sys/uio.h>
+#endif
+
+#if defined(HAVE_LINUX_NETLINK_H)
+#include <linux/netlink.h>
+#endif
+
+#if defined(HAVE_LINUX_IF_PACKET_H)
+#include <linux/if_packet.h>
+#endif
+
#ifndef PF_UNSPEC
#define PF_UNSPEC AF_UNSPEC
#endif
@@ -69,6 +81,21 @@
{ PF_UNSPEC, "PF_UNSPEC" },
{ PF_UNIX, "PF_UNIX" },
{ PF_INET, "PF_INET" },
+#ifdef PF_NETLINK
+ { PF_NETLINK, "PF_NETLINK" },
+#endif
+#ifdef PF_PACKET
+ { PF_PACKET, "PF_PACKET" },
+#endif
+#ifdef PF_INET6
+ { PF_INET6, "PF_INET6" },
+#endif
+#ifdef PF_ATMSVC
+ { PF_ATMSVC, "PF_INET6" },
+#endif
+#ifdef PF_INET6
+ { PF_INET6, "PF_INET6" },
+#endif
#ifdef PF_LOCAL
{ PF_LOCAL, "PS_LOCAL" },
#endif
@@ -96,9 +123,6 @@
#ifdef PF_X25
{ PF_X25, "PF_X25" },
#endif
-#ifdef PF_INET6
- { PF_INET6, "PF_INET6" },
-#endif
#ifdef PF_ROSE
{ PF_ROSE, "PF_ROSE" },
#endif
@@ -113,6 +137,25 @@
#endif
{ 0, NULL },
};
+static struct xlat addrfams[] = {
+ { AF_UNSPEC, "AF_UNSPEC" },
+ { AF_UNIX, "AF_UNIX" },
+ { AF_INET, "AF_INET" },
+ { AF_INET6, "AF_INET6" },
+ { AF_DECnet, "AF_DECnet" },
+#ifdef PF_ATMSVC
+ { AF_ATMSVC, "AF_ATMSVC" },
+#endif
+ { AF_PACKET, "AF_PACKET" },
+ { AF_NETLINK, "AF_NETLINK" },
+#ifdef PF_ISO
+ { AF_ISO, "AF_ISO" },
+#endif
+#ifdef PF_IMPLINK
+ { AF_IMPLINK, "AF_IMPLINK" },
+#endif
+ { 0, NULL },
+};
static struct xlat socktypes[] = {
{ SOCK_STREAM, "SOCK_STREAM" },
{ SOCK_DGRAM, "SOCK_DGRAM" },
@@ -193,10 +236,34 @@
#ifdef MSG_WAITALL
{ MSG_WAITALL, "MSG_WAITALL" },
#endif
+#ifdef MSG_TRUNC
+ { MSG_TRUNC, "MSG_TRUNC" },
+#endif
+#ifdef MSG_CTRUNC
+ { MSG_CTRUNC, "MSG_CTRUNC" },
+#endif
+#ifdef MSG_ERRQUEUE
+ { MSG_ERRQUEUE, "MSG_ERRQUEUE" },
+#endif
+#ifdef MSG_DONTWAIT
+ { MSG_DONTWAIT, "MSG_DONTWAIT" },
+#endif
+#ifdef MSG_CONFIRM
+ { MSG_CONFIRM, "MSG_CONFIRM" },
+#endif
+#ifdef MSG_PROBE
+ { MSG_PROBE, "MSG_PROBE" },
+#endif
{ 0, NULL },
};
static struct xlat sockoptions[] = {
+#ifdef SO_PEERCRED
+ { SO_PEERCRED, "SO_PEERCRED" },
+#endif
+#ifdef SO_PASSCRED
+ { SO_PASSCRED, "SO_PASSCRED" },
+#endif
#ifdef SO_DEBUG
{ SO_DEBUG, "SO_DEBUG" },
#endif
@@ -310,20 +377,30 @@
#endif /* SOL_TCP */
void
-printsock(tcp, addr)
+printsock(tcp, addr, addrlen)
struct tcb *tcp;
long addr;
+int addrlen;
{
- struct sockaddr sa;
- struct sockaddr_in *sin = (struct sockaddr_in *) &sa;
- struct sockaddr_un sau;
+ union {
+ char pad[128];
+ struct sockaddr sa;
+ struct sockaddr_in sin;
+ struct sockaddr_un sau;
#ifdef HAVE_INET_NTOP
- struct sockaddr_in6 sa6;
+ struct sockaddr_in6 sa6;
+#endif
+#if defined(LINUX) && defined(AF_IPX)
+ struct sockaddr_ipx sipx;
+#endif
+#ifdef AF_PACKET
+ struct sockaddr_ll ll;
+#endif
+#ifdef AF_NETLINK
+ struct sockaddr_nl nl;
+#endif
+ } addrbuf;
char string_addr[100];
-#endif
-#ifdef LINUX
- struct sockaddr_ipx sipx;
-#endif
if (addr == 0) {
tprintf("NULL");
@@ -333,74 +410,126 @@
tprintf("%#lx", addr);
return;
}
- if (umove(tcp, addr, &sa) < 0) {
+ if ((addrlen<2) || (addrlen>sizeof(addrbuf)))
+ addrlen=sizeof(addrbuf);
+
+ if (umoven(tcp, addr, addrlen, (char*)&addrbuf) < 0) {
tprintf("{...}");
return;
}
- switch (sa.sa_family) {
+
+ tprintf("{sin_family=");
+ printxval(addrfams, addrbuf.sa.sa_family, "AF_???");
+ tprintf(", ");
+
+ switch (addrbuf.sa.sa_family) {
case AF_UNIX:
- if (umove(tcp, addr, &sau) < 0)
- tprintf("{sun_family=AF_UNIX, ...}");
- else
- tprintf("{sun_family=AF_UNIX, sun_path=\"%s\"}",
- sau.sun_path);
+ if (addrlen==2) {
+ tprintf("<nil>");
+ } else if (addrbuf.sau.sun_path[0]) {
+ tprintf("path=\"%*.*s\"", addrlen-2, addrlen-2, addrbuf.sau.sun_path);
+ } else {
+ tprintf("path=@%*.*s", addrlen-3, addrlen-3, addrbuf.sau.sun_path+1);
+ }
break;
case AF_INET:
- tprintf("{sin_family=AF_INET, ");
tprintf("sin_port=htons(%u), sin_addr=inet_addr(\"%s\")}",
- ntohs(sin->sin_port), inet_ntoa(sin->sin_addr));
+ ntohs(addrbuf.sin.sin_port), inet_ntoa(addrbuf.sin.sin_addr));
break;
#ifdef HAVE_INET_NTOP
case AF_INET6:
- if (umove(tcp, addr, &sa6) < 0)
- tprintf("{sin6_family=AF_INET6, ...}");
- else
- {
- tprintf("{sin6_family=AF_INET6, ");
- inet_ntop(AF_INET6, &sa6.sin6_addr, string_addr, sizeof(string_addr));
- tprintf("sin6_port=htons(%u), inet_pton(AF_INET6, \"%s\", &sin6_addr), sin6_flowinfo=htonl(%u)}",
- ntohs(sa6.sin6_port), string_addr, ntohl(sa6.sin6_flowinfo));
- }
+ inet_ntop(AF_INET6, &addrbuf.sa6.sin6_addr, string_addr, sizeof(string_addr));
+ tprintf("sin6_port=htons(%u), inet_pton(AF_INET6, \"%s\", &sin6_addr), sin6_flowinfo=htonl(%u)}",
+ ntohs(addrbuf.sa6.sin6_port), string_addr, ntohl(addrbuf.sa6.sin6_flowinfo));
break;
#endif
#if defined(AF_IPX) && defined(linux)
case AF_IPX:
- if (umove(tcp, addr, &sipx)<0)
- tprintf("{sipx_family=AF_IPX, ...}");
- else {
+ {
int i;
- tprintf("{sipx_family=AF_IPX, ");
tprintf("{sipx_port=htons(%u), ",
- ntohs(sipx.sipx_port));
+ ntohs(addrbuf.sipx.sipx_port));
/* Yes, I know, this does not look too
* strace-ish, but otherwise the IPX
* addresses just look monstrous...
* Anyways, feel free if you don't like
* this way.. :)
*/
- tprintf("%08lx:", (unsigned long)ntohl(sipx.sipx_network));
+ tprintf("%08lx:", (unsigned long)ntohl(addrbuf.sipx.sipx_network));
for (i = 0; i<IPX_NODE_LEN; i++)
- tprintf("%02x", sipx.sipx_node[i]);
- tprintf("/[%02x]", sipx.sipx_type);
- tprintf("}");
+ tprintf("%02x", addrbuf.sipx.sipx_node[i]);
+ tprintf("/[%02x]", addrbuf.sipx.sipx_type);
}
break;
-#endif /* AF_IPX && linux */
+#endif /* AF_IPX && linux */
+#ifdef AF_PACKET
+ case AF_PACKET:
+ {
+ int i;
+ tprintf("proto=%#04x, if%d, pkttype=%d, addr(%d)={%d, ",
+ ntohs(addrbuf.ll.sll_protocol),
+ addrbuf.ll.sll_ifindex,
+ addrbuf.ll.sll_pkttype,
+ addrbuf.ll.sll_halen,
+ addrbuf.ll.sll_hatype);
+ for (i=0; i<addrbuf.ll.sll_addr[i]; i++)
+ tprintf("%02x", addrbuf.ll.sll_addr[i]);
+ }
+ break;
+
+#endif /* AF_APACKET */
+#ifdef AF_NETLINLK
+ case AF_NETLINK:
+ tprintf("pid=%d, groups=%08x", addrbuf.nl.nl_pid, addrbuf.nl.nl_groups);
+ break;
+#endif /* AF_NETLINK */
/* AF_AX25 AF_APPLETALK AF_NETROM AF_BRIDGE AF_AAL5
- AF_X25 AF_INET6 AF_ROSE still need to be done */
+ AF_X25 AF_ROSE etc. still need to be done */
default:
- tprintf("{sa_family=%u, sa_data=", sa.sa_family);
+ tprintf("{sa_family=%u, sa_data=", addrbuf.sa.sa_family);
printstr(tcp, (long) &((struct sockaddr *) addr)->sa_data,
- sizeof sa.sa_data);
- tprintf("}");
+ sizeof addrbuf.sa.sa_data);
break;
}
+ tprintf("}");
}
#if HAVE_SENDMSG
static void
+printiovec(tcp, iovec, len)
+struct tcb *tcp;
+struct iovec *iovec;
+long len;
+{
+ struct iovec *iov;
+ int i;
+
+ iov = (struct iovec *) malloc(len * sizeof *iov);
+ if (iov == NULL) {
+ fprintf(stderr, "No memory");
+ return;
+ }
+ if (umoven(tcp, (long)iovec,
+ len * sizeof *iov, (char *) iov) < 0) {
+ tprintf("%#lx", (unsigned long)iovec);
+ } else {
+ tprintf("[");
+ for (i = 0; i < len; i++) {
+ if (i)
+ tprintf(", ");
+ tprintf("{");
+ printstr(tcp, (long) iov[i].iov_base,
+ iov[i].iov_len);
+ tprintf(", %lu}", (unsigned long)iov[i].iov_len);
+ }
+ tprintf("]");
+ }
+ free((char *) iov);
+}
+
+static void
printmsghdr(tcp, addr)
struct tcb *tcp;
long addr;
@@ -411,19 +540,24 @@
tprintf("%#lx", addr);
return;
}
- tprintf("{msg_name=");
- printstr(tcp, (long) msg.msg_name, msg.msg_namelen);
- tprintf(", msg_namelen=%u, msg_iov=%#lx, msg_iovlen=%u, ",
- msg.msg_namelen,
- (unsigned long) msg.msg_iov, msg.msg_iovlen);
+ tprintf("{msg_name(%d)=", msg.msg_namelen);
+ printsock(tcp, (long)msg.msg_name, msg.msg_namelen);
+
+ tprintf(", msg_iov(%lu)=", (unsigned long)msg.msg_iovlen);
+ printiovec(tcp, msg.msg_iov, msg.msg_iovlen);
+
#ifdef HAVE_MSG_CONTROL
- tprintf("msg_control=%#lx, msg_controllen=%u, msg_flags=%#x}",
- (unsigned long) msg.msg_control, msg.msg_controllen,
- msg.msg_flags);
+ tprintf(", msg_controllen=%lu", (unsigned long)msg.msg_controllen);
+ if (msg.msg_controllen)
+ tprintf(", msg_control=%#lx, ", (unsigned long) msg.msg_control);
+ tprintf(", msg_flags=");
+ if (printflags(msg_flags, msg.msg_flags)==0)
+ tprintf("0");
#else /* !HAVE_MSG_CONTROL */
- tprintf("msg_accrights=%#lx, msg_accrightslen=%u}",
+ tprintf("msg_accrights=%#lx, msg_accrightslen=%u",
(unsigned long) msg.msg_accrights, msg.msg_accrightslen);
#endif /* !HAVE_MSG_CONTROL */
+ tprintf("}");
}
#endif /* HAVE_SENDMSG */
@@ -463,7 +597,7 @@
{
if (entering(tcp)) {
tprintf("%ld, ", tcp->u_arg[0]);
- printsock(tcp, tcp->u_arg[1]);
+ printsock(tcp, tcp->u_arg[1], tcp->u_arg[2]);
tprintf(", %lu", tcp->u_arg[2]);
}
return 0;
@@ -498,7 +632,7 @@
if (tcp->u_arg[1] == 0 || syserror(tcp)) {
tprintf("%#lx", tcp->u_arg[1]);
} else {
- printsock(tcp, tcp->u_arg[1]);
+ printsock(tcp, tcp->u_arg[1], tcp->u_arg[2]);
}
tprintf(", ");
printnum(tcp, tcp->u_arg[2], "%lu");
@@ -534,7 +668,7 @@
tprintf("0");
/* to address */
tprintf(", ");
- printsock(tcp, tcp->u_arg[4]);
+ printsock(tcp, tcp->u_arg[4], tcp->u_arg[5]);
/* to length */
tprintf(", %lu", tcp->u_arg[5]);
}
@@ -618,7 +752,7 @@
return 0;
}
tprintf(", ");
- printsock(tcp, tcp->u_arg[4]);
+ printsock(tcp, tcp->u_arg[4], tcp->u_arg[5]);
/* from length */
tprintf(", [%u]", fromlen);
}
@@ -797,7 +931,7 @@
default:
/* XXX - should know socket family here */
printxval(protocols, tcp->u_arg[1], "IPPROTO_???");
- tprintf("%lu, ", tcp->u_arg[2]);
+ tprintf(", %lu, ", tcp->u_arg[2]);
break;
}
} else {