1 /* $NetBSD: ipc_method.c,v 1.6 2013/11/27 20:52:24 christos Exp $ */
4 * Rob Zimmermann. All rights reserved.
6 * Keith Bostic. All rights reserved.
8 * See the LICENSE file for redistribution information.
13 #include <sys/types.h>
14 #include <sys/queue.h>
17 #include <bitstring.h>
27 #include "../common/common.h"
30 static int vi_send_
__P((IPVIWIN
*, int));
31 static int vi_send_1
__P((IPVIWIN
*, int, u_int32_t
));
32 static int vi_send_12
__P((IPVIWIN
*ipvi
, int code
, u_int32_t val1
, u_int32_t val2
));
34 static int vi_send_ab1
__P((IPVIWIN
*ipvi
, int code
,
35 const char *str1
, u_int32_t len1
,
36 const char *str2
, u_int32_t len2
, u_int32_t val
));
37 static int vi_send_a1
__P((IPVIWIN
*ipvi
, int code
, const char *str
, u_int32_t len
,
40 static int vi_send_a
__P((IPVIWIN
*ipvi
, int code
, const char *str
, u_int32_t len
));
44 static int vi_set_ops
__P((IPVIWIN
*, IPSIOPS
*));
45 static int vi_win_close
__P((IPVIWIN
*));
47 static int vi_close
__P((IPVI
*));
48 static int vi_new_window
__P((IPVI
*, IPVIWIN
**, int));
53 * PUBLIC: int vi_create __P((IPVI **, u_int32_t));
56 vi_create(IPVI
**ipvip
, u_int32_t flags
)
60 MALLOC_GOTO(NULL
, ipvi
, IPVI
*, sizeof(IPVI
));
61 memset(ipvi
, 0, sizeof(IPVI
));
66 ipvi
->new_window
= vi_new_window
;
67 ipvi
->close
= vi_close
;
78 vi_new_window (IPVI
*ipvi
, IPVIWIN
**ipviwinp
, int fd
)
82 MALLOC_GOTO(NULL
, ipviwin
, IPVIWIN
*, sizeof(IPVIWIN
));
83 memset(ipviwin
, 0, sizeof(IPVIWIN
));
86 ipviwin
->ifd
= ipvi
->ifd
;
87 ipviwin
->ofd
= ipvi
->ofd
;
95 if (socketpair(AF_LOCAL
, SOCK_STREAM
, 0, sockets
) == -1)
98 memset(&mh
, 0, sizeof(mh
));
102 mh
.msg_controllen
= sizeof(ch
);
103 mh
.msg_control
= (void *)&ch
;
106 iov
.iov_base
= &dummy
;
108 ch
.header
.cmsg_level
= SOL_SOCKET
;
109 ch
.header
.cmsg_type
= SCM_RIGHTS
;
110 ch
.header
.cmsg_len
= sizeof(ch
);
112 *(int *)CMSG_DATA(&ch
.header
) = sockets
[1];
113 if (sendmsg(ipvi
->ofd
, &mh
, 0) == -1)
115 dummy
= (fd
== -1) ? ' ' : 'F';
116 *(int *)CMSG_DATA(&ch
.header
) = sockets
[1];
117 sendmsg(sockets
[0], &mh
, 0);
121 *(int *)CMSG_DATA(&ch
.header
) = fd
;
122 if (sendmsg(sockets
[0], &mh
, 0) == -1)
127 ipviwin
->ifd
= sockets
[0];
128 ipviwin
->ofd
= sockets
[0];
131 #define IPVISET(func) \
132 ipviwin->func = vi_##func;
152 ipviwin
->close
= vi_win_close
;
166 vi_set_ops(IPVIWIN
*ipvi
, IPSIOPS
*ops
)
172 static int vi_close(IPVI
*ipvi
)
174 memset(ipvi
, 6, sizeof(IPVI
));
179 static int vi_win_close(IPVIWIN
*ipviwin
)
181 memset(ipviwin
, 6, sizeof(IPVIWIN
));
188 vi_send_(IPVIWIN
*ipvi
, int code
)
192 memset(&ipb
, 0, sizeof(ipb
));
194 return vi_send(ipvi
->ofd
, NULL
, &ipb
);
198 vi_send_1(IPVIWIN
*ipvi
, int code
, u_int32_t val
)
202 memset(&ipb
, 0, sizeof(ipb
));
205 return vi_send(ipvi
->ofd
, "1", &ipb
);
209 vi_send_12(IPVIWIN
*ipvi
, int code
, u_int32_t val1
, u_int32_t val2
)
213 memset(&ipb
, 0, sizeof(ipb
));
217 return vi_send(ipvi
->ofd
, "12", &ipb
);
221 vi_send_a(IPVIWIN
*ipvi
, int code
, const char *str
, u_int32_t len
)
225 memset(&ipb
, 0, sizeof(ipb
));
229 return vi_send(ipvi
->ofd
, "a", &ipb
);
234 vi_send_a1(IPVIWIN
*ipvi
, int code
, const char *str
, u_int32_t len
,
239 memset(&ipb
, 0, sizeof(ipb
));
244 return vi_send(ipvi
->ofd
, "a1", &ipb
);
248 vi_send_ab1(IPVIWIN
*ipvi
, int code
, const char *str1
, u_int32_t len1
,
249 const char *str2
, u_int32_t len2
, u_int32_t val
)
253 memset(&ipb
, 0, sizeof(ipb
));
260 return vi_send(ipvi
->ofd
, "ab1", &ipb
);