mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 23:18:21 +00:00
sockets: expose raw sockets to userspace
This commit is contained in:
@@ -88,6 +88,7 @@ typedef struct {
|
|||||||
|
|
||||||
#define AF_LOCAL 1
|
#define AF_LOCAL 1
|
||||||
#define AF_INET 2
|
#define AF_INET 2
|
||||||
|
#define AF_PACKET 17
|
||||||
|
|
||||||
#define SOCK_STREAM 1
|
#define SOCK_STREAM 1
|
||||||
#define SOCK_DGRAM 2
|
#define SOCK_DGRAM 2
|
||||||
@@ -155,6 +156,16 @@ typedef struct {
|
|||||||
char sun_path[ABISOCKADDR_UN_MAX];
|
char sun_path[ABISOCKADDR_UN_MAX];
|
||||||
} unaddr_t;
|
} unaddr_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t sll_family;
|
||||||
|
uint16_t sll_protocol;
|
||||||
|
int32_t sll_ifindex;
|
||||||
|
uint16_t sll_hatype;
|
||||||
|
uint8_t sll_pkttype;
|
||||||
|
uint8_t sll_halen;
|
||||||
|
uint8_t sll_addr[8];
|
||||||
|
} sockaddr_ll_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *addr;
|
void *addr;
|
||||||
socklen_t addrlen;
|
socklen_t addrlen;
|
||||||
|
|||||||
@@ -175,8 +175,8 @@ static inline int socket_send(socket_t *socket, void *buffer, size_t size, uintm
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int sock_convertaddress(sockaddr_t *sockaddr, abisockaddr_t *abisockaddr) {
|
static inline int sock_convertaddress(sockaddr_t *sockaddr, void *abisockaddr) {
|
||||||
switch (abisockaddr->type) {
|
switch (((abisockaddr_t *)abisockaddr)->type) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
inaddr_t *inaddr = (inaddr_t *)abisockaddr;
|
inaddr_t *inaddr = (inaddr_t *)abisockaddr;
|
||||||
sockaddr->ipv4addr.addr = be_to_cpu_d(inaddr->sin_addr);
|
sockaddr->ipv4addr.addr = be_to_cpu_d(inaddr->sin_addr);
|
||||||
@@ -190,6 +190,18 @@ static inline int sock_convertaddress(sockaddr_t *sockaddr, abisockaddr_t *abiso
|
|||||||
|
|
||||||
memcpy(sockaddr->path, unaddr->sun_path, length + 1);
|
memcpy(sockaddr->path, unaddr->sun_path, length + 1);
|
||||||
break;
|
break;
|
||||||
|
case AF_PACKET: {
|
||||||
|
sockaddr_ll_t lladdr;
|
||||||
|
memcpy(&lladdr, abisockaddr, sizeof(lladdr));
|
||||||
|
if (lladdr.sll_ifindex < 0 || lladdr.sll_ifindex > 0xffff)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
sockaddr->raw.netdev = lladdr.sll_ifindex;
|
||||||
|
sockaddr->raw.proto = be_to_cpu_w(lladdr.sll_protocol);
|
||||||
|
memset(sockaddr->raw.mac, 0, sizeof(sockaddr->raw.mac));
|
||||||
|
memcpy(sockaddr->raw.mac, lladdr.sll_addr, min((size_t)lladdr.sll_halen, sizeof(sockaddr->raw.mac)));
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
@@ -197,21 +209,33 @@ static inline int sock_convertaddress(sockaddr_t *sockaddr, abisockaddr_t *abiso
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int sock_addrtoabiaddr(int socktype, sockaddr_t *sockaddr, abisockaddr_t *abisockaddr) {
|
static inline int sock_addrtoabiaddr(int socktype, sockaddr_t *sockaddr, void *abisockaddr) {
|
||||||
switch (socktype) {
|
switch (socktype) {
|
||||||
case SOCKET_TYPE_UDP:
|
case SOCKET_TYPE_UDP:
|
||||||
case SOCKET_TYPE_TCP:
|
case SOCKET_TYPE_TCP:
|
||||||
abisockaddr->type = AF_INET;
|
((abisockaddr_t *)abisockaddr)->type = AF_INET;
|
||||||
inaddr_t *inaddr = (inaddr_t *)abisockaddr;
|
inaddr_t *inaddr = (inaddr_t *)abisockaddr;
|
||||||
inaddr->sin_addr = cpu_to_be_d(sockaddr->ipv4addr.addr);
|
inaddr->sin_addr = cpu_to_be_d(sockaddr->ipv4addr.addr);
|
||||||
inaddr->sin_port = cpu_to_be_w(sockaddr->ipv4addr.port);
|
inaddr->sin_port = cpu_to_be_w(sockaddr->ipv4addr.port);
|
||||||
break;
|
break;
|
||||||
case SOCKET_TYPE_LOCAL:
|
case SOCKET_TYPE_LOCAL:
|
||||||
case SOCKET_TYPE_LOCAL_SEQPACKET:
|
case SOCKET_TYPE_LOCAL_SEQPACKET:
|
||||||
abisockaddr->type = AF_LOCAL;
|
((abisockaddr_t *)abisockaddr)->type = AF_LOCAL;
|
||||||
unaddr_t *unaddr = (unaddr_t *)abisockaddr;
|
unaddr_t *unaddr = (unaddr_t *)abisockaddr;
|
||||||
strcpy(unaddr->sun_path, sockaddr->path);
|
strcpy(unaddr->sun_path, sockaddr->path);
|
||||||
break;
|
break;
|
||||||
|
case SOCKET_TYPE_RAW_STRIPPED: {
|
||||||
|
sockaddr_ll_t lladdr = {
|
||||||
|
.sll_family = AF_PACKET,
|
||||||
|
.sll_protocol = cpu_to_be_w(sockaddr->raw.proto),
|
||||||
|
.sll_ifindex = sockaddr->raw.netdev,
|
||||||
|
.sll_hatype = ARPHRD_ETHER,
|
||||||
|
.sll_halen = sizeof(sockaddr->raw.mac)
|
||||||
|
};
|
||||||
|
memcpy(lladdr.sll_addr, sockaddr->raw.mac, sizeof(sockaddr->raw.mac));
|
||||||
|
memcpy(abisockaddr, &lladdr, sizeof(lladdr));
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
@@ -253,6 +277,13 @@ static inline int sock_copy_addr_to_user(int socktype, sockaddr_t *sockaddr, voi
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
case SOCKET_TYPE_RAW_STRIPPED: {
|
||||||
|
sockaddr_ll_t lladdr = {0};
|
||||||
|
sock_addrtoabiaddr(socktype, sockaddr, &lladdr);
|
||||||
|
|
||||||
|
*actual_len = sizeof(lladdr);
|
||||||
|
return usercopy_touser(uaddr, &lladdr, min(uaddrlen, sizeof(lladdr)));
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,11 @@ syscallret_t syscall_socket(context_t *, int domain, int type, int protocol) {
|
|||||||
socktype = SOCKET_TYPE_LOCAL;
|
socktype = SOCKET_TYPE_LOCAL;
|
||||||
if (type == SOCK_SEQPACKET)
|
if (type == SOCK_SEQPACKET)
|
||||||
socktype = SOCKET_TYPE_LOCAL_SEQPACKET;
|
socktype = SOCKET_TYPE_LOCAL_SEQPACKET;
|
||||||
|
break;
|
||||||
|
case AF_PACKET:
|
||||||
|
if (type == SOCK_DGRAM)
|
||||||
|
socktype = SOCKET_TYPE_RAW_STRIPPED;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (socktype == -1) {
|
if (socktype == -1) {
|
||||||
|
|||||||
Reference in New Issue
Block a user