diff options
-rw-r--r-- | source4/libcli/raw/clitransport.c | 68 | ||||
-rw-r--r-- | source4/libcli/raw/interfaces.h | 18 |
2 files changed, 86 insertions, 0 deletions
diff --git a/source4/libcli/raw/clitransport.c b/source4/libcli/raw/clitransport.c index ea2aa880b6..71c87e631a 100644 --- a/source4/libcli/raw/clitransport.c +++ b/source4/libcli/raw/clitransport.c @@ -593,3 +593,71 @@ void smbcli_transport_send(struct smbcli_request *req) talloc_set_destructor(req, smbcli_request_destructor); } + + +/**************************************************************************** + Send an SMBecho (async send) +*****************************************************************************/ +struct smbcli_request *smb_raw_echo_send(struct smbcli_transport *transport, + struct smb_echo *p) +{ + struct smbcli_request *req; + + req = smbcli_request_setup_transport(transport, SMBecho, 1, p->in.size); + if (!req) return NULL; + + SSVAL(req->out.vwv, VWV(0), p->in.repeat_count); + + memcpy(req->out.data, p->in.data, p->in.size); + + ZERO_STRUCT(p->out); + + if (!smbcli_request_send(req)) { + smbcli_request_destroy(req); + return NULL; + } + + return req; +} + +/**************************************************************************** + raw echo interface (async recv) +****************************************************************************/ +NTSTATUS smb_raw_echo_recv(struct smbcli_request *req, TALLOC_CTX *mem_ctx, + struct smb_echo *p) +{ + if (!smbcli_request_receive(req) || + smbcli_request_is_error(req)) { + goto failed; + } + + SMBCLI_CHECK_WCT(req, 1); + p->out.count++; + p->out.sequence_number = SVAL(req->in.vwv, VWV(0)); + p->out.size = req->in.data_size; + talloc_free(p->out.data); + p->out.data = talloc_size(mem_ctx, p->out.size); + NT_STATUS_HAVE_NO_MEMORY(p->out.data); + + if (!smbcli_raw_pull_data(req, req->in.data, p->out.size, p->out.data)) { + req->status = NT_STATUS_BUFFER_TOO_SMALL; + } + + if (p->out.count == p->in.repeat_count) { + return smbcli_request_destroy(req); + } + + return NT_STATUS_OK; + +failed: + return smbcli_request_destroy(req); +} + +/**************************************************************************** + Send a echo (sync interface) +*****************************************************************************/ +NTSTATUS smb_raw_echo(struct smbcli_transport *transport, struct smb_echo *p) +{ + struct smbcli_request *req = smb_raw_echo_send(transport, p); + return smbcli_request_simple_recv(req); +} diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index d0c3ab2d15..93d8dd2c20 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -2614,4 +2614,22 @@ union smb_search_close { } findclose; }; + +/* + struct for SMBecho call +*/ +struct smb_echo { + struct { + uint16_t repeat_count; + uint16_t size; + uint8_t *data; + } in; + struct { + uint16_t count; + uint16_t sequence_number; + uint16_t size; + uint8_t *data; + } out; +}; + #endif /* __LIBCLI_RAW_INTERFACES_H__ */ |