]> granicus.if.org Git - strace/blob - net.c
e22056b35bcd050cec4529203d6246d174df265f
[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
39 #if defined(HAVE_SIN6_SCOPE_ID_LINUX)
40 #define in6_addr in6_addr_libc
41 #define ipv6_mreq ipv6_mreq_libc
42 #define sockaddr_in6 sockaddr_in6_libc
43 #endif
44
45 #include <netinet/in.h>
46 #ifdef HAVE_NETINET_TCP_H
47 #include <netinet/tcp.h>
48 #endif
49 #ifdef HAVE_NETINET_UDP_H
50 #include <netinet/udp.h>
51 #endif
52 #include <arpa/inet.h>
53 #include <net/if.h>
54 #if defined(LINUX)
55 #include <asm/types.h>
56 #if defined(__GLIBC__) && (__GLIBC__ >= 2) && (__GLIBC__ + __GLIBC_MINOR__ >= 3)
57 #  include <netipx/ipx.h>
58 #else
59 #  include <linux/ipx.h>
60 #endif
61 #endif /* LINUX */
62
63 #if defined (__GLIBC__) && (((__GLIBC__ < 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 1)) || defined(HAVE_SIN6_SCOPE_ID_LINUX))
64 #if defined(HAVE_LINUX_IN6_H)
65 #if defined(HAVE_SIN6_SCOPE_ID_LINUX)
66 #undef in6_addr
67 #undef ipv6_mreq
68 #undef sockaddr_in6
69 #define in6_addr in6_addr_kernel
70 #define ipv6_mreq ipv6_mreq_kernel
71 #define sockaddr_in6 sockaddr_in6_kernel
72 #endif
73 #include <linux/in6.h>
74 #if defined(HAVE_SIN6_SCOPE_ID_LINUX)
75 #undef in6_addr
76 #undef ipv6_mreq
77 #undef sockaddr_in6
78 #define in6_addr in6_addr_libc
79 #define ipv6_mreq ipv6_mreq_libc
80 #define sockaddr_in6 sockaddr_in6_kernel
81 #endif
82 #endif
83 #endif
84
85 #if defined(HAVE_SYS_UIO_H)
86 #include <sys/uio.h>
87 #endif
88
89 #if defined(HAVE_LINUX_NETLINK_H)
90 #include <linux/netlink.h>
91 #endif
92
93 #if defined(HAVE_LINUX_IF_PACKET_H)
94 #include <linux/if_packet.h>
95 #endif
96
97 #if defined(HAVE_LINUX_ICMP_H)
98 #include <linux/icmp.h>
99 #endif
100
101 #ifndef PF_UNSPEC
102 #define PF_UNSPEC AF_UNSPEC
103 #endif
104
105 #if UNIXWARE >= 7
106 #define HAVE_SENDMSG            1               /* HACK - *FIXME* */
107 #endif
108
109 #ifdef LINUX
110 /* Under Linux these are enums so we can't test for them with ifdef. */
111 #define IPPROTO_EGP IPPROTO_EGP
112 #define IPPROTO_PUP IPPROTO_PUP
113 #define IPPROTO_IDP IPPROTO_IDP
114 #define IPPROTO_IGMP IPPROTO_IGMP
115 #define IPPROTO_RAW IPPROTO_RAW
116 #define IPPROTO_MAX IPPROTO_MAX
117 #endif
118
119 static struct xlat domains[] = {
120         { PF_UNSPEC,    "PF_UNSPEC"     },
121         { PF_UNIX,      "PF_UNIX"       },
122         { PF_INET,      "PF_INET"       },
123 #ifdef PF_NETLINK
124         { PF_NETLINK,   "PF_NETLINK"    },
125 #endif
126 #ifdef PF_PACKET
127         { PF_PACKET,    "PF_PACKET"     },
128 #endif
129 #ifdef PF_INET6
130         { PF_INET6,     "PF_INET6"      },
131 #endif
132 #ifdef PF_ATMSVC
133         { PF_ATMSVC,    "PF_INET6"      },
134 #endif
135 #ifdef PF_INET6
136         { PF_INET6,     "PF_INET6"      },
137 #endif
138 #ifdef PF_LOCAL
139         { PF_LOCAL,     "PS_LOCAL"      },
140 #endif
141 #ifdef PF_ISO
142         { PF_ISO,       "PF_ISO"        },
143 #endif
144 #ifdef PF_AX25
145         { PF_AX25,      "PF_AX25"       },
146 #endif
147 #ifdef PF_IPX
148         { PF_IPX,       "PF_IPX"        },
149 #endif
150 #ifdef PF_APPLETALK
151         { PF_APPLETALK, "PF_APPLETALK"  },
152 #endif
153 #ifdef PF_NETROM
154         { PF_NETROM,    "PF_NETROM"     },
155 #endif
156 #ifdef PF_BRIDGE
157         { PF_BRIDGE,    "PF_BRIDGE"     },
158 #endif
159 #ifdef PF_AAL5
160         { PF_AAL5,      "PF_AAL5"       },
161 #endif
162 #ifdef PF_X25
163         { PF_X25,       "PF_X25"        },
164 #endif
165 #ifdef PF_ROSE
166         { PF_ROSE,      "PF_ROSE"       },
167 #endif
168 #ifdef PF_DECNET
169         { PF_DECNET,    "PF_DECNET"     },
170 #endif
171 #ifdef PF_NETBEUI
172         { PF_NETBEUI,   "PF_NETBEUI"    },
173 #endif
174 #ifdef PF_IMPLINK
175         { PF_IMPLINK,   "PF_IMPLINK"    },
176 #endif
177         { 0,            NULL            },
178 };
179 static struct xlat addrfams[] = {
180         { AF_UNSPEC,    "AF_UNSPEC"     },
181         { AF_UNIX,      "AF_UNIX"       },
182         { AF_INET,      "AF_INET"       },
183 #ifdef AF_INET6
184         { AF_INET6,     "AF_INET6"      },
185 #endif
186         { AF_DECnet,    "AF_DECnet"     },
187 #ifdef PF_ATMSVC
188         { AF_ATMSVC,    "AF_ATMSVC"     },
189 #endif
190 #ifdef AF_PACKET
191         { AF_PACKET,    "AF_PACKET"     },
192 #endif
193 #ifdef AF_NETLINK
194         { AF_NETLINK,   "AF_NETLINK"    },
195 #endif
196 #ifdef AF_ISO
197         { AF_ISO,       "AF_ISO"        },
198 #endif
199 #ifdef AF_IMPLINK
200         { AF_IMPLINK,   "AF_IMPLINK"    },
201 #endif
202         { 0,            NULL            },
203 };
204 static struct xlat socktypes[] = {
205         { SOCK_STREAM,  "SOCK_STREAM"   },
206         { SOCK_DGRAM,   "SOCK_DGRAM"    },
207 #ifdef SOCK_RAW
208         { SOCK_RAW,     "SOCK_RAW"      },
209 #endif
210 #ifdef SOCK_SEQPACKET
211         { SOCK_SEQPACKET,"SOCK_SEQPACKET"},
212 #endif
213 #ifdef SOCK_RDM
214         { SOCK_RDM,     "SOCK_RDM"      },
215 #endif
216 #ifdef SOCK_PACKET
217         { SOCK_PACKET,  "SOCK_PACKET"   },
218 #endif
219         { 0,            NULL            },
220 };
221 static struct xlat socketlayers[] = {
222 #if defined(SOL_IP)
223         { SOL_IP,       "SOL_IP"        },
224 #endif
225 #if defined(SOL_ICMP)
226         { SOL_ICMP,     "SOL_ICMP"      },
227 #endif
228 #if defined(SOL_TCP)
229         { SOL_TCP,      "SOL_TCP"       },
230 #endif
231 #if defined(SOL_UDP)
232         { SOL_UDP,      "SOL_UDP"       },
233 #endif
234 #if defined(SOL_IPV6)
235         { SOL_IPV6,     "SOL_IPV6"      },
236 #endif
237 #if defined(SOL_ICMPV6)
238         { SOL_ICMPV6,   "SOL_ICMPV6"    },
239 #endif
240 #if defined(SOL_RAW)
241         { SOL_RAW,      "SOL_RAW"       },
242 #endif
243 #if defined(SOL_IPX)
244         { SOL_IPX,      "SOL_IPX"       },
245 #endif
246 #if defined(SOL_IPX)
247         { SOL_IPX,      "SOL_IPX"       },
248 #endif
249 #if defined(SOL_AX25)
250         { SOL_AX25,     "SOL_AX25"      },
251 #endif
252 #if defined(SOL_ATALK)
253         { SOL_ATALK,    "SOL_ATALK"     },
254 #endif
255 #if defined(SOL_NETROM)
256         { SOL_NETROM,   "SOL_NETROM"    },
257 #endif
258 #if defined(SOL_ROSE)
259         { SOL_ROSE,     "SOL_ROSE"      },
260 #endif
261 #if defined(SOL_DECNET)
262         { SOL_DECNET,   "SOL_DECNET"    },
263 #endif
264 #if defined(SOL_X25)
265         { SOL_X25,      "SOL_X25"       },
266 #endif
267 #if defined(SOL_PACKET)
268         { SOL_PACKET,   "SOL_PACKET"    },
269 #endif
270 #if defined(SOL_ATM)
271         { SOL_ATM,      "SOL_ATM"       },
272 #endif
273 #if defined(SOL_AAL)
274         { SOL_AAL,      "SOL_AAL"       },
275 #endif
276 #if defined(SOL_IRDA)
277         { SOL_IRDA,     "SOL_IRDA"      },
278 #endif
279         { SOL_SOCKET,   "SOL_SOCKET"    },      /* Never used! */
280 };
281 static struct xlat protocols[] = {
282         { IPPROTO_IP,   "IPPROTO_IP"    },
283         { IPPROTO_ICMP, "IPPROTO_ICMP"  },
284         { IPPROTO_TCP,  "IPPROTO_TCP"   },
285         { IPPROTO_UDP,  "IPPROTO_UDP"   },
286 #ifdef IPPROTO_GGP
287         { IPPROTO_GGP,  "IPPROTO_GGP"   },
288 #endif
289 #ifdef IPPROTO_EGP
290         { IPPROTO_EGP,  "IPPROTO_EGP"   },
291 #endif
292 #ifdef IPPROTO_PUP
293         { IPPROTO_PUP,  "IPPROTO_PUP"   },
294 #endif
295 #ifdef IPPROTO_IDP
296         { IPPROTO_IDP,  "IPPROTO_IDP"   },
297 #endif
298 #ifdef IPPROTO_IPV6
299         { IPPROTO_IPV6, "IPPROTO_IPV6"  },
300 #endif
301 #ifdef IPPROTO_ICMPV6
302         { IPPROTO_ICMPV6,"IPPROTO_ICMPV6"},
303 #endif
304 #ifdef IPPROTO_IGMP
305         { IPPROTO_IGMP, "IPPROTO_IGMP"  },
306 #endif
307 #ifdef IPPROTO_HELLO
308         { IPPROTO_HELLO,"IPPROTO_HELLO" },
309 #endif
310 #ifdef IPPROTO_ND
311         { IPPROTO_ND,   "IPPROTO_ND"    },
312 #endif
313 #ifdef IPPROTO_RAW
314         { IPPROTO_RAW,  "IPPROTO_RAW"   },
315 #endif
316 #ifdef IPPROTO_MAX
317         { IPPROTO_MAX,  "IPPROTO_MAX"   },
318 #endif
319 #ifdef IPPROTO_IPIP
320         { IPPROTO_IPIP, "IPPROTO_IPIP"  },
321 #endif
322         { 0,            NULL            },
323 };
324 static struct xlat msg_flags[] = {
325         { MSG_OOB,      "MSG_OOB"       },
326 #ifdef MSG_DONTROUTE
327         { MSG_DONTROUTE,"MSG_DONTROUTE" },
328 #endif
329 #ifdef MSG_PEEK
330         { MSG_PEEK,     "MSG_PEEK"      },
331 #endif
332 #ifdef MSG_CTRUNC
333         { MSG_CTRUNC,   "MSG_CTRUNC"    },
334 #endif
335 #ifdef MSG_PROXY
336         { MSG_PROXY,    "MSG_PROXY"     },
337 #endif
338 #ifdef MSG_EOR
339         { MSG_EOR,      "MSG_EOR"       },
340 #endif
341 #ifdef MSG_WAITALL
342         { MSG_WAITALL,  "MSG_WAITALL"   },
343 #endif
344 #ifdef MSG_TRUNC
345         { MSG_TRUNC,    "MSG_TRUNC"     },
346 #endif
347 #ifdef MSG_CTRUNC
348         { MSG_CTRUNC,   "MSG_CTRUNC"    },
349 #endif
350 #ifdef MSG_ERRQUEUE
351         { MSG_ERRQUEUE, "MSG_ERRQUEUE"  },
352 #endif
353 #ifdef MSG_DONTWAIT
354         { MSG_DONTWAIT, "MSG_DONTWAIT"  },
355 #endif
356 #ifdef MSG_CONFIRM
357         { MSG_CONFIRM,  "MSG_CONFIRM"   },
358 #endif
359 #ifdef MSG_PROBE
360         { MSG_PROBE,    "MSG_PROBE"     },
361 #endif
362         { 0,            NULL            },
363 };
364
365 static struct xlat sockoptions[] = {
366 #ifdef SO_PEERCRED
367         { SO_PEERCRED,  "SO_PEERCRED"   },
368 #endif
369 #ifdef SO_PASSCRED
370         { SO_PASSCRED,  "SO_PASSCRED"   },
371 #endif
372 #ifdef SO_DEBUG
373         { SO_DEBUG,     "SO_DEBUG"      },
374 #endif
375 #ifdef SO_REUSEADDR
376         { SO_REUSEADDR, "SO_REUSEADDR"  },
377 #endif
378 #ifdef SO_KEEPALIVE
379         { SO_KEEPALIVE, "SO_KEEPALIVE"  },
380 #endif
381 #ifdef SO_DONTROUTE
382         { SO_DONTROUTE, "SO_DONTROUTE"  },
383 #endif
384 #ifdef SO_BROADCAST
385         { SO_BROADCAST, "SO_BROADCAST"  },
386 #endif
387 #ifdef SO_LINGER
388         { SO_LINGER,    "SO_LINGER"     },
389 #endif
390 #ifdef SO_OOBINLINE
391         { SO_OOBINLINE, "SO_OOBINLINE"  },
392 #endif
393 #ifdef SO_TYPE
394         { SO_TYPE,      "SO_TYPE"       },
395 #endif
396 #ifdef SO_ERROR
397         { SO_ERROR,     "SO_ERROR"      },
398 #endif
399 #ifdef SO_SNDBUF
400         { SO_SNDBUF,    "SO_SNDBUF"     },
401 #endif
402 #ifdef SO_RCVBUF
403         { SO_RCVBUF,    "SO_RCVBUF"     },
404 #endif
405 #ifdef SO_NO_CHECK
406         { SO_NO_CHECK,  "SO_NO_CHECK"   },
407 #endif
408 #ifdef SO_PRIORITY
409         { SO_PRIORITY,  "SO_PRIORITY"   },
410 #endif
411 #ifdef SO_ACCEPTCONN
412         { SO_ACCEPTCONN,"SO_ACCEPTCONN" },
413 #endif
414 #ifdef SO_USELOOPBACK
415         { SO_USELOOPBACK,"SO_USELOOPBACK"},
416 #endif
417 #ifdef SO_SNDLOWAT
418         { SO_SNDLOWAT,  "SO_SNDLOWAT"   },
419 #endif
420 #ifdef SO_RCVLOWAT
421         { SO_RCVLOWAT,  "SO_RCVLOWAT"   },
422 #endif
423 #ifdef SO_SNDTIMEO
424         { SO_SNDTIMEO,  "SO_SNDTIMEO"   },
425 #endif
426 #ifdef SO_RCVTIMEO
427         { SO_RCVTIMEO,  "SO_RCVTIMEO"   },
428 #endif
429 #ifdef SO_BSDCOMPAT
430         { SO_BSDCOMPAT, "SO_BSDCOMPAT"  },
431 #endif
432 #ifdef SO_REUSEPORT
433         { SO_REUSEPORT, "SO_REUSEPORT"  },
434 #endif
435 #ifdef SO_RCVLOWAT
436         { SO_RCVLOWAT, "SO_RCVLOWAT"    },
437 #endif
438 #ifdef SO_SNDLOWAT
439         { SO_SNDLOWAT, "SO_SNDLOWAT"    },
440 #endif
441 #ifdef SO_RCVTIMEO
442         { SO_RCVTIMEO, "SO_RCVTIMEO"    },
443 #endif
444 #ifdef SO_SNDTIMEO
445         { SO_SNDTIMEO, "SO_SNDTIMEO"    },
446 #endif
447         { 0,            NULL            },
448 };
449
450 #ifdef SOL_IP
451 static struct xlat sockipoptions[] = {
452         { IP_TOS,               "IP_TOS"                },
453         { IP_TTL,               "IP_TTL"                },
454 #if defined(IP_HDRINCL)
455         { IP_HDRINCL,           "IP_HDRINCL"            },
456 #endif
457 #if defined(IP_OPTIONS)
458         { IP_OPTIONS,           "IP_OPTIONS"            },
459 #endif
460         { IP_ROUTER_ALERT,      "IP_ROUTER_ALERT"       },
461 #if defined(IP_RECVOPTIONS)
462         { IP_RECVOPTIONS,       "IP_RECVOPTIONS"        },
463 #endif
464         { IP_RETOPTS,           "IP_RETOPTS"            },
465         { IP_PKTINFO,           "IP_PKTINFO"            },
466         { IP_PKTOPTIONS,        "IP_PKTOPTIONS" },
467         { IP_MTU_DISCOVER,      "IP_MTU_DISCOVER"       },
468         { IP_MTU_DISCOVER,      "IP_MTU_DISCOVER"       },
469         { IP_RECVERR,           "IP_RECVERR"            },
470         { IP_RECVTTL,           "IP_RECRECVTTL"         },
471         { IP_RECVTOS,           "IP_RECRECVTOS"         },
472 #if defined(IP_MTU)
473         { IP_MTU,               "IP_MTU"                },
474 #endif
475         { IP_MULTICAST_IF,      "IP_MULTICAST_IF"       },
476         { IP_MULTICAST_TTL,     "IP_MULTICAST_TTL"      },
477         { IP_MULTICAST_LOOP,    "IP_MULTICAST_LOOP"     },
478         { IP_ADD_MEMBERSHIP,    "IP_ADD_MEMBERSHIP"     },
479         { IP_DROP_MEMBERSHIP,   "IP_DROP_MEMBERSHIP"    },
480         { 0,                    NULL                    },
481 };
482 #endif /* SOL_IP */
483
484 #ifdef SOL_IPX
485 static struct xlat sockipxoptions[] = {
486         { IPX_TYPE,     "IPX_TYPE"      },
487         { 0,            NULL            },
488 };
489 #endif /* SOL_IPX */
490
491 #ifdef SOL_RAW
492 static struct xlat sockrawoptions[] = {
493 #if defined(ICMP_FILTER)
494         { ICMP_FILTER,          "ICMP_FILTER"   },
495 #endif
496         { 0,                    NULL            },
497 };
498 #endif /* SOL_RAW */
499
500 #ifdef SOL_PACKET
501 static struct xlat sockpacketoptions[] = {
502         { PACKET_ADD_MEMBERSHIP,        "PACKET_ADD_MEMBERSHIP" },
503         { PACKET_DROP_MEMBERSHIP,       "PACKET_DROP_MEMBERSHIP"},
504 #if defined(PACKET_RECV_OUTPUT)
505         { PACKET_RECV_OUTPUT,           "PACKET_RECV_OUTPUT"    },
506 #endif
507 #if defined(PACKET_RX_RING)
508         { PACKET_RX_RING,               "PACKET_RX_RING"        },
509 #endif
510 #if defined(PACKET_STATISTICS)
511         { PACKET_STATISTICS,            "PACKET_STATISTICS"     },
512 #endif
513         { 0,                            NULL                    },
514 };
515 #endif /* SOL_PACKET */
516
517 #ifdef SOL_TCP
518 static struct xlat socktcpoptions[] = {
519         { TCP_NODELAY,  "TCP_NODELAY"   },
520         { TCP_MAXSEG,   "TCP_MAXSEG"    },
521 #if defined(TCP_CORK)
522         { TCP_CORK,     "TCP_CORK"      },
523 #endif
524         { 0,            NULL            },
525 };
526 #endif /* SOL_TCP */
527
528 #ifdef SOL_RAW
529 static struct xlat icmpfilterflags[] = {
530 #if defined(ICMP_ECHOREPLY)
531         { (1<<ICMP_ECHOREPLY),          "ICMP_ECHOREPLY"        },
532 #endif
533 #if defined(ICMP_DEST_UNREACH)
534         { (1<<ICMP_DEST_UNREACH),       "ICMP_DEST_UNREACH"     },
535 #endif
536 #if defined(ICMP_SOURCE_QUENCH)
537         { (1<<ICMP_SOURCE_QUENCH),      "ICMP_SOURCE_QUENCH"    },
538 #endif
539 #if defined(ICMP_REDIRECT)
540         { (1<<ICMP_REDIRECT),           "ICMP_REDIRECT"         },
541 #endif
542 #if defined(ICMP_ECHO)
543         { (1<<ICMP_ECHO),               "ICMP_ECHO"             },
544 #endif
545 #if defined(ICMP_TIME_EXCEEDED)
546         { (1<<ICMP_TIME_EXCEEDED),      "ICMP_TIME_EXCEEDED"    },
547 #endif
548 #if defined(ICMP_PARAMETERPROB)
549         { (1<<ICMP_PARAMETERPROB),      "ICMP_PARAMETERPROB"    },
550 #endif
551 #if defined(ICMP_TIMESTAMP)
552         { (1<<ICMP_TIMESTAMP),          "ICMP_TIMESTAMP"        },
553 #endif
554 #if defined(ICMP_TIMESTAMPREPLY)
555         { (1<<ICMP_TIMESTAMPREPLY),     "ICMP_TIMESTAMPREPLY"   },
556 #endif
557 #if defined(ICMP_INFO_REQUEST)
558         { (1<<ICMP_INFO_REQUEST),       "ICMP_INFO_REQUEST"     },
559 #endif
560 #if defined(ICMP_INFO_REPLY)
561         { (1<<ICMP_INFO_REPLY),         "ICMP_INFO_REPLY"       },
562 #endif
563 #if defined(ICMP_ADDRESS)
564         { (1<<ICMP_ADDRESS),            "ICMP_ADDRESS"          },
565 #endif
566 #if defined(ICMP_ADDRESSREPLY)
567         { (1<<ICMP_ADDRESSREPLY),       "ICMP_ADDRESSREPLY"     },
568 #endif
569         { 0,                            NULL                    },
570 };
571 #endif /* SOL_RAW */
572
573
574 void
575 printsock(tcp, addr, addrlen)
576 struct tcb *tcp;
577 long addr;
578 int addrlen;
579 {
580         union {
581                 char pad[128];
582                 struct sockaddr sa;
583                 struct sockaddr_in sin;
584                 struct sockaddr_un sau;
585 #ifdef HAVE_INET_NTOP
586                 struct sockaddr_in6 sa6;
587 #endif
588 #if defined(LINUX) && defined(AF_IPX)
589                 struct sockaddr_ipx sipx;
590 #endif
591 #ifdef AF_PACKET
592                 struct sockaddr_ll ll;
593 #endif
594 #ifdef AF_NETLINK
595                 struct sockaddr_nl nl;
596 #endif
597         } addrbuf;
598         char string_addr[100];
599
600         if (addr == 0) {
601                 tprintf("NULL");
602                 return;
603         }
604         if (!verbose(tcp)) {
605                 tprintf("%#lx", addr);
606                 return;
607         }
608         if ((addrlen<2) || (addrlen>sizeof(addrbuf)))
609                 addrlen=sizeof(addrbuf);
610
611         if (umoven(tcp, addr, addrlen, (char*)&addrbuf) < 0) {
612                 tprintf("{...}");
613                 return;
614         }
615
616         tprintf("{sin_family=");
617         printxval(addrfams, addrbuf.sa.sa_family, "AF_???");
618         tprintf(", ");
619
620         switch (addrbuf.sa.sa_family) {
621         case AF_UNIX:
622                 if (addrlen==2) {
623                         tprintf("<nil>");
624                 } else if (addrbuf.sau.sun_path[0]) {
625                         tprintf("path=\"%-.*s\"", addrlen-2, addrbuf.sau.sun_path);
626                 } else {
627                         tprintf("path=@%-.*s", addrlen-3, addrbuf.sau.sun_path+1);
628                 }
629                 break;
630         case AF_INET:
631                 tprintf("sin_port=htons(%u), sin_addr=inet_addr(\"%s\")}",
632                         ntohs(addrbuf.sin.sin_port), inet_ntoa(addrbuf.sin.sin_addr));
633                 break;
634 #ifdef HAVE_INET_NTOP
635         case AF_INET6:
636                 inet_ntop(AF_INET6, &addrbuf.sa6.sin6_addr, string_addr, sizeof(string_addr));
637                 tprintf("sin6_port=htons(%u), inet_pton(AF_INET6, \"%s\", &sin6_addr), sin6_flowinfo=%u",
638                                 ntohs(addrbuf.sa6.sin6_port), string_addr,
639                                 addrbuf.sa6.sin6_flowinfo);
640 #ifdef HAVE_SIN6_SCOPE_ID
641                 {
642 #if defined(HAVE_IF_INDEXTONAME) && defined(IN6_IS_ADDR_LINKLOCAL) && defined(IN6_IS_ADDR_MC_LINKLOCAL)
643                     int numericscope = 0;
644                     if (IN6_IS_ADDR_LINKLOCAL (&addrbuf.sa6.sin6_addr)
645                             || IN6_IS_ADDR_MC_LINKLOCAL (&addrbuf.sa6.sin6_addr)) {
646                         char scopebuf[IFNAMSIZ + 1];
647                         
648                         if (if_indextoname (addrbuf.sa6.sin6_scope_id, scopebuf) == NULL)
649                             numericscope++;
650                         else
651                             tprintf(", sin6_scope_id=if_nametoindex(\"%s\")", scopebuf);
652                     } else
653                         numericscope++;
654                     
655                     if (numericscope)
656 #endif
657                         tprintf(", sin6_scope_id=%u", addrbuf.sa6.sin6_scope_id);
658                 }
659 #endif
660                     break;
661 #endif
662 #if defined(AF_IPX) && defined(linux)
663         case AF_IPX:
664                 {
665                         int i;
666                         tprintf("{sipx_port=htons(%u), ",
667                                         ntohs(addrbuf.sipx.sipx_port));
668                         /* Yes, I know, this does not look too
669                          * strace-ish, but otherwise the IPX
670                          * addresses just look monstrous...
671                          * Anyways, feel free if you don't like
672                          * this way.. :) 
673                          */
674                         tprintf("%08lx:", (unsigned long)ntohl(addrbuf.sipx.sipx_network));
675                         for (i = 0; i<IPX_NODE_LEN; i++)
676                                 tprintf("%02x", addrbuf.sipx.sipx_node[i]);
677                         tprintf("/[%02x]", addrbuf.sipx.sipx_type);
678                 }
679                 break;
680 #endif /* AF_IPX && linux */
681 #ifdef AF_PACKET
682         case AF_PACKET:
683                 {
684                         int i;
685                         tprintf("proto=%#04x, if%d, pkttype=%d, addr(%d)={%d, ",
686                                         ntohs(addrbuf.ll.sll_protocol),
687                                         addrbuf.ll.sll_ifindex,
688                                         addrbuf.ll.sll_pkttype,
689                                         addrbuf.ll.sll_halen,
690                                         addrbuf.ll.sll_hatype);
691                         for (i=0; i<addrbuf.ll.sll_addr[i]; i++) 
692                                 tprintf("%02x", addrbuf.ll.sll_addr[i]);
693                 }
694                 break;
695
696 #endif /* AF_APACKET */
697 #ifdef AF_NETLINLK
698         case AF_NETLINK:
699                 tprintf("pid=%d, groups=%08x", addrbuf.nl.nl_pid, addrbuf.nl.nl_groups);
700                 break;
701 #endif /* AF_NETLINK */
702         /* AF_AX25 AF_APPLETALK AF_NETROM AF_BRIDGE AF_AAL5
703         AF_X25 AF_ROSE etc. still need to be done */
704
705         default:
706                 tprintf("{sa_family=%u, sa_data=", addrbuf.sa.sa_family);
707                 printstr(tcp, (long) &((struct sockaddr *) addr)->sa_data,
708                         sizeof addrbuf.sa.sa_data);
709                 break;
710         }
711         tprintf("}");
712 }
713
714 #if HAVE_SENDMSG
715
716 static void
717 printiovec(tcp, iovec, len)
718 struct tcb *tcp;
719 struct iovec *iovec;
720 long   len;
721 {
722         struct iovec *iov;
723         int i;
724
725         iov = (struct iovec *) malloc(len * sizeof *iov);
726         if (iov == NULL) {
727                 fprintf(stderr, "No memory");
728                 return;
729         }
730         if (umoven(tcp, (long)iovec,
731                                 len * sizeof *iov, (char *) iov) < 0) {
732                 tprintf("%#lx", (unsigned long)iovec);
733         } else {
734                 tprintf("[");
735                 for (i = 0; i < len; i++) {
736                         if (i)
737                                 tprintf(", ");
738                         tprintf("{");
739                         printstr(tcp, (long) iov[i].iov_base,
740                                         iov[i].iov_len);
741                         tprintf(", %lu}", (unsigned long)iov[i].iov_len);
742                 }
743                 tprintf("]");
744         }
745         free((char *) iov);
746 }
747
748 static void
749 printmsghdr(tcp, addr)
750 struct tcb *tcp;
751 long addr;
752 {
753         struct msghdr msg;
754
755         if (umove(tcp, addr, &msg) < 0) {
756                 tprintf("%#lx", addr);
757                 return;
758         }
759         tprintf("{msg_name(%d)=", msg.msg_namelen);
760         printsock(tcp, (long)msg.msg_name, msg.msg_namelen);
761
762         tprintf(", msg_iov(%lu)=", (unsigned long)msg.msg_iovlen);
763         printiovec(tcp, msg.msg_iov, msg.msg_iovlen);
764
765 #ifdef HAVE_MSG_CONTROL
766         tprintf(", msg_controllen=%lu", (unsigned long)msg.msg_controllen);
767         if (msg.msg_controllen) 
768                 tprintf(", msg_control=%#lx, ", (unsigned long) msg.msg_control);
769         tprintf(", msg_flags=");
770         if (printflags(msg_flags, msg.msg_flags)==0)
771                 tprintf("0");
772 #else /* !HAVE_MSG_CONTROL */
773         tprintf("msg_accrights=%#lx, msg_accrightslen=%u",
774                 (unsigned long) msg.msg_accrights, msg.msg_accrightslen);
775 #endif /* !HAVE_MSG_CONTROL */
776         tprintf("}");
777 }
778
779 #endif /* HAVE_SENDMSG */
780
781 int
782 sys_socket(tcp)
783 struct tcb *tcp;
784 {
785         if (entering(tcp)) {
786                 printxval(domains, tcp->u_arg[0], "PF_???");
787                 tprintf(", ");
788                 printxval(socktypes, tcp->u_arg[1], "SOCK_???");
789                 tprintf(", ");
790                 switch (tcp->u_arg[0]) {
791                 case PF_INET:
792                         printxval(protocols, tcp->u_arg[2], "IPPROTO_???");
793                         break;
794 #ifdef PF_IPX
795                 case PF_IPX:
796                         /* BTW: I don't believe this.. */
797                         tprintf("[");
798                         printxval(domains, tcp->u_arg[2], "PF_???");
799                         tprintf("]");
800                         break;
801 #endif /* PF_IPX */
802                 default:
803                         tprintf("%lu", tcp->u_arg[2]);
804                         break;
805                 }
806         }
807         return 0;
808 }
809
810 int
811 sys_so_socket(tcp)
812 struct tcb *tcp;
813 {
814         if (entering(tcp)) {
815                 /* not sure really what these args are... but this
816                  * is how truss prints it
817                  */
818                 tprintf("%ld, %ld, %ld, ",
819                   tcp->u_arg[0], tcp->u_arg[1], tcp->u_arg[2]);
820                 printpath(tcp, tcp->u_arg[3]);
821                 tprintf(", %ld", tcp->u_arg[4]);
822         }
823         return 0;
824 }
825
826 int
827 sys_so_socketpair(tcp)
828 struct tcb *tcp;
829 {
830         if (entering(tcp)) {
831                 /* not sure what this arg is */
832                 tprintf("0x%lx", tcp->u_arg[0]);
833         }
834         return 0;
835 }
836
837 int
838 sys_bind(tcp)
839 struct tcb *tcp;
840 {
841         if (entering(tcp)) {
842                 tprintf("%ld, ", tcp->u_arg[0]);
843                 printsock(tcp, tcp->u_arg[1], tcp->u_arg[2]);
844                 tprintf(", %lu", tcp->u_arg[2]);
845         }
846         return 0;
847 }
848
849 int
850 sys_connect(tcp)
851 struct tcb *tcp;
852 {
853         return sys_bind(tcp);
854 }
855
856 int
857 sys_listen(tcp)
858 struct tcb *tcp;
859 {
860         if (entering(tcp)) {
861                 tprintf("%ld, %lu", tcp->u_arg[0], tcp->u_arg[1]);
862         }
863         return 0;
864 }
865
866 int
867 sys_accept(tcp)
868 struct tcb *tcp;
869 {
870         if (entering(tcp)) {
871                 tprintf("%ld, ", tcp->u_arg[0]);
872         } else if (!tcp->u_arg[2])
873                 tprintf("%#lx, NULL", tcp->u_arg[1]);
874         else {
875                 if (tcp->u_arg[1] == 0 || syserror(tcp)) {
876                         tprintf("%#lx", tcp->u_arg[1]);
877                 } else {
878                         printsock(tcp, tcp->u_arg[1], tcp->u_arg[2]);
879                 }
880                 tprintf(", ");
881                 printnum(tcp, tcp->u_arg[2], "%lu");
882         }
883         return 0;
884 }
885
886 int
887 sys_send(tcp)
888 struct tcb *tcp;
889 {
890         if (entering(tcp)) {
891                 tprintf("%ld, ", tcp->u_arg[0]);
892                 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
893                 tprintf(", %lu, ", tcp->u_arg[2]);
894                 /* flags */
895                 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
896                         tprintf("0");
897         }
898         return 0;
899 }
900
901 int
902 sys_sendto(tcp)
903 struct tcb *tcp;
904 {
905         if (entering(tcp)) {
906                 tprintf("%ld, ", tcp->u_arg[0]);
907                 printstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
908                 tprintf(", %lu, ", tcp->u_arg[2]);
909                 /* flags */
910                 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
911                         tprintf("0");
912                 /* to address */
913                 tprintf(", ");
914                 printsock(tcp, tcp->u_arg[4], tcp->u_arg[5]);
915                 /* to length */
916                 tprintf(", %lu", tcp->u_arg[5]);
917         }
918         return 0;
919 }
920
921 #ifdef HAVE_SENDMSG
922
923 int
924 sys_sendmsg(tcp)
925 struct tcb *tcp;
926 {
927         if (entering(tcp)) {
928                 tprintf("%ld, ", tcp->u_arg[0]);
929                 printmsghdr(tcp, tcp->u_arg[1]);
930                 /* flags */
931                 tprintf(", ");
932                 if (printflags(msg_flags, tcp->u_arg[2]) == 0)
933                         tprintf("0");
934         }
935         return 0;
936 }
937
938 #endif /* HAVE_SENDMSG */
939
940 int
941 sys_recv(tcp)
942 struct tcb *tcp;
943 {
944         if (entering(tcp)) {
945                 tprintf("%ld, ", tcp->u_arg[0]);
946         } else {
947                 if (syserror(tcp))
948                         tprintf("%#lx", tcp->u_arg[1]);
949                 else
950                         printstr(tcp, tcp->u_arg[1], tcp->u_rval);
951
952                 tprintf(", %lu, ", tcp->u_arg[2]);
953                 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
954                         tprintf("0");
955         }
956         return 0;
957 }
958
959 int
960 sys_recvfrom(tcp)
961 struct tcb *tcp;
962 {
963         int fromlen;
964
965         if (entering(tcp)) {
966                 tprintf("%ld, ", tcp->u_arg[0]);
967         } else {
968                 if (syserror(tcp)) {
969                         tprintf("%#lx, %lu, %lu, %#lx, %#lx",
970                                 tcp->u_arg[1], tcp->u_arg[2], tcp->u_arg[3],
971                                 tcp->u_arg[4], tcp->u_arg[5]);
972                         return 0;
973                 }
974                 /* buf */
975                 printstr(tcp, tcp->u_arg[1], tcp->u_rval);
976                 /* len */
977                 tprintf(", %lu, ", tcp->u_arg[2]);
978                 /* flags */
979                 if (printflags(msg_flags, tcp->u_arg[3]) == 0)
980                         tprintf("0");
981                 /* from address, len */
982                 if (!tcp->u_arg[4] || !tcp->u_arg[5]) {
983                         if (tcp->u_arg[4] == 0)
984                                 tprintf(", NULL");
985                         else
986                                 tprintf(", %#lx", tcp->u_arg[4]);
987                         if (tcp->u_arg[5] == 0)
988                                 tprintf(", NULL");
989                         else
990                                 tprintf(", %#lx", tcp->u_arg[5]);
991                         return 0;
992                 }
993                 if (umove(tcp, tcp->u_arg[5], &fromlen) < 0) {
994                         tprintf(", {...}, [?]");
995                         return 0;
996                 }
997                 tprintf(", ");
998                 printsock(tcp, tcp->u_arg[4], tcp->u_arg[5]);
999                 /* from length */
1000                 tprintf(", [%u]", fromlen);
1001         }
1002         return 0;
1003 }
1004
1005 #ifdef HAVE_SENDMSG
1006
1007 int
1008 sys_recvmsg(tcp)
1009 struct tcb *tcp;
1010 {
1011         if (entering(tcp)) {
1012                 tprintf("%ld, ", tcp->u_arg[0]);
1013         } else {
1014                 if (syserror(tcp) || !verbose(tcp))
1015                         tprintf("%#lx", tcp->u_arg[1]);
1016                 else
1017                         printmsghdr(tcp, tcp->u_arg[1]);
1018                 /* flags */
1019                 tprintf(", ");
1020                 if (printflags(msg_flags, tcp->u_arg[2]) == 0)
1021                         tprintf("0");
1022         }
1023         return 0;
1024 }
1025
1026 #endif /* HAVE_SENDMSG */
1027
1028 int
1029 sys_shutdown(tcp)
1030 struct tcb *tcp;
1031 {
1032         if (entering(tcp)) {
1033                 tprintf("%ld, %ld", tcp->u_arg[0], tcp->u_arg[1]);
1034                 switch (tcp->u_arg[1]) {
1035                 case 0:
1036                         tprintf("%s", " /* receive */");
1037                         break;
1038                 case 1:
1039                         tprintf("%s", " /* send */");
1040                         break;
1041                 case 2:
1042                         tprintf("%s", " /* send and receive */");
1043                         break;
1044                 }
1045         }
1046         return 0;
1047 }
1048
1049 int
1050 sys_getsockname(tcp)
1051 struct tcb *tcp;
1052 {
1053         return sys_accept(tcp);
1054 }
1055
1056 int
1057 sys_getpeername(tcp)
1058 struct tcb *tcp;
1059 {
1060         return sys_accept(tcp);
1061 }
1062
1063 int
1064 sys_pipe(tcp)
1065 struct tcb *tcp;
1066 {
1067
1068 #if defined(LINUX) && !defined(SPARC)
1069         int fds[2];
1070
1071         if (exiting(tcp)) {
1072                 if (syserror(tcp)) {
1073                         tprintf("%#lx", tcp->u_arg[0]);
1074                         return 0;
1075                 }
1076                 if (umoven(tcp, tcp->u_arg[0], sizeof fds, (char *) fds) < 0)
1077                         tprintf("[...]");
1078                 else
1079                         tprintf("[%u, %u]", fds[0], fds[1]);
1080         }
1081 #elif defined(SPARC) || defined(SVR4) || defined(FREEBSD)
1082         if (exiting(tcp))
1083                 tprintf("[%lu, %lu]", tcp->u_rval, getrval2(tcp));
1084 #endif
1085         return 0;
1086 }
1087
1088 int
1089 sys_socketpair(tcp)
1090 struct tcb *tcp;
1091 {
1092 #ifdef LINUX
1093         int fds[2];
1094 #endif
1095
1096         if (entering(tcp)) {
1097                 printxval(domains, tcp->u_arg[0], "PF_???");
1098                 tprintf(", ");
1099                 printxval(socktypes, tcp->u_arg[1], "SOCK_???");
1100                 tprintf(", ");
1101                 switch (tcp->u_arg[0]) {
1102                 case PF_INET:
1103                         printxval(protocols, tcp->u_arg[2], "IPPROTO_???");
1104                         break;
1105 #ifdef PF_IPX
1106                 case PF_IPX:
1107                         /* BTW: I don't believe this.. */
1108                         tprintf("[");
1109                         printxval(domains, tcp->u_arg[2], "PF_???");
1110                         tprintf("]");
1111                         break;
1112 #endif /* PF_IPX */
1113                 default:        
1114                         tprintf("%lu", tcp->u_arg[2]);
1115                         break;
1116                 }
1117         } else {
1118                 if (syserror(tcp)) {
1119                         tprintf(", %#lx", tcp->u_arg[3]);
1120                         return 0;
1121                 }
1122 #ifdef LINUX
1123                 if (umoven(tcp, tcp->u_arg[3], sizeof fds, (char *) fds) < 0)
1124                         tprintf(", [...]");
1125                 else
1126                         tprintf(", [%u, %u]", fds[0], fds[1]);
1127 #endif /* LINUX */
1128 #if defined(SUNOS4) || defined(SVR4) || defined(FREEBSD)
1129                 tprintf(", [%lu, %lu]", tcp->u_rval, getrval2(tcp));
1130 #endif /* SUNOS4 || SVR4 || FREEBSD */
1131         }
1132         return 0;
1133 }
1134
1135 int
1136 sys_getsockopt(tcp)
1137 struct tcb *tcp;
1138 {
1139         if (entering(tcp)) {
1140                 tprintf("%ld, ", tcp->u_arg[0]);
1141                 switch (tcp->u_arg[1]) {
1142                 case SOL_SOCKET:
1143                         tprintf("SOL_SOCKET, ");
1144                         printxval(sockoptions, tcp->u_arg[2], "SO_???");
1145                         tprintf(", ");
1146                         break;
1147 #ifdef SOL_IP
1148                 case SOL_IP:
1149                         tprintf("SOL_IP, ");
1150                         printxval(sockipoptions, tcp->u_arg[2], "IP_???");
1151                         tprintf(", ");
1152                         break;
1153 #endif
1154 #ifdef SOL_IPX
1155                 case SOL_IPX:
1156                         tprintf("SOL_IPX, ");
1157                         printxval(sockipxoptions, tcp->u_arg[2], "IPX_???");
1158                         tprintf(", ");
1159                         break;
1160 #endif
1161 #ifdef SOL_PACKET
1162                 case SOL_PACKET:
1163                         tprintf("SOL_PACKET, ");
1164                         printxval(sockpacketoptions, tcp->u_arg[2], "PACKET_???");
1165                         tprintf(", ");
1166                         break;
1167 #endif
1168 #ifdef SOL_TCP
1169                 case SOL_TCP:
1170                         tprintf("SOL_TCP, ");
1171                         printxval(socktcpoptions, tcp->u_arg[2], "TCP_???");
1172                         tprintf(", ");
1173                         break;
1174 #endif
1175
1176                 /* SOL_AX25 SOL_ROSE SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25
1177                  * etc. still need work */
1178                 default: 
1179                         /* XXX - should know socket family here */
1180                         printxval(socketlayers, tcp->u_arg[1], "SOL_???");
1181                         tprintf(", %lu, ", tcp->u_arg[2]);
1182                         break;
1183                 }
1184         } else {
1185                 if (syserror(tcp)) {
1186                         tprintf("%#lx, %#lx",
1187                                 tcp->u_arg[3], tcp->u_arg[4]);
1188                         return 0;
1189                 }
1190                 printnum(tcp, tcp->u_arg[3], "%ld");
1191                 tprintf(", ");
1192                 printnum(tcp, tcp->u_arg[4], "%ld");
1193         }
1194         return 0;
1195 }
1196
1197 #if defined(ICMP_FILTER)
1198 static void printicmpfilter(tcp, addr)
1199 struct tcb *tcp;
1200 long addr;
1201 {
1202         struct icmp_filter      filter;
1203
1204         if (!addr) {
1205                 tprintf("NULL");
1206                 return;
1207         }
1208         if (syserror(tcp) || !verbose(tcp)) {
1209                 tprintf("%#lx", addr);
1210                 return;
1211         }
1212         if (umove(tcp, addr, &filter) < 0) {
1213                 tprintf("{...}");
1214                 return;
1215         }
1216
1217         tprintf("~(");
1218         if (printflags(icmpfilterflags, ~filter.data) == 0)
1219                 tprintf("0");
1220         tprintf(")");
1221 }
1222 #endif /* ICMP_FILTER */
1223
1224 int
1225 sys_setsockopt(tcp)
1226 struct tcb *tcp;
1227 {
1228         if (entering(tcp)) {
1229                 tprintf("%ld, ", tcp->u_arg[0]);
1230                 switch (tcp->u_arg[1]) {
1231                 case SOL_SOCKET:
1232                         tprintf("SOL_SOCKET, ");
1233                         printxval(sockoptions, tcp->u_arg[2], "SO_???");
1234                         tprintf(", ");
1235                         printnum(tcp, tcp->u_arg[3], "%ld");
1236                         tprintf(", %lu", tcp->u_arg[4]);
1237                         break;
1238 #ifdef SOL_IP
1239                 case SOL_IP:
1240                         tprintf("SOL_IP, ");
1241                         printxval(sockipoptions, tcp->u_arg[2], "IP_???");
1242                         tprintf(", ");
1243                         printnum(tcp, tcp->u_arg[3], "%ld");
1244                         tprintf(", %lu", tcp->u_arg[4]);
1245                         break;
1246 #endif
1247 #ifdef SOL_IPX
1248                 case SOL_IPX:
1249                         tprintf("SOL_IPX, ");
1250                         printxval(sockipxoptions, tcp->u_arg[2], "IPX_???");
1251                         tprintf(", ");
1252                         printnum(tcp, tcp->u_arg[3], "%ld");
1253                         tprintf(", %lu", tcp->u_arg[4]);
1254                         break;
1255 #endif
1256 #ifdef SOL_PACKET
1257                 case SOL_PACKET:
1258                         tprintf("SOL_PACKET, ");
1259                         printxval(sockpacketoptions, tcp->u_arg[2], "PACKET_???");
1260                         tprintf(", ");
1261                         /* TODO: decode packate_mreq for PACKET_*_MEMBERSHIP */
1262                         printnum(tcp, tcp->u_arg[3], "%ld");
1263                         tprintf(", %lu", tcp->u_arg[4]);
1264                         break;
1265 #endif
1266 #ifdef SOL_TCP
1267                 case SOL_TCP:
1268                         tprintf("SOL_TCP, ");
1269                         printxval(socktcpoptions, tcp->u_arg[2], "TCP_???");
1270                         tprintf(", ");
1271                         printnum(tcp, tcp->u_arg[3], "%ld");
1272                         tprintf(", %lu", tcp->u_arg[4]);
1273                         break;
1274 #endif
1275 #ifdef SOL_RAW
1276                 case SOL_RAW:
1277                         tprintf("SOL_RAW, ");
1278                         printxval(sockrawoptions, tcp->u_arg[2], "RAW_???");
1279                         tprintf(", ");
1280                         switch (tcp->u_arg[2]) {
1281 #if defined(ICMP_FILTER)
1282                                 case ICMP_FILTER:
1283                                         printicmpfilter(tcp, tcp->u_arg[3]);
1284                                         break;
1285 #endif
1286                                 default:
1287                                         printnum(tcp, tcp->u_arg[3], "%ld");
1288                                         break;
1289                         }
1290                         tprintf(", %lu", tcp->u_arg[4]);
1291                         break;
1292 #endif
1293
1294                 /* SOL_AX25 SOL_ATALK SOL_NETROM SOL_UDP SOL_DECNET SOL_X25 
1295                  * etc. still need work  */
1296                 default:
1297                         /* XXX - should know socket family here */
1298                         printxval(socketlayers, tcp->u_arg[1], "IPPROTO_???");
1299                         tprintf(", %lu, ", tcp->u_arg[2]);
1300                         printnum(tcp, tcp->u_arg[3], "%ld");
1301                         tprintf(", %lu", tcp->u_arg[4]);
1302                         break;
1303                 }
1304         }
1305         return 0;
1306 }
1307
1308 #if UNIXWARE >= 7
1309
1310 static struct xlat sock_version[] = {
1311         { __NETLIB_UW211_SVR4,  "UW211_SVR4" },
1312         { __NETLIB_UW211_XPG4,  "UW211_XPG4" },
1313         { __NETLIB_GEMINI_SVR4, "GEMINI_SVR4" },
1314         { __NETLIB_GEMINI_XPG4, "GEMINI_XPG4" },
1315         { __NETLIB_FP1_SVR4,    "FP1_SVR4" },
1316         { __NETLIB_FP1_XPG4,    "FP1_XPG4" },
1317         { 0,            NULL            },
1318 };
1319
1320
1321 int
1322 netlib_call(tcp, func)
1323 struct tcb *tcp;
1324 int (*func) ();
1325 {
1326         if (entering(tcp)) {
1327                 int i;
1328                 printxval (sock_version, tcp->u_arg[0], "__NETLIB_???");
1329                 tprintf(", ");
1330                 --tcp->u_nargs;
1331                 for (i = 0; i < tcp->u_nargs; i++)
1332                         tcp->u_arg[i] = tcp->u_arg[i + 1];
1333                 return func (tcp);
1334                 
1335         }
1336
1337         return func (tcp);
1338 }
1339
1340 int
1341 sys_xsocket(tcp)
1342 struct tcb *tcp;
1343 {
1344         return netlib_call (tcp, sys_socket);
1345 }
1346
1347 int
1348 sys_xsocketpair(tcp)
1349 struct tcb *tcp;
1350 {
1351         return netlib_call (tcp, sys_socketpair);
1352 }
1353
1354 int
1355 sys_xbind(tcp)
1356 struct tcb *tcp;
1357 {
1358         return netlib_call (tcp, sys_bind);
1359 }
1360
1361 int
1362 sys_xconnect(tcp)
1363 struct tcb *tcp;
1364 {
1365         return netlib_call (tcp, sys_connect);
1366 }
1367
1368 int
1369 sys_xlisten(tcp)
1370 struct tcb *tcp;
1371 {
1372         return netlib_call (tcp, sys_listen);
1373 }
1374
1375 int
1376 sys_xaccept(tcp)
1377 struct tcb *tcp;
1378 {
1379         return netlib_call (tcp, sys_accept);
1380 }
1381
1382 int
1383 sys_xsendmsg(tcp)
1384 struct tcb *tcp;
1385 {
1386         return netlib_call (tcp, sys_sendmsg);
1387 }
1388
1389 int
1390 sys_xrecvmsg(tcp)
1391 struct tcb *tcp;
1392 {
1393         return netlib_call (tcp, sys_recvmsg);
1394 }
1395
1396 int
1397 sys_xgetsockaddr(tcp)
1398 struct tcb *tcp;
1399 {
1400         if (entering(tcp)) {
1401                 printxval (sock_version, tcp->u_arg[0], "__NETLIB_???");
1402                 tprintf(", ");
1403                 if (tcp->u_arg[1] == 0) {
1404                         tprintf ("LOCALNAME, ");
1405                 }
1406                 else if (tcp->u_arg[1] == 1) {
1407                         tprintf ("REMOTENAME, ");
1408                 }
1409                 else {
1410                         tprintf ("%ld, ", tcp->u_arg [1]);
1411                 }
1412                 tprintf ("%ld, ", tcp->u_arg [2]);
1413         } 
1414         else {
1415                 if (tcp->u_arg[3] == 0 || syserror(tcp)) {
1416                         tprintf("%#lx", tcp->u_arg[3]);
1417                 } else {
1418                         printsock(tcp, tcp->u_arg[3], tcp->u_arg[4]);
1419                 }
1420                 tprintf(", ");
1421                 printnum(tcp, tcp->u_arg[4], "%lu");
1422         }
1423
1424         return 0;
1425
1426 }
1427
1428 #if 0
1429
1430 int
1431 sys_xsetsockaddr(tcp)
1432 struct tcb *tcp;
1433 {
1434         return netlib_call (tcp, sys_setsockaddr);
1435 }
1436
1437 #endif
1438
1439 int
1440 sys_xgetsockopt(tcp)
1441 struct tcb *tcp;
1442 {
1443         return netlib_call (tcp, sys_getsockopt);
1444 }
1445
1446 int
1447 sys_xsetsockopt(tcp)
1448 struct tcb *tcp;
1449 {
1450         return netlib_call (tcp, sys_setsockopt);
1451 }
1452
1453 int
1454 sys_xshutdown(tcp)
1455 struct tcb *tcp;
1456 {
1457         return netlib_call (tcp, sys_shutdown);
1458 }
1459
1460 #endif