2 Unix SMB/CIFS implementation.
4 Copyright (C) Stefan Metzmacher 2004
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 NTSTATUS socket_create(const char *name, enum socket_type type, struct socket_context **new_sock, uint32_t flags)
27 (*new_sock) = talloc_p(NULL, struct socket_context);
29 return NT_STATUS_NO_MEMORY;
32 (*new_sock)->type = type;
33 (*new_sock)->state = SOCKET_STATE_UNDEFINED;
34 (*new_sock)->flags = flags;
38 (*new_sock)->private_data = NULL;
39 (*new_sock)->ops = socket_getops_byname(name, type);
40 if (!(*new_sock)->ops) {
41 talloc_free((*new_sock));
42 return NT_STATUS_INVALID_PARAMETER;
45 status = (*new_sock)->ops->init((*new_sock));
46 if (!NT_STATUS_IS_OK(status)) {
47 talloc_free((*new_sock));
54 void socket_destroy(struct socket_context *sock)
56 if (sock->ops->close) {
57 sock->ops->close(sock);
62 NTSTATUS socket_connect(struct socket_context *sock,
63 const char *my_address, int my_port,
64 const char *server_address, int server_port,
67 if (sock->type != SOCKET_TYPE_STREAM) {
68 return NT_STATUS_INVALID_PARAMETER;
71 if (sock->state != SOCKET_STATE_UNDEFINED) {
72 return NT_STATUS_INVALID_PARAMETER;
75 if (!sock->ops->connect) {
76 return NT_STATUS_NOT_IMPLEMENTED;
79 return sock->ops->connect(sock, my_address, my_port, server_address, server_port, flags);
82 NTSTATUS socket_listen(struct socket_context *sock, const char *my_address, int port, int queue_size, uint32_t flags)
84 if (sock->type != SOCKET_TYPE_STREAM) {
85 return NT_STATUS_INVALID_PARAMETER;
88 if (sock->state != SOCKET_STATE_UNDEFINED) {
89 return NT_STATUS_INVALID_PARAMETER;
92 if (!sock->ops->listen) {
93 return NT_STATUS_NOT_IMPLEMENTED;
96 return sock->ops->listen(sock, my_address, port, queue_size, flags);
99 NTSTATUS socket_accept(struct socket_context *sock, struct socket_context **new_sock, uint32_t flags)
101 if (sock->type != SOCKET_TYPE_STREAM) {
102 return NT_STATUS_INVALID_PARAMETER;
105 if (sock->state != SOCKET_STATE_SERVER_LISTEN) {
106 return NT_STATUS_INVALID_PARAMETER;
109 if (!sock->ops->accept) {
110 return NT_STATUS_NOT_IMPLEMENTED;
113 return sock->ops->accept(sock, new_sock, flags);
116 NTSTATUS socket_recv(struct socket_context *sock, TALLOC_CTX *mem_ctx,
117 DATA_BLOB *blob, size_t wantlen, uint32_t flags)
119 if (sock->type != SOCKET_TYPE_STREAM) {
120 return NT_STATUS_INVALID_PARAMETER;
123 if (sock->state != SOCKET_STATE_CLIENT_CONNECTED &&
124 sock->state != SOCKET_STATE_SERVER_CONNECTED) {
125 return NT_STATUS_INVALID_PARAMETER;
128 if (!sock->ops->recv) {
129 return NT_STATUS_NOT_IMPLEMENTED;
132 return sock->ops->recv(sock, mem_ctx, blob, wantlen, flags);
135 NTSTATUS socket_send(struct socket_context *sock, TALLOC_CTX *mem_ctx,
136 const DATA_BLOB *blob, size_t *sendlen, uint32_t flags)
138 if (sock->type != SOCKET_TYPE_STREAM) {
139 return NT_STATUS_INVALID_PARAMETER;
142 if (sock->state != SOCKET_STATE_CLIENT_CONNECTED &&
143 sock->state != SOCKET_STATE_SERVER_CONNECTED) {
144 return NT_STATUS_INVALID_PARAMETER;
147 if (!sock->ops->send) {
148 return NT_STATUS_NOT_IMPLEMENTED;
151 return sock->ops->send(sock, mem_ctx, blob, sendlen, flags);
154 NTSTATUS socket_set_option(struct socket_context *sock, const char *option, const char *val)
156 if (!sock->ops->set_option) {
157 return NT_STATUS_NOT_IMPLEMENTED;
160 return sock->ops->set_option(sock, option, val);
163 char *socket_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx)
165 if (!sock->ops->get_peer_name) {
169 return sock->ops->get_peer_name(sock, mem_ctx);
172 char *socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
174 if (!sock->ops->get_peer_addr) {
178 return sock->ops->get_peer_addr(sock, mem_ctx);
181 int socket_get_peer_port(struct socket_context *sock)
183 if (!sock->ops->get_peer_port) {
187 return sock->ops->get_peer_port(sock);
190 char *socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
192 if (!sock->ops->get_my_addr) {
196 return sock->ops->get_my_addr(sock, mem_ctx);
199 int socket_get_my_port(struct socket_context *sock)
201 if (!sock->ops->get_my_port) {
205 return sock->ops->get_my_port(sock);
208 int socket_get_fd(struct socket_context *sock)
210 if (!sock->ops->get_fd) {
214 return sock->ops->get_fd(sock);
217 const struct socket_ops *socket_getops_byname(const char *name, enum socket_type type)
219 if (strequal("ip", name) || strequal("ipv4", name)) {
220 return socket_ipv4_ops();