1 /***********************************************************************/
5 /* Xavier Leroy, projet Cristal, INRIA Rocquencourt */
7 /* Copyright 1996 Institut National de Recherche en Informatique et */
8 /* en Automatique. All rights reserved. This file is distributed */
9 /* under the terms of the GNU Library General Public License, with */
10 /* the special exception on linking described in file ../../LICENSE. */
12 /***********************************************************************/
21 #include "unixsupport.h"
25 #include "socketaddr.h"
28 #define EAFNOSUPPORT WSAEAFNOSUPPORT
31 CAMLexport value
alloc_inet_addr(struct in_addr
* a
)
34 /* Use a string rather than an abstract block so that it can be
35 marshaled safely. Remember that a is in network byte order,
36 hence is marshaled in an endian-independent manner. */
37 res
= alloc_string(4);
38 memcpy(String_val(res
), a
, 4);
44 CAMLexport value
alloc_inet6_addr(struct in6_addr
* a
)
47 res
= alloc_string(16);
48 memcpy(String_val(res
), a
, 16);
54 void get_sockaddr(value mladr
,
55 union sock_addr_union
* adr
/*out*/,
56 socklen_param_type
* adr_len
/*out*/)
58 switch(Tag_val(mladr
)) {
60 case 0: /* ADDR_UNIX */
63 path
= Field(mladr
, 0);
64 len
= string_length(path
);
65 adr
->s_unix
.sun_family
= AF_UNIX
;
66 if (len
>= sizeof(adr
->s_unix
.sun_path
)) {
67 unix_error(ENAMETOOLONG
, "", path
);
69 memmove (adr
->s_unix
.sun_path
, String_val(path
), len
+ 1);
71 ((char *)&(adr
->s_unix
.sun_path
) - (char *)&(adr
->s_unix
))
76 case 1: /* ADDR_INET */
78 if (string_length(Field(mladr
, 0)) == 16) {
79 memset(&adr
->s_inet6
, 0, sizeof(struct sockaddr_in6
));
80 adr
->s_inet6
.sin6_family
= AF_INET6
;
81 adr
->s_inet6
.sin6_addr
= GET_INET6_ADDR(Field(mladr
, 0));
82 adr
->s_inet6
.sin6_port
= htons(Int_val(Field(mladr
, 1)));
83 *adr_len
= sizeof(struct sockaddr_in6
);
87 memset(&adr
->s_inet
, 0, sizeof(struct sockaddr_in
));
88 adr
->s_inet
.sin_family
= AF_INET
;
89 adr
->s_inet
.sin_addr
= GET_INET_ADDR(Field(mladr
, 0));
90 adr
->s_inet
.sin_port
= htons(Int_val(Field(mladr
, 1)));
91 *adr_len
= sizeof(struct sockaddr_in
);
96 value
alloc_sockaddr(union sock_addr_union
* adr
/*in*/,
97 socklen_param_type adr_len
, int close_on_error
)
100 switch(adr
->s_gen
.sa_family
) {
103 { value n
= copy_string(adr
->s_unix
.sun_path
);
105 res
= alloc_small(1, 0);
112 { value a
= alloc_inet_addr(&adr
->s_inet
.sin_addr
);
114 res
= alloc_small(2, 1);
116 Field(res
,1) = Val_int(ntohs(adr
->s_inet
.sin_port
));
122 { value a
= alloc_inet6_addr(&adr
->s_inet6
.sin6_addr
);
124 res
= alloc_small(2, 1);
126 Field(res
,1) = Val_int(ntohs(adr
->s_inet6
.sin6_port
));
132 if (close_on_error
!= -1) close (close_on_error
);
133 unix_error(EAFNOSUPPORT
, "", Nothing
);