Skip to content

Commit

Permalink
Add ioctl code needed to implement ifconfig
Browse files Browse the repository at this point in the history
  • Loading branch information
pandax381 committed Mar 27, 2020
1 parent 67ff299 commit 4ccc32e
Show file tree
Hide file tree
Showing 13 changed files with 207 additions and 1 deletion.
5 changes: 5 additions & 0 deletions defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ void fileinit(void);
int fileread(struct file*, char*, int n);
int filestat(struct file*, struct stat*);
int filewrite(struct file*, char*, int n);
int fileioctl(struct file*, int, void*);

// fs.c
void readsb(int dev, struct superblock *sb);
Expand Down Expand Up @@ -208,6 +209,7 @@ void vprintfmt(void (*)(int, void*), void*, const char*, va_list);
int snprintf(char *buf, int n, const char *fmt, ...);

// string.c
int strcmp(const char *p, const char *q);
int strnlen(const char *s, size_t size);
long strtol(const char *s, char **endptr, int base);

Expand Down Expand Up @@ -282,6 +284,8 @@ unsigned long genrand_int32(void);
struct netdev * netdev_root(void);
struct netdev * netdev_alloc(void (*setup)(struct netdev *));
int netdev_register(struct netdev *dev);
struct netdev * netdev_by_index(int index);
struct netdev * netdev_by_name(const char *name);
void netdev_receive(struct netdev *dev, uint16_t type, uint8_t *packet, unsigned int plen);
int netdev_add_netif(struct netdev *dev, struct netif *netif);
struct netif * netdev_get_netif(struct netdev *dev, int family);
Expand Down Expand Up @@ -318,6 +322,7 @@ int socketread(struct socket*, char*, int);
int socketwrite(struct socket*, char*, int);
int socketrecvfrom(struct socket*, char*, int, struct sockaddr*, int*);
int socketsendto(struct socket*, char*, int, struct sockaddr*, int);
int socketioctl(struct socket*, int, void*);

#define sizeof_member(s, m) sizeof(((s *)NULL)->m)
#define array_tailof(x) (x + (sizeof(x) / sizeof(*x)))
Expand Down
7 changes: 7 additions & 0 deletions file.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,3 +162,10 @@ filewrite(struct file *f, char *addr, int n)
panic("filewrite");
}

int
fileioctl(struct file *f, int req, void *arg)
{
if(f->type == FD_SOCKET)
return socketioctl(f->socket, req, arg);
return -1;
}
27 changes: 26 additions & 1 deletion net.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ netdev_alloc(void (*setup)(struct netdev *))
return NULL;
}
memset(dev, 0, sizeof(struct netdev));
snprintf(dev->name, sizeof(dev->name), "net%d", index++);
dev->index = index++;
snprintf(dev->name, sizeof(dev->name), "net%d", dev->index);
setup(dev);
return dev;
}
Expand All @@ -46,6 +47,30 @@ netdev_register(struct netdev *dev)
return 0;
}

struct netdev *
netdev_by_index(int index)
{
struct netdev *dev;

for (dev = devices; dev; dev = dev->next)
if (dev->index == index)
return dev;

return NULL;
}

struct netdev *
netdev_by_name(const char *name)
{
struct netdev *dev;

for (dev = devices; dev; dev = dev->next)
if (strcmp(dev->name, name) == 0)
return dev;

return NULL;
}

