⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 net.cc

📁 rtpmon-1.0a7.tar.gz for UNIX like
💻 CC
字号:
/*- * Copyright (c) 1993-1994, 1996 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *      This product includes software developed by the University of *      California, Berkeley and the Network Research Group at *      Lawrence Berkeley Laboratory. * 4. Neither the name of the University nor of the Laboratory may be used *    to endorse or promote products derived from this software without *    specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * $Id: net.cc,v 1.2 1996/06/05 01:24:27 aswan Exp $ */#include <stdlib.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <fcntl.h>#include <errno.h>#include <string.h>#include <sys/socket.h>#include <sys/uio.h>#include "net.h"//#include "crypt.h"/* * Linux does not have sendmsg */#if defined(__linux__)#define MAXPACKETSIZE (1500-28)static intsendmsg(int s, struct msghdr* mh, int flags){	u_char wrkbuf[MAXPACKETSIZE];	int len = mh->msg_iovlen;	struct iovec* iov = mh->msg_iov;	u_char* cp;	u_char* ep;	for (cp = wrkbuf, ep = wrkbuf + MAXPACKETSIZE; --len >= 0; ++iov) {		int plen = iov->iov_len;		if (cp + plen >= ep) {			errno = E2BIG;			return (-1);		}		memcpy(cp, iov->iov_base, plen);		cp += plen;	}	return (send(s, (char*)wrkbuf, cp - wrkbuf, flags));}#endifNetwork::Network()	: addr_(0), local_(0), port_(0), ttl_(0),	  rsock_(-1), ssock_(-1), crypt_(0){}Network::~Network(){}int Network::command(int argc, const char*const* argv){	if (argc == 2) {		Tcl& tcl = Tcl::instance();		char* cp = tcl.buffer();		if (strcmp(argv[1], "addr") == 0)			strcpy(cp, intoa(addr_));		else if (strcmp(argv[1], "interface") == 0)			strcpy(cp, intoa(local_));		else if (strcmp(argv[1], "port") == 0)			sprintf(cp, "%d", ntohs(port_));		else if (strcmp(argv[1], "ttl") == 0)			sprintf(cp, "%d", ttl_);		else			return (TclObject::command(argc, argv));		tcl.result(cp);		return (TCL_OK);	} else if (argc == 3) {		if (strcmp(argv[1], "crypt") == 0) {			/*			 * 'crypt ""' will turn of encryption because			 * lookup() will return null.			 */			crypt_ = (Crypt*)TclObject::lookup(argv[2]);			return (TCL_OK);		}	}	return (TclObject::command(argc, argv));}void Network::nonblock(int fd){               int flags = fcntl(fd, F_GETFL, 0);#if defined(hpux) || defined(__hpux)        flags |= O_NONBLOCK;#else        flags |= O_NONBLOCK|O_NDELAY;#endif        if (fcntl(fd, F_SETFL, flags) == -1) {                perror("fcntl: F_SETFL");                exit(1);        }}u_char* Network::wrkbuf_;int Network::wrkbuflen_;void Network::expand_wrkbuf(int len){	if (wrkbuflen_ == 0)		wrkbuf_ = (u_char*)malloc(len);	else		wrkbuf_ = (u_char*)realloc((u_char*)wrkbuf_, len);	wrkbuflen_ = len;}void Network::dosend(u_char* buf, int len, int fd){	int cc = ::send(fd, (char*)buf, len, 0);	if (cc < 0) {		switch (errno) {		case ECONNREFUSED:			/* no one listening at some site - ignore */#if defined(__osf__) || defined(_AIX)			/*			 * Due to a bug in kern/uipc_socket.c, on several			 * systems, datagram sockets incorrectly persist			 * in an error state on receipt of an ICMP			 * port-unreachable.  This causes unicast connection			 * rendezvous problems, and worse, multicast			 * transmission problems because several systems			 * incorrectly send port unreachables for 			 * multicast destinations.  Our work around			 * is to simply close and reopen the socket			 * (by calling reset() below).			 *			 * This bug originated at CSRG in Berkeley			 * and was present in the BSD Reno networking			 * code release.  It has since been fixed			 * in 4.4BSD and OSF-3.x.  It is know to remain			 * in AIX-4.1.3.			 *			 * A fix is to change the following lines from			 * kern/uipc_socket.c:			 *			 *	if (so_serror)			 *		snderr(so->so_error);			 *			 * to:			 *			 *	if (so->so_error) {			 * 		error = so->so_error;			 *		so->so_error = 0;			 *		splx(s);			 *		goto release;			 *	}			 *			 */			reset();#endif			break;		case ENETUNREACH:		case EHOSTUNREACH:			/*			 * These "errors" are totally meaningless.			 * There is some broken host sending			 * icmp unreachables for multicast destinations.			 * UDP probably aborted the send because of them --			 * try exactly once more.  E.g., the send we			 * just did cleared the errno for the previous			 * icmp unreachable, so we should be able to			 * send now.			 */			(void)::send(ssock_, (char*)buf, len, 0);			break;		default:			perror("send");			return;		}	}}void Network::send(u_char* buf, int len){	if (crypt_)	        //buf = crypt_->Encrypt(buf, len);	dosend(buf, len, ssock_);}/* * Copy a scatter/gather packet to the work buffer and * return it's length. */int Network::cpmsg(const msghdr& mh){	int len, i;	for (len = 0, i = 0; i < mh.msg_iovlen; ++i)		len += mh.msg_iov[i].iov_len;	expand_wrkbuf(len);	u_char* cp = wrkbuf_;	for (i = 0; i < mh.msg_iovlen; ++i) {		int cc = mh.msg_iov[i].iov_len;		memcpy(cp, mh.msg_iov[i].iov_base, cc);		cp += cc;	}	return (len);}void Network::sendmsg(const msghdr& mh){	if (crypt_) {		int cc = cpmsg(mh);		send(wrkbuf_, cc);		return;	}	int cc = ::sendmsg(ssock_, (msghdr*)&mh, 0);	if (cc < 0) {		switch (errno) {		case ECONNREFUSED:			/* no one listening at some site - ignore */#if defined(__osf__) || defined(_AIX)			reset();#endif			break;		case ENETUNREACH:		case EHOSTUNREACH:			/*			 * These "errors" are totally meaningless.			 * There is some broken host sending			 * icmp unreachables for multicast destinations.			 * UDP probably aborted the send because of them --			 * try exactly once more.  E.g., the send we			 * just did cleared the errno for the previous			 * icmp unreachable, so we should be able to			 * send now.			 */			(void)::sendmsg(ssock_, (msghdr*)&mh, 0);			break;		default:			perror("sendmsg");			return;		}	}}int Network::dorecv(u_char* buf, int len, u_int32_t& from, int fd){    errno = 0;	sockaddr_in sfrom;	int fromlen = sizeof(sfrom);	int cc = ::recvfrom(fd, (char*)buf, len, 0,			    (sockaddr*)&sfrom, &fromlen);	if (cc < 0) {		if (errno != EWOULDBLOCK)			perror("recvfrom");		return (-1);	}	from = sfrom.sin_addr.s_addr;	return (cc);}int Network::recv(u_char* buf, int len, u_int32_t& from){	if (crypt_) {		if (len > wrkbuflen_)			expand_wrkbuf(len);		int cc = dorecv(wrkbuf_, len, from, rsock_);		//return (crypt_->Decrypt(wrkbuf_, cc, buf));	}	return (dorecv(buf, len, from, rsock_));}void Network::reset(){}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -