* You can now use SIOCGIFFLAGS on the AF_LINK level as well.

* Cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29231 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2009-02-16 11:05:25 +00:00
parent 1a905a762a
commit 86a0cf15e4

View File

@ -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<MutexLocking, LocalStackBundle> 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;
}