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