Add a userspace interface for DNS
This commit is contained in:
parent
8ac9742906
commit
79ad65c429
@ -317,32 +317,16 @@ fs_node_t * socket_ipv4_tcp_create(uint32_t dest, uint16_t target_port, uint16_t
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* TODO: socket_close - TCP close; UDP... just clean us up */
|
||||
/* TODO: socket_open - idk, whatever */
|
||||
|
||||
static fs_node_t * finddir_netfs(fs_node_t * node, char * name) {
|
||||
/* Should essentially find anything. */
|
||||
debug_print(WARNING, "Need to look up domain or check if is IP: %s", name);
|
||||
/* Block until lookup is complete */
|
||||
|
||||
int port = 80;
|
||||
char * colon;
|
||||
if ((colon = strstr(name, ":"))) {
|
||||
/* Port numbers */
|
||||
*colon = '\0';
|
||||
colon++;
|
||||
port = atoi(colon);
|
||||
}
|
||||
|
||||
uint32_t ip = 0;
|
||||
static int gethost(char * name, uint32_t * ip) {
|
||||
if (is_ip(name)) {
|
||||
debug_print(WARNING, " IP: %x", ip_aton(name));
|
||||
ip = ip_aton(name);
|
||||
*ip = ip_aton(name);
|
||||
return 0;
|
||||
} else {
|
||||
if (hashmap_has(dns_cache, name)) {
|
||||
ip = ip_aton(hashmap_get(dns_cache, name));
|
||||
*ip = ip_aton(hashmap_get(dns_cache, name));
|
||||
debug_print(WARNING, " In Cache: %s → %x", name, ip);
|
||||
return 0;
|
||||
} else {
|
||||
debug_print(WARNING, " Still needs look up.");
|
||||
char * xname = strdup(name);
|
||||
@ -373,13 +357,36 @@ static fs_node_t * finddir_netfs(fs_node_t * node, char * name) {
|
||||
/* wait for response */
|
||||
sleep_on(dns_waiters);
|
||||
if (hashmap_has(dns_cache, name)) {
|
||||
ip = ip_aton(hashmap_get(dns_cache, name));
|
||||
*ip = ip_aton(hashmap_get(dns_cache, name));
|
||||
debug_print(WARNING, " Now in cache: %s → %x", name, ip);
|
||||
return 0;
|
||||
} else {
|
||||
return NULL;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* TODO: socket_close - TCP close; UDP... just clean us up */
|
||||
/* TODO: socket_open - idk, whatever */
|
||||
|
||||
static fs_node_t * finddir_netfs(fs_node_t * node, char * name) {
|
||||
/* Should essentially find anything. */
|
||||
debug_print(WARNING, "Need to look up domain or check if is IP: %s", name);
|
||||
/* Block until lookup is complete */
|
||||
|
||||
int port = 80;
|
||||
char * colon;
|
||||
if ((colon = strstr(name, ":"))) {
|
||||
/* Port numbers */
|
||||
*colon = '\0';
|
||||
colon++;
|
||||
port = atoi(colon);
|
||||
}
|
||||
|
||||
uint32_t ip = 0;
|
||||
if (gethost(name, &ip)) return NULL;
|
||||
|
||||
fs_node_t * fnode = malloc(sizeof(fs_node_t));
|
||||
memset(fnode, 0x00, sizeof(fs_node_t));
|
||||
@ -396,6 +403,21 @@ static fs_node_t * finddir_netfs(fs_node_t * node, char * name) {
|
||||
return fnode;
|
||||
}
|
||||
|
||||
static int ioctl_netfs(fs_node_t * node, int request, void * argp) {
|
||||
switch (request) {
|
||||
case 0x5000: {
|
||||
/* */
|
||||
debug_print(INFO, "DNS query from userspace");
|
||||
void ** x = (void **)argp;
|
||||
char * host = x[0];
|
||||
uint32_t * ip = x[1];
|
||||
/* TODO: Validate */
|
||||
return gethost(host, ip);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t write_dns_packet(uint8_t * buffer, size_t queries_len, uint8_t * queries) {
|
||||
size_t offset = 0;
|
||||
size_t payload_size = sizeof(struct dns_packet) + queries_len;
|
||||
@ -1098,6 +1120,7 @@ static fs_node_t * netfs_create(void) {
|
||||
fnode->flags = FS_DIRECTORY;
|
||||
fnode->readdir = readdir_netfs;
|
||||
fnode->finddir = finddir_netfs;
|
||||
fnode->ioctl = ioctl_netfs;
|
||||
fnode->nlink = 1;
|
||||
return fnode;
|
||||
}
|
||||
|
@ -5,16 +5,36 @@
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include "network.h"
|
||||
|
||||
static struct hostent _out_host;
|
||||
static struct hostent _out_host = {0};
|
||||
static struct in_addr * _out_host_vector[2] = {NULL, NULL};
|
||||
static struct in_addr * _out_host_aliases[1] = {NULL};
|
||||
static uint32_t _out_addr;
|
||||
|
||||
#define UNIMPLEMENTED fprintf(stderr, "[libnetwork] Unimplemented: %s\n", __FUNCTION__)
|
||||
|
||||
struct hostent * gethostbyname(const char * name) {
|
||||
UNIMPLEMENTED;
|
||||
return NULL;
|
||||
if (_out_host.h_name) free(_out_host.h_name);
|
||||
_out_host.h_name = strdup(name);
|
||||
int fd = open("/dev/net",O_RDONLY);
|
||||
void * args[2] = {(void *)name,&_out_addr};
|
||||
int ret = ioctl(fd, 0x5000, args);
|
||||
close(fd);
|
||||
if (ret) return NULL;
|
||||
|
||||
_out_host_vector[0] = (struct in_addr *)&_out_addr;
|
||||
_out_host.h_aliases = (char **)&_out_host_aliases;
|
||||
_out_host.h_addrtype = AF_INET;
|
||||
_out_host.h_addr_list = (char**)_out_host_vector;
|
||||
_out_host.h_length = sizeof(uint32_t);
|
||||
return &_out_host;
|
||||
}
|
||||
|
||||
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
|
||||
|
@ -3,6 +3,10 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define AF_INET 1
|
||||
#define AF_UNSPEC 0
|
||||
|
||||
@ -97,4 +101,8 @@ int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
|
||||
int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
|
||||
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TOARU_SYS_SOCKET_H */
|
||||
|
40
userspace/net/nslookup.c
Normal file
40
userspace/net/nslookup.c
Normal file
@ -0,0 +1,40 @@
|
||||
/* vim: ts=4 sw=4 noexpandtab
|
||||
* This file is part of ToaruOS and is released under the terms
|
||||
* of the NCSA / University of Illinois License - see LICENSE.md
|
||||
* Copyright (C) 2016 Kevin Lange
|
||||
*
|
||||
* nslookup - perform nameserver lookups
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#include "lib/network.h"
|
||||
|
||||
static void ip_ntoa(uint32_t src_addr, char * out) {
|
||||
sprintf(out, "%d.%d.%d.%d",
|
||||
(src_addr & 0xFF000000) >> 24,
|
||||
(src_addr & 0xFF0000) >> 16,
|
||||
(src_addr & 0xFF00) >> 8,
|
||||
(src_addr & 0xFF));
|
||||
}
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
if (argc < 2) return 1;
|
||||
|
||||
struct hostent * host = gethostbyname(argv[1]);
|
||||
|
||||
if (!host) {
|
||||
fprintf(stderr, "%s: not found\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char addr[16] = {0};
|
||||
ip_ntoa(*(uint32_t *)host->h_addr_list[0], addr);
|
||||
|
||||
fprintf(stderr, "%s: %s\n", host->h_name, addr);
|
||||
return 0;
|
||||
}
|
@ -39,6 +39,7 @@ class Classifier(object):
|
||||
'"lib/shmemfonts.h"': (None, 'userspace/lib/shmemfonts.o', ['"lib/graphics.h"', '<ft2build.h>']),
|
||||
'"lib/rline.h"': (None, 'userspace/lib/rline.o', ['"lib/kbd.h"']),
|
||||
'"lib/confreader.h"': (None, 'userspace/lib/confreader.o', ['"lib/hashmap.h"']),
|
||||
'"lib/network.h"': (None, 'userspace/lib/network.o', []),
|
||||
'"lib/http_parser.h"': (None, 'userspace/lib/http_parser.o', []),
|
||||
# Yutani Libraries
|
||||
'"lib/yutani.h"': (None, 'userspace/lib/yutani.o', ['"lib/list.h"', '"lib/pex.h"', '"lib/graphics.h"', '"lib/hashmap.h"']),
|
||||
|
Loading…
x
Reference in New Issue
Block a user