Add a userspace interface for DNS

This commit is contained in:
Kevin Lange 2016-11-21 19:29:07 +09:00
parent 8ac9742906
commit 79ad65c429
5 changed files with 118 additions and 26 deletions

View File

@ -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;
}

View File

@ -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) {

View File

@ -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
View 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;
}

View File

@ -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"']),