* Changed the way the socket functions work:
- The net_stack driver is no longer used. Instead we have a kernel
module which is directly used by syscall implementations in the
kernel. I.e. we no longer tunnel those functions through ioctls, but
have normal syscalls.
- Removed the superfluous net starter module.
- Implemented the FDTYPE_SOCKET type file_descriptors, that is sockets
are no longer vnode based.
- Adjusted libnetwork (the socket function implementations)
accordingly.
- Adjusted netstat accordingly.
* Socket module:
- Implemented socketpair().
- Added "kernel" parameter to the control hook. Quite a few more hooks
would actually need the parameter, but I didn't change those yet,
since that would probably also require changes to the protocol
module interface.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24908 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -125,7 +125,7 @@ BEOS_ADD_ONS_DRIVERS_GRAPHICS = $(X86_ONLY)radeon $(X86_ONLY)nvidia
|
||||
;
|
||||
BEOS_ADD_ONS_DRIVERS_MIDI = emuxki ;
|
||||
BEOS_ADD_ONS_DRIVERS_NET = $(X86_ONLY)3com etherpci $(X86_ONLY)ipro1000
|
||||
$(X86_ONLY)rtl8139 rtl8169 sis900 $(X86_ONLY)via_rhine wb840 net_stack
|
||||
$(X86_ONLY)rtl8139 rtl8169 sis900 $(X86_ONLY)via_rhine wb840
|
||||
$(X86_ONLY)ipro100 $(X86_ONLY)nforce #vlance
|
||||
$(X86_ONLY)marvell_yukon $(X86_ONLY)syskonnect
|
||||
$(GPL_ONLY)bcm440x $(GPL_ONLY)bcm570x
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <DiskDeviceDefs.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -23,6 +24,7 @@ struct fd_info;
|
||||
struct fd_set;
|
||||
struct fs_info;
|
||||
struct iovec;
|
||||
struct net_stat;
|
||||
struct pollfd;
|
||||
struct rlimit;
|
||||
struct sigaction;
|
||||
@@ -222,6 +224,44 @@ extern status_t _kern_unlock_node(int fd);
|
||||
extern status_t _kern_get_next_fd_info(team_id team, uint32 *_cookie,
|
||||
struct fd_info *info, size_t infoSize);
|
||||
|
||||
// socket functions
|
||||
extern int _kern_socket(int family, int type, int protocol);
|
||||
extern status_t _kern_bind(int socket, const struct sockaddr *address,
|
||||
socklen_t addressLength);
|
||||
extern status_t _kern_shutdown_socket(int socket, int how);
|
||||
extern status_t _kern_connect(int socket, const struct sockaddr *address,
|
||||
socklen_t addressLength);
|
||||
extern status_t _kern_listen(int socket, int backlog);
|
||||
extern int _kern_accept(int socket, struct sockaddr *address,
|
||||
socklen_t *_addressLength);
|
||||
extern ssize_t _kern_recv(int socket, void *data, size_t length,
|
||||
int flags);
|
||||
extern ssize_t _kern_recvfrom(int socket, void *data, size_t length,
|
||||
int flags, struct sockaddr *address,
|
||||
socklen_t *_addressLength);
|
||||
extern ssize_t _kern_recvmsg(int socket, struct msghdr *message,
|
||||
int flags);
|
||||
extern ssize_t _kern_send(int socket, const void *data, size_t length,
|
||||
int flags);
|
||||
extern ssize_t _kern_sendto(int socket, const void *data, size_t length,
|
||||
int flags, const struct sockaddr *address,
|
||||
socklen_t addressLength);
|
||||
extern ssize_t _kern_sendmsg(int socket, const struct msghdr *message,
|
||||
int flags);
|
||||
extern status_t _kern_getsockopt(int socket, int level, int option,
|
||||
void *value, socklen_t *_length);
|
||||
extern status_t _kern_setsockopt(int socket, int level, int option,
|
||||
const void *value, socklen_t length);
|
||||
extern status_t _kern_getpeername(int socket, struct sockaddr *address,
|
||||
socklen_t *_addressLength);
|
||||
extern status_t _kern_getsockname(int socket, struct sockaddr *address,
|
||||
socklen_t *_addressLength);
|
||||
extern int _kern_sockatmark(int socket);
|
||||
extern status_t _kern_socketpair(int family, int type, int protocol,
|
||||
int *socketVector);
|
||||
extern status_t _kern_get_next_socket_stat(int family, uint32 *cookie,
|
||||
struct net_stat *stat);
|
||||
|
||||
// node monitor functions
|
||||
extern status_t _kern_stop_notifying(port_id port, uint32 token);
|
||||
extern status_t _kern_start_watching(dev_t device, ino_t node, uint32 flags,
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#include <dirent.h>
|
||||
#include <signal.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/select.h>
|
||||
|
||||
@@ -28,12 +29,13 @@
|
||||
|
||||
#define B_UNMOUNT_BUSY_PARTITION 0x80000000
|
||||
|
||||
struct kernel_args;
|
||||
struct vm_cache;
|
||||
struct file_descriptor;
|
||||
struct kernel_args;
|
||||
struct net_stat;
|
||||
struct pollfd;
|
||||
struct selectsync;
|
||||
struct select_info;
|
||||
struct pollfd;
|
||||
struct vm_cache;
|
||||
struct vnode;
|
||||
|
||||
|
||||
@@ -197,7 +199,7 @@ status_t _user_change_root(const char *path);
|
||||
int _user_open_query(dev_t device, const char *query, size_t queryLength, uint32 flags,
|
||||
port_id port, int32 token);
|
||||
|
||||
/* fd user prototypes (implementation located in fd.c) */
|
||||
/* fd user prototypes (implementation located in fd.cpp) */
|
||||
extern ssize_t _user_read(int fd, off_t pos, void *buffer, size_t bufferSize);
|
||||
extern ssize_t _user_readv(int fd, off_t pos, const iovec *vecs, size_t count);
|
||||
extern ssize_t _user_write(int fd, off_t pos, const void *buffer, size_t bufferSize);
|
||||
@@ -211,6 +213,44 @@ extern int _user_dup2(int ofd, int nfd);
|
||||
extern status_t _user_lock_node(int fd);
|
||||
extern status_t _user_unlock_node(int fd);
|
||||
|
||||
/* socket user prototypes (implementation in socket.cpp) */
|
||||
extern int _user_socket(int family, int type, int protocol);
|
||||
extern status_t _user_bind(int socket, const struct sockaddr *address,
|
||||
socklen_t addressLength);
|
||||
extern status_t _user_shutdown_socket(int socket, int how);
|
||||
extern status_t _user_connect(int socket, const struct sockaddr *address,
|
||||
socklen_t addressLength);
|
||||
extern status_t _user_listen(int socket, int backlog);
|
||||
extern int _user_accept(int socket, struct sockaddr *address,
|
||||
socklen_t *_addressLength);
|
||||
extern ssize_t _user_recv(int socket, void *data, size_t length,
|
||||
int flags);
|
||||
extern ssize_t _user_recvfrom(int socket, void *data, size_t length,
|
||||
int flags, struct sockaddr *address,
|
||||
socklen_t *_addressLength);
|
||||
extern ssize_t _user_recvmsg(int socket, struct msghdr *message,
|
||||
int flags);
|
||||
extern ssize_t _user_send(int socket, const void *data, size_t length,
|
||||
int flags);
|
||||
extern ssize_t _user_sendto(int socket, const void *data, size_t length,
|
||||
int flags, const struct sockaddr *address,
|
||||
socklen_t addressLength);
|
||||
extern ssize_t _user_sendmsg(int socket, const struct msghdr *message,
|
||||
int flags);
|
||||
extern status_t _user_getsockopt(int socket, int level, int option,
|
||||
void *value, socklen_t *_length);
|
||||
extern status_t _user_setsockopt(int socket, int level, int option,
|
||||
const void *value, socklen_t length);
|
||||
extern status_t _user_getpeername(int socket, struct sockaddr *address,
|
||||
socklen_t *_addressLength);
|
||||
extern status_t _user_getsockname(int socket, struct sockaddr *address,
|
||||
socklen_t *_addressLength);
|
||||
extern int _user_sockatmark(int socket);
|
||||
extern status_t _user_socketpair(int family, int type, int protocol,
|
||||
int *socketVector);
|
||||
extern status_t _user_get_next_socket_stat(int family, uint32 *cookie,
|
||||
struct net_stat *stat);
|
||||
|
||||
/* vfs entry points... */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -53,7 +53,7 @@ struct net_socket_module_info {
|
||||
status_t (*writev)(net_socket *socket, const iovec *vecs,
|
||||
size_t vecCount, size_t *_length);
|
||||
status_t (*control)(net_socket *socket, int32 op, void *data,
|
||||
size_t length);
|
||||
size_t length, bool kernel);
|
||||
|
||||
ssize_t (*read_avail)(net_socket *socket);
|
||||
ssize_t (*send_avail)(net_socket *socket);
|
||||
@@ -81,7 +81,7 @@ struct net_socket_module_info {
|
||||
|
||||
// notifications
|
||||
status_t (*request_notification)(net_socket *socket, uint8 event,
|
||||
uint32 ref, struct selectsync *sync);
|
||||
struct selectsync *sync);
|
||||
status_t (*cancel_notification)(net_socket *socket, uint8 event,
|
||||
struct selectsync *sync);
|
||||
status_t (*notify)(net_socket *socket, uint8 event, int32 value);
|
||||
@@ -107,6 +107,8 @@ struct net_socket_module_info {
|
||||
int (*setsockopt)(net_socket *socket, int level, int option,
|
||||
const void *optionValue, int optionLength);
|
||||
int (*shutdown)(net_socket *socket, int direction);
|
||||
status_t (*socketpair)(int family, int type, int protocol,
|
||||
net_socket* _sockets[2]);
|
||||
};
|
||||
|
||||
#endif // NET_SOCKET_H
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2008, Haiku, Inc. All Rights Reserved.
|
||||
* This file may be used under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef NET_STACK_INTERFACE_H
|
||||
#define NET_STACK_INTERFACE_H
|
||||
|
||||
|
||||
#include <sys/socket.h>
|
||||
|
||||
|
||||
// name of the kernel stack interface
|
||||
#define NET_STACK_INTERFACE_MODULE_NAME "network/stack/kernel_interface/v1"
|
||||
|
||||
// name of the userland stack interface
|
||||
#define NET_STACK_USERLAND_INTERFACE_MODULE_NAME \
|
||||
"network/stack/userland_interface/v1"
|
||||
|
||||
|
||||
struct net_socket;
|
||||
struct net_stat;
|
||||
|
||||
|
||||
struct net_stack_interface_module_info {
|
||||
module_info info;
|
||||
|
||||
status_t (*open)(int family, int type, int protocol, net_socket** _socket);
|
||||
status_t (*close)(net_socket* socket);
|
||||
status_t (*free)(net_socket* socket);
|
||||
|
||||
status_t (*bind)(net_socket* socket, const struct sockaddr* address,
|
||||
socklen_t addressLength, bool kernel);
|
||||
status_t (*shutdown)(net_socket* socket, int how);
|
||||
status_t (*connect)(net_socket* socket, const struct sockaddr* address,
|
||||
socklen_t addressLength, bool kernel);
|
||||
status_t (*listen)(net_socket* socket, int backlog);
|
||||
status_t (*accept)(net_socket* socket, struct sockaddr* address,
|
||||
socklen_t* _addressLength, net_socket** _acceptedSocket);
|
||||
|
||||
ssize_t (*recv)(net_socket* socket, void* data, size_t length, int flags,
|
||||
bool kernel);
|
||||
ssize_t (*recvfrom)(net_socket* socket, void* data, size_t length,
|
||||
int flags, struct sockaddr* address,
|
||||
socklen_t* _addressLength, bool kernel);
|
||||
ssize_t (*recvmsg)(net_socket* socket, struct msghdr* message, int flags,
|
||||
bool kernel);
|
||||
|
||||
ssize_t (*send)(net_socket* socket, const void* data, size_t length,
|
||||
int flags, bool kernel);
|
||||
ssize_t (*sendto)(net_socket* socket, const void* data, size_t length,
|
||||
int flags, const struct sockaddr* address,
|
||||
socklen_t addressLength, bool kernel);
|
||||
ssize_t (*sendmsg)(net_socket* socket, const struct msghdr* message,
|
||||
int flags, bool kernel);
|
||||
|
||||
status_t (*getsockopt)(net_socket* socket, int level, int option,
|
||||
void* value, socklen_t* _length);
|
||||
status_t (*setsockopt)(net_socket* socket, int level, int option,
|
||||
const void* value, socklen_t length);
|
||||
|
||||
status_t (*getpeername)(net_socket* socket, struct sockaddr* address,
|
||||
socklen_t* _addressLength);
|
||||
status_t (*getsockname)(net_socket* socket, struct sockaddr* address,
|
||||
socklen_t* _addressLength);
|
||||
|
||||
int (*sockatmark)(net_socket* socket);
|
||||
|
||||
status_t (*socketpair)(int family, int type, int protocol,
|
||||
net_socket* _sockets[2]);
|
||||
|
||||
status_t (*ioctl)(net_socket* socket, uint32 op, void *buffer,
|
||||
size_t length, bool kernel);
|
||||
status_t (*select)(net_socket* socket, uint8 event,
|
||||
struct selectsync *sync);
|
||||
status_t (*deselect)(net_socket* socket, uint8 event,
|
||||
struct selectsync *sync);
|
||||
|
||||
status_t (*get_next_socket_stat)(int family, uint32 *cookie,
|
||||
struct net_stat *stat);
|
||||
};
|
||||
|
||||
|
||||
#endif // NET_STACK_INTERFACE_H
|
||||
@@ -24,6 +24,7 @@ KernelAddon stack :
|
||||
radix.c
|
||||
routes.cpp
|
||||
stack.cpp
|
||||
stack_interface.cpp
|
||||
utility.cpp
|
||||
;
|
||||
|
||||
|
||||
@@ -270,7 +270,7 @@ create_interface(net_domain *domain, const char *name, const char *baseName,
|
||||
// Grab a reference to the networking stack, to make sure it won't be
|
||||
// unloaded as long as an interface exists
|
||||
module_info *module;
|
||||
get_module(NET_STARTER_MODULE_NAME, &module);
|
||||
get_module(gNetStackInterfaceModule.info.name, &module);
|
||||
|
||||
*_interface = interface;
|
||||
return B_OK;
|
||||
@@ -320,7 +320,7 @@ delete_interface(net_interface_private *interface)
|
||||
|
||||
// Release reference of the stack - at this point, our stack may be unloaded
|
||||
// if no other interfaces or sockets are left
|
||||
put_module(NET_STARTER_MODULE_NAME);
|
||||
put_module(gNetStackInterfaceModule.info.name);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -9,21 +9,26 @@
|
||||
|
||||
#include "stack_private.h"
|
||||
|
||||
#include <net_protocol.h>
|
||||
#include <net_stack.h>
|
||||
#include <net_stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <Drivers.h>
|
||||
#include <KernelExport.h>
|
||||
#include <Select.h>
|
||||
#include <team.h>
|
||||
#include <util/AutoLock.h>
|
||||
#include <util/list.h>
|
||||
#include <fs/select_sync_pool.h>
|
||||
|
||||
#include <new>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
#include <fs/select_sync_pool.h>
|
||||
#include <kernel.h>
|
||||
|
||||
#include <net_protocol.h>
|
||||
#include <net_stack.h>
|
||||
#include <net_stat.h>
|
||||
|
||||
|
||||
struct net_socket_private : net_socket {
|
||||
@@ -42,6 +47,8 @@ struct net_socket_private : net_socket {
|
||||
void socket_delete(net_socket *socket);
|
||||
int socket_bind(net_socket *socket, const struct sockaddr *address,
|
||||
socklen_t addressLength);
|
||||
int socket_setsockopt(net_socket *socket, int level, int option,
|
||||
const void *value, int length);
|
||||
|
||||
|
||||
struct list sSocketList;
|
||||
@@ -236,8 +243,37 @@ socket_writev(net_socket *socket, const iovec *vecs, size_t vecCount,
|
||||
|
||||
|
||||
status_t
|
||||
socket_control(net_socket *socket, int32 op, void *data, size_t length)
|
||||
socket_control(net_socket *socket, int32 op, void *data, size_t length,
|
||||
bool kernel)
|
||||
{
|
||||
switch (op) {
|
||||
case FIONBIO:
|
||||
{
|
||||
if (data == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
int value;
|
||||
if (kernel) {
|
||||
value = *(int*)data;
|
||||
} else {
|
||||
if (!IS_USER_ADDRESS(data)
|
||||
|| user_memcpy(&value, data, sizeof(int)) != B_OK) {
|
||||
return B_BAD_ADDRESS;
|
||||
}
|
||||
}
|
||||
return socket_setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &value,
|
||||
sizeof(int));
|
||||
}
|
||||
|
||||
case B_SET_BLOCKING_IO:
|
||||
case B_SET_NONBLOCKING_IO:
|
||||
{
|
||||
int value = op == B_SET_NONBLOCKING_IO;
|
||||
return socket_setsockopt(socket, SOL_SOCKET, SO_NONBLOCK, &value,
|
||||
sizeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
return socket->first_info->control(socket->first_protocol,
|
||||
LEVEL_DRIVER_IOCTL, op, data, &length);
|
||||
}
|
||||
@@ -499,8 +535,7 @@ socket_connected(net_socket *socket)
|
||||
|
||||
|
||||
status_t
|
||||
socket_request_notification(net_socket *_socket, uint8 event, uint32 ref,
|
||||
selectsync *sync)
|
||||
socket_request_notification(net_socket *_socket, uint8 event, selectsync *sync)
|
||||
{
|
||||
net_socket_private *socket = (net_socket_private *)_socket;
|
||||
|
||||
@@ -1177,6 +1212,59 @@ socket_shutdown(net_socket *socket, int direction)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
socket_socketpair(int family, int type, int protocol, net_socket* sockets[2])
|
||||
{
|
||||
sockets[0] = NULL;
|
||||
sockets[1] = NULL;
|
||||
|
||||
// create sockets
|
||||
status_t error = socket_open(family, type, protocol, &sockets[0]);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
if (error == B_OK)
|
||||
error = socket_open(family, type, protocol, &sockets[1]);
|
||||
|
||||
// bind one
|
||||
if (error == B_OK)
|
||||
error = socket_bind(sockets[0], NULL, 0);
|
||||
|
||||
// start listening
|
||||
if (error == B_OK)
|
||||
error = socket_listen(sockets[0], 1);
|
||||
|
||||
// connect them
|
||||
if (error == B_OK) {
|
||||
error = socket_connect(sockets[1], (sockaddr*)&sockets[0]->address,
|
||||
sockets[0]->address.ss_len);
|
||||
}
|
||||
|
||||
// accept a socket
|
||||
net_socket* acceptedSocket = NULL;
|
||||
if (error == B_OK)
|
||||
error = socket_accept(sockets[0], NULL, NULL, &acceptedSocket);
|
||||
|
||||
if (error == B_OK) {
|
||||
// everything worked: close the listener socket
|
||||
socket_close(sockets[0]);
|
||||
socket_free(sockets[0]);
|
||||
sockets[0] = acceptedSocket;
|
||||
} else {
|
||||
// close sockets on error
|
||||
for (int i = 0; i < 2; i++) {
|
||||
if (sockets[i] != NULL) {
|
||||
socket_close(sockets[i]);
|
||||
socket_free(sockets[i]);
|
||||
sockets[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
@@ -1254,5 +1342,6 @@ net_socket_module_info gNetSocketModule = {
|
||||
socket_send,
|
||||
socket_setsockopt,
|
||||
socket_shutdown,
|
||||
socket_socketpair
|
||||
};
|
||||
|
||||
|
||||
@@ -737,7 +737,7 @@ scan_modules(const char *path)
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
status_t
|
||||
init_stack()
|
||||
{
|
||||
status_t status = init_domains();
|
||||
@@ -858,21 +858,6 @@ uninit_stack()
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
starter_std_ops(int32 op, ...)
|
||||
{
|
||||
switch (op) {
|
||||
case B_MODULE_INIT:
|
||||
return init_stack();
|
||||
case B_MODULE_UNINIT:
|
||||
return uninit_stack();
|
||||
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
stack_std_ops(int32 op, ...)
|
||||
{
|
||||
@@ -938,18 +923,12 @@ net_stack_module_info gNetStackModule = {
|
||||
restore_syscall_restart_timeout,
|
||||
};
|
||||
|
||||
static module_info sNetStarterModule = {
|
||||
NET_STARTER_MODULE_NAME,
|
||||
0,
|
||||
starter_std_ops
|
||||
};
|
||||
|
||||
module_info *modules[] = {
|
||||
(module_info *)&gNetStackModule,
|
||||
(module_info *)&sNetStarterModule,
|
||||
(module_info *)&gNetBufferModule,
|
||||
(module_info *)&gNetSocketModule,
|
||||
(module_info *)&gNetDatalinkModule,
|
||||
(module_info *)&gLinkModule,
|
||||
(module_info *)&gNetStackInterfaceModule,
|
||||
NULL
|
||||
};
|
||||
|
||||
@@ -0,0 +1,306 @@
|
||||
|
||||
|
||||
|
||||
#include "stack_private.h"
|
||||
|
||||
|
||||
/* Interface module providing networking to the kernel.
|
||||
*/
|
||||
|
||||
|
||||
static status_t
|
||||
stack_interface_open(int family, int type, int protocol, net_socket** _socket)
|
||||
{
|
||||
return gNetSocketModule.open_socket(family, type, protocol, _socket);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
stack_interface_close(net_socket* socket)
|
||||
{
|
||||
return gNetSocketModule.close(socket);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
stack_interface_free(net_socket* socket)
|
||||
{
|
||||
return gNetSocketModule.free(socket);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
stack_interface_bind(net_socket* socket, const struct sockaddr* address,
|
||||
socklen_t addressLength, bool kernel)
|
||||
{
|
||||
// TODO: Pass kernel flag!
|
||||
return gNetSocketModule.bind(socket, address, addressLength);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
stack_interface_shutdown(net_socket* socket, int how)
|
||||
{
|
||||
return gNetSocketModule.shutdown(socket, how);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
stack_interface_connect(net_socket* socket, const struct sockaddr* address,
|
||||
socklen_t addressLength, bool kernel)
|
||||
{
|
||||
// TODO: Pass kernel flag!
|
||||
return gNetSocketModule.connect(socket, address, addressLength);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
stack_interface_listen(net_socket* socket, int backlog)
|
||||
{
|
||||
return gNetSocketModule.listen(socket, backlog);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
stack_interface_accept(net_socket* socket, struct sockaddr* address,
|
||||
socklen_t* _addressLength, net_socket** _acceptedSocket)
|
||||
{
|
||||
return gNetSocketModule.accept(socket, address, _addressLength,
|
||||
_acceptedSocket);
|
||||
}
|
||||
|
||||
|
||||
static ssize_t
|
||||
stack_interface_recv(net_socket* socket, void* data, size_t length, int flags,
|
||||
bool kernel)
|
||||
{
|
||||
// TODO: Pass kernel flag!
|
||||
return gNetSocketModule.receive(socket, NULL, data, length, flags);
|
||||
}
|
||||
|
||||
|
||||
static ssize_t
|
||||
stack_interface_recvfrom(net_socket* socket, void* data, size_t length,
|
||||
int flags, struct sockaddr* address, socklen_t* _addressLength, bool kernel)
|
||||
{
|
||||
msghdr message;
|
||||
iovec vecs[1] = { { data, length } };
|
||||
message.msg_name = address;
|
||||
message.msg_namelen = *_addressLength;
|
||||
message.msg_iov = vecs;
|
||||
message.msg_iovlen = 1;
|
||||
message.msg_control = NULL;
|
||||
message.msg_controllen = 0;
|
||||
message.msg_flags = 0;
|
||||
|
||||
// TODO: Pass kernel flag!
|
||||
status_t error = gNetSocketModule.receive(socket, &message, data, length,
|
||||
flags);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
|
||||
*_addressLength = message.msg_namelen;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
static ssize_t
|
||||
stack_interface_recvmsg(net_socket* socket, struct msghdr* message, int flags,
|
||||
bool kernel)
|
||||
{
|
||||
void* buffer = NULL;
|
||||
size_t len = 0;
|
||||
if (message->msg_iovlen > 0) {
|
||||
buffer = message->msg_iov[0].iov_base;
|
||||
len = message->msg_iov[0].iov_len;
|
||||
}
|
||||
|
||||
// TODO: Pass kernel flag!
|
||||
return gNetSocketModule.receive(socket, message, buffer, len, flags);
|
||||
}
|
||||
|
||||
|
||||
static ssize_t
|
||||
stack_interface_send(net_socket* socket, const void* data, size_t length,
|
||||
int flags, bool kernel)
|
||||
{
|
||||
// TODO: Pass kernel flag!
|
||||
return gNetSocketModule.send(socket, NULL, data, length, flags);
|
||||
}
|
||||
|
||||
|
||||
static ssize_t
|
||||
stack_interface_sendto(net_socket* socket, const void* data, size_t length,
|
||||
int flags, const struct sockaddr* address, socklen_t addressLength,
|
||||
bool kernel)
|
||||
{
|
||||
msghdr message;
|
||||
iovec vecs[1] = { { (void*)data, length } };
|
||||
message.msg_name = (void*)address;
|
||||
message.msg_namelen = addressLength;
|
||||
message.msg_iov = vecs;
|
||||
message.msg_iovlen = 1;
|
||||
message.msg_control = NULL;
|
||||
message.msg_controllen = 0;
|
||||
message.msg_flags = 0;
|
||||
|
||||
// TODO: Pass kernel flag!
|
||||
return gNetSocketModule.send(socket, &message, data, length, flags);
|
||||
}
|
||||
|
||||
|
||||
static ssize_t
|
||||
stack_interface_sendmsg(net_socket* socket, const struct msghdr* message,
|
||||
int flags, bool kernel)
|
||||
{
|
||||
void* buffer = NULL;
|
||||
size_t len = 0;
|
||||
if (message->msg_iovlen > 0) {
|
||||
buffer = message->msg_iov[0].iov_base;
|
||||
len = message->msg_iov[0].iov_len;
|
||||
}
|
||||
|
||||
// TODO: Pass kernel flag!
|
||||
return gNetSocketModule.send(socket, (msghdr*)message, buffer, len, flags);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
stack_interface_getsockopt(net_socket* socket, int level, int option,
|
||||
void* value, socklen_t* _length)
|
||||
{
|
||||
int length = *_length;
|
||||
status_t error = gNetSocketModule.getsockopt(socket, level, option, value,
|
||||
&length);
|
||||
*_length = length;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
stack_interface_setsockopt(net_socket* socket, int level, int option,
|
||||
const void* value, socklen_t length)
|
||||
{
|
||||
return gNetSocketModule.setsockopt(socket, level, option, value, length);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
stack_interface_getpeername(net_socket* socket, struct sockaddr* address,
|
||||
socklen_t* _addressLength)
|
||||
{
|
||||
return gNetSocketModule.getpeername(socket, address, _addressLength);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
stack_interface_getsockname(net_socket* socket, struct sockaddr* address,
|
||||
socklen_t* _addressLength)
|
||||
{
|
||||
return gNetSocketModule.getsockname(socket, address, _addressLength);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
stack_interface_sockatmark(net_socket* socket)
|
||||
{
|
||||
// TODO:...
|
||||
return B_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
stack_interface_socketpair(int family, int type, int protocol,
|
||||
net_socket* _sockets[2])
|
||||
{
|
||||
return gNetSocketModule.socketpair(family, type, protocol, _sockets);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
stack_interface_ioctl(net_socket* socket, uint32 op, void *buffer,
|
||||
size_t length, bool kernel)
|
||||
{
|
||||
return gNetSocketModule.control(socket, op, buffer, length, kernel);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
stack_interface_select(net_socket* socket, uint8 event, struct selectsync *sync)
|
||||
{
|
||||
return gNetSocketModule.request_notification(socket, event, sync);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
stack_interface_deselect(net_socket* socket, uint8 event,
|
||||
struct selectsync *sync)
|
||||
{
|
||||
return gNetSocketModule.cancel_notification(socket, event, sync);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
stack_interface_get_next_socket_stat(int family, uint32 *cookie,
|
||||
struct net_stat *stat)
|
||||
{
|
||||
return gNetSocketModule.get_next_stat(cookie, family, stat);
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
stack_interface_std_ops(int32 op, ...)
|
||||
{
|
||||
switch (op) {
|
||||
case B_MODULE_INIT:
|
||||
return init_stack();
|
||||
case B_MODULE_UNINIT:
|
||||
return uninit_stack();
|
||||
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
net_stack_interface_module_info gNetStackInterfaceModule = {
|
||||
{
|
||||
NET_STACK_INTERFACE_MODULE_NAME,
|
||||
0,
|
||||
stack_interface_std_ops
|
||||
},
|
||||
|
||||
&stack_interface_open,
|
||||
&stack_interface_close,
|
||||
&stack_interface_free,
|
||||
|
||||
&stack_interface_bind,
|
||||
&stack_interface_shutdown,
|
||||
&stack_interface_connect,
|
||||
&stack_interface_listen,
|
||||
&stack_interface_accept,
|
||||
|
||||
&stack_interface_recv,
|
||||
&stack_interface_recvfrom,
|
||||
&stack_interface_recvmsg,
|
||||
|
||||
&stack_interface_send,
|
||||
&stack_interface_sendto,
|
||||
&stack_interface_sendmsg,
|
||||
|
||||
&stack_interface_getsockopt,
|
||||
&stack_interface_setsockopt,
|
||||
|
||||
&stack_interface_getpeername,
|
||||
&stack_interface_getsockname,
|
||||
|
||||
&stack_interface_sockatmark,
|
||||
|
||||
&stack_interface_socketpair,
|
||||
|
||||
&stack_interface_ioctl,
|
||||
&stack_interface_select,
|
||||
&stack_interface_deselect,
|
||||
|
||||
&stack_interface_get_next_socket_stat
|
||||
};
|
||||
@@ -15,15 +15,15 @@
|
||||
#include <net_protocol.h>
|
||||
#include <net_socket.h>
|
||||
#include <net_stack.h>
|
||||
#include <net_stack_interface.h>
|
||||
|
||||
|
||||
#define NET_STARTER_MODULE_NAME "network/stack/starter/v1"
|
||||
|
||||
extern net_stack_module_info gNetStackModule;
|
||||
extern net_buffer_module_info gNetBufferModule;
|
||||
extern net_socket_module_info gNetSocketModule;
|
||||
extern net_datalink_module_info gNetDatalinkModule;
|
||||
extern net_datalink_protocol_module_info gDatalinkInterfaceProtocolModule;
|
||||
extern net_stack_interface_module_info gNetStackInterfaceModule;
|
||||
|
||||
// stack.cpp
|
||||
status_t register_domain_datalink_protocols(int family, int type, ...);
|
||||
@@ -33,4 +33,7 @@ status_t put_domain_protocols(net_socket *socket);
|
||||
status_t get_domain_datalink_protocols(net_interface *interface);
|
||||
status_t put_domain_datalink_protocols(net_interface *interface);
|
||||
|
||||
status_t init_stack();
|
||||
status_t uninit_stack();
|
||||
|
||||
#endif // STACK_PRIVATE_H
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
SubDir HAIKU_TOP src bin network netstat ;
|
||||
|
||||
UsePrivateHeaders net ;
|
||||
UsePrivateKernelHeaders ; # for syscalls.h
|
||||
|
||||
BinCommand netstat :
|
||||
netstat.cpp
|
||||
|
||||
@@ -7,23 +7,21 @@
|
||||
* James Woodcock
|
||||
*/
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include <net_stack_driver.h>
|
||||
#include <net_stat.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <net/if.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include <net_stat.h>
|
||||
#include <syscalls.h>
|
||||
|
||||
|
||||
extern const char* __progname;
|
||||
@@ -110,22 +108,6 @@ usage(int status)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
get_next_stat(int stack, uint32& cookie, int family, net_stat& stat)
|
||||
{
|
||||
get_next_stat_args args;
|
||||
args.cookie = cookie;
|
||||
args.family = family;
|
||||
|
||||
if (ioctl(stack, NET_STACK_GET_NEXT_STAT, &args, sizeof(args)) < 0)
|
||||
return errno;
|
||||
|
||||
cookie = args.cookie;
|
||||
memcpy(&stat, &args.stat, sizeof(net_stat));
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
get_address_family(const char* argument, int32& familyIndex)
|
||||
{
|
||||
@@ -177,13 +159,6 @@ main(int argc, char** argv)
|
||||
}
|
||||
} while (opt != -1);
|
||||
|
||||
int stack = open(NET_STACK_DRIVER_PATH, O_RDWR);
|
||||
if (stack < 0) {
|
||||
fprintf(stderr, "%s: The networking stack doesn't seem to be "
|
||||
"available.\n", kProgramName);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool printProgram = true;
|
||||
// TODO: add some more program options... :-)
|
||||
|
||||
@@ -193,7 +168,7 @@ main(int argc, char** argv)
|
||||
uint32 cookie = 0;
|
||||
int family = -1;
|
||||
net_stat stat;
|
||||
while (get_next_stat(stack, cookie, family, stat) == B_OK) {
|
||||
while (_kern_get_next_socket_stat(family, &cookie, &stat) == B_OK) {
|
||||
protoent* proto = getprotobynumber(stat.protocol);
|
||||
if (proto != NULL)
|
||||
printf("%-6s ", proto->p_name);
|
||||
@@ -226,7 +201,6 @@ main(int argc, char** argv)
|
||||
printf("%ld\n", stat.owner);
|
||||
}
|
||||
|
||||
close(stack);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
SubDir HAIKU_TOP src kits network ;
|
||||
|
||||
UsePrivateHeaders libroot net ;
|
||||
UsePrivateHeaders libroot net shared ;
|
||||
UsePrivateKernelHeaders ;
|
||||
|
||||
local services = [ FGristFiles services ] ;
|
||||
SEARCH on $(services) = [ FDirName $(SUBDIR) dns defaults ] ;
|
||||
|
||||
+79
-197
@@ -18,19 +18,9 @@
|
||||
#include <sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <syscall_utils.h>
|
||||
|
||||
// TODO: this is meant for debugging purposes only, and should be disabled later
|
||||
static char *
|
||||
stack_driver_path(void)
|
||||
{
|
||||
// user-defined stack driver path?
|
||||
char *path = getenv("NET_STACK_DRIVER_PATH");
|
||||
if (path != NULL)
|
||||
return path;
|
||||
|
||||
// use the default stack driver path
|
||||
return NET_STACK_DRIVER_PATH;
|
||||
}
|
||||
#include <syscalls.h>
|
||||
|
||||
|
||||
static inline bool
|
||||
@@ -171,24 +161,10 @@ convert_from_r5_sockopt(int& level, int& option)
|
||||
extern "C" int
|
||||
socket(int family, int type, int protocol)
|
||||
{
|
||||
int socket = open(stack_driver_path(), O_RDWR);
|
||||
if (socket < 0)
|
||||
return -1;
|
||||
|
||||
if (check_r5_compatibility())
|
||||
convert_from_r5_socket(family, type, protocol);
|
||||
|
||||
socket_args args;
|
||||
args.family = family;
|
||||
args.type = type;
|
||||
args.protocol = protocol;
|
||||
|
||||
if (ioctl(socket, NET_STACK_SOCKET, &args, sizeof(args)) < 0) {
|
||||
close(socket);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return socket;
|
||||
RETURN_AND_SET_ERRNO(_kern_socket(family, type, protocol));
|
||||
}
|
||||
|
||||
|
||||
@@ -203,18 +179,14 @@ bind(int socket, const struct sockaddr *address, socklen_t addressLength)
|
||||
addressLength = sizeof(struct sockaddr_in);
|
||||
}
|
||||
|
||||
sockaddr_args args;
|
||||
args.address = const_cast<struct sockaddr *>(address);
|
||||
args.address_length = addressLength;
|
||||
|
||||
return ioctl(socket, NET_STACK_BIND, &args, sizeof(args));
|
||||
RETURN_AND_SET_ERRNO(_kern_bind(socket, address, addressLength));
|
||||
}
|
||||
|
||||
|
||||
extern "C" int
|
||||
shutdown(int socket, int how)
|
||||
{
|
||||
return ioctl(socket, NET_STACK_SHUTDOWN, (void *)how, 0);
|
||||
RETURN_AND_SET_ERRNO(_kern_shutdown_socket(socket, how));
|
||||
}
|
||||
|
||||
|
||||
@@ -229,53 +201,46 @@ connect(int socket, const struct sockaddr *address, socklen_t addressLength)
|
||||
addressLength = sizeof(struct sockaddr_in);
|
||||
}
|
||||
|
||||
sockaddr_args args;
|
||||
args.address = const_cast<struct sockaddr *>(address);
|
||||
args.address_length = addressLength;
|
||||
|
||||
return ioctl(socket, NET_STACK_CONNECT, &args, sizeof(args));
|
||||
RETURN_AND_SET_ERRNO(_kern_connect(socket, address, addressLength));
|
||||
}
|
||||
|
||||
|
||||
extern "C" int
|
||||
listen(int socket, int backlog)
|
||||
{
|
||||
return ioctl(socket, NET_STACK_LISTEN, (void *)backlog, 0);
|
||||
RETURN_AND_SET_ERRNO(_kern_listen(socket, backlog));
|
||||
}
|
||||
|
||||
|
||||
extern "C" int
|
||||
accept(int socket, struct sockaddr *address, socklen_t *_addressLength)
|
||||
accept(int socket, struct sockaddr *_address, socklen_t *_addressLength)
|
||||
{
|
||||
int acceptSocket = open(stack_driver_path(), O_RDWR);
|
||||
if (acceptSocket < 0)
|
||||
return -1;
|
||||
|
||||
bool r5compatible = check_r5_compatibility();
|
||||
struct sockaddr r5addr;
|
||||
accept_args args;
|
||||
|
||||
args.accept_socket = acceptSocket;
|
||||
sockaddr* address;
|
||||
socklen_t addressLength;
|
||||
|
||||
if (r5compatible && address != NULL) {
|
||||
args.address = &r5addr;
|
||||
args.address_length = sizeof(r5addr);
|
||||
if (r5compatible && _address != NULL) {
|
||||
address = &r5addr;
|
||||
addressLength = sizeof(r5addr);
|
||||
} else {
|
||||
args.address = address;
|
||||
args.address_length = _addressLength ? *_addressLength : 0;
|
||||
address = _address;
|
||||
addressLength = _addressLength ? *_addressLength : 0;
|
||||
}
|
||||
|
||||
if (ioctl(socket, NET_STACK_ACCEPT, &args, sizeof(args)) < 0) {
|
||||
close(acceptSocket);
|
||||
int acceptSocket = _kern_accept(socket, address, &addressLength);
|
||||
if (acceptSocket < 0) {
|
||||
errno = acceptSocket;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (r5compatible && address != NULL) {
|
||||
convert_to_r5_sockaddr(address, &r5addr);
|
||||
if (r5compatible && _address != NULL) {
|
||||
convert_to_r5_sockaddr(_address, &r5addr);
|
||||
if (_addressLength != NULL)
|
||||
*_addressLength = sizeof(struct r5_sockaddr_in);
|
||||
} else if (_addressLength != NULL)
|
||||
*_addressLength = args.address_length;
|
||||
*_addressLength = addressLength;
|
||||
|
||||
return acceptSocket;
|
||||
}
|
||||
@@ -284,50 +249,41 @@ accept(int socket, struct sockaddr *address, socklen_t *_addressLength)
|
||||
extern "C" ssize_t
|
||||
recv(int socket, void *data, size_t length, int flags)
|
||||
{
|
||||
message_args args;
|
||||
args.data = data;
|
||||
args.length = length;
|
||||
args.flags = flags;
|
||||
args.header = NULL;
|
||||
|
||||
return ioctl(socket, NET_STACK_RECEIVE, &args, sizeof(args));
|
||||
RETURN_AND_SET_ERRNO(_kern_recv(socket, data, length, flags));
|
||||
}
|
||||
|
||||
|
||||
extern "C" ssize_t
|
||||
recvfrom(int socket, void *data, size_t length, int flags,
|
||||
struct sockaddr *address, socklen_t *_addressLength)
|
||||
struct sockaddr *_address, socklen_t *_addressLength)
|
||||
{
|
||||
bool r5compatible = check_r5_compatibility();
|
||||
struct sockaddr r5addr;
|
||||
|
||||
message_args args;
|
||||
args.data = data;
|
||||
args.length = length;
|
||||
args.flags = flags;
|
||||
sockaddr* address;
|
||||
socklen_t addressLength;
|
||||
|
||||
msghdr header;
|
||||
memset(&header, 0, sizeof(header));
|
||||
args.header = &header;
|
||||
|
||||
if (r5compatible) {
|
||||
header.msg_name = (char *)&r5addr;
|
||||
header.msg_namelen = sizeof(r5addr);
|
||||
if (r5compatible && _address != NULL) {
|
||||
address = &r5addr;
|
||||
addressLength = sizeof(r5addr);
|
||||
} else {
|
||||
header.msg_name = (char *)address;
|
||||
header.msg_namelen = _addressLength ? *_addressLength : 0;
|
||||
address = _address;
|
||||
addressLength = _addressLength ? *_addressLength : 0;
|
||||
}
|
||||
|
||||
ssize_t bytesReceived = ioctl(socket, NET_STACK_RECEIVE, &args, sizeof(args));
|
||||
if (bytesReceived < 0)
|
||||
ssize_t bytesReceived = _kern_recvfrom(socket, data, length, flags,
|
||||
address, &addressLength);
|
||||
if (bytesReceived < 0) {
|
||||
errno = bytesReceived;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (r5compatible) {
|
||||
convert_to_r5_sockaddr(address, &r5addr);
|
||||
convert_to_r5_sockaddr(_address, &r5addr);
|
||||
if (_addressLength != NULL)
|
||||
*_addressLength = sizeof(struct r5_sockaddr_in);
|
||||
} else if (_addressLength != NULL)
|
||||
*_addressLength = header.msg_namelen;
|
||||
*_addressLength = addressLength;
|
||||
|
||||
return bytesReceived;
|
||||
}
|
||||
@@ -336,36 +292,14 @@ recvfrom(int socket, void *data, size_t length, int flags,
|
||||
extern "C" ssize_t
|
||||
recvmsg(int socket, struct msghdr *message, int flags)
|
||||
{
|
||||
message_args args;
|
||||
|
||||
if (message == NULL || (message->msg_iovlen > 0 && message->msg_iov == NULL))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
args.header = message;
|
||||
args.flags = flags;
|
||||
|
||||
if (message->msg_iovlen > 0) {
|
||||
args.data = message->msg_iov[0].iov_base;
|
||||
args.length = message->msg_iov[0].iov_len;
|
||||
} else {
|
||||
args.data = NULL;
|
||||
args.length = 0;
|
||||
}
|
||||
|
||||
return ioctl(socket, NET_STACK_RECEIVE, &args, sizeof(args));
|
||||
RETURN_AND_SET_ERRNO(_kern_recvmsg(socket, message, flags));
|
||||
}
|
||||
|
||||
|
||||
extern "C" ssize_t
|
||||
send(int socket, const void *data, size_t length, int flags)
|
||||
{
|
||||
message_args args;
|
||||
args.data = const_cast<void *>(data);
|
||||
args.length = length;
|
||||
args.flags = flags;
|
||||
args.header = NULL;
|
||||
|
||||
return ioctl(socket, NET_STACK_SEND, &args, sizeof(args));
|
||||
RETURN_AND_SET_ERRNO(_kern_send(socket, data, length, flags));
|
||||
}
|
||||
|
||||
|
||||
@@ -381,41 +315,15 @@ sendto(int socket, const void *data, size_t length, int flags,
|
||||
addressLength = sizeof(struct sockaddr_in);
|
||||
}
|
||||
|
||||
message_args args;
|
||||
msghdr header;
|
||||
memset(&header, 0, sizeof(header));
|
||||
|
||||
args.header = &header;
|
||||
args.data = const_cast<void *>(data);
|
||||
args.length = length;
|
||||
args.flags = flags;
|
||||
header.msg_name = (char *)const_cast<sockaddr *>(address);
|
||||
header.msg_namelen = addressLength;
|
||||
|
||||
return ioctl(socket, NET_STACK_SEND, &args, sizeof(args));
|
||||
RETURN_AND_SET_ERRNO(_kern_sendto(socket, data, length, flags, address,
|
||||
addressLength));
|
||||
}
|
||||
|
||||
|
||||
extern "C" ssize_t
|
||||
sendmsg(int socket, const struct msghdr *message, int flags)
|
||||
{
|
||||
message_args args;
|
||||
|
||||
if (message == NULL || (message->msg_iovlen > 0 && message->msg_iov == NULL))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
args.header = const_cast<msghdr *>(message);
|
||||
args.flags = flags;
|
||||
|
||||
if (message->msg_iovlen > 0) {
|
||||
args.data = message->msg_iov[0].iov_base;
|
||||
args.length = message->msg_iov[0].iov_len;
|
||||
} else {
|
||||
args.data = NULL;
|
||||
args.length = 0;
|
||||
}
|
||||
|
||||
return ioctl(socket, NET_STACK_SEND, &args, sizeof(args));
|
||||
RETURN_AND_SET_ERRNO(_kern_sendmsg(socket, message, flags));
|
||||
}
|
||||
|
||||
|
||||
@@ -432,19 +340,8 @@ getsockopt(int socket, int level, int option, void *value, socklen_t *_length)
|
||||
convert_from_r5_sockopt(level, option);
|
||||
}
|
||||
|
||||
sockopt_args args;
|
||||
args.level = level;
|
||||
args.option = option;
|
||||
args.value = value;
|
||||
args.length = _length ? *_length : 0;
|
||||
|
||||
if (ioctl(socket, NET_STACK_GETSOCKOPT, &args, sizeof(args)) < 0)
|
||||
return -1;
|
||||
|
||||
if (_length)
|
||||
*_length = args.length;
|
||||
|
||||
return 0;
|
||||
RETURN_AND_SET_ERRNO(_kern_getsockopt(socket, level, option, value,
|
||||
_length));
|
||||
}
|
||||
|
||||
|
||||
@@ -455,69 +352,74 @@ setsockopt(int socket, int level, int option, const void *value,
|
||||
if (check_r5_compatibility())
|
||||
convert_from_r5_sockopt(level, option);
|
||||
|
||||
sockopt_args args;
|
||||
args.level = level;
|
||||
args.option = option;
|
||||
args.value = const_cast<void *>(value);
|
||||
args.length = length;
|
||||
|
||||
return ioctl(socket, NET_STACK_SETSOCKOPT, &args, sizeof(args));
|
||||
RETURN_AND_SET_ERRNO(_kern_setsockopt(socket, level, option, value,
|
||||
length));
|
||||
}
|
||||
|
||||
|
||||
extern "C" int
|
||||
getpeername(int socket, struct sockaddr *address, socklen_t *_addressLength)
|
||||
getpeername(int socket, struct sockaddr *_address, socklen_t *_addressLength)
|
||||
{
|
||||
bool r5compatible = check_r5_compatibility();
|
||||
struct sockaddr r5addr;
|
||||
|
||||
sockaddr_args args;
|
||||
if (r5compatible) {
|
||||
args.address = &r5addr;
|
||||
args.address_length = sizeof(r5addr);
|
||||
sockaddr* address;
|
||||
socklen_t addressLength;
|
||||
|
||||
if (r5compatible && _address != NULL) {
|
||||
address = &r5addr;
|
||||
addressLength = sizeof(r5addr);
|
||||
} else {
|
||||
args.address = address;
|
||||
args.address_length = _addressLength ? *_addressLength : 0;
|
||||
address = _address;
|
||||
addressLength = _addressLength ? *_addressLength : 0;
|
||||
}
|
||||
|
||||
if (ioctl(socket, NET_STACK_GETPEERNAME, &args, sizeof(args)) < 0)
|
||||
status_t error = _kern_getpeername(socket, address, &addressLength);
|
||||
if (error != B_OK) {
|
||||
errno = error;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (r5compatible) {
|
||||
convert_to_r5_sockaddr(address, &r5addr);
|
||||
convert_to_r5_sockaddr(_address, &r5addr);
|
||||
if (_addressLength != NULL)
|
||||
*_addressLength = sizeof(struct r5_sockaddr_in);
|
||||
} else if (_addressLength != NULL)
|
||||
*_addressLength = args.address_length;
|
||||
*_addressLength = addressLength;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
extern "C" int
|
||||
getsockname(int socket, struct sockaddr *address, socklen_t *_addressLength)
|
||||
getsockname(int socket, struct sockaddr *_address, socklen_t *_addressLength)
|
||||
{
|
||||
bool r5compatible = check_r5_compatibility();
|
||||
struct sockaddr r5addr;
|
||||
|
||||
sockaddr_args args;
|
||||
if (r5compatible) {
|
||||
args.address = &r5addr;
|
||||
args.address_length = sizeof(r5addr);
|
||||
sockaddr* address;
|
||||
socklen_t addressLength;
|
||||
|
||||
if (r5compatible && _address != NULL) {
|
||||
address = &r5addr;
|
||||
addressLength = sizeof(r5addr);
|
||||
} else {
|
||||
args.address = address;
|
||||
args.address_length = _addressLength ? *_addressLength : 0;
|
||||
address = _address;
|
||||
addressLength = _addressLength ? *_addressLength : 0;
|
||||
}
|
||||
|
||||
if (ioctl(socket, NET_STACK_GETSOCKNAME, &args, sizeof(args)) < 0)
|
||||
status_t error = _kern_getsockname(socket, address, &addressLength);
|
||||
if (error != B_OK) {
|
||||
errno = error;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (r5compatible) {
|
||||
convert_to_r5_sockaddr(address, &r5addr);
|
||||
convert_to_r5_sockaddr(_address, &r5addr);
|
||||
if (_addressLength != NULL)
|
||||
*_addressLength = sizeof(struct r5_sockaddr_in);
|
||||
} else if (_addressLength != NULL)
|
||||
*_addressLength = args.address_length;
|
||||
*_addressLength = addressLength;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -526,33 +428,13 @@ getsockname(int socket, struct sockaddr *address, socklen_t *_addressLength)
|
||||
extern "C" int
|
||||
sockatmark(int socket)
|
||||
{
|
||||
// TODO: implement me!
|
||||
return -1;
|
||||
RETURN_AND_SET_ERRNO(_kern_sockatmark(socket));
|
||||
}
|
||||
|
||||
|
||||
extern "C" int
|
||||
socketpair(int family, int type, int protocol, int socketVector[2])
|
||||
{
|
||||
socketVector[0] = socket(family, type, protocol);
|
||||
if (socketVector[0] < 0)
|
||||
return -1;
|
||||
|
||||
socketVector[1] = socket(family, type, protocol);
|
||||
if (socketVector[1] < 0)
|
||||
goto err1;
|
||||
|
||||
socketpair_args args;
|
||||
args.second_socket = socketVector[1];
|
||||
|
||||
if (ioctl(socketVector[0], NET_STACK_SOCKETPAIR, &args, sizeof(args)) < 0)
|
||||
goto err2;
|
||||
|
||||
return 0;
|
||||
|
||||
err2:
|
||||
close(socketVector[1]);
|
||||
err1:
|
||||
close(socketVector[0]);
|
||||
return -1;
|
||||
RETURN_AND_SET_ERRNO(_kern_socketpair(family, type, protocol,
|
||||
socketVector));
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ SubDir HAIKU_TOP src system kernel fs ;
|
||||
UsePrivateHeaders [ FDirName kernel disk_device_manager ] ;
|
||||
UsePrivateHeaders [ FDirName kernel fs ] ;
|
||||
UsePrivateHeaders [ FDirName kernel util ] ;
|
||||
UsePrivateHeaders shared storage ;
|
||||
UsePrivateHeaders net shared storage ;
|
||||
|
||||
KernelMergeObject kernel_fs.o :
|
||||
devfs.cpp
|
||||
@@ -13,6 +13,7 @@ KernelMergeObject kernel_fs.o :
|
||||
KPath.cpp
|
||||
node_monitor.cpp
|
||||
rootfs.cpp
|
||||
socket.cpp
|
||||
vfs.cpp
|
||||
vfs_boot.cpp
|
||||
vfs_net_boot.cpp
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user