1 /* 2 * Copyright 2014, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Lin Longzhou, linlongzhou@163.com 7 */ 8 9 10 #include <ethernet.h> 11 #include <net/if_types.h> 12 #include <net_datalink_protocol.h> 13 #include <net_datalink.h> 14 15 #include <KernelExport.h> 16 17 #include <new> 18 19 #include <PPPControl.h> 20 #include <ppp_device.h> 21 22 struct ppp_frame_protocol : net_datalink_protocol { 23 }; 24 25 26 static net_stack_module_info *sStackModule; 27 28 status_t 29 ppp_deframe(net_device* device, net_buffer* buffer) 30 { 31 TRACE("%s: buffer type:0x%" B_PRIx32 "\n", __func__, buffer->type); 32 return B_OK; 33 } 34 35 36 // #pragma mark - 37 38 status_t 39 ppp_frame_init(struct net_interface* interface, net_domain* domain, 40 net_datalink_protocol** _protocol) 41 { 42 // We only support a single type! 43 dprintf("in function: %s::%s\n", __FILE__, __func__); 44 if (interface->device->type != IFT_PPP) 45 return B_BAD_TYPE; 46 47 ppp_frame_protocol* protocol; 48 49 status_t status = sStackModule->register_device_deframer(interface->device, 50 &ppp_deframe); 51 if (status != B_OK) 52 return status; 53 54 status = sStackModule->register_domain_device_handler( 55 interface->device, B_NET_FRAME_TYPE(IFT_ETHER, ETHER_TYPE_PPPOE), domain); 56 if (status != B_OK) 57 return status; 58 59 status = sStackModule->register_domain_device_handler( 60 interface->device, B_NET_FRAME_TYPE_IPV4, domain); 61 if (status != B_OK) 62 return status; 63 64 // Locally received buffers don't need a domain device handler, as the 65 // buffer reception is handled internally. 66 67 protocol = new(std::nothrow) ppp_frame_protocol; 68 if (protocol == NULL) { 69 sStackModule->unregister_device_deframer(interface->device); 70 return B_NO_MEMORY; 71 } 72 73 *_protocol = protocol; 74 return B_OK; 75 } 76 77 78 status_t 79 ppp_frame_uninit(net_datalink_protocol* protocol) 80 { 81 sStackModule->unregister_device_deframer(protocol->interface->device); 82 sStackModule->unregister_device_handler(protocol->interface->device, 0); 83 84 delete protocol; 85 TRACE("%s\n", __func__); 86 return B_OK; 87 } 88 89 90 status_t 91 ppp_frame_send_data(net_datalink_protocol* protocol, net_buffer* buffer) 92 { 93 TRACE("%s: next module is %s\n", __func__, protocol->next->module->info.name); 94 return protocol->next->module->send_data(protocol->next, buffer); 95 } 96 97 98 status_t 99 ppp_frame_up(net_datalink_protocol* protocol) 100 { 101 dprintf("in function: %s\n", __func__); 102 103 return protocol->next->module->interface_up(protocol->next); 104 } 105 106 107 void 108 ppp_frame_down(net_datalink_protocol* protocol) 109 { 110 dprintf("%s::%s: entry\n", __FILE__, __func__); 111 protocol->next->module->interface_down(protocol->next); 112 return; 113 } 114 115 116 status_t 117 ppp_frame_change_address(net_datalink_protocol* protocol, 118 net_interface_address* address, int32 option, 119 const struct sockaddr* oldAddress, const struct sockaddr* newAddress) 120 { 121 TRACE("in function: %s::%s\n", __FILE__, __func__); 122 return protocol->next->module->change_address(protocol->next, address, 123 option, oldAddress, newAddress); 124 } 125 126 127 static status_t 128 PPP_module_control(int32 option, void* argument, size_t length) 129 { 130 // control_net_module_args* args=(control_net_module_args*)argument; 131 132 if (option < PPPC_CONTROL_MODULE || option > PPP_CONTROL_OPS_END) 133 return B_ERROR; 134 135 // if (args->name != PPP_INTERFACE_MODULE_NAME) 136 // return B_ERROR; 137 138 switch(option) 139 { 140 case PPPC_CREATE_INTERFACE: 141 // process_CreateInterface(args->data, args->length); 142 case PPPC_CREATE_INTERFACE_WITH_NAME: 143 case PPPC_DELETE_INTERFACE: 144 case PPPC_BRING_INTERFACE_UP: 145 case PPPC_BRING_INTERFACE_DOWN: 146 case PPPC_CONTROL_INTERFACE: 147 case PPPC_GET_INTERFACES: 148 case PPPC_COUNT_INTERFACES: 149 case PPPC_FIND_INTERFACE_WITH_SETTINGS: 150 151 // interface control 152 case PPPC_GET_INTERFACE_INFO: 153 case PPPC_SET_USERNAME: 154 case PPPC_SET_PASSWORD: 155 case PPPC_SET_ASK_BEFORE_CONNECTING: 156 // ppp_up uses this in order to finalize a connection request 157 case PPPC_SET_MRU: 158 case PPPC_SET_CONNECT_ON_DEMAND: 159 case PPPC_SET_AUTO_RECONNECT: 160 case PPPC_HAS_INTERFACE_SETTINGS: 161 case PPPC_GET_STATISTICS: 162 // handler access 163 case PPPC_CONTROL_DEVICE: 164 case PPPC_CONTROL_PROTOCOL: 165 case PPPC_CONTROL_OPTION_HANDLER: 166 case PPPC_CONTROL_LCP_EXTENSION: 167 case PPPC_CONTROL_CHILD: 168 // KPPPDevice 169 case PPPC_GET_DEVICE_INFO: 170 // KPPPProtocol 171 case PPPC_GET_PROTOCOL_INFO: 172 // Common/mixed ops 173 case PPPC_ENABLE: 174 case PPPC_GET_SIMPLE_HANDLER_INFO: 175 176 // these two control ops use the ppp_report_request structure 177 case PPPC_ENABLE_REPORTS: 178 case PPPC_DISABLE_REPORTS: 179 180 case PPP_CONTROL_OPS_END: 181 case PPPC_CONTROL_MODULE: 182 default: 183 return B_ERROR; 184 } 185 } 186 187 188 static status_t 189 ppp_frame_control(net_datalink_protocol* protocol, int32 option, 190 void* argument, size_t length) 191 { 192 TRACE("%s: option:%" B_PRId32 "\n", __func__, option); 193 194 if (option >= PPPC_CONTROL_MODULE && option <=PPP_CONTROL_OPS_END) 195 { 196 status_t status =PPP_module_control(option, argument, length); 197 // gPPPInterfaceModule->ControlInterface(1, option, argument, length); 198 return status; 199 } 200 201 return protocol->next->module->control(protocol->next, option, argument, 202 length); 203 } 204 205 206 static status_t 207 ppp_frame_join_multicast(net_datalink_protocol* protocol, 208 const sockaddr* address) 209 { 210 TRACE("in function: %s\n", __func__); 211 return protocol->next->module->join_multicast(protocol->next, address); 212 } 213 214 215 static status_t 216 ppp_frame_leave_multicast(net_datalink_protocol* protocol, 217 const sockaddr* address) 218 { 219 TRACE("in function: %s\n", __func__); 220 return protocol->next->module->leave_multicast(protocol->next, address); 221 } 222 223 224 static status_t 225 pppoe_frame_std_ops(int32 op, ...) 226 { 227 switch (op) { 228 case B_MODULE_INIT: 229 if (get_module(NET_STACK_MODULE_NAME, 230 (module_info **)&sStackModule) != B_OK) 231 return B_ERROR; 232 return B_OK; 233 234 case B_MODULE_UNINIT: 235 put_module(NET_STACK_MODULE_NAME); 236 return B_OK; 237 238 default: 239 return B_ERROR; 240 } 241 } 242 243 244 static net_datalink_protocol_module_info sPPPFrameModule = { 245 { 246 "network/datalink_protocols/ppp_frame/v1", 247 0, 248 pppoe_frame_std_ops 249 }, 250 ppp_frame_init, 251 ppp_frame_uninit, 252 ppp_frame_send_data, 253 ppp_frame_up, 254 ppp_frame_down, 255 ppp_frame_change_address, 256 ppp_frame_control, 257 ppp_frame_join_multicast, 258 ppp_frame_leave_multicast, 259 }; 260 261 262 module_info* modules[] = { 263 (module_info*)&sPPPFrameModule, 264 NULL 265 }; 266