2 * Copyright (c) 1995 Søren Schmidt
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer
10 * in this position and unchanged.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software withough specific prior written permission
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 * $FreeBSD: src/sys/compat/linux/linux_socket.c,v 1.19.2.8 2001/11/07 20:33:55 marcel Exp $
29 * $DragonFly: src/sys/emulation/linux/linux_socket.c,v 1.10 2003/09/07 20:36:11 daver Exp $
32 /* XXX we use functions that might not exist. */
33 #include "opt_compat.h"
36 #error "Unable to compile Linux-emulator due to missing COMPAT_43 option!"
39 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/sysproto.h>
43 #include <sys/fcntl.h>
45 #include <sys/kern_syscall.h>
46 #include <sys/socket.h>
47 #include <sys/socketvar.h>
49 #include <sys/malloc.h>
51 #include <netinet/in.h>
52 #include <netinet/in_systm.h>
53 #include <netinet/ip.h>
55 #include <arch_linux/linux.h>
56 #include <arch_linux/linux_proto.h>
57 #include "linux_socket.h"
58 #include "linux_util.h"
61 * Copyin a sockaddr structure provided by a Linux binary. Linux uses
62 * the 4.3BSD sockaddr structure which has no sa_len field. We must
63 * pass 4.4BSD sockaddr structures when we call native functions in the
64 * BSD kernel. his function does the conversion for us.
66 * Also, our socket calls require the sockaddr structure length to agree
67 * with the address family. Linux does not, so we must force it.
69 * This function should only need to be called from linux_connect()
73 linux_getsockaddr(struct sockaddr **namp, struct sockaddr *uaddr, size_t len)
76 uint16_t family; /* XXX: must match Linux sockaddr */
82 if (len > SOCK_MAXADDRLEN)
84 error = copyin(uaddr, &family, sizeof(family));
89 * Force the sa_len field to match the address family.
93 sa_len = sizeof(struct sockaddr_in);
96 sa_len = sizeof(struct sockaddr_in6);
100 * This is the default behavior of the old
101 * linux_to_bsd_namelen() function. NOTE! The
102 * minimum length we allocate must cover sa->sa_len and
105 sa_len = offsetof(struct sockaddr, sa_data[0]);
111 MALLOC(sa, struct sockaddr *, sa_len, M_SONAME, M_WAITOK);
112 error = copyin(uaddr, sa, sa_len);
117 * Convert to the 4.4BSD sockaddr structure.
119 sa->sa_family = *(sa_family_t *)sa;
129 linux_to_bsd_domain(int domain)
133 case LINUX_AF_UNSPEC:
143 case LINUX_AF_APPLETALK:
144 return (AF_APPLETALK);
150 linux_to_bsd_sockopt_level(int level)
154 case LINUX_SOL_SOCKET:
161 linux_to_bsd_ip_sockopt(int opt)
169 case LINUX_IP_OPTIONS:
171 case LINUX_IP_MULTICAST_IF:
172 return (IP_MULTICAST_IF);
173 case LINUX_IP_MULTICAST_TTL:
174 return (IP_MULTICAST_TTL);
175 case LINUX_IP_MULTICAST_LOOP:
176 return (IP_MULTICAST_LOOP);
177 case LINUX_IP_ADD_MEMBERSHIP:
178 return (IP_ADD_MEMBERSHIP);
179 case LINUX_IP_DROP_MEMBERSHIP:
180 return (IP_DROP_MEMBERSHIP);
181 case LINUX_IP_HDRINCL:
188 linux_to_bsd_so_sockopt(int opt)
194 case LINUX_SO_REUSEADDR:
195 return (SO_REUSEADDR);
200 case LINUX_SO_DONTROUTE:
201 return (SO_DONTROUTE);
202 case LINUX_SO_BROADCAST:
203 return (SO_BROADCAST);
204 case LINUX_SO_SNDBUF:
206 case LINUX_SO_RCVBUF:
208 case LINUX_SO_KEEPALIVE:
209 return (SO_KEEPALIVE);
210 case LINUX_SO_OOBINLINE:
211 return (SO_OOBINLINE);
212 case LINUX_SO_LINGER:
219 linux_to_bsd_msg_flags(int flags)
223 if (flags & LINUX_MSG_OOB)
224 ret_flags |= MSG_OOB;
225 if (flags & LINUX_MSG_PEEK)
226 ret_flags |= MSG_PEEK;
227 if (flags & LINUX_MSG_DONTROUTE)
228 ret_flags |= MSG_DONTROUTE;
229 if (flags & LINUX_MSG_CTRUNC)
230 ret_flags |= MSG_CTRUNC;
231 if (flags & LINUX_MSG_TRUNC)
232 ret_flags |= MSG_TRUNC;
233 if (flags & LINUX_MSG_DONTWAIT)
234 ret_flags |= MSG_DONTWAIT;
235 if (flags & LINUX_MSG_EOR)
236 ret_flags |= MSG_EOR;
237 if (flags & LINUX_MSG_WAITALL)
238 ret_flags |= MSG_WAITALL;
239 #if 0 /* not handled */
240 if (flags & LINUX_MSG_PROXY)
242 if (flags & LINUX_MSG_FIN)
244 if (flags & LINUX_MSG_SYN)
246 if (flags & LINUX_MSG_CONFIRM)
248 if (flags & LINUX_MSG_RST)
250 if (flags & LINUX_MSG_ERRQUEUE)
252 if (flags & LINUX_MSG_NOSIGNAL)
258 /* Return 0 if IP_HDRINCL is set for the given socket. */
260 linux_check_hdrincl(int s)
262 struct getsockopt_args /* {
270 caddr_t sg, val, valsize;
271 int size_val = sizeof val;
274 sg = stackgap_init();
275 val = stackgap_alloc(&sg, sizeof(int));
276 valsize = stackgap_alloc(&sg, sizeof(int));
278 if ((error = copyout(&size_val, valsize, sizeof(size_val))))
282 bsd_args.level = IPPROTO_IP;
283 bsd_args.name = IP_HDRINCL;
285 bsd_args.avalsize = (int *)valsize;
286 bsd_args.sysmsg_result = 0;
287 if ((error = getsockopt(&bsd_args)))
289 /* return value not used */
291 if ((error = copyin(val, &optval, sizeof(optval))))
294 return (optval == 0);
298 * Updated sendto() when IP_HDRINCL is set:
299 * tweak endian-dependent fields in the IP packet.
302 linux_sendto_hdrincl(struct sendto_args *bsd_args)
305 * linux_ip_copysize defines how many bytes we should copy
306 * from the beginning of the IP packet before we customize it for BSD.
307 * It should include all the fields we modify (ip_len and ip_off)
308 * and be as small as possible to minimize copying overhead.
310 #define linux_ip_copysize 8
317 struct sendmsg_args /* {
323 /* Check the packet isn't too small before we mess with it */
324 if (bsd_args->len < linux_ip_copysize)
328 * Tweaking the user buffer in place would be bad manners.
329 * We create a corrected IP header with just the needed length,
330 * then use an iovec to glue it to the rest of the user packet
331 * when calling sendmsg().
333 sg = stackgap_init();
334 packet = (struct ip *)stackgap_alloc(&sg, linux_ip_copysize);
335 msg = (struct msghdr *)stackgap_alloc(&sg, sizeof(*msg));
336 iov = (struct iovec *)stackgap_alloc(&sg, sizeof(*iov)*2);
338 /* Make a copy of the beginning of the packet to be sent */
339 if ((error = copyin(bsd_args->buf, packet, linux_ip_copysize)))
342 /* Convert fields from Linux to BSD raw IP socket format */
343 packet->ip_len = bsd_args->len;
344 packet->ip_off = ntohs(packet->ip_off);
346 /* Prepare the msghdr and iovec structures describing the new packet */
347 msg->msg_name = bsd_args->to;
348 msg->msg_namelen = bsd_args->tolen;
351 msg->msg_control = NULL;
352 msg->msg_controllen = 0;
354 iov[0].iov_base = (char *)packet;
355 iov[0].iov_len = linux_ip_copysize;
356 iov[1].iov_base = (char *)(bsd_args->buf) + linux_ip_copysize;
357 iov[1].iov_len = bsd_args->len - linux_ip_copysize;
359 sendmsg_args.s = bsd_args->s;
360 sendmsg_args.msg = (caddr_t)msg;
361 sendmsg_args.flags = bsd_args->flags;
362 sendmsg_args.sysmsg_result = 0;
363 error = sendmsg(&sendmsg_args);
364 bsd_args->sysmsg_result = sendmsg_args.sysmsg_result;
368 struct linux_socket_args {
375 linux_socket(struct linux_socket_args *args, int *res)
377 struct linux_socket_args linux_args;
378 struct socket_args bsd_args;
382 if ((error = copyin(args, &linux_args, sizeof(linux_args))))
385 bsd_args.sysmsg_result = 0;
386 bsd_args.protocol = linux_args.protocol;
387 bsd_args.type = linux_args.type;
388 bsd_args.domain = linux_to_bsd_domain(linux_args.domain);
389 if (bsd_args.domain == -1)
392 retval_socket = socket(&bsd_args);
393 /* Copy back the return value from socket() */
394 *res = bsd_args.sysmsg_result;
395 if (bsd_args.type == SOCK_RAW
396 && (bsd_args.protocol == IPPROTO_RAW || bsd_args.protocol == 0)
397 && bsd_args.domain == AF_INET
398 && retval_socket >= 0) {
399 /* It's a raw IP socket: set the IP_HDRINCL option. */
400 struct setsockopt_args /* {
406 } */ bsd_setsockopt_args;
410 sg = stackgap_init();
411 hdrincl = (int *)stackgap_alloc(&sg, sizeof(*hdrincl));
413 bsd_setsockopt_args.s = bsd_args.sysmsg_result;
414 bsd_setsockopt_args.level = IPPROTO_IP;
415 bsd_setsockopt_args.name = IP_HDRINCL;
416 bsd_setsockopt_args.val = (caddr_t)hdrincl;
417 bsd_setsockopt_args.valsize = sizeof(*hdrincl);
418 /* We ignore any error returned by setsockopt() */
419 setsockopt(&bsd_setsockopt_args);
422 return (retval_socket);
425 struct linux_bind_args {
427 struct sockaddr *name;
432 linux_bind(struct linux_bind_args *args, int *res)
434 struct linux_bind_args linux_args;
438 error = copyin(args, &linux_args, sizeof(linux_args));
441 error = linux_getsockaddr(&sa, linux_args.name, linux_args.namelen);
445 error = kern_bind(linux_args.s, sa);
451 struct linux_connect_args {
453 struct sockaddr * name;
456 int linux_connect(struct linux_connect_args *, int *res);
457 #endif /* !__alpha__*/
460 linux_connect(struct linux_connect_args *args, int *res)
462 struct thread *td = curthread; /* XXX */
463 struct proc *p = td->td_proc;
464 struct linux_connect_args linux_args;
472 error = copyin(args, &linux_args, sizeof(linux_args));
475 error = linux_getsockaddr(&sa, linux_args.name, linux_args.namelen);
479 error = kern_connect(linux_args.s, sa);
482 if (error != EISCONN)
486 * Linux doesn't return EISCONN the first time it occurs,
487 * when on a non-blocking socket. Instead it returns the
488 * error getsockopt(SOL_SOCKET, SO_ERROR) would return on BSD.
490 error = holdsock(p->p_fd, linux_args.s, &fp);
494 if (fp->f_flag & FNONBLOCK) {
495 so = (struct socket *)fp->f_data;
496 if (so->so_emuldata == 0)
497 error = so->so_error;
498 so->so_emuldata = (void *)1;
506 struct linux_listen_args {
512 linux_listen(struct linux_listen_args *args, int *res)
514 struct linux_listen_args linux_args;
515 struct listen_args /* {
521 if ((error = copyin(args, &linux_args, sizeof(linux_args))))
524 bsd_args.sysmsg_result = 0;
525 bsd_args.s = linux_args.s;
526 bsd_args.backlog = linux_args.backlog;
527 error = listen(&bsd_args);
528 *res = bsd_args.sysmsg_result;
532 struct linux_accept_args {
534 struct sockaddr *addr;
539 linux_accept(struct linux_accept_args *args, int *res)
541 struct linux_accept_args linux_args;
542 struct fcntl_args /* {
547 struct sockaddr *sa = NULL;
550 error = copyin(args, &linux_args, sizeof(linux_args));
554 if (linux_args.addr) {
555 error = copyin(linux_args.namelen, &sa_len, sizeof(sa_len));
559 error = kern_accept(linux_args.s, &sa, &sa_len, res);
563 * Return a namelen of zero for older code which
564 * might ignore the return value from accept().
567 copyout(&sa_len, linux_args.namelen,
568 sizeof(*linux_args.namelen));
571 * Convert to the Linux sockaddr strucuture.
573 *(u_short *)sa = sa->sa_family;
574 error = copyout(sa, linux_args.addr, sa_len);
576 error = copyout(&sa_len, linux_args.namelen,
577 sizeof(*linux_args.namelen));
583 error = kern_accept(linux_args.s, NULL, 0, res);
590 * linux appears not to copy flags from the parent socket to the
591 * accepted one, so we must clear the flags in the new descriptor.
592 * Ignore any errors, because we already have an open fd.
595 f_args.cmd = F_SETFL;
597 (void)fcntl(&f_args);
601 struct linux_getsockname_args {
603 struct sockaddr *addr;
608 linux_getsockname(struct linux_getsockname_args *args, int *res)
610 struct linux_getsockname_args linux_args;
611 struct getsockname_args /* {
618 if ((error = copyin(args, &linux_args, sizeof(linux_args))))
621 bsd_args.sysmsg_result = 0;
622 bsd_args.fdes = linux_args.s;
623 bsd_args.asa = (caddr_t) linux_args.addr;
624 bsd_args.alen = linux_args.namelen;
625 error = ogetsockname(&bsd_args);
626 *res = bsd_args.sysmsg_result;
630 struct linux_getpeername_args {
632 struct sockaddr *addr;
637 linux_getpeername(struct linux_getpeername_args *args, int *res)
639 struct linux_getpeername_args linux_args;
640 struct ogetpeername_args /* {
647 if ((error = copyin(args, &linux_args, sizeof(linux_args))))
650 bsd_args.sysmsg_result = 0;
651 bsd_args.fdes = linux_args.s;
652 bsd_args.asa = (caddr_t) linux_args.addr;
653 bsd_args.alen = linux_args.namelen;
654 error = ogetpeername(&bsd_args);
655 *res = bsd_args.sysmsg_result;
659 struct linux_socketpair_args {
667 linux_socketpair(struct linux_socketpair_args *args, int *res)
669 struct linux_socketpair_args linux_args;
670 struct socketpair_args /* {
678 if ((error = copyin(args, &linux_args, sizeof(linux_args))))
681 bsd_args.domain = linux_to_bsd_domain(linux_args.domain);
682 if (bsd_args.domain == -1)
685 bsd_args.sysmsg_result = 0;
686 bsd_args.type = linux_args.type;
687 bsd_args.protocol = linux_args.protocol;
688 bsd_args.rsv = linux_args.rsv;
689 error = socketpair(&bsd_args);
690 *res = bsd_args.sysmsg_result;
694 struct linux_send_args {
702 linux_send(struct linux_send_args *args, int *res)
704 struct linux_send_args linux_args;
705 struct osend_args /* {
713 if ((error = copyin(args, &linux_args, sizeof(linux_args))))
716 bsd_args.sysmsg_result = 0;
717 bsd_args.s = linux_args.s;
718 bsd_args.buf = linux_args.msg;
719 bsd_args.len = linux_args.len;
720 bsd_args.flags = linux_args.flags;
721 error = osend(&bsd_args);
722 *res = bsd_args.sysmsg_result;
726 struct linux_recv_args {
734 linux_recv(struct linux_recv_args *args, int *res)
736 struct linux_recv_args linux_args;
737 struct orecv_args /* {
745 if ((error = copyin(args, &linux_args, sizeof(linux_args))))
748 bsd_args.sysmsg_result = 0;
749 bsd_args.s = linux_args.s;
750 bsd_args.buf = linux_args.msg;
751 bsd_args.len = linux_args.len;
752 bsd_args.flags = linux_args.flags;
753 error = orecv(&bsd_args);
754 *res = bsd_args.sysmsg_result;
758 struct linux_sendto_args {
768 linux_sendto(struct linux_sendto_args *args, int *res)
770 struct linux_sendto_args linux_args;
771 struct sendto_args /* {
781 if ((error = copyin(args, &linux_args, sizeof(linux_args))))
784 bsd_args.sysmsg_result = 0;
785 bsd_args.s = linux_args.s;
786 bsd_args.buf = linux_args.msg;
787 bsd_args.len = linux_args.len;
788 bsd_args.flags = linux_args.flags;
789 bsd_args.to = linux_args.to;
790 bsd_args.tolen = linux_args.tolen;
792 if (linux_check_hdrincl(linux_args.s) == 0)
793 /* IP_HDRINCL set, tweak the packet before sending */
794 return (linux_sendto_hdrincl(&bsd_args));
796 error = sendto(&bsd_args);
797 *res = bsd_args.sysmsg_result;
801 struct linux_recvfrom_args {
811 linux_recvfrom(struct linux_recvfrom_args *args, int *res)
813 struct linux_recvfrom_args linux_args;
814 struct recvfrom_args /* {
824 if ((error = copyin(args, &linux_args, sizeof(linux_args))))
827 bsd_args.sysmsg_result = 0;
828 bsd_args.s = linux_args.s;
829 bsd_args.buf = linux_args.buf;
830 bsd_args.len = linux_args.len;
831 bsd_args.flags = linux_to_bsd_msg_flags(linux_args.flags);
832 bsd_args.from = linux_args.from;
833 bsd_args.fromlenaddr = linux_args.fromlen;
834 error = orecvfrom(&bsd_args);
835 *res = bsd_args.sysmsg_result;
839 struct linux_recvmsg_args {
846 linux_recvmsg(struct linux_recvmsg_args *args, int *res)
848 struct linux_recvmsg_args linux_args;
849 struct recvmsg_args /* {
856 if ((error = copyin(args, &linux_args, sizeof(linux_args))))
859 bsd_args.sysmsg_result = 0;
860 bsd_args.s = linux_args.s;
861 bsd_args.msg = linux_args.msg;
862 bsd_args.flags = linux_to_bsd_msg_flags(linux_args.flags);
863 error = recvmsg(&bsd_args);
864 *res = bsd_args.sysmsg_result;
868 struct linux_shutdown_args {
874 linux_shutdown(struct linux_shutdown_args *args, int *res)
876 struct linux_shutdown_args linux_args;
877 struct shutdown_args /* {
883 if ((error = copyin(args, &linux_args, sizeof(linux_args))))
886 bsd_args.sysmsg_result = 0;
887 bsd_args.s = linux_args.s;
888 bsd_args.how = linux_args.how;
889 error = shutdown(&bsd_args);
890 *res = bsd_args.sysmsg_result;
894 struct linux_setsockopt_args {
903 linux_setsockopt(struct linux_setsockopt_args *args, int *res)
905 struct linux_setsockopt_args linux_args;
906 struct setsockopt_args /* {
915 if ((error = copyin(args, &linux_args, sizeof(linux_args))))
918 bsd_args.sysmsg_result = 0;
919 bsd_args.s = linux_args.s;
920 bsd_args.level = linux_to_bsd_sockopt_level(linux_args.level);
921 switch (bsd_args.level) {
923 name = linux_to_bsd_so_sockopt(linux_args.optname);
926 name = linux_to_bsd_ip_sockopt(linux_args.optname);
929 /* Linux TCP option values match BSD's */
930 name = linux_args.optname;
939 bsd_args.name = name;
940 bsd_args.val = linux_args.optval;
941 bsd_args.valsize = linux_args.optlen;
942 error = setsockopt(&bsd_args);
943 *res = bsd_args.sysmsg_result;
947 struct linux_getsockopt_args {
956 linux_getsockopt(struct linux_getsockopt_args *args, int *res)
958 struct linux_getsockopt_args linux_args;
959 struct getsockopt_args /* {
968 if ((error = copyin(args, &linux_args, sizeof(linux_args))))
971 bsd_args.sysmsg_result = 0;
972 bsd_args.s = linux_args.s;
973 bsd_args.level = linux_to_bsd_sockopt_level(linux_args.level);
974 switch (bsd_args.level) {
976 name = linux_to_bsd_so_sockopt(linux_args.optname);
979 name = linux_to_bsd_ip_sockopt(linux_args.optname);
982 /* Linux TCP option values match BSD's */
983 name = linux_args.optname;
992 bsd_args.name = name;
993 bsd_args.val = linux_args.optval;
994 bsd_args.avalsize = linux_args.optlen;
995 error = getsockopt(&bsd_args);
996 *res = bsd_args.sysmsg_result;
1001 linux_socketcall(struct linux_socketcall_args *args)
1003 void *arg = (void *)args->args;
1005 switch (args->what) {
1007 return (linux_socket(arg, &args->sysmsg_result));
1009 return (linux_bind(arg, &args->sysmsg_result));
1011 return (linux_connect(arg, &args->sysmsg_result));
1013 return (linux_listen(arg, &args->sysmsg_result));
1015 return (linux_accept(arg, &args->sysmsg_result));
1016 case LINUX_GETSOCKNAME:
1017 return (linux_getsockname(arg, &args->sysmsg_result));
1018 case LINUX_GETPEERNAME:
1019 return (linux_getpeername(arg, &args->sysmsg_result));
1020 case LINUX_SOCKETPAIR:
1021 return (linux_socketpair(arg, &args->sysmsg_result));
1023 return (linux_send(arg, &args->sysmsg_result));
1025 return (linux_recv(arg, &args->sysmsg_result));
1027 return (linux_sendto(arg, &args->sysmsg_result));
1028 case LINUX_RECVFROM:
1029 return (linux_recvfrom(arg, &args->sysmsg_result));
1030 case LINUX_SHUTDOWN:
1031 return (linux_shutdown(arg, &args->sysmsg_result));
1032 case LINUX_SETSOCKOPT:
1033 return (linux_setsockopt(arg, &args->sysmsg_result));
1034 case LINUX_GETSOCKOPT:
1035 return (linux_getsockopt(arg, &args->sysmsg_result));
1041 struct sendmsg_args bsd_args;
1043 error = copyin(arg, &bsd_args.s, sizeof(bsd_args) - offsetof(struct sendmsg_args, s));
1046 error = copyin(&((struct msghdr *)bsd_args.msg)->msg_control, &control,
1051 if (control == NULL)
1054 error = copyin(&((struct cmsghdr*)control)->cmsg_level,
1055 &level, sizeof(int));
1061 * Linux thinks that SOL_SOCKET is 1; we know
1062 * that it's really 0xffff, of course.
1065 error = copyout(&level,
1066 &((struct cmsghdr *)control)->cmsg_level,
1072 bsd_args.sysmsg_result = 0;
1073 error = sendmsg(&bsd_args);
1074 args->sysmsg_result = bsd_args.sysmsg_result;
1078 return (linux_recvmsg(arg, &args->sysmsg_result));
1081 uprintf("LINUX: 'socket' typ=%d not implemented\n", args->what);
1084 #endif /*!__alpha__*/