-
#define AF_INET 1
#define SOCK_RAW 1
#define INADDR_LOOPBACK 0x7F000001UL
#define IN_LOOPBACK(a) (((a) >> 24) == 0x7F)
+
+#ifndef NSOCKET
+#define NSOCKET 8
+#endif
+
+
+struct sockaddrs {
+ uint32_t addr;
+ uint16_t port;
+};
+
+struct socket
+{
+ inoptr s_inode;
+ uint8_t s_type;
+ uint8_t s_error;
+
+ uint8_t s_state;
+#define SS_UNUSED 0 /* Free slot */
+#define SS_INIT 1 /* Initializing state (for IP offloaders) */
+#define SS_UNCONNECTED 2 /* Created */
+#define SS_BOUND 3 /* Bind or autobind */
+#define SS_LISTENING 4 /* Listen called */
+#define SS_CONNECTING 5 /* Connect initiated */
+#define SS_CONNECTED 6 /* Connect has completed */
+#define SS_ACCEPTING 7 /* Accepting in progress */
+#define SS_ACCEPTWAIT 8 /* Waiting for accept to harvest */
+#define SS_CLOSEWAIT 9 /* Remote has closed */
+#define SS_CLOSING 10 /* Protocol close in progress */
+#define SS_CLOSED 11 /* Protocol layers done, not close()d */
+ /* FIXME: need state for shutdown handling */
+ uint8_t s_data;
+ struct sockaddrs s_addr[3];
+#define SADDR_SRC 0
+#define SADDR_DST 1
+#define SADDR_TMP 2
+ uint8_t s_flag;
+#define SFLAG_ATMP 1 /* Use SADDR_TMP */
+ uint8_t s_iflag; /* Flags touched in IRQ handlers */
+#define SI_DATA 1 /* Data is ready */
+#define SI_EOF 2 /* At EOF */
+#define SI_THROTTLE 4 /* Transmit is throttled */
+ uint8_t s_lcn; /* Logical channel (for link layer) */
+ uint8_t s_lcnflag; /* LCN private flags */
+};
+
+#define NSOCKTYPE 3
+#define SOCKTYPE_TCP 1
+#define SOCKTYPE_UDP 2
+#define SOCKTYPE_RAW 3
+
+struct netdevice
+{
+ uint8_t mac_len;
+ const char *name;
+ uint16_t flags;
+#define IFF_POINTOPOINT 1
+};
+
+extern struct socket sockets[NSOCKET];
+extern uint32_t our_address;
+
/* Network layer syscalls */
extern arg_t _socket(void);
extern arg_t _listen(void);
extern int is_netd(void);
extern int sock_write(inoptr ino, uint8_t flag);
extern bool issocket(inoptr ino);
+
+/* Hooks between the network implementation and the socket layer */
+extern int net_init(struct socket *s);
+extern int net_bind(struct socket *s);
+extern int net_connect(struct socket *s);
+extern void net_close(struct socket *s);
+extern int net_listen(struct socket *s);
+extern arg_t net_read(struct socket *s, uint8_t flag);
+extern arg_t net_write(struct socket *s, uint8_t flag);
+extern arg_t net_ioctl(uint8_t op, void *p);
+extern void netdev_init(void);
+
+extern struct netdevice net_dev;
#ifdef CONFIG_NET
-#ifndef NSOCKET
-#define NSOCKET 8
-#endif
-
-
-struct sockaddrs {
- uint32_t addr;
- uint16_t port;
-};
-
-struct socket
-{
- inoptr s_inode;
- uint8_t s_type;
- uint8_t s_error;
-
- uint8_t s_state;
-#define SS_UNUSED 0 /* Free slot */
-#define SS_UNCONNECTED 1 /* Created */
-#define SS_BOUND 2 /* Bind or autobind */
-#define SS_LISTENING 3 /* Listen called */
-#define SS_CONNECTING 4 /* Connect initiated */
-#define SS_CONNECTED 5 /* Connect has completed */
-#define SS_ACCEPTWAIT 6 /* Waiting for accept to harvest */
-#define SS_CLOSED 7 /* Protocol layers done, not close()d */
- /* FIXME: need state for shutdown handling */
- uint8_t s_data;
- struct sockaddrs s_addr[3];
-#define SADDR_SRC 0
-#define SADDR_DST 1
-#define SADDR_TMP 2
- uint8_t s_flag;
-#define SFLAG_ATMP 1 /* Use SADDR_TMP */
-};
-
struct socket sockets[NSOCKET];
uint32_t our_address;
static uint16_t nextauto = 5000;
struct socket *s = &sockets[ino->c_node.i_nlink];
used(flag);
- if (s->s_state != SS_CONNECTED) {
- /* FIXME: handle shutdown states properly */
- if (s->s_state == SS_CLOSED) {
- ssig(udata.u_ptab, SIGPIPE);
- udata.u_error = EPIPE;
- } else
- udata.u_error = EINVAL;
- return -1;
+ /* FIXME: IRQ protection */
+ while(1) {
+ if (s->s_state != SS_CONNECTED && s->s_state != SS_CLOSING) {
+ /* FIXME: handle shutdown states properly */
+ if (s->s_state >= SS_CLOSEWAIT) {
+ ssig(udata.u_ptab, SIGPIPE);
+ udata.u_error = EPIPE;
+ } else
+ udata.u_error = EINVAL;
+ return -1;
+ }
+ if (s->s_iflag == SI_THROTTLE || net_write(s, flag) == -2) {
+ s->s_iflag |= SI_THROTTLE;
+ if (psleep_flags(&s->s_iflag, flag) == -1)
+ return -1;
+ }
}
- /* For now */
- udata.u_error = EINVAL;
- return -1;
}
int netd_sock_read(inoptr ino, uint8_t flag)
return -1;
}
+struct socket *sock_alloc_accept(struct socket *s)
+{
+ struct socket *n;
+ int8_t i = alloc_socket();
+ if (i == -1)
+ return NULL;
+ n = &sockets[i];
+
+ memcpy(n, s, sizeof(*n));
+ n->s_state = SS_ACCEPTING;
+ n->s_data = s - sockets;
+ return n;
+}
+
+void sock_wake_listener(struct socket *s)
+{
+ wakeup(&sockets[s->s_data]);
+}
+
void sock_close(inoptr ino)
{
/* For the moment */
struct socket *s = &sockets[ino->c_node.i_nlink];
+ net_close(s);
sock_wait_enter(s, 0, SS_CLOSED);
- sockets[ino->c_node.i_nlink].s_state = SS_UNUSED;
+ s->s_state = SS_UNUSED;
}
// sa.port = nextauto++;
// } while(sock_find(SADDR_SRC, &sa));
memcpy(&s->s_addr[SADDR_SRC], &sa, sizeof(sa));
- s->s_state = SS_BOUND;
- return 0;
+ return net_bind(s);
}
static struct socket *sock_find_local(uint32_t addr, uint16_t port)
uint8_t priv;
};
-#define NSOCKTYPE 3
struct sockinfo socktypes[NSOCKTYPE] = {
{ AF_INET, SOCK_STREAM, IPPROTO_TCP, 0 },
-#define SOCKTYPE_TCP 1
{ AF_INET, SOCK_DGRAM, IPPROTO_UDP, 0 },
-#define SOCKTYPE_UDP 2
{ AF_INET, SOCK_RAW, 0, 0 }
-#define SOCKTYPE_RAW 3
};
arg_t make_socket(struct sockinfo *s, int8_t *np)
if (s->priv && esuper())
return -1;
- /* Start by getting the file and inode table entries */
- if ((uindex = uf_alloc()) == -1)
- return -1;
- if ((oftindex = oft_alloc()) == -1)
- goto nooft;
-
if (np)
n = *np;
else {
n = alloc_socket();
if (n == -1)
- goto noalloc;
+ return -1;
}
+ sockets[n].s_type = s - socktypes; /* Pointer or uint8_t best ? */
+ sockets[n].s_state = SS_INIT;
+
+ if (net_init(&sockets[n]) == -1)
+ goto nosock;
+
+ /* Start by getting the file and inode table entries */
+ if ((uindex = uf_alloc()) == -1)
+ goto nosock;
+ if ((oftindex = oft_alloc()) == -1)
+ goto nooft;
+
/* We need an inode : FIXME - do we want a pipedev aka Unix ? */
if (!(ino = i_open(root_dev, 0)))
goto noalloc;
/* The nlink cheat needs to be taught to fsck! */
ino->c_node.i_mode = F_SOCK | 0777;
ino->c_node.i_nlink = n; /* Cheat !! */
+ sockets[n].s_inode = ino;
of_tab[oftindex].o_inode = ino;
of_tab[oftindex].o_access = O_RDWR;
udata.u_files[uindex] = oftindex;
- sockets[n].s_inode = ino;
- sockets[n].s_type = s - socktypes; /* Pointer or uint8_t best ? */
- sockets[n].s_state = SS_UNCONNECTED;
-
+ sock_wait_leave(&sockets[n], 0, SS_INIT);
if (np)
*np = n;
return uindex;
oft_deref(oftindex); /* Will call i_deref! */
nooft:
udata.u_files[uindex] = NO_FILE;
+nosock:
+ sockets[n].s_state = SS_UNUSED;
return -1;
}
return -1;
}
/* Call the protocol services */
- s->s_state = SS_LISTENING;
- return 0;
+ return net_listen(s);
}
#undef fd
s->s_addr[SADDR_SRC].addr = sin.sin_addr.s_addr;
s->s_addr[SADDR_SRC].port = sin.sin_port;
- s->s_state = SS_BOUND;
- return 0;
+ return net_bind(s);
}
#undef fd
return -1;
s->s_addr[SADDR_DST].addr = sin.sin_addr.s_addr;
s->s_addr[SADDR_DST].port = sin.sin_port;
- s->s_state = SS_CONNECTING;
- /* Protocol op to kick off */
+ if (net_connect(s))
+ return -1;
}
if (sock_wait_leave(s, 0, SS_CONNECTING))