1 /* 2 * Copyright 2006, 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 // count number of interfaces 178 struct ifconf config; 179 if (user_memcpy(&config, value, sizeof(struct ifconf)) < B_OK) 180 return B_BAD_ADDRESS; 181 182 return list_device_interfaces(config.ifc_buf, config.ifc_len); 183 } 184 185 case SIOCGIFADDR: 186 { 187 // get address of interface 188 struct ifreq request; 189 if (user_memcpy(&request, value, IF_NAMESIZE) < B_OK) 190 return B_BAD_ADDRESS; 191 192 net_device_interface *interface = get_device_interface(request.ifr_name); 193 if (interface != NULL) { 194 get_device_interface_address(interface, &request.ifr_addr); 195 put_device_interface(interface); 196 } else 197 return ENODEV; 198 199 return user_memcpy(&((struct ifreq *)value)->ifr_addr, 200 &request.ifr_addr, request.ifr_addr.sa_len); 201 } 202 203 case SIOCSPACKETCAP: 204 { 205 // start packet monitoring 206 207 if (protocol->registered_monitor) 208 return B_BUSY; 209 210 struct ifreq request; 211 if (user_memcpy(&request, value, IF_NAMESIZE) < B_OK) 212 return B_BAD_ADDRESS; 213 214 net_device_interface *interface = get_device_interface(request.ifr_name); 215 status_t status; 216 if (interface != NULL) { 217 status = register_device_monitor(interface->device, 218 link_monitor_data, protocol); 219 if (status == B_OK) { 220 // we're now registered 221 strlcpy(protocol->registered_interface, request.ifr_name, IF_NAMESIZE); 222 protocol->registered_monitor = true; 223 } 224 put_device_interface(interface); 225 } else 226 status = ENODEV; 227 228 return status; 229 } 230 231 case SIOCCPACKETCAP: 232 { 233 // stop packet monitoring 234 235 if (!protocol->registered_monitor) 236 return B_BAD_VALUE; 237 238 struct ifreq request; 239 if (user_memcpy(&request, value, IF_NAMESIZE) < B_OK) 240 return B_BAD_ADDRESS; 241 242 net_device_interface *interface = get_device_interface(request.ifr_name); 243 status_t status; 244 if (interface != NULL) { 245 status = unregister_device_monitor(interface->device, 246 link_monitor_data, protocol); 247 if (status == B_OK) { 248 // we're now no longer registered 249 protocol->registered_monitor = false; 250 } 251 put_device_interface(interface); 252 } else 253 status = ENODEV; 254 255 return status; 256 } 257 } 258 259 return datalink_control(sDomain, option, value, _length); 260 } 261 262 263 status_t 264 link_bind(net_protocol *protocol, struct sockaddr *address) 265 { 266 // TODO: bind to a specific interface and ethernet type 267 return B_ERROR; 268 } 269 270 271 status_t 272 link_unbind(net_protocol *protocol, struct sockaddr *address) 273 { 274 return B_ERROR; 275 } 276 277 278 status_t 279 link_listen(net_protocol *protocol, int count) 280 { 281 return EOPNOTSUPP; 282 } 283 284 285 status_t 286 link_shutdown(net_protocol *protocol, int direction) 287 { 288 return EOPNOTSUPP; 289 } 290 291 292 status_t 293 link_send_data(net_protocol *protocol, net_buffer *buffer) 294 { 295 return B_NOT_ALLOWED; 296 } 297 298 299 status_t 300 link_send_routed_data(net_protocol *protocol, struct net_route *route, 301 net_buffer *buffer) 302 { 303 return B_NOT_ALLOWED; 304 } 305 306 307 ssize_t 308 link_send_avail(net_protocol *protocol) 309 { 310 return B_ERROR; 311 } 312 313 314 status_t 315 link_read_data(net_protocol *_protocol, size_t numBytes, uint32 flags, 316 net_buffer **_buffer) 317 { 318 link_protocol *protocol = (link_protocol *)_protocol; 319 320 dprintf("link_read is waiting for data...\n"); 321 322 net_buffer *buffer; 323 status_t status = fifo_dequeue_buffer(&protocol->fifo, 324 flags, protocol->socket->receive.timeout, &buffer); 325 if (status < B_OK) 326 return status; 327 328 if (numBytes < buffer->size) { 329 // discard any data behind the amount requested 330 gNetBufferModule.trim(buffer, numBytes); 331 } 332 333 *_buffer = buffer; 334 return B_OK; 335 } 336 337 338 ssize_t 339 link_read_avail(net_protocol *_protocol) 340 { 341 link_protocol *protocol = (link_protocol *)_protocol; 342 return protocol->fifo.current_bytes; 343 } 344 345 346 struct net_domain * 347 link_get_domain(net_protocol *protocol) 348 { 349 return sDomain; 350 } 351 352 353 size_t 354 link_get_mtu(net_protocol *protocol, const struct sockaddr *address) 355 { 356 // TODO: for now 357 return 0; 358 } 359 360 361 status_t 362 link_receive_data(net_buffer *buffer) 363 { 364 return B_ERROR; 365 } 366 367 368 status_t 369 link_error(uint32 code, net_buffer *data) 370 { 371 return B_ERROR; 372 } 373 374 375 status_t 376 link_error_reply(net_protocol *protocol, net_buffer *causedError, uint32 code, 377 void *errorData) 378 { 379 return B_ERROR; 380 } 381 382 383 static status_t 384 link_std_ops(int32 op, ...) 385 { 386 switch (op) { 387 case B_MODULE_INIT: 388 return register_domain(AF_LINK, "link", NULL, NULL, &sDomain); 389 390 case B_MODULE_UNINIT: 391 unregister_domain(sDomain); 392 return B_OK; 393 394 default: 395 return B_ERROR; 396 } 397 } 398 399 400 // #pragma mark - 401 402 403 void 404 link_init() 405 { 406 register_domain_protocols(AF_LINK, SOCK_DGRAM, 0, "network/stack/link/v1", NULL); 407 408 register_domain_datalink_protocols(AF_LINK, IFT_ETHER, 409 "network/datalink_protocols/ethernet_frame/v1", 410 NULL); 411 } 412 413 414 net_protocol_module_info gLinkModule = { 415 { 416 "network/stack/link/v1", 417 0, 418 link_std_ops 419 }, 420 link_init_protocol, 421 link_uninit_protocol, 422 link_open, 423 link_close, 424 link_free, 425 link_connect, 426 link_accept, 427 link_control, 428 link_bind, 429 link_unbind, 430 link_listen, 431 link_shutdown, 432 link_send_data, 433 link_send_routed_data, 434 link_send_avail, 435 link_read_data, 436 link_read_avail, 437 link_get_domain, 438 link_get_mtu, 439 link_receive_data, 440 link_error, 441 link_error_reply, 442 }; 443