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

📄 raw_ip.c

📁 VxWorks网络部分的源代码
💻 C
字号:
/* rawip.c - raw interface to IP protocol *//* Copyright 1984-1996 Wind River Systems, Inc. */#include "copyright_wrs.h"/* * Copyright (c) 1982, 1986, 1988, 1993, 1995 *	The Regents of the University of California.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)raw_ip.c	8.7 (Berkeley) 5/15/95 *//*modification history--------------------01g,26aug98,n_s  corrected rip_output for IP_HDRINCL case. spr #2224601f,26aug98,n_s  added return val check for M_PREPEND in rip_output and                 mBufClGet in rip_ctloutput. spr # 22238.01e,16apr97,vin	 added PRU_CONTROL support to rip_usrreq().01d,08apr97,vin  include pcb hashing changes from FREEBSD2.2.1, removed		 ip_mrouter, added mCastRouteCmdHook. removed all MROUTING01c,31jan97,vin  changed declaration according to prototype decl in protosw.h01b,22nov96,vin  added cluster support replaced m_get(..) with mBufClGet(..).01a,03mar96,vin  created from BSD4.4 stuff,integrated with 02i of raw_usrreq.c*//*DESCRIPTION*/#include "vxWorks.h"#include "net/mbuf.h"#include "sys/socket.h"#include "net/protosw.h"#include "net/socketvar.h"#include "errno.h"#include "net/if.h"#include "net/route.h"#include "net/raw_cb.h"#include "netinet/in.h"#include "netinet/in_systm.h"#include "netinet/ip.h"#include "netinet/ip_var.h"#include "netinet/ip_mroute.h"#include "netinet/in_pcb.h"/* externs */extern FUNCPTR _mCastRouteCmdHook;	/* WRS mcast route command hook *//* globals */static struct inpcbhead ripcb;static struct inpcbinfo ripcbinfo;static struct sockaddr_in ripsrc = { sizeof(ripsrc), AF_INET };/* * Nominal space allocated to a raw ip socket. */#define	RIPSNDQ		8192#define	RIPRCVQ		8192/* locals */static int _mCastCtlOutput (int option, int optName, struct socket * sockPtr,                            struct mbuf ** pPtrMbuf); /* * Raw interface to IP protocol. *//* * Initialize raw connection block q. */voidrip_init(){	LIST_INIT(&ripcb);        ripcbinfo.listhead = &ripcb;        /*         * XXX We don't use the hash list for raw IP, but it's easier         * to allocate a one entry hash list than it is to check all         * over the place for hashbase == NULL.         */        ripcbinfo.hashbase = hashinit(1, MT_PCB, &ripcbinfo.hashmask);}/* * Setup generic address and protocol structures * for raw_input routine, then pass them along with * mbuf chain. */voidrip_input(m)	struct mbuf *m;{	register struct ip *ip = mtod(m, struct ip *);	register struct inpcb *inp;	struct socket *last = 0;	ripsrc.sin_addr = ip->ip_src;        for (inp = ripcb.lh_first; inp != NULL; inp = inp->inp_list.le_next) {		if (inp->inp_ip.ip_p && inp->inp_ip.ip_p != ip->ip_p)			continue;		if (inp->inp_laddr.s_addr &&		    inp->inp_laddr.s_addr != ip->ip_dst.s_addr)			continue;		if (inp->inp_faddr.s_addr &&		    inp->inp_faddr.s_addr != ip->ip_src.s_addr)			continue;		if (last) {			struct mbuf *n;			if (n = m_copy(m, 0, (int)M_COPYALL)) {				if (sbappendaddr(&last->so_rcv,				    (struct sockaddr *)&ripsrc, n,				    (struct mbuf *)0) == 0)					/* should notify about lost packet */					m_freem(n);				else					sorwakeup(last);			}		}		last = inp->inp_socket;	}	if (last) {		if (sbappendaddr(&last->so_rcv, (struct sockaddr *)&ripsrc,		    m, (struct mbuf *)0) == 0)			m_freem(m);		else			sorwakeup(last);	} else {		m_freem(m);		ipstat.ips_noproto++;		ipstat.ips_delivered--;	}	return;}/* * Generate IP header and pass packet to ip_output. * Tack on options user may have setup with control call. */intrip_output(m, so, dst)	register struct mbuf *m;	struct socket *so;	u_long dst;{	register struct ip *ip;	register struct inpcb *inp = sotoinpcb(so);	struct mbuf *opts;	int flags = (so->so_options & SO_DONTROUTE) | IP_ALLOWBROADCAST;	/*	 * If the user handed us a complete IP packet, use it.	 * Otherwise, allocate an mbuf for a header and fill it in.	 */	if ((inp->inp_flags & INP_HDRINCL) == 0) {		M_PREPEND(m, sizeof(struct ip), M_WAIT);		if (m == (struct mbuf *) NULL)		    {		    return (ENOBUFS);		    }		    		ip = mtod(m, struct ip *);		ip->ip_tos = 0;		ip->ip_off = 0;		ip->ip_p = inp->inp_ip.ip_p;		ip->ip_len = m->m_pkthdr.len;		ip->ip_src = inp->inp_laddr;		ip->ip_dst.s_addr = dst;	/* Default set to IPDEFTTL but can be Modified by SNMP through MIB-II */		ip->ip_ttl = ipTimeToLive;		opts = inp->inp_options;	} else {	        if (m->m_len < sizeof (struct ip) &&		    (m = m_pullup (m, sizeof (struct ip))) == NULL)		    {		    return (ENOBUFS);		    }		ip = mtod(m, struct ip *);		if (ip->ip_id == 0)			ip->ip_id = htons(ip_id++);		opts = NULL;		/* XXX prevent ip_output from overwriting header fields */		flags |= IP_RAWOUTPUT;		ipstat.ips_rawout++;	}	return (ip_output(m, opts, &inp->inp_route, flags, inp->inp_moptions));}/* * Raw IP socket option processing. */intrip_ctloutput(op, so, level, optname, m)	int op;	struct socket *so;	int level, optname;	struct mbuf **m;{	register struct inpcb *inp = sotoinpcb(so);	register int error;	if (level != IPPROTO_IP) {		if (op == PRCO_SETOPT && *m)			(void) m_free(*m);		return (EINVAL);	}	switch (optname) {	case IP_HDRINCL:		error = 0;		if (op == PRCO_SETOPT) {			if (*m == 0 || (*m)->m_len < sizeof (int))				error = EINVAL;			else if (*mtod(*m, int *))				inp->inp_flags |= INP_HDRINCL;			else				inp->inp_flags &= ~INP_HDRINCL;			if (*m)				(void)m_free(*m);		} else {			*m = mBufClGet(M_WAIT, MT_SOOPTS, CL_SIZE_128, TRUE);			if (*m == (struct mbuf *) NULL)			    {			    error = ENOBUFS;			    }			else			    {			    (*m)->m_len = sizeof (int);			    *mtod(*m, int *) = inp->inp_flags & INP_HDRINCL;			    }		}		return (error);	case DVMRP_INIT:	case DVMRP_DONE:	case DVMRP_ADD_VIF:	case DVMRP_DEL_VIF:	case DVMRP_ADD_LGRP:	case DVMRP_DEL_LGRP:	case DVMRP_ADD_MRT:	case DVMRP_DEL_MRT:            	return (_mCastCtlOutput (op, optname, so, m));	default:		if (optname >= DVMRP_INIT)            		return (_mCastCtlOutput (op, optname, so, m));	}	return (ip_ctloutput(op, so, level, optname, m));}u_long	rip_sendspace = RIPSNDQ;u_long	rip_recvspace = RIPRCVQ;/*ARGSUSED*/intrip_usrreq(so, req, m, nam, control)	register struct socket *so;	int req;	struct mbuf *m, *nam, *control;{	register int error = 0;	register struct inpcb *inp = sotoinpcb(so);        if (req == PRU_CONTROL)            return (in_control(so, (u_long)m, (caddr_t)nam,                    (struct ifnet *)control));	switch (req) {	case PRU_ATTACH:		if (inp)			panic("rip_attach");		if ((so->so_state & SS_PRIV) == 0) {			error = EACCES;			break;		}		if ((error = soreserve(so, rip_sendspace, rip_recvspace)) ||		    (error = in_pcballoc(so, &ripcbinfo)))			break;		inp = (struct inpcb *)so->so_pcb;		inp->inp_ip.ip_p = (int)nam;		break;	case PRU_DISCONNECT:		if ((so->so_state & SS_ISCONNECTED) == 0) {			error = ENOTCONN;			break;		}		/* FALLTHROUGH */	case PRU_ABORT:		soisdisconnected(so);		/* FALLTHROUGH */	case PRU_DETACH:		if (inp == 0)			panic("rip_detach");		in_pcbdetach(inp);		break;	case PRU_BIND:	    {		struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *);		if (nam->m_len != sizeof(*addr)) {			error = EINVAL;			break;		}		if ((ifnet == 0) ||		    ((addr->sin_family != AF_INET) &&		     (addr->sin_family != AF_IMPLINK)) ||		    (addr->sin_addr.s_addr &&		     ifa_ifwithaddr((struct sockaddr *)addr) == 0)) {			error = EADDRNOTAVAIL;			break;		}		inp->inp_laddr = addr->sin_addr;		break;	    }	case PRU_CONNECT:	    {		struct sockaddr_in *addr = mtod(nam, struct sockaddr_in *);		if (nam->m_len != sizeof(*addr)) {			error = EINVAL;			break;		}		if (ifnet == 0) {			error = EADDRNOTAVAIL;			break;		}		if ((addr->sin_family != AF_INET) &&		     (addr->sin_family != AF_IMPLINK)) {			error = EAFNOSUPPORT;			break;		}		inp->inp_faddr = addr->sin_addr;		soisconnected(so);		break;	    }	case PRU_CONNECT2:		error = EOPNOTSUPP;		break;	/*	 * Mark the connection as being incapable of further input.	 */	case PRU_SHUTDOWN:		socantsendmore(so);		break;	/*	 * Ship a packet out.  The appropriate raw output	 * routine handles any massaging necessary.	 */	case PRU_SEND:	    {		register u_long dst;		if (so->so_state & SS_ISCONNECTED) {			if (nam) {				error = EISCONN;				break;			}			dst = inp->inp_faddr.s_addr;		} else {			if (nam == NULL) {				error = ENOTCONN;				break;			}			dst = mtod(nam, struct sockaddr_in *)->sin_addr.s_addr;		}		error = rip_output(m, so, dst);		m = NULL;		break;	    }	case PRU_SENSE:		/*		 * stat: don't bother with a blocksize.		 */		return (0);	/*	 * Not supported.	 */	case PRU_RCVOOB:	case PRU_RCVD:	case PRU_LISTEN:	case PRU_ACCEPT:	case PRU_SENDOOB:		error = EOPNOTSUPP;		break;	case PRU_SOCKADDR:		in_setsockaddr(inp, nam);		break;	case PRU_PEERADDR:		in_setpeeraddr(inp, nam);		break;	default:		panic("rip_usrreq");	}	if (m != NULL)		m_freem(m);	return (error);}/******************************************************************************** mCastCtlOutput - send commands to multicast routing engine.** This function sends commands to multicast routing engine.** INTERNAL* This function can be further expanded to receive multicast options also.* That is the reason for passing a pointer to a pointer to an mbuf as one of* the argument.** RETURNS: OK/ERROR** NOMANUAL*/static int _mCastCtlOutput    (    int 		option,		/* type of option */    int 		optName,	/* name of the option */    struct socket * 	sockPtr,	/* pointer to the socket */    struct mbuf **	pPtrMbuf	/* pointer to pointer to an mbuf */    )    {    register int error = EINVAL;	/* default error value */    if (pPtrMbuf == NULL)        return (error);        if (option == PRCO_SETOPT)        {        if (_mCastRouteCmdHook != NULL)            error = (*_mCastRouteCmdHook)(optName, sockPtr, *pPtrMbuf);        else            error = EOPNOTSUPP;         }    if (*pPtrMbuf != NULL)        (void) m_free (*pPtrMbuf);    return (error);    }

⌨️ 快捷键说明

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