152153Sbp/*
252153Sbp * Copyright (c) 1999, Boris Popov
352153Sbp * All rights reserved.
452153Sbp *
552153Sbp * Redistribution and use in source and binary forms, with or without
652153Sbp * modification, are permitted provided that the following conditions
752153Sbp * are met:
852153Sbp * 1. Redistributions of source code must retain the above copyright
952153Sbp *    notice, this list of conditions and the following disclaimer.
1052153Sbp * 2. Redistributions in binary form must reproduce the above copyright
1152153Sbp *    notice, this list of conditions and the following disclaimer in the
1252153Sbp *    documentation and/or other materials provided with the distribution.
13165920Simp * 3. Neither the name of the author nor the names of any co-contributors
1452153Sbp *    may be used to endorse or promote products derived from this software
1552153Sbp *    without specific prior written permission.
1652153Sbp *
1752153Sbp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1852153Sbp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1952153Sbp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2052153Sbp * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2152153Sbp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2252153Sbp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2352153Sbp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2452153Sbp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2552153Sbp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2652153Sbp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2752153Sbp * SUCH DAMAGE.
2852153Sbp * NetWare RPCs
2952153Sbp */
3084213Sdillon
3184213Sdillon#include <sys/cdefs.h>
3284213Sdillon__FBSDID("$FreeBSD$");
3384213Sdillon
3452153Sbp#include <sys/types.h>
3552153Sbp#include <sys/time.h>
3690868Smike#include <arpa/inet.h>
3752153Sbp#include <errno.h>
3852153Sbp#include <stdio.h>
39162486Skan#include <string.h>
4052153Sbp#include <netncp/ncp_lib.h>
4152153Sbp
4252153Sbpstruct ncp_rpc_rq {
4352153Sbp	nuint16		len;	/* HL */
4452153Sbp	nuint8		subfn;
4552153Sbp	nuint32		reserved[4];
4652153Sbp	nuint8		flags[4];
4752153Sbp} __attribute__ ((packed));
4852153Sbp
4952153Sbpstruct ncp_rpc_rp {
5052153Sbp	nuint32		rpccode;
5152153Sbp	nuint32		reserved[4];
5252153Sbp	nuint32		rpcval;
5352153Sbp} __attribute__ ((packed));
5452153Sbp
5552153Sbpstatic NWCCODE
5652153Sbpncp_rpc(NWCONN_HANDLE cH, int rpcfn,
5752153Sbp	const nuint8* rpcarg, char* arg1, char *arg2,
5852153Sbp	nuint32* rpcval) {
5952153Sbp	NWCCODE error;
6052153Sbp	NW_FRAGMENT rq[4], rp;
6152153Sbp	struct ncp_rpc_rq rqh;
6252153Sbp	struct ncp_rpc_rp rph;
6352153Sbp
6452153Sbp	rqh.subfn = rpcfn;
6552153Sbp	if (rpcarg)
6652153Sbp		bcopy(rpcarg, rqh.reserved, 4 * 4 + 4);
6752153Sbp	else
6852153Sbp		bzero(rqh.reserved, 4 * 4 + 4);
6952153Sbp	rq[0].fragAddress = (char*)&rqh;
7052153Sbp	rq[0].fragSize = sizeof(rqh);
7152153Sbp	rq[1].fragAddress = arg1;
7252153Sbp	rq[1].fragSize = strlen(arg1) + 1;
7352153Sbp	rq[2].fragAddress = arg2;
7452153Sbp	rq[2].fragSize = arg2 ? (strlen(arg2) + 1) : 0;
7552153Sbp	rqh.len = htons(rq[2].fragSize + rq[1].fragSize + sizeof(rqh) - 2);
7652153Sbp	rp.fragAddress = (char*)&rph;
7752153Sbp	rp.fragSize = sizeof(rph);
7852153Sbp	error = NWRequest(cH, 131, 3, rq, 1, &rp);
7952153Sbp	if (error) return error;
8052153Sbp	if (rp.fragSize < 4) return EBADRPC;
8152153Sbp	error = rph.rpccode;
8252153Sbp	if (error) return error;
8352153Sbp	if (rpcval) {
8452153Sbp		if (rp.fragSize < 24)
8552153Sbp			return EBADRPC;
8652153Sbp		*rpcval = rph.rpcval;
8752153Sbp	}
8852153Sbp	return 0;
8952153Sbp}
9052153Sbp
9152153SbpNWCCODE
9252153SbpNWSMLoadNLM(NWCONN_HANDLE cH, pnstr8 cmd) {
9352153Sbp	return ncp_rpc(cH, 1, NULL, cmd, NULL, NULL);
9452153Sbp}
9552153Sbp
9652153SbpNWCCODE
9752153SbpNWSMUnloadNLM(NWCONN_HANDLE cH, pnstr8 cmd) {
9852153Sbp	return ncp_rpc(cH, 2, NULL, cmd, NULL, NULL);
9952153Sbp}
10052153Sbp
10152153SbpNWCCODE
10252153SbpNWSMMountVolume(NWCONN_HANDLE cH, pnstr8 volName, nuint32* volnum) {
10352153Sbp	return ncp_rpc(cH, 3, NULL, volName, NULL, volnum);
10452153Sbp}
10552153Sbp
10652153SbpNWCCODE
10752153SbpNWSMDismountVolumeByName(NWCONN_HANDLE cH, pnstr8 vol) {
10852153Sbp	return ncp_rpc(cH, 4, NULL, vol, NULL, NULL);
10952153Sbp}
11052153Sbp
11152153Sbpstruct ncp_set_hdr {
11252153Sbp	nuint32	typeFlag;	/* 0 - str, 1 - value */
11352153Sbp	nuint32	value;
11452153Sbp	nuint32	pad[20 - 4 - 4];
11552153Sbp} __attribute__ ((packed));
11652153Sbp
11752153SbpNWCCODE
11852153SbpNWSMSetDynamicCmdIntValue(NWCONN_HANDLE cH, pnstr8 setCommandName, nuint32 cmdValue) {
11952153Sbp	struct ncp_set_hdr rq;
12052153Sbp
12152153Sbp	memset(&rq, 0, sizeof(rq));
12252153Sbp	rq.typeFlag = 1;
12352153Sbp	rq.value = cmdValue;
12452153Sbp	return ncp_rpc(cH, 6, (char*)&rq, setCommandName, NULL, NULL);
12552153Sbp}
12652153Sbp
12752153SbpNWCCODE
12852153SbpNWSMSetDynamicCmdStrValue(NWCONN_HANDLE cH, pnstr8 setCommandName,
12952153Sbp		pnstr8 cmdValue) {
13052153Sbp	return ncp_rpc(cH, 6, NULL, setCommandName, cmdValue, NULL);
13152153Sbp}
13252153Sbp
13352153SbpNWCCODE
13452153SbpNWSMExecuteNCFFile(NWCONN_HANDLE cH, pnstr8 NCFFileName) {
13552153Sbp	return ncp_rpc(cH, 7, NULL, NCFFileName, NULL, NULL);
13652153Sbp}
137