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

📄 tp_inet.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
 * * CALLED FROM:  tp_emit() * * FUNCTION and ARGUMENTS: *  Take a packet(m0) from tp and package it so that ip will accept it. *  This means prepending space for the ip header and filling in a few *  of the fields. *  inp is the inpcb structure; datalen is the length of the data in the *  mbuf string m0. * RETURNS:			 *  whatever (E*) is returned form the net layer output routine. * * SIDE EFFECTS:	 * * NOTES:			 */inttpip_output(inp, m0, datalen, nochksum)	struct inpcb		*inp;	struct mbuf 		*m0;	int 				datalen;	int					nochksum;{	return tpip_output_dg( &inp->inp_laddr, &inp->inp_faddr, m0, datalen,		&inp->inp_route, nochksum);}/* * NAME:	tpip_output_dg() * * CALLED FROM:  tp_error_emit() * * FUNCTION and ARGUMENTS: *  This is a copy of tpip_output that takes the addresses *  instead of a pcb.  It's used by the tp_error_emit, when we *  don't have an in_pcb with which to call the normal output rtn. * * RETURNS:	 ENOBUFS or  whatever (E*) is  *	returned form the net layer output routine. * * SIDE EFFECTS:	 * * NOTES:			 *//*ARGSUSED*/inttpip_output_dg(laddr, faddr, m0, datalen, ro, nochksum)	struct in_addr		*laddr, *faddr;	struct mbuf 		*m0;	int 				datalen;	struct route 		*ro;	int					nochksum;{	register struct mbuf 	*m;	register struct ip *ip;	int 					error;	IFDEBUG(D_EMIT)		printf("tpip_output_dg  datalen 0x%x m0 0x%x\n", datalen, m0);	ENDDEBUG	MGETHDR(m, M_DONTWAIT, TPMT_IPHDR);	if (m == 0) {		error = ENOBUFS;		goto bad;	}	m->m_next = m0;	MH_ALIGN(m, sizeof(struct ip));	m->m_len = sizeof(struct ip);	ip = mtod(m, struct ip *);	bzero((caddr_t)ip, sizeof *ip);	ip->ip_p = IPPROTO_TP;	m->m_pkthdr.len = ip->ip_len = sizeof(struct ip) + datalen;	ip->ip_ttl = MAXTTL;			/* don't know why you need to set ttl;		 * overlay doesn't even make this available		 */	ip->ip_src = *laddr;	ip->ip_dst = *faddr;	IncStat(ts_tpdu_sent);	IFDEBUG(D_EMIT)		dump_mbuf(m, "tpip_output_dg before ip_output\n");	ENDDEBUG	error = ip_output(m, (struct mbuf *)0, ro, IP_ALLOWBROADCAST, NULL);	IFDEBUG(D_EMIT)		printf("tpip_output_dg after ip_output\n");	ENDDEBUG	return error;bad:	m_freem(m);	IncStat(ts_send_drop);	return error;}/* * NAME:  tpip_input() * * CALLED FROM: * 	ip's input routine, indirectly through the protosw. * * FUNCTION and ARGUMENTS: * Take a packet (m) from ip, strip off the ip header and give it to tp * * RETURNS:  No return value.   *  * SIDE EFFECTS: * * NOTES: */ProtoHooktpip_input(m, iplen)	struct mbuf *m;	int iplen;{	struct sockaddr_in 	src, dst;	register struct ip 		*ip;	int						s = splnet(), hdrlen;	IncStat(ts_pkt_rcvd);	/*	 * IP layer has already pulled up the IP header,	 * but the first byte after the IP header may not be there,	 * e.g. if you came in via loopback, so you have to do an	 * m_pullup to before you can even look to see how much you	 * really need.  The good news is that m_pullup will round	 * up to almost the next mbuf's worth.	 */	if((m = m_pullup(m, iplen + 1)) == MNULL)		goto discard;	CHANGE_MTYPE(m, TPMT_DATA);		/*	 * Now pull up the whole tp header:	 * Unfortunately, there may be IP options to skip past so we	 * just fetch it as an unsigned char.	 */	hdrlen = iplen + 1 + mtod(m, u_char *)[iplen];	if( m->m_len < hdrlen ) {		if((m = m_pullup(m, hdrlen)) == MNULL){			IFDEBUG(D_TPINPUT)				printf("tp_input, pullup 2!\n");			ENDDEBUG			goto discard;		}	}	/* 	 * cannot use tp_inputprep() here 'cause you don't 	 * have quite the same situation	 */	IFDEBUG(D_TPINPUT)		dump_mbuf(m, "after tpip_input both pullups");	ENDDEBUG	/* 	 * m_pullup may have returned a different mbuf	 */	ip = mtod(m, struct ip *);	/*	 * drop the ip header from the front of the mbuf	 * this is necessary for the tp checksum	 */	m->m_len -= iplen;	m->m_data += iplen;	src.sin_addr = *(struct in_addr *)&(ip->ip_src);	src.sin_family  = AF_INET;	src.sin_len  = sizeof(src);	dst.sin_addr = *(struct in_addr *)&(ip->ip_dst);	dst.sin_family  = AF_INET; 	dst.sin_len  = sizeof(dst);	(void) tp_input(m, (struct sockaddr *)&src, (struct sockaddr *)&dst,				0, tpip_output_dg, 0);	return 0;discard:	IFDEBUG(D_TPINPUT)		printf("tpip_input DISCARD\n");	ENDDEBUG	IFTRACE(D_TPINPUT)		tptrace(TPPTmisc, "tpip_input DISCARD m",  m,0,0,0);	ENDTRACE	m_freem(m);	IncStat(ts_recv_drop);	splx(s);	return 0;}#include <sys/protosw.h>#include <netinet/ip_icmp.h>extern void tp_quench();/* * NAME:	tpin_quench() * * CALLED FROM: tpip_ctlinput() * * FUNCTION and ARGUMENTS:  find the tpcb pointer and pass it to tp_quench * * RETURNS:	Nada * * SIDE EFFECTS:	 * * NOTES:			 */voidtpin_quench(inp)	struct inpcb *inp;{	tp_quench((struct tp_pcb *)inp->inp_socket->so_pcb, PRC_QUENCH);}/* * NAME:	tpip_ctlinput() * * CALLED FROM: *  The network layer through the protosw table. * * FUNCTION and ARGUMENTS: *	When clnp gets an ICMP msg this gets called. *	It either returns an error status to the user or *	causes all connections on this address to be aborted *	by calling the appropriate xx_notify() routine. *	(cmd) is the type of ICMP error.    * 	(sa) the address of the sender * * RETURNS:	 Nothing * * SIDE EFFECTS:	 * * NOTES:			 */ProtoHooktpip_ctlinput(cmd, sin)	int cmd;	struct sockaddr_in *sin;{	extern u_char inetctlerrmap[];	extern struct in_addr zeroin_addr;	void tp_quench __P((struct inpcb *,int));	void tpin_abort __P((struct inpcb *,int));	if (sin->sin_family != AF_INET && sin->sin_family != AF_IMPLINK)		return 0;	if (sin->sin_addr.s_addr == INADDR_ANY)		return 0;	if (cmd < 0 || cmd > PRC_NCMDS)		return 0;	switch (cmd) {		case	PRC_QUENCH:			in_pcbnotify(&tp_inpcb, (struct sockaddr *)sin, 0,				zeroin_addr, 0, cmd, tp_quench);			break;		case	PRC_ROUTEDEAD:		case	PRC_HOSTUNREACH:		case	PRC_UNREACH_NET:		case	PRC_IFDOWN:		case	PRC_HOSTDEAD:			in_pcbnotify(&tp_inpcb, (struct sockaddr *)sin, 0,				zeroin_addr, 0, cmd, in_rtchange);			break;		default:		/*		case	PRC_MSGSIZE:		case	PRC_UNREACH_HOST:		case	PRC_UNREACH_PROTOCOL:		case	PRC_UNREACH_PORT:		case	PRC_UNREACH_NEEDFRAG:		case	PRC_UNREACH_SRCFAIL:		case	PRC_REDIRECT_NET:		case	PRC_REDIRECT_HOST:		case	PRC_REDIRECT_TOSNET:		case	PRC_REDIRECT_TOSHOST:		case	PRC_TIMXCEED_INTRANS:		case	PRC_TIMXCEED_REASS:		case	PRC_PARAMPROB:		*/		in_pcbnotify(&tp_inpcb, (struct sockaddr *)sin, 0,			zeroin_addr, 0, cmd, tpin_abort);	}	return 0;}/* * NAME:	tpin_abort() * * CALLED FROM: *	xxx_notify() from tp_ctlinput() when *  net level gets some ICMP-equiv. type event. * * FUNCTION and ARGUMENTS: *  Cause the connection to be aborted with some sort of error *  reason indicating that the network layer caused the abort. *  Fakes an ER TPDU so we can go through the driver. * * RETURNS:	 Nothing * * SIDE EFFECTS:	 * * NOTES:			 */ProtoHooktpin_abort(inp)	struct inpcb *inp;{	struct tp_event e;	e.ev_number = ER_TPDU;	e.ATTR(ER_TPDU).e_reason = ENETRESET;	(void) tp_driver((struct tp_pcb *)inp->inp_ppcb, &e);	return 0;}#ifdef ARGO_DEBUGdump_inaddr(addr)	register struct sockaddr_in *addr;{	printf("INET: port 0x%x; addr 0x%x\n", addr->sin_port, addr->sin_addr);}#endif /* ARGO_DEBUG */#endif /* INET */

⌨️ 快捷键说明

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