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

📄 udp_usrreq.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
	 * Calculate data length and get a mbuf	 * for UDP and IP headers.	 */	for (m = m0; m; m = m->m_next)		len += m->m_len;	MGET(m, M_DONTWAIT, MT_DATA);	if (m == 0) {		m_freem(m0);		return (ENOBUFS);	}	/*	 * Fill in mbuf with extended UDP header	 * and addresses and length put into network format.	 */	m->m_off = MMAXOFF - sizeof (struct udpiphdr);	m->m_len = sizeof (struct udpiphdr);	m->m_next = m0;	ui = mtod(m, struct udpiphdr *);	ui->ui_next = ui->ui_prev = 0;	ui->ui_x1 = 0;	ui->ui_pr = IPPROTO_UDP;	ui->ui_len = htons((u_short)len + sizeof (struct udphdr));	ui->ui_src = inp->inp_laddr;	ui->ui_dst = inp->inp_faddr;	ui->ui_sport = inp->inp_lport;	ui->ui_dport = inp->inp_fport;	ui->ui_ulen = ui->ui_len;	/*	 * Stuff checksum and output datagram.	 */	ui->ui_sum = 0;	if (udpcksum) {	    if ((ui->ui_sum = in_cksum(m, sizeof (struct udpiphdr) + len)) == 0)		ui->ui_sum = -1;	}	((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len;	((struct ip *)ui)->ip_ttl = udp_ttl;	UDPSTAT(udps_total++);	UDPSTAT(udps_outdatagrams++);	return (ip_output(m, inp->inp_options, &inp->inp_route,	 inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST), 	 inp->inp_socket));}/* CJ - increased sendspace from 2K, recvspace from 4K */int	udp_sendspace = 9000;		/* really max datagram size */int	udp_recvspace = 9000;/*ARGSUSED*/udp_usrreq(so, req, m, nam, rights)	struct socket *so;	int req;	struct mbuf *m, *nam, *rights;{	struct inpcb *inp = sotoinpcb(so);	int error = 0;	struct socket *so_tmp;		/* SMP */	struct socket *so_addr = NULL;	/* SMP */	int status;			/* SMP */	struct inpcb *inp_tmp = NULL; 	/* SMP */	struct inpcb *head = NULL; 	/* SMP */	/*	 * SMP: Socket lock set coming in all cases save SENSE.  	 * Up to splnet coming in. 	 */	if (req == PRU_CONTROL)		return (in_control(so, (int)m, (caddr_t)nam,			(struct ifnet *)rights));	if (rights && rights->m_len) {		error = EINVAL;		goto release;	}	if (inp == NULL && req != PRU_ATTACH) {		error = EINVAL;		goto release;	}	switch (req) {	case PRU_ATTACH:		if (inp != NULL) {			error = EINVAL;			break;		}		if (smp){			so->ref = 15;	                smp_unlock(&so->lk_socket);			smp_lock(&lk_udb, LK_RETRY);			smp_lock(&so->lk_socket, LK_RETRY);			so->ref = 0;			error = in_pcballoc(so, &udb);			smp_unlock(&lk_udb);		}else			error = in_pcballoc(so, &udb);		if (error)			break;		error = soreserve(so, udp_sendspace, udp_recvspace);		if (error)			break;#ifdef XTI		so->so_xticb.xti_tpinfo = &xti_udpinfo;#endif XTI		break;	case PRU_DETACH:		if (inp == NULL) {			error = ENOTCONN;			break;		}		if (smp){			so->ref = 16;	                smp_unlock(&so->lk_socket);			smp_lock(&lk_udb, LK_RETRY);			smp_lock(&so->lk_socket, LK_RETRY);			so->ref = 0;			in_pcbdetach(inp);			smp_unlock(&lk_udb);		}else			in_pcbdetach(inp);		break;	case PRU_BIND:		if (smp){			so->ref = 17;	                smp_unlock(&so->lk_socket);			smp_lock(&lk_udb, LK_RETRY);			smp_lock(&so->lk_socket, LK_RETRY);			so->ref = 0;			error = in_pcbbind(inp, nam);			smp_unlock(&lk_udb);		}else			error = in_pcbbind(inp, nam);		break;	case PRU_LISTEN:		error = EOPNOTSUPP;		break;	case PRU_CONNECT:		if (inp->inp_faddr.s_addr != INADDR_ANY) {			error = EISCONN;			break;		}		if (smp){			so->ref = 18;	                smp_unlock(&so->lk_socket);			smp_lock(&lk_udb, LK_RETRY);			smp_lock(&so->lk_socket, LK_RETRY);			so->ref = 0;			error = in_pcbconnect(inp, nam);			smp_unlock(&lk_udb);		}else			error = in_pcbconnect(inp, nam);		if (error == 0)			soisconnected(so);		break;	case PRU_CONNECT2:		error = EOPNOTSUPP;		break;	case PRU_ACCEPT:		error = EOPNOTSUPP;		break;	case PRU_DISCONNECT:		if (inp->inp_faddr.s_addr == INADDR_ANY) {			error = ENOTCONN;			break;		}		if (smp){			so->ref = 19;	                smp_unlock(&so->lk_socket);			smp_lock(&lk_udb, LK_RETRY);			smp_lock(&so->lk_socket, LK_RETRY);			so->ref = 0;			in_pcbdisconnect(inp);			smp_unlock(&lk_udb);		}else			in_pcbdisconnect(inp);		so->so_state &= ~SS_ISCONNECTED;		/* XXX */		break;	case PRU_SHUTDOWN:		socantsendmore(so);		break;	case PRU_SEND: {		struct in_addr laddr;		if (nam) {			laddr = inp->inp_laddr;			if (inp->inp_faddr.s_addr != INADDR_ANY) {				error = EISCONN;				break;			}			/*			 * Must block input while temporarily connected.			 */			if (smp){				so->ref = 20;		                smp_unlock(&so->lk_socket);				smp_lock(&lk_udb, LK_RETRY);				smp_lock(&so->lk_socket, LK_RETRY);				so->ref = 0;				error = in_pcbconnect(inp, nam);				smp_unlock(&lk_udb);			}else				error = in_pcbconnect(inp, nam);			if (error) {				break;			}		} else {			if (inp->inp_faddr.s_addr == INADDR_ANY) {				error = ENOTCONN;				break;			}		}		error = udp_output(inp, m);		m = NULL;		if (nam) {			if (smp){				so->ref = 21;		                smp_unlock(&so->lk_socket);				smp_lock(&lk_udb, LK_RETRY);				smp_lock(&so->lk_socket, LK_RETRY);				so->ref = 0;				in_pcbdisconnect(inp);				smp_unlock(&lk_udb);			}else				in_pcbdisconnect(inp);			inp->inp_laddr = laddr;		}		}		break;	case PRU_ABORT:		soisdisconnected(so);		if (smp){			so->ref = 22;	                smp_unlock(&so->lk_socket);			smp_lock(&lk_udb, LK_RETRY);			smp_lock(&so->lk_socket, LK_RETRY);			so->ref = 0;			in_pcbdetach(inp);			smp_unlock(&lk_udb);		}else			in_pcbdetach(inp);		break;	case PRU_SOCKADDR:		in_setsockaddr(inp, nam);		break;	case PRU_PEERADDR:		in_setpeeraddr(inp, nam);		break;	case PRU_SENSE:		/*		 * stat: don't bother with a blocksize.		 */		return (0);	case PRU_SENDOOB:	case PRU_FASTTIMO:	case PRU_SLOWTIMO:	case PRU_PROTORCV:	case PRU_PROTOSEND:		error =  EOPNOTSUPP;		break;	case PRU_RCVD:	case PRU_RCVOOB:		return (EOPNOTSUPP);	/* do not free mbuf's */	default:		error = EOPNOTSUPP;	}release:	if (m != NULL)		m_freem(m);	return (error);}#ifdef XTIudp_ctloutput(op, so, level, optname, mp)        int op;        struct socket *so;        int level, optname;        struct mbuf **mp;{        int error = 0;	struct inpcb *inp = sotoinpcb(so);	register struct mbuf *m = 0;  	if (level != IPPROTO_UDP)	  return (ip_ctloutput(op, so, level, optname, mp));	switch (op) {	case PRCO_XTIMAPSTATE:	  so->so_xticb.xti_states = udp_to_xtistate(so);	  break;    	case PRCO_XTIMAPINFO:	  so->so_xticb.xti_tpinfo = 	    &xti_udpinfo; /* info is per provider */	  break;	case PRCO_XTIUNBIND:	  xtiin_pcbunbind(so->so_pcb);	  break;	case PRCO_SETOPT:	  m = *mp;	  switch (optname) {	    	  default:	    error = EINVAL;	    break;	  };	  break;	case PRCO_GETOPT:	  {	    int tmp_status;      	    *mp = m = m_get(M_WAIT, MT_SOOPTS);	    m->m_len = sizeof(int);    	    switch (optname) {		    default:	      error = EINVAL;	      break;	    };	    break;	  }	};	if(m)	  (void) m_free(m);	return (error);}/* * KEY * --- * so   - socket pointer * inp  - internet control block pointer * fd   - file desciptor * * STATE        MINIMUM MAPPING * ----------   ----------------------------- * T_UNINIT     (getsock(fd) == 0)) * T_UNBND      (getsock(fd) > 0) * T_IDLE	(inp->inp_lport || inp->inp_fport) */udp_to_xtistate(so)        struct socket *so;{        int status;	int default_state;	struct inpcb *inp;	/*	 * determine what state we are in	 */	/*	 * we are already past T_UNINIT state, because	 * if we were a bogus descriptor or a non-socket descriptor we	 * would have been caught.	 */	default_state = T_UNBND;		if (so) inp = (struct inpcb *) so->so_pcb;		if (inp)	  if (inp->inp_lport || inp->inp_fport) {	    default_state = T_IDLE;	  } else {	    return(default_state);	  }	else	  return(default_state);		return(default_state);}#endif XTI

⌨️ 快捷键说明

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