sockets.c
ubixos/types.h
net/debug.h
net/api.h
net/sockets.h
net/ipv4/ip.h
arch/lib.h
net/netif.h
net/udp.h
arch/cpu.h
arch/sys_arch.h
net/tcp.h
ubixos/types.h
sys/_types.h
net/arch.h
net/ipv4/icmp.h
net/lwipopts.h
net/def.h
net/mem.h
net/ipv4/ip_addr.h
net/err.h
net/api.h
net/sockets.h
net/opt.h
net/sys.h
src/sys/net/api/sockets.c
net/pbuf.h
net/debug.h
net/ipv4/inet.h
arch/cc.h
lwip_socket
NUM_SOCKETS
10
alloc_socket
get_socket
int static int alloc_socket (struct netconn *newconn) alloc_socket struct netconn * newconn lwip_socket::conn lwip_socket::lastdata lwip_socket::lastoffset NULL NUM_SOCKETS sockets lwip_accept lwip_socket
struct lwip_socket * static struct lwip_socket* get_socket (int s) get_socket int s lwip_socket::conn NULL NUM_SOCKETS sockets lwip_accept lwip_bind lwip_close lwip_connect lwip_listen lwip_recvfrom lwip_send lwip_sendto lwip_write
int int lwip_accept (int s, struct sockaddr *addr, int *addrlen) lwip_accept int s struct sockaddr * addr int * addrlen ip_addr::addr alloc_socket lwip_socket::conn get_socket netconn_accept netconn_delete netconn_peer NULL
int int lwip_bind (int s, struct sockaddr *name, int namelen) lwip_bind int s struct sockaddr * name int namelen ip_addr::addr lwip_socket::conn ERR_OK get_socket name netconn_bind ntohs NULL
int int lwip_close (int s) lwip_close int s lwip_socket::conn DEBUGF get_socket lwip_socket::lastdata lwip_socket::lastoffset netbuf_delete netconn_delete NULL SOCKETS_DEBUG
int int lwip_connect (int s, struct sockaddr *name, int namelen) lwip_connect int s struct sockaddr * name int namelen ip_addr::addr lwip_socket::conn ERR_OK get_socket name netconn_connect ntohs NULL
int int lwip_listen (int s, int backlog) lwip_listen int s int backlog lwip_socket::conn ERR_OK get_socket netconn_listen NULL
int int lwip_read (int s, void *mem, int len) lwip_read int s void * mem int len lwip_recv
int int lwip_recv (int s, void *mem, int len, unsigned int flags) lwip_recv int s void * mem int len unsigned int flags lwip_recvfrom NULL lwip_read
int int lwip_recvfrom (int s, void *mem, int len, unsigned int flags, struct sockaddr *from, int *fromlen) lwip_recvfrom int s void * mem int len unsigned int flags struct sockaddr * from int * fromlen ip_addr::addr lwip_socket::conn get_socket htons lwip_socket::lastdata lwip_socket::lastoffset netbuf_copy_partial netbuf_delete netbuf_fromaddr netbuf_fromport netbuf_len netconn_recv NETCONN_TCP netconn_type NULL lwip_recv
int int lwip_send (int s, void *data, int size, unsigned int flags) lwip_send int s void * data int size unsigned int flags lwip_socket::conn DEBUGF netbuf::err ERR_ARG ERR_OK get_socket netbuf_delete netbuf_new netbuf_ref NETCONN_COPY netconn_send NETCONN_TCP netconn_type NETCONN_UDP netconn_write NULL SOCKETS_DEBUG lwip_sendto lwip_write
int int lwip_sendto (int s, void *data, int size, unsigned int flags, struct sockaddr *to, int tolen) lwip_sendto int s void * data int size unsigned int flags struct sockaddr * to int tolen ip_addr::addr lwip_socket::conn get_socket lwip_send netconn_connect netconn_peer NULL
int int lwip_socket (int domain, int type, int protocol) lwip_socket int domain int type int protocol alloc_socket DEBUGF netconn_delete netconn_new NETCONN_TCP NETCONN_UDP NULL SOCK_DGRAM SOCK_STREAM SOCKETS_DEBUG
int int lwip_write (int s, void *data, int size) lwip_write int s void * data int size lwip_socket::conn DEBUGF ERR_ARG ERR_OK get_socket lwip_send NETCONN_COPY NETCONN_TCP netconn_type NETCONN_UDP netconn_write NULL SOCKETS_DEBUG
struct lwip_socket struct lwip_socket sockets[NUM_SOCKETS] [NUM_SOCKETS] sockets alloc_socket get_socket

    /*
    *Copyright(c)2001,SwedishInstituteofComputerScience.
    *Allrightsreserved.
    *
    *Redistributionanduseinsourceandbinaryforms,withorwithout
    *modification,arepermittedprovidedthatthefollowingconditions
    *aremet:
    *1.Redistributionsofsourcecodemustretaintheabovecopyright
    *notice,thislistofconditionsandthefollowingdisclaimer.
    *2.Redistributionsinbinaryformmustreproducetheabovecopyright
    *notice,thislistofconditionsandthefollowingdisclaimerinthe
    *documentationand/orothermaterialsprovidedwiththedistribution.
    *3.NeitherthenameoftheInstitutenorthenamesofitscontributors
    *maybeusedtoendorseorpromoteproductsderivedfromthissoftware
    *withoutspecificpriorwrittenpermission.
    *
    *THISSOFTWAREISPROVIDEDBYTHEINSTITUTEANDCONTRIBUTORS``ASIS''AND
    *ANYEXPRESSORIMPLIEDWARRANTIES,INCLUDING,BUTNOTLIMITEDTO,THE
    *IMPLIEDWARRANTIESOFMERCHANTABILITYANDFITNESSFORAPARTICULARPURPOSE
    *AREDISCLAIMED.INNOEVENTSHALLTHEINSTITUTEORCONTRIBUTORSBELIABLE
    *FORANYDIRECT,INDIRECT,INCIDENTAL,SPECIAL,EXEMPLARY,ORCONSEQUENTIAL
    *DAMAGES(INCLUDING,BUTNOTLIMITEDTO,PROCUREMENTOFSUBSTITUTEGOODS
    *ORSERVICES;LOSSOFUSE,DATA,ORPROFITS;ORBUSINESSINTERRUPTION)
    *HOWEVERCAUSEDANDONANYTHEORYOFLIABILITY,WHETHERINCONTRACT,STRICT
    *LIABILITY,ORTORT(INCLUDINGNEGLIGENCEOROTHERWISE)ARISINGINANYWAY
    *OUTOFTHEUSEOFTHISSOFTWARE,EVENIFADVISEDOFTHEPOSSIBILITYOF
    *SUCHDAMAGE.
    *
    *ThisfileispartofthelwIPTCP/IPstack.
    *
    *Author:AdamDunkels<adam@sics.se>
    *
    *$Id: sockets_8c.xml 88 2016-01-12 00:11:29Z reddawg $
    */

    #include<ubixos/types.h>

    #include"net/debug.h"
    #include"net/api.h"

    #include"net/sockets.h"

    #defineNUM_SOCKETS10

    structlwip_socket{
    structnetconn*conn;
    structnetbuf*lastdata;
    uInt16lastoffset;
    };

    staticstructlwip_socketsockets[NUM_SOCKETS];

    /*-----------------------------------------------------------------------------------*/
    staticstructlwip_socket*
    get_socket(ints)
    {
    structlwip_socket*sock;

    if(s>NUM_SOCKETS){
    /*errno=EBADF;*/
    returnNULL;
    }

    sock=&sockets[s];

    if(sock->conn==NULL){
    /*errno=EBADF;*/
    returnNULL;
    }
    returnsock;
    }
    /*-----------------------------------------------------------------------------------*/
    staticint
    alloc_socket(structnetconn*newconn)
    {
    inti;

    /*allocateanewsocketidentifier*/
    for(i=0;i<NUM_SOCKETS;++i){
    if(sockets[i].conn==NULL){
    sockets[i].conn=newconn;
    sockets[i].lastdata=NULL;
    sockets[i].lastoffset=0;
    returni;
    }
    }
    return-1;
    }
    /*-----------------------------------------------------------------------------------*/
    int
    lwip_accept(ints,structsockaddr*addr,int*addrlen)
    {
    structlwip_socket*sock;
    structnetconn*newconn;
    structip_addr*naddr;
    uInt16port;
    intnewsock;

    sock=get_socket(s);
    if(sock==NULL){
    return-1;
    }

    newconn=netconn_accept(sock->conn);

    /*gettheIPaddressandportoftheremotehost*/
    netconn_peer(newconn,&naddr,&port);

    ((structsockaddr_in*)addr)->sin_addr.s_addr=naddr->addr;
    ((structsockaddr_in*)addr)->sin_port=port;

    newsock=alloc_socket(newconn);
    if(newsock==-1){
    netconn_delete(newconn);
    /*errno=ENOBUFS;*/
    }
    returnnewsock;
    }
    /*-----------------------------------------------------------------------------------*/
    int
    lwip_bind(ints,structsockaddr*name,intnamelen)
    {
    structlwip_socket*sock;
    structip_addrremote_addr;
    uInt16remote_port;
    err_terr;

    sock=get_socket(s);
    if(sock==NULL){
    return-1;
    }

    remote_addr.addr=((structsockaddr_in*)name)->sin_addr.s_addr;
    remote_port=((structsockaddr_in*)name)->sin_port;

    err=netconn_bind(sock->conn,&remote_addr,ntohs(remote_port));

    if(err!=ERR_OK){
    /*errno=...*/
    return-1;
    }

    return0;
    }
    /*-----------------------------------------------------------------------------------*/
    int
    lwip_close(ints)
    {
    structlwip_socket*sock;

    DEBUGF(SOCKETS_DEBUG,("close:socket%d\n",s));
    sock=get_socket(s);
    if(sock==NULL){
    return-1;
    }

    netconn_delete(sock->conn);
    if(sock->lastdata!=NULL){
    netbuf_delete(sock->lastdata);
    }
    sock->lastdata=NULL;
    sock->lastoffset=0;
    sock->conn=NULL;
    return0;
    }
    /*-----------------------------------------------------------------------------------*/
    int
    lwip_connect(ints,structsockaddr*name,intnamelen)
    {
    structlwip_socket*sock;
    structip_addrremote_addr;
    uInt16remote_port;
    err_terr;

    sock=get_socket(s);
    if(sock==NULL){
    return-1;
    }

    remote_addr.addr=((structsockaddr_in*)name)->sin_addr.s_addr;
    remote_port=((structsockaddr_in*)name)->sin_port;

    err=netconn_connect(sock->conn,&remote_addr,ntohs(remote_port));

    if(err!=ERR_OK){
    /*errno=...*/
    return-1;
    }

    return0;
    }
    /*-----------------------------------------------------------------------------------*/
    int
    lwip_listen(ints,intbacklog)
    {
    structlwip_socket*sock;
    err_terr;

    sock=get_socket(s);
    if(sock==NULL){
    return-1;
    }

    err=netconn_listen(sock->conn);

    if(err!=ERR_OK){
    /*errno=...*/
    return-1;
    }

    return0;
    }
    /*-----------------------------------------------------------------------------------*/
    int
    lwip_recvfrom(ints,void*mem,intlen,unsignedintflags,
    structsockaddr*from,int*fromlen)
    {
    structlwip_socket*sock;
    structnetbuf*buf;
    uInt16buflen,copylen;
    structip_addr*addr;
    uInt16port;

    sock=get_socket(s);
    if(sock==NULL){
    return-1;
    }

    /*Checkifthereisdataleftfromthelastrecvoperation.*/
    if(sock->lastdata!=NULL){
    buf=sock->lastdata;
    }else{
    /*Nodatawasleftfromthepreviousoperation,sowetrytoget
    somefromthenetwork.*/
    buf=netconn_recv(sock->conn);

    if(buf==NULL){
    /*Weshouldreallydosomeerrorcheckinghere.*/
    return0;
    }
    }

    buflen=netbuf_len(buf);

    buflen-=sock->lastoffset;

    if(len>buflen){
    copylen=buflen;
    }else{
    copylen=len;
    }

    /*copythecontentsofthereceivedbufferinto
    thesuppliedmemorypointermem*/
    netbuf_copy_partial(buf,mem,copylen,sock->lastoffset);

    /*IfthisisaTCPsocket,checkifthereisdataleftinthe
    buffer.Ifso,itshouldbesavedinthesockstructurefornext
    timearound.*/
    if(netconn_type(sock->conn)==NETCONN_TCP&&buflen-copylen>0){
    sock->lastdata=buf;
    sock->lastoffset=buflen-copylen;
    }else{
    sock->lastdata=NULL;
    sock->lastoffset=0;
    netbuf_delete(buf);
    }

    /*Checktoseefromwherethedatawas.*/
    if(from!=NULL&&fromlen!=NULL){
    addr=netbuf_fromaddr(buf);
    port=htons(netbuf_fromport(buf));
    ((structsockaddr_in*)from)->sin_addr.s_addr=addr->addr;
    ((structsockaddr_in*)from)->sin_port=port;
    *fromlen=sizeof(structsockaddr_in);
    }

    /*ifthelengthofthereceiveddataislargerthan
    len,thisdataisdiscardedandwereturnlen.
    otherwisewereturntheactuallengthofthereceived
    data*/
    if(len>copylen){
    returncopylen;
    }else{
    returnlen;
    }
    }
    /*-----------------------------------------------------------------------------------*/
    int
    lwip_read(ints,void*mem,intlen)
    {
    returnlwip_recv(s,mem,len,0);
    }
    /*-----------------------------------------------------------------------------------*/
    int
    lwip_recv(ints,void*mem,intlen,unsignedintflags)
    {
    returnlwip_recvfrom(s,mem,len,flags,NULL,NULL);
    }
    /*-----------------------------------------------------------------------------------*/
    int
    lwip_send(ints,void*data,intsize,unsignedintflags)
    {
    structlwip_socket*sock;
    structnetbuf*buf;
    err_terr;

    DEBUGF(SOCKETS_DEBUG,("send:socket%d,size%d\n",s,size));

    sock=get_socket(s);
    if(sock==NULL){
    return-1;
    }

    switch(netconn_type(sock->conn)){
    caseNETCONN_UDP:
    /*createabuffer*/
    buf=netbuf_new();

    if(buf==NULL){
    /*errno=ENOBUFS;*/
    return-1;
    }

    /*makethebufferpointtothedatathatshould
    besent*/
    netbuf_ref(buf,data,size);

    /*sendthedata*/
    err=netconn_send(sock->conn,buf);

    /*deallocatedthebuffer*/
    netbuf_delete(buf);
    break;
    caseNETCONN_TCP:
    err=netconn_write(sock->conn,data,size,NETCONN_COPY);
    break;
    default:
    err=ERR_ARG;
    break;
    }
    if(err!=ERR_OK){
    /*errno=...*/
    return-1;
    }

    returnsize;
    }
    /*-----------------------------------------------------------------------------------*/
    int
    lwip_sendto(ints,void*data,intsize,unsignedintflags,
    structsockaddr*to,inttolen)
    {
    structlwip_socket*sock;
    structip_addrremote_addr,*addr;
    uInt16remote_port,port;
    intret;

    sock=get_socket(s);
    if(sock==NULL){
    return-1;
    }

    /*getthepeerifcurrentlyconnected*/
    netconn_peer(sock->conn,&addr,&port);

    remote_addr.addr=((structsockaddr_in*)to)->sin_addr.s_addr;
    remote_port=((structsockaddr_in*)to)->sin_port;
    netconn_connect(sock->conn,&remote_addr,remote_port);

    ret=lwip_send(s,data,size,flags);

    /*resettheremoteaddressandportnumber
    oftheconnection*/
    netconn_connect(sock->conn,addr,port);
    returnret;
    }
    /*-----------------------------------------------------------------------------------*/
    int
    lwip_socket(intdomain,inttype,intprotocol)
    {
    structnetconn*conn;
    inti;

    /*createanetconn*/
    switch(type){
    caseSOCK_DGRAM:
    conn=netconn_new(NETCONN_UDP);
    break;
    caseSOCK_STREAM:
    conn=netconn_new(NETCONN_TCP);
    break;
    default:
    /*errno=...*/
    return-1;
    }

    if(conn==NULL){
    DEBUGF(SOCKETS_DEBUG,("socket:couldnotcreatenetconn.\n"));
    /*errno=ENOBUFS;*/
    return-1;
    }

    i=alloc_socket(conn);

    if(i==-1){
    /*errno=ENOBUFS;*/
    netconn_delete(conn);
    }
    returni;
    }
    /*-----------------------------------------------------------------------------------*/
    int
    lwip_write(ints,void*data,intsize)
    {
    structlwip_socket*sock;
    err_terr;

    DEBUGF(SOCKETS_DEBUG,("write:socket%d,size%d\n",s,size));

    sock=get_socket(s);
    if(sock==NULL){
    return-1;
    }

    switch(netconn_type(sock->conn)){
    caseNETCONN_UDP:
    returnlwip_send(s,data,size,0);

    caseNETCONN_TCP:
    err=netconn_write(sock->conn,data,size,NETCONN_COPY);
    break;
    default:
    err=ERR_ARG;
    break;
    }
    if(err!=ERR_OK){
    /*errno=...*/
    return-1;
    }
    returnsize;
    }
    /*-----------------------------------------------------------------------------------*/