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

📄 in_pcb.c

📁 VxWorks网络部分的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
}voidin_pcbdisconnect(inp)	struct inpcb *inp;{	inp->inp_faddr.s_addr = INADDR_ANY;	inp->inp_fport = 0;	in_pcbrehash(inp);	if (inp->inp_socket->so_state & SS_NOFDREF)		in_pcbdetach(inp);}voidin_pcbdetach(inp)	struct inpcb *inp;{	struct socket *so = inp->inp_socket;	int s;	so->so_pcb = 0;	sofree(so);	if (inp->inp_options)		(void)m_free(inp->inp_options);	if (inp->inp_route.ro_rt)		rtfree(inp->inp_route.ro_rt);	ip_freemoptions(inp->inp_moptions, inp);	s = splnet();	LIST_REMOVE(inp, inp_hash);	LIST_REMOVE(inp, inp_list);	splx(s);	FREE(inp, MT_PCB);}voidin_setsockaddr(inp, nam)	register struct inpcb *inp;	struct mbuf *nam;{	register struct sockaddr_in *sin;	nam->m_len = sizeof (*sin);	sin = mtod(nam, struct sockaddr_in *);	bzero((caddr_t)sin, sizeof (*sin));	sin->sin_family = AF_INET;	sin->sin_len = sizeof(*sin);	sin->sin_port = inp->inp_lport;	sin->sin_addr = inp->inp_laddr;}voidin_setpeeraddr(inp, nam)	struct inpcb *inp;	struct mbuf *nam;{	register struct sockaddr_in *sin;	nam->m_len = sizeof (*sin);	sin = mtod(nam, struct sockaddr_in *);	bzero((caddr_t)sin, sizeof (*sin));	sin->sin_family = AF_INET;	sin->sin_len = sizeof(*sin);	sin->sin_port = inp->inp_fport;	sin->sin_addr = inp->inp_faddr;}/* * Pass some notification to all connections of a protocol * associated with address dst.  The local address and/or port numbers * may be specified to limit the search.  The "usual action" will be * taken, depending on the ctlinput cmd.  The caller must filter any * cmds that are uninteresting (e.g., no error in the map). * Call the protocol specific routine (if any) to report * any errors for each matching socket. * * Must be called at splnet. */voidin_pcbnotify(head, dst, fport_arg, laddr, lport_arg, cmd, notify)	struct inpcbhead *head;	struct sockaddr *dst;	u_int fport_arg, lport_arg;	struct in_addr laddr;	int cmd;	void (*notify) (struct inpcb *, int);{	register struct inpcb *inp, *oinp;	struct in_addr faddr;	u_short fport = fport_arg, lport = lport_arg;	int errno, s;	if ((unsigned)cmd > PRC_NCMDS || dst->sa_family != AF_INET)		return;	faddr = ((struct sockaddr_in *)dst)->sin_addr;	if (faddr.s_addr == INADDR_ANY)		return;	/*	 * Redirects go to all references to the destination,	 * and use in_rtchange to invalidate the route cache.	 * Dead host indications: notify all references to the destination.	 * Otherwise, if we have knowledge of the local port and address,	 * deliver only to that socket.	 */	if (PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD) {		fport = 0;		lport = 0;		laddr.s_addr = 0;		if (cmd != PRC_HOSTDEAD)			notify = in_rtchange;	}	errno = inetctlerrmap[cmd];	s = splnet();	for (inp = head->lh_first; inp != NULL;) {		if (inp->inp_faddr.s_addr != faddr.s_addr ||		    inp->inp_socket == 0 ||		    (lport && inp->inp_lport != lport) ||		    (laddr.s_addr && inp->inp_laddr.s_addr != laddr.s_addr) ||		    (fport && inp->inp_fport != fport)) {			inp = inp->inp_list.le_next;			continue;		}		oinp = inp;		inp = inp->inp_list.le_next;		if (notify)			(*notify)(oinp, errno);	}	splx(s);}/* * Check for alternatives when higher level complains * about service problems.  For now, invalidate cached * routing information.  If the route was created dynamically * (by a redirect), time to try a default gateway again. */voidin_losing(inp)	struct inpcb *inp;{	register struct rtentry *rt;	struct rt_addrinfo info;	if ((rt = inp->inp_route.ro_rt)) {		inp->inp_route.ro_rt = 0;		bzero((caddr_t)&info, sizeof(info));		info.rti_info[RTAX_DST] =			(struct sockaddr *)&inp->inp_route.ro_dst;		info.rti_info[RTAX_GATEWAY] = rt->rt_gateway;		info.rti_info[RTAX_NETMASK] = rt_mask(rt);                if (_rtMissMsgHook)                    (*_rtMissMsgHook) (RTM_LOSING, &info, rt->rt_flags, 0);		if (rt->rt_flags & RTF_DYNAMIC)			(void) rtrequestDelEqui(rt_key(rt),rt_mask(rt), 				rt->rt_gateway, rt->rt_flags,                                  RT_PROTO_GET(rt_key(rt)),				(ROUTE_ENTRY **)0);		else		/*		 * A new route can be allocated		 * the next time output is attempted.		 */			rtfree(rt);	}}/* * After a routing change, flush old routing * and allocate a (hopefully) better one. */voidin_rtchange(inp, error)	register struct inpcb *inp;	int error;{	if (inp->inp_route.ro_rt) {		rtfree(inp->inp_route.ro_rt);		inp->inp_route.ro_rt = 0;		/*		 * A new route can be allocated the next time		 * output is attempted.		 */	}}struct inpcb *in_pcblookup(pcbinfo, faddr, fport_arg, laddr, lport_arg, wild_okay)	struct inpcbinfo *pcbinfo;	struct in_addr faddr, laddr;	u_int fport_arg, lport_arg;	int wild_okay;{	register struct inpcb *inp, *match = NULL;	int matchwild = 3, wildcard;	u_short fport = fport_arg, lport = lport_arg;	int s;	s = splnet();	for (inp = pcbinfo->listhead->lh_first; inp != NULL; inp = inp->inp_list.le_next) {		if (inp->inp_lport != lport)			continue;		wildcard = 0;		if (inp->inp_faddr.s_addr != INADDR_ANY) {			if (faddr.s_addr == INADDR_ANY)				wildcard++;			else if (inp->inp_faddr.s_addr != faddr.s_addr ||			    inp->inp_fport != fport)				continue;		} else {			if (faddr.s_addr != INADDR_ANY)				wildcard++;		}		if (inp->inp_laddr.s_addr != INADDR_ANY) {			if (laddr.s_addr == INADDR_ANY)				wildcard++;			else if (inp->inp_laddr.s_addr != laddr.s_addr)				continue;		} else {			if (laddr.s_addr != INADDR_ANY)				wildcard++;		}		if (wildcard && wild_okay == 0)			continue;		if (wildcard < matchwild) {			match = inp;			matchwild = wildcard;			if (matchwild == 0) {				break;			}		}	}	splx(s);	return (match);}/* * Lookup PCB in hash list. */struct inpcb *in_pcblookuphash(pcbinfo, faddr, fport_arg, laddr, lport_arg, wildcard)	struct inpcbinfo *pcbinfo;	struct in_addr faddr, laddr;	u_int fport_arg, lport_arg;	int wildcard;{	struct inpcbhead *head;	register struct inpcb *inp;	u_short fport = fport_arg, lport = lport_arg;	int s;	s = splnet();	/*	 * First look for an exact match.	 */	head = &pcbinfo->hashbase[INP_PCBHASH(faddr.s_addr, lport, fport, pcbinfo->hashmask)];	for (inp = head->lh_first; inp != NULL; inp = inp->inp_hash.le_next) {		if (inp->inp_faddr.s_addr == faddr.s_addr &&		    inp->inp_fport == fport && inp->inp_lport == lport &&		    inp->inp_laddr.s_addr == laddr.s_addr)			goto found;	}	if (wildcard) {		struct inpcb *local_wild = NULL;		head = &pcbinfo->hashbase[INP_PCBHASH(INADDR_ANY, lport, 0, pcbinfo->hashmask)];		for (inp = head->lh_first; inp != NULL; inp = inp->inp_hash.le_next) {			if (inp->inp_faddr.s_addr == INADDR_ANY &&			    inp->inp_fport == 0 && inp->inp_lport == lport) {				if (inp->inp_laddr.s_addr == laddr.s_addr)					goto found;				else if (inp->inp_laddr.s_addr == INADDR_ANY)					local_wild = inp;			}		}		if (local_wild != NULL) {			inp = local_wild;			goto found;		}	}	splx(s);	return (NULL);found:	/*	 * Move PCB to head of this hash chain so that it can be	 * found more quickly in the future.	 * XXX - this is a pessimization on machines with few	 * concurrent connections.	 */	if (inp != head->lh_first) {		LIST_REMOVE(inp, inp_hash);		LIST_INSERT_HEAD(head, inp, inp_hash);	}	splx(s);	return (inp);}/* * Insert PCB into hash chain. Must be called at splnet. */voidin_pcbinshash(inp)	struct inpcb *inp;{	struct inpcbhead *head;	head = &inp->inp_pcbinfo->hashbase[INP_PCBHASH(inp->inp_faddr.s_addr,		 inp->inp_lport, inp->inp_fport, inp->inp_pcbinfo->hashmask)];	LIST_INSERT_HEAD(head, inp, inp_hash);}voidin_pcbrehash(inp)	struct inpcb *inp;{	struct inpcbhead *head;	int s;	s = splnet();	LIST_REMOVE(inp, inp_hash);	head = &inp->inp_pcbinfo->hashbase[INP_PCBHASH(inp->inp_faddr.s_addr,		inp->inp_lport, inp->inp_fport, inp->inp_pcbinfo->hashmask)];	LIST_INSERT_HEAD(head, inp, inp_hash);	splx(s);}

⌨️ 快捷键说明

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