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 //! The net_protocol one talks to when using the AF_LINK protocol 11 12 13 #include "link.h" 14 15 #include <net/if_types.h> 16 #include <new> 17 #include <stdlib.h> 18 #include <string.h> 19 #include <sys/sockio.h> 20 21 #include <KernelExport.h> 22 23 #include <lock.h> 24 #include <net_datalink.h> 25 #include <net_device.h> 26 #include <ProtocolUtilities.h> 27 #include <util/AutoLock.h> 28 29 #include "device_interfaces.h" 30 #include "domains.h" 31 #include "stack_private.h" 32 #include "utility.h" 33 34 35 class LocalStackBundle { 36 public: 37 static net_stack_module_info* Stack() { return &gNetStackModule; } 38 static net_buffer_module_info* Buffer() { return &gNetBufferModule; } 39 }; 40 41 typedef DatagramSocket<MutexLocking, LocalStackBundle> LocalDatagramSocket; 42 43 class LinkProtocol : public net_protocol, public LocalDatagramSocket { 44 public: 45 LinkProtocol(net_socket* socket); 46 virtual ~LinkProtocol(); 47 48 status_t StartMonitoring(const char* deviceName); 49 status_t StopMonitoring(); 50 51 protected: 52 status_t SocketStatus(bool peek) const; 53 54 private: 55 status_t _Unregister(); 56 57 static status_t _MonitorData(net_device_monitor* monitor, 58 net_buffer* buffer); 59 static void _MonitorEvent(net_device_monitor* monitor, 60 int32 event); 61 62 private: 63 net_device_monitor fMonitor; 64 net_device_interface* fMonitoredDevice; 65 }; 66 67 68 struct net_domain* sDomain; 69 70 71 LinkProtocol::LinkProtocol(net_socket* socket) 72 : LocalDatagramSocket("packet capture", socket) 73 { 74 fMonitor.cookie = this; 75 fMonitor.receive = _MonitorData; 76 fMonitor.event = _MonitorEvent; 77 fMonitoredDevice = NULL; 78 } 79 80 81 LinkProtocol::~LinkProtocol() 82 { 83 if (fMonitoredDevice) { 84 unregister_device_monitor(fMonitoredDevice->device, &fMonitor); 85 put_device_interface(fMonitoredDevice); 86 } 87 } 88 89 90 status_t 91 LinkProtocol::StartMonitoring(const char* deviceName) 92 { 93 MutexLocker _(fLock); 94 95 if (fMonitoredDevice) 96 return B_BUSY; 97 98 net_device_interface* interface = get_device_interface(deviceName); 99 if (interface == NULL) 100 return B_DEVICE_NOT_FOUND; 101 102 status_t status = register_device_monitor(interface->device, &fMonitor); 103 if (status < B_OK) { 104 put_device_interface(interface); 105 return status; 106 } 107 108 fMonitoredDevice = interface; 109 return B_OK; 110 } 111 112 113 status_t 114 LinkProtocol::StopMonitoring() 115 { 116 MutexLocker _(fLock); 117 118 // TODO compare our device with the supplied device name? 119 return _Unregister(); 120 } 121 122 123 status_t 124 LinkProtocol::SocketStatus(bool peek) const 125 { 126 if (fMonitoredDevice == NULL) 127 return B_DEVICE_NOT_FOUND; 128 129 return LocalDatagramSocket::SocketStatus(peek); 130 } 131 132 133 status_t 134 LinkProtocol::_Unregister() 135 { 136 if (fMonitoredDevice == NULL) 137 return B_BAD_VALUE; 138 139 status_t status = unregister_device_monitor(fMonitoredDevice->device, 140 &fMonitor); 141 put_device_interface(fMonitoredDevice); 142 fMonitoredDevice = NULL; 143 144 return status; 145 } 146 147 148 status_t 149 LinkProtocol::_MonitorData(net_device_monitor* monitor, net_buffer* packet) 150 { 151 return ((LinkProtocol*)monitor->cookie)->SocketEnqueue(packet); 152 } 153 154 155 void 156 LinkProtocol::_MonitorEvent(net_device_monitor* monitor, int32 event) 157 { 158 LinkProtocol* protocol = (LinkProtocol*)monitor->cookie; 159 160 if (event == B_DEVICE_GOING_DOWN) { 161 MutexLocker _(protocol->fLock); 162 163 protocol->_Unregister(); 164 if (protocol->IsEmpty()) { 165 protocol->WakeAll(); 166 notify_socket(protocol->socket, B_SELECT_READ, B_DEVICE_NOT_FOUND); 167 } 168 } 169 } 170 171 172 // #pragma mark - 173 174 175 static bool 176 user_request_get_device_interface(void* value, struct ifreq& request, 177 net_device_interface*& interface) 178 { 179 if (user_memcpy(&request, value, IF_NAMESIZE) < B_OK) 180 return false; 181 182 interface = get_device_interface(request.ifr_name); 183 return true; 184 } 185 186 187 // #pragma mark - 188 189 190 net_protocol* 191 link_init_protocol(net_socket* socket) 192 { 193 LinkProtocol* protocol = new (std::nothrow) LinkProtocol(socket); 194 if (protocol != NULL && protocol->InitCheck() < B_OK) { 195 delete protocol; 196 return NULL; 197 } 198 199 return protocol; 200 } 201 202 203 status_t 204 link_uninit_protocol(net_protocol* protocol) 205 { 206 delete (LinkProtocol*)protocol; 207 return B_OK; 208 } 209 210 211 status_t 212 link_open(net_protocol* protocol) 213 { 214 return B_OK; 215 } 216 217 218 status_t 219 link_close(net_protocol* protocol) 220 { 221 return B_OK; 222 } 223 224 225 status_t 226 link_free(net_protocol* protocol) 227 { 228 return B_OK; 229 } 230 231 232 status_t 233 link_connect(net_protocol* protocol, const struct sockaddr* address) 234 { 235 return EOPNOTSUPP; 236 } 237 238 239 status_t 240 link_accept(net_protocol* protocol, struct net_socket** _acceptedSocket) 241 { 242 return EOPNOTSUPP; 243 } 244 245 246 status_t 247 link_control(net_protocol* _protocol, int level, int option, void* value, 248 size_t* _length) 249 { 250 LinkProtocol* protocol = (LinkProtocol*)_protocol; 251 252 switch (option) { 253 case SIOCGIFINDEX: 254 { 255 // get index of interface 256 net_device_interface* interface; 257 struct ifreq request; 258 if (!user_request_get_device_interface(value, request, interface)) 259 return B_BAD_ADDRESS; 260 261 if (interface != NULL) { 262 request.ifr_index = interface->device->index; 263 put_device_interface(interface); 264 } else 265 request.ifr_index = 0; 266 267 return user_memcpy(value, &request, sizeof(struct ifreq)); 268 } 269 case SIOCGIFNAME: 270 { 271 // get name of interface via index 272 struct ifreq request; 273 if (user_memcpy(&request, value, sizeof(struct ifreq)) < B_OK) 274 return B_BAD_ADDRESS; 275 276 net_device_interface* interface 277 = get_device_interface(request.ifr_index); 278 if (interface == NULL) 279 return B_DEVICE_NOT_FOUND; 280 281 strlcpy(request.ifr_name, interface->device->name, IF_NAMESIZE); 282 put_device_interface(interface); 283 284 return user_memcpy(value, &request, sizeof(struct ifreq)); 285 } 286 287 case SIOCGIFCOUNT: 288 { 289 // count number of interfaces 290 struct ifconf config; 291 config.ifc_value = count_device_interfaces(); 292 293 return user_memcpy(value, &config, sizeof(struct ifconf)); 294 } 295 296 case SIOCGIFCONF: 297 { 298 // retrieve available interfaces 299 struct ifconf config; 300 if (user_memcpy(&config, value, sizeof(struct ifconf)) < B_OK) 301 return B_BAD_ADDRESS; 302 303 status_t result = list_device_interfaces(config.ifc_buf, 304 (size_t*)&config.ifc_len); 305 if (result != B_OK) 306 return result; 307 308 return user_memcpy(value, &config, sizeof(struct ifconf)); 309 } 310 311 case SIOCGIFADDR: 312 { 313 // get address of interface 314 net_device_interface* interface; 315 struct ifreq request; 316 if (!user_request_get_device_interface(value, request, interface)) 317 return B_BAD_ADDRESS; 318 319 if (interface == NULL) 320 return B_DEVICE_NOT_FOUND; 321 322 get_device_interface_address(interface, &request.ifr_addr); 323 put_device_interface(interface); 324 325 return user_memcpy(&((struct ifreq*)value)->ifr_addr, 326 &request.ifr_addr, request.ifr_addr.sa_len); 327 } 328 329 case SIOCGIFFLAGS: 330 { 331 // get flags of interface 332 net_device_interface* interface; 333 struct ifreq request; 334 if (!user_request_get_device_interface(value, request, interface)) 335 return B_BAD_ADDRESS; 336 337 if (interface == NULL) 338 return B_DEVICE_NOT_FOUND; 339 340 request.ifr_flags = interface->device->flags; 341 put_device_interface(interface); 342 343 return user_memcpy(&((struct ifreq*)value)->ifr_flags, 344 &request.ifr_flags, sizeof(request.ifr_flags)); 345 } 346 347 case SIOCSPACKETCAP: 348 { 349 // Only root is allowed to capture packets 350 if (geteuid() != 0) 351 return B_NOT_ALLOWED; 352 353 struct ifreq request; 354 if (user_memcpy(&request, value, IF_NAMESIZE) < B_OK) 355 return B_BAD_ADDRESS; 356 357 return protocol->StartMonitoring(request.ifr_name); 358 } 359 360 case SIOCCPACKETCAP: 361 return protocol->StopMonitoring(); 362 } 363 364 return gNetDatalinkModule.control(sDomain, option, value, _length); 365 } 366 367 368 status_t 369 link_getsockopt(net_protocol* protocol, int level, int option, void* value, 370 int* length) 371 { 372 if (protocol->next != NULL) { 373 return protocol->next->module->getsockopt(protocol, level, option, 374 value, length); 375 } 376 377 return gNetSocketModule.get_option(protocol->socket, level, option, value, 378 length); 379 } 380 381 382 status_t 383 link_setsockopt(net_protocol* protocol, int level, int option, 384 const void* value, int length) 385 { 386 if (protocol->next != NULL) { 387 return protocol->next->module->setsockopt(protocol, level, option, 388 value, length); 389 } 390 391 return gNetSocketModule.set_option(protocol->socket, level, option, 392 value, length); 393 } 394 395 396 status_t 397 link_bind(net_protocol* protocol, const struct sockaddr* address) 398 { 399 // TODO: bind to a specific interface and ethernet type 400 return B_ERROR; 401 } 402 403 404 status_t 405 link_unbind(net_protocol* protocol, struct sockaddr* address) 406 { 407 return B_ERROR; 408 } 409 410 411 status_t 412 link_listen(net_protocol* protocol, int count) 413 { 414 return EOPNOTSUPP; 415 } 416 417 418 status_t 419 link_shutdown(net_protocol* protocol, int direction) 420 { 421 return EOPNOTSUPP; 422 } 423 424 425 status_t 426 link_send_data(net_protocol* protocol, net_buffer* buffer) 427 { 428 // Only root is allowed to send link protocol packets 429 if (geteuid() != 0) 430 return B_NOT_ALLOWED; 431 432 return B_NOT_SUPPORTED; 433 } 434 435 436 status_t 437 link_send_routed_data(net_protocol* protocol, struct net_route* route, 438 net_buffer* buffer) 439 { 440 return B_NOT_SUPPORTED; 441 } 442 443 444 ssize_t 445 link_send_avail(net_protocol* protocol) 446 { 447 return B_ERROR; 448 } 449 450 451 status_t 452 link_read_data(net_protocol* protocol, size_t numBytes, uint32 flags, 453 net_buffer** _buffer) 454 { 455 return ((LinkProtocol*)protocol)->SocketDequeue(flags, _buffer); 456 } 457 458 459 ssize_t 460 link_read_avail(net_protocol* protocol) 461 { 462 return ((LinkProtocol*)protocol)->AvailableData(); 463 } 464 465 466 struct net_domain* 467 link_get_domain(net_protocol* protocol) 468 { 469 return sDomain; 470 } 471 472 473 size_t 474 link_get_mtu(net_protocol* protocol, const struct sockaddr* address) 475 { 476 // TODO: for now 477 return 0; 478 } 479 480 481 status_t 482 link_receive_data(net_buffer* buffer) 483 { 484 return B_ERROR; 485 } 486 487 488 status_t 489 link_error(uint32 code, net_buffer* data) 490 { 491 return B_ERROR; 492 } 493 494 495 status_t 496 link_error_reply(net_protocol* protocol, net_buffer* causedError, uint32 code, 497 void* errorData) 498 { 499 return B_ERROR; 500 } 501 502 503 static status_t 504 link_std_ops(int32 op, ...) 505 { 506 switch (op) { 507 case B_MODULE_INIT: 508 return register_domain(AF_LINK, "link", NULL, NULL, &sDomain); 509 510 case B_MODULE_UNINIT: 511 unregister_domain(sDomain); 512 return B_OK; 513 514 default: 515 return B_ERROR; 516 } 517 } 518 519 520 // #pragma mark - 521 522 523 void 524 link_init() 525 { 526 register_domain_protocols(AF_LINK, SOCK_DGRAM, 0, "network/stack/link/v1", 527 NULL); 528 529 register_domain_datalink_protocols(AF_LINK, IFT_ETHER, 530 "network/datalink_protocols/ethernet_frame/v1", 531 NULL); 532 } 533 534 535 net_protocol_module_info gLinkModule = { 536 { 537 "network/stack/link/v1", 538 0, 539 link_std_ops 540 }, 541 NET_PROTOCOL_ATOMIC_MESSAGES, 542 543 link_init_protocol, 544 link_uninit_protocol, 545 link_open, 546 link_close, 547 link_free, 548 link_connect, 549 link_accept, 550 link_control, 551 link_getsockopt, 552 link_setsockopt, 553 link_bind, 554 link_unbind, 555 link_listen, 556 link_shutdown, 557 link_send_data, 558 link_send_routed_data, 559 link_send_avail, 560 link_read_data, 561 link_read_avail, 562 link_get_domain, 563 link_get_mtu, 564 link_receive_data, 565 NULL, 566 link_error, 567 link_error_reply, 568 }; 569