示例#1
0
/*
**  BootDone -- free up memory allocated for a connection.
**
**	Parameters:
**		rconn - incoming boot complete packet.
**
**	Returns:
**		1 on success, 0 on failure.
**
**	Side Effects:
**		none.
*/
int
BootDone(RMPCONN *rconn)
{
	RMPCONN *oldconn;
	struct rmp_packet *rpl;

	/*
	 *  If we cant find the connection, ignore the request.
	 */
	if ((oldconn = FindConn(rconn)) == NULL) {
		syslog(LOG_ERR, "BootDone: no existing connection (%s)",
		       EnetStr(rconn));
		return(0);
	}

	rpl = &oldconn->rmp;			/* cache ptr to RMP packet */

	/*
	 *  Make sure Session ID's match.
	 */
	if (ntohs(rconn->rmp.r_rrq.rmp_session) !=
	    ((rpl->r_type == RMP_BOOT_REPL)? ntohs(rpl->r_brpl.rmp_session):
	                                    ntohs(rpl->r_rrpl.rmp_session))) {
		syslog(LOG_ERR, "BootDone: bad session id (%s)",
		       EnetStr(rconn));
		return(0);
	}

	RemoveConn(oldconn);			/* remove connection */

	syslog(LOG_INFO, "%s: boot complete", EnetStr(rconn));

	return(1);
}
示例#2
0
void C4Network2Client::CloseConns(const char *szMsg) {
  C4PacketConnRe Pkt(false, false, szMsg);
  C4Network2IOConnection *pConn;
  while (pConn = pMsgConn) {
    // send packet, close
    if (pConn->isOpen()) {
      pConn->Send(MkC4NetIOPacket(PID_ConnRe, Pkt));
      pConn->Close();
    }
    // remove
    RemoveConn(pConn);
  }
}
示例#3
0
/*
**  DoTimeout -- Free any connections that have timed out.
**
**	Parameters:
**		None.
**
**	Returns:
**		Nothing.
**
**	Side Effects:
**		- Timed out connections in `RmpConns' will be freed.
*/
void
DoTimeout(void)
{
	RMPCONN *rtmp;
	time_t now;

	/*
	 *  For each active connection, if RMP_TIMEOUT seconds have passed
	 *  since the last packet was sent, delete the connection.
	 */
	now = time(NULL);
	for (rtmp = RmpConns; rtmp != NULL; rtmp = rtmp->next)
		if ((rtmp->tstamp.tv_sec + RMP_TIMEOUT) < now) {
			syslog(LOG_WARNING, "%s: connection timed out (%u)",
			       EnetStr(rtmp), rtmp->rmp.r_type);
			RemoveConn(rtmp);
		}
}
示例#4
0
/*
**  SendBootRepl -- open boot file and respond to boot request.
**
**	Parameters:
**		req - RMP BOOT packet containing the request.
**		rconn - the reply packet to be formatted.
**		filelist - list of files available to the requester.
**
**	Returns:
**		1 on success, 0 on failure.
**
**	Side Effects:
**		none.
*/
int
SendBootRepl(struct rmp_packet *req, RMPCONN *rconn, char *filelist[])
{
	int retval;
	char *filename, filepath[RMPBOOTDATA+1];
	RMPCONN *oldconn;
	struct rmp_packet *rpl;
	char *src, *dst1, *dst2;
	u_int8_t i;

	/*
	 *  If another connection already exists, delete it since we
	 *  are obviously starting again.
	 */
	if ((oldconn = FindConn(rconn)) != NULL) {
		syslog(LOG_WARNING, "%s: dropping existing connection",
		       EnetStr(oldconn));
		RemoveConn(oldconn);
	}

	rpl = &rconn->rmp;			/* cache ptr to RMP packet */

	/*
	 *  Set up assorted fields in reply packet.
	 */
	rpl->r_brpl.rmp_type = RMP_BOOT_REPL;
	COPYWORD(req->r_brq.rmp_seqno, rpl->r_brpl.rmp_seqno);
	rpl->r_brpl.rmp_session = htons(GenSessID());
	rpl->r_brpl.rmp_version = htons(RMP_VERSION);
	rpl->r_brpl.rmp_flnmsize = req->r_brq.rmp_flnmsize;

	/*
	 *  Copy file name to `filepath' string, and into reply packet.
	 */
	src = &req->r_brq.rmp_flnm;
	dst1 = filepath;
	dst2 = &rpl->r_brpl.rmp_flnm;
	for (i = 0; i < req->r_brq.rmp_flnmsize; i++)
		*dst1++ = *dst2++ = *src++;
	*dst1 = '\0';

	/*
	 *  If we are booting HP-UX machines, their secondary loader will
	 *  ask for files like "/hp-ux".  As a security measure, we do not
	 *  allow boot files to lay outside the boot directory (unless they
	 *  are purposely link'd out.  So, make `filename' become the path-
	 *  stripped file name and spoof the client into thinking that it
	 *  really got what it wanted.
	 */
	filename = (filename = strrchr(filepath,'/'))? ++filename: filepath;

	/*
	 *  Check that this is a valid boot file name.
	 */
	for (i = 0; i < C_MAXFILE && filelist[i] != NULL; i++)
		if (STREQN(filename, filelist[i]))
			goto match;

	/*
	 *  Invalid boot file name, set error and send reply packet.
	 */
	rpl->r_brpl.rmp_retcode = RMP_E_NOFILE;
	retval = 0;
	goto sendpkt;

match:
	/*
	 *  This is a valid boot file.  Open the file and save the file
	 *  descriptor associated with this connection and set success
	 *  indication.  If the file couldnt be opened, set error:
	 *  	"no such file or dir" - RMP_E_NOFILE
	 *	"file table overflow" - RMP_E_BUSY
	 *	"too many open files" - RMP_E_BUSY
	 *	anything else         - RMP_E_OPENFILE
	 */
	if ((rconn->bootfd = open(filename, O_RDONLY, 0600)) < 0) {
		rpl->r_brpl.rmp_retcode = (errno == ENOENT)? RMP_E_NOFILE:
			(errno == EMFILE || errno == ENFILE)? RMP_E_BUSY:
			RMP_E_OPENFILE;
		retval = 0;
	} else {
		rpl->r_brpl.rmp_retcode = RMP_E_OKAY;
		retval = 1;
	}

sendpkt:
	syslog(LOG_INFO, "%s: request to boot %s (%s)",
	       EnetStr(rconn), filename, retval? "granted": "denied");

	rconn->rmplen = RMPBOOTSIZE(rpl->r_brpl.rmp_flnmsize);

	return (retval & SendPacket(rconn));
}