/*1* ng_hole.c2*/34/*-5* Copyright (c) 1996-1999 Whistle Communications, Inc.6* All rights reserved.7*8* Subject to the following obligations and disclaimer of warranty, use and9* redistribution of this software, in source or object code forms, with or10* without modifications are expressly permitted by Whistle Communications;11* provided, however, that:12* 1. Any and all reproductions of the source or object code must include the13* copyright notice above and the following disclaimer of warranties; and14* 2. No rights are granted, in any manner or form, to use Whistle15* Communications, Inc. trademarks, including the mark "WHISTLE16* COMMUNICATIONS" on advertising, endorsements, or otherwise except as17* such appears in the above copyright notice or in the software.18*19* THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND20* TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO21* REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,22* INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF23* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.24* WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY25* REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS26* SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.27* IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES28* RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING29* WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,30* PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR31* SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY32* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT33* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF34* THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY35* OF SUCH DAMAGE.36*37* Author: Julian Elisher <[email protected]>38* $Whistle: ng_hole.c,v 1.10 1999/11/01 09:24:51 julian Exp $39*/4041/*42* This node is a 'black hole' that simply discards everything it receives43*/4445#include <sys/param.h>46#include <sys/systm.h>47#include <sys/kernel.h>48#include <sys/malloc.h>49#include <sys/mbuf.h>50#include <netgraph/ng_message.h>51#include <netgraph/netgraph.h>52#include <netgraph/ng_parse.h>53#include <netgraph/ng_hole.h>5455/* Per hook private info. */56struct ng_hole_hookinfo {57struct ng_hole_hookstat stats;58};59typedef struct ng_hole_hookinfo *hinfo_p;6061/* Parse type for struct ng_hole_hookstat. */62static const struct ng_parse_struct_field ng_hole_hookstat_type_fields[] =63NG_HOLE_HOOKSTAT_TYPE_INFO;64static const struct ng_parse_type ng_hole_hookstat_type = {65&ng_parse_struct_type,66&ng_hole_hookstat_type_fields67};6869/* List of commands and how to convert arguments to/from ASCII. */70static const struct ng_cmdlist ng_hole_cmdlist[] = {71{72NGM_HOLE_COOKIE,73NGM_HOLE_GET_STATS,74"getstats",75&ng_parse_hookbuf_type,76&ng_hole_hookstat_type77},78{79NGM_HOLE_COOKIE,80NGM_HOLE_CLR_STATS,81"clrstats",82&ng_parse_hookbuf_type,83NULL84},85{86NGM_HOLE_COOKIE,87NGM_HOLE_GETCLR_STATS,88"getclrstats",89&ng_parse_hookbuf_type,90&ng_hole_hookstat_type91},92{ 0 }93};9495/* Netgraph methods */96static ng_constructor_t ngh_cons;97static ng_rcvmsg_t ngh_rcvmsg;98static ng_newhook_t ngh_newhook;99static ng_rcvdata_t ngh_rcvdata;100static ng_disconnect_t ngh_disconnect;101102static struct ng_type typestruct = {103.version = NG_ABI_VERSION,104.name = NG_HOLE_NODE_TYPE,105.constructor = ngh_cons,106.rcvmsg = ngh_rcvmsg,107.newhook = ngh_newhook,108.rcvdata = ngh_rcvdata,109.disconnect = ngh_disconnect,110.cmdlist = ng_hole_cmdlist,111};112NETGRAPH_INIT(hole, &typestruct);113114/*115* Be obliging. but no work to do.116*/117static int118ngh_cons(node_p node)119{120return(0);121}122123/*124* Add a hook.125*/126static int127ngh_newhook(node_p node, hook_p hook, const char *name)128{129hinfo_p hip;130131/* Create hook private structure. */132hip = malloc(sizeof(*hip), M_NETGRAPH, M_NOWAIT | M_ZERO);133if (hip == NULL)134return (ENOMEM);135NG_HOOK_SET_PRIVATE(hook, hip);136return (0);137}138139/*140* Receive a control message.141*/142static int143ngh_rcvmsg(node_p node, item_p item, hook_p lasthook)144{145struct ng_mesg *msg;146struct ng_mesg *resp = NULL;147int error = 0;148struct ng_hole_hookstat *stats;149hook_p hook;150151NGI_GET_MSG(item, msg);152switch (msg->header.typecookie) {153case NGM_HOLE_COOKIE:154switch (msg->header.cmd) {155case NGM_HOLE_GET_STATS:156case NGM_HOLE_CLR_STATS:157case NGM_HOLE_GETCLR_STATS:158/* Sanity check. */159if (msg->header.arglen != NG_HOOKSIZ) {160error = EINVAL;161break;162}163/* Find hook. */164hook = ng_findhook(node, (char *)msg->data);165if (hook == NULL) {166error = ENOENT;167break;168}169stats = &((hinfo_p)NG_HOOK_PRIVATE(hook))->stats;170/* Build response (if desired). */171if (msg->header.cmd != NGM_HOLE_CLR_STATS) {172NG_MKRESPONSE(resp, msg, sizeof(*stats),173M_NOWAIT);174if (resp == NULL) {175error = ENOMEM;176break;177}178bcopy(stats, resp->data, sizeof(*stats));179}180/* Clear stats (if desired). */181if (msg->header.cmd != NGM_HOLE_GET_STATS)182bzero(stats, sizeof(*stats));183break;184default: /* Unknown command. */185error = EINVAL;186break;187}188break;189default: /* Unknown type cookie. */190error = EINVAL;191break;192}193NG_RESPOND_MSG(error, node, item, resp);194NG_FREE_MSG(msg);195return (error);196}197198/*199* Receive data200*/201static int202ngh_rcvdata(hook_p hook, item_p item)203{204const hinfo_p hip = NG_HOOK_PRIVATE(hook);205206hip->stats.frames++;207hip->stats.octets += NGI_M(item)->m_pkthdr.len;208NG_FREE_ITEM(item);209return 0;210}211212/*213* Hook disconnection214*/215static int216ngh_disconnect(hook_p hook)217{218219free(NG_HOOK_PRIVATE(hook), M_NETGRAPH);220NG_HOOK_SET_PRIVATE(hook, NULL);221if (NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0)222ng_rmnode_self(NG_HOOK_NODE(hook));223return (0);224}225226227