mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +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_INET 2
|
||||
#define AF_PACKET 17
|
||||
|
||||
#define SOCK_STREAM 1
|
||||
#define SOCK_DGRAM 2
|
||||
@@ -155,6 +156,16 @@ typedef struct {
|
||||
char sun_path[ABISOCKADDR_UN_MAX];
|
||||
} 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 {
|
||||
void *addr;
|
||||
socklen_t addrlen;
|
||||
|
||||
@@ -175,8 +175,8 @@ static inline int socket_send(socket_t *socket, void *buffer, size_t size, uintm
|
||||
return e;
|
||||
}
|
||||
|
||||
static inline int sock_convertaddress(sockaddr_t *sockaddr, abisockaddr_t *abisockaddr) {
|
||||
switch (abisockaddr->type) {
|
||||
static inline int sock_convertaddress(sockaddr_t *sockaddr, void *abisockaddr) {
|
||||
switch (((abisockaddr_t *)abisockaddr)->type) {
|
||||
case AF_INET:
|
||||
inaddr_t *inaddr = (inaddr_t *)abisockaddr;
|
||||
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);
|
||||
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:
|
||||
return EINVAL;
|
||||
}
|
||||
@@ -197,21 +209,33 @@ static inline int sock_convertaddress(sockaddr_t *sockaddr, abisockaddr_t *abiso
|
||||
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) {
|
||||
case SOCKET_TYPE_UDP:
|
||||
case SOCKET_TYPE_TCP:
|
||||
abisockaddr->type = AF_INET;
|
||||
((abisockaddr_t *)abisockaddr)->type = AF_INET;
|
||||
inaddr_t *inaddr = (inaddr_t *)abisockaddr;
|
||||
inaddr->sin_addr = cpu_to_be_d(sockaddr->ipv4addr.addr);
|
||||
inaddr->sin_port = cpu_to_be_w(sockaddr->ipv4addr.port);
|
||||
break;
|
||||
case SOCKET_TYPE_LOCAL:
|
||||
case SOCKET_TYPE_LOCAL_SEQPACKET:
|
||||
abisockaddr->type = AF_LOCAL;
|
||||
((abisockaddr_t *)abisockaddr)->type = AF_LOCAL;
|
||||
unaddr_t *unaddr = (unaddr_t *)abisockaddr;
|
||||
strcpy(unaddr->sun_path, sockaddr->path);
|
||||
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:
|
||||
return EINVAL;
|
||||
}
|
||||
@@ -253,6 +277,13 @@ static inline int sock_copy_addr_to_user(int socktype, sockaddr_t *sockaddr, voi
|
||||
|
||||
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:
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
@@ -36,6 +36,11 @@ syscallret_t syscall_socket(context_t *, int domain, int type, int protocol) {
|
||||
socktype = SOCKET_TYPE_LOCAL;
|
||||
if (type == SOCK_SEQPACKET)
|
||||
socktype = SOCKET_TYPE_LOCAL_SEQPACKET;
|
||||
break;
|
||||
case AF_PACKET:
|
||||
if (type == SOCK_DGRAM)
|
||||
socktype = SOCKET_TYPE_RAW_STRIPPED;
|
||||
break;
|
||||
}
|
||||
|
||||
if (socktype == -1) {
|
||||
|
||||
Reference in New Issue
Block a user