1/* 2 * Copyright 2006-2010, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Axel Dörfler, axeld@pinc-software.de 7 */ 8 9 10#include <ethernet.h> 11#include <net_datalink_protocol.h> 12#include <net_device.h> 13#include <net_datalink.h> 14#include <net_stack.h> 15#include <NetBufferUtilities.h> 16 17#include <ByteOrder.h> 18#include <KernelExport.h> 19 20#include <net/if.h> 21#include <net/if_types.h> 22#include <net/if_dl.h> 23#include <new> 24#include <string.h> 25 26 27struct loopback_frame_protocol : net_datalink_protocol { 28}; 29 30 31struct net_buffer_module_info* gBufferModule; 32 33 34status_t 35loopback_deframe(net_device* device, net_buffer* buffer) 36{ 37 // there is not that much to do... 38 return B_OK; 39} 40 41 42// #pragma mark - 43 44 45status_t 46loopback_frame_init(struct net_interface*interface, net_domain* domain, 47 net_datalink_protocol** _protocol) 48{ 49 // We only support a single type! 50 if (interface->device->type != IFT_LOOP) 51 return B_BAD_TYPE; 52 53 loopback_frame_protocol* protocol; 54 55 net_stack_module_info* stack; 56 status_t status = get_module(NET_STACK_MODULE_NAME, (module_info**)&stack); 57 if (status != B_OK) 58 return status; 59 60 status = stack->register_device_deframer(interface->device, 61 &loopback_deframe); 62 if (status != B_OK) 63 goto err1; 64 65 // Locally received buffers don't need a domain device handler, as the 66 // buffer reception is handled internally. 67 68 protocol = new(std::nothrow) loopback_frame_protocol; 69 if (protocol == NULL) { 70 status = B_NO_MEMORY; 71 goto err2; 72 } 73 74 put_module(NET_STACK_MODULE_NAME); 75 76 *_protocol = protocol; 77 return B_OK; 78 79err2: 80 stack->unregister_device_deframer(interface->device); 81err1: 82 put_module(NET_STACK_MODULE_NAME); 83 return status; 84} 85 86 87status_t 88loopback_frame_uninit(net_datalink_protocol* protocol) 89{ 90 net_stack_module_info* stack; 91 if (get_module(NET_STACK_MODULE_NAME, (module_info**)&stack) == B_OK) { 92 stack->unregister_device_deframer(protocol->interface->device); 93 stack->unregister_device_handler(protocol->interface->device, 0); 94 put_module(NET_STACK_MODULE_NAME); 95 } 96 97 delete protocol; 98 return B_OK; 99} 100 101 102status_t 103loopback_frame_send_data(net_datalink_protocol* protocol, net_buffer* buffer) 104{ 105 return protocol->next->module->send_data(protocol->next, buffer); 106} 107 108 109status_t 110loopback_frame_up(net_datalink_protocol* protocol) 111{ 112 return protocol->next->module->interface_up(protocol->next); 113} 114 115 116void 117loopback_frame_down(net_datalink_protocol* protocol) 118{ 119 return protocol->next->module->interface_down(protocol->next); 120} 121 122 123status_t 124loopback_frame_change_address(net_datalink_protocol* protocol, 125 net_interface_address* address, int32 option, 126 const struct sockaddr* oldAddress, const struct sockaddr* newAddress) 127{ 128 return protocol->next->module->change_address(protocol->next, address, 129 option, oldAddress, newAddress); 130} 131 132 133status_t 134loopback_frame_control(net_datalink_protocol* protocol, int32 option, 135 void* argument, size_t length) 136{ 137 return protocol->next->module->control(protocol->next, option, argument, 138 length); 139} 140 141 142static status_t 143loopback_frame_join_multicast(net_datalink_protocol* protocol, 144 const sockaddr* address) 145{ 146 return protocol->next->module->join_multicast(protocol->next, address); 147} 148 149 150static status_t 151loopback_frame_leave_multicast(net_datalink_protocol* protocol, 152 const sockaddr* address) 153{ 154 return protocol->next->module->leave_multicast(protocol->next, address); 155} 156 157 158static status_t 159loopback_frame_std_ops(int32 op, ...) 160{ 161 switch (op) { 162 case B_MODULE_INIT: 163 return get_module(NET_BUFFER_MODULE_NAME, 164 (module_info**)&gBufferModule); 165 case B_MODULE_UNINIT: 166 put_module(NET_BUFFER_MODULE_NAME); 167 return B_OK; 168 169 default: 170 return B_ERROR; 171 } 172} 173 174 175static net_datalink_protocol_module_info sLoopbackFrameModule = { 176 { 177 "network/datalink_protocols/loopback_frame/v1", 178 0, 179 loopback_frame_std_ops 180 }, 181 loopback_frame_init, 182 loopback_frame_uninit, 183 loopback_frame_send_data, 184 loopback_frame_up, 185 loopback_frame_down, 186 loopback_frame_change_address, 187 loopback_frame_control, 188 loopback_frame_join_multicast, 189 loopback_frame_leave_multicast, 190}; 191 192module_info* modules[] = { 193 (module_info*)&sLoopbackFrameModule, 194 NULL 195}; 196