1
0
mirror of https://github.com/samba-team/samba.git synced 2025-12-14 20:23:54 +03:00
Files
samba-mirror/source/libcli/raw/clisocket.c
Andrew Tridgell 2e25c71853 r3443: the next stage in the include files re-organisation.
I have created the include/system/ directory, which will contain the
wrappers for the system includes for logical subsystems. So far I have
created include/system/kerberos.h and include/system/network.h, which
contain all the system includes for kerberos code and networking code.
These are the included in subsystems that need kerberos or networking
respectively.

Note that this method avoids the mess of #ifdef HAVE_XXX_H in every C
file, instead each C module includes the include/system/XXX.h file for
the logical system support it needs, and the details are kept isolated
in include/system/

This patch also creates a "struct ipv4_addr" which replaces "struct
in_addr" in our code. That avoids every C file needing to import all
the system networking headers.
2007-10-10 13:05:11 -05:00

196 lines
4.7 KiB
C

/*
Unix SMB/CIFS implementation.
SMB client socket context management functions
Copyright (C) Andrew Tridgell 1994-2003
Copyright (C) James Myers 2003 <myersjj@samba.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "libcli/raw/libcliraw.h"
/*
create a smbcli_socket context
*/
struct smbcli_socket *smbcli_sock_init(TALLOC_CTX *mem_ctx)
{
struct smbcli_socket *sock;
sock = talloc_p(mem_ctx, struct smbcli_socket);
if (!sock) {
return NULL;
}
ZERO_STRUCTP(sock);
sock->sock = NULL;
sock->port = 0;
/* 20 second default timeout */
sock->timeout = 20000;
sock->hostname = NULL;
return sock;
}
/*
connect a smbcli_socket context to an IP/port pair
if port is 0 then choose 445 then 139
*/
BOOL smbcli_sock_connect(struct smbcli_socket *sock, struct ipv4_addr *ip, int port)
{
NTSTATUS status;
if (port == 0) {
int i;
const char **ports = lp_smb_ports();
for (i=0;ports[i];i++) {
port = atoi(ports[i]);
if (port != 0 && smbcli_sock_connect(sock, ip, port)) {
return True;
}
}
return False;
}
status = socket_create("ip", SOCKET_TYPE_STREAM, &sock->sock, 0);
if (!NT_STATUS_IS_OK(status)) {
return False;
}
talloc_steal(sock, sock->sock);
status = socket_connect(sock->sock, NULL, 0, sys_inet_ntoa(*ip), port, 0);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(sock->sock);
sock->sock = NULL;
return False;
}
sock->dest_ip = *ip;
sock->port = port;
socket_set_option(sock->sock, lp_socket_options(), NULL);
return True;
}
/****************************************************************************
mark the socket as dead
****************************************************************************/
void smbcli_sock_dead(struct smbcli_socket *sock)
{
if (sock->sock != NULL) {
talloc_free(sock->sock);
sock->sock = NULL;
}
}
/****************************************************************************
Set socket options on a open connection.
****************************************************************************/
void smbcli_sock_set_options(struct smbcli_socket *sock, const char *options)
{
socket_set_option(sock->sock, options, NULL);
}
/****************************************************************************
Write to socket. Return amount written.
****************************************************************************/
ssize_t smbcli_sock_write(struct smbcli_socket *sock, const char *data, size_t len)
{
NTSTATUS status;
DATA_BLOB blob;
size_t nsent;
if (sock->sock == NULL) {
errno = EIO;
return -1;
}
blob.data = discard_const(data);
blob.length = len;
status = socket_send(sock->sock, &blob, &nsent, 0);
if (NT_STATUS_IS_ERR(status)) {
return -1;
}
return nsent;
}
/****************************************************************************
Read from socket. return amount read
****************************************************************************/
ssize_t smbcli_sock_read(struct smbcli_socket *sock, char *data, size_t len)
{
NTSTATUS status;
size_t nread;
if (sock->sock == NULL) {
errno = EIO;
return -1;
}
status = socket_recv(sock->sock, data, len, &nread, 0);
if (NT_STATUS_IS_ERR(status)) {
return -1;
}
return nread;
}
/****************************************************************************
resolve a hostname and connect
****************************************************************************/
BOOL smbcli_sock_connect_byname(struct smbcli_socket *sock, const char *host, int port)
{
int name_type = 0x20;
struct ipv4_addr ip;
char *name, *p;
BOOL ret;
#if 0
if (getenv("LIBSMB_PROG")) {
sock->fd = sock_exec(getenv("LIBSMB_PROG"));
return sock->fd != -1;
}
#endif
name = talloc_strdup(sock, host);
/* allow hostnames of the form NAME#xx and do a netbios lookup */
if ((p = strchr(name, '#'))) {
name_type = strtol(p+1, NULL, 16);
*p = 0;
}
if (!resolve_name(name, name, &ip, name_type)) {
talloc_free(name);
return False;
}
ret = smbcli_sock_connect(sock, &ip, port);
if (ret) {
sock->hostname = talloc_steal(sock, name);
} else {
talloc_free(name);
}
return ret;
}