From ecb8e59d6d2f8645229435997700789a06e65007 Mon Sep 17 00:00:00 2001 From: Kelvin Sherlock Date: Mon, 7 May 2012 22:41:45 -0400 Subject: [PATCH] more sock options. --- marignotti.h | 9 ++++ mgetsockopt.c | 128 +++++++++++++++++++++++--------------------------- msetsockopt.c | 128 +++++++++++++++++++++++++++++++++++--------------- 3 files changed, 158 insertions(+), 107 deletions(-) diff --git a/marignotti.h b/marignotti.h index 174b95f..b637ff4 100644 --- a/marignotti.h +++ b/marignotti.h @@ -33,6 +33,11 @@ typedef struct Entry { unsigned _NONBLOCK:1; //setsockopt(2) + unsigned _DEBUG:1; + unsigned _REUSEADDR:1; + unsigned _REUSEPORT:1; + unsigned _KEEPALIVE:1; + unsigned _OOBINLINE:1; unsigned _LINGER:1; unsigned _NOSIGPIPE:1; @@ -60,6 +65,8 @@ typedef struct xsockaddr_in { #define DecBusy() asm { jsl 0xE10068 } #define Resched() asm { cop 0x7f } +#define BusyFlag ((byte *)0xE100FFl) + #define SEI() asm { sei } #define CLI() asm { cli } @@ -95,6 +102,8 @@ int mgetsockopt(Entry *, void *p1, void *p2, void *p3, void *p4, void *p5); int msetsockopt(Entry *, void *p1, void *p2, void *p3, void *p4, void *p5); int mioctl(Entry *, void *p1, void *p2, void *p3, void *p4, void *p5); +int mgetsockname(Entry *, void *p1, void *p2, void *p3, void *p4, void *p5); +int mselect(Entry *, void *p1, void *p2, void *p3, void *p4, void *p5); diff --git a/mgetsockopt.c b/mgetsockopt.c index 79e5851..2d5cd75 100644 --- a/mgetsockopt.c +++ b/mgetsockopt.c @@ -30,6 +30,38 @@ static void ticks_to_timeval(LongWord ticks, struct timeval *tv) } +static int set_flag(void *p, int size, int flag) +{ + if (size == 4) + { + *(long *)p = flag; + return 0; + } + if (size == 2) + { + *(int *)p = flag; + return 0; + } + + return EINVAL; +} + +static int set_flag_long(void *p, int size, long flag) +{ + if (size == 4) + { + *(long *)p = flag; + return 0; + } + if (size == 2) + { + *(int *)p = flag; + return 0; + } + + return EINVAL; +} + int mgetsockopt(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5) { Word terr; @@ -44,68 +76,43 @@ int mgetsockopt(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5) if (!optval) return EINVAL; + // todo -- should set optlen = returned size. + // todo -- linger switch (optname) { case SO_TYPE: // todo... non-stream - if (optlen == 4) - { - *(LongWord *)optval = SOCK_STREAM; - return 0; - } - if (optlen == 2) - { - *(Word *)optval = SOCK_STREAM; - return 0; - } + return set_flag(optval, optlen, SOCK_STREAM); break; + case SO_DEBUG: + return set_flag(optval, optlen, e->_DEBUG); + break; + + case SO_REUSEADDR: + return set_flag(optval, optlen, e->_REUSEADDR); + break; + + case SO_REUSEPORT: + return set_flag(optval, optlen, e->_REUSEPORT); + break; + + case SO_KEEPALIVE: + return set_flag(optval, optlen, e->_KEEPALIVE); + break; case SO_OOBINLINE: - if (optlen == 4) - { - *(LongWord *)optval = 1; - return 0; - } - if (optlen == 2) - { - *(Word *)optval = 1; - return 0; - } - if (optlen == 1) - { - *(char *)optval = 1; - return 0; - } + return set_flag(optval, optlen, 1); break; - case SO_SNDLOWAT: - if (optlen == 4) - { - *(LongWord *)optval = e->_SNDLOWAT; - return 0; - } - if (optlen == 2) - { - *(Word *)optval = e->_SNDLOWAT; - return 0; - } + return set_flag(optval, optlen, e->_SNDLOWAT); break; case SO_RCVLOWAT: - if (optlen == 4) - { - *(LongWord *)optval = e->_RCVLOWAT; - return 0; - } - if (optlen == 2) - { - *(Word *)optval = e->_RCVLOWAT; - return 0; - } + return set_flag(optval, optlen, e->_RCVLOWAT); break; case SO_SNDTIMEO: @@ -135,19 +142,11 @@ int mgetsockopt(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5) IncBusy(); terr = TCPIPStatusTCP(e->ipid, &e->sr); t = _toolErr; - DecBusy(); if (t) terr = t; + e->terr = terr; + DecBusy(); - if (optlen == 4) - { - *(LongWord *)optval = e->sr.srRcvQueued; - return 0; - } - if (optlen == 2) - { - *(Word *)optval = e->sr.srRcvQueued; - return 0; - } + return set_flag_long(optval, optlen, e->sr.srRcvQueued); break; #endif @@ -157,20 +156,11 @@ int mgetsockopt(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5) IncBusy(); terr = TCPIPStatusTCP(e->ipid, &e->sr); t = _toolErr; - DecBusy(); if (t) terr = t; + e->terr = terr; + DecBusy(); - if (optlen == 4) - { - *(LongWord *)optval = e->sr.srSndQueued; - return 0; - } - if (optlen == 2) - { - *(Word *)optval = e->sr.srSndQueued; - return 0; - } - return EINVAL; + return set_flag_long(optval, optlen, e->sr.srSndQueued); break; #endif diff --git a/msetsockopt.c b/msetsockopt.c index 8df0e72..0751c5e 100644 --- a/msetsockopt.c +++ b/msetsockopt.c @@ -30,11 +30,53 @@ static LongWord timeval_to_ticks(struct timeval tv) return rv; } +static boolean get_flag(void *p, int size, Word *flag) +{ + if (size == 4) + { + *flag = *(LongWord *)flag; + return true; + } + if (size == 2) + { + *flag = *(Word *)flag; + return true; + } + if (size == 1) + { + *flag = *(Byte *)flag; + return true; + } + + return false; +} + +static boolean get_flag_long(void *p, int size, LongWord *flag) +{ + if (size == 4) + { + *flag = *(LongWord *)flag; + return true; + } + if (size == 2) + { + *flag = *(Word *)flag; + return true; + } + if (size == 1) + { + *flag = *(Byte *)flag; + return true; + } + + return false; +} int msetsockopt(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5) { Word terr; Word t; + Word flag; int level = *(int *)p1; int optname = *(int *)p2; @@ -49,52 +91,62 @@ int msetsockopt(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5) switch(optname) { + case SO_DEBUG: + if (!get_flag(optval, optlen, &flag)) + return EINVAL; + e->_DEBUG = flag ? 1 : 0; + return 0; + + case SO_REUSEADDR: + if (!get_flag(optval, optlen, &flag)) + return EINVAL; + e->_REUSEADDR = flag ? 1 : 0; + return 0; + + case SO_REUSEPORT: + if (!get_flag(optval, optlen, &flag)) + return EINVAL; + e->_REUSEPORT = flag ? 1 : 0; + return 0; + + case SO_DEBUG: + if (!get_flag(optval, optlen, &flag)) + return EINVAL; + e->_DEBUG = flag ? 1 : 0; + return 0; + + case SO_KEEPALIVE: + if (!get_flag(optval, optlen, &flag)) + return EINVAL; + e->_KEEPALIVE = flag ? 1 : 0; + return 0; + case SO_OOBINLINE: - if (optlen == 4) - { - Word flag = *(LongWord *)optval; - if (!flag) return EINVAL; - return 0; - } - if (optlen == 2) - { - Word flag = *(Word *)optval; - if (!flag) return EINVAL; - return 0; - } - if (optlen == 1) - { - Word flag = *(char *)optval; - if (!flag) return EINVAL; - return 0; - } + // always 1. + if (!get_flag(optval, optlen, &flag)) + return EINVAL; + if (!flag) + return EINVAL; + return 0; break; + case SO_SNDLOWAT: - if (optlen == 4) - { - e->_SNDLOWAT = *(LongWord *)optval; - return 0; - } - if (optlen == 2) - { - e->_SNDLOWAT = *(Word *)optval; - return 0; - } + // 0 is valid. + if (!get_flag_long(optval, optlen, &e->_SNDLOWAT)) + return EINVAL; + return 0; break; case SO_RCVLOWAT: - if (optlen == 4) - { - e->_RCVLOWAT = *(LongWord *)optval; - return 0; - } - if (optlen == 2) - { - e->_RCVLOWAT = *(Word *)optval; - return 0; - } + // min size = 1. + if (!get_flag_long(optval, optlen, &e->_RCVLOWAT)) + return EINVAL; + if (e->_RCVLOWAT) return 0; + + e->_RCVLOWAT = 1; + return EINVAL; break; case SO_SNDTIMEO: