|
Packit Service |
392537 |
/*
|
|
Packit Service |
392537 |
* Copyright (c) 1998,1999,2000
|
|
Packit Service |
392537 |
* Traakan, Inc., Los Altos, CA
|
|
Packit Service |
392537 |
* All rights reserved.
|
|
Packit Service |
392537 |
*
|
|
Packit Service |
392537 |
* Redistribution and use in source and binary forms, with or without
|
|
Packit Service |
392537 |
* modification, are permitted provided that the following conditions
|
|
Packit Service |
392537 |
* are met:
|
|
Packit Service |
392537 |
* 1. Redistributions of source code must retain the above copyright
|
|
Packit Service |
392537 |
* notice unmodified, this list of conditions, and the following
|
|
Packit Service |
392537 |
* disclaimer.
|
|
Packit Service |
392537 |
* 2. Redistributions in binary form must reproduce the above copyright
|
|
Packit Service |
392537 |
* notice, this list of conditions and the following disclaimer in the
|
|
Packit Service |
392537 |
* documentation and/or other materials provided with the distribution.
|
|
Packit Service |
392537 |
*
|
|
Packit Service |
392537 |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
Packit Service |
392537 |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
Packit Service |
392537 |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
Packit Service |
392537 |
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
|
Packit Service |
392537 |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
Packit Service |
392537 |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
Packit Service |
392537 |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
Packit Service |
392537 |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
Packit Service |
392537 |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
Packit Service |
392537 |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
Packit Service |
392537 |
* SUCH DAMAGE.
|
|
Packit Service |
392537 |
*/
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/*
|
|
Packit Service |
392537 |
* Project: NDMJOB
|
|
Packit Service |
392537 |
* Ident: $Id: $
|
|
Packit Service |
392537 |
*
|
|
Packit Service |
392537 |
* Description:
|
|
Packit Service |
392537 |
*
|
|
Packit Service |
392537 |
*/
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
#include "ndmjob.h"
|
|
Packit Service |
392537 |
#include "ndmlib.h"
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
#ifndef NDMOS_OPTION_NO_NDMP4
|
|
Packit Service |
392537 |
#define MAX_PROTOCOL_VERSION NDMP4VER
|
|
Packit Service |
392537 |
#else /* !NDMOS_OPTION_NO_NDMP4 */
|
|
Packit Service |
392537 |
#ifndef NDMOS_OPTION_NO_NDMP3
|
|
Packit Service |
392537 |
#define MAX_PROTOCOL_VERSION NDMP3VER
|
|
Packit Service |
392537 |
#else /* !NDMOS_OPTION_NO_NDMP3 */
|
|
Packit Service |
392537 |
#ifndef NDMOS_OPTION_NO_NDMP2
|
|
Packit Service |
392537 |
#define MAX_PROTOCOL_VERSION NDMP2VER
|
|
Packit Service |
392537 |
#else /* !NDMOS_OPTION_NO_NDMP2 */
|
|
Packit Service |
392537 |
#define MAX_PROTOCOL_VERSION 0
|
|
Packit Service |
392537 |
#endif /* !NDMOS_OPTION_NO_NDM2 */
|
|
Packit Service |
392537 |
#endif /* !NDMOS_OPTION_NO_NDMP3 */
|
|
Packit Service |
392537 |
#endif /* !NDMOS_OPTION_NO_NDMP4 */
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/*
|
|
Packit Service |
392537 |
* INITIALIZE AND DESTRUCT
|
|
Packit Service |
392537 |
****************************************************************
|
|
Packit Service |
392537 |
*
|
|
Packit Service |
392537 |
* Initialize an ndmconn. This pretty much amounts to
|
|
Packit Service |
392537 |
* initializing the underlying ndmchan and stuffing
|
|
Packit Service |
392537 |
* the function pointers.
|
|
Packit Service |
392537 |
*/
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
struct ndmconn *
|
|
Packit Service |
392537 |
ndmconn_initialize (struct ndmconn *aconn, char *name)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
struct ndmconn * conn = aconn;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (!conn) {
|
|
Packit Service |
392537 |
conn = NDMOS_MACRO_NEW(struct ndmconn);
|
|
Packit Service |
392537 |
if (!conn)
|
|
Packit Service |
392537 |
return 0;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
NDMOS_MACRO_ZEROFILL(conn);
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (!name) name = "#?"; /* default */
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
ndmchan_initialize (&conn->chan, name);
|
|
Packit Service |
392537 |
conn->was_allocated = aconn == 0;
|
|
Packit Service |
392537 |
conn->next_sequence = 1;
|
|
Packit Service |
392537 |
xdrrec_create (&conn->xdrs, 0, 0, (void*) conn,
|
|
Packit Service |
392537 |
(void*)ndmconn_readit,
|
|
Packit Service |
392537 |
(void*)ndmconn_writeit);
|
|
Packit Service |
392537 |
conn->unexpected = ndmconn_unexpected;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
conn->call = ndmconn_call;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
conn->time_limit = 0;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
return conn;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/*
|
|
Packit Service |
392537 |
* Get rid of an ndmconn.
|
|
Packit Service |
392537 |
*/
|
|
Packit Service |
392537 |
void
|
|
Packit Service |
392537 |
ndmconn_destruct (struct ndmconn *conn)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
if (conn->chan.fd >= 0) {
|
|
Packit Service |
392537 |
close (conn->chan.fd);
|
|
Packit Service |
392537 |
conn->chan.fd = -1;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
xdr_destroy (&conn->xdrs);
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (conn->was_allocated) {
|
|
Packit Service |
392537 |
NDMOS_API_FREE (conn);
|
|
Packit Service |
392537 |
conn = 0;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/*
|
|
Packit Service |
392537 |
* ESTABLISH CONNECTION
|
|
Packit Service |
392537 |
****************************************************************
|
|
Packit Service |
392537 |
*
|
|
Packit Service |
392537 |
* The following four routines establish the TCP/IP connection
|
|
Packit Service |
392537 |
* between agents.
|
|
Packit Service |
392537 |
*
|
|
Packit Service |
392537 |
* ndmconn_connect_agent()
|
|
Packit Service |
392537 |
* make a connection per an ndmagent, uses ..._host_port()
|
|
Packit Service |
392537 |
* ndmconn_connect_host_port ()
|
|
Packit Service |
392537 |
* make a connection per a hostname and port, uses ..._sockaddr_in()
|
|
Packit Service |
392537 |
* ndmconn_connect_sockaddr_in()
|
|
Packit Service |
392537 |
* make a connection per sockaddr_in, performs NDMP_CONNECT_
|
|
Packit Service |
392537 |
* sequences, but no authentication
|
|
Packit Service |
392537 |
* ndmconn_accept()
|
|
Packit Service |
392537 |
* make a connection (receive it really) from a file descriptor
|
|
Packit Service |
392537 |
* already accept()ed.
|
|
Packit Service |
392537 |
*/
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
ndmconn_connect_agent (struct ndmconn *conn, struct ndmagent *agent)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
if (agent->conn_type == NDMCONN_TYPE_RESIDENT) {
|
|
Packit Service |
392537 |
conn->conn_type = NDMCONN_TYPE_RESIDENT;
|
|
Packit Service |
392537 |
conn->protocol_version = agent->protocol_version;
|
|
Packit Service |
392537 |
if (conn->protocol_version == 0) {
|
|
Packit Service |
392537 |
/* Let's negotiate......MAX */
|
|
Packit Service |
392537 |
conn->protocol_version = MAX_PROTOCOL_VERSION;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
ndmchan_start_resident (&conn->chan);
|
|
Packit Service |
392537 |
return 0;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (agent->port == 0) agent->port = NDMPPORT;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
return ndmconn_connect_host_port (conn,
|
|
Packit Service |
392537 |
agent->host, agent->port, agent->protocol_version);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
ndmconn_connect_host_port (struct ndmconn *conn,
|
|
Packit Service |
392537 |
char * hostname, int port, unsigned want_protocol_version)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
struct sockaddr_in sin;
|
|
Packit Service |
392537 |
char * err = "???";
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (conn->chan.fd >= 0) {
|
|
Packit Service |
392537 |
err = "already-connected";
|
|
Packit Service |
392537 |
return ndmconn_set_err_msg (conn, err);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (ndmhost_lookup (hostname, &sin) != 0) {
|
|
Packit Service |
392537 |
err = "bad-host-name";
|
|
Packit Service |
392537 |
return ndmconn_set_err_msg (conn, err);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (port == 0) port = NDMPPORT;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
sin.sin_port = htons(port);
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
return ndmconn_connect_sockaddr_in (conn, &sin, want_protocol_version);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
ndmconn_connect_sockaddr_in (struct ndmconn *conn,
|
|
Packit Service |
392537 |
struct sockaddr_in *sin, unsigned want_protocol_version)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
int fd = -1;
|
|
Packit Service |
392537 |
int rc;
|
|
Packit Service |
392537 |
char * err = "???";
|
|
Packit Service |
392537 |
unsigned max_protocol_version = MAX_PROTOCOL_VERSION;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (conn->chan.fd >= 0) {
|
|
Packit Service |
392537 |
err = "already-connected";
|
|
Packit Service |
392537 |
return ndmconn_set_err_msg (conn, err);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
fd = socket (AF_INET, SOCK_STREAM, 0);
|
|
Packit Service |
392537 |
if (fd < 0) {
|
|
Packit Service |
392537 |
err = malloc(1024);
|
|
Packit Service |
392537 |
snprintf(err, 1023, "open a socket failed: %s", strerror(errno));
|
|
Packit Service |
392537 |
goto error_out;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/* reserved port? */
|
|
Packit Service |
392537 |
if (connect (fd, (struct sockaddr *)sin, sizeof *sin) < 0) {
|
|
Packit Service |
392537 |
// leak memory
|
|
Packit Service |
392537 |
err = malloc(1024);
|
|
Packit Service |
392537 |
snprintf(err, 1023, "connect failed: %s", strerror(errno));
|
|
Packit Service |
392537 |
goto error_out;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
ndmchan_start_readchk (&conn->chan, fd);
|
|
Packit Service |
392537 |
conn->conn_type = NDMCONN_TYPE_REMOTE;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/*
|
|
Packit Service |
392537 |
* Await the NDMP_NOTIFY_CONNECTED request (no reply)
|
|
Packit Service |
392537 |
* Don't get confused that this client-side is awaiting
|
|
Packit Service |
392537 |
* a "request" from the server.
|
|
Packit Service |
392537 |
*/
|
|
Packit Service |
392537 |
NDMC_WITH_NO_REPLY(ndmp0_notify_connected,0)
|
|
Packit Service |
392537 |
rc = ndmconn_recv_nmb(conn, &xa->request);
|
|
Packit Service |
392537 |
if (rc != 0) {
|
|
Packit Service |
392537 |
err = "recv-notify-connected";
|
|
Packit Service |
392537 |
goto error_out;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
if (xa->request.header.message_type != NDMP0_MESSAGE_REQUEST
|
|
Packit Service |
392537 |
|| xa->request.header.message != NDMP0_NOTIFY_CONNECTED) {
|
|
Packit Service |
392537 |
err = "msg-not-notify-connected";
|
|
Packit Service |
392537 |
goto error_out;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (request->reason != NDMP0_CONNECTED) {
|
|
Packit Service |
392537 |
err = "notify-connected-not-connected";
|
|
Packit Service |
392537 |
goto error_out;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (max_protocol_version > request->protocol_version) {
|
|
Packit Service |
392537 |
max_protocol_version = request->protocol_version;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
NDMC_ENDWITH
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (want_protocol_version == 0) {
|
|
Packit Service |
392537 |
want_protocol_version = max_protocol_version;
|
|
Packit Service |
392537 |
} else if (want_protocol_version > max_protocol_version) {
|
|
Packit Service |
392537 |
err = "connect-want/max-version-mismatch";
|
|
Packit Service |
392537 |
goto error_out;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/*
|
|
Packit Service |
392537 |
* Send the OPEN request
|
|
Packit Service |
392537 |
*/
|
|
Packit Service |
392537 |
NDMC_WITH(ndmp0_connect_open,0)
|
|
Packit Service |
392537 |
request->protocol_version = want_protocol_version;
|
|
Packit Service |
392537 |
rc = NDMC_CALL(conn);
|
|
Packit Service |
392537 |
if (rc) {
|
|
Packit Service |
392537 |
err = "connect-open-failed";
|
|
Packit Service |
392537 |
goto error_out;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
NDMC_ENDWITH
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/* GOOD! */
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
conn->protocol_version = want_protocol_version;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
return 0;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
error_out:
|
|
Packit Service |
392537 |
if (fd >= 0) {
|
|
Packit Service |
392537 |
close (fd);
|
|
Packit Service |
392537 |
fd = -1;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
conn->chan.fd = -1;
|
|
Packit Service |
392537 |
conn->chan.mode = NDMCHAN_MODE_IDLE;
|
|
Packit Service |
392537 |
conn->conn_type = NDMCONN_TYPE_NONE;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
return ndmconn_set_err_msg (conn, err);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
ndmconn_try_open (struct ndmconn *conn, unsigned protocol_version)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
int rc;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/*
|
|
Packit Service |
392537 |
* Send the OPEN request
|
|
Packit Service |
392537 |
*/
|
|
Packit Service |
392537 |
NDMC_WITH(ndmp0_connect_open,0)
|
|
Packit Service |
392537 |
request->protocol_version = protocol_version;
|
|
Packit Service |
392537 |
rc = NDMC_CALL(conn);
|
|
Packit Service |
392537 |
if (rc) {
|
|
Packit Service |
392537 |
ndmconn_set_err_msg (conn, "connect-open-failed");
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
NDMC_ENDWITH
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
return rc;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
ndmconn_accept (struct ndmconn *conn, int sock)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
char * err = "???";
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (conn->chan.fd >= 0) {
|
|
Packit Service |
392537 |
err = "already-connected";
|
|
Packit Service |
392537 |
return ndmconn_set_err_msg (conn, err);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
ndmchan_start_readchk (&conn->chan, sock);
|
|
Packit Service |
392537 |
conn->conn_type = NDMCONN_TYPE_REMOTE;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/*
|
|
Packit Service |
392537 |
* Send the NDMP_NOTIFY_CONNECTED message, no reply
|
|
Packit Service |
392537 |
* The connect()er is waiting for it.
|
|
Packit Service |
392537 |
*/
|
|
Packit Service |
392537 |
NDMC_WITH_NO_REPLY(ndmp0_notify_connected,0)
|
|
Packit Service |
392537 |
request->reason = NDMP0_CONNECTED;
|
|
Packit Service |
392537 |
request->protocol_version = MAX_PROTOCOL_VERSION;
|
|
Packit Service |
392537 |
request->text_reason = "Hello";
|
|
Packit Service |
392537 |
NDMC_SEND(conn);
|
|
Packit Service |
392537 |
NDMC_ENDWITH
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/* assume connection is running in offered protocol_version */
|
|
Packit Service |
392537 |
conn->protocol_version = MAX_PROTOCOL_VERSION;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
return 0;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/*
|
|
Packit Service |
392537 |
* TERMINATE CONNECTION
|
|
Packit Service |
392537 |
****************************************************************
|
|
Packit Service |
392537 |
*
|
|
Packit Service |
392537 |
* These two routines are about terminating a connection.
|
|
Packit Service |
392537 |
* They are incomplete.
|
|
Packit Service |
392537 |
*/
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/* hangup */
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
ndmconn_abort (struct ndmconn *conn)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
return 0;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/* orderly close */
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
ndmconn_close (struct ndmconn *conn)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
return 0;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/*
|
|
Packit Service |
392537 |
* Return the underlying fd of the ndmconn.
|
|
Packit Service |
392537 |
* This is no longer used since the ndmchan stuff was done.
|
|
Packit Service |
392537 |
*/
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
ndmconn_fileno (struct ndmconn *conn)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
return conn->chan.fd;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/*
|
|
Packit Service |
392537 |
* AUTHENTICATION
|
|
Packit Service |
392537 |
*
|
|
Packit Service |
392537 |
* The following three routines do the NDMP_CONNECT_AUTH sequences.
|
|
Packit Service |
392537 |
*/
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
ndmconn_auth_agent (struct ndmconn *conn, struct ndmagent *agent)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
int rc;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (conn->conn_type == NDMCONN_TYPE_RESIDENT)
|
|
Packit Service |
392537 |
return 0;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
switch (agent->auth_type) {
|
|
Packit Service |
392537 |
case 'n': /* NDMP_AUTH_NONE */
|
|
Packit Service |
392537 |
rc = ndmconn_auth_none (conn);
|
|
Packit Service |
392537 |
break;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
case 't': /* NDMP_AUTH_TEXT */
|
|
Packit Service |
392537 |
rc = ndmconn_auth_text (conn, agent->account, agent->password);
|
|
Packit Service |
392537 |
break;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
case 'm': /* NDMP_AUTH_MD5 */
|
|
Packit Service |
392537 |
rc = ndmconn_auth_md5 (conn, agent->account, agent->password);
|
|
Packit Service |
392537 |
break;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
case 'v': /* void (don't auth) */
|
|
Packit Service |
392537 |
rc = 0;
|
|
Packit Service |
392537 |
break;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
default:
|
|
Packit Service |
392537 |
ndmconn_set_err_msg (conn, "connect-auth-unknown");
|
|
Packit Service |
392537 |
rc = -1;
|
|
Packit Service |
392537 |
break;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
return rc;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
ndmconn_auth_none (struct ndmconn *conn)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
int rc;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
switch (conn->protocol_version) {
|
|
Packit Service |
392537 |
default:
|
|
Packit Service |
392537 |
ndmconn_set_err_msg (conn, "connect-auth-none-vers-botch");
|
|
Packit Service |
392537 |
return -1;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
#ifndef NDMOS_OPTION_NO_NDMP2
|
|
Packit Service |
392537 |
case NDMP2VER:
|
|
Packit Service |
392537 |
NDMC_WITH(ndmp2_connect_client_auth, NDMP2VER)
|
|
Packit Service |
392537 |
request->auth_data.auth_type = NDMP2_AUTH_NONE;
|
|
Packit Service |
392537 |
rc = NDMC_CALL(conn);
|
|
Packit Service |
392537 |
NDMC_ENDWITH
|
|
Packit Service |
392537 |
break;
|
|
Packit Service |
392537 |
#endif /* !NDMOS_OPTION_NO_NDMP2 */
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
#ifndef NDMOS_OPTION_NO_NDMP3
|
|
Packit Service |
392537 |
case NDMP3VER:
|
|
Packit Service |
392537 |
NDMC_WITH(ndmp3_connect_client_auth, NDMP3VER)
|
|
Packit Service |
392537 |
request->auth_data.auth_type = NDMP3_AUTH_NONE;
|
|
Packit Service |
392537 |
rc = NDMC_CALL(conn);
|
|
Packit Service |
392537 |
NDMC_ENDWITH
|
|
Packit Service |
392537 |
break;
|
|
Packit Service |
392537 |
#endif /* !NDMOS_OPTION_NO_NDMP3 */
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
#ifndef NDMOS_OPTION_NO_NDMP4
|
|
Packit Service |
392537 |
case NDMP4VER:
|
|
Packit Service |
392537 |
NDMC_WITH(ndmp4_connect_client_auth, NDMP4VER)
|
|
Packit Service |
392537 |
request->auth_data.auth_type = NDMP4_AUTH_NONE;
|
|
Packit Service |
392537 |
rc = NDMC_CALL(conn);
|
|
Packit Service |
392537 |
NDMC_ENDWITH
|
|
Packit Service |
392537 |
break;
|
|
Packit Service |
392537 |
#endif /* !NDMOS_OPTION_NO_NDMP4 */
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (rc) {
|
|
Packit Service |
392537 |
ndmconn_set_err_msg (conn, "connect-auth-none-failed");
|
|
Packit Service |
392537 |
return -1;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
return 0;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
ndmconn_auth_text (struct ndmconn *conn, char *id, char *pw)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
int rc;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
switch (conn->protocol_version) {
|
|
Packit Service |
392537 |
default:
|
|
Packit Service |
392537 |
ndmconn_set_err_msg (conn, "connect-auth-text-vers-botch");
|
|
Packit Service |
392537 |
return -1;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
#ifndef NDMOS_OPTION_NO_NDMP2
|
|
Packit Service |
392537 |
case NDMP2VER:
|
|
Packit Service |
392537 |
NDMC_WITH(ndmp2_connect_client_auth, NDMP2VER)
|
|
Packit Service |
392537 |
struct ndmp2_auth_text *at;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
request->auth_data.auth_type = NDMP2_AUTH_TEXT;
|
|
Packit Service |
392537 |
at = &request->auth_data.ndmp2_auth_data_u.auth_text;
|
|
Packit Service |
392537 |
at->auth_id = id;
|
|
Packit Service |
392537 |
at->auth_password = pw;
|
|
Packit Service |
392537 |
rc = NDMC_CALL(conn);
|
|
Packit Service |
392537 |
NDMC_ENDWITH
|
|
Packit Service |
392537 |
break;
|
|
Packit Service |
392537 |
#endif /* !NDMOS_OPTION_NO_NDMP2 */
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
#ifndef NDMOS_OPTION_NO_NDMP3
|
|
Packit Service |
392537 |
case NDMP3VER:
|
|
Packit Service |
392537 |
NDMC_WITH(ndmp3_connect_client_auth, NDMP3VER)
|
|
Packit Service |
392537 |
struct ndmp3_auth_text *at;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
request->auth_data.auth_type = NDMP3_AUTH_TEXT;
|
|
Packit Service |
392537 |
at = &request->auth_data.ndmp3_auth_data_u.auth_text;
|
|
Packit Service |
392537 |
at->auth_id = id;
|
|
Packit Service |
392537 |
at->auth_password = pw;
|
|
Packit Service |
392537 |
rc = NDMC_CALL(conn);
|
|
Packit Service |
392537 |
NDMC_ENDWITH
|
|
Packit Service |
392537 |
break;
|
|
Packit Service |
392537 |
#endif /* !NDMOS_OPTION_NO_NDMP3 */
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
#ifndef NDMOS_OPTION_NO_NDMP4
|
|
Packit Service |
392537 |
case NDMP4VER:
|
|
Packit Service |
392537 |
NDMC_WITH(ndmp4_connect_client_auth, NDMP4VER)
|
|
Packit Service |
392537 |
struct ndmp4_auth_text *at;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
request->auth_data.auth_type = NDMP4_AUTH_TEXT;
|
|
Packit Service |
392537 |
at = &request->auth_data.ndmp4_auth_data_u.auth_text;
|
|
Packit Service |
392537 |
at->auth_id = id;
|
|
Packit Service |
392537 |
at->auth_password = pw;
|
|
Packit Service |
392537 |
rc = NDMC_CALL(conn);
|
|
Packit Service |
392537 |
NDMC_ENDWITH
|
|
Packit Service |
392537 |
break;
|
|
Packit Service |
392537 |
#endif /* !NDMOS_OPTION_NO_NDMP4 */
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (rc) {
|
|
Packit Service |
392537 |
ndmconn_set_err_msg (conn, "connect-auth-text-failed");
|
|
Packit Service |
392537 |
return -1;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
return 0;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
ndmconn_auth_md5 (struct ndmconn *conn, char *id, char *pw)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
int rc;
|
|
Packit Service |
392537 |
char challenge[NDMP_MD5_CHALLENGE_LENGTH];
|
|
Packit Service |
392537 |
char digest[NDMP_MD5_DIGEST_LENGTH];
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
switch (conn->protocol_version) {
|
|
Packit Service |
392537 |
default:
|
|
Packit Service |
392537 |
ndmconn_set_err_msg (conn, "connect-auth-md5-vers-botch");
|
|
Packit Service |
392537 |
return -1;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
#ifndef NDMOS_OPTION_NO_NDMP2
|
|
Packit Service |
392537 |
case NDMP2VER:
|
|
Packit Service |
392537 |
NDMC_WITH(ndmp2_config_get_auth_attr, NDMP2VER)
|
|
Packit Service |
392537 |
request->auth_type = NDMP2_AUTH_MD5;
|
|
Packit Service |
392537 |
rc = NDMC_CALL(conn);
|
|
Packit Service |
392537 |
if (rc == 0) {
|
|
Packit Service |
392537 |
if (reply->server_attr.auth_type != NDMP2_AUTH_MD5) {
|
|
Packit Service |
392537 |
ndmconn_set_err_msg (conn,
|
|
Packit Service |
392537 |
"connect-auth-md5-attr-type-botch");
|
|
Packit Service |
392537 |
return -1;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
NDMOS_API_BCOPY (
|
|
Packit Service |
392537 |
reply->server_attr.ndmp2_auth_attr_u.challenge,
|
|
Packit Service |
392537 |
challenge, sizeof challenge);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
NDMC_ENDWITH
|
|
Packit Service |
392537 |
break;
|
|
Packit Service |
392537 |
#endif /* !NDMOS_OPTION_NO_NDMP2 */
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
#ifndef NDMOS_OPTION_NO_NDMP3
|
|
Packit Service |
392537 |
case NDMP3VER:
|
|
Packit Service |
392537 |
NDMC_WITH(ndmp3_config_get_auth_attr, NDMP3VER)
|
|
Packit Service |
392537 |
request->auth_type = NDMP3_AUTH_MD5;
|
|
Packit Service |
392537 |
rc = NDMC_CALL(conn);
|
|
Packit Service |
392537 |
if (rc == 0) {
|
|
Packit Service |
392537 |
if (reply->server_attr.auth_type != NDMP3_AUTH_MD5) {
|
|
Packit Service |
392537 |
ndmconn_set_err_msg (conn,
|
|
Packit Service |
392537 |
"connect-auth-md5-attr-type-botch");
|
|
Packit Service |
392537 |
return -1;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
NDMOS_API_BCOPY (
|
|
Packit Service |
392537 |
reply->server_attr.ndmp3_auth_attr_u.challenge,
|
|
Packit Service |
392537 |
challenge, sizeof challenge);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
NDMC_ENDWITH
|
|
Packit Service |
392537 |
break;
|
|
Packit Service |
392537 |
#endif /* !NDMOS_OPTION_NO_NDMP3 */
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
#ifndef NDMOS_OPTION_NO_NDMP4
|
|
Packit Service |
392537 |
case NDMP4VER:
|
|
Packit Service |
392537 |
NDMC_WITH(ndmp4_config_get_auth_attr, NDMP4VER)
|
|
Packit Service |
392537 |
request->auth_type = NDMP4_AUTH_MD5;
|
|
Packit Service |
392537 |
rc = NDMC_CALL(conn);
|
|
Packit Service |
392537 |
if (rc == 0) {
|
|
Packit Service |
392537 |
if (reply->server_attr.auth_type != NDMP4_AUTH_MD5) {
|
|
Packit Service |
392537 |
ndmconn_set_err_msg (conn,
|
|
Packit Service |
392537 |
"connect-auth-md5-attr-type-botch");
|
|
Packit Service |
392537 |
return -1;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
NDMOS_API_BCOPY (
|
|
Packit Service |
392537 |
reply->server_attr.ndmp4_auth_attr_u.challenge,
|
|
Packit Service |
392537 |
challenge, sizeof challenge);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
NDMC_ENDWITH
|
|
Packit Service |
392537 |
break;
|
|
Packit Service |
392537 |
#endif /* !NDMOS_OPTION_NO_NDMP4 */
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (rc) {
|
|
Packit Service |
392537 |
ndmconn_set_err_msg (conn, "connect-auth-md5-attr-failed");
|
|
Packit Service |
392537 |
return -1;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
ndmmd5_digest (challenge, pw, digest);
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
switch (conn->protocol_version) {
|
|
Packit Service |
392537 |
default:
|
|
Packit Service |
392537 |
ndmconn_set_err_msg (conn, "connect-auth-text-vers-botch");
|
|
Packit Service |
392537 |
return -1;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
#ifndef NDMOS_OPTION_NO_NDMP2
|
|
Packit Service |
392537 |
case NDMP2VER:
|
|
Packit Service |
392537 |
NDMC_WITH(ndmp2_connect_client_auth, NDMP2VER)
|
|
Packit Service |
392537 |
struct ndmp2_auth_md5 *am;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
request->auth_data.auth_type = NDMP2_AUTH_MD5;
|
|
Packit Service |
392537 |
am = &request->auth_data.ndmp2_auth_data_u.auth_md5;
|
|
Packit Service |
392537 |
am->auth_id = id;
|
|
Packit Service |
392537 |
NDMOS_API_BCOPY (digest, am->auth_digest, sizeof digest);
|
|
Packit Service |
392537 |
rc = NDMC_CALL(conn);
|
|
Packit Service |
392537 |
NDMC_ENDWITH
|
|
Packit Service |
392537 |
break;
|
|
Packit Service |
392537 |
#endif /* !NDMOS_OPTION_NO_NDMP2 */
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
#ifndef NDMOS_OPTION_NO_NDMP3
|
|
Packit Service |
392537 |
case NDMP3VER:
|
|
Packit Service |
392537 |
NDMC_WITH(ndmp3_connect_client_auth, NDMP3VER)
|
|
Packit Service |
392537 |
struct ndmp3_auth_md5 *am;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
request->auth_data.auth_type = NDMP3_AUTH_MD5;
|
|
Packit Service |
392537 |
am = &request->auth_data.ndmp3_auth_data_u.auth_md5;
|
|
Packit Service |
392537 |
am->auth_id = id;
|
|
Packit Service |
392537 |
NDMOS_API_BCOPY (digest, am->auth_digest, sizeof digest);
|
|
Packit Service |
392537 |
rc = NDMC_CALL(conn);
|
|
Packit Service |
392537 |
NDMC_ENDWITH
|
|
Packit Service |
392537 |
break;
|
|
Packit Service |
392537 |
#endif /* !NDMOS_OPTION_NO_NDMP3 */
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
#ifndef NDMOS_OPTION_NO_NDMP4
|
|
Packit Service |
392537 |
case NDMP4VER:
|
|
Packit Service |
392537 |
NDMC_WITH(ndmp4_connect_client_auth, NDMP4VER)
|
|
Packit Service |
392537 |
struct ndmp4_auth_md5 *am;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
request->auth_data.auth_type = NDMP4_AUTH_MD5;
|
|
Packit Service |
392537 |
am = &request->auth_data.ndmp4_auth_data_u.auth_md5;
|
|
Packit Service |
392537 |
am->auth_id = id;
|
|
Packit Service |
392537 |
NDMOS_API_BCOPY (digest, am->auth_digest, sizeof digest);
|
|
Packit Service |
392537 |
rc = NDMC_CALL(conn);
|
|
Packit Service |
392537 |
NDMC_ENDWITH
|
|
Packit Service |
392537 |
break;
|
|
Packit Service |
392537 |
#endif /* !NDMOS_OPTION_NO_NDMP4 */
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (rc) {
|
|
Packit Service |
392537 |
ndmconn_set_err_msg (conn, "connect-auth-md5-failed");
|
|
Packit Service |
392537 |
return -1;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
return 0;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/*
|
|
Packit Service |
392537 |
* CALL (REQUEST/REPLY), SEND, and RECEIVE
|
|
Packit Service |
392537 |
****************************************************************
|
|
Packit Service |
392537 |
*/
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
ndmconn_call (struct ndmconn *conn, struct ndmp_xa_buf *xa)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
unsigned protocol_version = conn->protocol_version;
|
|
Packit Service |
392537 |
unsigned msg = xa->request.header.message;
|
|
Packit Service |
392537 |
int rc;
|
|
Packit Service |
392537 |
struct ndmp_xdr_message_table * xmte;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
conn->last_message = msg;
|
|
Packit Service |
392537 |
conn->last_call_status = NDMCONN_CALL_STATUS_BOTCH;
|
|
Packit Service |
392537 |
conn->last_header_error = -1; /* invalid */
|
|
Packit Service |
392537 |
conn->last_reply_error = -1; /* invalid */
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (protocol_version != xa->request.protocol_version) {
|
|
Packit Service |
392537 |
ndmconn_set_err_msg (conn, "protocol-version-mismatch");
|
|
Packit Service |
392537 |
return NDMCONN_CALL_STATUS_BOTCH;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
xmte = ndmp_xmt_lookup (protocol_version, msg);
|
|
Packit Service |
392537 |
if (!xmte) {
|
|
Packit Service |
392537 |
ndmconn_set_err_msg (conn, "no-xdr-found");
|
|
Packit Service |
392537 |
return NDMCONN_CALL_STATUS_BOTCH;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
xa->request.header.message_type = NDMP0_MESSAGE_REQUEST;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (!xmte->xdr_reply) {
|
|
Packit Service |
392537 |
/* no reply expected, just a send (eg NOTIFY) */
|
|
Packit Service |
392537 |
return ndmconn_send_nmb (conn, &xa->request);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
rc = ndmconn_exchange_nmb (conn, &xa->request, &xa->reply);
|
|
Packit Service |
392537 |
if (rc) {
|
|
Packit Service |
392537 |
ndmconn_set_err_msg (conn, "exchange-failed");
|
|
Packit Service |
392537 |
return NDMCONN_CALL_STATUS_BOTCH;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (xa->reply.header.message != msg) {
|
|
Packit Service |
392537 |
ndmconn_set_err_msg (conn, "msg-mismatch");
|
|
Packit Service |
392537 |
return NDMCONN_CALL_STATUS_BOTCH;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/* TODO: this should be converted ndmp_xto9_error(....) */
|
|
Packit Service |
392537 |
conn->last_header_error = xa->reply.header.error;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (xa->reply.header.error) {
|
|
Packit Service |
392537 |
conn->last_call_status = NDMCONN_CALL_STATUS_HDR_ERROR;
|
|
Packit Service |
392537 |
ndmconn_set_err_msg (conn, "reply-error-hdr");
|
|
Packit Service |
392537 |
return NDMCONN_CALL_STATUS_HDR_ERROR;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
conn->last_reply_error = ndmnmb_get_reply_error (&xa->reply);
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (conn->last_reply_error != NDMP9_NO_ERR) {
|
|
Packit Service |
392537 |
conn->last_call_status = NDMCONN_CALL_STATUS_REPLY_ERROR;
|
|
Packit Service |
392537 |
ndmconn_set_err_msg (conn, "reply-error");
|
|
Packit Service |
392537 |
return NDMCONN_CALL_STATUS_REPLY_ERROR;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
return NDMCONN_CALL_STATUS_OK;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
ndmconn_exchange_nmb (struct ndmconn *conn,
|
|
Packit Service |
392537 |
struct ndmp_msg_buf *request_nmb,
|
|
Packit Service |
392537 |
struct ndmp_msg_buf *reply_nmb)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
int rc;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if ((rc = ndmconn_send_nmb (conn, request_nmb)) != 0)
|
|
Packit Service |
392537 |
return rc;
|
|
Packit Service |
392537 |
conn->received_time = 0;
|
|
Packit Service |
392537 |
conn->sent_time = time(0);
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
for (;;) {
|
|
Packit Service |
392537 |
if ((rc = ndmconn_recv_nmb (conn, reply_nmb)) != 0)
|
|
Packit Service |
392537 |
return rc;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (reply_nmb->header.message_type == NDMP0_MESSAGE_REPLY
|
|
Packit Service |
392537 |
&& reply_nmb->header.reply_sequence
|
|
Packit Service |
392537 |
== request_nmb->header.sequence) {
|
|
Packit Service |
392537 |
conn->received_time = time(0);
|
|
Packit Service |
392537 |
return 0;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
(*conn->unexpected)(conn, reply_nmb);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
ndmconn_send_nmb (struct ndmconn *conn, struct ndmp_msg_buf *nmb)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
return ndmconn_xdr_nmb (conn, nmb, XDR_ENCODE);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
ndmconn_recv_nmb (struct ndmconn *conn, struct ndmp_msg_buf *nmb)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
NDMOS_MACRO_ZEROFILL (nmb);
|
|
Packit Service |
392537 |
nmb->protocol_version = conn->protocol_version;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
return ndmconn_xdr_nmb (conn, nmb, XDR_DECODE);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
void
|
|
Packit Service |
392537 |
ndmconn_free_nmb (struct ndmconn *conn, struct ndmp_msg_buf *nmb)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
ndmnmb_free (nmb);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
ndmconn_xdr_nmb (struct ndmconn *conn,
|
|
Packit Service |
392537 |
struct ndmp_msg_buf *nmb,
|
|
Packit Service |
392537 |
enum xdr_op x_op)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
xdrproc_t xdr_body = 0;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
assert (conn->conn_type == NDMCONN_TYPE_REMOTE);
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (conn->chan.fd < 0) {
|
|
Packit Service |
392537 |
return ndmconn_set_err_msg (conn, "not-open");
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
conn->xdrs.x_op = x_op;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (x_op == XDR_ENCODE) {
|
|
Packit Service |
392537 |
xdr_body = ndmnmb_find_xdrproc (nmb);
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (nmb->header.error == NDMP0_NO_ERR && !xdr_body) {
|
|
Packit Service |
392537 |
return ndmconn_set_err_msg (conn, "unknown-body");
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
nmb->header.sequence = conn->next_sequence++;
|
|
Packit Service |
392537 |
nmb->header.time_stamp = time(0);
|
|
Packit Service |
392537 |
ndmconn_snoop_nmb (conn, nmb, "Send");
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
if (x_op == XDR_DECODE) {
|
|
Packit Service |
392537 |
if (!xdrrec_skiprecord (&conn->xdrs)) {
|
|
Packit Service |
392537 |
return ndmconn_set_err_msg (conn, "xdr-get-next");
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (!xdr_ndmp0_header (&conn->xdrs, &nmb->header)) {
|
|
Packit Service |
392537 |
ndmconn_abort (conn);
|
|
Packit Service |
392537 |
if (x_op == XDR_DECODE
|
|
Packit Service |
392537 |
&& conn->chan.eof && !conn->chan.error) {
|
|
Packit Service |
392537 |
return ndmconn_set_err_msg (conn, "EOF");
|
|
Packit Service |
392537 |
} else {
|
|
Packit Service |
392537 |
return ndmconn_set_err_msg (conn, "xdr-hdr");
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (x_op == XDR_DECODE) {
|
|
Packit Service |
392537 |
xdr_body = ndmnmb_find_xdrproc (nmb);
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (nmb->header.error == NDMP0_NO_ERR && !xdr_body) {
|
|
Packit Service |
392537 |
return ndmconn_set_err_msg (conn, "unknown-body");
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
if (nmb->header.error == NDMP0_NO_ERR) {
|
|
Packit Service |
392537 |
if (!(*xdr_body) (&conn->xdrs, &nmb->body)) {
|
|
Packit Service |
392537 |
ndmconn_abort (conn);
|
|
Packit Service |
392537 |
return ndmconn_set_err_msg (conn, "xdr-body");
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (x_op == XDR_ENCODE) {
|
|
Packit Service |
392537 |
if (!xdrrec_endofrecord(&conn->xdrs, 1)) {
|
|
Packit Service |
392537 |
ndmconn_abort (conn);
|
|
Packit Service |
392537 |
return ndmconn_set_err_msg (conn, "xdr-send");
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
if (x_op == XDR_DECODE) {
|
|
Packit Service |
392537 |
ndmconn_snoop_nmb (conn, nmb, "Recv");
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
return 0;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/*
|
|
Packit Service |
392537 |
* XDR READ/WRITE CALLBACKS
|
|
Packit Service |
392537 |
****************************************************************
|
|
Packit Service |
392537 |
*
|
|
Packit Service |
392537 |
* ndmconn_readit() and ndmconn_writeit() are the XDR callbacks
|
|
Packit Service |
392537 |
* used by xdrrec_create(). They are fundamentally wrappers
|
|
Packit Service |
392537 |
* around read() and write(), and have very similar parameters.
|
|
Packit Service |
392537 |
* See the xdr(3) manual page (or try "man xdrrec_create").
|
|
Packit Service |
392537 |
*
|
|
Packit Service |
392537 |
* ndmconn_readit() tracks the XDR record marks, and never
|
|
Packit Service |
392537 |
* reads across a record boundary. This keeps select() an
|
|
Packit Service |
392537 |
* indicator of when there is a (single) request pending.
|
|
Packit Service |
392537 |
* Otherwise, we have to check buffers internal to XDR
|
|
Packit Service |
392537 |
* as well as the file descriptor (via select) to determine
|
|
Packit Service |
392537 |
* if a request is pending.
|
|
Packit Service |
392537 |
*/
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
ndmconn_readit (void *a_conn, char *buf, int len)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
struct ndmconn *conn = (struct ndmconn *)a_conn;
|
|
Packit Service |
392537 |
int rc, i, c;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/* could impose timeout here */
|
|
Packit Service |
392537 |
if (conn->chan.fd < 0 || conn->chan.eof)
|
|
Packit Service |
392537 |
return -1;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
ndmconn_snoop (conn, 8,
|
|
Packit Service |
392537 |
"frag_resid=%d fhb_off=%d", conn->frag_resid, conn->fhb_off);
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (conn->frag_resid == 0) {
|
|
Packit Service |
392537 |
i = 0;
|
|
Packit Service |
392537 |
while (i < 4) {
|
|
Packit Service |
392537 |
c = 4 - i;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
rc = ndmconn_sys_read (conn, (void *)(conn->frag_hdr_buf+i), c);
|
|
Packit Service |
392537 |
if (rc <= 0) {
|
|
Packit Service |
392537 |
return rc;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
i += rc;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
conn->frag_resid = conn->frag_hdr_buf[0] << 24;
|
|
Packit Service |
392537 |
conn->frag_resid |= conn->frag_hdr_buf[1] << 16;
|
|
Packit Service |
392537 |
conn->frag_resid |= conn->frag_hdr_buf[2] << 8;
|
|
Packit Service |
392537 |
conn->frag_resid |= conn->frag_hdr_buf[3];
|
|
Packit Service |
392537 |
conn->frag_resid &= 0xFFFFFF;
|
|
Packit Service |
392537 |
conn->fhb_off = 0;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
if (conn->fhb_off < 4) {
|
|
Packit Service |
392537 |
i = 0;
|
|
Packit Service |
392537 |
while (conn->fhb_off < 4 && len > 0) {
|
|
Packit Service |
392537 |
buf[i++] = conn->frag_hdr_buf[conn->fhb_off++];
|
|
Packit Service |
392537 |
len--;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
return i;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if ((unsigned int)len > conn->frag_resid)
|
|
Packit Service |
392537 |
len = (unsigned int)conn->frag_resid;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
rc = ndmconn_sys_read (conn, buf, len);
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (rc > 0) {
|
|
Packit Service |
392537 |
conn->frag_resid -= rc;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
return rc;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
ndmconn_writeit (void *a_conn, char *buf, int len)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
struct ndmconn *conn = (struct ndmconn *)a_conn;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/* could impose timeout here */
|
|
Packit Service |
392537 |
if (conn->chan.fd < 0)
|
|
Packit Service |
392537 |
return -1;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
return ndmconn_sys_write (conn, buf, len);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/*
|
|
Packit Service |
392537 |
* ndmconn_sys_read() and ndmconn_sys_write() are simply
|
|
Packit Service |
392537 |
* wrappers around read() and write(). They implement
|
|
Packit Service |
392537 |
* the low-level snooping.
|
|
Packit Service |
392537 |
*/
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
ndmconn_sys_read (struct ndmconn *conn, char *buf, unsigned len)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
int rc;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
ndmconn_snoop (conn, 9, "reading %d ...", len);
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
rc = read (conn->chan.fd, buf, len);
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
ndmconn_snoop (conn, 8, "read=%d len=%d", rc, len);
|
|
Packit Service |
392537 |
ndmconn_hex_dump (conn, buf, rc);
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (rc <= 0) {
|
|
Packit Service |
392537 |
conn->chan.eof = 1;
|
|
Packit Service |
392537 |
if (rc < 0)
|
|
Packit Service |
392537 |
conn->chan.error = 1;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
return rc;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
ndmconn_sys_write (struct ndmconn *conn, char *buf, unsigned len)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
int rc;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
ndmconn_snoop (conn, 9, "writing %d ...", len);
|
|
Packit Service |
392537 |
ndmconn_hex_dump (conn, buf, len);
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
rc = write (conn->chan.fd, buf, len);
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
ndmconn_snoop (conn, 8, "write=%d len=%d", rc, len);
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (rc !=(int)len) {
|
|
Packit Service |
392537 |
conn->chan.eof = 1;
|
|
Packit Service |
392537 |
conn->chan.error = 1;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
return rc;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/*
|
|
Packit Service |
392537 |
* UNEXPECTED
|
|
Packit Service |
392537 |
****************************************************************
|
|
Packit Service |
392537 |
*
|
|
Packit Service |
392537 |
* The default unexpected() handler for a connection. It is
|
|
Packit Service |
392537 |
* called when ndmconn_exchange_nmb() receives something
|
|
Packit Service |
392537 |
* other than the reply for which it is waiting.
|
|
Packit Service |
392537 |
* This default routine silently dumps the message.
|
|
Packit Service |
392537 |
*/
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
void
|
|
Packit Service |
392537 |
ndmconn_unexpected (struct ndmconn *conn, struct ndmp_msg_buf *nmb)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
xdrproc_t xdr_body = ndmnmb_find_xdrproc (nmb);
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (xdr_body) {
|
|
Packit Service |
392537 |
xdr_free (xdr_body, (void*) &nmb->body);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/*
|
|
Packit Service |
392537 |
* SNOOP
|
|
Packit Service |
392537 |
****************************************************************
|
|
Packit Service |
392537 |
*
|
|
Packit Service |
392537 |
* The ndmconn snoop stuff. The cool part. This pretty prints
|
|
Packit Service |
392537 |
* NDMP messages as they go flying by this end-point.
|
|
Packit Service |
392537 |
*/
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
ndmconn_set_snoop (struct ndmconn *conn, struct ndmlog *log, int level)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
conn->snoop_log = log;
|
|
Packit Service |
392537 |
conn->snoop_level = level;
|
|
Packit Service |
392537 |
return 0;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
void
|
|
Packit Service |
392537 |
ndmconn_clear_snoop (struct ndmconn *conn)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
conn->snoop_log = 0;
|
|
Packit Service |
392537 |
conn->snoop_level = 0;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
void
|
|
Packit Service |
392537 |
ndmconn_snoop_nmb (struct ndmconn *conn,
|
|
Packit Service |
392537 |
struct ndmp_msg_buf *nmb,
|
|
Packit Service |
392537 |
char *whence)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
if (!conn->snoop_log) {
|
|
Packit Service |
392537 |
return;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
ndmnmb_snoop (conn->snoop_log, conn->chan.name, conn->snoop_level,
|
|
Packit Service |
392537 |
nmb, whence);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
void
|
|
Packit Service |
392537 |
ndmconn_snoop (struct ndmconn *conn, int level, char *fmt, ...)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
va_list ap;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (conn->snoop_log && conn->snoop_level >= level) {
|
|
Packit Service |
392537 |
va_start (ap, fmt);
|
|
Packit Service |
392537 |
ndmlogfv (conn->snoop_log, conn->chan.name, level, fmt, ap);
|
|
Packit Service |
392537 |
va_end (ap);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/* used by ndmconn_sys_read() and ndmconn_sys_write() to show low-level */
|
|
Packit Service |
392537 |
void
|
|
Packit Service |
392537 |
ndmconn_hex_dump (struct ndmconn *conn, char *buf, unsigned len)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
struct ndmlog * log = conn->snoop_log;
|
|
Packit Service |
392537 |
char * tag = conn->chan.name;
|
|
Packit Service |
392537 |
char linebuf[16*3+3];
|
|
Packit Service |
392537 |
char * p = linebuf;
|
|
Packit Service |
392537 |
int b;
|
|
Packit Service |
392537 |
unsigned i;
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
if (log && conn->snoop_level > 8) {
|
|
Packit Service |
392537 |
for (i = 0; i < len; i++) {
|
|
Packit Service |
392537 |
b = buf[i] & 0xFF;
|
|
Packit Service |
392537 |
sprintf (p, " %02x", b);
|
|
Packit Service |
392537 |
while (*p) p++;
|
|
Packit Service |
392537 |
if ((i&0xF) == 0xF) {
|
|
Packit Service |
392537 |
ndmlogf (log,tag,9,"%s",linebuf+1);
|
|
Packit Service |
392537 |
p = linebuf;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
if (p > linebuf) {
|
|
Packit Service |
392537 |
ndmlogf (log,tag,9,"%s",linebuf+1);
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
/*
|
|
Packit Service |
392537 |
* ERRORS
|
|
Packit Service |
392537 |
****************************************************************
|
|
Packit Service |
392537 |
*
|
|
Packit Service |
392537 |
* Possible errors for ndmconn are not enumerated.
|
|
Packit Service |
392537 |
* Instead, errors are indicated by a -1 return, and
|
|
Packit Service |
392537 |
* a simple string error message is available for details.
|
|
Packit Service |
392537 |
* Appologies for the english-centric design, but it
|
|
Packit Service |
392537 |
* is quick and easy, and better than using printf().
|
|
Packit Service |
392537 |
*/
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
int
|
|
Packit Service |
392537 |
ndmconn_set_err_msg (struct ndmconn *conn, char *err_msg)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
conn->last_err_msg = err_msg;
|
|
Packit Service |
392537 |
ndmconn_snoop (conn, 4, "ERR=%s", err_msg);
|
|
Packit Service |
392537 |
return -1;
|
|
Packit Service |
392537 |
}
|
|
Packit Service |
392537 |
|
|
Packit Service |
392537 |
char *
|
|
Packit Service |
392537 |
ndmconn_get_err_msg (struct ndmconn *conn)
|
|
Packit Service |
392537 |
{
|
|
Packit Service |
392537 |
if (!conn->last_err_msg)
|
|
Packit Service |
392537 |
return "-no-error-";
|
|
Packit Service |
392537 |
else
|
|
Packit Service |
392537 |
return conn->last_err_msg;
|
|
Packit Service |
392537 |
}
|