/*1* ng_ether_echo.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_echo.c,v 1.13 1999/11/01 09:24:51 julian Exp $39*/4041/*42* Netgraph "ether_echo" node43*44* This node simply bounces data and messages back to whence they came.45* However it swaps the source and destination ether fields.46* No testing is done!47*/4849#include <sys/param.h>50#include <sys/systm.h>51#include <sys/kernel.h>52#include <sys/malloc.h>53#include <sys/mbuf.h>54#include <netgraph/ng_message.h>55#include <netgraph/netgraph.h>56#include <netgraph/ng_ether_echo.h>5758#include <net/ethernet.h>5960/* Netgraph methods */61static ng_constructor_t ngee_cons;62static ng_rcvmsg_t ngee_rcvmsg;63static ng_rcvdata_t ngee_rcvdata;64static ng_disconnect_t ngee_disconnect;6566/* Netgraph type */67static struct ng_type typestruct = {68.version = NG_ABI_VERSION,69.name = NG_ETHER_ECHO_NODE_TYPE,70.constructor = ngee_cons,71.rcvmsg = ngee_rcvmsg,72.rcvdata = ngee_rcvdata,73.disconnect = ngee_disconnect,74};75NETGRAPH_INIT(ether_echo, &typestruct);7677static int78ngee_cons(node_p node)79{80return (0);81}8283/*84* Receive control message. We just bounce it back as a reply.85*/86static int87ngee_rcvmsg(node_p node, item_p item, hook_p lasthook)88{89struct ng_mesg *msg;90int error = 0;9192NGI_GET_MSG(item, msg);93msg->header.flags |= NGF_RESP;94NG_RESPOND_MSG(error, node, item, msg);95return (error);96}9798/*99* Receive data100*/101static int102ngee_rcvdata(hook_p hook, item_p item)103{104int error;105struct mbuf *m;106107struct ether_header *eh;108struct ether_addr tmpaddr;109110/* Make sure we have an entire header */111NGI_GET_M(item, m);112if (m->m_len < sizeof(*eh) ) {113m = m_pullup(m, sizeof(*eh));114if (m == NULL) {115NG_FREE_ITEM(item);116return(EINVAL);117}118}119eh = mtod(m, struct ether_header *);120121/* swap the source and destination fields */122bcopy(eh->ether_dhost, &tmpaddr, ETHER_ADDR_LEN);123bcopy(eh->ether_shost, eh->ether_dhost, ETHER_ADDR_LEN);124bcopy(&tmpaddr, eh->ether_shost, ETHER_ADDR_LEN);125126NG_FWD_NEW_DATA(error, item, hook, m);127return (error);128}129130/*131* Removal of the last link destroys the nodeo132*/133static int134ngee_disconnect(hook_p hook)135{136if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0)137&& (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) {138ng_rmnode_self(NG_HOOK_NODE(hook));139}140return (0);141}142143144