1186481Sjulian/* 2186481Sjulian * ng_ether_echo.c 3186481Sjulian */ 4186481Sjulian 5186481Sjulian/*- 6186481Sjulian * Copyright (c) 1996-1999 Whistle Communications, Inc. 7186481Sjulian * All rights reserved. 8186481Sjulian * 9186481Sjulian * Subject to the following obligations and disclaimer of warranty, use and 10186481Sjulian * redistribution of this software, in source or object code forms, with or 11186481Sjulian * without modifications are expressly permitted by Whistle Communications; 12186481Sjulian * provided, however, that: 13186481Sjulian * 1. Any and all reproductions of the source or object code must include the 14186481Sjulian * copyright notice above and the following disclaimer of warranties; and 15186481Sjulian * 2. No rights are granted, in any manner or form, to use Whistle 16186481Sjulian * Communications, Inc. trademarks, including the mark "WHISTLE 17186481Sjulian * COMMUNICATIONS" on advertising, endorsements, or otherwise except as 18186481Sjulian * such appears in the above copyright notice or in the software. 19186481Sjulian * 20186481Sjulian * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND 21186481Sjulian * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO 22186481Sjulian * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, 23186481Sjulian * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF 24186481Sjulian * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. 25186481Sjulian * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY 26186481Sjulian * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS 27186481Sjulian * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. 28186481Sjulian * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES 29186481Sjulian * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING 30186481Sjulian * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 31186481Sjulian * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR 32186481Sjulian * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY 33186481Sjulian * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34186481Sjulian * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35186481Sjulian * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY 36186481Sjulian * OF SUCH DAMAGE. 37186481Sjulian * 38186481Sjulian * Author: Julian Elisher <julian@freebsd.org> 39186481Sjulian * 40186481Sjulian * $FreeBSD$ 41186481Sjulian * $Whistle: ng_echo.c,v 1.13 1999/11/01 09:24:51 julian Exp $ 42186481Sjulian */ 43186481Sjulian 44186481Sjulian/* 45186481Sjulian * Netgraph "ether_echo" node 46186481Sjulian * 47186481Sjulian * This node simply bounces data and messages back to whence they came. 48186481Sjulian * However it swaps the source and destination ether fields. 49186481Sjulian * No testing is done! 50186481Sjulian */ 51186481Sjulian 52186481Sjulian#include <sys/param.h> 53186481Sjulian#include <sys/systm.h> 54186481Sjulian#include <sys/kernel.h> 55186481Sjulian#include <sys/malloc.h> 56186481Sjulian#include <sys/mbuf.h> 57186481Sjulian#include <netgraph/ng_message.h> 58186481Sjulian#include <netgraph/netgraph.h> 59186481Sjulian#include <netgraph/ng_ether_echo.h> 60186481Sjulian 61186481Sjulian#include <net/ethernet.h> 62186481Sjulian 63186481Sjulian/* Netgraph methods */ 64186481Sjulianstatic ng_constructor_t ngee_cons; 65186481Sjulianstatic ng_rcvmsg_t ngee_rcvmsg; 66186481Sjulianstatic ng_rcvdata_t ngee_rcvdata; 67186481Sjulianstatic ng_disconnect_t ngee_disconnect; 68186481Sjulian 69186481Sjulian/* Netgraph type */ 70186481Sjulianstatic struct ng_type typestruct = { 71186481Sjulian .version = NG_ABI_VERSION, 72186481Sjulian .name = NG_ETHER_ECHO_NODE_TYPE, 73186481Sjulian .constructor = ngee_cons, 74186481Sjulian .rcvmsg = ngee_rcvmsg, 75186481Sjulian .rcvdata = ngee_rcvdata, 76186481Sjulian .disconnect = ngee_disconnect, 77186481Sjulian}; 78186481SjulianNETGRAPH_INIT(ether_echo, &typestruct); 79186481Sjulian 80186481Sjulianstatic int 81186481Sjulianngee_cons(node_p node) 82186481Sjulian{ 83186481Sjulian return (0); 84186481Sjulian} 85186481Sjulian 86186481Sjulian/* 87186481Sjulian * Receive control message. We just bounce it back as a reply. 88186481Sjulian */ 89186481Sjulianstatic int 90186481Sjulianngee_rcvmsg(node_p node, item_p item, hook_p lasthook) 91186481Sjulian{ 92186481Sjulian struct ng_mesg *msg; 93186481Sjulian int error = 0; 94186481Sjulian 95186481Sjulian NGI_GET_MSG(item, msg); 96186481Sjulian msg->header.flags |= NGF_RESP; 97186481Sjulian NG_RESPOND_MSG(error, node, item, msg); 98186481Sjulian return (error); 99186481Sjulian} 100186481Sjulian 101186481Sjulian/* 102186481Sjulian * Receive data 103186481Sjulian */ 104186481Sjulianstatic int 105186481Sjulianngee_rcvdata(hook_p hook, item_p item) 106186481Sjulian{ 107186481Sjulian int error; 108186481Sjulian struct mbuf *m; 109186481Sjulian 110186481Sjulian struct ether_header *eh; 111186481Sjulian struct ether_addr tmpaddr; 112186481Sjulian 113186481Sjulian /* Make sure we have an entire header */ 114186481Sjulian NGI_GET_M(item, m); 115186481Sjulian if (m->m_len < sizeof(*eh) ) { 116186481Sjulian m = m_pullup(m, sizeof(*eh)); 117186481Sjulian if (m == NULL) { 118186481Sjulian NG_FREE_ITEM(item); 119186481Sjulian return(EINVAL); 120186481Sjulian } 121186481Sjulian } 122186481Sjulian eh = mtod(m, struct ether_header *); 123186481Sjulian 124186481Sjulian /* swap the source and destination fields */ 125186481Sjulian bcopy(eh->ether_dhost, &tmpaddr, ETHER_ADDR_LEN); 126186481Sjulian bcopy(eh->ether_shost, eh->ether_dhost, ETHER_ADDR_LEN); 127186481Sjulian bcopy(&tmpaddr, eh->ether_shost, ETHER_ADDR_LEN); 128186481Sjulian 129186481Sjulian NG_FWD_NEW_DATA(error, item, hook, m); 130186481Sjulian return (error); 131186481Sjulian} 132186481Sjulian 133186481Sjulian/* 134186481Sjulian * Removal of the last link destroys the nodeo 135186481Sjulian */ 136186481Sjulianstatic int 137186481Sjulianngee_disconnect(hook_p hook) 138186481Sjulian{ 139186481Sjulian if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0) 140186481Sjulian && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) { 141186481Sjulian ng_rmnode_self(NG_HOOK_NODE(hook)); 142186481Sjulian } 143186481Sjulian return (0); 144186481Sjulian} 145186481Sjulian 146