2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 #include <sys/socket.h>
38 #include <netinet/in.h>
39 #include <arpa/inet.h>
41 #include <asm/types.h>
42 #if defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC__ + __GLIBC_MINOR__ >= 3)
43 # include <netipx/ipx.h>
45 # include <linux/ipx.h>
49 #if defined (__GLIBC__) && ((__GLIBC__ < 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1))
50 #if defined(HAVE_LINUX_IN6_H)
51 #include <linux/in6.h>
55 #if defined(HAVE_SYS_UIO_H)
59 #if defined(HAVE_LINUX_NETLINK_H)
60 #include <linux/netlink.h>
63 #if defined(HAVE_LINUX_IF_PACKET_H)
64 #include <linux/if_packet.h>
68 #define PF_UNSPEC AF_UNSPEC
72 /* Under Linux these are enums so we can't test for them with ifdef. */
73 #define IPPROTO_EGP IPPROTO_EGP
74 #define IPPROTO_PUP IPPROTO_PUP
75 #define IPPROTO_IDP IPPROTO_IDP
76 #define IPPROTO_IGMP IPPROTO_IGMP
77 #define IPPROTO_RAW IPPROTO_RAW
78 #define IPPROTO_MAX IPPROTO_MAX
81 static struct xlat domains[] = {
82 { PF_UNSPEC, "PF_UNSPEC" },
83 { PF_UNIX, "PF_UNIX" },
84 { PF_INET, "PF_INET" },
86 { PF_NETLINK, "PF_NETLINK" },
89 { PF_PACKET, "PF_PACKET" },
92 { PF_INET6, "PF_INET6" },
95 { PF_ATMSVC, "PF_INET6" },
98 { PF_INET6, "PF_INET6" },
101 { PF_LOCAL, "PS_LOCAL" },
104 { PF_ISO, "PF_ISO" },
107 { PF_AX25, "PF_AX25" },
110 { PF_IPX, "PF_IPX" },
113 { PF_APPLETALK, "PF_APPLETALK" },
116 { PF_NETROM, "PF_NETROM" },
119 { PF_BRIDGE, "PF_BRIDGE" },
122 { PF_AAL5, "PF_AAL5" },
125 { PF_X25, "PF_X25" },
128 { PF_ROSE, "PF_ROSE" },
131 { PF_DECNET, "PF_DECNET" },
134 { PF_NETBEUI, "PF_NETBEUI" },
137 { PF_IMPLINK, "PF_IMPLINK" },
141 static struct xlat addrfams[] = {
142 { AF_UNSPEC, "AF_UNSPEC" },
143 { AF_UNIX, "AF_UNIX" },
144 { AF_INET, "AF_INET" },
146 { AF_INET6, "AF_INET6" },
148 { AF_DECnet, "AF_DECnet" },
150 { AF_ATMSVC, "AF_ATMSVC" },
153 { AF_PACKET, "AF_PACKET" },
156 { AF_NETLINK, "AF_NETLINK" },
159 { AF_ISO, "AF_ISO" },
162 { AF_IMPLINK, "AF_IMPLINK" },
166 static struct xlat socktypes[] = {
167 { SOCK_STREAM, "SOCK_STREAM" },
168 { SOCK_DGRAM, "SOCK_DGRAM" },
170 { SOCK_RAW, "SOCK_RAW" },
172 #ifdef SOCK_SEQPACKET
173 { SOCK_SEQPACKET,"SOCK_SEQPACKET"},
176 { SOCK_RDM, "SOCK_RDM" },
179 { SOCK_PACKET, "SOCK_PACKET" },
183 static struct xlat protocols[] = {
184 { IPPROTO_IP, "IPPROTO_IP" },
185 { IPPROTO_ICMP, "IPPROTO_ICMP" },
186 { IPPROTO_TCP, "IPPROTO_TCP" },
187 { IPPROTO_UDP, "IPPROTO_UDP" },
189 { IPPROTO_GGP, "IPPROTO_GGP" },
192 { IPPROTO_EGP, "IPPROTO_EGP" },
195 { IPPROTO_PUP, "IPPROTO_PUP" },
198 { IPPROTO_IDP, "IPPROTO_IDP" },
201 { IPPROTO_IPV6, "IPPROTO_IPV6" },
203 #ifdef IPPROTO_ICMPV6
204 { IPPROTO_ICMPV6,"IPPROTO_ICMPV6"},
207 { IPPROTO_IGMP, "IPPROTO_IGMP" },
210 { IPPROTO_HELLO,"IPPROTO_HELLO" },
213 { IPPROTO_ND, "IPPROTO_ND" },
216 { IPPROTO_RAW, "IPPROTO_RAW" },
219 { IPPROTO_MAX, "IPPROTO_MAX" },
222 { IPPROTO_IPIP, "IPPROTO_IPIP" },
226 static struct xlat msg_flags[] = {
227 { MSG_OOB, "MSG_OOB" },
229 { MSG_DONTROUTE,"MSG_DONTROUTE" },
232 { MSG_PEEK, "MSG_PEEK" },
235 { MSG_CTRUNC, "MSG_CTRUNC" },
238 { MSG_PROXY, "MSG_PROXY" },
241 { MSG_EOR, "MSG_EOR" },
244 { MSG_WAITALL, "MSG_WAITALL" },
247 { MSG_TRUNC, "MSG_TRUNC" },
250 { MSG_CTRUNC, "MSG_CTRUNC" },
253 { MSG_ERRQUEUE, "MSG_ERRQUEUE" },
256 { MSG_DONTWAIT, "MSG_DONTWAIT" },
259 { MSG_CONFIRM, "MSG_CONFIRM" },
262 { MSG_PROBE, "MSG_PROBE" },
267 static struct xlat sockoptions[] = {
269 { SO_PEERCRED, "SO_PEERCRED" },
272 { SO_PASSCRED, "SO_PASSCRED" },
275 { SO_DEBUG, "SO_DEBUG" },
278 { SO_REUSEADDR, "SO_REUSEADDR" },
281 { SO_KEEPALIVE, "SO_KEEPALIVE" },
284 { SO_DONTROUTE, "SO_DONTROUTE" },
287 { SO_BROADCAST, "SO_BROADCAST" },
290 { SO_LINGER, "SO_LINGER" },
293 { SO_OOBINLINE, "SO_OOBINLINE" },
296 { SO_TYPE, "SO_TYPE" },
299 { SO_ERROR, "SO_ERROR" },
302 { SO_SNDBUF, "SO_SNDBUF" },
305 { SO_RCVBUF, "SO_RCVBUF" },
308 { SO_NO_CHECK, "SO_NO_CHECK" },
311 { SO_PRIORITY, "SO_PRIORITY" },
314 { SO_ACCEPTCONN,"SO_ACCEPTCONN" },
316 #ifdef SO_USELOOPBACK
317 { SO_USELOOPBACK,"SO_USELOOPBACK"},
320 { SO_SNDLOWAT, "SO_SNDLOWAT" },
323 { SO_RCVLOWAT, "SO_RCVLOWAT" },
326 { SO_SNDTIMEO, "SO_SNDTIMEO" },
329 { SO_RCVTIMEO, "SO_RCVTIMEO" },
332 { SO_BSDCOMPAT, "SO_BSDCOMPAT" },
335 { SO_REUSEPORT, "SO_REUSEPORT" },
338 { SO_RCVLOWAT, "SO_RCVLOWAT" },
341 { SO_SNDLOWAT, "SO_SNDLOWAT" },
344 { SO_RCVTIMEO, "SO_RCVTIMEO" },
347 { SO_SNDTIMEO, "SO_SNDTIMEO" },
353 static struct xlat sockipoptions[] = {
354 { IP_TOS, "IP_TOS" },
355 { IP_TTL, "IP_TTL" },
356 #if defined(IP_HDRINCL)
357 { IP_HDRINCL, "IP_HDRINCL" },
359 #if defined(IP_OPTIONS)
360 { IP_OPTIONS, "IP_OPTIONS" },
362 { IP_MULTICAST_IF, "IP_MULTICAST_IF" },
363 { IP_MULTICAST_TTL, "IP_MULTICAST_TTL" },
364 { IP_MULTICAST_LOOP, "IP_MULTICAST_LOOP" },
365 { IP_ADD_MEMBERSHIP, "IP_ADD_MEMBERSHIP" },
366 { IP_DROP_MEMBERSHIP, "IP_DROP_MEMBERSHIP" },
372 static struct xlat sockipxoptions[] = {
373 { IPX_TYPE, "IPX_TYPE" },
379 static struct xlat socktcpoptions[] = {
380 { TCP_NODELAY, "TCP_NODELAY" },
381 { TCP_MAXSEG, "TCP_MAXSEG" },
387 printsock(tcp, addr, addrlen)
395 struct sockaddr_in sin;
396 struct sockaddr_un sau;
397 #ifdef HAVE_INET_NTOP
398 struct sockaddr_in6 sa6;
400 #if defined(LINUX) && defined(AF_IPX)
401 struct sockaddr_ipx sipx;
404 struct sockaddr_ll ll;
407 struct sockaddr_nl nl;
410 char string_addr[100];
417 tprintf("%#lx", addr);
420 if ((addrlen<2) || (addrlen>sizeof(addrbuf)))
421 addrlen=sizeof(addrbuf);
423 if (umoven(tcp, addr, addrlen, (char*)&addrbuf) < 0) {
428 tprintf("{sin_family=");
429 printxval(addrfams, addrbuf.sa.sa_family, "AF_???");
432 switch (addrbuf.sa.sa_family) {
436 } else if (addrbuf.sau.sun_path[0]) {
437 tprintf("path=\"%*.*s\"", addrlen-2, addrlen-2, addrbuf.sau.sun_path);
439 tprintf("path=@%*.*s", addrlen-3, addrlen-3, addrbuf.sau.sun_path+1);
443 tprintf("sin_port=htons(%u), sin_addr=inet_addr(\"%s\")}",
444 ntohs(addrbuf.sin.sin_port), inet_ntoa(addrbuf.sin.sin_addr));
446 #ifdef HAVE_INET_NTOP
448 inet_ntop(AF_INET6, &addrbuf.sa6.sin6_addr, string_addr, sizeof(string_addr));
449 tprintf("sin6_port=htons(%u), inet_pton(AF_INET6, \"%s\", &sin6_addr), sin6_flowinfo=htonl(%u)}",
450 ntohs(addrbuf.sa6.sin6_port), string_addr, ntohl(addrbuf.sa6.sin6_flowinfo));
453 #if defined(AF_IPX) && defined(linux)
457 tprintf("{sipx_port=htons(%u), ",
458 ntohs(addrbuf.sipx.sipx_port));
459 /* Yes, I know, this does not look too
460 * strace-ish, but otherwise the IPX
461 * addresses just look monstrous...
462 * Anyways, feel free if you don't like
465 tprintf("%08lx:", (unsigned long)ntohl(addrbuf.sipx.sipx_network));
466 for (i = 0; i<IPX_NODE_LEN; i++)
467 tprintf("%02x", addrbuf.sipx.sipx_node[i]);
468 tprintf("/[%02x]", addrbuf.sipx.sipx_type);
471 #endif /* AF_IPX && linux */
476 tprintf("proto=%#04x, if%d, pkttype=%d, addr(%d)={%d, ",
477 ntohs(addrbuf.ll.sll_protocol),
478 addrbuf.ll.sll_ifindex,
479 addrbuf.ll.sll_pkttype,
480 addrbuf.ll.sll_halen,
481 addrbuf.ll.sll_hatype);
482 for (i=0; i<addrbuf.ll.sll_addr[i]; i++)
483 tprintf("%02x", addrbuf.ll.sll_addr[i]);
487 #endif /* AF_APACKET */
490 tprintf("pid=%d, groups=%08x", addrbuf.nl.nl_pid, addrbuf.nl.nl_groups);
492 #endif /* AF_NETLINK */
493 /* AF_AX25 AF_APPLETALK AF_NETROM AF_BRIDGE AF_AAL5
494 AF_X25 AF_ROSE etc. still need to be done */
497 tprintf("{sa_family=%u, sa_data=", addrbuf.sa.sa_family);
498 printstr(tcp, (long) &((struct sockaddr *) addr)->sa_data,
499 sizeof addrbuf.sa.sa_data);
508 printiovec(tcp, iovec, len)
516 iov = (struct iovec *) malloc(len * sizeof *iov);
518 fprintf(stderr, "No memory");
521 if (umoven(tcp, (long)iovec,
522 len * sizeof *iov, (char *) iov) < 0) {
523 tprintf("%#lx", (unsigned long)iovec);
526 for (i = 0; i < len; i++) {
530 printstr(tcp, (long) iov[i].iov_base,
532 tprintf(", %lu}", (unsigned long)iov[i].iov_len);
540 printmsghdr(tcp, addr)
546 if (umove(tcp, addr, &msg) < 0) {
547 tprintf("%#lx", addr);
550 tprintf("{msg_name(%d)=", msg.msg_namelen);
551 printsock(tcp, (long)msg.msg_name, msg.msg_namelen);
553 tprintf(", msg_iov(%lu)=", (unsigned long)msg.msg_iovlen);
554 printiovec(tcp, msg.msg_iov, msg.msg_iovlen);
556 #ifdef HAVE_MSG_CONTROL
557 tprintf(", msg_controllen=%lu", (unsigned long)msg.msg_controllen);
558 if (msg.msg_controllen)
559 tprintf(", msg_control=%#lx, ", (unsigned long) msg.msg_control);
560 tprintf(", msg_flags=");
561 if (printflags(msg_flags, msg.msg_flags)==0)
563 #else /* !HAVE_MSG_CONTROL */
564 tprintf("msg_accrights=%#lx, msg_accrightslen=%u",
565 (unsigned long) msg.msg_accrights, msg.msg_accrightslen);
566 #endif /* !HAVE_MSG_CONTROL */
570 #endif /* HAVE_SENDMSG */
577 printxval(domains, tcp->u_arg[0], "PF_???");
579 printxval(socktypes, tcp->u_arg[1], "SOCK_???");
581 switch (tcp->u_arg[0]) {
583 printxval(protocols, tcp->u_arg[2], "IPPROTO_???");
587 /* BTW: I don't believe this.. */
589 printxval(domains, tcp->u_arg[2], "PF_???");
594 tprintf("%lu", tcp->u_arg[2]);
606 tprintf("%ld, ", tcp->u_arg[0]);
607 printsock(tcp, tcp->u_arg[1], tcp->u_arg[2]);
608 tprintf(", %lu", tcp->u_arg[2]);
617 return sys_bind(tcp);
625 tprintf("%ld, %lu", tcp->u_arg[0], tcp->u_arg[1]);
635 tprintf("%ld, ", tcp->u_arg[0]);
636 } else if (!tcp->u_arg[2])
637 tprintf("%#lx, NULL", tcp->u_arg[1]);
639 if (tcp->u_arg[1] == 0 || syserror(tcp)) {
640 tprintf("%#lx", tcp->u_arg[1]);
642 printsock(tcp, tcp->u_arg[1], tcp->u_arg[2]);
645 printnum(tcp, tcp->u_arg[2], "%lu");
655 tprintf("%ld, ", tcp->u_arg[0]);
656 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
657 tprintf(", %lu, ", tcp->u_arg[2]);
659 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
670 tprintf("%ld, ", tcp->u_arg[0]);
671 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
672 tprintf(", %lu, ", tcp->u_arg[2]);
674 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
678 printsock(tcp, tcp->u_arg[4], tcp->u_arg[5]);
680 tprintf(", %lu", tcp->u_arg[5]);
692 tprintf("%ld, ", tcp->u_arg[0]);
693 printmsghdr(tcp, tcp->u_arg[1]);
696 if (printflags(msg_flags, tcp->u_arg[2]) == 0)
702 #endif /* HAVE_SENDMSG */
709 tprintf("%ld, ", tcp->u_arg[0]);
712 tprintf("%#lx", tcp->u_arg[1]);
714 printstr(tcp, tcp->u_arg[1], tcp->u_rval);
716 tprintf(", %lu, ", tcp->u_arg[2]);
717 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
730 tprintf("%ld, ", tcp->u_arg[0]);
733 tprintf("%#lx, %lu, %lu, %#lx, %#lx",
734 tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3],
735 tcp->u_arg[4], tcp->u_arg[5]);
739 printstr(tcp, tcp->u_arg[1], tcp->u_rval);
741 tprintf(", %lu, ", tcp->u_arg[2]);
743 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
745 /* from address, len */
746 if (!tcp->u_arg[4] || !tcp->u_arg[5]) {
747 if (tcp->u_arg[4] == 0)
750 tprintf(", %#lx", tcp->u_arg[4]);
751 if (tcp->u_arg[5] == 0)
754 tprintf(", %#lx", tcp->u_arg[5]);
757 if (umove(tcp, tcp->u_arg[5], &fromlen) < 0) {
758 tprintf(", {...}, [?]");
762 printsock(tcp, tcp->u_arg[4], tcp->u_arg[5]);
764 tprintf(", [%u]", fromlen);
776 tprintf("%ld, ", tcp->u_arg[0]);
778 if (syserror(tcp) || !verbose(tcp))
779 tprintf("%#lx", tcp->u_arg[1]);
781 printmsghdr(tcp, tcp->u_arg[1]);
784 if (printflags(msg_flags, tcp->u_arg[2]) == 0)
790 #endif /* HAVE_SENDMSG */
797 tprintf("%ld, %ld", tcp->u_arg[0], tcp->u_arg[1]);
798 switch (tcp->u_arg[1]) {
800 tprintf("%s", " /* receive */");
803 tprintf("%s", " /* send */");
806 tprintf("%s", " /* send and receive */");
817 return sys_accept(tcp);
824 return sys_accept(tcp);
832 #if defined(LINUX) && !defined(SPARC)
837 tprintf("%#lx", tcp->u_arg[0]);
840 if (umoven(tcp, tcp->u_arg[0], sizeof fds, (char *) fds) < 0)
843 tprintf("[%u, %u]", fds[0], fds[1]);
845 #elif defined(SPARC) || defined(SVR4)
847 tprintf("[%lu, %lu]", tcp->u_rval, getrval2(tcp));
861 printxval(domains, tcp->u_arg[0], "PF_???");
863 printxval(socktypes, tcp->u_arg[1], "SOCK_???");
865 switch (tcp->u_arg[0]) {
867 printxval(protocols, tcp->u_arg[2], "IPPROTO_???");
871 /* BTW: I don't believe this.. */
873 printxval(domains, tcp->u_arg[2], "PF_???");
878 tprintf("%lu", tcp->u_arg[2]);
883 tprintf(", %#lx", tcp->u_arg[3]);
887 if (umoven(tcp, tcp->u_arg[3], sizeof fds, (char *) fds) < 0)
890 tprintf(", [%u, %u]", fds[0], fds[1]);
893 tprintf(", [%lu, %lu]", tcp->u_rval, getrval2(tcp));
896 tprintf(", [%lu, %lu]", tcp->u_rval, getrval2(tcp));
907 tprintf("%ld, ", tcp->u_arg[0]);
908 switch (tcp->u_arg[1]) {
910 tprintf("SOL_SOCKET, ");
911 printxval(sockoptions, tcp->u_arg[2], "SO_???");
917 printxval(sockipoptions, tcp->u_arg[2], "IP_???");
923 tprintf("SOL_IPX, ");
924 printxval(sockipxoptions, tcp->u_arg[2], "IPX_???");
930 tprintf("SOL_TCP, ");
931 printxval(socktcpoptions, tcp->u_arg[2], "TCP_???");
936 /* SOL_AX25 SOL_ROSE SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25
937 * etc. still need work */
939 /* XXX - should know socket family here */
940 printxval(protocols, tcp->u_arg[1], "IPPROTO_???");
941 tprintf(", %lu, ", tcp->u_arg[2]);
946 tprintf("%#lx, %#lx",
947 tcp->u_arg[3], tcp->u_arg[4]);
950 printnum(tcp, tcp->u_arg[3], "%ld");
952 printnum(tcp, tcp->u_arg[4], "%ld");
962 tprintf("%ld, ", tcp->u_arg[0]);
963 switch (tcp->u_arg[1]) {
965 tprintf("SOL_SOCKET, ");
966 printxval(sockoptions, tcp->u_arg[2], "SO_???");
972 printxval(sockipoptions, tcp->u_arg[2], "IP_???");
978 tprintf("SOL_IPX, ");
979 printxval(sockipxoptions, tcp->u_arg[2], "IPX_???");
985 tprintf("SOL_TCP, ");
986 printxval(socktcpoptions, tcp->u_arg[2], "TCP_???");
991 /* SOL_AX25 SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25
992 * etc. still need work */
994 /* XXX - should know socket family here */
995 printxval(protocols, tcp->u_arg[1], "IPPROTO_???");
996 tprintf("%lu, ", tcp->u_arg[2]);
999 printnum(tcp, tcp->u_arg[3], "%ld");
1000 tprintf(", %lu", tcp->u_arg[4]);