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