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