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

📄 net-ip.cc

📁 柯老师网站上找到的
💻 CC
📖 第 1 页 / 共 2 页
字号:
		return (-1);	}	if (mode_ == O_RDONLY) {		fprintf(stderr,		"UDPIPNetwork(%s): attempted connect but net is read-only\n",			name());		return (-1);	}	int rval = connectsock(ssock_, addr, port, sin);	if (rval < 0)		return (rval);	destaddr_ = addr;	port_ = port;	last_reset_ = 0;	return(rval);}intUDPIPNetwork::command(int argc, const char*const* argv){	Tcl& tcl = Tcl::instance();	if (argc == 2) {		// $udpip port		if (strcmp(argv[1], "port") == 0) {			tcl.resultf("%d", ntohs(port_));			return (TCL_OK);		}		// $udpip lport		if (strcmp(argv[1], "lport") == 0) {			tcl.resultf("%d", ntohs(lport_));			return (TCL_OK);		}	} else if (argc == 4) {		// $udpip listen addr port		// $udpip bind addr port		if (strcmp(argv[1], "listen") == 0 ||		    strcmp(argv[1], "bind") == 0) {			in_addr addr;			if (strcmp(argv[2], "any") == 0)				addr.s_addr = INADDR_ANY;			else				addr.s_addr = LookupHostAddr(argv[2]);			u_int16_t port = htons(atoi(argv[3]));			if (bind(addr, port) < 0) {				tcl.resultf("%s %hu",					inet_ntoa(addr), port);			} else {				tcl.result("0");			}			return (TCL_OK);		}		// $udpip connect addr port		if (strcmp(argv[1], "connect") == 0) {			in_addr addr;			addr.s_addr = LookupHostAddr(argv[2]);			u_int16_t port = htons(atoi(argv[3]));			if (connect(addr, port) < 0) {				tcl.resultf("%s %hu",					inet_ntoa(addr), port);			} else {				tcl.result("0");			}			return (TCL_OK);		}	}	return (IPNetwork::command(argc, argv));}//// raw IP network recv()//intIPNetwork::recv(u_char* buf, int len, sockaddr& sa, double& ts){	if (mode_ == O_WRONLY) {		fprintf(stderr,		    "IPNetwork(%s) recv while in writeonly mode!\n",			name());		abort();	}	int fromlen = sizeof(sa);	int cc = ::recvfrom(rsock_, (char*)buf, len, 0, &sa, &fromlen);	if (cc < 0) {		if (errno != EWOULDBLOCK)			perror("recvfrom");		return (-1);	}	ts = Scheduler::instance().clock();	return (cc);}//// we are given a "raw" IP datagram.// the raw interface appears to want the len and off fields// in *host* order, so make it this way here// note also, that it will compute the cksum "for" us... :(//intIPNetwork::send(u_char* buf, int len){	struct ip *ip = (struct ip*) buf;	ip->ip_len = ntohs(ip->ip_len);	ip->ip_off = ntohs(ip->ip_off);	return (::send(ssock_, (char*)buf, len, 0));}int IPNetwork::command(int argc, const char*const* argv){	Tcl& tcl = Tcl::instance();	if (argc == 2) {		if (strcmp(argv[1], "close") == 0) {			close();			return (TCL_OK);		}		char* cp = tcl.result();		if (strcmp(argv[1], "destaddr") == 0) {			strcpy(cp, inet_ntoa(destaddr_));			return (TCL_OK);		}		if (strcmp(argv[1], "localaddr") == 0) {			strcpy(cp, inet_ntoa(localaddr_));			return (TCL_OK);		}		if (strcmp(argv[1], "mttl") == 0) {			tcl.resultf("%d", mttl_);			return (TCL_OK);		}		/* for backward compatability */		if (strcmp(argv[1], "ismulticast") == 0) {			tcl.result(IN_CLASSD(ntohl(destaddr_.s_addr)) ?				"1" : "0");			return (TCL_OK);		}		if (strcmp(argv[1], "addr") == 0) {			strcpy(cp, inet_ntoa(destaddr_));			return (TCL_OK);		}		if (strcmp(argv[1], "ttl") == 0) {			tcl.resultf("%d", mttl_);			return (TCL_OK);		}		if (strcmp(argv[1], "interface") == 0) {			strcpy(cp, inet_ntoa(localaddr_));			return (TCL_OK);		}	} else if (argc == 3) {				if (strcmp(argv[1], "open") == 0) {			int mode = parsemode(argv[2]);			if (open(mode) < 0)				return (TCL_ERROR);			return (TCL_OK);		}		if (strcmp(argv[1], "add-membership") == 0) {			in_addr addr;			addr.s_addr = LookupHostAddr(argv[2]);			if (add_membership(rchannel(), addr) < 0)				tcl.result("0");			else				tcl.result("1");			return (TCL_OK);		}		if (strcmp(argv[1], "drop-membership") == 0) {			in_addr addr;			addr.s_addr = LookupHostAddr(argv[2]);			if (drop_membership(rchannel(), addr) < 0)				tcl.result("0");			else				tcl.result("1");			return (TCL_OK);		}		if (strcmp(argv[1], "loopback") == 0) {			int val = atoi(argv[2]);			if (strcmp(argv[2], "true") == 0)				val = 1;			else if (strcmp(argv[2], "false") == 0)				val = 0;			if (setmloop(schannel(), val) < 0)				tcl.result("0");			else				tcl.result("1");			return (TCL_OK);		}	}	return (Network::command(argc, argv));}intIPNetwork::setmttl(Socket s, int ttl){        /* set the multicast TTL */  #ifdef WIN32        u_int t = ttl; #else         u_char t = ttl;#endif        t = (ttl > 255) ? 255 : (ttl < 0) ? 0 : ttl;         if (::setsockopt(s, IPPROTO_IP, IP_MULTICAST_TTL,                       (char*)&t, sizeof(t)) < 0) {		fprintf(stderr,		    "IPNetwork(%s): couldn't set multicast ttl to %d\n",			name(), t);                return (-1);        }	return (0);}/* * open a RAW IP socket (will require privilege). * turn on HDRINCL, specifying that we will be writing the raw IP header */intIPNetwork::open(int mode){	// obtain a raw socket we can use to send ip datagrams	Socket fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);	if (fd < 0) {		perror("socket(RAW)");		if (::getuid() != 0 && ::geteuid() != 0) {			fprintf(stderr,	  "IPNetwork(%s): open: use of the Network/IP object requires super-user privs\n",			name());		}		return (-1);	}	// turn on HDRINCL option (we will be writing IP header)	// in FreeBSD 2.2.5 (and possibly others), the IP id field	// is set by the kernel routine rip_output()	// only if it is non-zero, so we should be ok.	int one = 1;	if (::setsockopt(fd, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one)) < 0) {		fprintf(stderr,	"IPNetwork(%s): open: unable to turn on IP_HDRINCL: %s\n",			name(), strerror(errno));		return (-1);	}	// sort of curious, but do a connect() even though we have	// HDRINCL on.  Otherwise, we get ENOTCONN when doing a send()	sockaddr_in sin;	in_addr ia = { INADDR_ANY };	if (connectsock(fd, ia, 0, sin) < 0) {		fprintf(stderr,	"IPNetwork(%s): open: unable to connect : %s\n",			name(), strerror(errno));	}	rsock_ = ssock_ = fd;	mode_ = mode;	NIDEBUG5("IPNetwork(%s): opened with mode %d, rsock_:%d, ssock_:%d\n",		name(), mode_, rsock_, ssock_);	return 0;}/* * close both sending and receiving sockets */intIPNetwork::close(){	if (ssock_ >= 0) {		(void)::close(ssock_);		ssock_ = -1;	}	if (rsock_ >= 0) {		(void)::close(rsock_);		rsock_ = -1;	}	return (0);}/* * add multicast group membership on the socket */intIPNetwork::add_membership(Socket fd, in_addr& addr){#if defined(IP_ADD_MEMBERSHIP)	if (IN_CLASSD(ntohl(addr.s_addr))) {#ifdef notdef		/*		 * Try to bind the multicast address as the socket		 * dest address.  On many systems this won't work		 * so fall back to a destination of INADDR_ANY if		 * the first bind fails.		 */		sockaddr_in sin;		memset(&sin, 0, sizeof(sin));		sin.sin_family = AF_INET;		sin.sin_addr = addr;		if (::bind(fd, (struct sockaddr *) &sin, sizeof(sin)) < 0) {			sin.sin_addr.s_addr = INADDR_ANY;			if (::bind(fd, (struct sockaddr *) &sin, sizeof(sin)) < 0) {				fprintf(stderr,	"IPNetwork(%s): add_membership: unable to bind to addr %s: %s\n",					name(), inet_ntoa(sin.sin_addr),					strerror(errno));				return (-1);			}		}#endif		/* 		 * XXX This is bogus multicast setup that really		 * shouldn't have to be done (group membership should be		 * implicit in the IP class D address, route should contain		 * ttl & no loopback flag, etc.).  Steve Deering has promised		 * to fix this for the 4.4bsd release.  We're all waiting		 * with bated breath.		 */		struct ip_mreq mr;		mr.imr_multiaddr = addr;		mr.imr_interface.s_addr = INADDR_ANY;		if (::setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, 			       (char *)&mr, sizeof(mr)) < 0) {			fprintf(stderr, "IPNetwork(%s): add_membership: unable to add membership for addr %s: %s\n",				name(), inet_ntoa(addr), strerror(errno));			return (-1);		}		NIDEBUG3("IPNetwork(%s): add_membership for grp %s done\n",			name(), inet_ntoa(addr));		return (0);	}#else	fprintf(stderr, "IPNetwork(%s): add_membership: host does not support IP multicast\n",		name());#endif	NIDEBUG3("IPNetwork(%s): add_membership for grp %s failed\n",		name(), inet_ntoa(addr));	return (-1);}/* * drop membership from the specified group on the specified socket */intIPNetwork::drop_membership(Socket fd, in_addr& addr){#if defined(IP_DROP_MEMBERSHIP)	if (IN_CLASSD(ntohl(addr.s_addr))) {		struct ip_mreq mr;		mr.imr_multiaddr = addr;		mr.imr_interface.s_addr = INADDR_ANY;		if (::setsockopt(fd, IPPROTO_IP, IP_DROP_MEMBERSHIP, 			       (char *)&mr, sizeof(mr)) < 0) {			fprintf(stderr, "IPNetwork(%s): drop_membership: unable to drop membership for addr %s: %s\n",				name(), inet_ntoa(addr), strerror(errno));			return (-1);		}		NIDEBUG3("IPNetwork(%s): drop_membership for grp %s done\n",			name(), inet_ntoa(addr));		return (0);	}#else	fprintf(stderr, "IPNetwork(%s): drop_membership: host does not support IP multicast\n",		name());#endif	NIDEBUG3("IPNetwork(%s): drop_membership for grp %s failed\n",		name(), inet_ntoa(addr));	return (-1);}intIPNetwork::bindsock(Socket s, in_addr& addr, u_int16_t port, sockaddr_in& sin){	memset((char *)&sin, 0, sizeof(sin));	sin.sin_family = AF_INET;	sin.sin_port = port;	sin.sin_addr = addr;	return(::bind(s, (struct sockaddr *)&sin, sizeof(sin)));}intIPNetwork::connectsock(Socket s, in_addr& addr, u_int16_t port, sockaddr_in& sin){	memset((char *)&sin, 0, sizeof(sin));	sin.sin_family = AF_INET;	sin.sin_port = port;	sin.sin_addr = addr;	return(::connect(s, (struct sockaddr *)&sin, sizeof(sin)));}int IPNetwork::sbufsize(Socket s, int cnt){           return(::setsockopt(s, SOL_SOCKET, SO_SNDBUF, (char *)&cnt, sizeof(cnt)));}   intIPNetwork::rbufsize(Socket s, int cnt){           return(::setsockopt(s, SOL_SOCKET, SO_RCVBUF, (char *)&cnt, sizeof(cnt)));}   intIPNetwork::setmloop(Socket s, int loop){#ifdef IP_MULTICAST_LOOP	u_char c = loop;	if (::setsockopt(s, IPPROTO_IP, IP_MULTICAST_LOOP, &c, sizeof(c)) < 0) {		/*		 * If we cannot turn off loopback (Like on the		 * Microsoft TCP/IP stack), then declare this		 * option broken so that our packets can be		 * filtered on the recv path.		 */		if (c != loop) {			noloopback_broken_ = 1;			loop_ = c;		}		return (-1);	}	noloopback_broken_ = 0;#else	fprintf(stderr, "IPNetwork(%s): msetloop: host does not support IP multicast\n",		name());#endif	loop_ = c;	return (0);}voidIPNetwork::reset(int restart){	time_t t = time(0);	int d = int(t - last_reset_);	NIDEBUG2("IPNetwork(%s): reset\n", name());	if (d > 3) {	// Steve: why?		last_reset_ = t;		if (ssock_ >= 0)			(void)::close(ssock_);		if (rsock_ >= 0)			(void)::close(rsock_);		if (open(mode_) < 0) {			fprintf(stderr,			  "IPNetwork(%s): couldn't reset\n",			  name());			mode_ = -1;			return;		}		if (restart)			(void) reconfigure();	}}/* * after a reset, we may want to re-establish our state * [set up addressing, etc].  Do this here */voidIPNetwork::reconfigure(){}voidUDPIPNetwork::reconfigure(){}

⌨️ 快捷键说明

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