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

📄 inet.c

📁 7号信令功能代码,为开源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	}	if (!flags || opt->reuse) {		opt->reuse = &opt_defaults.reuse;		opt->flags |= TF_IP_REUSEADDR;	}	if (!flags || opt->norte) {		opt->norte = &opt_defaults.norte;		opt->flags |= TF_IP_DONTROUTE;	}	if (!flags || opt->bcast) {		opt->bcast = &opt_defaults.bcast;		opt->flags |= TF_IP_BROADCAST;	}	if (ss->p.prot.protocol == T_INET_TCP) {		if (!flags || opt->nodly) {			opt->nodly = &opt_defaults.nodly;			opt->flags |= TF_TCP_NODELAY;		}		if (!flags || opt->mss) {			opt->mss = &opt_defaults.mss;			opt->flags |= TF_TCP_MAXSEG;		}		if (!flags || opt->alive) {			opt->alive = &opt_defaults.alive;			opt->flags |= TF_TCP_KEEPALIVE;		}	}	if (ss->p.prot.protocol == T_INET_UDP) {		if (!flags || opt->csum) {			opt->csum = &opt_defaults.csum;			opt->flags |= TF_UDP_CHECKSUM;		}	}	return (0);}/*  *  NEGOTIATE Options *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */STATIC intss_opt_negotiate(ss_t * ss, ss_opts_t * opt){	struct sock *sk = NULL;	if (ss->sock)		sk = ss->sock->sk;	if (opt) {		opt->flags = 0;		if (opt->opt) {			ss->options.opt = *(opt->opt);#ifdef LINUX_2_4			if (sk)				sk->protinfo.af_inet.opt = &ss->options.opt;#else			if (sk)				sk->opt = &ss->options.opt;#endif			opt->flags |= TF_IP_OPTIONS;		}		if (opt->tos) {			ss->options.tos = *(opt->tos);#ifdef LINUX_2_4			if (sk)				sk->protinfo.af_inet.tos = ss->options.tos;#else			if (sk)				sk->ip_tos = ss->options.tos;#endif			opt->flags |= TF_IP_TOS;		}		if (opt->ttl) {			ss->options.ttl = *(opt->ttl);#ifdef LINUX_2_4			if (sk)				sk->protinfo.af_inet.ttl = ss->options.ttl;#else			if (sk)				sk->ip_ttl = ss->options.ttl;#endif			opt->flags |= TF_IP_TTL;		}		if (opt->reuse) {			ss->options.reuse = *(opt->reuse) ? 1 : 0;			if (sk)				sk->reuse = ss->options.reuse;			opt->flags |= TF_IP_REUSEADDR;		}		if (opt->norte) {			ss->options.norte = *(opt->norte) ? 1 : 0;			if (sk)				sk->localroute = ss->options.norte;			opt->flags |= TF_IP_DONTROUTE;		}		if (opt->bcast) {			ss->options.bcast = *(opt->bcast) ? 1 : 0;			if (sk)				sk->broadcast = ss->options.bcast;			opt->flags |= TF_IP_BROADCAST;		}		if (opt->nodly) {			ss->options.nodly = *(opt->nodly) ? 1 : 0;#ifdef LINUX_2_4			if (sk)				sk->tp_pinfo.af_tcp.nonagle = ss->options.nodly;#else			if (sk)				sk->nonagle = ss->options.nodly;#endif			opt->flags |= TF_TCP_NODELAY;		}		if (opt->mss) {			ss->options.mss = *(opt->mss) ? 1 : 0;			if (sk)				sk->tp_pinfo.af_tcp.user_mss = ss->options.mss;			opt->flags |= TF_TCP_MAXSEG;		}		if (opt->alive) {			ss->options.alive = *(opt->alive) ? 1 : 0;			if (sk)				sk->keepopen = ss->options.alive;			opt->flags |= TF_TCP_KEEPALIVE;		}		if (opt->csum) {			ss->options.csum = *(opt->csum) ? 1 : 0;			// if ( sk ) sk->csum = ss->options.csum;			opt->flags |= TF_UDP_CHECKSUM;		}	}	return (0);}/*  *  CURRENT Options *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */STATIC intss_opt_current(ss_t * ss, ss_opts_t * opt){	uint flags = opt->flags;	opt->flags = 0;	if (!flags || opt->opt) {		opt->opt = &ss->options.opt;		opt->flags |= TF_IP_OPTIONS;	}	if (!flags || opt->tos) {		opt->tos = &ss->options.tos;		opt->flags |= TF_IP_TOS;	}	if (!flags || opt->ttl) {		opt->ttl = &ss->options.ttl;		opt->flags |= TF_IP_TTL;	}	if (!flags || opt->reuse) {		opt->reuse = &ss->options.reuse;		opt->flags |= TF_IP_REUSEADDR;	}	if (!flags || opt->norte) {		opt->norte = &ss->options.norte;		opt->flags |= TF_IP_DONTROUTE;	}	if (!flags || opt->bcast) {		opt->bcast = &ss->options.bcast;		opt->flags |= TF_IP_BROADCAST;	}	if (ss->p.prot.protocol == T_INET_TCP) {		if (!flags || opt->nodly) {			opt->nodly = &ss->options.nodly;			opt->flags |= TF_TCP_NODELAY;		}		if (!flags || opt->mss) {			opt->mss = &ss->options.mss;			opt->flags |= TF_TCP_MAXSEG;		}		if (!flags || opt->alive) {			opt->alive = &ss->options.alive;			opt->flags |= TF_TCP_KEEPALIVE;		}	}	if (ss->p.prot.protocol == T_INET_UDP) {		if (!flags || opt->csum) {			opt->csum = &ss->options.csum;			opt->flags |= TF_UDP_CHECKSUM;		}	}	return (0);}/*  *  ========================================================================= * *  Address Handling * *  ========================================================================= */STATIC intss_addr_size(ss_t * ss, struct sockaddr *add){	if (add) {		switch (add->sa_family) {		case AF_INET:			return sizeof(struct sockaddr_in);		case AF_UNIX:			return sizeof(struct sockaddr_un);		case AF_UNSPEC:			return sizeof(add->sa_family);		default:			return sizeof(struct sockaddr);		}	}	return (0);}/*  *  ========================================================================= * *  STATE Changes * *  ========================================================================= */#ifdef _DEBUGSTATIC const char *state_name(long state){	switch (state) {	case TS_UNBND:		return ("TS_UNBND");	case TS_WACK_BREQ:		return ("TS_WACK_BREQ");	case TS_WACK_UREQ:		return ("TS_WACK_UREQ");	case TS_IDLE:		return ("TS_IDLE");	case TS_WACK_OPTREQ:		return ("TS_WACK_OPTREQ");	case TS_WACK_CREQ:		return ("TS_WACK_CREQ");	case TS_WCON_CREQ:		return ("TS_WCON_CREQ");	case TS_WRES_CIND:		return ("TS_WRES_CIND");	case TS_WACK_CRES:		return ("TS_WACK_CRES");	case TS_DATA_XFER:		return ("TS_DATA_XFER");	case TS_WIND_ORDREL:		return ("TS_WIND_ORDREL");	case TS_WREQ_ORDREL:		return ("TS_WREQ_ORDREL");	case TS_WACK_DREQ6:		return ("TS_WACK_DREQ6");	case TS_WACK_DREQ7:		return ("TS_WACK_DREQ7");	case TS_WACK_DREQ9:		return ("TS_WACK_DREQ9");	case TS_WACK_DREQ10:		return ("TS_WACK_DREQ10");	case TS_WACK_DREQ11:		return ("TS_WACK_DREQ11");	case TS_NOSTATES:		return ("TS_NOSTATES");	default:		return ("(unknown)");	}}#endifSTATIC voidss_set_state(ss_t * ss, long state){	printd(("%s: %p: %s <- %s\n", SS_MOD_NAME, ss, state_name(state),		state_name(ss->p.info.CURRENT_state)));	ss->p.info.CURRENT_state = state;}STATIC longss_get_state(ss_t * ss){	return (ss->p.info.CURRENT_state);}#ifdef _DEBUGSTATIC const char *tcp_state_name(int state){	switch (state) {	case TCP_ESTABLISHED:		return ("TCP_ESTABLISHED");	case TCP_SYN_SENT:		return ("TCP_SYN_SENT");	case TCP_SYN_RECV:		return ("TCP_SYN_RECV");	case TCP_FIN_WAIT1:		return ("TCP_FIN_WAIT1");	case TCP_FIN_WAIT2:		return ("TCP_FIN_WAIT2");	case TCP_TIME_WAIT:		return ("TCP_TIME_WAIT");	case TCP_CLOSE:		return ("TCP_CLOSE");	case TCP_CLOSE_WAIT:		return ("TCP_CLOSE_WAIT");	case TCP_LAST_ACK:		return ("TCP_LAST_ACK");	case TCP_LISTEN:		return ("TCP_LISTEN");	case TCP_CLOSING:		return ("TCP_CLOSING");	case TCP_MAX_STATES:		return ("TCP_MAX_STATES");	default:		return ("(unknown)");	}}#endif/*  *  ------------------------------------------------------------------------ * *  Socket Calls * *  ------------------------------------------------------------------------ *  These are wrappered versions of socket calls. *//*  *  SOCKET CREATE *  ------------------------------------------------------------------------ */STATIC intss_socket(ss_t * ss){	int err;	int family, type, protocol;	ensure(ss, return (-EFAULT));	unless(ss->sock, return (-EFAULT));	family = ss->p.prot.family;	type = ss->p.prot.type;	protocol = (ss->p.prot.protocol == IPPROTO_RAW) ? ss->port : ss->p.prot.protocol;	printd(("%s: %p: SS_CREATE %d:%d:%d\n", SS_MOD_NAME, ss, family, type, protocol));	if (!(err = sock_create(family, type, protocol, &ss->sock))) {		ensure(ss->sock, return (-EFAULT));		ensure(ss->sock->sk, return (-EFAULT));		ss->sock->sk->allocation = GFP_ATOMIC;		ss_socket_get(ss->sock, ss);		return (0);	}	printd(("%s: %p: ERROR: from sock_create %d\n", SS_MOD_NAME, ss, err));	return (err);}/*  *  SOCKET BIND *  ------------------------------------------------------------------------ */STATIC intss_bind(ss_t * ss, struct sockaddr *add){	int err;	ensure(ss, return (-EFAULT));	ensure(ss->sock, return (-EFAULT));	ensure(ss->sock->sk, return (-EFAULT));	ensure(ss->sock->ops, return (-EFAULT));	ensure(ss->sock->ops->bind, return (-EFAULT));	printd(("%s: %p: SS_BIND\n", SS_MOD_NAME, ss));	if (!(err = ss->sock->ops->bind(ss->sock, add, sizeof(*add)))) {		ss->src = *add;		return (0);	}	printd(("%s: %p: ERROR: from sock->ops->bind %d\n", SS_MOD_NAME, ss, err));	return (err);}/*  *  SOCKET LISTEN *  ------------------------------------------------------------------------ */STATIC intss_listen(ss_t * ss, uint cons){	int err;	int type;	ensure(ss, return (-EFAULT));	ensure(ss->sock, return (-EFAULT));	ensure(ss->sock->sk, return (-EFAULT));	ensure(ss->sock->ops, return (-EFAULT));	ensure(ss->sock->ops->listen, return (-EFAULT));	type = ss->p.prot.type;	ensure(type == SOCK_STREAM || type == SOCK_SEQPACKET, return (-EFAULT));	printd(("%s: %p: SS_LISTEN %d\n", SS_MOD_NAME, ss, cons));	if (!(err = ss->sock->ops->listen(ss->sock, cons))) {		ss->conind = cons;		ss->tcp_state = ss->sock->sk->state;		return (0);	}	printd(("%s: %p: ERROR: from sock->ops->listen %d\n", SS_MOD_NAME, ss, err));	return (err);}/*  *  SOCKET ACCEPT *  ------------------------------------------------------------------------ *  Unfortunately, sock->ops->accept will only accept the next sequential *  connection indication.  In TLI's case, we want to be able to accept or *  release connection indications other than the next sequential indication. *  To do this we must muck with TCP's accept queue when the SEQ_number is not *  the next in the queue.  To do this we mimic some of the tcp_accept *  behavior. */STATIC intss_accept(ss_t * ss, struct socket **newsock, mblk_t *cp){	struct socket *sock;	ensure(newsock, return (-EFAULT));	ensure(cp, return (-EFAULT));	ensure(ss, return (-EFAULT));	ensure(ss->sock, return (-EFAULT));	ensure(ss->sock->sk, return (-EFAULT));	ensure(ss->sock->ops, return (-EFAULT));	ensure(ss->sock->ops->accept, return (-EFAULT));	printd(("%s: %p: SS_ACCEPT\n", SS_MOD_NAME, ss));	if ((sock = sock_alloc())) {		struct sock *sk = ss->sock->sk;		struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;		struct open_request *req, *req_prev, **reqp;		struct sock *ask = ((ss_event_t *) cp->b_rptr)->sk;		sock->type = ss->sock->type;		sock->ops = ss->sock->ops;		lock_sock(sk);		if (tp->accept_queue) {			/* 			   find connection in queue */			for (reqp = &tp->accept_queue, req_prev = NULL; *reqp && (*reqp)->sk != ask;			     req_prev = (*reqp), reqp = &(*reqp)->dl_next) ;			if ((req = *reqp)) {				if (!((*reqp) = (*reqp)->dl_next))					tp->accept_queue_tail = req_prev;				sk->ack_backlog--;				tcp_openreq_fastfree(req);			}			release_sock(sk);			lock_sock(ask);			sock_graft(ask, sock);			release_sock(ask);			sock->state = SS_CONNECTED;			*newsock = sock;			bufq_unlink(&ss->conq, cp);			freemsg(cp);			return (0);		}		release_sock(sk);		ss_socket_put(sock);		printd(("%s: %p: invalid accept\n", SS_MOD_NAME, ss));		return (-EAGAIN);	}	printd(("%s: %p: ERROR: couldn't allocate accepting socket\n", SS_MOD_NAME, ss));	return (-EFAULT);}/*  *  SOCKET UNBIND *  ------------------------------------------------------------------------ *  There is no good way to unbind and rebind a socket in Linux, so we just *  close the entire socket.  The next time we go to bind, we will create *  a fresh socket to bind. */STATIC intss_unbind(ss_t * ss){	ensure(ss, return (-EFAULT));	ensure(ss->sock, return (-EFAULT));	ensure(ss->sock->sk, return (-EFAULT));	printd(("%s: %p: SS_UNBIND\n", SS_MOD_NAME, ss));	ss_socket_put(xchg(&ss->sock, NULL));	return (0);}/*  *  SOCKET CONNECT *  ------------------------------------------------------------------------ */STATIC intss_connect(ss_t * ss, struct sockaddr *dst){	int err;	ensure(ss, return (-EFAULT));	ensure(ss->sock, return (-EFAULT));	ensure(ss->sock->sk, return (-EFAULT));

⌨️ 快捷键说明

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