mirror of
https://github.com/ksherlock/marignotti.git
synced 2024-09-27 14:57:01 +00:00
socket options.
This commit is contained in:
parent
94cd1304c4
commit
20ae337205
6
driver.c
6
driver.c
@ -32,9 +32,6 @@ int queue_command(Entry *e, Word command, LongWord cookie, LongWord timeout)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#pragma databank 1
|
#pragma databank 1
|
||||||
|
|
||||||
int driver(
|
int driver(
|
||||||
@ -53,6 +50,7 @@ int driver(
|
|||||||
return mattach(socknum, p1, p2, p3, p4, p5);
|
return mattach(socknum, p1, p2, p3, p4, p5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
e = find_entry(socknum);
|
e = find_entry(socknum);
|
||||||
if (!e)
|
if (!e)
|
||||||
{
|
{
|
||||||
@ -153,9 +151,11 @@ int driver(
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PRU_CO_GETOPT:
|
case PRU_CO_GETOPT:
|
||||||
|
return mgetsockopt(e, p1, p2, p3, p4, p5);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PRU_CO_SETOPT:
|
case PRU_CO_SETOPT:
|
||||||
|
return msetsockopt(e, p1, p2, p3, p4, p5);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PRU_SELECT:
|
case PRU_SELECT:
|
||||||
|
@ -39,7 +39,8 @@ typedef struct Entry {
|
|||||||
|
|
||||||
LongWord _SNDLOWAT;
|
LongWord _SNDLOWAT;
|
||||||
LongWord _RCVLOWAT;
|
LongWord _RCVLOWAT;
|
||||||
Word _RCVTIMEO;
|
LongWord _RCVTIMEO;
|
||||||
|
LongWord _SNDTIMEO;
|
||||||
Word _LINGER_SEC;
|
Word _LINGER_SEC;
|
||||||
|
|
||||||
|
|
||||||
|
179
mgetsockopt.c
Normal file
179
mgetsockopt.c
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
#include "marignotti.h"
|
||||||
|
#include <gno/kerntool.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#pragma noroot
|
||||||
|
#pragma optimize 79
|
||||||
|
|
||||||
|
static void ticks_to_timeval(LongWord ticks, struct timeval *tv)
|
||||||
|
{
|
||||||
|
LongDivRec qr;
|
||||||
|
|
||||||
|
if (ticks == 0)
|
||||||
|
{
|
||||||
|
tv->tv_sec = 0;
|
||||||
|
tv->tv_usec = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qr = LongDivide(ticks, 60);
|
||||||
|
|
||||||
|
tv->tv_sec = qr.quotient;
|
||||||
|
tv->tv_usec = Multiply(qr.remainder, 16667);
|
||||||
|
// qr.remainder * 1,000,000 / 60
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int mgetsockopt(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5)
|
||||||
|
{
|
||||||
|
Word terr;
|
||||||
|
Word t;
|
||||||
|
|
||||||
|
int level = *(int *)p1;
|
||||||
|
int optname = *(int *)p2;
|
||||||
|
void *optval = (void *)p3;
|
||||||
|
int optlen = p4 ? *(int *)p4 : 0;
|
||||||
|
|
||||||
|
if (level != SOL_SOCKET) return EINVAL;
|
||||||
|
if (!optval) return EINVAL;
|
||||||
|
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case SO_SNDLOWAT:
|
||||||
|
if (optlen == 4)
|
||||||
|
{
|
||||||
|
*(LongWord *)optval = e->_SNDLOWAT;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (optlen == 2)
|
||||||
|
{
|
||||||
|
*(Word *)optval = e->_SNDLOWAT;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SO_RCVLOWAT:
|
||||||
|
if (optlen == 4)
|
||||||
|
{
|
||||||
|
*(LongWord *)optval = e->_RCVLOWAT;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (optlen == 2)
|
||||||
|
{
|
||||||
|
*(Word *)optval = e->_RCVLOWAT;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SO_SNDTIMEO:
|
||||||
|
if (optlen == sizeof(struct timeval))
|
||||||
|
{
|
||||||
|
// stored as ticks aka seconds * 60.
|
||||||
|
struct timeval *tv = (struct timeval *)optval;
|
||||||
|
|
||||||
|
ticks_to_timeval(e->_SNDTIMEO, tv);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SO_RCVTIMEO:
|
||||||
|
if (optlen == sizeof(struct timeval))
|
||||||
|
{
|
||||||
|
// stored as ticks aka seconds * 60.
|
||||||
|
struct timeval *tv = (struct timeval *)optval;
|
||||||
|
|
||||||
|
ticks_to_timeval(e->_RCVTIMEO, tv);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifdef SO_NREAD
|
||||||
|
case SO_NREAD:
|
||||||
|
IncBusy();
|
||||||
|
terr = TCPIPStatusTCP(e->ipid, &e->sr);
|
||||||
|
t = _toolErr;
|
||||||
|
DecBusy();
|
||||||
|
if (t) terr = t;
|
||||||
|
|
||||||
|
if (optlen == 4)
|
||||||
|
{
|
||||||
|
*(LongWord *)optval = e->sr.srRcvQueued;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (optlen == 2)
|
||||||
|
{
|
||||||
|
*(Word *)optval = e->sr.srRcvQueued;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SO_NWRITE
|
||||||
|
case SO_NWRITE:
|
||||||
|
IncBusy();
|
||||||
|
terr = TCPIPStatusTCP(e->ipid, &e->sr);
|
||||||
|
t = _toolErr;
|
||||||
|
DecBusy();
|
||||||
|
if (t) terr = t;
|
||||||
|
|
||||||
|
if (optlen == 4)
|
||||||
|
{
|
||||||
|
*(LongWord *)optval = e->sr.srSndQueued;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (optlen == 2)
|
||||||
|
{
|
||||||
|
*(Word *)optval = e->sr.srSndQueued;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return EINVAL;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
}
|
125
msetsockopt.c
Normal file
125
msetsockopt.c
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
#include "marignotti.h"
|
||||||
|
#include <gno/kerntool.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
#pragma noroot
|
||||||
|
#pragma optimize 79
|
||||||
|
|
||||||
|
static LongWord timeval_to_ticks(struct timeval tv)
|
||||||
|
{
|
||||||
|
LongWord rv;
|
||||||
|
|
||||||
|
rv = 0;
|
||||||
|
if (tv.tv_usec || tv.tv_sec)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (tv.tv_sec)
|
||||||
|
rv = 60 * tv.tv_sec;
|
||||||
|
|
||||||
|
// usec = 1/1,000,000
|
||||||
|
// split into 60
|
||||||
|
if (tv.tv_usec)
|
||||||
|
rv += ((tv.tv_usec + 16666) / 16667);
|
||||||
|
|
||||||
|
if (!rv) rv = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int msetsockopt(Entry *e, void *p1, void *p2, void *p3, void *p4, void *p5)
|
||||||
|
{
|
||||||
|
Word terr;
|
||||||
|
Word t;
|
||||||
|
|
||||||
|
int level = *(int *)p1;
|
||||||
|
int optname = *(int *)p2;
|
||||||
|
void *optval = (void *)p3;
|
||||||
|
int optlen = p4 ? *(int *)p4 : 0;
|
||||||
|
|
||||||
|
if (level != SOL_SOCKET) return EINVAL;
|
||||||
|
if (!optval) return EINVAL;
|
||||||
|
|
||||||
|
// todo -- linger.
|
||||||
|
// todo -- oobinline (error if 0?)
|
||||||
|
switch(optname)
|
||||||
|
{
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SO_SNDLOWAT:
|
||||||
|
if (optlen == 4)
|
||||||
|
{
|
||||||
|
e->_SNDLOWAT = *(LongWord *)optval;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (optlen == 2)
|
||||||
|
{
|
||||||
|
e->_SNDLOWAT = *(Word *)optval;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case SO_RCVLOWAT:
|
||||||
|
if (optlen == 4)
|
||||||
|
{
|
||||||
|
e->_RCVLOWAT = *(LongWord *)optval;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (optlen == 2)
|
||||||
|
{
|
||||||
|
e->_RCVLOWAT = *(Word *)optval;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SO_SNDTIMEO:
|
||||||
|
if (optlen == sizeof(struct timeval))
|
||||||
|
{
|
||||||
|
// stored as ticks aka seconds * 60.
|
||||||
|
struct timeval *tv = (struct timeval *)optval;
|
||||||
|
|
||||||
|
e->_SNDTIMEO = timeval_to_ticks(*tv);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SO_RCVTIMEO:
|
||||||
|
if (optlen == sizeof(struct timeval))
|
||||||
|
{
|
||||||
|
// stored as ticks aka seconds * 60.
|
||||||
|
struct timeval *tv = (struct timeval *)optval;
|
||||||
|
|
||||||
|
e->_RCVTIMEO = timeval_to_ticks(*tv);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return EINVAL;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user