152419Sjulian/*
252419Sjulian * ng_hole.c
3139823Simp */
4139823Simp
5139823Simp/*-
652419Sjulian * Copyright (c) 1996-1999 Whistle Communications, Inc.
752419Sjulian * All rights reserved.
852419Sjulian *
952419Sjulian * Subject to the following obligations and disclaimer of warranty, use and
1052419Sjulian * redistribution of this software, in source or object code forms, with or
1152419Sjulian * without modifications are expressly permitted by Whistle Communications;
1252419Sjulian * provided, however, that:
1352419Sjulian * 1. Any and all reproductions of the source or object code must include the
1452419Sjulian *    copyright notice above and the following disclaimer of warranties; and
1552419Sjulian * 2. No rights are granted, in any manner or form, to use Whistle
1652419Sjulian *    Communications, Inc. trademarks, including the mark "WHISTLE
1752419Sjulian *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
1852419Sjulian *    such appears in the above copyright notice or in the software.
1952419Sjulian *
2052419Sjulian * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
2152419Sjulian * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
2252419Sjulian * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
2352419Sjulian * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
2452419Sjulian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
2552419Sjulian * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
2652419Sjulian * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
2752419Sjulian * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
2852419Sjulian * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
2952419Sjulian * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
3052419Sjulian * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
3152419Sjulian * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
3252419Sjulian * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
3352419Sjulian * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3452419Sjulian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3552419Sjulian * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
3652419Sjulian * OF SUCH DAMAGE.
3752419Sjulian *
3867506Sjulian * Author: Julian Elisher <julian@freebsd.org>
3952419Sjulian *
4052419Sjulian * $FreeBSD$
4152752Sjulian * $Whistle: ng_hole.c,v 1.10 1999/11/01 09:24:51 julian Exp $
4252419Sjulian */
4352419Sjulian
4452419Sjulian/*
4552419Sjulian * This node is a 'black hole' that simply discards everything it receives
4652419Sjulian */
4752419Sjulian
4852419Sjulian#include <sys/param.h>
4970784Sjulian#include <sys/systm.h>
5052419Sjulian#include <sys/kernel.h>
5152419Sjulian#include <sys/malloc.h>
5252419Sjulian#include <sys/mbuf.h>
5352419Sjulian#include <netgraph/ng_message.h>
5452419Sjulian#include <netgraph/netgraph.h>
55129441Sru#include <netgraph/ng_parse.h>
5652419Sjulian#include <netgraph/ng_hole.h>
5752419Sjulian
58129441Sru/* Per hook private info. */
59129441Srustruct ng_hole_hookinfo {
60129441Sru	struct ng_hole_hookstat	stats;
61129441Sru};
62129441Srutypedef struct ng_hole_hookinfo *hinfo_p;
63129441Sru
64129441Sru/* Parse type for struct ng_hole_hookstat. */
65129441Srustatic const struct ng_parse_struct_field ng_hole_hookstat_type_fields[] =
66129441Sru	NG_HOLE_HOOKSTAT_TYPE_INFO;
67129441Srustatic const struct ng_parse_type ng_hole_hookstat_type = {
68129441Sru	&ng_parse_struct_type,
69129441Sru	&ng_hole_hookstat_type_fields
70129441Sru};
71129441Sru
72129441Sru/* List of commands and how to convert arguments to/from ASCII. */
73129441Srustatic const struct ng_cmdlist ng_hole_cmdlist[] = {
74129441Sru	{
75129441Sru	  NGM_HOLE_COOKIE,
76129441Sru	  NGM_HOLE_GET_STATS,
77129441Sru	  "getstats",
78129441Sru	  &ng_parse_hookbuf_type,
79129441Sru	  &ng_hole_hookstat_type
80129441Sru	},
81129441Sru	{
82129441Sru	  NGM_HOLE_COOKIE,
83129441Sru	  NGM_HOLE_CLR_STATS,
84129441Sru	  "clrstats",
85129441Sru	  &ng_parse_hookbuf_type,
86129441Sru	  NULL
87129441Sru	},
88129441Sru	{
89129441Sru	  NGM_HOLE_COOKIE,
90129441Sru	  NGM_HOLE_GETCLR_STATS,
91129441Sru	  "getclrstats",
92129441Sru	  &ng_parse_hookbuf_type,
93129441Sru	  &ng_hole_hookstat_type
94129441Sru	},
95129441Sru	{ 0 }
96129441Sru};
97129441Sru
9852419Sjulian/* Netgraph methods */
9970700Sjulianstatic ng_constructor_t	ngh_cons;
100129441Srustatic ng_rcvmsg_t	ngh_rcvmsg;
101129441Srustatic ng_newhook_t	ngh_newhook;
10252752Sjulianstatic ng_rcvdata_t	ngh_rcvdata;
10352752Sjulianstatic ng_disconnect_t	ngh_disconnect;
10452419Sjulian
10552419Sjulianstatic struct ng_type typestruct = {
106129823Sjulian	.version =	NG_ABI_VERSION,
107129823Sjulian	.name =		NG_HOLE_NODE_TYPE,
108129823Sjulian	.constructor =	ngh_cons,
109129823Sjulian	.rcvmsg =	ngh_rcvmsg,
110129823Sjulian	.newhook = 	ngh_newhook,
111129823Sjulian	.rcvdata =	ngh_rcvdata,
112129823Sjulian	.disconnect =	ngh_disconnect,
113129823Sjulian	.cmdlist =	ng_hole_cmdlist,
11452419Sjulian};
11552419SjulianNETGRAPH_INIT(hole, &typestruct);
11652419Sjulian
11770700Sjulian/*
11870700Sjulian * Be obliging. but no work to do.
11970700Sjulian */
12070700Sjulianstatic int
12170700Sjulianngh_cons(node_p node)
12270700Sjulian{
12370700Sjulian	return(0);
12470700Sjulian}
12570700Sjulian
12652419Sjulian/*
127129441Sru * Add a hook.
128129441Sru */
129129441Srustatic int
130129441Srungh_newhook(node_p node, hook_p hook, const char *name)
131129441Sru{
132129441Sru	hinfo_p hip;
133129441Sru
134129441Sru	/* Create hook private structure. */
135184205Sdes	hip = malloc(sizeof(*hip), M_NETGRAPH, M_NOWAIT | M_ZERO);
136129441Sru	if (hip == NULL)
137129441Sru		return (ENOMEM);
138129441Sru	NG_HOOK_SET_PRIVATE(hook, hip);
139129441Sru	return (0);
140129441Sru}
141129441Sru
142129441Sru/*
143129441Sru * Receive a control message.
144129441Sru */
145129441Srustatic int
146129441Srungh_rcvmsg(node_p node, item_p item, hook_p lasthook)
147129441Sru{
148129441Sru	struct ng_mesg *msg;
149129441Sru	struct ng_mesg *resp = NULL;
150129441Sru	int error = 0;
151129441Sru	struct ng_hole_hookstat *stats;
152129441Sru	hook_p hook;
153129441Sru
154129441Sru	NGI_GET_MSG(item, msg);
155129441Sru	switch (msg->header.typecookie) {
156129441Sru	case NGM_HOLE_COOKIE:
157129441Sru		switch (msg->header.cmd) {
158129441Sru		case NGM_HOLE_GET_STATS:
159129441Sru		case NGM_HOLE_CLR_STATS:
160129441Sru		case NGM_HOLE_GETCLR_STATS:
161129441Sru			/* Sanity check. */
162129674Sjulian			if (msg->header.arglen != NG_HOOKSIZ) {
163129441Sru				error = EINVAL;
164129441Sru				break;
165129441Sru			}
166129441Sru			/* Find hook. */
167129441Sru			hook = ng_findhook(node, (char *)msg->data);
168129441Sru			if (hook == NULL) {
169129441Sru				error = ENOENT;
170129441Sru				break;
171129441Sru			}
172129441Sru			stats = &((hinfo_p)NG_HOOK_PRIVATE(hook))->stats;
173129441Sru			/* Build response (if desired). */
174129441Sru			if (msg->header.cmd != NGM_HOLE_CLR_STATS) {
175129441Sru				NG_MKRESPONSE(resp, msg, sizeof(*stats),
176129441Sru				    M_NOWAIT);
177129441Sru				if (resp == NULL) {
178129441Sru					error = ENOMEM;
179129441Sru					break;
180129441Sru				}
181129441Sru				bcopy(stats, resp->data, sizeof(*stats));
182129441Sru			}
183129441Sru			/* Clear stats (if desired). */
184129441Sru			if (msg->header.cmd != NGM_HOLE_GET_STATS)
185129441Sru				bzero(stats, sizeof(*stats));
186129441Sru			break;
187129441Sru		default:		/* Unknown command. */
188129441Sru			error = EINVAL;
189129441Sru			break;
190129441Sru		}
191129441Sru		break;
192129441Sru	default:			/* Unknown type cookie. */
193129441Sru		error = EINVAL;
194129441Sru		break;
195129441Sru	}
196129441Sru	NG_RESPOND_MSG(error, node, item, resp);
197129441Sru	NG_FREE_MSG(msg);
198129441Sru	return (error);
199129441Sru}
200129441Sru
201129441Sru/*
20252419Sjulian * Receive data
20352419Sjulian */
20452419Sjulianstatic int
20570700Sjulianngh_rcvdata(hook_p hook, item_p item)
20652419Sjulian{
207129441Sru	const hinfo_p hip = NG_HOOK_PRIVATE(hook);
208129441Sru
209129441Sru	hip->stats.frames++;
210129441Sru	hip->stats.octets += NGI_M(item)->m_pkthdr.len;
21170700Sjulian	NG_FREE_ITEM(item);
21252419Sjulian	return 0;
21352419Sjulian}
21452419Sjulian
21552419Sjulian/*
21652419Sjulian * Hook disconnection
21752419Sjulian */
21852419Sjulianstatic int
21952419Sjulianngh_disconnect(hook_p hook)
22052419Sjulian{
221129441Sru
222184205Sdes	free(NG_HOOK_PRIVATE(hook), M_NETGRAPH);
223129441Sru	NG_HOOK_SET_PRIVATE(hook, NULL);
22470784Sjulian	if (NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0)
22570784Sjulian		ng_rmnode_self(NG_HOOK_NODE(hook));
22652419Sjulian	return (0);
22752419Sjulian}
228