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