void
netdev_receive(struct netdev *dev, uint16_t type, uint8_t *packet, unsigned int plen)
{
Expand Down
1 change: 1 addition & 0 deletions net.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ struct netdev_ops {
struct netdev {
struct netdev *next;
struct netif *ifs;
int index;
char name[IFNAMSIZ];
uint16_t type;
uint16_t mtu;
Expand Down
100 changes: 100 additions & 0 deletions socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include "spinlock.h"
#include "sleeplock.h"
#include "file.h"
#include "net.h"
#include "ip.h"
#include "socket.h"

struct socket {
Expand Down Expand Up @@ -129,3 +131,101 @@ socketsendto(struct socket *s, char *buf, int n, struct sockaddr *addr, int addr
return -1;
return udp_api_sendto(s->desc, (uint8_t *)buf, n, addr, addrlen);
}

int
socketioctl(struct socket *s, int req, void *arg) {
struct ifreq *ifreq;
struct netdev *dev;
struct netif *iface;

switch (req) {
case SIOCGIFINDEX:
ifreq = (struct ifreq *)arg;
dev = netdev_by_name(ifreq->ifr_name);
if (!dev)
return -1;
ifreq->ifr_ifindex = dev->index;
break;
case SIOCGIFNAME:
ifreq = (struct ifreq *)arg;
dev = netdev_by_index(ifreq->ifr_ifindex);
if (!dev)
return -1;
strncpy(ifreq->ifr_name, dev->name, sizeof(ifreq->ifr_name));
break;
case SIOCSIFNAME:
/* TODO */
break;
case SIOCGIFHWADDR:
ifreq = (struct ifreq *)arg;
dev = netdev_by_name(ifreq->ifr_name);
if (!dev)
return -1;
/* TODO: HW type check */
memcpy(ifreq->ifr_hwaddr.sa_data, dev->addr, dev->alen);
break;
case SIOCSIFHWADDR:
/* TODO */
break;
case SIOCGIFFLAGS:
ifreq = (struct ifreq *)arg;
dev = netdev_by_name(ifreq->ifr_name);
if (!dev)
return -1;
ifreq->ifr_flags = dev->flags;
break;
case SIOCSIFFLAGS:
break;
case SIOCGIFADDR:
ifreq = (struct ifreq *)arg;
dev = netdev_by_name(ifreq->ifr_name);
if (!dev)
return -1;
iface = netdev_get_netif(dev, ifreq->ifr_addr.sa_family);
if (!iface)
return -1;
((struct sockaddr_in *)&ifreq->ifr_addr)->sin_addr = ((struct netif_ip *)iface)->unicast;
break;
case SIOCSIFADDR:
/* TODO */
break;
case SIOCGIFNETMASK:
ifreq = (struct ifreq *)arg;
dev = netdev_by_name(ifreq->ifr_name);
if (!dev)
return -1;
iface = netdev_get_netif(dev, ifreq->ifr_addr.sa_family);
if (!iface)
return -1;
((struct sockaddr_in *)&ifreq->ifr_netmask)->sin_addr = ((struct netif_ip *)iface)->netmask;
break;
case SIOCSIFNETMASK:
/* TODO */
break;
case SIOCGIFBRDADDR:
ifreq = (struct ifreq *)arg;
dev = netdev_by_name(ifreq->ifr_name);
if (!dev)
return -1;
iface = netdev_get_netif(dev, ifreq->ifr_addr.sa_family);
if (!iface)
return -1;
((struct sockaddr_in *)&ifreq->ifr_broadaddr)->sin_addr = ((struct netif_ip *)iface)->broadcast;
break;
case SIOCSIFBRDADDR:
/* TODO */
break;
case SIOCGIFMTU:
ifreq = (struct ifreq *)arg;
dev = netdev_by_name(ifreq->ifr_name);
if (!dev)
return -1;
ifreq->ifr_mtu = dev->mtu;
break;
case SIOCSIFMTU:
break;
default:
return -1;
}
return 0;
}
23 changes: 23 additions & 0 deletions socket.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include "sockio.h"

#define PF_UNSPEC 0
#define PF_LOCAL 1
#define PF_INET 2
Expand All @@ -24,3 +26,24 @@ struct sockaddr_in {
uint16_t sin_port;
ip_addr_t sin_addr;
};

#define IFNAMSIZ 16

struct ifreq {
char ifr_name[IFNAMSIZ]; /* Interface name */
union {
struct sockaddr ifr_addr;
struct sockaddr ifr_dstaddr;
struct sockaddr ifr_broadaddr;
struct sockaddr ifr_netmask;
struct sockaddr ifr_hwaddr;
short ifr_flags;
int ifr_ifindex;
int ifr_metric;
int ifr_mtu;
// struct ifmap ifr_map;
char ifr_slave[IFNAMSIZ];
char ifr_newname[IFNAMSIZ];
char *ifr_data;
};
};
17 changes: 17 additions & 0 deletions sockio.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#include "ioccom.h"

#define SIOCGIFINDEX _IOWR('i', 0, struct ifreq)
#define SIOCGIFNAME _IOWR('i', 1, struct ifreq)
#define SIOCSIFNAME _IOW('i', 2, struct ifreq)
#define SIOCGIFHWADDR _IOWR('i', 3, struct ifreq)
#define SIOCSIFHWADDR _IOW('i', 4, struct ifreq)
#define SIOCGIFFLAGS _IOWR('i', 5, struct ifreq)
#define SIOCSIFFLAGS _IOW('i', 6, struct ifreq)
#define SIOCGIFADDR _IOWR('i', 7, struct ifreq)
#define SIOCSIFADDR _IOW('i', 8, struct ifreq)
#define SIOCGIFNETMASK _IOWR('i', 9, struct ifreq)
#define SIOCSIFNETMASK _IOW('i', 10, struct ifreq)
#define SIOCGIFBRDADDR _IOWR('i', 11, struct ifreq)
#define SIOCSIFBRDADDR _IOW('i', 12, struct ifreq)
#define SIOCGIFMTU _IOWR('i', 13, struct ifreq)
#define SIOCSIFMTU _IOW('i', 14, struct ifreq)
8 changes: 8 additions & 0 deletions string.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,14 @@ strlen(const char *s)

/* copy from JOS */

int
strcmp(const char *p, const char *q)
{
while(*p && *p == *q)
p++, q++;
return (uchar)*p - (uchar)*q;
}

int
strnlen(const char *s, size_t size)
{
Expand Down
2 changes: 2 additions & 0 deletions syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ extern int sys_ifget(void);
extern int sys_ifset(void);
extern int sys_ifup(void);
extern int sys_ifdown(void);
extern int sys_ioctl(void);
// socket
extern int sys_socket(void);
extern int sys_connect(void);
Expand Down Expand Up @@ -146,6 +147,7 @@ static int (*syscalls[])(void) = {
[SYS_ifset] sys_ifset,
[SYS_ifup] sys_ifup,
[SYS_ifdown] sys_ifdown,
[SYS_ioctl] sys_ioctl,
// socket
[SYS_socket] sys_socket,
[SYS_connect] sys_connect,
Expand Down
1 change: 1 addition & 0 deletions syscall.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#define SYS_ifset 23
#define SYS_ifup 24
#define SYS_ifdown 25
#define SYS_ioctl 35
// socket
#define SYS_socket 26
#define SYS_connect 27
Expand Down
15 changes: 15 additions & 0 deletions sysfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "sleeplock.h"
#include "file.h"
#include "fcntl.h"
#include "ioccom.h"

// Fetch the nth word-sized system call argument as a file descriptor
// and return both the descriptor and the corresponding struct file.
Expand Down Expand Up @@ -442,3 +443,17 @@ sys_pipe(void)
fd[1] = fd1;
return 0;
}

int
sys_ioctl(void)
{
struct file *f;
int req;
void *arg;

if(argfd(0, 0, &f) < 0 || argint(1, &req) < 0)
return -1;
if(argptr(2, (void*)&arg, IOCPARM_LEN(req)) < 0)
return -1;
return fileioctl(f, req, arg);
}
1 change: 1 addition & 0 deletions user.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ int ifget(const char*);
int ifset(const char*, const char*, const char*);
int ifup(const char*);
int ifdown(const char*);
int ioctl(int, int, ...);
// socket
int socket(int, int, int);
int connect(int, struct sockaddr*, int);
Expand Down
1 change: 1 addition & 0 deletions usys.S
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ SYSCALL(ifget)
SYSCALL(ifset)
SYSCALL(ifup)
SYSCALL(ifdown)
SYSCALL(ioctl)
# socket
SYSCALL(socket)
SYSCALL(bind)
Expand Down

0 comments on commit 4ccc32e

Please sign in to comment.