mirror of
https://git.FreeBSD.org/src.git
synced 2024-10-19 02:29:40 +00:00
/home/brooks/ng_gif.message
This commit is contained in:
parent
20af0ffaa1
commit
94408d94c3
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=83998
@ -90,6 +90,7 @@ MAN= aac.4 \
|
||||
ng_echo.4 \
|
||||
ng_ether.4 \
|
||||
ng_frame_relay.4 \
|
||||
ng_gif.4 \
|
||||
ng_hole.4 \
|
||||
ng_iface.4 \
|
||||
ng_ksocket.4 \
|
||||
|
129
share/man/man4/ng_gif.4
Normal file
129
share/man/man4/ng_gif.4
Normal file
@ -0,0 +1,129 @@
|
||||
.\" Copyright 2000 The Aerospace Corporation. 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. The name of The Aerospace Corporation may not be used to endorse or
|
||||
.\" promote products derived from this software.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION "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 AEROSPACE CORPORATION 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.
|
||||
.\"
|
||||
.\" Author: Brooks Davis <brooks@FreeBSD.org>
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd September 18, 2001
|
||||
.Dt NG_GIF 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm ng_gif
|
||||
.Nd Generic tunnel interface netgraph node type
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <netgraph/ng_gif.h>
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
netgraph node type allows
|
||||
.Xr gif 4
|
||||
interfaces to interact with
|
||||
the
|
||||
.Xr netgraph 4
|
||||
networking subsystem.
|
||||
Once the
|
||||
.Nm
|
||||
module is loaded in the kernel, a node is automatically created
|
||||
for each
|
||||
.Xr gif 4
|
||||
interface in the system.
|
||||
Each node will attempt to name itself with the same name
|
||||
as the associated interface.
|
||||
All
|
||||
.Nm
|
||||
nodes are persistent for as long as the interface itself exists.
|
||||
.Pp
|
||||
Two hooks are supported:
|
||||
.Dv lower
|
||||
and
|
||||
.Dv orphans .
|
||||
The hook name
|
||||
.Dv divert
|
||||
may be used as an alias for
|
||||
.Dv lower ,
|
||||
and is provided for compatibility with
|
||||
.Xr ng_ether 4 .
|
||||
In reality the two names represent the same hook.
|
||||
.Pp
|
||||
The
|
||||
.Dv lower
|
||||
hook is a connection to the raw
|
||||
.Xr gif 4
|
||||
device.
|
||||
When connected, all incoming packets are diverted out this hook.
|
||||
Writing to this hook results in a raw encapsulated packet being transmitted
|
||||
by the device.
|
||||
Normal outgoing packets are not affected by
|
||||
.Dv lower
|
||||
being connected.
|
||||
.Pp
|
||||
The
|
||||
.Dv orphans
|
||||
hook is equivalent to
|
||||
.Dv lower ,
|
||||
except that only unrecognized packets (that would otherwise be discarded)
|
||||
are written to the hook, and normal incoming traffic is unaffected.
|
||||
At most one of
|
||||
.Dv orphans
|
||||
and
|
||||
.Dv lower
|
||||
may be connected at any time.
|
||||
.Pp
|
||||
In all cases, frames are raw packets with the address family of the
|
||||
packet attached to the front.
|
||||
.Pp
|
||||
When no hooks are connected, packets flow normally upwards and downwards.
|
||||
.Sh HOOKS
|
||||
This node type supports the following hooks:
|
||||
.Pp
|
||||
.Bl -tag -width orphans
|
||||
.It Dv lower
|
||||
Connection to the lower device link layer.
|
||||
.It Dv orphans
|
||||
Like
|
||||
.Dv lower ,
|
||||
but only receives unrecognized packets.
|
||||
.El
|
||||
.Sh CONTROL MESSAGES
|
||||
This node type supports only the generic control messages generic
|
||||
control messages.
|
||||
.Sh EXAMPLES
|
||||
This command dumps all unrecognized packets received by the
|
||||
.Dv gif0
|
||||
interface to standard output decoded in hex and ASCII:
|
||||
.Bd -literal -offset indent
|
||||
nghook -a gif0: orphans
|
||||
.Ed
|
||||
.Sh SEE ALSO
|
||||
.Xr gif 4 ,
|
||||
.Xr netgraph 4 ,
|
||||
.Xr netintro 4 ,
|
||||
.Xr ifconfig 8 ,
|
||||
.Xr ngctl 8 ,
|
||||
.Xr nghook 8
|
||||
.Sh AUTHORS
|
||||
.An Brooks Davis Aq brooks@FreeBSD.org
|
114
share/man/man4/ng_gif_demux.4
Normal file
114
share/man/man4/ng_gif_demux.4
Normal file
@ -0,0 +1,114 @@
|
||||
.\" Copyright 2000 The Aerospace Corporation. 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. The name of The Aerospace Corporation may not be used to endorse or
|
||||
.\" promote products derived from this software.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION "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 AEROSPACE CORPORATION 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.
|
||||
.\"
|
||||
.\" Author: Brooks Davis <brooks@FreeBSD.org>
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd September 18, 2001
|
||||
.Dt NG_GIF_DEMUX 4
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm ng_gif_demux
|
||||
.Nd Demultiplexr for packets from
|
||||
.Xr ng_gif 4
|
||||
nodes
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <netgraph/ng_gif_demux.h>
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
netgraph node type demultiplexes the output from
|
||||
.Xr ng_gif 4
|
||||
nodes in the
|
||||
.Xr netgraph 4
|
||||
networking subsystem.
|
||||
.Pp
|
||||
The
|
||||
.Dv gif
|
||||
hook is ment to be connected to the
|
||||
.Dv lower
|
||||
or
|
||||
.Dv orphans
|
||||
hook of an
|
||||
.Xr ng_gif 4
|
||||
node.
|
||||
The
|
||||
.Dv inet ,
|
||||
.Dv inet6 ,
|
||||
.Dv atalk ,
|
||||
.Dv ipx ,
|
||||
.Dv atm ,
|
||||
.Dv natm ,
|
||||
and
|
||||
.Dv ns
|
||||
hooks output frames of the given type when they are recieved on the
|
||||
.Dv gif
|
||||
hook.
|
||||
When a frame is recived on one of these hooks, it is encapsulated and
|
||||
sent out the
|
||||
.Dv gif
|
||||
hook.
|
||||
.Sh HOOKS
|
||||
This node type supports the following hooks:
|
||||
.Pp
|
||||
.Bl -tag -width inet6
|
||||
.It Dv gif
|
||||
Connection to the
|
||||
.Dv lower
|
||||
or
|
||||
.Dv orphans
|
||||
hook of an
|
||||
.Xr ng_gif 4
|
||||
node.
|
||||
.It Dv inet
|
||||
Hook for input and output of IP frames.
|
||||
.It Dv inet6
|
||||
Hook for input and output of IPv6 frames.
|
||||
.It Dv atalk
|
||||
Hook for input and output of AppleTalk frames.
|
||||
.It Dv ipx
|
||||
Hook for input and output of IPX frames.
|
||||
.It Dv atm
|
||||
Hook for input and output of ATM frames.
|
||||
.It Dv natm
|
||||
Hook for input and output of NATM frames.
|
||||
.It Dv ns
|
||||
Hook for input and output of NS frames.
|
||||
.El
|
||||
.Sh CONTROL MESSAGES
|
||||
This node type supports only the generic control messages generic
|
||||
control messages.
|
||||
.Sh SEE ALSO
|
||||
.Xr gif 4 ,
|
||||
.Xr netgraph 4 ,
|
||||
.Xr netintro 4 ,
|
||||
.Xr ng_gif 4 ,
|
||||
.Xr ifconfig 8 ,
|
||||
.Xr ngctl 8 ,
|
||||
.Xr nghook 8
|
||||
.Sh AUTHORS
|
||||
.An Brooks Davis Aq brooks@FreeBSD.org
|
@ -1029,6 +1029,8 @@ netgraph/ng_cisco.c optional netgraph_cisco
|
||||
netgraph/ng_echo.c optional netgraph_echo
|
||||
netgraph/ng_ether.c optional netgraph_ether
|
||||
netgraph/ng_frame_relay.c optional netgraph_frame_relay
|
||||
netgraph/ng_gif.c optional netgraph_gif
|
||||
netgraph/ng_gif_demux.c optional netgraph_gif_demux
|
||||
netgraph/ng_hole.c optional netgraph_hole
|
||||
netgraph/ng_iface.c optional netgraph_iface
|
||||
netgraph/ng_ksocket.c optional netgraph_ksocket
|
||||
|
@ -311,6 +311,8 @@ NETGRAPH_CISCO opt_netgraph.h
|
||||
NETGRAPH_ECHO opt_netgraph.h
|
||||
NETGRAPH_ETHER opt_netgraph.h
|
||||
NETGRAPH_FRAME_RELAY opt_netgraph.h
|
||||
NETGRAPH_GIF opt_netgraph.h
|
||||
NETGRAPH_GIF_DEMUX opt_netgraph.h
|
||||
NETGRAPH_HOLE opt_netgraph.h
|
||||
NETGRAPH_IFACE opt_netgraph.h
|
||||
NETGRAPH_KSOCKET opt_netgraph.h
|
||||
|
@ -9,6 +9,8 @@ SUBDIR= async \
|
||||
eiface \
|
||||
ether \
|
||||
frame_relay \
|
||||
gif \
|
||||
gif_demux \
|
||||
hole \
|
||||
iface \
|
||||
ksocket \
|
||||
|
12
sys/modules/netgraph/gif/Makefile
Normal file
12
sys/modules/netgraph/gif/Makefile
Normal file
@ -0,0 +1,12 @@
|
||||
# $FreeBSD$
|
||||
|
||||
KMOD= ng_gif
|
||||
SRCS= ng_gif.c opt_inet.h opt_inet6.h
|
||||
|
||||
opt_inet.h:
|
||||
echo "#define INET 1" > ${.TARGET}
|
||||
|
||||
opt_inet6.h:
|
||||
echo "#define INET6 1" > ${.TARGET}
|
||||
|
||||
.include <bsd.kmod.mk>
|
6
sys/modules/netgraph/gif_demux/Makefile
Normal file
6
sys/modules/netgraph/gif_demux/Makefile
Normal file
@ -0,0 +1,6 @@
|
||||
# $FreeBSD$
|
||||
|
||||
KMOD= ng_gif_demux
|
||||
SRCS= ng_gif_demux.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
@ -87,6 +87,11 @@ static MALLOC_DEFINE(M_GIF, "gif", "Generic Tunnel Interface");
|
||||
static struct rman gifunits[1];
|
||||
LIST_HEAD(, gif_softc) gif_softc_list;
|
||||
|
||||
void (*ng_gif_input_p)(struct ifnet *ifp, struct mbuf **mp, int af);
|
||||
void (*ng_gif_input_orphan_p)(struct ifnet *ifp, struct mbuf *m, int af);
|
||||
void (*ng_gif_attach_p)(struct ifnet *ifp);
|
||||
void (*ng_gif_detach_p)(struct ifnet *ifp);
|
||||
|
||||
int gif_clone_create __P((struct if_clone *, int *));
|
||||
void gif_clone_destroy __P((struct ifnet *));
|
||||
|
||||
@ -199,6 +204,8 @@ gif_clone_create(ifc, unit)
|
||||
sc->gif_if.if_snd.ifq_maxlen = IFQ_MAXLEN;
|
||||
if_attach(&sc->gif_if);
|
||||
bpfattach(&sc->gif_if, DLT_NULL, sizeof(u_int));
|
||||
if (ng_gif_attach_p != NULL)
|
||||
(*ng_gif_attach_p)(&sc->gif_if);
|
||||
LIST_INSERT_HEAD(&gif_softc_list, sc, gif_link);
|
||||
return (0);
|
||||
}
|
||||
@ -221,6 +228,8 @@ gif_clone_destroy(ifp)
|
||||
KASSERT(err == 0, ("Unexpected error detaching encap_cookie6"));
|
||||
}
|
||||
|
||||
if (ng_gif_detach_p != NULL)
|
||||
(*ng_gif_detach_p)(ifp);
|
||||
bpfdetach(ifp);
|
||||
if_detach(ifp);
|
||||
|
||||
@ -462,6 +471,12 @@ gif_input(m, af, gifp)
|
||||
bpf_mtap(gifp, &m0);
|
||||
}
|
||||
|
||||
if (ng_gif_input_p != NULL) {
|
||||
(*ng_gif_input_p)(gifp, &m, af);
|
||||
if (m == NULL)
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Put the packet to the network layer input queue according to the
|
||||
* specified address family.
|
||||
@ -488,7 +503,10 @@ gif_input(m, af, gifp)
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
m_freem(m);
|
||||
if (ng_gif_input_orphan_p != NULL)
|
||||
(*ng_gif_input_orphan_p)(gifp, m, af);
|
||||
else
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,14 @@
|
||||
|
||||
struct encaptab;
|
||||
|
||||
extern void (*ng_gif_input_p)(struct ifnet *ifp, struct mbuf **mp,
|
||||
int af);
|
||||
extern void (*ng_gif_input_orphan_p)(struct ifnet *ifp, struct mbuf *m,
|
||||
int af);
|
||||
extern int (*ng_gif_output_p)(struct ifnet *ifp, struct mbuf **mp);
|
||||
extern void (*ng_gif_attach_p)(struct ifnet *ifp);
|
||||
extern void (*ng_gif_detach_p)(struct ifnet *ifp);
|
||||
|
||||
struct gif_softc {
|
||||
struct ifnet gif_if; /* common area - must be at the top */
|
||||
struct sockaddr *gif_psrc; /* Physical src addr */
|
||||
@ -61,6 +69,7 @@ struct gif_softc {
|
||||
const struct encaptab *encap_cookie4;
|
||||
const struct encaptab *encap_cookie6;
|
||||
struct resource *r_unit; /* resource allocated for this unit */
|
||||
void *gif_netgraph; /* ng_gif(4) netgraph node info */
|
||||
LIST_ENTRY(gif_softc) gif_link; /* all gif's are linked */
|
||||
};
|
||||
|
||||
|
596
sys/netgraph/ng_gif.c
Normal file
596
sys/netgraph/ng_gif.c
Normal file
@ -0,0 +1,596 @@
|
||||
/*
|
||||
* ng_gif.c
|
||||
*
|
||||
* Copyright 2001 The Aerospace Corporation. 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION ``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 AEROSPACE CORPORATION 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.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1996-2000 Whistle Communications, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Subject to the following obligations and disclaimer of warranty, use and
|
||||
* redistribution of this software, in source or object code forms, with or
|
||||
* without modifications are expressly permitted by Whistle Communications;
|
||||
* provided, however, that:
|
||||
* 1. Any and all reproductions of the source or object code must include the
|
||||
* copyright notice above and the following disclaimer of warranties; and
|
||||
* 2. No rights are granted, in any manner or form, to use Whistle
|
||||
* Communications, Inc. trademarks, including the mark "WHISTLE
|
||||
* COMMUNICATIONS" on advertising, endorsements, or otherwise except as
|
||||
* such appears in the above copyright notice or in the software.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
|
||||
* TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
|
||||
* REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
|
||||
* WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
|
||||
* REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
|
||||
* SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
|
||||
* IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
|
||||
* RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
|
||||
* WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* ng_gif(4) netgraph node type
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/if_var.h>
|
||||
#include <net/if_gif.h>
|
||||
|
||||
#include <netgraph/ng_message.h>
|
||||
#include <netgraph/netgraph.h>
|
||||
#include <netgraph/ng_parse.h>
|
||||
#include <netgraph/ng_gif.h>
|
||||
|
||||
#define IFP2NG(ifp) ((struct ng_node *)((struct gif_softc *)(ifp))->gif_netgraph)
|
||||
|
||||
/* Per-node private data */
|
||||
struct private {
|
||||
struct ifnet *ifp; /* associated interface */
|
||||
hook_p lower; /* lower OR orphan hook connection */
|
||||
u_char lowerOrphan; /* whether lower is lower or orphan */
|
||||
};
|
||||
typedef struct private *priv_p;
|
||||
|
||||
/* Functional hooks called from if_gif.c */
|
||||
static void ng_gif_input(struct ifnet *ifp, struct mbuf **mp, int af);
|
||||
static void ng_gif_input_orphan(struct ifnet *ifp, struct mbuf *m, int af);
|
||||
static void ng_gif_attach(struct ifnet *ifp);
|
||||
static void ng_gif_detach(struct ifnet *ifp);
|
||||
|
||||
/* Other functions */
|
||||
static void ng_gif_input2(node_p node, struct mbuf **mp, int af);
|
||||
static int ng_gif_glue_af(struct mbuf **mp, int af);
|
||||
static int ng_gif_rcv_lower(node_p node, struct mbuf *m, meta_p meta);
|
||||
|
||||
/* Netgraph node methods */
|
||||
static ng_constructor_t ng_gif_constructor;
|
||||
static ng_rcvmsg_t ng_gif_rcvmsg;
|
||||
static ng_shutdown_t ng_gif_shutdown;
|
||||
static ng_newhook_t ng_gif_newhook;
|
||||
static ng_connect_t ng_gif_connect;
|
||||
static ng_rcvdata_t ng_gif_rcvdata;
|
||||
static ng_disconnect_t ng_gif_disconnect;
|
||||
static int ng_gif_mod_event(module_t mod, int event, void *data);
|
||||
|
||||
/* List of commands and how to convert arguments to/from ASCII */
|
||||
static const struct ng_cmdlist ng_gif_cmdlist[] = {
|
||||
{
|
||||
NGM_GIF_COOKIE,
|
||||
NGM_GIF_GET_IFNAME,
|
||||
"getifname",
|
||||
NULL,
|
||||
&ng_parse_string_type
|
||||
},
|
||||
{
|
||||
NGM_GIF_COOKIE,
|
||||
NGM_GIF_GET_IFINDEX,
|
||||
"getifindex",
|
||||
NULL,
|
||||
&ng_parse_int32_type
|
||||
},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static struct ng_type ng_gif_typestruct = {
|
||||
NG_ABI_VERSION,
|
||||
NG_GIF_NODE_TYPE,
|
||||
ng_gif_mod_event,
|
||||
ng_gif_constructor,
|
||||
ng_gif_rcvmsg,
|
||||
ng_gif_shutdown,
|
||||
ng_gif_newhook,
|
||||
NULL,
|
||||
ng_gif_connect,
|
||||
ng_gif_rcvdata,
|
||||
ng_gif_disconnect,
|
||||
ng_gif_cmdlist,
|
||||
};
|
||||
MODULE_VERSION(ng_gif, 1);
|
||||
MODULE_DEPEND(ng_gif, if_gif, 1,1,1);
|
||||
NETGRAPH_INIT(gif, &ng_gif_typestruct);
|
||||
|
||||
/******************************************************************
|
||||
GIF FUNCTION HOOKS
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* Handle a packet that has come in on an interface. We get to
|
||||
* look at it here before any upper layer protocols do.
|
||||
*
|
||||
* NOTE: this function will get called at splimp()
|
||||
*/
|
||||
static void
|
||||
ng_gif_input(struct ifnet *ifp, struct mbuf **mp, int af)
|
||||
{
|
||||
const node_p node = IFP2NG(ifp);
|
||||
const priv_p priv = NG_NODE_PRIVATE(node);
|
||||
|
||||
/* If "lower" hook not connected, let packet continue */
|
||||
if (priv->lower == NULL || priv->lowerOrphan)
|
||||
return;
|
||||
ng_gif_input2(node, mp, af);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle a packet that has come in on an interface, and which
|
||||
* does not match any of our known protocols (an ``orphan'').
|
||||
*
|
||||
* NOTE: this function will get called at splimp()
|
||||
*/
|
||||
static void
|
||||
ng_gif_input_orphan(struct ifnet *ifp, struct mbuf *m, int af)
|
||||
{
|
||||
const node_p node = IFP2NG(ifp);
|
||||
const priv_p priv = NG_NODE_PRIVATE(node);
|
||||
|
||||
/* If "orphan" hook not connected, let packet continue */
|
||||
if (priv->lower == NULL || !priv->lowerOrphan) {
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
ng_gif_input2(node, &m, af);
|
||||
if (m != NULL)
|
||||
m_freem(m);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle a packet that has come in on a gif interface.
|
||||
* Attach the address family to the mbuf for later use.
|
||||
*
|
||||
* NOTE: this function will get called at splimp()
|
||||
*/
|
||||
static void
|
||||
ng_gif_input2(node_p node, struct mbuf **mp, int af)
|
||||
{
|
||||
const priv_p priv = NG_NODE_PRIVATE(node);
|
||||
int error;
|
||||
|
||||
/* Glue address family on */
|
||||
if ((error = ng_gif_glue_af(mp, af)) != 0)
|
||||
return;
|
||||
|
||||
/* Send out lower/orphan hook */
|
||||
NG_SEND_DATA_ONLY(error, priv->lower, *mp);
|
||||
*mp = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* A new gif interface has been attached.
|
||||
* Create a new node for it, etc.
|
||||
*/
|
||||
static void
|
||||
ng_gif_attach(struct ifnet *ifp)
|
||||
{
|
||||
char name[IFNAMSIZ + 1];
|
||||
priv_p priv;
|
||||
node_p node;
|
||||
|
||||
/* Create node */
|
||||
KASSERT(!IFP2NG(ifp), ("%s: node already exists?", __FUNCTION__));
|
||||
snprintf(name, sizeof(name), "%s%d", ifp->if_name, ifp->if_unit);
|
||||
if (ng_make_node_common(&ng_gif_typestruct, &node) != 0) {
|
||||
log(LOG_ERR, "%s: can't %s for %s\n",
|
||||
__FUNCTION__, "create node", name);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Allocate private data */
|
||||
MALLOC(priv, priv_p, sizeof(*priv), M_NETGRAPH, M_NOWAIT | M_ZERO);
|
||||
if (priv == NULL) {
|
||||
log(LOG_ERR, "%s: can't %s for %s\n",
|
||||
__FUNCTION__, "allocate memory", name);
|
||||
NG_NODE_UNREF(node);
|
||||
return;
|
||||
}
|
||||
NG_NODE_SET_PRIVATE(node, priv);
|
||||
priv->ifp = ifp;
|
||||
IFP2NG(ifp) = node;
|
||||
|
||||
/* Try to give the node the same name as the interface */
|
||||
if (ng_name_node(node, name) != 0) {
|
||||
log(LOG_WARNING, "%s: can't name node %s\n",
|
||||
__FUNCTION__, name);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* An Ethernet interface is being detached.
|
||||
* REALLY Destroy its node.
|
||||
*/
|
||||
static void
|
||||
ng_gif_detach(struct ifnet *ifp)
|
||||
{
|
||||
const node_p node = IFP2NG(ifp);
|
||||
const priv_p priv = NG_NODE_PRIVATE(node);
|
||||
|
||||
if (node == NULL) /* no node (why not?), ignore */
|
||||
return;
|
||||
NG_NODE_REALLY_DIE(node); /* Force real removal of node */
|
||||
/*
|
||||
* We can't assume the ifnet is still around when we run shutdown
|
||||
* So zap it now. XXX We HOPE that anything running at this time
|
||||
* handles it (as it should in the non netgraph case).
|
||||
*/
|
||||
IFP2NG(ifp) = NULL;
|
||||
priv->ifp = NULL; /* XXX race if interrupted an output packet */
|
||||
ng_rmnode_self(node); /* remove all netgraph parts */
|
||||
}
|
||||
|
||||
/*
|
||||
* Optimization for gluing the Ethernet header back onto
|
||||
* the front of an incoming packet.
|
||||
*/
|
||||
static int
|
||||
ng_gif_glue_af(struct mbuf **mp, int af)
|
||||
{
|
||||
struct mbuf *m = *mp;
|
||||
int error = 0;
|
||||
sa_family_t tmp_af;
|
||||
|
||||
tmp_af = (sa_family_t) af;
|
||||
|
||||
/*
|
||||
* XXX: should try to bring back some of the optimizations from
|
||||
* ng_ether.c
|
||||
*/
|
||||
|
||||
/*
|
||||
* Doing anything more is likely to get more
|
||||
* expensive than it's worth..
|
||||
* it's probable that everything else is in one
|
||||
* big lump. The next node will do an m_pullup()
|
||||
* for exactly the amount of data it needs and
|
||||
* hopefully everything after that will not
|
||||
* need one. So let's just use M_PREPEND.
|
||||
*/
|
||||
M_PREPEND(m, sizeof (tmp_af), M_DONTWAIT);
|
||||
if (m == NULL) {
|
||||
error = ENOBUFS;
|
||||
goto done;
|
||||
}
|
||||
|
||||
#if 0
|
||||
copy:
|
||||
#endif
|
||||
/* Copy header and return (possibly new) mbuf */
|
||||
*mtod(m, sa_family_t *) = tmp_af;
|
||||
#if 0
|
||||
bcopy((caddr_t)&tmp_af, mtod(m, sa_family_t *), sizeof(tmp_af));
|
||||
#endif
|
||||
done:
|
||||
*mp = m;
|
||||
return error;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
NETGRAPH NODE METHODS
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* It is not possible or allowable to create a node of this type.
|
||||
* Nodes get created when the interface is attached (or, when
|
||||
* this node type's KLD is loaded).
|
||||
*/
|
||||
static int
|
||||
ng_gif_constructor(node_p node)
|
||||
{
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for attaching a new hook.
|
||||
*/
|
||||
static int
|
||||
ng_gif_newhook(node_p node, hook_p hook, const char *name)
|
||||
{
|
||||
const priv_p priv = NG_NODE_PRIVATE(node);
|
||||
u_char orphan = priv->lowerOrphan;
|
||||
hook_p *hookptr;
|
||||
|
||||
/* Divert hook is an alias for lower */
|
||||
if (strcmp(name, NG_GIF_HOOK_DIVERT) == 0)
|
||||
name = NG_GIF_HOOK_LOWER;
|
||||
|
||||
/* Which hook? */
|
||||
if (strcmp(name, NG_GIF_HOOK_LOWER) == 0) {
|
||||
hookptr = &priv->lower;
|
||||
orphan = 0;
|
||||
} else if (strcmp(name, NG_GIF_HOOK_ORPHAN) == 0) {
|
||||
hookptr = &priv->lower;
|
||||
orphan = 1;
|
||||
} else
|
||||
return (EINVAL);
|
||||
|
||||
/* Check if already connected (shouldn't be, but doesn't hurt) */
|
||||
if (*hookptr != NULL)
|
||||
return (EISCONN);
|
||||
|
||||
/* OK */
|
||||
*hookptr = hook;
|
||||
priv->lowerOrphan = orphan;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hooks are attached, adjust to force queueing.
|
||||
* We don't really care which hook it is.
|
||||
* they should all be queuing for outgoing data.
|
||||
*/
|
||||
static int
|
||||
ng_gif_connect(hook_p hook)
|
||||
{
|
||||
NG_HOOK_FORCE_QUEUE(NG_HOOK_PEER(hook));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive an incoming control message.
|
||||
*/
|
||||
static int
|
||||
ng_gif_rcvmsg(node_p node, item_p item, hook_p lasthook)
|
||||
{
|
||||
const priv_p priv = NG_NODE_PRIVATE(node);
|
||||
struct ng_mesg *resp = NULL;
|
||||
int error = 0;
|
||||
struct ng_mesg *msg;
|
||||
|
||||
NGI_GET_MSG(item, msg);
|
||||
switch (msg->header.typecookie) {
|
||||
case NGM_GIF_COOKIE:
|
||||
switch (msg->header.cmd) {
|
||||
case NGM_GIF_GET_IFNAME:
|
||||
NG_MKRESPONSE(resp, msg, IFNAMSIZ + 1, M_NOWAIT);
|
||||
if (resp == NULL) {
|
||||
error = ENOMEM;
|
||||
break;
|
||||
}
|
||||
snprintf(resp->data, IFNAMSIZ + 1,
|
||||
"%s%d", priv->ifp->if_name, priv->ifp->if_unit);
|
||||
break;
|
||||
case NGM_GIF_GET_IFINDEX:
|
||||
NG_MKRESPONSE(resp, msg, sizeof(u_int32_t), M_NOWAIT);
|
||||
if (resp == NULL) {
|
||||
error = ENOMEM;
|
||||
break;
|
||||
}
|
||||
*((u_int32_t *)resp->data) = priv->ifp->if_index;
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
NG_RESPOND_MSG(error, node, item, resp);
|
||||
NG_FREE_MSG(msg);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive data on a hook.
|
||||
*/
|
||||
static int
|
||||
ng_gif_rcvdata(hook_p hook, item_p item)
|
||||
{
|
||||
const node_p node = NG_HOOK_NODE(hook);
|
||||
const priv_p priv = NG_NODE_PRIVATE(node);
|
||||
struct mbuf *m;
|
||||
meta_p meta;
|
||||
|
||||
NGI_GET_M(item, m);
|
||||
NGI_GET_META(item, meta);
|
||||
NG_FREE_ITEM(item);
|
||||
if (hook == priv->lower)
|
||||
return ng_gif_rcv_lower(node, m, meta);
|
||||
panic("%s: weird hook", __FUNCTION__);
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle an mbuf received on the "lower" hook.
|
||||
*/
|
||||
static int
|
||||
ng_gif_rcv_lower(node_p node, struct mbuf *m, meta_p meta)
|
||||
{
|
||||
struct sockaddr dst;
|
||||
const priv_p priv = NG_NODE_PRIVATE(node);
|
||||
|
||||
bzero(&dst, sizeof(dst));
|
||||
|
||||
/* We don't process metadata. */
|
||||
NG_FREE_META(meta);
|
||||
|
||||
/* Make sure header is fully pulled up */
|
||||
if (m->m_pkthdr.len < sizeof(sa_family_t)) {
|
||||
NG_FREE_M(m);
|
||||
return (EINVAL);
|
||||
}
|
||||
if (m->m_len < sizeof(sa_family_t)
|
||||
&& (m = m_pullup(m, sizeof(sa_family_t))) == NULL) {
|
||||
return (ENOBUFS);
|
||||
}
|
||||
|
||||
dst.sa_family = *mtod(m, sa_family_t *);
|
||||
m_adj(m, sizeof(sa_family_t));
|
||||
|
||||
/* Send it on its way */
|
||||
/*
|
||||
* XXX: gif_output only uses dst for the family and passes the
|
||||
* fourth argument (rt) to in{,6}_gif_output which ignore it.
|
||||
* If this changes ng_gif will probably break.
|
||||
*/
|
||||
return gif_output(priv->ifp, m, &dst, NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Shutdown node. This resets the node but does not remove it
|
||||
* unless the REALLY_DIE flag is set.
|
||||
*/
|
||||
static int
|
||||
ng_gif_shutdown(node_p node)
|
||||
{
|
||||
const priv_p priv = NG_NODE_PRIVATE(node);
|
||||
|
||||
if (node->nd_flags & NG_REALLY_DIE) {
|
||||
/*
|
||||
* WE came here because the gif interface is being destroyed,
|
||||
* so stop being persistant.
|
||||
* Actually undo all the things we did on creation.
|
||||
* Assume the ifp has already been freed.
|
||||
*/
|
||||
NG_NODE_SET_PRIVATE(node, NULL);
|
||||
FREE(priv, M_NETGRAPH);
|
||||
NG_NODE_UNREF(node); /* free node itself */
|
||||
return (0);
|
||||
}
|
||||
node->nd_flags &= ~NG_INVALID; /* Signal ng_rmnode we are persisant */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hook disconnection.
|
||||
*/
|
||||
static int
|
||||
ng_gif_disconnect(hook_p hook)
|
||||
{
|
||||
const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
|
||||
|
||||
if (hook == priv->lower) {
|
||||
priv->lower = NULL;
|
||||
priv->lowerOrphan = 0;
|
||||
} else
|
||||
panic("%s: weird hook", __FUNCTION__);
|
||||
if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0)
|
||||
&& (NG_NODE_IS_VALID(NG_HOOK_NODE(hook))))
|
||||
ng_rmnode_self(NG_HOOK_NODE(hook)); /* reset node */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
INITIALIZATION
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* Handle loading and unloading for this node type.
|
||||
*/
|
||||
static int
|
||||
ng_gif_mod_event(module_t mod, int event, void *data)
|
||||
{
|
||||
struct ifnet *ifp;
|
||||
int error = 0;
|
||||
int s;
|
||||
|
||||
s = splnet();
|
||||
switch (event) {
|
||||
case MOD_LOAD:
|
||||
|
||||
/* Register function hooks */
|
||||
if (ng_gif_attach_p != NULL) {
|
||||
error = EEXIST;
|
||||
break;
|
||||
}
|
||||
ng_gif_attach_p = ng_gif_attach;
|
||||
ng_gif_detach_p = ng_gif_detach;
|
||||
ng_gif_input_p = ng_gif_input;
|
||||
ng_gif_input_orphan_p = ng_gif_input_orphan;
|
||||
|
||||
/* Create nodes for any already-existing gif interfaces */
|
||||
TAILQ_FOREACH(ifp, &ifnet, if_link) {
|
||||
if (ifp->if_type == IFT_GIF)
|
||||
ng_gif_attach(ifp);
|
||||
}
|
||||
break;
|
||||
|
||||
case MOD_UNLOAD:
|
||||
|
||||
/*
|
||||
* Note that the base code won't try to unload us until
|
||||
* all nodes have been removed, and that can't happen
|
||||
* until all gif interfaces are destroyed. In any
|
||||
* case, we know there are no nodes left if the action
|
||||
* is MOD_UNLOAD, so there's no need to detach any nodes.
|
||||
*
|
||||
* XXX: what about manual unloads?!?
|
||||
*/
|
||||
|
||||
/* Unregister function hooks */
|
||||
ng_gif_attach_p = NULL;
|
||||
ng_gif_detach_p = NULL;
|
||||
ng_gif_input_p = NULL;
|
||||
ng_gif_input_orphan_p = NULL;
|
||||
break;
|
||||
|
||||
default:
|
||||
error = EOPNOTSUPP;
|
||||
break;
|
||||
}
|
||||
splx(s);
|
||||
return (error);
|
||||
}
|
||||
|
81
sys/netgraph/ng_gif.h
Normal file
81
sys/netgraph/ng_gif.h
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* ng_gif.h
|
||||
*
|
||||
* Copyright 2001 The Aerospace Corporation. 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION ``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 AEROSPACE CORPORATION 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.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1996-1999 Whistle Communications, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Subject to the following obligations and disclaimer of warranty, use and
|
||||
* redistribution of this software, in source or object code forms, with or
|
||||
* without modifications are expressly permitted by Whistle Communications;
|
||||
* provided, however, that:
|
||||
* 1. Any and all reproductions of the source or object code must include the
|
||||
* copyright notice above and the following disclaimer of warranties; and
|
||||
* 2. No rights are granted, in any manner or form, to use Whistle
|
||||
* Communications, Inc. trademarks, including the mark "WHISTLE
|
||||
* COMMUNICATIONS" on advertising, endorsements, or otherwise except as
|
||||
* such appears in the above copyright notice or in the software.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
|
||||
* TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
|
||||
* REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
|
||||
* WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
|
||||
* REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
|
||||
* SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
|
||||
* IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
|
||||
* RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
|
||||
* WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NETGRAPH_NG_GIF_H_
|
||||
#define _NETGRAPH_NG_GIF_H_
|
||||
|
||||
/* Node type name and magic cookie */
|
||||
#define NG_GIF_NODE_TYPE "gif"
|
||||
#define NGM_GIF_COOKIE 994115727
|
||||
|
||||
/* Hook names */
|
||||
#define NG_GIF_HOOK_LOWER "lower" /* connection to raw device */
|
||||
#define NG_GIF_HOOK_DIVERT "divert" /* alias for lower */
|
||||
#define NG_GIF_HOOK_ORPHAN "orphans" /* like lower, unknowns only */
|
||||
|
||||
/* Netgraph control messages */
|
||||
enum {
|
||||
NGM_GIF_GET_IFNAME = 1, /* get the interface name */
|
||||
NGM_GIF_GET_IFINDEX, /* get the interface global index # */
|
||||
};
|
||||
|
||||
#endif /* _NETGRAPH_NG_GIF_H_ */
|
398
sys/netgraph/ng_gif_demux.c
Normal file
398
sys/netgraph/ng_gif_demux.c
Normal file
@ -0,0 +1,398 @@
|
||||
/*
|
||||
* ng_gif_demux.c
|
||||
*
|
||||
* Copyright 2001 The Aerospace Corporation. 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION ``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 AEROSPACE CORPORATION 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.
|
||||
*
|
||||
*
|
||||
* Copyright (c) 1996-1999 Whistle Communications, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Subject to the following obligations and disclaimer of warranty, use and
|
||||
* redistribution of this software, in source or object code forms, with or
|
||||
* without modifications are expressly permitted by Whistle Communications;
|
||||
* provided, however, that:
|
||||
* 1. Any and all reproductions of the source or object code must include the
|
||||
* copyright notice above and the following disclaimer of warranties; and
|
||||
* 2. No rights are granted, in any manner or form, to use Whistle
|
||||
* Communications, Inc. trademarks, including the mark "WHISTLE
|
||||
* COMMUNICATIONS" on advertising, endorsements, or otherwise except as
|
||||
* such appears in the above copyright notice or in the software.
|
||||
*
|
||||
* THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
|
||||
* TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
|
||||
* REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
|
||||
* WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
|
||||
* REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
|
||||
* SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
|
||||
* IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
|
||||
* RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
|
||||
* WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
|
||||
* PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
|
||||
* OF SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
/*
|
||||
* ng_gif_demux(4) netgraph node type
|
||||
*
|
||||
* Packets received on the "gif" hook have their type header removed
|
||||
* and are passed to the appropriate hook protocol hook. Packets
|
||||
* recieved on a protocol hook have a type header added back and are
|
||||
* passed out the gif hook. The currently supported protocol hooks are:
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/ctype.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netgraph/ng_message.h>
|
||||
#include <netgraph/netgraph.h>
|
||||
#include <netgraph/ng_parse.h>
|
||||
#include <netgraph/ng_gif_demux.h>
|
||||
|
||||
#ifdef NG_SEPARATE_MALLOC
|
||||
MALLOC_DEFINE(M_NETGRAPH_GIF_DEMUX, "netgraph_gif_demux",
|
||||
"netgraph gif demux node");
|
||||
#else
|
||||
#define M_NETGRAPH_GIF_DEMUX M_NETGRAPH
|
||||
#endif
|
||||
|
||||
/* This struct describes one address family */
|
||||
struct iffam {
|
||||
sa_family_t family; /* Address family */
|
||||
const char *hookname; /* Name for hook */
|
||||
};
|
||||
typedef const struct iffam *iffam_p;
|
||||
|
||||
/* List of address families supported by our interface */
|
||||
const static struct iffam gFamilies[] = {
|
||||
{ AF_INET, NG_GIF_DEMUX_HOOK_INET },
|
||||
{ AF_INET6, NG_GIF_DEMUX_HOOK_INET6 },
|
||||
{ AF_APPLETALK, NG_GIF_DEMUX_HOOK_ATALK },
|
||||
{ AF_IPX, NG_GIF_DEMUX_HOOK_IPX },
|
||||
{ AF_ATM, NG_GIF_DEMUX_HOOK_ATM },
|
||||
{ AF_NATM, NG_GIF_DEMUX_HOOK_NATM },
|
||||
{ AF_NS, NG_GIF_DEMUX_HOOK_NS },
|
||||
};
|
||||
#define NUM_FAMILIES (sizeof(gFamilies) / sizeof(*gFamilies))
|
||||
|
||||
/* Per-node private data */
|
||||
struct ng_gif_demux_private {
|
||||
node_p node; /* Our netgraph node */
|
||||
hook_p gif; /* The gif hook */
|
||||
hook_p hooks[NUM_FAMILIES]; /* The protocol hooks */
|
||||
};
|
||||
typedef struct ng_gif_demux_private *priv_p;
|
||||
|
||||
/* Netgraph node methods */
|
||||
static ng_constructor_t ng_gif_demux_constructor;
|
||||
static ng_rcvmsg_t ng_gif_demux_rcvmsg;
|
||||
static ng_shutdown_t ng_gif_demux_shutdown;
|
||||
static ng_newhook_t ng_gif_demux_newhook;
|
||||
static ng_rcvdata_t ng_gif_demux_rcvdata;
|
||||
static ng_disconnect_t ng_gif_demux_disconnect;
|
||||
|
||||
/* Helper stuff */
|
||||
static iffam_p get_iffam_from_af(sa_family_t family);
|
||||
static iffam_p get_iffam_from_hook(priv_p priv, hook_p hook);
|
||||
static iffam_p get_iffam_from_name(const char *name);
|
||||
static hook_p *get_hook_from_iffam(priv_p priv, iffam_p iffam);
|
||||
|
||||
/******************************************************************
|
||||
NETGRAPH PARSE TYPES
|
||||
******************************************************************/
|
||||
|
||||
/* List of commands and how to convert arguments to/from ASCII */
|
||||
static const struct ng_cmdlist ng_gif_demux_cmdlist[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
/* Node type descriptor */
|
||||
static struct ng_type ng_gif_demux_typestruct = {
|
||||
NG_ABI_VERSION,
|
||||
NG_GIF_DEMUX_NODE_TYPE,
|
||||
NULL,
|
||||
ng_gif_demux_constructor,
|
||||
ng_gif_demux_rcvmsg,
|
||||
ng_gif_demux_shutdown,
|
||||
ng_gif_demux_newhook,
|
||||
NULL,
|
||||
NULL,
|
||||
ng_gif_demux_rcvdata,
|
||||
ng_gif_demux_disconnect,
|
||||
ng_gif_demux_cmdlist,
|
||||
};
|
||||
NETGRAPH_INIT(gif_demux, &ng_gif_demux_typestruct);
|
||||
|
||||
/************************************************************************
|
||||
HELPER STUFF
|
||||
************************************************************************/
|
||||
|
||||
/*
|
||||
* Get the family descriptor from the family ID
|
||||
*/
|
||||
static __inline__ iffam_p
|
||||
get_iffam_from_af(sa_family_t family)
|
||||
{
|
||||
iffam_p iffam;
|
||||
int k;
|
||||
|
||||
for (k = 0; k < NUM_FAMILIES; k++) {
|
||||
iffam = &gFamilies[k];
|
||||
if (iffam->family == family)
|
||||
return (iffam);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the family descriptor from the hook
|
||||
*/
|
||||
static __inline__ iffam_p
|
||||
get_iffam_from_hook(priv_p priv, hook_p hook)
|
||||
{
|
||||
int k;
|
||||
|
||||
for (k = 0; k < NUM_FAMILIES; k++)
|
||||
if (priv->hooks[k] == hook)
|
||||
return (&gFamilies[k]);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the hook from the iffam descriptor
|
||||
*/
|
||||
|
||||
static __inline__ hook_p *
|
||||
get_hook_from_iffam(priv_p priv, iffam_p iffam)
|
||||
{
|
||||
return (&priv->hooks[iffam - gFamilies]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the iffam descriptor from the name
|
||||
*/
|
||||
static __inline__ iffam_p
|
||||
get_iffam_from_name(const char *name)
|
||||
{
|
||||
iffam_p iffam;
|
||||
int k;
|
||||
|
||||
for (k = 0; k < NUM_FAMILIES; k++) {
|
||||
iffam = &gFamilies[k];
|
||||
if (!strcmp(iffam->hookname, name))
|
||||
return (iffam);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
NETGRAPH NODE METHODS
|
||||
******************************************************************/
|
||||
|
||||
/*
|
||||
* Node constructor
|
||||
*/
|
||||
static int
|
||||
ng_gif_demux_constructor(node_p node)
|
||||
{
|
||||
priv_p priv;
|
||||
|
||||
/* Allocate and initialize private info */
|
||||
MALLOC(priv, priv_p, sizeof(*priv), M_NETGRAPH_GIF_DEMUX,
|
||||
M_NOWAIT | M_ZERO);
|
||||
if (priv == NULL)
|
||||
return (ENOMEM);
|
||||
priv->node = node;
|
||||
|
||||
NG_NODE_SET_PRIVATE(node, priv);
|
||||
|
||||
/* Done */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Method for attaching a new hook
|
||||
*/
|
||||
static int
|
||||
ng_gif_demux_newhook(node_p node, hook_p hook, const char *name)
|
||||
{
|
||||
const priv_p priv = NG_NODE_PRIVATE(node);
|
||||
iffam_p iffam;
|
||||
hook_p *hookptr;
|
||||
|
||||
if (strcmp(NG_GIF_DEMUX_HOOK_GIF, name) == 0)
|
||||
hookptr = &priv->gif;
|
||||
else {
|
||||
iffam = get_iffam_from_name(name);
|
||||
if (iffam == NULL)
|
||||
return (EPFNOSUPPORT);
|
||||
hookptr = get_hook_from_iffam(NG_NODE_PRIVATE(node), iffam);
|
||||
}
|
||||
if (*hookptr != NULL)
|
||||
return (EISCONN);
|
||||
*hookptr = hook;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive a control message
|
||||
*/
|
||||
static int
|
||||
ng_gif_demux_rcvmsg(node_p node, item_p item, hook_p lasthook)
|
||||
{
|
||||
struct ng_mesg *resp = NULL;
|
||||
int error = 0;
|
||||
struct ng_mesg *msg;
|
||||
|
||||
NGI_GET_MSG(item, msg);
|
||||
switch (msg->header.typecookie) {
|
||||
case NGM_GIF_DEMUX_COOKIE:
|
||||
switch (msg->header.cmd) {
|
||||
/* XXX: Add commands here. */
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Done */
|
||||
NG_RESPOND_MSG(error, node, item, resp);
|
||||
NG_FREE_MSG(msg);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Receive data on a hook
|
||||
*/
|
||||
static int
|
||||
ng_gif_demux_rcvdata(hook_p hook, item_p item)
|
||||
{
|
||||
const node_p node = NG_HOOK_NODE(hook);
|
||||
const priv_p priv = NG_NODE_PRIVATE(node);
|
||||
iffam_p iffam;
|
||||
hook_p outhook;
|
||||
int error = 0;
|
||||
struct mbuf *m;
|
||||
|
||||
/* Pull the mbuf out of the item for processing. */
|
||||
NGI_GET_M(item, m);
|
||||
|
||||
if (hook == priv->gif) {
|
||||
/*
|
||||
* Pull off the address family header and find the
|
||||
* output hook.
|
||||
*/
|
||||
if (m->m_pkthdr.len < sizeof(sa_family_t)) {
|
||||
NG_FREE_M(m);
|
||||
NG_FREE_ITEM(item);
|
||||
return (EINVAL);
|
||||
}
|
||||
if (m->m_len < sizeof(sa_family_t)
|
||||
&& (m = m_pullup(m, sizeof(sa_family_t))) == NULL) {
|
||||
NG_FREE_ITEM(item);
|
||||
return (ENOBUFS);
|
||||
}
|
||||
iffam = get_iffam_from_af(*mtod(m, sa_family_t *));
|
||||
if (iffam == NULL) {
|
||||
NG_FREE_M(m);
|
||||
NG_FREE_ITEM(item);
|
||||
return (EINVAL);
|
||||
}
|
||||
outhook = *get_hook_from_iffam(priv, iffam);
|
||||
m_adj(m, sizeof(sa_family_t));
|
||||
} else {
|
||||
/*
|
||||
* Add address family header and set the output hook.
|
||||
*/
|
||||
iffam = get_iffam_from_hook(priv, hook);
|
||||
M_PREPEND(m, sizeof (iffam->family), M_DONTWAIT);
|
||||
if (m == NULL) {
|
||||
NG_FREE_M(m);
|
||||
NG_FREE_ITEM(item);
|
||||
return (ENOBUFS);
|
||||
}
|
||||
bcopy(&iffam->family, mtod(m, sa_family_t *),
|
||||
sizeof(iffam->family));
|
||||
outhook = priv->gif;
|
||||
}
|
||||
|
||||
/* Stuff the mbuf back in. */
|
||||
NGI_M(item) = m;
|
||||
|
||||
/* Deliver packet */
|
||||
NG_FWD_ITEM_HOOK(error, item, outhook);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Shutdown node
|
||||
*/
|
||||
static int
|
||||
ng_gif_demux_shutdown(node_p node)
|
||||
{
|
||||
const priv_p priv = NG_NODE_PRIVATE(node);
|
||||
|
||||
FREE(priv, M_NETGRAPH_GIF_DEMUX);
|
||||
NG_NODE_SET_PRIVATE(node, NULL);
|
||||
NG_NODE_UNREF(node);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hook disconnection.
|
||||
*/
|
||||
static int
|
||||
ng_gif_demux_disconnect(hook_p hook)
|
||||
{
|
||||
const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
|
||||
iffam_p iffam;
|
||||
|
||||
if (hook == priv->gif)
|
||||
priv->gif = NULL;
|
||||
else {
|
||||
iffam = get_iffam_from_hook(priv, hook);
|
||||
if (iffam == NULL)
|
||||
panic(__FUNCTION__);
|
||||
*get_hook_from_iffam(priv, iffam) = NULL;
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
47
sys/netgraph/ng_gif_demux.h
Normal file
47
sys/netgraph/ng_gif_demux.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* ng_gif_demux.h
|
||||
*
|
||||
* Copyright 2001 The Aerospace Corporation. 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AEROSPACE CORPORATION ``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 AEROSPACE CORPORATION 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.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _NETGRAPH_NG_GIF_DEMUX_H_
|
||||
#define _NETGRAPH_NG_GIF_DEMUX_H_
|
||||
|
||||
/* Node type name and magic cookie */
|
||||
#define NG_GIF_DEMUX_NODE_TYPE "gif_demux"
|
||||
#define NGM_GIF_DEMUX_COOKIE 995567329
|
||||
|
||||
/* Hook names */
|
||||
#define NG_GIF_DEMUX_HOOK_GIF "gif"
|
||||
#define NG_GIF_DEMUX_HOOK_INET "inet"
|
||||
#define NG_GIF_DEMUX_HOOK_INET6 "inet6"
|
||||
#define NG_GIF_DEMUX_HOOK_ATALK "atalk"
|
||||
#define NG_GIF_DEMUX_HOOK_IPX "ipx"
|
||||
#define NG_GIF_DEMUX_HOOK_ATM "atm"
|
||||
#define NG_GIF_DEMUX_HOOK_NATM "natm"
|
||||
#define NG_GIF_DEMUX_HOOK_NS "ns"
|
||||
|
||||
#endif /* _NETGRAPH_NG_GIF_DEMUX_H_ */
|
Loading…
Reference in New Issue
Block a user