diff --git a/src/add-ons/kernel/network/stack/link.cpp b/src/add-ons/kernel/network/stack/link.cpp index b8a404ebf8..21919d208b 100644 --- a/src/add-ons/kernel/network/stack/link.cpp +++ b/src/add-ons/kernel/network/stack/link.cpp @@ -1,12 +1,12 @@ /* - * Copyright 2006-2008, Haiku, Inc. All Rights Reserved. + * Copyright 2006-2009, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: * Axel Dörfler, axeld@pinc-software.de */ -//! The net_protocol you talk to when using the AF_LINK protocol +//! The net_protocol one talks to when using the AF_LINK protocol #include "datalink.h" #include "domains.h" @@ -32,37 +32,37 @@ class LocalStackBundle { public: - static net_stack_module_info *Stack() { return &gNetStackModule; } - static net_buffer_module_info *Buffer() { return &gNetBufferModule; } + static net_stack_module_info* Stack() { return &gNetStackModule; } + static net_buffer_module_info* Buffer() { return &gNetBufferModule; } }; typedef DatagramSocket LocalDatagramSocket; class LinkProtocol : public net_protocol, public LocalDatagramSocket { public: - LinkProtocol(net_socket *socket); + LinkProtocol(net_socket* socket); ~LinkProtocol(); - status_t StartMonitoring(const char *); + status_t StartMonitoring(const char* deviceName); status_t StopMonitoring(); private: status_t _SocketStatus() const; status_t _Unregister(); - net_device_monitor fMonitor; - net_device_interface *fMonitoredDevice; + static status_t _MonitorData(net_device_monitor* monitor, + net_buffer* buffer); + static void _MonitorEvent(net_device_monitor* monitor, int32 event); - static status_t _MonitorData(net_device_monitor *monitor, - net_buffer *buffer); - static void _MonitorEvent(net_device_monitor *monitor, int32 event); + net_device_monitor fMonitor; + net_device_interface* fMonitoredDevice; }; -struct net_domain *sDomain; +struct net_domain* sDomain; -LinkProtocol::LinkProtocol(net_socket *socket) +LinkProtocol::LinkProtocol(net_socket* socket) : LocalDatagramSocket("packet capture", socket) { fMonitor.cookie = this; @@ -82,14 +82,14 @@ LinkProtocol::~LinkProtocol() status_t -LinkProtocol::StartMonitoring(const char *deviceName) +LinkProtocol::StartMonitoring(const char* deviceName) { MutexLocker _(fLock); if (fMonitoredDevice) return B_BUSY; - net_device_interface *interface = get_device_interface(deviceName); + net_device_interface* interface = get_device_interface(deviceName); if (interface == NULL) return ENODEV; @@ -138,16 +138,16 @@ LinkProtocol::_Unregister() status_t -LinkProtocol::_MonitorData(net_device_monitor *monitor, net_buffer *packet) +LinkProtocol::_MonitorData(net_device_monitor* monitor, net_buffer* packet) { - return ((LinkProtocol *)monitor->cookie)->SocketEnqueue(packet); + return ((LinkProtocol*)monitor->cookie)->SocketEnqueue(packet); } void -LinkProtocol::_MonitorEvent(net_device_monitor *monitor, int32 event) +LinkProtocol::_MonitorEvent(net_device_monitor* monitor, int32 event) { - LinkProtocol *protocol = (LinkProtocol *)monitor->cookie; + LinkProtocol* protocol = (LinkProtocol*)monitor->cookie; if (event == B_DEVICE_GOING_DOWN) { MutexLocker _(protocol->fLock); @@ -164,11 +164,26 @@ LinkProtocol::_MonitorEvent(net_device_monitor *monitor, int32 event) // #pragma mark - -net_protocol * -link_init_protocol(net_socket *socket) +static bool +user_request_get_device_interface(void* value, struct ifreq& request, + net_device_interface*& interface) { - LinkProtocol *protocol = new (std::nothrow) LinkProtocol(socket); - if (protocol && protocol->InitCheck() < B_OK) { + if (user_memcpy(&request, value, IF_NAMESIZE) < B_OK) + return false; + + interface = get_device_interface(request.ifr_name); + return true; +} + + +// #pragma mark - + + +net_protocol* +link_init_protocol(net_socket* socket) +{ + LinkProtocol* protocol = new (std::nothrow) LinkProtocol(socket); + if (protocol != NULL && protocol->InitCheck() < B_OK) { delete protocol; return NULL; } @@ -178,64 +193,63 @@ link_init_protocol(net_socket *socket) status_t -link_uninit_protocol(net_protocol *protocol) +link_uninit_protocol(net_protocol* protocol) { - delete (LinkProtocol *)protocol; + delete (LinkProtocol*)protocol; return B_OK; } status_t -link_open(net_protocol *protocol) +link_open(net_protocol* protocol) { return B_OK; } status_t -link_close(net_protocol *protocol) +link_close(net_protocol* protocol) { return B_OK; } status_t -link_free(net_protocol *protocol) +link_free(net_protocol* protocol) { return B_OK; } status_t -link_connect(net_protocol *protocol, const struct sockaddr *address) +link_connect(net_protocol* protocol, const struct sockaddr* address) { return EOPNOTSUPP; } status_t -link_accept(net_protocol *protocol, struct net_socket **_acceptedSocket) +link_accept(net_protocol* protocol, struct net_socket** _acceptedSocket) { return EOPNOTSUPP; } status_t -link_control(net_protocol *_protocol, int level, int option, void *value, - size_t *_length) +link_control(net_protocol* _protocol, int level, int option, void* value, + size_t* _length) { - LinkProtocol *protocol = (LinkProtocol *)_protocol; + LinkProtocol* protocol = (LinkProtocol*)_protocol; switch (option) { case SIOCGIFINDEX: { // get index of interface + net_device_interface* interface; struct ifreq request; - if (user_memcpy(&request, value, IF_NAMESIZE) < B_OK) + if (!user_request_get_device_interface(value, request, interface)) return B_BAD_ADDRESS; - net_device_interface *interface - = get_device_interface(request.ifr_name); if (interface != NULL) { request.ifr_index = interface->device->index; put_device_interface(interface); @@ -251,14 +265,14 @@ link_control(net_protocol *_protocol, int level, int option, void *value, if (user_memcpy(&request, value, sizeof(struct ifreq)) < B_OK) return B_BAD_ADDRESS; - net_device_interface *interface + net_device_interface* interface = get_device_interface(request.ifr_index); - if (interface != NULL) { - strlcpy(request.ifr_name, interface->device->name, IF_NAMESIZE); - put_device_interface(interface); - } else + if (interface == NULL) return ENODEV; + strlcpy(request.ifr_name, interface->device->name, IF_NAMESIZE); + put_device_interface(interface); + return user_memcpy(value, &request, sizeof(struct ifreq)); } @@ -279,7 +293,7 @@ link_control(net_protocol *_protocol, int level, int option, void *value, return B_BAD_ADDRESS; status_t result = list_device_interfaces(config.ifc_buf, - (size_t *)&config.ifc_len); + (size_t*)&config.ifc_len); if (result != B_OK) return result; @@ -289,22 +303,39 @@ link_control(net_protocol *_protocol, int level, int option, void *value, case SIOCGIFADDR: { // get address of interface + net_device_interface* interface; struct ifreq request; - if (user_memcpy(&request, value, IF_NAMESIZE) < B_OK) + if (!user_request_get_device_interface(value, request, interface)) return B_BAD_ADDRESS; - net_device_interface *interface - = get_device_interface(request.ifr_name); - if (interface != NULL) { - get_device_interface_address(interface, &request.ifr_addr); - put_device_interface(interface); - } else + if (interface == NULL) return ENODEV; - return user_memcpy(&((struct ifreq *)value)->ifr_addr, + get_device_interface_address(interface, &request.ifr_addr); + put_device_interface(interface); + + return user_memcpy(&((struct ifreq*)value)->ifr_addr, &request.ifr_addr, request.ifr_addr.sa_len); } + case SIOCGIFFLAGS: + { + // get flags of interface + net_device_interface* interface; + struct ifreq request; + if (!user_request_get_device_interface(value, request, interface)) + return B_BAD_ADDRESS; + + if (interface == NULL) + return ENODEV; + + request.ifr_flags = interface->device->flags; + put_device_interface(interface); + + return user_memcpy(&((struct ifreq*)value)->ifr_flags, + &request.ifr_flags, sizeof(request.ifr_flags)); + } + case SIOCSPACKETCAP: { struct ifreq request; @@ -323,8 +354,8 @@ link_control(net_protocol *_protocol, int level, int option, void *value, status_t -link_getsockopt(net_protocol *protocol, int level, int option, void *value, - int *length) +link_getsockopt(net_protocol* protocol, int level, int option, void* value, + int* length) { if (protocol->next != NULL) { return protocol->next->module->getsockopt(protocol, level, option, @@ -337,8 +368,8 @@ link_getsockopt(net_protocol *protocol, int level, int option, void *value, status_t -link_setsockopt(net_protocol *protocol, int level, int option, - const void *value, int length) +link_setsockopt(net_protocol* protocol, int level, int option, + const void* value, int length) { if (protocol->next != NULL) { return protocol->next->module->setsockopt(protocol, level, option, @@ -351,7 +382,7 @@ link_setsockopt(net_protocol *protocol, int level, int option, status_t -link_bind(net_protocol *protocol, const struct sockaddr *address) +link_bind(net_protocol* protocol, const struct sockaddr* address) { // TODO: bind to a specific interface and ethernet type return B_ERROR; @@ -359,72 +390,72 @@ link_bind(net_protocol *protocol, const struct sockaddr *address) status_t -link_unbind(net_protocol *protocol, struct sockaddr *address) +link_unbind(net_protocol* protocol, struct sockaddr* address) { return B_ERROR; } status_t -link_listen(net_protocol *protocol, int count) +link_listen(net_protocol* protocol, int count) { return EOPNOTSUPP; } status_t -link_shutdown(net_protocol *protocol, int direction) +link_shutdown(net_protocol* protocol, int direction) { return EOPNOTSUPP; } status_t -link_send_data(net_protocol *protocol, net_buffer *buffer) +link_send_data(net_protocol* protocol, net_buffer* buffer) { return B_NOT_ALLOWED; } status_t -link_send_routed_data(net_protocol *protocol, struct net_route *route, - net_buffer *buffer) +link_send_routed_data(net_protocol* protocol, struct net_route* route, + net_buffer* buffer) { return B_NOT_ALLOWED; } ssize_t -link_send_avail(net_protocol *protocol) +link_send_avail(net_protocol* protocol) { return B_ERROR; } status_t -link_read_data(net_protocol *protocol, size_t numBytes, uint32 flags, - net_buffer **_buffer) +link_read_data(net_protocol* protocol, size_t numBytes, uint32 flags, + net_buffer** _buffer) { - return ((LinkProtocol *)protocol)->SocketDequeue(flags, _buffer); + return ((LinkProtocol*)protocol)->SocketDequeue(flags, _buffer); } ssize_t -link_read_avail(net_protocol *protocol) +link_read_avail(net_protocol* protocol) { - return ((LinkProtocol *)protocol)->AvailableData(); + return ((LinkProtocol*)protocol)->AvailableData(); } -struct net_domain * -link_get_domain(net_protocol *protocol) +struct net_domain* +link_get_domain(net_protocol* protocol) { return sDomain; } size_t -link_get_mtu(net_protocol *protocol, const struct sockaddr *address) +link_get_mtu(net_protocol* protocol, const struct sockaddr* address) { // TODO: for now return 0; @@ -432,22 +463,22 @@ link_get_mtu(net_protocol *protocol, const struct sockaddr *address) status_t -link_receive_data(net_buffer *buffer) +link_receive_data(net_buffer* buffer) { return B_ERROR; } status_t -link_error(uint32 code, net_buffer *data) +link_error(uint32 code, net_buffer* data) { return B_ERROR; } status_t -link_error_reply(net_protocol *protocol, net_buffer *causedError, uint32 code, - void *errorData) +link_error_reply(net_protocol* protocol, net_buffer* causedError, uint32 code, + void* errorData) { return B_ERROR; }