added stio_checksumip(), stio_iphdr_t, stio_icmphdr_t
This commit is contained in:
parent
ef4477ea7c
commit
4396006e7a
307
stio/lib/main.c
307
stio/lib/main.c
@ -40,6 +40,8 @@
|
|||||||
#include <netpacket/packet.h>
|
#include <netpacket/packet.h>
|
||||||
#include <net/if.h>
|
#include <net/if.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#if defined(HAVE_OPENSSL_SSL_H) && defined(HAVE_SSL)
|
#if defined(HAVE_OPENSSL_SSL_H) && defined(HAVE_SSL)
|
||||||
# include <openssl/ssl.h>
|
# include <openssl/ssl.h>
|
||||||
# if defined(HAVE_OPENSSL_ERR_H)
|
# if defined(HAVE_OPENSSL_ERR_H)
|
||||||
@ -126,11 +128,11 @@ static void tcp_sck_on_disconnect (stio_dev_sck_t* tcp)
|
|||||||
switch (STIO_DEV_SCK_GET_PROGRESS(tcp))
|
switch (STIO_DEV_SCK_GET_PROGRESS(tcp))
|
||||||
{
|
{
|
||||||
case STIO_DEV_SCK_CONNECTING:
|
case STIO_DEV_SCK_CONNECTING:
|
||||||
printf ("OUTGOING TCP DISCONNECTED - FAILED TO CONNECT (%d) TO REMOTE SERVER\n", (int)tcp->sck);
|
printf ("OUTGOING SESSION DISCONNECTED - FAILED TO CONNECT (%d) TO REMOTE SERVER\n", (int)tcp->sck);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STIO_DEV_SCK_CONNECTING_SSL:
|
case STIO_DEV_SCK_CONNECTING_SSL:
|
||||||
printf ("OUTGOING TCP DISCONNECTED - FAILED TO SSL-CONNECT (%d) TO REMOTE SERVER\n", (int)tcp->sck);
|
printf ("OUTGOING SESSION DISCONNECTED - FAILED TO SSL-CONNECT (%d) TO REMOTE SERVER\n", (int)tcp->sck);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STIO_DEV_SCK_LISTENING:
|
case STIO_DEV_SCK_LISTENING:
|
||||||
@ -150,7 +152,7 @@ static void tcp_sck_on_disconnect (stio_dev_sck_t* tcp)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
printf ("TCP DISCONNECTED - THIS MUST NOT HAPPEN (%d - %x)\n", (int)tcp->sck, (unsigned int)tcp->state);
|
printf ("SOCKET DEVICE DISCONNECTED (%d - %x)\n", (int)tcp->sck, (unsigned int)tcp->state);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -203,6 +205,8 @@ else
|
|||||||
|
|
||||||
printf ("ENABLING READING..............................\n");
|
printf ("ENABLING READING..............................\n");
|
||||||
stio_dev_sck_read (tcp, 1);
|
stio_dev_sck_read (tcp, 1);
|
||||||
|
|
||||||
|
//stio_dev_sck_timedread (tcp, 1, 1000);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -237,12 +241,14 @@ free (xxx);
|
|||||||
if (n <= -1) return -1;
|
if (n <= -1) return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
printf ("DISABLING READING..............................\n");
|
||||||
|
stio_dev_sck_read (tcp, 0);
|
||||||
|
|
||||||
/* post the write finisher */
|
/* post the write finisher */
|
||||||
n = stio_dev_sck_write (tcp, STIO_NULL, 0, STIO_NULL, STIO_NULL);
|
n = stio_dev_sck_write (tcp, STIO_NULL, 0, STIO_NULL, STIO_NULL);
|
||||||
if (n <= -1) return -1;
|
if (n <= -1) return -1;
|
||||||
|
|
||||||
printf ("DISABLING READING..............................\n");
|
|
||||||
stio_dev_sck_read (tcp, 0);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* return 1; let the main loop to read more greedily without consulting the multiplexer */
|
/* return 1; let the main loop to read more greedily without consulting the multiplexer */
|
||||||
@ -250,6 +256,26 @@ printf ("DISABLING READING..............................\n");
|
|||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
|
||||||
|
static void pro_on_close (stio_dev_pro_t* dev, stio_dev_pro_sid_t sid)
|
||||||
|
{
|
||||||
|
printf (">>>>>>>>>>>>> ON CLOSE OF SLAVE %d.\n", sid);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pro_on_read (stio_dev_pro_t* dev, const void* data, stio_iolen_t dlen, stio_dev_pro_sid_t sid)
|
||||||
|
{
|
||||||
|
printf ("PROCESS READ DATA on SLAVE[%d]... [%.*s]\n", (int)sid, (int)dlen, (char*)data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int pro_on_write (stio_dev_pro_t* dev, stio_iolen_t wrlen, void* wrctx)
|
||||||
|
{
|
||||||
|
printf ("PROCESS WROTE DATA...\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========================================================================= */
|
||||||
|
|
||||||
static int arp_sck_on_read (stio_dev_sck_t* dev, const void* data, stio_iolen_t dlen, const stio_sckaddr_t* srcaddr)
|
static int arp_sck_on_read (stio_dev_sck_t* dev, const void* data, stio_iolen_t dlen, const stio_sckaddr_t* srcaddr)
|
||||||
{
|
{
|
||||||
stio_etharp_pkt_t* eap;
|
stio_etharp_pkt_t* eap;
|
||||||
@ -272,26 +298,232 @@ static int arp_sck_on_write (stio_dev_sck_t* dev, stio_iolen_t wrlen, void* wrct
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void arp_sck_on_disconnect (stio_dev_sck_t* dev)
|
||||||
|
{
|
||||||
|
printf ("SHUTTING DOWN ARP SOCKET %d...\n", dev->sck);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int setup_arp_tester (stio_t* stio)
|
||||||
|
{
|
||||||
|
stio_sckaddr_t ethdst;
|
||||||
|
stio_etharp_pkt_t etharp;
|
||||||
|
stio_dev_sck_make_t sck_make;
|
||||||
|
stio_dev_sck_t* sck;
|
||||||
|
|
||||||
|
memset (&sck_make, 0, STIO_SIZEOF(sck_make));
|
||||||
|
sck_make.type = STIO_DEV_SCK_ARP;
|
||||||
|
//sck_make.type = STIO_DEV_SCK_ARP_DGRAM;
|
||||||
|
sck_make.on_write = arp_sck_on_write;
|
||||||
|
sck_make.on_read = arp_sck_on_read;
|
||||||
|
sck_make.on_disconnect = arp_sck_on_disconnect;
|
||||||
|
sck = stio_dev_sck_make (stio, 0, &sck_make);
|
||||||
|
if (!sck)
|
||||||
|
{
|
||||||
|
printf ("Cannot make socket device\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//stio_sckaddr_initforeth (ðdst, if_nametoindex("enp0s25.3"), (stio_ethaddr_t*)"\xFF\xFF\xFF\xFF\xFF\xFF");
|
||||||
|
stio_sckaddr_initforeth (ðdst, if_nametoindex("enp0s25.3"), (stio_ethaddr_t*)"\xAA\xBB\xFF\xCC\xDD\xFF");
|
||||||
|
|
||||||
|
memset (ðarp, 0, sizeof(etharp));
|
||||||
|
|
||||||
|
memcpy (etharp.ethhdr.source, "\xB8\x6B\x23\x9C\x10\x76", STIO_ETHADDR_LEN);
|
||||||
|
//memcpy (etharp.ethhdr.dest, "\xFF\xFF\xFF\xFF\xFF\xFF", STIO_ETHADDR_LEN);
|
||||||
|
memcpy (etharp.ethhdr.dest, "\xAA\xBB\xFF\xCC\xDD\xFF", STIO_ETHADDR_LEN);
|
||||||
|
etharp.ethhdr.proto = STIO_CONST_HTON16(STIO_ETHHDR_PROTO_ARP);
|
||||||
|
|
||||||
|
etharp.arphdr.htype = STIO_CONST_HTON16(STIO_ARPHDR_HTYPE_ETH);
|
||||||
|
etharp.arphdr.ptype = STIO_CONST_HTON16(STIO_ARPHDR_PTYPE_IP4);
|
||||||
|
etharp.arphdr.hlen = STIO_ETHADDR_LEN;
|
||||||
|
etharp.arphdr.plen = STIO_IP4ADDR_LEN;
|
||||||
|
etharp.arphdr.opcode = STIO_CONST_HTON16(STIO_ARPHDR_OPCODE_REQUEST);
|
||||||
|
|
||||||
|
memcpy (etharp.arppld.sha, "\xB8\x6B\x23\x9C\x10\x76", STIO_ETHADDR_LEN);
|
||||||
|
|
||||||
|
if (stio_dev_sck_write (sck, ðarp, sizeof(etharp), NULL, ðdst) <= -1)
|
||||||
|
//if (stio_dev_sck_write (sck, ðarp.arphdr, sizeof(etharp) - sizeof(etharp.ethhdr), NULL, ðaddr) <= -1)
|
||||||
|
{
|
||||||
|
printf ("CANNOT WRITE ARP...\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
|
||||||
static void pro_on_close (stio_dev_pro_t* dev, stio_dev_pro_sid_t sid)
|
struct icmpxtn_t
|
||||||
{
|
{
|
||||||
printf (">>>>>>>>>>>>> ON CLOSE OF SLAVE %d.\n", sid);
|
stio_uint16_t icmp_seq;
|
||||||
|
stio_tmridx_t tmout_jobidx;
|
||||||
|
int reply_received;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct icmpxtn_t icmpxtn_t;
|
||||||
|
|
||||||
|
static int schedule_icmp_wait (stio_dev_sck_t* dev);
|
||||||
|
|
||||||
|
static void send_icmp (stio_dev_sck_t* dev, stio_uint16_t seq)
|
||||||
|
{
|
||||||
|
stio_sckaddr_t dstaddr;
|
||||||
|
stio_ip4addr_t ia;
|
||||||
|
stio_icmphdr_t* icmphdr;
|
||||||
|
stio_uint8_t buf[512];
|
||||||
|
|
||||||
|
inet_pton (AF_INET, "192.168.1.131", &ia);
|
||||||
|
stio_sckaddr_initforip4 (&dstaddr, 0, &ia);
|
||||||
|
|
||||||
|
memset(buf, 0, STIO_SIZEOF(buf));
|
||||||
|
icmphdr = (stio_icmphdr_t*)buf;
|
||||||
|
icmphdr->type = STIO_ICMP_ECHO_REQUEST;
|
||||||
|
icmphdr->u.echo.id = STIO_CONST_HTON16(100);
|
||||||
|
icmphdr->u.echo.seq = stio_hton16(seq);
|
||||||
|
|
||||||
|
memset (&buf[STIO_SIZEOF(*icmphdr)], 'A', STIO_SIZEOF(buf) - STIO_SIZEOF(*icmphdr));
|
||||||
|
icmphdr->checksum = stio_checksumip (icmphdr, STIO_SIZEOF(buf));
|
||||||
|
|
||||||
|
if (stio_dev_sck_write (dev, buf, STIO_SIZEOF(buf), NULL, &dstaddr) <= -1)
|
||||||
|
{
|
||||||
|
printf ("CANNOT WRITE ICMP...\n");
|
||||||
|
stio_dev_sck_halt (dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (schedule_icmp_wait (dev) <= -1)
|
||||||
|
{
|
||||||
|
printf ("CANNOT SCHEDULE ICMP WAIT...\n");
|
||||||
|
stio_dev_sck_halt (dev);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pro_on_read (stio_dev_pro_t* dev, const void* data, stio_iolen_t dlen, stio_dev_pro_sid_t sid)
|
static void on_icmp_due (stio_t* stio, const stio_ntime_t* now, stio_tmrjob_t* tmrjob)
|
||||||
{
|
{
|
||||||
printf ("PROCESS READ DATA on SLAVE[%d]... [%.*s]\n", (int)sid, (int)dlen, (char*)data);
|
stio_dev_sck_t* dev;
|
||||||
|
icmpxtn_t* icmpxtn;
|
||||||
|
|
||||||
|
dev = tmrjob->ctx;
|
||||||
|
icmpxtn = (icmpxtn_t*)(dev + 1);
|
||||||
|
|
||||||
|
if (icmpxtn->reply_received)
|
||||||
|
icmpxtn->reply_received = 0;
|
||||||
|
else
|
||||||
|
printf ("NO ICMP REPLY RECEIVED....\n");
|
||||||
|
|
||||||
|
send_icmp (dev, ++icmpxtn->icmp_seq);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int schedule_icmp_wait (stio_dev_sck_t* dev)
|
||||||
|
{
|
||||||
|
icmpxtn_t* icmpxtn;
|
||||||
|
stio_tmrjob_t tmrjob;
|
||||||
|
stio_ntime_t fire_after;
|
||||||
|
|
||||||
|
icmpxtn = (icmpxtn_t*)(dev + 1);
|
||||||
|
stio_inittime (&fire_after, 2, 0);
|
||||||
|
|
||||||
|
memset (&tmrjob, 0, STIO_SIZEOF(tmrjob));
|
||||||
|
tmrjob.ctx = dev;
|
||||||
|
stio_gettime (&tmrjob.when);
|
||||||
|
stio_addtime (&tmrjob.when, &fire_after, &tmrjob.when);
|
||||||
|
tmrjob.handler = on_icmp_due;
|
||||||
|
tmrjob.idxptr = &icmpxtn->tmout_jobidx;
|
||||||
|
|
||||||
|
assert (icmpxtn->tmout_jobidx == STIO_TMRIDX_INVALID);
|
||||||
|
|
||||||
|
return (stio_instmrjob (dev->stio, &tmrjob) == STIO_TMRIDX_INVALID)? -1: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int icmp_sck_on_read (stio_dev_sck_t* dev, const void* data, stio_iolen_t dlen, const stio_sckaddr_t* srcaddr)
|
||||||
|
{
|
||||||
|
icmpxtn_t* icmpxtn;
|
||||||
|
stio_iphdr_t* iphdr;
|
||||||
|
stio_icmphdr_t* icmphdr;
|
||||||
|
|
||||||
|
/* when received, the data contains the IP header.. */
|
||||||
|
icmpxtn = (icmpxtn_t*)(dev + 1);
|
||||||
|
|
||||||
|
if (dlen < STIO_SIZEOF(*iphdr) + STIO_SIZEOF(*icmphdr))
|
||||||
|
{
|
||||||
|
printf ("INVALID ICMP PACKET.. TOO SHORT...%d\n", (int)dlen);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* TODO: consider IP options... */
|
||||||
|
iphdr = (stio_iphdr_t*)data;
|
||||||
|
icmphdr = (stio_icmphdr_t*)((stio_uint8_t*)data + (iphdr->ihl * 4));
|
||||||
|
|
||||||
|
/* TODO": check srcaddr against target */
|
||||||
|
|
||||||
|
if (icmphdr->type == STIO_ICMP_ECHO_REPLY &&
|
||||||
|
stio_ntoh16(icmphdr->u.echo.seq) == icmpxtn->icmp_seq) /* TODO: more check.. echo.id.. */
|
||||||
|
{
|
||||||
|
icmpxtn->reply_received = 1;
|
||||||
|
printf ("ICMP REPLY RECEIVED...ID %d SEQ %d\n", (int)stio_ntoh16(icmphdr->u.echo.id), (int)stio_ntoh16(icmphdr->u.echo.seq));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf ("GARBAGE ICMP PACKET...LEN %d SEQ %d,%d\n", (int)dlen, (int)icmpxtn->icmp_seq, (int)stio_ntoh16(icmphdr->u.echo.seq));
|
||||||
|
}
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int pro_on_write (stio_dev_pro_t* dev, stio_iolen_t wrlen, void* wrctx)
|
static int icmp_sck_on_write (stio_dev_sck_t* dev, stio_iolen_t wrlen, void* wrctx, const stio_sckaddr_t* dstaddr)
|
||||||
{
|
{
|
||||||
printf ("PROCESS WROTE DATA...\n");
|
/*icmpxtn_t* icmpxtn;
|
||||||
|
|
||||||
|
icmpxtn = (icmpxtn_t*)(dev + 1); */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void icmp_sck_on_disconnect (stio_dev_sck_t* dev)
|
||||||
|
{
|
||||||
|
icmpxtn_t* icmpxtn;
|
||||||
|
|
||||||
|
icmpxtn = (icmpxtn_t*)(dev + 1);
|
||||||
|
|
||||||
|
printf ("SHUTTING DOWN ICMP SOCKET %d...\n", dev->sck);
|
||||||
|
if (icmpxtn->tmout_jobidx != STIO_TMRIDX_INVALID)
|
||||||
|
{
|
||||||
|
|
||||||
|
stio_deltmrjob (dev->stio, icmpxtn->tmout_jobidx);
|
||||||
|
icmpxtn->tmout_jobidx = STIO_TMRIDX_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int setup_ping4_tester (stio_t* stio)
|
||||||
|
{
|
||||||
|
stio_dev_sck_make_t sck_make;
|
||||||
|
stio_dev_sck_t* sck;
|
||||||
|
icmpxtn_t* icmpxtn;
|
||||||
|
|
||||||
|
memset (&sck_make, 0, STIO_SIZEOF(sck_make));
|
||||||
|
sck_make.type = STIO_DEV_SCK_ICMP4;
|
||||||
|
sck_make.on_write = icmp_sck_on_write;
|
||||||
|
sck_make.on_read = icmp_sck_on_read;
|
||||||
|
sck_make.on_disconnect = icmp_sck_on_disconnect;
|
||||||
|
|
||||||
|
sck = stio_dev_sck_make (stio, STIO_SIZEOF(icmpxtn_t), &sck_make);
|
||||||
|
if (!sck)
|
||||||
|
{
|
||||||
|
printf ("Cannot make ICMP4 socket device\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
icmpxtn = (icmpxtn_t*)(sck + 1);
|
||||||
|
icmpxtn->tmout_jobidx = STIO_TMRIDX_INVALID;
|
||||||
|
icmpxtn->icmp_seq = 0;
|
||||||
|
|
||||||
|
/*TODO: stio_dev_sck_setbroadcast (sck, 1);*/
|
||||||
|
|
||||||
|
send_icmp (sck, ++icmpxtn->icmp_seq);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
|
||||||
static stio_t* g_stio;
|
static stio_t* g_stio;
|
||||||
@ -306,7 +538,6 @@ int main ()
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
stio_t* stio;
|
stio_t* stio;
|
||||||
stio_dev_sck_t* sck;
|
|
||||||
stio_dev_sck_t* tcp[3];
|
stio_dev_sck_t* tcp[3];
|
||||||
|
|
||||||
struct sigaction sigact;
|
struct sigaction sigact;
|
||||||
@ -315,7 +546,6 @@ int main ()
|
|||||||
stio_dev_sck_bind_t tcp_bind;
|
stio_dev_sck_bind_t tcp_bind;
|
||||||
stio_dev_sck_make_t tcp_make;
|
stio_dev_sck_make_t tcp_make;
|
||||||
|
|
||||||
stio_dev_sck_make_t sck_make;
|
|
||||||
tcp_server_t* ts;
|
tcp_server_t* ts;
|
||||||
|
|
||||||
#if defined(USE_SSL)
|
#if defined(USE_SSL)
|
||||||
@ -363,6 +593,7 @@ int main ()
|
|||||||
tcp_make.type = STIO_DEV_SCK_TCP4;
|
tcp_make.type = STIO_DEV_SCK_TCP4;
|
||||||
tcp_make.on_write = tcp_sck_on_write;
|
tcp_make.on_write = tcp_sck_on_write;
|
||||||
tcp_make.on_read = tcp_sck_on_read;
|
tcp_make.on_read = tcp_sck_on_read;
|
||||||
|
tcp_make.on_disconnect = tcp_sck_on_disconnect;
|
||||||
tcp[0] = stio_dev_sck_make (stio, STIO_SIZEOF(tcp_server_t), &tcp_make);
|
tcp[0] = stio_dev_sck_make (stio, STIO_SIZEOF(tcp_server_t), &tcp_make);
|
||||||
if (!tcp[0])
|
if (!tcp[0])
|
||||||
{
|
{
|
||||||
@ -382,7 +613,6 @@ int main ()
|
|||||||
|
|
||||||
stio_inittime (&tcp_conn.connect_tmout, 5, 0);
|
stio_inittime (&tcp_conn.connect_tmout, 5, 0);
|
||||||
tcp_conn.on_connect = tcp_sck_on_connect;
|
tcp_conn.on_connect = tcp_sck_on_connect;
|
||||||
tcp_conn.on_disconnect = tcp_sck_on_disconnect;
|
|
||||||
tcp_conn.options = STIO_DEV_SCK_CONNECT_SSL;
|
tcp_conn.options = STIO_DEV_SCK_CONNECT_SSL;
|
||||||
if (stio_dev_sck_connect (tcp[0], &tcp_conn) <= -1)
|
if (stio_dev_sck_connect (tcp[0], &tcp_conn) <= -1)
|
||||||
{
|
{
|
||||||
@ -395,7 +625,7 @@ int main ()
|
|||||||
tcp_make.type = STIO_DEV_SCK_TCP4;
|
tcp_make.type = STIO_DEV_SCK_TCP4;
|
||||||
tcp_make.on_write = tcp_sck_on_write;
|
tcp_make.on_write = tcp_sck_on_write;
|
||||||
tcp_make.on_read = tcp_sck_on_read;
|
tcp_make.on_read = tcp_sck_on_read;
|
||||||
|
tcp_make.on_disconnect = tcp_sck_on_disconnect;
|
||||||
|
|
||||||
tcp[1] = stio_dev_sck_make (stio, STIO_SIZEOF(tcp_server_t), &tcp_make);
|
tcp[1] = stio_dev_sck_make (stio, STIO_SIZEOF(tcp_server_t), &tcp_make);
|
||||||
if (!tcp[1])
|
if (!tcp[1])
|
||||||
@ -419,7 +649,6 @@ int main ()
|
|||||||
|
|
||||||
tcp_lstn.backlogs = 100;
|
tcp_lstn.backlogs = 100;
|
||||||
tcp_lstn.on_connect = tcp_sck_on_connect;
|
tcp_lstn.on_connect = tcp_sck_on_connect;
|
||||||
tcp_lstn.on_disconnect = tcp_sck_on_disconnect;
|
|
||||||
if (stio_dev_sck_listen (tcp[1], &tcp_lstn) <= -1)
|
if (stio_dev_sck_listen (tcp[1], &tcp_lstn) <= -1)
|
||||||
{
|
{
|
||||||
printf ("stio_dev_sck_listen() failed....\n");
|
printf ("stio_dev_sck_listen() failed....\n");
|
||||||
@ -431,6 +660,7 @@ int main ()
|
|||||||
tcp_make.type = STIO_DEV_SCK_TCP4;
|
tcp_make.type = STIO_DEV_SCK_TCP4;
|
||||||
tcp_make.on_write = tcp_sck_on_write;
|
tcp_make.on_write = tcp_sck_on_write;
|
||||||
tcp_make.on_read = tcp_sck_on_read;
|
tcp_make.on_read = tcp_sck_on_read;
|
||||||
|
tcp_make.on_disconnect = tcp_sck_on_disconnect;
|
||||||
|
|
||||||
tcp[2] = stio_dev_sck_make (stio, STIO_SIZEOF(tcp_server_t), &tcp_make);
|
tcp[2] = stio_dev_sck_make (stio, STIO_SIZEOF(tcp_server_t), &tcp_make);
|
||||||
if (!tcp[2])
|
if (!tcp[2])
|
||||||
@ -456,7 +686,6 @@ int main ()
|
|||||||
|
|
||||||
tcp_lstn.backlogs = 100;
|
tcp_lstn.backlogs = 100;
|
||||||
tcp_lstn.on_connect = tcp_sck_on_connect;
|
tcp_lstn.on_connect = tcp_sck_on_connect;
|
||||||
tcp_lstn.on_disconnect = tcp_sck_on_disconnect;
|
|
||||||
if (stio_dev_sck_listen (tcp[2], &tcp_lstn) <= -1)
|
if (stio_dev_sck_listen (tcp[2], &tcp_lstn) <= -1)
|
||||||
{
|
{
|
||||||
printf ("stio_dev_sck_listen() failed....\n");
|
printf ("stio_dev_sck_listen() failed....\n");
|
||||||
@ -464,49 +693,9 @@ int main ()
|
|||||||
}
|
}
|
||||||
|
|
||||||
//stio_dev_sck_sendfile (tcp[2], fd, offset, count);
|
//stio_dev_sck_sendfile (tcp[2], fd, offset, count);
|
||||||
#if 1
|
|
||||||
{
|
|
||||||
|
|
||||||
stio_sckaddr_t ethdst;
|
if (setup_arp_tester(stio) <= -1) goto oops;
|
||||||
stio_etharp_pkt_t etharp;
|
if (setup_ping4_tester(stio) <= -1) goto oops;
|
||||||
|
|
||||||
memset (&sck_make, 0, STIO_SIZEOF(sck_make));
|
|
||||||
sck_make.type = STIO_DEV_SCK_ARP;
|
|
||||||
//sck_make.type = STIO_DEV_SCK_ARP_DGRAM;
|
|
||||||
sck_make.on_write = arp_sck_on_write;
|
|
||||||
sck_make.on_read = arp_sck_on_read;
|
|
||||||
sck = stio_dev_sck_make (stio, 0, &sck_make);
|
|
||||||
if (!sck)
|
|
||||||
{
|
|
||||||
printf ("Cannot make socket device\n");
|
|
||||||
goto oops;
|
|
||||||
}
|
|
||||||
|
|
||||||
//stio_sckaddr_initforeth (ðdst, if_nametoindex("enp0s25.3"), (stio_ethaddr_t*)"\xFF\xFF\xFF\xFF\xFF\xFF");
|
|
||||||
stio_sckaddr_initforeth (ðdst, if_nametoindex("enp0s25.3"), (stio_ethaddr_t*)"\xAA\xBB\xFF\xCC\xDD\xFF");
|
|
||||||
|
|
||||||
memset (ðarp, 0, sizeof(etharp));
|
|
||||||
|
|
||||||
memcpy (etharp.ethhdr.source, "\xB8\x6B\x23\x9C\x10\x76", STIO_ETHADDR_LEN);
|
|
||||||
//memcpy (etharp.ethhdr.dest, "\xFF\xFF\xFF\xFF\xFF\xFF", STIO_ETHADDR_LEN);
|
|
||||||
memcpy (etharp.ethhdr.dest, "\xAA\xBB\xFF\xCC\xDD\xFF", STIO_ETHADDR_LEN);
|
|
||||||
etharp.ethhdr.proto = STIO_CONST_HTON16(STIO_ETHHDR_PROTO_ARP);
|
|
||||||
|
|
||||||
etharp.arphdr.htype = STIO_CONST_HTON16(STIO_ARPHDR_HTYPE_ETH);
|
|
||||||
etharp.arphdr.ptype = STIO_CONST_HTON16(STIO_ARPHDR_PTYPE_IP4);
|
|
||||||
etharp.arphdr.hlen = STIO_ETHADDR_LEN;
|
|
||||||
etharp.arphdr.plen = STIO_IP4ADDR_LEN;
|
|
||||||
etharp.arphdr.opcode = STIO_CONST_HTON16(STIO_ARPHDR_OPCODE_REQUEST);
|
|
||||||
|
|
||||||
memcpy (etharp.arppld.sha, "\xB8\x6B\x23\x9C\x10\x76", STIO_ETHADDR_LEN);
|
|
||||||
|
|
||||||
if (stio_dev_sck_write (sck, ðarp, sizeof(etharp), NULL, ðdst) <= -1)
|
|
||||||
//if (stio_dev_sck_write (sck, ðarp.arphdr, sizeof(etharp) - sizeof(etharp.ethhdr), NULL, ðaddr) <= -1)
|
|
||||||
{
|
|
||||||
printf ("CANNOT WRITE ARP...\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
for (i = 0; i < 5; i++)
|
for (i = 0; i < 5; i++)
|
||||||
|
@ -40,17 +40,6 @@
|
|||||||
#define STIO_MEMCMP(dst,src,count) memcmp(dst,src,count)
|
#define STIO_MEMCMP(dst,src,count) memcmp(dst,src,count)
|
||||||
#define STIO_ASSERT assert
|
#define STIO_ASSERT assert
|
||||||
|
|
||||||
|
|
||||||
struct stio_tmrjob_t
|
|
||||||
{
|
|
||||||
void* ctx;
|
|
||||||
stio_ntime_t when;
|
|
||||||
stio_tmrjob_handler_t handler;
|
|
||||||
stio_tmridx_t* idxptr; /* pointer to the index holder */
|
|
||||||
};
|
|
||||||
|
|
||||||
#define STIO_TMRIDX_INVALID ((stio_tmridx_t)-1)
|
|
||||||
|
|
||||||
typedef struct stio_mux_t stio_mux_t;
|
typedef struct stio_mux_t stio_mux_t;
|
||||||
|
|
||||||
struct stio_t
|
struct stio_t
|
||||||
|
@ -116,7 +116,6 @@ stio_sckhnd_t stio_openasyncsck (stio_t* stio, int domain, int type, int proto)
|
|||||||
return STIO_SCKHND_INVALID;
|
return STIO_SCKHND_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return sck;
|
return sck;
|
||||||
@ -249,15 +248,29 @@ struct sck_type_map_t
|
|||||||
|
|
||||||
static struct sck_type_map_t sck_type_map[] =
|
static struct sck_type_map_t sck_type_map[] =
|
||||||
{
|
{
|
||||||
|
/* STIO_DEV_SCK_TCP4 */
|
||||||
{ AF_INET, SOCK_STREAM, 0, STIO_DEV_CAPA_STREAM | STIO_DEV_CAPA_OUT_QUEUED },
|
{ AF_INET, SOCK_STREAM, 0, STIO_DEV_CAPA_STREAM | STIO_DEV_CAPA_OUT_QUEUED },
|
||||||
|
|
||||||
|
/* STIO_DEV_SCK_TCP6 */
|
||||||
{ AF_INET6, SOCK_STREAM, 0, STIO_DEV_CAPA_STREAM | STIO_DEV_CAPA_OUT_QUEUED },
|
{ AF_INET6, SOCK_STREAM, 0, STIO_DEV_CAPA_STREAM | STIO_DEV_CAPA_OUT_QUEUED },
|
||||||
|
|
||||||
|
/* STIO_DEV_SCK_UPD4 */
|
||||||
{ AF_INET, SOCK_DGRAM, 0, 0 },
|
{ AF_INET, SOCK_DGRAM, 0, 0 },
|
||||||
|
|
||||||
|
/* STIO_DEV_SCK_UDP6 */
|
||||||
{ AF_INET6, SOCK_DGRAM, 0, 0 },
|
{ AF_INET6, SOCK_DGRAM, 0, 0 },
|
||||||
|
|
||||||
{ AF_PACKET, SOCK_RAW, STIO_CONST_HTON16(0x0806), 0 },
|
/* STIO_DEV_SCK_ARP - Ethernet type is 2 bytes long. Protocol must be specified in the network byte order */
|
||||||
{ AF_PACKET, SOCK_DGRAM, STIO_CONST_HTON16(0x0806), 0 },
|
{ AF_PACKET, SOCK_RAW, STIO_CONST_HTON16(STIO_ETHHDR_PROTO_ARP), 0 },
|
||||||
|
|
||||||
{ AF_INET, SOCK_RAW, IPPROTO_ICMP, 0, }
|
/* STIO_DEV_SCK_DGRAM */
|
||||||
|
{ AF_PACKET, SOCK_DGRAM, STIO_CONST_HTON16(STIO_ETHHDR_PROTO_ARP), 0 },
|
||||||
|
|
||||||
|
/* STIO_DEV_SCK_ICMP4 - IP protocol field is 1 byte only. no byte order conversion is needed */
|
||||||
|
{ AF_INET, SOCK_RAW, IPPROTO_ICMP, 0, },
|
||||||
|
|
||||||
|
/* STIO_DEV_SCK_ICMP6 - IP protocol field is 1 byte only. no byte order conversion is needed */
|
||||||
|
{ AF_INET6, SOCK_RAW, IPPROTO_ICMP, 0, }
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ======================================================================== */
|
/* ======================================================================== */
|
||||||
@ -346,6 +359,7 @@ static int dev_sck_make (stio_dev_t* dev, void* ctx)
|
|||||||
rdev->dev_capa = STIO_DEV_CAPA_IN | STIO_DEV_CAPA_OUT | sck_type_map[arg->type].extra_dev_capa;
|
rdev->dev_capa = STIO_DEV_CAPA_IN | STIO_DEV_CAPA_OUT | sck_type_map[arg->type].extra_dev_capa;
|
||||||
rdev->on_write = arg->on_write;
|
rdev->on_write = arg->on_write;
|
||||||
rdev->on_read = arg->on_read;
|
rdev->on_read = arg->on_read;
|
||||||
|
rdev->on_disconnect = arg->on_disconnect;
|
||||||
rdev->type = arg->type;
|
rdev->type = arg->type;
|
||||||
rdev->tmrjob_index = STIO_TMRIDX_INVALID;
|
rdev->tmrjob_index = STIO_TMRIDX_INVALID;
|
||||||
|
|
||||||
@ -365,7 +379,7 @@ static int dev_sck_make_client (stio_dev_t* dev, void* ctx)
|
|||||||
stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
|
stio_dev_sck_t* rdev = (stio_dev_sck_t*)dev;
|
||||||
stio_syshnd_t* sck = (stio_syshnd_t*)ctx;
|
stio_syshnd_t* sck = (stio_syshnd_t*)ctx;
|
||||||
|
|
||||||
/* nothing special is done here except setting the socket handle.
|
/* nothing special is done here except setting the sock et handle.
|
||||||
* most of the initialization is done by the listening socket device
|
* most of the initialization is done by the listening socket device
|
||||||
* after a client socket has been created. */
|
* after a client socket has been created. */
|
||||||
|
|
||||||
@ -393,12 +407,12 @@ static int dev_sck_kill (stio_dev_t* dev, int force)
|
|||||||
|
|
||||||
if (IS_STATEFUL(rdev))
|
if (IS_STATEFUL(rdev))
|
||||||
{
|
{
|
||||||
if (STIO_DEV_SCK_GET_PROGRESS(rdev))
|
/*if (STIO_DEV_SCK_GET_PROGRESS(rdev))
|
||||||
{
|
{*/
|
||||||
/* for STIO_DEV_SCK_CONNECTING, STIO_DEV_SCK_CONNECTING_SSL, and STIO_DEV_ACCEPTING_SSL
|
/* for STIO_DEV_SCK_CONNECTING, STIO_DEV_SCK_CONNECTING_SSL, and STIO_DEV_ACCEPTING_SSL
|
||||||
* on_disconnect() is called without corresponding on_connect() */
|
* on_disconnect() is called without corresponding on_connect() */
|
||||||
if (rdev->on_disconnect) rdev->on_disconnect (rdev);
|
if (rdev->on_disconnect) rdev->on_disconnect (rdev);
|
||||||
}
|
/*}*/
|
||||||
|
|
||||||
if (rdev->tmrjob_index != STIO_TMRIDX_INVALID)
|
if (rdev->tmrjob_index != STIO_TMRIDX_INVALID)
|
||||||
{
|
{
|
||||||
@ -410,6 +424,8 @@ static int dev_sck_kill (stio_dev_t* dev, int force)
|
|||||||
{
|
{
|
||||||
STIO_ASSERT (rdev->state == 0);
|
STIO_ASSERT (rdev->state == 0);
|
||||||
STIO_ASSERT (rdev->tmrjob_index == STIO_TMRIDX_INVALID);
|
STIO_ASSERT (rdev->tmrjob_index == STIO_TMRIDX_INVALID);
|
||||||
|
|
||||||
|
if (rdev->on_disconnect) rdev->on_disconnect (rdev);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(USE_SSL)
|
#if defined(USE_SSL)
|
||||||
@ -533,8 +549,6 @@ static int dev_sck_write_stateful (stio_dev_t* dev, const void* data, stio_iolen
|
|||||||
{
|
{
|
||||||
int err = SSL_get_error ((SSL*)rdev->ssl, x);
|
int err = SSL_get_error ((SSL*)rdev->ssl, x);
|
||||||
if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) return 0;
|
if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) return 0;
|
||||||
/*else if (err == SSL_ERROR_SYSCALL)
|
|
||||||
rdev->stio->errnum = stio_syserrtoerrnum(errno); */
|
|
||||||
rdev->stio->errnum = STIO_ESYSERR;
|
rdev->stio->errnum = STIO_ESYSERR;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -932,7 +946,6 @@ fcntl (rdev->sck, F_SETFL, flags | O_NONBLOCK);
|
|||||||
|
|
||||||
rdev->remoteaddr = conn->remoteaddr;
|
rdev->remoteaddr = conn->remoteaddr;
|
||||||
rdev->on_connect = conn->on_connect;
|
rdev->on_connect = conn->on_connect;
|
||||||
rdev->on_disconnect = conn->on_disconnect;
|
|
||||||
#if defined(USE_SSL)
|
#if defined(USE_SSL)
|
||||||
rdev->ssl_ctx = ssl_ctx;
|
rdev->ssl_ctx = ssl_ctx;
|
||||||
#endif
|
#endif
|
||||||
@ -960,7 +973,6 @@ fcntl (rdev->sck, F_SETFL, flags | O_NONBLOCK);
|
|||||||
/* connected immediately */
|
/* connected immediately */
|
||||||
rdev->remoteaddr = conn->remoteaddr;
|
rdev->remoteaddr = conn->remoteaddr;
|
||||||
rdev->on_connect = conn->on_connect;
|
rdev->on_connect = conn->on_connect;
|
||||||
rdev->on_disconnect = conn->on_disconnect;
|
|
||||||
|
|
||||||
sl = STIO_SIZEOF(localaddr);
|
sl = STIO_SIZEOF(localaddr);
|
||||||
if (getsockname (rdev->sck, (struct sockaddr*)&localaddr, &sl) == 0) rdev->localaddr = localaddr;
|
if (getsockname (rdev->sck, (struct sockaddr*)&localaddr, &sl) == 0) rdev->localaddr = localaddr;
|
||||||
@ -1055,7 +1067,6 @@ fcntl (rdev->sck, F_SETFL, flags | O_NONBLOCK);
|
|||||||
|
|
||||||
STIO_DEV_SCK_SET_PROGRESS (rdev, STIO_DEV_SCK_LISTENING);
|
STIO_DEV_SCK_SET_PROGRESS (rdev, STIO_DEV_SCK_LISTENING);
|
||||||
rdev->on_connect = lstn->on_connect;
|
rdev->on_connect = lstn->on_connect;
|
||||||
rdev->on_disconnect = lstn->on_disconnect;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1598,3 +1609,29 @@ int stio_dev_sck_timedwrite (stio_dev_sck_t* dev, const void* data, stio_iolen_t
|
|||||||
stio_devaddr_t devaddr;
|
stio_devaddr_t devaddr;
|
||||||
return stio_dev_timedwrite ((stio_dev_t*)dev, data, dlen, tmout, wrctx, sckaddr_to_devaddr(dev, dstaddr, &devaddr));
|
return stio_dev_timedwrite ((stio_dev_t*)dev, data, dlen, tmout, wrctx, sckaddr_to_devaddr(dev, dstaddr, &devaddr));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ========================================================================= */
|
||||||
|
|
||||||
|
stio_uint16_t stio_checksumip (const void* hdr, stio_size_t len)
|
||||||
|
{
|
||||||
|
stio_uint32_t sum = 0;
|
||||||
|
stio_uint16_t *ptr = (stio_uint16_t*)hdr;
|
||||||
|
|
||||||
|
|
||||||
|
while (len > 1)
|
||||||
|
{
|
||||||
|
sum += *ptr++;
|
||||||
|
if (sum & 0x80000000)
|
||||||
|
sum = (sum & 0xFFFF) + (sum >> 16);
|
||||||
|
len -= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (sum >> 16) sum = (sum & 0xFFFF) + (sum >> 16);
|
||||||
|
|
||||||
|
return (stio_uint16_t)~sum;
|
||||||
|
}
|
||||||
|
@ -29,6 +29,188 @@
|
|||||||
|
|
||||||
#include <stio.h>
|
#include <stio.h>
|
||||||
|
|
||||||
|
/* ========================================================================= */
|
||||||
|
/* TOOD: move these to a separte file */
|
||||||
|
|
||||||
|
#define STIO_ETHHDR_PROTO_IP4 0x0800
|
||||||
|
#define STIO_ETHHDR_PROTO_ARP 0x0806
|
||||||
|
#define STIO_ETHHDR_PROTO_8021Q 0x8100 /* 802.1Q VLAN */
|
||||||
|
#define STIO_ETHHDR_PROTO_IP6 0x86DD
|
||||||
|
|
||||||
|
|
||||||
|
#define STIO_ARPHDR_OPCODE_REQUEST 1
|
||||||
|
#define STIO_ARPHDR_OPCODE_REPLY 2
|
||||||
|
|
||||||
|
#define STIO_ARPHDR_HTYPE_ETH 0x0001
|
||||||
|
#define STIO_ARPHDR_PTYPE_IP4 0x0800
|
||||||
|
|
||||||
|
#define STIO_ETHADDR_LEN 6
|
||||||
|
#define STIO_IP4ADDR_LEN 4
|
||||||
|
#define STIO_IP6ADDR_LEN 16
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
# define STIO_PACKED __attribute__((__packed__))
|
||||||
|
|
||||||
|
#else
|
||||||
|
# define STIO_PACKED
|
||||||
|
# STIO_PACK_PUSH pack(push)
|
||||||
|
# STIO_PACK_PUSH pack(push)
|
||||||
|
# STIO_PACK(x) pack(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
/* nothing */
|
||||||
|
#else
|
||||||
|
#pragma pack(push)
|
||||||
|
#pragma pack(1)
|
||||||
|
#endif
|
||||||
|
struct STIO_PACKED stio_ethaddr_t
|
||||||
|
{
|
||||||
|
stio_uint8_t v[STIO_ETHADDR_LEN];
|
||||||
|
};
|
||||||
|
typedef struct stio_ethaddr_t stio_ethaddr_t;
|
||||||
|
|
||||||
|
struct STIO_PACKED stio_ip4addr_t
|
||||||
|
{
|
||||||
|
stio_uint8_t v[STIO_IP4ADDR_LEN];
|
||||||
|
};
|
||||||
|
typedef struct stio_ip4addr_t stio_ip4addr_t;
|
||||||
|
|
||||||
|
struct STIO_PACKED stio_ip6addr_t
|
||||||
|
{
|
||||||
|
stio_uint8_t v[STIO_IP6ADDR_LEN];
|
||||||
|
};
|
||||||
|
typedef struct stio_ip6addr_t stio_ip6addr_t;
|
||||||
|
|
||||||
|
|
||||||
|
struct STIO_PACKED stio_ethhdr_t
|
||||||
|
{
|
||||||
|
stio_uint8_t dest[STIO_ETHADDR_LEN];
|
||||||
|
stio_uint8_t source[STIO_ETHADDR_LEN];
|
||||||
|
stio_uint16_t proto;
|
||||||
|
};
|
||||||
|
typedef struct stio_ethhdr_t stio_ethhdr_t;
|
||||||
|
|
||||||
|
struct STIO_PACKED stio_arphdr_t
|
||||||
|
{
|
||||||
|
stio_uint16_t htype; /* hardware type (ethernet: 0x0001) */
|
||||||
|
stio_uint16_t ptype; /* protocol type (ipv4: 0x0800) */
|
||||||
|
stio_uint8_t hlen; /* hardware address length (ethernet: 6) */
|
||||||
|
stio_uint8_t plen; /* protocol address length (ipv4 :4) */
|
||||||
|
stio_uint16_t opcode; /* operation code */
|
||||||
|
};
|
||||||
|
typedef struct stio_arphdr_t stio_arphdr_t;
|
||||||
|
|
||||||
|
/* arp payload for ipv4 over ethernet */
|
||||||
|
struct STIO_PACKED stio_etharp_t
|
||||||
|
{
|
||||||
|
stio_uint8_t sha[STIO_ETHADDR_LEN]; /* source hardware address */
|
||||||
|
stio_uint8_t spa[STIO_IP4ADDR_LEN]; /* source protocol address */
|
||||||
|
stio_uint8_t tha[STIO_ETHADDR_LEN]; /* target hardware address */
|
||||||
|
stio_uint8_t tpa[STIO_IP4ADDR_LEN]; /* target protocol address */
|
||||||
|
};
|
||||||
|
typedef struct stio_etharp_t stio_etharp_t;
|
||||||
|
|
||||||
|
struct STIO_PACKED stio_etharp_pkt_t
|
||||||
|
{
|
||||||
|
stio_ethhdr_t ethhdr;
|
||||||
|
stio_arphdr_t arphdr;
|
||||||
|
stio_etharp_t arppld;
|
||||||
|
};
|
||||||
|
typedef struct stio_etharp_pkt_t stio_etharp_pkt_t;
|
||||||
|
|
||||||
|
|
||||||
|
struct stio_iphdr_t
|
||||||
|
{
|
||||||
|
#if defined(STIO_ENDIAN_LITTLE)
|
||||||
|
stio_uint8_t ihl:4;
|
||||||
|
stio_uint8_t version:4;
|
||||||
|
#elif defined(STIO_ENDIAN_BIG)
|
||||||
|
stio_uint8_t version:4;
|
||||||
|
stio_uint8_t ihl:4;
|
||||||
|
#else
|
||||||
|
# UNSUPPORTED ENDIAN
|
||||||
|
#endif
|
||||||
|
stio_int8_t tos;
|
||||||
|
stio_int16_t tot_len;
|
||||||
|
stio_int16_t id;
|
||||||
|
stio_int16_t frag_off;
|
||||||
|
stio_int8_t ttl;
|
||||||
|
stio_int8_t protocol;
|
||||||
|
stio_int16_t check;
|
||||||
|
stio_int32_t saddr;
|
||||||
|
stio_int32_t daddr;
|
||||||
|
/*The options start here. */
|
||||||
|
};
|
||||||
|
typedef struct stio_iphdr_t stio_iphdr_t;
|
||||||
|
|
||||||
|
|
||||||
|
struct STIO_PACKED stio_icmphdr_t
|
||||||
|
{
|
||||||
|
stio_uint8_t type; /* message type */
|
||||||
|
stio_uint8_t code; /* subcode */
|
||||||
|
stio_uint16_t checksum;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
stio_uint16_t id;
|
||||||
|
stio_uint16_t seq;
|
||||||
|
} echo;
|
||||||
|
|
||||||
|
stio_uint32_t gateway;
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
stio_uint16_t frag_unused;
|
||||||
|
stio_uint16_t mtu;
|
||||||
|
} frag; /* path mut discovery */
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
typedef struct stio_icmphdr_t stio_icmphdr_t;
|
||||||
|
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
/* nothing */
|
||||||
|
#else
|
||||||
|
#pragma pack(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ICMP types */
|
||||||
|
#define STIO_ICMP_ECHO_REPLY 0
|
||||||
|
#define STIO_ICMP_UNREACH 3 /* destination unreachable */
|
||||||
|
#define STIO_ICMP_SOURCE_QUENCE 4
|
||||||
|
#define STIO_ICMP_REDIRECT 5
|
||||||
|
#define STIO_ICMP_ECHO_REQUEST 8
|
||||||
|
#define STIO_ICMP_TIME_EXCEEDED 11
|
||||||
|
#define STIO_ICMP_PARAM_PROBLEM 12
|
||||||
|
#define STIO_ICMP_TIMESTAMP_REQUEST 13
|
||||||
|
#define STIO_ICMP_TIMESTAMP_REPLY 14
|
||||||
|
#define STIO_ICMP_INFO_REQUEST 15
|
||||||
|
#define STIO_ICMP_INFO_REPLY 16
|
||||||
|
#define STIO_ICMP_ADDR_MASK_REQUEST 17
|
||||||
|
#define STIO_ICMP_ADDR_MASK_REPLY 18
|
||||||
|
|
||||||
|
/* Subcode for STIO_ICMP_UNREACH */
|
||||||
|
#define STIO_ICMP_UNREACH_NET 0
|
||||||
|
#define STIO_ICMP_UNREACH_HOST 1
|
||||||
|
#define STIO_ICMP_UNREACH_PROTOCOL 2
|
||||||
|
#define STIO_ICMP_UNREACH_PORT 3
|
||||||
|
#define STIO_ICMP_UNREACH_FRAG_NEEDED 4
|
||||||
|
|
||||||
|
/* Subcode for STIO_ICMP_REDIRECT */
|
||||||
|
#define STIO_ICMP_REDIRECT_NET 0
|
||||||
|
#define STIO_ICMP_REDIRECT_HOST 1
|
||||||
|
#define STIO_ICMP_REDIRECT_NETTOS 2
|
||||||
|
#define STIO_ICMP_REDIRECT_HOSTTOS 3
|
||||||
|
|
||||||
|
/* Subcode for STIO_ICMP_TIME_EXCEEDED */
|
||||||
|
#define STIO_ICMP_TIME_EXCEEDED_TTL 0
|
||||||
|
#define STIO_ICMP_TIME_EXCEEDED_FRAGTIME 1
|
||||||
|
|
||||||
|
/* ========================================================================= */
|
||||||
|
|
||||||
typedef int stio_sckfam_t;
|
typedef int stio_sckfam_t;
|
||||||
|
|
||||||
struct stio_sckaddr_t
|
struct stio_sckaddr_t
|
||||||
@ -72,11 +254,6 @@ typedef struct stio_sckaddr_t stio_sckaddr_t;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define STIO_SCK_ETH_PROTO_IP4 0x0800
|
|
||||||
#define STIO_SCK_ETH_PROTO_ARP 0x0806
|
|
||||||
#define STIO_SCK_ETH_PROTO_8021Q 0x8100 /* 802.1Q VLAN */
|
|
||||||
#define STIO_SCK_ETH_PROTO_IP6 0x86DD
|
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
|
||||||
enum stio_dev_sck_ioctl_cmd_t
|
enum stio_dev_sck_ioctl_cmd_t
|
||||||
@ -127,6 +304,7 @@ typedef int (*stio_dev_sck_on_read_t) (
|
|||||||
stio_iolen_t dlen,
|
stio_iolen_t dlen,
|
||||||
const stio_sckaddr_t* srcaddr
|
const stio_sckaddr_t* srcaddr
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef int (*stio_dev_sck_on_write_t) (
|
typedef int (*stio_dev_sck_on_write_t) (
|
||||||
stio_dev_sck_t* dev,
|
stio_dev_sck_t* dev,
|
||||||
stio_iolen_t wrlen,
|
stio_iolen_t wrlen,
|
||||||
@ -134,8 +312,13 @@ typedef int (*stio_dev_sck_on_write_t) (
|
|||||||
const stio_sckaddr_t* dstaddr
|
const stio_sckaddr_t* dstaddr
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef int (*stio_dev_sck_on_connect_t) (stio_dev_sck_t* dev);
|
typedef void (*stio_dev_sck_on_disconnect_t) (
|
||||||
typedef void (*stio_dev_sck_on_disconnect_t) (stio_dev_sck_t* dev);
|
stio_dev_sck_t* dev
|
||||||
|
);
|
||||||
|
|
||||||
|
typedef int (*stio_dev_sck_on_connect_t) (
|
||||||
|
stio_dev_sck_t* dev
|
||||||
|
);
|
||||||
|
|
||||||
enum stio_dev_sck_type_t
|
enum stio_dev_sck_type_t
|
||||||
{
|
{
|
||||||
@ -144,10 +327,15 @@ enum stio_dev_sck_type_t
|
|||||||
STIO_DEV_SCK_UPD4,
|
STIO_DEV_SCK_UPD4,
|
||||||
STIO_DEV_SCK_UDP6,
|
STIO_DEV_SCK_UDP6,
|
||||||
|
|
||||||
|
/* ARP at the ethernet layer */
|
||||||
STIO_DEV_SCK_ARP,
|
STIO_DEV_SCK_ARP,
|
||||||
STIO_DEV_SCK_ARP_DGRAM,
|
STIO_DEV_SCK_ARP_DGRAM,
|
||||||
|
|
||||||
STIO_DEV_SCK_ICMP4
|
/* ICMP at the IPv4 layer */
|
||||||
|
STIO_DEV_SCK_ICMP4,
|
||||||
|
|
||||||
|
/* ICMP at the IPv6 layer */
|
||||||
|
STIO_DEV_SCK_ICMP6
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
STIO_DEV_SCK_RAW, /* raw L2-level packet */
|
STIO_DEV_SCK_RAW, /* raw L2-level packet */
|
||||||
@ -161,6 +349,7 @@ struct stio_dev_sck_make_t
|
|||||||
stio_dev_sck_type_t type;
|
stio_dev_sck_type_t type;
|
||||||
stio_dev_sck_on_write_t on_write;
|
stio_dev_sck_on_write_t on_write;
|
||||||
stio_dev_sck_on_read_t on_read;
|
stio_dev_sck_on_read_t on_read;
|
||||||
|
stio_dev_sck_on_disconnect_t on_disconnect;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum stio_dev_sck_bind_option_t
|
enum stio_dev_sck_bind_option_t
|
||||||
@ -195,7 +384,6 @@ enum stio_def_sck_connect_option_t
|
|||||||
};
|
};
|
||||||
typedef enum stio_dev_sck_connect_option_t stio_dev_sck_connect_option_t;
|
typedef enum stio_dev_sck_connect_option_t stio_dev_sck_connect_option_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct stio_dev_sck_connect_t stio_dev_sck_connect_t;
|
typedef struct stio_dev_sck_connect_t stio_dev_sck_connect_t;
|
||||||
struct stio_dev_sck_connect_t
|
struct stio_dev_sck_connect_t
|
||||||
{
|
{
|
||||||
@ -203,7 +391,6 @@ struct stio_dev_sck_connect_t
|
|||||||
stio_sckaddr_t remoteaddr;
|
stio_sckaddr_t remoteaddr;
|
||||||
stio_ntime_t connect_tmout;
|
stio_ntime_t connect_tmout;
|
||||||
stio_dev_sck_on_connect_t on_connect;
|
stio_dev_sck_on_connect_t on_connect;
|
||||||
stio_dev_sck_on_disconnect_t on_disconnect;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct stio_dev_sck_listen_t stio_dev_sck_listen_t;
|
typedef struct stio_dev_sck_listen_t stio_dev_sck_listen_t;
|
||||||
@ -211,7 +398,6 @@ struct stio_dev_sck_listen_t
|
|||||||
{
|
{
|
||||||
int backlogs;
|
int backlogs;
|
||||||
stio_dev_sck_on_connect_t on_connect; /* optional, but new connections are dropped immediately without this */
|
stio_dev_sck_on_connect_t on_connect; /* optional, but new connections are dropped immediately without this */
|
||||||
stio_dev_sck_on_disconnect_t on_disconnect; /* should on_discconneted be part of on_accept_t??? */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct stio_dev_sck_accept_t stio_dev_sck_accept_t;
|
typedef struct stio_dev_sck_accept_t stio_dev_sck_accept_t;
|
||||||
@ -373,7 +559,6 @@ STIO_EXPORT int stio_dev_sck_timedwrite (
|
|||||||
static STIO_INLINE void stio_dev_sck_halt (stio_dev_sck_t* sck)
|
static STIO_INLINE void stio_dev_sck_halt (stio_dev_sck_t* sck)
|
||||||
{
|
{
|
||||||
stio_dev_halt ((stio_dev_t*)sck);
|
stio_dev_halt ((stio_dev_t*)sck);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static STIO_INLINE int stio_dev_sck_read (stio_dev_sck_t* sck, int enabled)
|
static STIO_INLINE int stio_dev_sck_read (stio_dev_sck_t* sck, int enabled)
|
||||||
@ -386,10 +571,17 @@ static STIO_INLINE int stio_dev_sck_read (stio_dev_sck_t* sck, int enabled)
|
|||||||
#define stio_dev_sck_halt(sck) stio_dev_halt((stio_dev_t*)sck)
|
#define stio_dev_sck_halt(sck) stio_dev_halt((stio_dev_t*)sck)
|
||||||
#define stio_dev_sck_read(sck,enabled) stio_dev_read((stio_dev_t*)sck, enabled)
|
#define stio_dev_sck_read(sck,enabled) stio_dev_read((stio_dev_t*)sck, enabled)
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
STIO_EXPORT stio_uint16_t stio_checksumip (
|
||||||
|
const void* hdr,
|
||||||
|
stio_size_t len
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
114
stio/lib/stio.h
114
stio/lib/stio.h
@ -125,15 +125,30 @@ enum stio_stopreq_t
|
|||||||
};
|
};
|
||||||
typedef enum stio_stopreq_t stio_stopreq_t;
|
typedef enum stio_stopreq_t stio_stopreq_t;
|
||||||
|
|
||||||
typedef struct stio_tmrjob_t stio_tmrjob_t;
|
/* ========================================================================= */
|
||||||
|
|
||||||
|
#define STIO_TMRIDX_INVALID ((stio_tmridx_t)-1)
|
||||||
|
|
||||||
typedef stio_size_t stio_tmridx_t;
|
typedef stio_size_t stio_tmridx_t;
|
||||||
|
|
||||||
|
typedef struct stio_tmrjob_t stio_tmrjob_t;
|
||||||
|
|
||||||
typedef void (*stio_tmrjob_handler_t) (
|
typedef void (*stio_tmrjob_handler_t) (
|
||||||
stio_t* stio,
|
stio_t* stio,
|
||||||
const stio_ntime_t* now,
|
const stio_ntime_t* now,
|
||||||
stio_tmrjob_t* tmrjob
|
stio_tmrjob_t* tmrjob
|
||||||
);
|
);
|
||||||
|
|
||||||
|
struct stio_tmrjob_t
|
||||||
|
{
|
||||||
|
void* ctx;
|
||||||
|
stio_ntime_t when;
|
||||||
|
stio_tmrjob_handler_t handler;
|
||||||
|
stio_tmridx_t* idxptr; /* pointer to the index holder */
|
||||||
|
};
|
||||||
|
|
||||||
|
/* ========================================================================= */
|
||||||
|
|
||||||
struct stio_dev_mth_t
|
struct stio_dev_mth_t
|
||||||
{
|
{
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
@ -306,102 +321,6 @@ enum stio_dev_event_t
|
|||||||
typedef enum stio_dev_event_t stio_dev_event_t;
|
typedef enum stio_dev_event_t stio_dev_event_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ========================================================================= */
|
|
||||||
/* TOOD: move these to a separte file */
|
|
||||||
|
|
||||||
#define STIO_ETHHDR_PROTO_IP4 0x0800
|
|
||||||
#define STIO_ETHHDR_PROTO_ARP 0x0806
|
|
||||||
|
|
||||||
#define STIO_ARPHDR_OPCODE_REQUEST 1
|
|
||||||
#define STIO_ARPHDR_OPCODE_REPLY 2
|
|
||||||
|
|
||||||
#define STIO_ARPHDR_HTYPE_ETH 0x0001
|
|
||||||
#define STIO_ARPHDR_PTYPE_IP4 0x0800
|
|
||||||
|
|
||||||
#define STIO_ETHADDR_LEN 6
|
|
||||||
#define STIO_IP4ADDR_LEN 4
|
|
||||||
#define STIO_IP6ADDR_LEN 16
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
# define STIO_PACKED __attribute__((__packed__))
|
|
||||||
|
|
||||||
#else
|
|
||||||
# define STIO_PACKED
|
|
||||||
# STIO_PACK_PUSH pack(push)
|
|
||||||
# STIO_PACK_PUSH pack(push)
|
|
||||||
# STIO_PACK(x) pack(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
/* nothing */
|
|
||||||
#else
|
|
||||||
#pragma pack(push)
|
|
||||||
#pragma pack(1)
|
|
||||||
#endif
|
|
||||||
struct STIO_PACKED stio_ethaddr_t
|
|
||||||
{
|
|
||||||
stio_uint8_t v[STIO_ETHADDR_LEN];
|
|
||||||
};
|
|
||||||
typedef struct stio_ethaddr_t stio_ethaddr_t;
|
|
||||||
|
|
||||||
struct STIO_PACKED stio_ip4addr_t
|
|
||||||
{
|
|
||||||
stio_uint8_t v[STIO_IP4ADDR_LEN];
|
|
||||||
};
|
|
||||||
typedef struct stio_ip4addr_t stio_ip4addr_t;
|
|
||||||
|
|
||||||
struct STIO_PACKED stio_ip6addr_t
|
|
||||||
{
|
|
||||||
stio_uint8_t v[STIO_IP6ADDR_LEN];
|
|
||||||
};
|
|
||||||
typedef struct stio_ip6addr_t stio_ip6addr_t;
|
|
||||||
|
|
||||||
|
|
||||||
struct STIO_PACKED stio_ethhdr_t
|
|
||||||
{
|
|
||||||
stio_uint8_t dest[STIO_ETHADDR_LEN];
|
|
||||||
stio_uint8_t source[STIO_ETHADDR_LEN];
|
|
||||||
stio_uint16_t proto;
|
|
||||||
};
|
|
||||||
typedef struct stio_ethhdr_t stio_ethhdr_t;
|
|
||||||
|
|
||||||
struct STIO_PACKED stio_arphdr_t
|
|
||||||
{
|
|
||||||
stio_uint16_t htype; /* hardware type (ethernet: 0x0001) */
|
|
||||||
stio_uint16_t ptype; /* protocol type (ipv4: 0x0800) */
|
|
||||||
stio_uint8_t hlen; /* hardware address length (ethernet: 6) */
|
|
||||||
stio_uint8_t plen; /* protocol address length (ipv4 :4) */
|
|
||||||
stio_uint16_t opcode; /* operation code */
|
|
||||||
};
|
|
||||||
typedef struct stio_arphdr_t stio_arphdr_t;
|
|
||||||
|
|
||||||
/* arp payload for ipv4 over ethernet */
|
|
||||||
struct STIO_PACKED stio_etharp_t
|
|
||||||
{
|
|
||||||
stio_uint8_t sha[STIO_ETHADDR_LEN]; /* source hardware address */
|
|
||||||
stio_uint8_t spa[STIO_IP4ADDR_LEN]; /* source protocol address */
|
|
||||||
stio_uint8_t tha[STIO_ETHADDR_LEN]; /* target hardware address */
|
|
||||||
stio_uint8_t tpa[STIO_IP4ADDR_LEN]; /* target protocol address */
|
|
||||||
};
|
|
||||||
typedef struct stio_etharp_t stio_etharp_t;
|
|
||||||
|
|
||||||
struct STIO_PACKED stio_etharp_pkt_t
|
|
||||||
{
|
|
||||||
stio_ethhdr_t ethhdr;
|
|
||||||
stio_arphdr_t arphdr;
|
|
||||||
stio_etharp_t arppld;
|
|
||||||
};
|
|
||||||
typedef struct stio_etharp_pkt_t stio_etharp_pkt_t;
|
|
||||||
|
|
||||||
#if defined(__GNUC__)
|
|
||||||
/* nothing */
|
|
||||||
#else
|
|
||||||
#pragma pack(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -504,7 +423,6 @@ STIO_EXPORT void stio_dev_halt (
|
|||||||
stio_dev_t* dev
|
stio_dev_t* dev
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
|
||||||
#define stio_inittime(x,s,ns) (((x)->sec = (s)), ((x)->nsec = (ns)))
|
#define stio_inittime(x,s,ns) (((x)->sec = (s)), ((x)->nsec = (ns)))
|
||||||
|
Loading…
Reference in New Issue
Block a user