1 /* 2 * Copyright 2006-2007, 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 "datalink.h" 11 #include "domains.h" 12 #include "interfaces.h" 13 #include "link.h" 14 #include "stack_private.h" 15 #include "utility.h" 16 17 #include <net_device.h> 18 19 #include <KernelExport.h> 20 21 #include <net/if_types.h> 22 #include <new> 23 #include <stdlib.h> 24 #include <string.h> 25 #include <sys/sockio.h> 26 27 28 struct link_protocol : net_protocol { 29 net_fifo fifo; 30 char registered_interface[IF_NAMESIZE]; 31 bool registered_monitor; 32 }; 33 34 35 struct net_domain *sDomain; 36 37 38 static status_t 39 link_monitor_data(void *cookie, net_buffer *packet) 40 { 41 link_protocol *protocol = (link_protocol *)cookie; 42 43 // we need to make a clone for that buffer and pass it to the socket 44 net_buffer *buffer = gNetBufferModule.clone(packet, false); 45 if (buffer == NULL) 46 return B_NO_MEMORY; 47 48 status_t status = fifo_enqueue_buffer(&protocol->fifo, buffer); 49 if (status >= B_OK) 50 notify_socket(protocol->socket, B_SELECT_READ, 51 protocol->fifo.current_bytes); 52 else 53 gNetBufferModule.free(buffer); 54 55 return status; 56 } 57 58 59 // #pragma mark - 60 61 62 net_protocol * 63 link_init_protocol(net_socket *socket) 64 { 65 link_protocol *protocol = new (std::nothrow) link_protocol; 66 if (protocol == NULL) 67 return NULL; 68 69 if (init_fifo(&protocol->fifo, "packet monitor socket", 65536) < B_OK) { 70 delete protocol; 71 return NULL; 72 } 73 74 protocol->registered_monitor = false; 75 return protocol; 76 } 77 78 79 status_t 80 link_uninit_protocol(net_protocol *_protocol) 81 { 82 link_protocol *protocol = (link_protocol *)_protocol; 83 84 if (protocol->registered_monitor) { 85 net_device_interface *interface = get_device_interface(protocol->registered_interface); 86 if (interface != NULL) { 87 unregister_device_monitor(interface->device, link_monitor_data, protocol); 88 put_device_interface(interface); 89 } 90 } 91 92 uninit_fifo(&protocol->fifo); 93 delete protocol; 94 return B_OK; 95 } 96 97 98 status_t 99 link_open(net_protocol *protocol) 100 { 101 return B_OK; 102 } 103 104 105 status_t 106 link_close(net_protocol *protocol) 107 { 108 return B_OK; 109 } 110 111 112 status_t 113 link_free(net_protocol *protocol) 114 { 115 return B_OK; 116 } 117 118 119 status_t 120 link_connect(net_protocol *protocol, const struct sockaddr *address) 121 { 122 return EOPNOTSUPP; 123 } 124 125 126 status_t 127 link_accept(net_protocol *protocol, struct net_socket **_acceptedSocket) 128 { 129 return EOPNOTSUPP; 130 } 131 132 133 status_t 134 link_control(net_protocol *_protocol, int level, int option, void *value, 135 size_t *_length) 136 { 137 link_protocol *protocol = (link_protocol *)_protocol; 138 139 switch (option) { 140 case SIOCGIFINDEX: 141 { 142 // get index of interface 143 struct ifreq request; 144 if (user_memcpy(&request, value, IF_NAMESIZE) < B_OK) 145 return B_BAD_ADDRESS; 146 147 net_device_interface *interface = get_device_interface(request.ifr_name); 148 if (interface != NULL) { 149 request.ifr_index = interface->device->index; 150 put_device_interface(interface); 151 } else 152 request.ifr_index = 0; 153 154 return user_memcpy(value, &request, sizeof(struct ifreq)); 155 } 156 case SIOCGIFNAME: 157 { 158 // get name of interface via index 159 struct ifreq request; 160 if (user_memcpy(&request, value, sizeof(struct ifreq)) < B_OK) 161 return B_BAD_ADDRESS; 162 163 net_device_interface *interface = get_device_interface(request.ifr_index); 164 if (interface != NULL) { 165 strlcpy(request.ifr_name, interface->name, IF_NAMESIZE); 166 put_device_interface(interface); 167 } else 168 return ENODEV; 169 170 return user_memcpy(value, &request, sizeof(struct ifreq)); 171 } 172 173 case SIOCGIFCOUNT: 174 { 175 // count number of interfaces 176 struct ifconf config; 177 config.ifc_value = count_device_interfaces(); 178 179 return user_memcpy(value, &config, sizeof(struct ifconf)); 180 } 181 182 case SIOCGIFCONF: 183 { 184 // retrieve available interfaces 185 struct ifconf config; 186 if (user_memcpy(&config, value, sizeof(struct ifconf)) < B_OK) 187 return B_BAD_ADDRESS; 188 189 status_t result = list_device_interfaces(config.ifc_buf, 190 (size_t *)&config.ifc_len); 191 if (result != B_OK) 192 return result; 193 194 return user_memcpy(value, &config, sizeof(struct ifconf)); 195 } 196 197 case SIOCGIFADDR: 198 { 199 // get address of interface 200 struct ifreq request; 201 if (user_memcpy(&request, value, IF_NAMESIZE) < B_OK) 202 return B_BAD_ADDRESS; 203 204 net_device_interface *interface = get_device_interface(request.ifr_name); 205 if (interface != NULL) { 206 get_device_interface_address(interface, &request.ifr_addr); 207 put_device_interface(interface); 208 } else 209 return ENODEV; 210 211 return user_memcpy(&((struct ifreq *)value)->ifr_addr, 212 &request.ifr_addr, request.ifr_addr.sa_len); 213 } 214 215 case SIOCSPACKETCAP: 216 { 217 // start packet monitoring 218 219 if (protocol->registered_monitor) 220 return B_BUSY; 221 222 struct ifreq request; 223 if (user_memcpy(&request, value, IF_NAMESIZE) < B_OK) 224 return B_BAD_ADDRESS; 225 226 net_device_interface *interface = get_device_interface(request.ifr_name); 227 status_t status; 228 if (interface != NULL) { 229 status = register_device_monitor(interface->device, 230 link_monitor_data, protocol); 231 if (status == B_OK) { 232 // we're now registered 233 strlcpy(protocol->registered_interface, request.ifr_name, IF_NAMESIZE); 234 protocol->registered_monitor = true; 235 } 236 put_device_interface(interface); 237 } else 238 status = ENODEV; 239 240 return status; 241 } 242 243 case SIOCCPACKETCAP: 244 { 245 // stop packet monitoring 246 247 if (!protocol->registered_monitor) 248 return B_BAD_VALUE; 249 250 struct ifreq request; 251 if (user_memcpy(&request, value, IF_NAMESIZE) < B_OK) 252 return B_BAD_ADDRESS; 253 254 net_device_interface *interface = get_device_interface(request.ifr_name); 255 status_t status; 256 if (interface != NULL) { 257 status = unregister_device_monitor(interface->device, 258 link_monitor_data, protocol); 259 if (status == B_OK) { 260 // we're now no longer registered 261 protocol->registered_monitor = false; 262 } 263 put_device_interface(interface); 264 } else 265 status = ENODEV; 266 267 return status; 268 } 269 } 270 271 return datalink_control(sDomain, option, value, _length); 272 } 273 274 275 status_t 276 link_bind(net_protocol *protocol, struct sockaddr *address) 277 { 278 // TODO: bind to a specific interface and ethernet type 279 return B_ERROR; 280 } 281 282 283 status_t 284 link_unbind(net_protocol *protocol, struct sockaddr *address) 285 { 286 return B_ERROR; 287 } 288 289 290 status_t 291 link_listen(net_protocol *protocol, int count) 292 { 293 return EOPNOTSUPP; 294 } 295 296 297 status_t 298 link_shutdown(net_protocol *protocol, int direction) 299 { 300 return EOPNOTSUPP; 301 } 302 303 304 status_t 305 link_send_data(net_protocol *protocol, net_buffer *buffer) 306 { 307 return B_NOT_ALLOWED; 308 } 309 310 311 status_t 312 link_send_routed_data(net_protocol *protocol, struct net_route *route, 313 net_buffer *buffer) 314 { 315 return B_NOT_ALLOWED; 316 } 317 318 319 ssize_t 320 link_send_avail(net_protocol *protocol) 321 { 322 return B_ERROR; 323 } 324 325 326 status_t 327 link_read_data(net_protocol *_protocol, size_t numBytes, uint32 flags, 328 net_buffer **_buffer) 329 { 330 link_protocol *protocol = (link_protocol *)_protocol; 331 332 dprintf("link_read is waiting for data...\n"); 333 334 net_buffer *buffer; 335 status_t status = fifo_dequeue_buffer(&protocol->fifo, 336 flags, protocol->socket->receive.timeout, &buffer); 337 if (status < B_OK) 338 return status; 339 340 if (numBytes < buffer->size) { 341 // discard any data behind the amount requested 342 gNetBufferModule.trim(buffer, numBytes); 343 } 344 345 *_buffer = buffer; 346 return B_OK; 347 } 348 349 350 ssize_t 351 link_read_avail(net_protocol *_protocol) 352 { 353 link_protocol *protocol = (link_protocol *)_protocol; 354 return protocol->fifo.current_bytes; 355 } 356 357 358 struct net_domain * 359 link_get_domain(net_protocol *protocol) 360 { 361 return sDomain; 362 } 363 364 365 size_t 366 link_get_mtu(net_protocol *protocol, const struct sockaddr *address) 367 { 368 // TODO: for now 369 return 0; 370 } 371 372 373 status_t 374 link_receive_data(net_buffer *buffer) 375 { 376 return B_ERROR; 377 } 378 379 380 status_t 381 link_error(uint32 code, net_buffer *data) 382 { 383 return B_ERROR; 384 } 385 386 387 status_t 388 link_error_reply(net_protocol *protocol, net_buffer *causedError, uint32 code, 389 void *errorData) 390 { 391 return B_ERROR; 392 } 393 394 395 static status_t 396 link_std_ops(int32 op, ...) 397 { 398 switch (op) { 399 case B_MODULE_INIT: 400 return register_domain(AF_LINK, "link", NULL, NULL, &sDomain); 401 402 case B_MODULE_UNINIT: 403 unregister_domain(sDomain); 404 return B_OK; 405 406 default: 407 return B_ERROR; 408 } 409 } 410 411 412 // #pragma mark - 413 414 415 void 416 link_init() 417 { 418 register_domain_protocols(AF_LINK, SOCK_DGRAM, 0, "network/stack/link/v1", NULL); 419 420 register_domain_datalink_protocols(AF_LINK, IFT_ETHER, 421 "network/datalink_protocols/ethernet_frame/v1", 422 NULL); 423 } 424 425 426 net_protocol_module_info gLinkModule = { 427 { 428 "network/stack/link/v1", 429 0, 430 link_std_ops 431 }, 432 link_init_protocol, 433 link_uninit_protocol, 434 link_open, 435 link_close, 436 link_free, 437 link_connect, 438 link_accept, 439 link_control, 440 link_bind, 441 link_unbind, 442 link_listen, 443 link_shutdown, 444 link_send_data, 445 link_send_routed_data, 446 link_send_avail, 447 link_read_data, 448 link_read_avail, 449 link_get_domain, 450 link_get_mtu, 451 link_receive_data, 452 link_error, 453 link_error_reply, 454 }; 455