]> granicus.if.org Git - strace/blob - net.c
net.c: add SOL_PACKET and SOL_RAW socket options, update SOL_IP and SOL_TCP
[strace] / net.c
1 /*
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-2000 Wichert Akkerman <wichert@cistron.nl>
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
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.
18  *
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.
29  *
30  *      $Id$
31  */
32
33 #include "defs.h"
34
35 #include <sys/stat.h>
36 #include <sys/socket.h>
37 #include <sys/un.h>
38 #include <netinet/in.h>
39 #include <arpa/inet.h>
40 #if defined(LINUX)
41 #include <asm/types.h>
42 #if defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC__ + __GLIBC_MINOR__ >= 3)
43 #  include <netipx/ipx.h>
44 #else
45 #  include <linux/ipx.h>
46 #endif
47 #endif /* LINUX */
48
49 #if defined (__GLIBC__) && ((__GLIBC__ < 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1))
50 #if defined(HAVE_LINUX_IN6_H)
51 #include <linux/in6.h>
52 #endif
53 #endif
54
55 #if defined(HAVE_SYS_UIO_H)
56 #include <sys/uio.h>
57 #endif
58
59 #if defined(HAVE_LINUX_NETLINK_H)
60 #include <linux/netlink.h>
61 #endif
62
63 #if defined(HAVE_LINUX_IF_PACKET_H)
64 #include <linux/if_packet.h>
65 #endif
66
67 #if defined(HAVE_LINUX_ICMP_H)
68 #include <linux/icmp.h>
69 #endif
70
71 #ifndef PF_UNSPEC
72 #define PF_UNSPEC AF_UNSPEC
73 #endif
74
75 #ifdef LINUX
76 /* Under Linux these are enums so we can't test for them with ifdef. */
77 #define IPPROTO_EGP IPPROTO_EGP
78 #define IPPROTO_PUP IPPROTO_PUP
79 #define IPPROTO_IDP IPPROTO_IDP
80 #define IPPROTO_IGMP IPPROTO_IGMP
81 #define IPPROTO_RAW IPPROTO_RAW
82 #define IPPROTO_MAX IPPROTO_MAX
83 #endif
84
85 static struct xlat domains[] = {
86         { PF_UNSPEC,    "PF_UNSPEC"     },
87         { PF_UNIX,      "PF_UNIX"       },
88         { PF_INET,      "PF_INET"       },
89 #ifdef PF_NETLINK
90         { PF_NETLINK,   "PF_NETLINK"    },
91 #endif
92 #ifdef PF_PACKET
93         { PF_PACKET,    "PF_PACKET"     },
94 #endif
95 #ifdef PF_INET6
96         { PF_INET6,     "PF_INET6"      },
97 #endif
98 #ifdef PF_ATMSVC
99         { PF_ATMSVC,    "PF_INET6"      },
100 #endif
101 #ifdef PF_INET6
102         { PF_INET6,     "PF_INET6"      },
103 #endif
104 #ifdef PF_LOCAL
105         { PF_LOCAL,     "PS_LOCAL"      },
106 #endif
107 #ifdef PF_ISO
108         { PF_ISO,       "PF_ISO"        },
109 #endif
110 #ifdef PF_AX25
111         { PF_AX25,      "PF_AX25"       },
112 #endif
113 #ifdef PF_IPX
114         { PF_IPX,       "PF_IPX"        },
115 #endif
116 #ifdef PF_APPLETALK
117         { PF_APPLETALK, "PF_APPLETALK"  },
118 #endif
119 #ifdef PF_NETROM
120         { PF_NETROM,    "PF_NETROM"     },
121 #endif
122 #ifdef PF_BRIDGE
123         { PF_BRIDGE,    "PF_BRIDGE"     },
124 #endif
125 #ifdef PF_AAL5
126         { PF_AAL5,      "PF_AAL5"       },
127 #endif
128 #ifdef PF_X25
129         { PF_X25,       "PF_X25"        },
130 #endif
131 #ifdef PF_ROSE
132         { PF_ROSE,      "PF_ROSE"       },
133 #endif
134 #ifdef PF_DECNET
135         { PF_DECNET,    "PF_DECNET"     },
136 #endif
137 #ifdef PF_NETBEUI
138         { PF_NETBEUI,   "PF_NETBEUI"    },
139 #endif
140 #ifdef PF_IMPLINK
141         { PF_IMPLINK,   "PF_IMPLINK"    },
142 #endif
143         { 0,            NULL            },
144 };
145 static struct xlat addrfams[] = {
146         { AF_UNSPEC,    "AF_UNSPEC"     },
147         { AF_UNIX,      "AF_UNIX"       },
148         { AF_INET,      "AF_INET"       },
149 #ifdef AF_INET6
150         { AF_INET6,     "AF_INET6"      },
151 #endif
152         { AF_DECnet,    "AF_DECnet"     },
153 #ifdef PF_ATMSVC
154         { AF_ATMSVC,    "AF_ATMSVC"     },
155 #endif
156 #ifdef AF_PACKET
157         { AF_PACKET,    "AF_PACKET"     },
158 #endif
159 #ifdef AF_NETLINK
160         { AF_NETLINK,   "AF_NETLINK"    },
161 #endif
162 #ifdef AF_ISO
163         { AF_ISO,       "AF_ISO"        },
164 #endif
165 #ifdef AF_IMPLINK
166         { AF_IMPLINK,   "AF_IMPLINK"    },
167 #endif
168         { 0,            NULL            },
169 };
170 static struct xlat socktypes[] = {
171         { SOCK_STREAM,  "SOCK_STREAM"   },
172         { SOCK_DGRAM,   "SOCK_DGRAM"    },
173 #ifdef SOCK_RAW
174         { SOCK_RAW,     "SOCK_RAW"      },
175 #endif
176 #ifdef SOCK_SEQPACKET
177         { SOCK_SEQPACKET,"SOCK_SEQPACKET"},
178 #endif
179 #ifdef SOCK_RDM
180         { SOCK_RDM,     "SOCK_RDM"      },
181 #endif
182 #ifdef SOCK_PACKET
183         { SOCK_PACKET,  "SOCK_PACKET"   },
184 #endif
185         { 0,            NULL            },
186 };
187 static struct xlat protocols[] = {
188         { IPPROTO_IP,   "IPPROTO_IP"    },
189         { IPPROTO_ICMP, "IPPROTO_ICMP"  },
190         { IPPROTO_TCP,  "IPPROTO_TCP"   },
191         { IPPROTO_UDP,  "IPPROTO_UDP"   },
192 #ifdef IPPROTO_GGP
193         { IPPROTO_GGP,  "IPPROTO_GGP"   },
194 #endif
195 #ifdef IPPROTO_EGP
196         { IPPROTO_EGP,  "IPPROTO_EGP"   },
197 #endif
198 #ifdef IPPROTO_PUP
199         { IPPROTO_PUP,  "IPPROTO_PUP"   },
200 #endif
201 #ifdef IPPROTO_IDP
202         { IPPROTO_IDP,  "IPPROTO_IDP"   },
203 #endif
204 #ifdef IPPROTO_IPV6
205         { IPPROTO_IPV6, "IPPROTO_IPV6"  },
206 #endif
207 #ifdef IPPROTO_ICMPV6
208         { IPPROTO_ICMPV6,"IPPROTO_ICMPV6"},
209 #endif
210 #ifdef IPPROTO_IGMP
211         { IPPROTO_IGMP, "IPPROTO_IGMP"  },
212 #endif
213 #ifdef IPPROTO_HELLO
214         { IPPROTO_HELLO,"IPPROTO_HELLO" },
215 #endif
216 #ifdef IPPROTO_ND
217         { IPPROTO_ND,   "IPPROTO_ND"    },
218 #endif
219 #ifdef IPPROTO_RAW
220         { IPPROTO_RAW,  "IPPROTO_RAW"   },
221 #endif
222 #ifdef IPPROTO_MAX
223         { IPPROTO_MAX,  "IPPROTO_MAX"   },
224 #endif
225 #ifdef IPPROTO_IPIP
226         { IPPROTO_IPIP, "IPPROTO_IPIP"  },
227 #endif
228         { 0,            NULL            },
229 };
230 static struct xlat msg_flags[] = {
231         { MSG_OOB,      "MSG_OOB"       },
232 #ifdef MSG_DONTROUTE
233         { MSG_DONTROUTE,"MSG_DONTROUTE" },
234 #endif
235 #ifdef MSG_PEEK
236         { MSG_PEEK,     "MSG_PEEK"      },
237 #endif
238 #ifdef MSG_CTRUNC
239         { MSG_CTRUNC,   "MSG_CTRUNC"    },
240 #endif
241 #ifdef MSG_PROXY
242         { MSG_PROXY,    "MSG_PROXY"     },
243 #endif
244 #ifdef MSG_EOR
245         { MSG_EOR,      "MSG_EOR"       },
246 #endif
247 #ifdef MSG_WAITALL
248         { MSG_WAITALL,  "MSG_WAITALL"   },
249 #endif
250 #ifdef MSG_TRUNC
251         { MSG_TRUNC,    "MSG_TRUNC"     },
252 #endif
253 #ifdef MSG_CTRUNC
254         { MSG_CTRUNC,   "MSG_CTRUNC"    },
255 #endif
256 #ifdef MSG_ERRQUEUE
257         { MSG_ERRQUEUE, "MSG_ERRQUEUE"  },
258 #endif
259 #ifdef MSG_DONTWAIT
260         { MSG_DONTWAIT, "MSG_DONTWAIT"  },
261 #endif
262 #ifdef MSG_CONFIRM
263         { MSG_CONFIRM,  "MSG_CONFIRM"   },
264 #endif
265 #ifdef MSG_PROBE
266         { MSG_PROBE,    "MSG_PROBE"     },
267 #endif
268         { 0,            NULL            },
269 };
270
271 static struct xlat sockoptions[] = {
272 #ifdef SO_PEERCRED
273         { SO_PEERCRED,  "SO_PEERCRED"   },
274 #endif
275 #ifdef SO_PASSCRED
276         { SO_PASSCRED,  "SO_PASSCRED"   },
277 #endif
278 #ifdef SO_DEBUG
279         { SO_DEBUG,     "SO_DEBUG"      },
280 #endif
281 #ifdef SO_REUSEADDR
282         { SO_REUSEADDR, "SO_REUSEADDR"  },
283 #endif
284 #ifdef SO_KEEPALIVE
285         { SO_KEEPALIVE, "SO_KEEPALIVE"  },
286 #endif
287 #ifdef SO_DONTROUTE
288         { SO_DONTROUTE, "SO_DONTROUTE"  },
289 #endif
290 #ifdef SO_BROADCAST
291         { SO_BROADCAST, "SO_BROADCAST"  },
292 #endif
293 #ifdef SO_LINGER
294         { SO_LINGER,    "SO_LINGER"     },
295 #endif
296 #ifdef SO_OOBINLINE
297         { SO_OOBINLINE, "SO_OOBINLINE"  },
298 #endif
299 #ifdef SO_TYPE
300         { SO_TYPE,      "SO_TYPE"       },
301 #endif
302 #ifdef SO_ERROR
303         { SO_ERROR,     "SO_ERROR"      },
304 #endif
305 #ifdef SO_SNDBUF
306         { SO_SNDBUF,    "SO_SNDBUF"     },
307 #endif
308 #ifdef SO_RCVBUF
309         { SO_RCVBUF,    "SO_RCVBUF"     },
310 #endif
311 #ifdef SO_NO_CHECK
312         { SO_NO_CHECK,  "SO_NO_CHECK"   },
313 #endif
314 #ifdef SO_PRIORITY
315         { SO_PRIORITY,  "SO_PRIORITY"   },
316 #endif
317 #ifdef SO_ACCEPTCONN
318         { SO_ACCEPTCONN,"SO_ACCEPTCONN" },
319 #endif
320 #ifdef SO_USELOOPBACK
321         { SO_USELOOPBACK,"SO_USELOOPBACK"},
322 #endif
323 #ifdef SO_SNDLOWAT
324         { SO_SNDLOWAT,  "SO_SNDLOWAT"   },
325 #endif
326 #ifdef SO_RCVLOWAT
327         { SO_RCVLOWAT,  "SO_RCVLOWAT"   },
328 #endif
329 #ifdef SO_SNDTIMEO
330         { SO_SNDTIMEO,  "SO_SNDTIMEO"   },
331 #endif
332 #ifdef SO_RCVTIMEO
333         { SO_RCVTIMEO,  "SO_RCVTIMEO"   },
334 #endif
335 #ifdef SO_BSDCOMPAT
336         { SO_BSDCOMPAT, "SO_BSDCOMPAT"  },
337 #endif
338 #ifdef SO_REUSEPORT
339         { SO_REUSEPORT, "SO_REUSEPORT"  },
340 #endif
341 #ifdef SO_RCVLOWAT
342         { SO_RCVLOWAT, "SO_RCVLOWAT"    },
343 #endif
344 #ifdef SO_SNDLOWAT
345         { SO_SNDLOWAT, "SO_SNDLOWAT"    },
346 #endif
347 #ifdef SO_RCVTIMEO
348         { SO_RCVTIMEO, "SO_RCVTIMEO"    },
349 #endif
350 #ifdef SO_SNDTIMEO
351         { SO_SNDTIMEO, "SO_SNDTIMEO"    },
352 #endif
353         { 0,            NULL            },
354 };
355
356 #ifdef SOL_IP
357 static struct xlat sockipoptions[] = {
358         { IP_TOS,               "IP_TOS"                },
359         { IP_TTL,               "IP_TTL"                },
360 #if defined(IP_HDRINCL)
361         { IP_HDRINCL,           "IP_HDRINCL"            },
362 #endif
363 #if defined(IP_OPTIONS)
364         { IP_OPTIONS,           "IP_OPTIONS"            },
365 #endif
366         { IP_ROUTER_ALERT,      "IP_ROUTER_ALERT"       },
367 #if defined(IP_RECVOPTIONS)
368         { IP_RECVOPTIONS,       "IP_RECVOPTIONS"        },
369 #endif
370         { IP_RETOPTS,           "IP_RETOPTS"            },
371         { IP_PKTINFO,           "IP_PKTINFO"            },
372         { IP_PKTOPTIONS,        "IP_PKTOPTIONS" },
373         { IP_MTU_DISCOVER,      "IP_MTU_DISCOVER"       },
374         { IP_MTU_DISCOVER,      "IP_MTU_DISCOVER"       },
375         { IP_RECVERR,           "IP_RECVERR"            },
376         { IP_RECVTTL,           "IP_RECRECVTTL"         },
377         { IP_RECVTOS,           "IP_RECRECVTOS"         },
378 #if defined(IP_MTU)
379         { IP_MTU,               "IP_MTU"                },
380 #endif
381         { IP_MULTICAST_IF,      "IP_MULTICAST_IF"       },
382         { IP_MULTICAST_TTL,     "IP_MULTICAST_TTL"      },
383         { IP_MULTICAST_LOOP,    "IP_MULTICAST_LOOP"     },
384         { IP_ADD_MEMBERSHIP,    "IP_ADD_MEMBERSHIP"     },
385         { IP_DROP_MEMBERSHIP,   "IP_DROP_MEMBERSHIP"    },
386         { 0,                    NULL                    },
387 };
388 #endif /* SOL_IP */
389
390 #ifdef SOL_IPX
391 static struct xlat sockipxoptions[] = {
392         { IPX_TYPE,     "IPX_TYPE"      },
393         { 0,            NULL            },
394 };
395 #endif /* SOL_IPX */
396
397 #ifdef SOL_RAW
398 static struct xlat sockrawoptions[] = {
399 #if defined(ICMP_FILTER)
400         { ICMP_FILTER,          "ICMP_FILTER"   },
401 #endif
402         { 0,                    NULL            },
403 };
404 #endif /* SOL_RAW */
405
406 #ifdef SOL_PACKET
407 static struct xlat sockpacketoptions[] = {
408         { PACKET_ADD_MEMBERSHIP,        "PACKET_ADD_MEMBERSHIP" },
409         { PACKET_DROP_MEMBERSHIP,       "PACKET_DROP_MEMBERSHIP"},
410 #if defined(PACKET_RECV_OUTPUT)
411         { PACKET_RECV_OUTPUT,           "PACKET_RECV_OUTPUT"    },
412 #endif
413 #if defined(PACKET_RX_RING)
414         { PACKET_RX_RING,               "PACKET_RX_RING"        },
415 #endif
416 #if defined(PACKET_STATISTICS)
417         { PACKET_STATISTICS,            "PACKET_STATISTICS"     },
418 #endif
419         { 0,                            NULL                    },
420 };
421 #endif /* SOL_PACKET */
422
423 #ifdef SOL_TCP
424 static struct xlat socktcpoptions[] = {
425         { TCP_NODELAY,  "TCP_NODELAY"   },
426         { TCP_MAXSEG,   "TCP_MAXSEG"    },
427 #if defined(TCP_CORK)
428         { TCP_CORK,     "TCP_CORK"      },
429 #endif
430         { 0,            NULL            },
431 };
432 #endif /* SOL_TCP */
433
434 #ifdef SOL_RAW
435 static struct xlat icmpfilterflags[] = {
436 #if defined(ICMP_ECHOREPLY)
437         { (1<<ICMP_ECHOREPLY),          "ICMP_ECHOREPLY"        },
438 #endif
439 #if defined(ICMP_DEST_UNREACH)
440         { (1<<ICMP_DEST_UNREACH),       "ICMP_DEST_UNREACH"     },
441 #endif
442 #if defined(ICMP_SOURCE_QUENCH)
443         { (1<<ICMP_SOURCE_QUENCH),      "ICMP_SOURCE_QUENCH"    },
444 #endif
445 #if defined(ICMP_REDIRECT)
446         { (1<<ICMP_REDIRECT),           "ICMP_REDIRECT"         },
447 #endif
448 #if defined(ICMP_ECHO)
449         { (1<<ICMP_ECHO),               "ICMP_ECHO"             },
450 #endif
451 #if defined(ICMP_TIME_EXCEEDED)
452         { (1<<ICMP_TIME_EXCEEDED),      "ICMP_TIME_EXCEEDED"    },
453 #endif
454 #if defined(ICMP_PARAMETERPROB)
455         { (1<<ICMP_PARAMETERPROB),      "ICMP_PARAMETERPROB"    },
456 #endif
457 #if defined(ICMP_TIMESTAMP)
458         { (1<<ICMP_TIMESTAMP),          "ICMP_TIMESTAMP"        },
459 #endif
460 #if defined(ICMP_TIMESTAMPREPLY)
461         { (1<<ICMP_TIMESTAMPREPLY),     "ICMP_TIMESTAMPREPLY"   },
462 #endif
463 #if defined(ICMP_INFO_REQUEST)
464         { (1<<ICMP_INFO_REQUEST),       "ICMP_INFO_REQUEST"     },
465 #endif
466 #if defined(ICMP_INFO_REPLY)
467         { (1<<ICMP_INFO_REPLY),         "ICMP_INFO_REPLY"       },
468 #endif
469 #if defined(ICMP_ADDRESS)
470         { (1<<ICMP_ADDRESS),            "ICMP_ADDRESS"          },
471 #endif
472 #if defined(ICMP_ADDRESSREPLY)
473         { (1<<ICMP_ADDRESSREPLY),       "ICMP_ADDRESSREPLY"     },
474 #endif
475         { 0,                            NULL                    },
476 };
477 #endif /* SOL_RAW */
478
479 void
480 printsock(tcp, addr, addrlen)
481 struct tcb *tcp;
482 long addr;
483 int addrlen;
484 {
485         union {
486                 char pad[128];
487                 struct sockaddr sa;
488                 struct sockaddr_in sin;
489                 struct sockaddr_un sau;
490 #ifdef HAVE_INET_NTOP
491                 struct sockaddr_in6 sa6;
492 #endif
493 #if defined(LINUX) && defined(AF_IPX)
494                 struct sockaddr_ipx sipx;
495 #endif
496 #ifdef AF_PACKET
497                 struct sockaddr_ll ll;
498 #endif
499 #ifdef AF_NETLINK
500                 struct sockaddr_nl nl;
501 #endif
502         } addrbuf;
503         char string_addr[100];
504
505         if (addr == 0) {
506                 tprintf("NULL");
507                 return;
508         }
509         if (!verbose(tcp)) {
510                 tprintf("%#lx", addr);
511                 return;
512         }
513         if ((addrlen<2) || (addrlen>sizeof(addrbuf)))
514                 addrlen=sizeof(addrbuf);
515
516         if (umoven(tcp, addr, addrlen, (char*)&addrbuf) < 0) {
517                 tprintf("{...}");
518                 return;
519         }
520
521         tprintf("{sin_family=");
522         printxval(addrfams, addrbuf.sa.sa_family, "AF_???");
523         tprintf(", ");
524
525         switch (addrbuf.sa.sa_family) {
526         case AF_UNIX:
527                 if (addrlen==2) {
528                         tprintf("<nil>");
529                 } else if (addrbuf.sau.sun_path[0]) {
530                         tprintf("path=\"%*.*s\"", addrlen-2, addrlen-2, addrbuf.sau.sun_path);
531                 } else {
532                         tprintf("path=@%*.*s", addrlen-3, addrlen-3, addrbuf.sau.sun_path+1);
533                 }
534                 break;
535         case AF_INET:
536                 tprintf("sin_port=htons(%u), sin_addr=inet_addr(\"%s\")}",
537                         ntohs(addrbuf.sin.sin_port), inet_ntoa(addrbuf.sin.sin_addr));
538                 break;
539 #ifdef HAVE_INET_NTOP
540         case AF_INET6:
541                 inet_ntop(AF_INET6, &addrbuf.sa6.sin6_addr, string_addr, sizeof(string_addr));
542                 tprintf("sin6_port=htons(%u), inet_pton(AF_INET6, \"%s\", &sin6_addr), sin6_flowinfo=htonl(%u)}",
543                         ntohs(addrbuf.sa6.sin6_port), string_addr, ntohl(addrbuf.sa6.sin6_flowinfo));
544                 break;  
545 #endif
546 #if defined(AF_IPX) && defined(linux)
547         case AF_IPX:
548                 {
549                         int i;
550                         tprintf("{sipx_port=htons(%u), ",
551                                         ntohs(addrbuf.sipx.sipx_port));
552                         /* Yes, I know, this does not look too
553                          * strace-ish, but otherwise the IPX
554                          * addresses just look monstrous...
555                          * Anyways, feel free if you don't like
556                          * this way.. :) 
557                          */
558                         tprintf("%08lx:", (unsigned long)ntohl(addrbuf.sipx.sipx_network));
559                         for (i = 0; i<IPX_NODE_LEN; i++)
560                                 tprintf("%02x", addrbuf.sipx.sipx_node[i]);
561                         tprintf("/[%02x]", addrbuf.sipx.sipx_type);
562                 }
563                 break;
564 #endif /* AF_IPX && linux */
565 #ifdef AF_PACKET
566         case AF_PACKET:
567                 {
568                         int i;
569                         tprintf("proto=%#04x, if%d, pkttype=%d, addr(%d)={%d, ",
570                                         ntohs(addrbuf.ll.sll_protocol),
571                                         addrbuf.ll.sll_ifindex,
572                                         addrbuf.ll.sll_pkttype,
573                                         addrbuf.ll.sll_halen,
574                                         addrbuf.ll.sll_hatype);
575                         for (i=0; i<addrbuf.ll.sll_addr[i]; i++) 
576                                 tprintf("%02x", addrbuf.ll.sll_addr[i]);
577                 }
578                 break;
579
580 #endif /* AF_APACKET */
581 #ifdef AF_NETLINLK
582         case AF_NETLINK:
583                 tprintf("pid=%d, groups=%08x", addrbuf.nl.nl_pid, addrbuf.nl.nl_groups);
584                 break;
585 #endif /* AF_NETLINK */
586         /* AF_AX25 AF_APPLETALK AF_NETROM AF_BRIDGE AF_AAL5
587         AF_X25 AF_ROSE etc. still need to be done */
588
589         default:
590                 tprintf("{sa_family=%u, sa_data=", addrbuf.sa.sa_family);
591                 printstr(tcp, (long) &((struct sockaddr *) addr)->sa_data,
592                         sizeof addrbuf.sa.sa_data);
593                 break;
594         }
595         tprintf("}");
596 }
597
598 #if HAVE_SENDMSG
599
600 static void
601 printiovec(tcp, iovec, len)
602 struct tcb *tcp;
603 struct iovec *iovec;
604 long   len;
605 {
606         struct iovec *iov;
607         int i;
608
609         iov = (struct iovec *) malloc(len * sizeof *iov);
610         if (iov == NULL) {
611                 fprintf(stderr, "No memory");
612                 return;
613         }
614         if (umoven(tcp, (long)iovec,
615                                 len * sizeof *iov, (char *) iov) < 0) {
616                 tprintf("%#lx", (unsigned long)iovec);
617         } else {
618                 tprintf("[");
619                 for (i = 0; i < len; i++) {
620                         if (i)
621                                 tprintf(", ");
622                         tprintf("{");
623                         printstr(tcp, (long) iov[i].iov_base,
624                                         iov[i].iov_len);
625                         tprintf(", %lu}", (unsigned long)iov[i].iov_len);
626                 }
627                 tprintf("]");
628         }
629         free((char *) iov);
630 }
631
632 static void
633 printmsghdr(tcp, addr)
634 struct tcb *tcp;
635 long addr;
636 {
637         struct msghdr msg;
638
639         if (umove(tcp, addr, &msg) < 0) {
640                 tprintf("%#lx", addr);
641                 return;
642         }
643         tprintf("{msg_name(%d)=", msg.msg_namelen);
644         printsock(tcp, (long)msg.msg_name, msg.msg_namelen);
645
646         tprintf(", msg_iov(%lu)=", (unsigned long)msg.msg_iovlen);
647         printiovec(tcp, msg.msg_iov, msg.msg_iovlen);
648
649 #ifdef HAVE_MSG_CONTROL
650         tprintf(", msg_controllen=%lu", (unsigned long)msg.msg_controllen);
651         if (msg.msg_controllen) 
652                 tprintf(", msg_control=%#lx, ", (unsigned long) msg.msg_control);
653         tprintf(", msg_flags=");
654         if (printflags(msg_flags, msg.msg_flags)==0)
655                 tprintf("0");
656 #else /* !HAVE_MSG_CONTROL */
657         tprintf("msg_accrights=%#lx, msg_accrightslen=%u",
658                 (unsigned long) msg.msg_accrights, msg.msg_accrightslen);
659 #endif /* !HAVE_MSG_CONTROL */
660         tprintf("}");
661 }
662
663 #endif /* HAVE_SENDMSG */
664
665 int
666 sys_socket(tcp)
667 struct tcb *tcp;
668 {
669         if (entering(tcp)) {
670                 printxval(domains, tcp->u_arg[0], "PF_???");
671                 tprintf(", ");
672                 printxval(socktypes, tcp->u_arg[1], "SOCK_???");
673                 tprintf(", ");
674                 switch (tcp->u_arg[0]) {
675                 case PF_INET:
676                         printxval(protocols, tcp->u_arg[2], "IPPROTO_???");
677                         break;
678 #ifdef PF_IPX
679                 case PF_IPX:
680                         /* BTW: I don't believe this.. */
681                         tprintf("[");
682                         printxval(domains, tcp->u_arg[2], "PF_???");
683                         tprintf("]");
684                         break;
685 #endif /* PF_IPX */
686                 default:
687                         tprintf("%lu", tcp->u_arg[2]);
688                         break;
689                 }
690         }
691         return 0;
692 }
693
694 int
695 sys_bind(tcp)
696 struct tcb *tcp;
697 {
698         if (entering(tcp)) {
699                 tprintf("%ld, ", tcp->u_arg[0]);
700                 printsock(tcp, tcp->u_arg[1], tcp->u_arg[2]);
701                 tprintf(", %lu", tcp->u_arg[2]);
702         }
703         return 0;
704 }
705
706 int
707 sys_connect(tcp)
708 struct tcb *tcp;
709 {
710         return sys_bind(tcp);
711 }
712
713 int
714 sys_listen(tcp)
715 struct tcb *tcp;
716 {
717         if (entering(tcp)) {
718                 tprintf("%ld, %lu", tcp->u_arg[0], tcp->u_arg[1]);
719         }
720         return 0;
721 }
722
723 int
724 sys_accept(tcp)
725 struct tcb *tcp;
726 {
727         if (entering(tcp)) {
728                 tprintf("%ld, ", tcp->u_arg[0]);
729         } else if (!tcp->u_arg[2])
730                 tprintf("%#lx, NULL", tcp->u_arg[1]);
731         else {
732                 if (tcp->u_arg[1] == 0 || syserror(tcp)) {
733                         tprintf("%#lx", tcp->u_arg[1]);
734                 } else {
735                         printsock(tcp, tcp->u_arg[1], tcp->u_arg[2]);
736                 }
737                 tprintf(", ");
738                 printnum(tcp, tcp->u_arg[2], "%lu");
739         }
740         return 0;
741 }
742
743 int
744 sys_send(tcp)
745 struct tcb *tcp;
746 {
747         if (entering(tcp)) {
748                 tprintf("%ld, ", tcp->u_arg[0]);
749                 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
750                 tprintf(", %lu, ", tcp->u_arg[2]);
751                 /* flags */
752                 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
753                         tprintf("0");
754         }
755         return 0;
756 }
757
758 int
759 sys_sendto(tcp)
760 struct tcb *tcp;
761 {
762         if (entering(tcp)) {
763                 tprintf("%ld, ", tcp->u_arg[0]);
764                 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
765                 tprintf(", %lu, ", tcp->u_arg[2]);
766                 /* flags */
767                 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
768                         tprintf("0");
769                 /* to address */
770                 tprintf(", ");
771                 printsock(tcp, tcp->u_arg[4], tcp->u_arg[5]);
772                 /* to length */
773                 tprintf(", %lu", tcp->u_arg[5]);
774         }
775         return 0;
776 }
777
778 #ifdef HAVE_SENDMSG
779
780 int
781 sys_sendmsg(tcp)
782 struct tcb *tcp;
783 {
784         if (entering(tcp)) {
785                 tprintf("%ld, ", tcp->u_arg[0]);
786                 printmsghdr(tcp, tcp->u_arg[1]);
787                 /* flags */
788                 tprintf(", ");
789                 if (printflags(msg_flags, tcp->u_arg[2]) == 0)
790                         tprintf("0");
791         }
792         return 0;
793 }
794
795 #endif /* HAVE_SENDMSG */
796
797 int
798 sys_recv(tcp)
799 struct tcb *tcp;
800 {
801         if (entering(tcp)) {
802                 tprintf("%ld, ", tcp->u_arg[0]);
803         } else {
804                 if (syserror(tcp))
805                         tprintf("%#lx", tcp->u_arg[1]);
806                 else
807                         printstr(tcp, tcp->u_arg[1], tcp->u_rval);
808
809                 tprintf(", %lu, ", tcp->u_arg[2]);
810                 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
811                         tprintf("0");
812         }
813         return 0;
814 }
815
816 int
817 sys_recvfrom(tcp)
818 struct tcb *tcp;
819 {
820         int fromlen;
821
822         if (entering(tcp)) {
823                 tprintf("%ld, ", tcp->u_arg[0]);
824         } else {
825                 if (syserror(tcp)) {
826                         tprintf("%#lx, %lu, %lu, %#lx, %#lx",
827                                 tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3],
828                                 tcp->u_arg[4], tcp->u_arg[5]);
829                         return 0;
830                 }
831                 /* buf */
832                 printstr(tcp, tcp->u_arg[1], tcp->u_rval);
833                 /* len */
834                 tprintf(", %lu, ", tcp->u_arg[2]);
835                 /* flags */
836                 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
837                         tprintf("0");
838                 /* from address, len */
839                 if (!tcp->u_arg[4] || !tcp->u_arg[5]) {
840                         if (tcp->u_arg[4] == 0)
841                                 tprintf(", NULL");
842                         else
843                                 tprintf(", %#lx", tcp->u_arg[4]);
844                         if (tcp->u_arg[5] == 0)
845                                 tprintf(", NULL");
846                         else
847                                 tprintf(", %#lx", tcp->u_arg[5]);
848                         return 0;
849                 }
850                 if (umove(tcp, tcp->u_arg[5], &fromlen) < 0) {
851                         tprintf(", {...}, [?]");
852                         return 0;
853                 }
854                 tprintf(", ");
855                 printsock(tcp, tcp->u_arg[4], tcp->u_arg[5]);
856                 /* from length */
857                 tprintf(", [%u]", fromlen);
858         }
859         return 0;
860 }
861
862 #ifdef HAVE_SENDMSG
863
864 int
865 sys_recvmsg(tcp)
866 struct tcb *tcp;
867 {
868         if (entering(tcp)) {
869                 tprintf("%ld, ", tcp->u_arg[0]);
870         } else {
871                 if (syserror(tcp) || !verbose(tcp))
872                         tprintf("%#lx", tcp->u_arg[1]);
873                 else
874                         printmsghdr(tcp, tcp->u_arg[1]);
875                 /* flags */
876                 tprintf(", ");
877                 if (printflags(msg_flags, tcp->u_arg[2]) == 0)
878                         tprintf("0");
879         }
880         return 0;
881 }
882
883 #endif /* HAVE_SENDMSG */
884
885 int
886 sys_shutdown(tcp)
887 struct tcb *tcp;
888 {
889         if (entering(tcp)) {
890                 tprintf("%ld, %ld", tcp->u_arg[0], tcp->u_arg[1]);
891                 switch (tcp->u_arg[1]) {
892                 case 0:
893                         tprintf("%s", " /* receive */");
894                         break;
895                 case 1:
896                         tprintf("%s", " /* send */");
897                         break;
898                 case 2:
899                         tprintf("%s", " /* send and receive */");
900                         break;
901                 }
902         }
903         return 0;
904 }
905
906 int
907 sys_getsockname(tcp)
908 struct tcb *tcp;
909 {
910         return sys_accept(tcp);
911 }
912
913 int
914 sys_getpeername(tcp)
915 struct tcb *tcp;
916 {
917         return sys_accept(tcp);
918 }
919
920 int
921 sys_pipe(tcp)
922 struct tcb *tcp;
923 {
924
925 #if defined(LINUX) && !defined(SPARC)
926         int fds[2];
927
928         if (exiting(tcp)) {
929                 if (syserror(tcp)) {
930                         tprintf("%#lx", tcp->u_arg[0]);
931                         return 0;
932                 }
933                 if (umoven(tcp, tcp->u_arg[0], sizeof fds, (char *) fds) < 0)
934                         tprintf("[...]");
935                 else
936                         tprintf("[%u, %u]", fds[0], fds[1]);
937         }
938 #elif defined(SPARC) || defined(SVR4)
939         if (exiting(tcp))
940                 tprintf("[%lu, %lu]", tcp->u_rval, getrval2(tcp));
941 #endif
942         return 0;
943 }
944
945 int
946 sys_socketpair(tcp)
947 struct tcb *tcp;
948 {
949 #ifdef LINUX
950         int fds[2];
951 #endif
952
953         if (entering(tcp)) {
954                 printxval(domains, tcp->u_arg[0], "PF_???");
955                 tprintf(", ");
956                 printxval(socktypes, tcp->u_arg[1], "SOCK_???");
957                 tprintf(", ");
958                 switch (tcp->u_arg[0]) {
959                 case PF_INET:
960                         printxval(protocols, tcp->u_arg[2], "IPPROTO_???");
961                         break;
962 #ifdef PF_IPX
963                 case PF_IPX:
964                         /* BTW: I don't believe this.. */
965                         tprintf("[");
966                         printxval(domains, tcp->u_arg[2], "PF_???");
967                         tprintf("]");
968                         break;
969 #endif /* PF_IPX */
970                 default:        
971                         tprintf("%lu", tcp->u_arg[2]);
972                         break;
973                 }
974         } else {
975                 if (syserror(tcp)) {
976                         tprintf(", %#lx", tcp->u_arg[3]);
977                         return 0;
978                 }
979 #ifdef LINUX
980                 if (umoven(tcp, tcp->u_arg[3], sizeof fds, (char *) fds) < 0)
981                         tprintf(", [...]");
982                 else
983                         tprintf(", [%u, %u]", fds[0], fds[1]);
984 #endif /* LINUX */
985 #ifdef SUNOS4
986                 tprintf(", [%lu, %lu]", tcp->u_rval, getrval2(tcp));
987 #endif /* SUNOS4 */
988 #ifdef SVR4
989                 tprintf(", [%lu, %lu]", tcp->u_rval, getrval2(tcp));
990 #endif /* SVR4 */
991         }
992         return 0;
993 }
994
995 int
996 sys_getsockopt(tcp)
997 struct tcb *tcp;
998 {
999         if (entering(tcp)) {
1000                 tprintf("%ld, ", tcp->u_arg[0]);
1001                 switch (tcp->u_arg[1]) {
1002                 case SOL_SOCKET:
1003                         tprintf("SOL_SOCKET, ");
1004                         printxval(sockoptions, tcp->u_arg[2], "SO_???");
1005                         tprintf(", ");
1006                         break;
1007 #ifdef SOL_IP
1008                 case SOL_IP:
1009                         tprintf("SOL_IP, ");
1010                         printxval(sockipoptions, tcp->u_arg[2], "IP_???");
1011                         tprintf(", ");
1012                         break;
1013 #endif
1014 #ifdef SOL_IPX
1015                 case SOL_IPX:
1016                         tprintf("SOL_IPX, ");
1017                         printxval(sockipxoptions, tcp->u_arg[2], "IPX_???");
1018                         tprintf(", ");
1019                         break;
1020 #endif
1021 #ifdef SOL_PACKET
1022                 case SOL_PACKET:
1023                         tprintf("SOL_PACKET, ");
1024                         printxval(sockpacketoptions, tcp->u_arg[2], "PACKET_???");
1025                         tprintf(", ");
1026                         break;
1027 #endif
1028 #ifdef SOL_TCP
1029                 case SOL_TCP:
1030                         tprintf("SOL_TCP, ");
1031                         printxval(socktcpoptions, tcp->u_arg[2], "TCP_???");
1032                         tprintf(", ");
1033                         break;
1034 #endif
1035
1036                 /* SOL_AX25 SOL_ROSE SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25
1037                  * etc. still need work */
1038                 default: 
1039                         /* XXX - should know socket family here */
1040                         printxval(protocols, tcp->u_arg[1], "IPPROTO_???");
1041                         tprintf(", %lu, ", tcp->u_arg[2]);
1042                         break;
1043                 }
1044         } else {
1045                 if (syserror(tcp)) {
1046                         tprintf("%#lx, %#lx",
1047                                 tcp->u_arg[3], tcp->u_arg[4]);
1048                         return 0;
1049                 }
1050                 printnum(tcp, tcp->u_arg[3], "%ld");
1051                 tprintf(", ");
1052                 printnum(tcp, tcp->u_arg[4], "%ld");
1053         }
1054         return 0;
1055 }
1056
1057 #if defined(ICMP_FILTER)
1058 static void printicmpfilter(tcp, addr)
1059 struct tcb *tcp;
1060 long addr;
1061 {
1062         struct icmp_filter      filter;
1063
1064         if (!addr) {
1065                 tprintf("NULL");
1066                 return;
1067         }
1068         if (syserror(tcp) || !verbose(tcp)) {
1069                 tprintf("%#lx", addr);
1070                 return;
1071         }
1072         if (umove(tcp, addr, &filter) < 0) {
1073                 tprintf("{...}");
1074                 return;
1075         }
1076
1077         tprintf("~(");
1078         if (printflags(icmpfilterflags, ~filter.data) == 0)
1079                 tprintf("0");
1080         tprintf(")");
1081 }
1082 #endif /* ICMP_FILTER */
1083
1084 int
1085 sys_setsockopt(tcp)
1086 struct tcb *tcp;
1087 {
1088         if (entering(tcp)) {
1089                 tprintf("%ld, ", tcp->u_arg[0]);
1090                 switch (tcp->u_arg[1]) {
1091                 case SOL_SOCKET:
1092                         tprintf("SOL_SOCKET, ");
1093                         printxval(sockoptions, tcp->u_arg[2], "SO_???");
1094                         tprintf(", ");
1095                         printnum(tcp, tcp->u_arg[3], "%ld");
1096                         tprintf(", %lu", tcp->u_arg[4]);
1097                         break;
1098 #ifdef SOL_IP
1099                 case SOL_IP:
1100                         tprintf("SOL_IP, ");
1101                         printxval(sockipoptions, tcp->u_arg[2], "IP_???");
1102                         tprintf(", ");
1103                         printnum(tcp, tcp->u_arg[3], "%ld");
1104                         tprintf(", %lu", tcp->u_arg[4]);
1105                         break;
1106 #endif
1107 #ifdef SOL_IPX
1108                 case SOL_IPX:
1109                         tprintf("SOL_IPX, ");
1110                         printxval(sockipxoptions, tcp->u_arg[2], "IPX_???");
1111                         tprintf(", ");
1112                         printnum(tcp, tcp->u_arg[3], "%ld");
1113                         tprintf(", %lu", tcp->u_arg[4]);
1114                         break;
1115 #endif
1116 #ifdef SOL_PACKET
1117                 case SOL_PACKET:
1118                         tprintf("SOL_PACKET, ");
1119                         printxval(sockpacketoptions, tcp->u_arg[2], "PACKET_???");
1120                         tprintf(", ");
1121                         /* TODO: decode packate_mreq for PACKET_*_MEMBERSHIP */
1122                         printnum(tcp, tcp->u_arg[3], "%ld");
1123                         tprintf(", %lu", tcp->u_arg[4]);
1124                         break;
1125 #endif
1126 #ifdef SOL_TCP
1127                 case SOL_TCP:
1128                         tprintf("SOL_TCP, ");
1129                         printxval(socktcpoptions, tcp->u_arg[2], "TCP_???");
1130                         tprintf(", ");
1131                         printnum(tcp, tcp->u_arg[3], "%ld");
1132                         tprintf(", %lu", tcp->u_arg[4]);
1133                         break;
1134 #endif
1135 #ifdef SOL_RAW
1136                 case SOL_RAW:
1137                         tprintf("SOL_RAW, ");
1138                         printxval(sockrawoptions, tcp->u_arg[2], "RAW_???");
1139                         tprintf(", ");
1140                         switch (tcp->u_arg[2]) {
1141 #if defined(ICMP_FILTER)
1142                                 case ICMP_FILTER:
1143                                         printicmpfilter(tcp, tcp->u_arg[3]);
1144                                         break;
1145 #endif
1146                                 default:
1147                                         printnum(tcp, tcp->u_arg[3], "%ld");
1148                                         break;
1149                         }
1150                         tprintf(", %lu", tcp->u_arg[4]);
1151                         break;
1152 #endif
1153
1154                 /* SOL_AX25 SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25 
1155                  * etc. still need work  */
1156                 default:
1157                         /* XXX - should know socket family here */
1158                         printxval(protocols, tcp->u_arg[1], "IPPROTO_???");
1159                         tprintf("%lu, ", tcp->u_arg[2]);
1160                         printnum(tcp, tcp->u_arg[3], "%ld");
1161                         tprintf(", %lu", tcp->u_arg[4]);
1162                         break;
1163                 }
1164         }
1165         return 0;
1166 }