home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR3 / KA9Q212.ZIP / SOCKET.C < prev    next >
C/C++ Source or Header  |  1993-07-16  |  47KB  |  1,990 lines

  1. /* Application programming interface routines - based loosely on the
  2.  * "socket" model in Berkeley UNIX.
  3.  *
  4.  * Copyright 1991 Phil Karn, KA9Q
  5.  */
  6.  
  7. /****************************************************************************
  8. *    $Id: socket.c 1.2 93/07/16 11:50:49 ROOT_DOS Exp $
  9. *    04 Jul 93    1.2        GT    Fix warnings.                                    *
  10. ****************************************************************************/
  11.  
  12. #include <stdio.h>
  13. #ifdef    __STDC__
  14. #include <stdarg.h>
  15. #endif
  16. #include "global.h"
  17. #include "mbuf.h"
  18. #include "netuser.h"
  19. #include "timer.h"
  20. #include "iface.h"
  21. #include "ip.h"
  22. #include "tcp.h"
  23. #include "udp.h"
  24. #include "ax25.h"
  25. #include "lapb.h"
  26. #include "netrom.h"
  27. #include "nr4.h"
  28. #include "proc.h"
  29. #include "lzw.h"
  30. #include "usock.h"
  31. #include "socket.h"
  32. #include "config.h"
  33.  
  34. static void autobind __ARGS((int s,int af));
  35. static int checkaddr __ARGS((int type,char *name,int namelen));
  36. static void rip_recv __ARGS((struct raw_ip *rp));
  37. static void s_trcall __ARGS((struct tcb *tcb,int cnt));
  38. static void s_tscall __ARGS((struct tcb *tcb,int old,int new));
  39. static void s_ttcall __ARGS((struct tcb *tcb,int cnt));
  40. static void s_urcall __ARGS((struct iface *iface,struct udp_cb *udp,int cnt));
  41. static void trdiscard __ARGS((struct tcb *tcb,int cnt));
  42. #ifdef    NETROM
  43. static void s_nrcall __ARGS((struct nr4cb *cb,int cnt));
  44. static void s_nscall __ARGS((struct nr4cb *cb,int old,int new));
  45. static void s_ntcall __ARGS((struct nr4cb *cb,int cnt));
  46. #endif
  47.  
  48. static int16 Lport = 1024;
  49.  
  50. char *Socktypes[] = {
  51.     "Not Used",
  52.     "TCP",
  53.     "UDP",
  54.     "AX25 I",
  55.     "AX25 UI",
  56.     "Raw IP",
  57.     "NETROM3",
  58.     "NETROM",
  59.     "Loc St",
  60.     "Loc Dg"
  61. };
  62. char Badsocket[] = "Bad socket";
  63. struct usock *Usock;        /* Socket entry array */
  64. int Nusock = DEFNSOCK;        /* Number of socket entries */
  65.  
  66. /* The following two variables are needed because there can be only one
  67.  * socket listening on each of the AX.25 modes (I and UI)
  68.  */
  69. #ifdef    AX25
  70. int Axi_sock = -1;    /* Socket number listening for AX25 connections */
  71. static int Axui_sock = -1;    /* Socket number listening for AX25 UI frames */
  72. static struct mbuf *Bcq;    /* Queue of incoming UI frames */
  73.  
  74. /* Function that handles incoming UI frames from lapb.c */
  75. void
  76. beac_input(iface,src,bp)
  77. struct iface *iface;
  78. char *src;
  79. struct mbuf *bp;
  80. {
  81.     struct mbuf *hdr;
  82.     struct sockaddr_ax *sax;
  83.  
  84.     if(Axui_sock == -1){
  85.         /* Nobody there to read it */
  86.         free_p(bp);
  87.     } else {
  88.         if((hdr = pushdown(NULLBUF,sizeof(struct sockaddr_ax))) == NULLBUF){
  89.             free_p(bp);
  90.             return;
  91.         }
  92.         sax = (struct sockaddr_ax *)hdr->data;
  93.         sax->sax_family = AF_AX25;
  94.         memcpy(sax->ax25_addr,src,AXALEN);
  95.         strncpy(sax->iface,iface->name,ILEN);
  96.         hdr->next = bp;
  97.         enqueue(&Bcq,hdr);
  98.     }
  99. }
  100. #endif
  101.  
  102. /* Initialize user socket array */
  103. void
  104. sockinit()
  105. {
  106.     if(Usock != NULLUSOCK)
  107.         return;    /* Already initialized */
  108.     Usock = (struct usock *)callocw(Nusock,sizeof(struct usock));
  109. }
  110.  
  111. /* Create a user socket, return socket index
  112.  * The mapping to actual protocols is as follows:
  113.  *        
  114.  *        
  115.  * ADDRESS FAMILY    Stream        Datagram    Raw        Seq. Packet
  116.  *
  117.  * AF_INET        TCP        UDP        IP
  118.  * AF_AX25        I-frames    UI-frames
  119.  * AF_NETROM                        NET/ROM L3  NET/ROM L4
  120.  * AF_LOCAL        stream loopback    packet loopback
  121.  */
  122. int
  123. socket(af,type,protocol)
  124. int af;        /* Address family */
  125. int type;    /* Stream or datagram */
  126. int protocol;    /* Used for raw IP sockets */
  127. {
  128.     register struct usock *up;
  129.     int s;
  130.  
  131.     for(up=Usock;up < &Usock[Nusock];up++)
  132.         if(up->type == NOTUSED)
  133.             break;
  134.  
  135.     if(up == &Usock[Nusock]){
  136.         /* None left */
  137.         errno = EMFILE;
  138.         return -1;
  139.     }
  140.     up->refcnt = 1;
  141.     s = (int) (up - Usock + SOCKBASE);
  142.     errno = 0;
  143.     up->noblock = 0;
  144.     up->rdysock = -1;
  145.     up->cb.p = NULLCHAR;
  146.     up->peername = up->name = NULLCHAR;
  147.     up->namelen = up->peernamelen = 0;
  148.     up->owner = Curproc;
  149.     up->obuf = NULLBUF;
  150.     memset(up->errcodes,0,sizeof(up->errcodes));
  151.     memset(up->eol,0,sizeof(up->eol));
  152.     up->flush = '\n';    /* default is line buffered */
  153.     switch(af){
  154.     case AF_LOCAL:
  155.         up->cb.local = (struct loc *) callocw(1,sizeof(struct loc));
  156.         up->cb.local->peer = up;    /* connect to self */
  157.         switch(type){
  158.         case SOCK_STREAM:
  159.             up->type = TYPE_LOCAL_STREAM;
  160.             up->cb.local->hiwat = LOCSFLOW;
  161.             break;
  162.         case SOCK_DGRAM:
  163.             up->type = TYPE_LOCAL_DGRAM;
  164.             up->cb.local->hiwat = LOCDFLOW;
  165.             break;
  166.         default:
  167.             free(up->cb.local);
  168.             errno = ESOCKTNOSUPPORT;
  169.             break;
  170.         }
  171.         break;
  172. #ifdef    AX25
  173.     case AF_AX25:
  174.         switch(type){
  175.         case SOCK_STREAM:
  176.             up->type = TYPE_AX25I;
  177.             break;
  178.         case SOCK_DGRAM:
  179.             up->type = TYPE_AX25UI;
  180.             break;
  181.         default:
  182.             errno = ESOCKTNOSUPPORT;
  183.             break;
  184.         }
  185.         strcpy(up->eol,AX_EOL);
  186.         break;
  187. #endif
  188. #ifdef NETROM
  189.     case AF_NETROM:
  190.         switch(type){
  191.         case SOCK_RAW:
  192.             up->type = TYPE_NETROML3;
  193.             up->cb.rnr = raw_nr((char)protocol);
  194.             break;
  195.         case SOCK_SEQPACKET:
  196.             up->type = TYPE_NETROML4;
  197.             break;
  198.         default:
  199.             errno = ESOCKTNOSUPPORT;
  200.             break;
  201.         }
  202.         strcpy(up->eol,AX_EOL);
  203.         break;
  204. #endif
  205.     case AF_INET:
  206.         switch(type){
  207.         case SOCK_STREAM:
  208.             up->type = TYPE_TCP;
  209.             strcpy(up->eol,INET_EOL);
  210.             break;
  211.         case SOCK_DGRAM:
  212.             up->type = TYPE_UDP;
  213.             break;
  214.         case SOCK_RAW:
  215.             up->type = TYPE_RAW;
  216.             up->cb.rip = raw_ip(protocol,rip_recv);
  217.                         up->cb.rip->user = s;
  218.             break;
  219.         default:
  220.             errno = ESOCKTNOSUPPORT;
  221.             break;
  222.         }
  223.         break;
  224.     default:
  225.         errno = EAFNOSUPPORT;
  226.         break;
  227.     }
  228.     if(errno)
  229.         return -1;
  230.  
  231.     return s;
  232. }
  233.  
  234. /* Attach a local address/port to a socket. If not issued before a connect
  235.  * or listen, will be issued automatically
  236.  */
  237. int
  238. bind(s,name,namelen)
  239. int s;        /* Socket index */
  240. char *name;    /* Local name */
  241. int namelen;    /* Length of name */
  242. {
  243.     register struct usock *up;
  244.     union sp local;
  245.     struct socket lsock;
  246.  
  247.     if((up = itop(s)) == NULLUSOCK){
  248.         errno = EBADF;
  249.         return -1;
  250.     }
  251.     if(up->type == TYPE_LOCAL_STREAM || up->type == TYPE_LOCAL_DGRAM){
  252.         errno = EINVAL;
  253.         return -1;
  254.     }
  255.     if(name == NULLCHAR){
  256.         errno = EFAULT;
  257.         return -1;
  258.     }
  259.     if(up->name != NULLCHAR){
  260.         /* Bind has already been issued */
  261.         errno = EINVAL;
  262.         return -1;
  263.     }
  264.     if(checkaddr(up->type,name,namelen) == -1){
  265.         /* Incorrect length or family for chosen protocol */
  266.         errno = EAFNOSUPPORT;
  267.         return -1;    
  268.     }
  269.     /* Stash name in an allocated block */
  270.     up->namelen = namelen;
  271.     up->name = mallocw(namelen);
  272.     memcpy(up->name,name,namelen);
  273.     /* Create control block for datagram sockets */
  274.     switch(up->type){
  275.     case TYPE_UDP:
  276.         local.in = (struct sockaddr_in *)up->name;
  277.         lsock.address = local.in->sin_addr.s_addr;
  278.         lsock.port = local.in->sin_port;
  279.         up->cb.udp = open_udp(&lsock,s_urcall);
  280.         up->cb.udp->user = s;
  281.         break;
  282. #ifdef    AX25
  283.     case TYPE_AX25UI:
  284.         if(Axui_sock != -1){
  285.             errno = EADDRINUSE;
  286.             return -1;
  287.         }
  288.         Axui_sock = s;
  289.         break;
  290. #endif
  291.     }
  292.     return 0;
  293. }
  294. /* Post a listen on a socket */
  295. int
  296. listen(s,backlog)
  297. int s;        /* Socket index */
  298. int backlog;    /* 0 for a single connection, 1 for multiple connections */
  299. {
  300.     register struct usock *up;
  301.     union sp local;
  302.     struct socket lsock;
  303.  
  304.     if((up = itop(s)) == NULLUSOCK){
  305.         errno = EBADF;
  306.         return -1;
  307.     }
  308.     if(up->type == TYPE_LOCAL_STREAM || up->type == TYPE_LOCAL_DGRAM){
  309.         errno = EINVAL;
  310.         return -1;
  311.     }
  312.     if(up->cb.p != NULLCHAR){
  313.         errno = EISCONN;
  314.         return -1;
  315.     }
  316.     switch(up->type){
  317.     case TYPE_TCP:
  318.         if(up->name == NULLCHAR)
  319.             autobind(s,AF_INET);
  320.  
  321.         local.in = (struct sockaddr_in *)up->name;
  322.         lsock.address = local.in->sin_addr.s_addr;
  323.         lsock.port = local.in->sin_port;
  324.         up->cb.tcb = open_tcp(&lsock,NULLSOCK,
  325.          backlog ? TCP_SERVER:TCP_PASSIVE,0,
  326.         s_trcall,s_ttcall,s_tscall,0,s);
  327.         break;
  328. #ifdef AX25
  329.     case TYPE_AX25I:
  330.         if(up->name == NULLCHAR)
  331.             autobind(s,AF_AX25);
  332.         if(s != Axi_sock){
  333.             errno = EOPNOTSUPP;
  334.             return -1;
  335.         }
  336.         local.ax = (struct sockaddr_ax *)up->name;
  337.         up->cb.ax25 = open_ax25(NULLIF,local.ax->ax25_addr,NULLCHAR,
  338.          backlog ? AX_SERVER:AX_PASSIVE,0,
  339.          s_arcall,s_atcall,s_ascall,s);
  340.         break;
  341. #endif
  342. #ifdef NETROM
  343.     case TYPE_NETROML4:
  344.         if(up->name == NULLCHAR)
  345.             autobind(s,AF_NETROM);
  346.         local.nr = (struct sockaddr_nr *)up->name;
  347.         up->cb.nr4 = open_nr4(&local.nr->nr_addr,NULLNRADDR,
  348.          backlog ? AX_SERVER:AX_PASSIVE,
  349.          s_nrcall,s_ntcall,s_nscall,s);
  350.         break;
  351. #endif
  352.     default:
  353.         /* Listen not supported on datagram sockets */
  354.         errno = EOPNOTSUPP;
  355.         return -1;        
  356.     }
  357.     return 0;
  358. }
  359. /* Initiate active open. For datagram sockets, merely bind the remote address. */
  360. int
  361. connect(s,peername,peernamelen)
  362. int s;            /* Socket index */
  363. char *peername;        /* Peer name */
  364. int peernamelen;    /* Length of peer name */
  365. {
  366.     register struct usock *up;
  367.     union cb cb;
  368.     union sp local,remote;
  369.     struct socket lsock,fsock;
  370. #ifdef    AX25
  371.     struct iface *iface;
  372. #endif
  373.  
  374.     if((up = itop(s)) == NULLUSOCK){
  375.         errno = EBADF;
  376.         return -1;
  377.     }
  378.     if(up->type == TYPE_LOCAL_DGRAM || up->type == TYPE_LOCAL_STREAM){
  379.         errno = EINVAL;
  380.         return -1;
  381.     }
  382.     if(peername == NULLCHAR){
  383.         /* Connect must specify a remote address */
  384.         errno = EFAULT;
  385.         return -1;
  386.     }
  387.     if(checkaddr(up->type,peername,peernamelen) == -1){
  388.         errno = EAFNOSUPPORT;
  389.         return -1;
  390.     }
  391.     /* Raw socket control blocks are created in socket() */
  392.     if(up->type != TYPE_RAW && up->type != TYPE_NETROML3 &&
  393.        up->cb.p != NULLCHAR){
  394.         errno = EISCONN;
  395.         return -1;
  396.     }
  397.     up->peername = mallocw(peernamelen);
  398.     memcpy(up->peername,peername,peernamelen);
  399.     up->peernamelen = peernamelen;
  400.  
  401.     /* Set up the local socket structures */
  402.     if(up->name == NULLCHAR){
  403.         switch(up->type){
  404.         case TYPE_TCP:
  405.         case TYPE_UDP:
  406.         case TYPE_RAW:
  407.             autobind(s,AF_INET);
  408.             break;
  409. #ifdef    AX25
  410.         case TYPE_AX25I:
  411.         case TYPE_AX25UI:
  412.             autobind(s,AF_AX25);
  413.             break;
  414. #endif
  415. #ifdef    NETROM
  416.         case TYPE_NETROML3:
  417.         case TYPE_NETROML4:
  418.             autobind(s,AF_NETROM);
  419.             break;
  420. #endif
  421.         }
  422.     }
  423.     switch(up->type){
  424.     case TYPE_TCP:
  425.         /* Construct the TCP-style ports from the sockaddr structs */
  426.         local.in = (struct sockaddr_in *)up->name;
  427.         remote.in = (struct sockaddr_in *)up->peername;
  428.  
  429.         if(local.in->sin_addr.s_addr == INADDR_ANY)
  430.             /* Choose a local address */
  431.             local.in->sin_addr.s_addr =
  432.              locaddr(remote.in->sin_addr.s_addr);
  433.  
  434.         lsock.address = local.in->sin_addr.s_addr;
  435.         lsock.port = local.in->sin_port;
  436.         fsock.address = remote.in->sin_addr.s_addr;
  437.         fsock.port = remote.in->sin_port;
  438.  
  439.         /* Open the TCB in active mode */
  440.         up->cb.tcb = open_tcp(&lsock,&fsock,TCP_ACTIVE,0,
  441.          s_trcall,s_ttcall,s_tscall,0,s);
  442.  
  443.         /* Wait for the connection to complete */
  444.         while((cb.tcb = up->cb.tcb) != NULLTCB && cb.tcb->state != TCP_ESTABLISHED){
  445.             if(up->noblock){
  446.                 errno = EWOULDBLOCK;
  447.                 return -1;
  448.             } else if((errno = pwait(up)) != 0){
  449.                 return -1;
  450.             }
  451.         }
  452.         if(cb.tcb == NULLTCB){
  453.             /* Probably got refused */
  454.             free(up->peername);
  455.             up->peername = NULLCHAR;
  456.             errno = ECONNREFUSED;
  457.             return -1;
  458.         }
  459.         break;
  460.     case TYPE_UDP:
  461. #ifdef    AX25
  462.     case TYPE_AX25UI:
  463. #endif
  464. #ifdef    NETROM
  465.     case TYPE_NETROML3:
  466. #endif
  467.     case TYPE_RAW:
  468.         /* Control block already created by bind() */
  469.         break;
  470. #ifdef    AX25
  471.     case TYPE_AX25I:
  472.         local.ax = (struct sockaddr_ax *)up->name;
  473.         remote.ax = (struct sockaddr_ax *)up->peername;
  474.         if((iface = if_lookup(remote.ax->iface)) == NULLIF){
  475.             errno = EINVAL;
  476.             return -1;
  477.         }
  478.         if(local.ax->ax25_addr[0] == '\0'){
  479.             /* The local address was unspecified; set it from
  480.              * the interface address
  481.              */
  482.             memcpy(local.ax->ax25_addr,iface->hwaddr,AXALEN);
  483.         }
  484.         /* If we already have an AX25 link we can use it */
  485.         if((up->cb.ax25 = find_ax25(remote.ax->ax25_addr)) != NULLAX25
  486.            && up->cb.ax25->state != LAPB_DISCONNECTED &&
  487.            up->cb.ax25->user == -1) {
  488.             up->cb.ax25->user = s;
  489.             up->cb.ax25->r_upcall = s_arcall;
  490.             up->cb.ax25->t_upcall = s_atcall;
  491.             up->cb.ax25->s_upcall = s_ascall;
  492.             if(up->cb.ax25->state == LAPB_CONNECTED
  493.                || up->cb.ax25->state == LAPB_RECOVERY)
  494.                     return 0;
  495.         } else
  496.             up->cb.ax25 = open_ax25(iface,local.ax->ax25_addr,
  497.              remote.ax->ax25_addr,AX_ACTIVE,
  498.              Axwindow,s_arcall,s_atcall,s_ascall,s);
  499.  
  500.         /* Wait for the connection to complete */
  501.         while((cb.ax25 = up->cb.ax25) != NULLAX25 && cb.ax25->state != LAPB_CONNECTED){
  502.             if(up->noblock){
  503.                 errno = EWOULDBLOCK;
  504.                 return -1;
  505.             } else if((errno = pwait(up)) != 0){
  506.                 return -1;
  507.             }
  508.         }
  509.         if(cb.ax25 == NULLAX25){
  510.             /* Connection probably already exists */
  511.             free(up->peername);
  512.             up->peername = NULLCHAR;
  513.             errno = ECONNREFUSED;
  514.             return -1;
  515.         }
  516.         break;
  517. #endif
  518. #ifdef    NETROM
  519.     case TYPE_NETROML4:
  520.         local.nr = (struct sockaddr_nr *)up->name;
  521.         remote.nr = (struct sockaddr_nr *)up->peername;
  522.         up->cb.nr4 = open_nr4(&local.nr->nr_addr,&remote.nr->nr_addr,
  523.          AX_ACTIVE,s_nrcall,s_ntcall,s_nscall,s);
  524.  
  525.         /* Wait for the connection to complete */
  526.         while((cb.nr4 = up->cb.nr4) != NULLNR4CB && cb.nr4->state != NR4STCON){
  527.             if(up->noblock){
  528.                 errno = EWOULDBLOCK;
  529.                 return -1;
  530.             } else if((errno = pwait(up)) != 0){
  531.                 return -1;
  532.             }
  533.         }
  534.         if(cb.nr4 == NULLNR4CB){
  535.             /* Connection probably already exists */
  536.             free(up->peername);
  537.             up->peername = NULLCHAR;
  538.             errno = ECONNREFUSED;
  539.             return -1;
  540.         }
  541.         break;
  542. #endif
  543.     }
  544.     return 0;
  545. }
  546. /* Wait for a connection. Valid only for connection-oriented sockets. */
  547. int
  548. accept(s,peername,peernamelen)
  549. int s;            /* Socket index */
  550. char *peername;        /* Peer name */
  551. int *peernamelen;    /* Length of peer name */
  552. {
  553.     int i;
  554.     register struct usock *up;
  555.  
  556.     if((up = itop(s)) == NULLUSOCK){
  557.         errno = EBADF;
  558.         return -1;
  559.     }
  560.     if(up->type == TYPE_LOCAL_DGRAM || up->type == TYPE_LOCAL_STREAM){
  561.         errno = EINVAL;
  562.         return -1;
  563.     }
  564.     if(up->cb.p == NULLCHAR){
  565.         errno = EOPNOTSUPP;
  566.         return -1;
  567.     }
  568.     /* Accept is valid only for stream sockets */
  569.     switch(up->type){
  570.     case TYPE_TCP:
  571. #ifdef    AX25
  572.     case TYPE_AX25I:
  573. #endif
  574. #ifdef    NETROM
  575.     case TYPE_NETROML4:
  576. #endif
  577.         break;
  578.     default:
  579.         errno = EOPNOTSUPP;
  580.         return -1;
  581.     }    
  582.     /* Wait for the state-change upcall routine to signal us */
  583.     while(up->cb.p != NULLCHAR && up->rdysock == -1){
  584.         if(up->noblock){
  585.             errno = EWOULDBLOCK;
  586.             return -1;
  587.         } else if((errno = pwait(up)) != 0){
  588.             return -1;
  589.         }
  590.     }
  591.     if(up->cb.p == NULLCHAR){
  592.         /* Blown away */
  593.         errno = EBADF;
  594.         return -1;
  595.     }
  596.     i = up->rdysock;
  597.     up->rdysock = -1;
  598.  
  599.     up = itop(i);
  600.     if(peername != NULLCHAR && peernamelen != NULL){
  601.         *peernamelen = min(up->peernamelen,*peernamelen);
  602.         memcpy(peername,up->peername,*peernamelen);
  603.     }
  604.     return i;
  605. }
  606. /* Low-level receive routine. Passes mbuf back to user; more efficient than
  607.  * higher-level functions recv() and recvfrom(). Datagram sockets ignore
  608.  * the len parameter.
  609.  */
  610. int
  611. recv_mbuf(s,bpp,flags,from,fromlen)
  612. int s;            /* Socket index */
  613. struct mbuf **bpp;    /* Place to stash receive buffer */
  614. int flags;        /* Unused; will control out-of-band data, etc */
  615. char *from;        /* Peer address (only for datagrams) */
  616. int *fromlen;        /* Length of peer address */
  617. {
  618.     register struct usock *up;
  619.     int cnt;
  620.     union cb cb;
  621.     struct socket fsocket;
  622. #ifdef    NETROM
  623.     struct nr3hdr n3hdr;
  624. #endif
  625.     union sp remote;
  626.     struct ip ip;
  627.     struct mbuf *bp;
  628.  
  629.     if((up = itop(s)) == NULLUSOCK){
  630.         errno = EBADF;
  631.         return -1;
  632.     }
  633.     if(up->ibuf != NULLBUF){
  634.         /* Return input buffer */
  635.         cnt = len_p(up->ibuf);
  636.         if(bpp != NULLBUFP)
  637.             *bpp = up->ibuf;
  638.         else
  639.             free_p(up->ibuf);
  640.         up->ibuf = NULLBUF;        
  641.         return cnt;
  642.     }
  643.     switch(up->type){
  644.     case TYPE_LOCAL_STREAM:
  645.     case TYPE_LOCAL_DGRAM:
  646.         while(up->cb.local != NULLLOC && up->cb.local->q == NULLBUF
  647.               && up->cb.local->peer != NULLUSOCK){
  648.             if(up->noblock){
  649.                 errno = EWOULDBLOCK;
  650.                 return -1;
  651.             } else if((errno = pwait(up)) != 0){
  652.                 return -1;
  653.             }
  654.         }
  655.         if(up->cb.local == NULLLOC){
  656.             errno = EBADF;
  657.             return -1;
  658.         }
  659.         if(up->cb.local->q == NULLBUF &&
  660.            up->cb.local->peer == NULLUSOCK){
  661.             errno = ENOTCONN;
  662.             return -1;
  663.         }
  664.         /* For datagram sockets, this will return the
  665.          * first packet on the queue. For stream sockets,
  666.          * this will return everything.
  667.          */
  668.         bp = dequeue(&up->cb.local->q);
  669.         if(up->cb.local->q == NULLBUF
  670.          && (up->cb.local->flags & LOC_SHUTDOWN))
  671.             close_s(s);
  672.         psignal(up,0);
  673.         cnt = len_p(bp);
  674.         break;
  675.     case TYPE_TCP:
  676.         while((cb.tcb = up->cb.tcb) != NULLTCB
  677.          && cb.tcb->r_upcall != trdiscard
  678.                  && (cnt = recv_tcp(cb.tcb,&bp,(int16)0)) == -1){
  679.             if(up->noblock){
  680.                 errno = EWOULDBLOCK;
  681.                 return -1;
  682.             } else if((errno = pwait(up)) != 0){
  683.                 return -1;
  684.             }
  685.         }
  686.         if(cb.tcb == NULLTCB){
  687.             /* Connection went away */
  688.             errno = ENOTCONN;
  689.             return -1;
  690.         } else if(cb.tcb->r_upcall == trdiscard){
  691.             /* Receive shutdown has been done */
  692.             errno = ENOTCONN;    /* CHANGE */
  693.             return -1;
  694.         }
  695.         break;
  696.     case TYPE_UDP:
  697.         while((cb.udp = up->cb.udp) != NULLUDP
  698.         && (cnt = recv_udp(cb.udp,&fsocket,&bp)) == -1){
  699.             if(up->noblock){
  700.                 errno = EWOULDBLOCK;
  701.                 return -1;
  702.             } else if((errno = pwait(up)) != 0){
  703.                 return -1;
  704.             }
  705.         }
  706.         if(cb.udp == NULLUDP){
  707.             /* Connection went away */
  708.             errno = ENOTCONN;
  709.             return -1;
  710.         }
  711.         if(from != NULLCHAR && fromlen != (int *)NULL && *fromlen >= SOCKSIZE){
  712.             remote.in = (struct sockaddr_in *)from;
  713.             remote.in->sin_family = AF_INET;
  714.             remote.in->sin_addr.s_addr = fsocket.address;
  715.             remote.in->sin_port = fsocket.port;
  716.             *fromlen = SOCKSIZE;
  717.         }
  718.         break;
  719.     case TYPE_RAW:
  720.         while((cb.rip = up->cb.rip) != NULLRIP
  721.          && cb.rip->rcvq == NULLBUF){
  722.             if(up->noblock){
  723.                 errno = EWOULDBLOCK;
  724.                 return -1;
  725.             } else if((errno = pwait(up)) != 0){
  726.                 return -1;
  727.             }
  728.         }
  729.         if(cb.rip == NULLRIP){
  730.             /* Connection went away */
  731.             errno = ENOTCONN;
  732.             return -1;
  733.         }
  734.         bp = dequeue(&cb.rip->rcvq);
  735.         ntohip(&ip,&bp);
  736.  
  737.         cnt = len_p(bp);
  738.         if(from != NULLCHAR && fromlen != (int *)NULL && *fromlen >= SOCKSIZE){
  739.             remote.in = (struct sockaddr_in *)from;
  740.             remote.in->sin_family = AF_INET;
  741.             remote.in->sin_addr.s_addr = ip.source;
  742.             remote.in->sin_port = 0;
  743.             *fromlen = SOCKSIZE;
  744.         }
  745.         break;
  746. #ifdef    AX25
  747.     case TYPE_AX25I:
  748.         while((cb.ax25 = up->cb.ax25) != NULLAX25
  749.          && (bp = recv_ax25(cb.ax25,(int16)0)) == NULLBUF){
  750.             if(up->noblock){
  751.                 errno = EWOULDBLOCK;
  752.                 return -1;
  753.             } else if((errno = pwait(up)) != 0){
  754.                 return -1;
  755.             }
  756.         }
  757.         if(cb.ax25 == NULLAX25){
  758.             /* Connection went away */
  759.             errno = ENOTCONN;
  760.             return -1;
  761.         }
  762.         cnt = bp->cnt;
  763.         break;
  764.     case TYPE_AX25UI:
  765.         while(s == Axui_sock && Bcq == NULLBUF){
  766.             if(up->noblock){
  767.                 errno = EWOULDBLOCK;
  768.                 return -1;
  769.             } else if((errno = pwait(&Bcq)) != 0){
  770.                 return -1;
  771.             }
  772.         }
  773.         if(s != Axui_sock){
  774.             errno = ENOTCONN;
  775.             return -1;
  776.         }
  777.         bp = dequeue(&Bcq);
  778.  
  779.         if(from != NULLCHAR && fromlen != NULLINT
  780.            && *fromlen >= sizeof(struct sockaddr_ax)){
  781.             pullup(&bp,from,sizeof(struct sockaddr_ax));
  782.             *fromlen = sizeof(struct sockaddr_ax);
  783.         } else {
  784.             pullup(&bp,NULLCHAR,sizeof(struct sockaddr_ax));
  785.         }
  786.         cnt = len_p(bp);
  787.         break;
  788. #endif
  789. #ifdef NETROM
  790.     case TYPE_NETROML3:
  791.         while((cb.rnr = up->cb.rnr) != NULLRNR
  792.          && cb.rnr->rcvq == NULLBUF){
  793.             if(up->noblock){
  794.                 errno = EWOULDBLOCK;
  795.                 return -1;
  796.             } else if((errno = pwait(up)) != 0){
  797.                 return -1;
  798.             }
  799.         }
  800.         if(cb.rnr == NULLRNR){
  801.             /* Connection went away */
  802.             errno = ENOTCONN;
  803.             return -1;
  804.         }
  805.         bp = dequeue(&cb.rnr->rcvq);
  806.         ntohnr3(&n3hdr,&bp);
  807.         cnt = len_p(bp);
  808.         if(from != NULLCHAR && fromlen != NULLINT
  809.            && *fromlen >= sizeof(struct sockaddr_nr)){
  810.             remote.nr = (struct sockaddr_nr *)from;
  811.             remote.nr->nr_family = AF_NETROM;
  812.             /* The callsign of the local user is not part of
  813.                NET/ROM level 3, so that field is not used here */
  814.             memcpy(remote.nr->nr_addr.node,n3hdr.source,AXALEN);
  815.             *fromlen = sizeof(struct sockaddr_nr);
  816.         }
  817.         break;
  818.     case TYPE_NETROML4:
  819.         while((cb.nr4 = up->cb.nr4) != NULLNR4CB
  820.          && (bp = recv_nr4(cb.nr4,(int16)0)) == NULLBUF){
  821.             if(up->noblock){
  822.                 errno = EWOULDBLOCK;
  823.                 return -1;
  824.             } else if((errno = pwait(up)) != 0){
  825.                 return -1;
  826.             }
  827.         }
  828.         if(cb.nr4 == NULLNR4CB){
  829.             /* Connection went away */
  830.             errno = ENOTCONN;
  831.             return -1;
  832.         }
  833.         cnt = bp->cnt;
  834.         break;
  835. #endif
  836.     }
  837.     if(bpp != NULLBUFP)
  838.         *bpp = bp;
  839.     else
  840.         free_p(bp);
  841.     return cnt;
  842. }
  843. /* Low level send routine; user supplies mbuf for transmission. More
  844.  * efficient than send() or sendto(), the higher level interfaces.
  845.  * The "to" and "tolen" parameters are ignored on connection-oriented
  846.  * sockets.
  847.  *
  848.  * In case of error, bp is freed so the caller doesn't have to worry about it.
  849.  */
  850. int
  851. send_mbuf(s,bp,flags,to,tolen)
  852. int s;            /* Socket index */
  853. struct mbuf *bp;    /* Buffer to send */
  854. int flags;        /* not currently used */
  855. char *to;        /* Destination, only for datagrams */
  856. int tolen;        /* Length of destination */
  857. {
  858.     register struct usock *up;
  859.     union cb cb;
  860.     union sp local,remote;
  861.     struct socket lsock,fsock;
  862.     int cnt;
  863.  
  864.     if((up = itop(s)) == NULLUSOCK){
  865.         free_p(bp);
  866.         errno = EBADF;
  867.         return -1;
  868.     }
  869. #ifndef    notdef
  870.     if(up->obuf != NULLBUF){
  871.         /* If there's unflushed output, send it.
  872.          * Note the importance of clearing up->obuf
  873.          * before the recursive call!
  874.          */
  875.         struct mbuf *bp1;
  876.  
  877.         bp1 = up->obuf;
  878.         up->obuf = NULLBUF;
  879.         send_mbuf(s,bp1,flags,to,tolen);
  880.     }
  881. #endif
  882.     if(up->name == NULLCHAR){
  883.         /* Automatic local name assignment for datagram sockets */
  884.         switch(up->type){
  885.         case TYPE_LOCAL_STREAM:
  886.         case TYPE_LOCAL_DGRAM:
  887.             break;    /* no op */
  888.         case TYPE_UDP:
  889.         case TYPE_RAW:
  890.             autobind(s,AF_INET);
  891.             break;
  892. #ifdef    AX25
  893.         case TYPE_AX25UI:
  894.             autobind(s,AF_AX25);
  895.             break;
  896. #endif
  897. #ifdef    NETROM
  898.         case TYPE_NETROML3:
  899.         case TYPE_NETROML4:
  900.             autobind(s,AF_NETROM);
  901.             break;
  902. #endif
  903.         default:
  904.             free_p(bp);
  905.             errno = ENOTCONN;
  906.             return -1;
  907.         }
  908.     }
  909.     cnt = len_p(bp);
  910.     switch(up->type){
  911.     case TYPE_LOCAL_DGRAM:
  912.         if(up->cb.local->peer == NULLUSOCK){
  913.             free_p(bp);
  914.             errno = ENOTCONN;
  915.             return -1;
  916.         }
  917.         enqueue(&up->cb.local->peer->cb.local->q,bp);
  918.         psignal(up->cb.local->peer,0);
  919.         /* If high water mark has been reached, block */
  920.         while(up->cb.local->peer != NULLUSOCK &&
  921.               len_q(up->cb.local->peer->cb.local->q) >=
  922.               up->cb.local->peer->cb.local->hiwat){
  923.             if(up->noblock){
  924.                 errno = EWOULDBLOCK;
  925.                 return -1;
  926.             } else if((errno = pwait(up->cb.local->peer)) != 0){
  927.                 return -1;
  928.             }
  929.         }
  930.         if(up->cb.local->peer == NULLUSOCK){
  931.             errno = ENOTCONN;
  932.             return -1;
  933.         }
  934.         break;
  935.     case TYPE_LOCAL_STREAM:
  936.         if(up->cb.local->peer == NULLUSOCK){
  937.             free_p(bp);
  938.             errno = ENOTCONN;
  939.             return -1;
  940.         }
  941.         append(&up->cb.local->peer->cb.local->q,bp);
  942.         psignal(up->cb.local->peer,0);
  943.         /* If high water mark has been reached, block */
  944.         while(up->cb.local->peer != NULLUSOCK &&
  945.               len_p(up->cb.local->peer->cb.local->q) >=
  946.               up->cb.local->peer->cb.local->hiwat){
  947.             if(up->noblock){
  948.                 errno = EWOULDBLOCK;
  949.                 return -1;
  950.             } else if((errno = pwait(up->cb.local->peer)) != 0){
  951.                 return -1;
  952.             }
  953.         }
  954.         if(up->cb.local->peer == NULLUSOCK){
  955.             errno = ENOTCONN;
  956.             return -1;
  957.         }
  958.         break;
  959.     case TYPE_TCP:
  960.         if((cb.tcb = up->cb.tcb) == NULLTCB){
  961.             free_p(bp);
  962.             errno = ENOTCONN;
  963.             return -1;
  964.         }        
  965.         cnt = send_tcp(cb.tcb,bp);
  966.  
  967.         while((cb.tcb = up->cb.tcb) != NULLTCB &&
  968.          cb.tcb->sndcnt > cb.tcb->window){
  969.             /* Send queue is full */
  970.             if(up->noblock){
  971.                 errno = EWOULDBLOCK;
  972.                 return -1;
  973.             } else if((errno = pwait(up)) != 0){
  974.                 return -1;
  975.             }
  976.         }
  977.          if(cb.tcb == NULLTCB){
  978.             errno = ENOTCONN;
  979.             return -1;
  980.         }
  981.         break;
  982.     case TYPE_UDP:
  983.         local.in = (struct sockaddr_in *)up->name;
  984.         lsock.address = local.in->sin_addr.s_addr;
  985.         lsock.port = local.in->sin_port;
  986.         if(to != NULLCHAR)
  987.             remote.in = (struct sockaddr_in *)to;
  988.         else if(up->peername != NULLCHAR)
  989.             remote.in = (struct sockaddr_in *)up->peername;
  990.         else {
  991.             errno = ENOTCONN;
  992.             return -1;
  993.         }    
  994.         fsock.address = remote.in->sin_addr.s_addr;
  995.         fsock.port = remote.in->sin_port;
  996.         send_udp(&lsock,&fsock,0,0,bp,0,0,0);
  997.         break;
  998.     case TYPE_RAW:
  999.         local.in = (struct sockaddr_in *)up->name;
  1000.         if(to != NULLCHAR)
  1001.             remote.in = (struct sockaddr_in *)to;
  1002.         else if(up->peername != NULLCHAR)
  1003.             remote.in = (struct sockaddr_in *)up->peername;
  1004.         else {
  1005.             errno = ENOTCONN;
  1006.             return -1;
  1007.         }    
  1008.         ip_send(local.in->sin_addr.s_addr,remote.in->sin_addr.s_addr,
  1009.             (char)up->cb.rip->protocol,0,0,bp,0,0,0);
  1010.         break;
  1011. #ifdef    AX25
  1012.     case TYPE_AX25I:
  1013.         if((cb.ax25 = up->cb.ax25) == NULLAX25){
  1014.             free_p(bp);
  1015.             errno = ENOTCONN;
  1016.             return -1;
  1017.         }
  1018.         send_ax25(cb.ax25,bp,PID_NO_L3);
  1019.  
  1020.         while((cb.ax25 = up->cb.ax25) != NULLAX25 &&
  1021.          len_q(cb.ax25->txq) * cb.ax25->paclen > cb.ax25->window){
  1022.             if(up->noblock){
  1023.                 errno = EWOULDBLOCK;
  1024.                 return -1;
  1025.             } else if((errno = pwait(up)) != 0){
  1026.                 return -1;
  1027.             }
  1028.         }
  1029.         if(cb.ax25 == NULLAX25){
  1030.             errno = EBADF;
  1031.             return -1;
  1032.         }
  1033.         break;
  1034.     case TYPE_AX25UI:
  1035.         local.ax = (struct sockaddr_ax *)up->name;
  1036.         if(to != NULLCHAR)
  1037.             remote.ax = (struct sockaddr_ax *)to;
  1038.         else if(up->peername != NULLCHAR)
  1039.             remote.ax = (struct sockaddr_ax *)up->peername;
  1040.         else {
  1041.             errno = ENOTCONN;
  1042.             return -1;
  1043.         }
  1044.         ax_output(if_lookup(remote.ax->iface),
  1045.               remote.ax->ax25_addr,
  1046.               local.ax->ax25_addr,PID_NO_L3,bp);
  1047.         break;
  1048. #endif
  1049. #ifdef NETROM
  1050.     case TYPE_NETROML3:
  1051.         if(len_p(bp) > NR4MAXINFO) {
  1052.             free_p(bp);
  1053.             errno = EMSGSIZE;
  1054.             return -1;
  1055.         }
  1056.         local.nr = (struct sockaddr_nr *)up->name;
  1057.         if(to != NULLCHAR)
  1058.             remote.nr = (struct sockaddr_nr *)to;
  1059.         else if(up->peername != NULLCHAR)
  1060.             remote.nr = (struct sockaddr_nr *)up->peername;
  1061.         else {
  1062.             errno = ENOTCONN;
  1063.             return -1;
  1064.         }    
  1065.         /* The NETROM username is always ignored in outgoing traffic */
  1066.         nr_sendraw(remote.nr->nr_addr.node,
  1067.          up->cb.rnr->protocol,up->cb.rnr->protocol,bp);
  1068.         break;
  1069.     case TYPE_NETROML4:
  1070.         if((cb.nr4 = up->cb.nr4) == NULLNR4CB) {
  1071.             free_p(bp);
  1072.             errno = ENOTCONN;
  1073.             return -1;
  1074.         }
  1075.         if(len_p(bp) > NR4MAXINFO){ /* reject big packets */
  1076.             free_p(bp);
  1077.             errno = EMSGSIZE;
  1078.             return -1;
  1079.         }
  1080.         send_nr4(cb.nr4,bp);
  1081.  
  1082.         while((cb.nr4 = up->cb.nr4) != NULLNR4CB &&
  1083.          cb.nr4->nbuffered >= cb.nr4->window){
  1084.             if(up->noblock){
  1085.                 errno = EWOULDBLOCK;
  1086.                 return -1;
  1087.             } else if((errno = pwait(up)) != 0){
  1088.                 errno = EINTR;
  1089.                 return -1;
  1090.             }
  1091.         }
  1092.         if(cb.nr4 == NULLNR4CB){
  1093.             errno = EBADF;
  1094.             return -1;
  1095.         }
  1096.         break;
  1097. #endif
  1098.     }    
  1099.     return cnt;
  1100. }
  1101. /* Return local name passed in an earlier bind() call */
  1102. int
  1103. getsockname(s,name,namelen)
  1104. int s;        /* Socket index */
  1105. char *name;    /* Place to stash name */
  1106. int *namelen;    /* Length of same */
  1107. {
  1108.     register struct usock *up;
  1109.  
  1110.     if((up = itop(s)) == NULLUSOCK){
  1111.         errno = EBADF;
  1112.         return -1;
  1113.     }
  1114.     if(name == NULLCHAR || namelen == (int *)NULL){
  1115.         errno = EFAULT;
  1116.         return -1;
  1117.     }
  1118.     if(up->name == NULLCHAR){
  1119.         /* Not bound yet */
  1120.         *namelen = 0;
  1121.         return 0;
  1122.     }
  1123.     if(up->name != NULLCHAR){
  1124.         *namelen = min(*namelen,up->namelen);
  1125.         memcpy(name,up->name,*namelen);
  1126.     }
  1127.     return 0;
  1128. }
  1129. /* Get remote name, returning result of earlier connect() call. */
  1130. int
  1131. getpeername(s,peername,peernamelen)
  1132. int s;            /* Socket index */
  1133. char *peername;        /* Place to stash name */
  1134. int *peernamelen;    /* Length of same */
  1135. {
  1136.     register struct usock *up;
  1137.  
  1138.     if((up = itop(s)) == NULLUSOCK){
  1139.         errno = EBADF;
  1140.         return -1;
  1141.     }
  1142.     if(up->peername == NULLCHAR){
  1143.         errno = ENOTCONN;
  1144.         return -1;
  1145.     }
  1146.     if(peername == NULLCHAR || peernamelen == (int *)NULL){
  1147.         errno = EFAULT;
  1148.         return -1;
  1149.     }
  1150.     *peernamelen = min(*peernamelen,up->peernamelen);
  1151.     memcpy(peername,up->peername,*peernamelen);
  1152.     return 0;
  1153. }
  1154. /* Return length of protocol queue, either send or receive. */
  1155. int
  1156. socklen(s,rtx)
  1157. int s;        /* Socket index */
  1158. int rtx;    /* 0 = receive queue, 1 = transmit queue */
  1159. {
  1160.     register struct usock *up;
  1161.     int len = -1;
  1162.  
  1163.     if((up = itop(s)) == NULLUSOCK){
  1164.         errno = EBADF;
  1165.         return -1;
  1166.     }
  1167.     if(up->cb.p == NULLCHAR){
  1168.         errno = ENOTCONN;
  1169.         return -1;
  1170.     }
  1171.     if(rtx < 0 || rtx > 1){
  1172.         errno = EINVAL;
  1173.         return -1;
  1174.     }
  1175.     switch(up->type){
  1176.     case TYPE_LOCAL_DGRAM:
  1177.         switch(rtx){
  1178.         case 0:
  1179.             len = len_q(up->cb.local->q);
  1180.             break;
  1181.         case 1:
  1182.             if(up->cb.local->peer != NULLUSOCK)
  1183.                 len = len_q(up->cb.local->peer->cb.local->q);
  1184.             break;
  1185.         }
  1186.         break;
  1187.     case TYPE_LOCAL_STREAM:
  1188.         switch(rtx){
  1189.         case 0:
  1190.             len = len_p(up->cb.local->q) + len_p(up->ibuf);
  1191.             break;
  1192.         case 1:
  1193.             if(up->cb.local->peer != NULLUSOCK)
  1194.                 len = len_p(up->cb.local->peer->cb.local->q)
  1195.                       + len_p(up->obuf);
  1196.             break;
  1197.         }
  1198.         break;
  1199.     case TYPE_TCP:
  1200.         switch(rtx){
  1201.         case 0:
  1202.             len = up->cb.tcb->rcvcnt + len_p(up->ibuf);
  1203.             break;
  1204.         case 1:
  1205.             len = up->cb.tcb->sndcnt + len_p(up->obuf);
  1206.             break;
  1207.         }
  1208.         break;
  1209.     case TYPE_UDP:
  1210.         switch(rtx){
  1211.         case 0:
  1212.             len = up->cb.udp->rcvcnt;
  1213.             break;
  1214.         case 1:
  1215.             len = 0;
  1216.             break;
  1217.         }
  1218.         break;
  1219. #ifdef    AX25
  1220.     case TYPE_AX25I:
  1221.         switch(rtx){
  1222.         case 0:
  1223.             len = len_p(up->cb.ax25->rxq) + len_p(up->ibuf);
  1224.             break;
  1225.         case 1:    /* Number of packets, not bytes */
  1226.             len = len_q(up->cb.ax25->txq);
  1227.             if(up->obuf != NULLBUF)
  1228.                 len++;
  1229.         }
  1230.         break;
  1231.     case TYPE_AX25UI:
  1232.         switch(rtx){    
  1233.         case 0:
  1234.             len = len_q(Bcq);
  1235.             break;
  1236.         case 1:
  1237.             len = 0;        
  1238.             break;
  1239.         }
  1240.         break;
  1241. #endif
  1242. #ifdef NETROM
  1243.     case TYPE_NETROML3:
  1244.         switch(rtx){    
  1245.         case 0:
  1246.             len = len_q(up->cb.rnr->rcvq);
  1247.             break;
  1248.         case 1:
  1249.             len = 0;        
  1250.         }
  1251.         break;
  1252.     case TYPE_NETROML4:
  1253.         switch(rtx){
  1254.         case 0:
  1255.             len = len_p(up->cb.nr4->rxq) + len_p(up->obuf);
  1256.             break;
  1257.         case 1:    /* Number of packets, not bytes */
  1258.             len = len_q(up->cb.nr4->txq);
  1259.             if(up->obuf != NULLBUF)
  1260.                 len++;
  1261.             break;
  1262.         }
  1263.         break;
  1264. #endif
  1265.     case TYPE_RAW:
  1266.         switch(rtx){    
  1267.         case 0:
  1268.             len = len_q(up->cb.rip->rcvq);
  1269.             break;
  1270.         case 1:
  1271.             len = 0;        
  1272.             break;
  1273.         }
  1274.         break;
  1275.     }
  1276.     return len;
  1277. }
  1278. /* Force retransmission. Valid only for connection-oriented sockets. */
  1279. int
  1280. sockkick(s)
  1281. int s;    /* Socket index */
  1282. {
  1283.     register struct usock *up;
  1284.  
  1285.     if((up = itop(s)) == NULLUSOCK){
  1286.         errno = EBADF;
  1287.         return -1;
  1288.     }
  1289.     if(up->type == TYPE_LOCAL_STREAM || up->type == TYPE_LOCAL_DGRAM){
  1290.         errno = EINVAL;
  1291.         return -1;
  1292.     }
  1293.     if(up->cb.p == NULLCHAR){
  1294.         errno = ENOTCONN;
  1295.         return -1;
  1296.     }
  1297.     switch(up->type){
  1298.     case TYPE_TCP:
  1299.         kick_tcp(up->cb.tcb);
  1300.         break;
  1301. #ifdef    AX25
  1302.     case TYPE_AX25I:
  1303.         kick_ax25(up->cb.ax25);
  1304.         break;
  1305. #endif
  1306. #ifdef NETROM
  1307.     case TYPE_NETROML4:
  1308.         kick_nr4(up->cb.nr4);
  1309.         break;
  1310. #endif
  1311.     default:
  1312.         /* Datagram sockets can't be kicked */
  1313.         errno = EOPNOTSUPP;
  1314.         return -1;
  1315.     }
  1316.     return 0;
  1317. }
  1318.  
  1319. /* Change owner of socket, return previous owner */
  1320. struct proc *
  1321. sockowner(s,newowner)
  1322. int s;            /* Socket index */
  1323. struct proc *newowner;    /* Process table address of new owner */
  1324. {
  1325.     register struct usock *up;
  1326.     struct proc *pp;
  1327.  
  1328.     if((up = itop(s)) == NULLUSOCK){
  1329.         errno = EBADF;
  1330.         return NULLPROC;
  1331.     }
  1332.     pp = up->owner;
  1333.     if(newowner != NULLPROC)
  1334.         up->owner = newowner;
  1335.     return pp;
  1336. }
  1337. /* Close down a socket three ways. Type 0 means "no more receives"; this
  1338.  * replaces the incoming data upcall with a routine that discards further
  1339.  * data. Type 1 means "no more sends", and obviously corresponds to sending
  1340.  * a TCP FIN. Type 2 means "no more receives or sends". This I interpret
  1341.  * as "abort the connection".
  1342.  */
  1343. int
  1344. shutdown(s,how)
  1345. int s;        /* Socket index */
  1346. int how;    /* (see above) */
  1347. {
  1348.     register struct usock *up;
  1349.  
  1350.     if((up = itop(s)) == NULLUSOCK){
  1351.         errno = EBADF;
  1352.         return -1;
  1353.     }
  1354.     if(up->cb.p == NULLCHAR){
  1355.         errno = ENOTCONN;
  1356.         return -1;
  1357.     }
  1358.     switch(up->type){
  1359.     case TYPE_LOCAL_DGRAM:
  1360.     case TYPE_LOCAL_STREAM:
  1361.         if(up->cb.local->q == NULLBUF)
  1362.             close_s(s);
  1363.         else
  1364.             up->cb.local->flags = LOC_SHUTDOWN;
  1365.         break;
  1366.     case TYPE_TCP:
  1367.         switch(how){
  1368.         case 0:    /* No more receives -- replace upcall */
  1369.             up->cb.tcb->r_upcall = trdiscard;
  1370.             break;
  1371.         case 1:    /* Send EOF */
  1372.             close_tcp(up->cb.tcb);
  1373.             break;
  1374.         case 2:    /* Blow away TCB */
  1375.             reset_tcp(up->cb.tcb);
  1376.             up->cb.tcb = NULLTCB;
  1377.             break;
  1378.         }
  1379.         break;
  1380. #ifdef    AX25
  1381.     case TYPE_AX25UI:
  1382.         close_s(s);
  1383.         break;
  1384.     case TYPE_AX25I:
  1385.         switch(how){
  1386.         case 0:
  1387.         case 1:    /* Attempt regular disconnect */
  1388.             disc_ax25(up->cb.ax25);
  1389.             break;
  1390.         case 2: /* Blow it away */
  1391.             reset_ax25(up->cb.ax25);
  1392.             up->cb.ax25 = NULLAX25;
  1393.             break;
  1394.         }
  1395.         break;        
  1396. #endif
  1397. #ifdef    NETROM
  1398.     case TYPE_NETROML3:
  1399.         close_s(s);
  1400.         break;
  1401.     case TYPE_NETROML4:
  1402.         switch(how){
  1403.         case 0:
  1404.         case 1:    /* Attempt regular disconnect */
  1405.             disc_nr4(up->cb.nr4);
  1406.             break;
  1407.         case 2: /* Blow it away */
  1408.             reset_nr4(up->cb.nr4);
  1409.             up->cb.nr4 = NULLNR4CB;
  1410.             break;
  1411.         }
  1412.         break;        
  1413. #endif
  1414.     case TYPE_RAW:
  1415.     case TYPE_UDP:
  1416.         close_s(s);
  1417.         break;
  1418.     default:
  1419.         errno = EOPNOTSUPP;
  1420.         return -1;
  1421.     }
  1422.     psignal(up,0);
  1423.     return 0;
  1424. }
  1425. /* Close a socket, freeing it for reuse. Try to do a graceful close on a
  1426.  * TCP socket, if possible
  1427.  */
  1428. int
  1429. close_s(s)
  1430. int s;        /* Socket index */
  1431. {
  1432.     register struct usock *up;
  1433.  
  1434.     if((up = itop(s)) == NULLUSOCK){
  1435.         errno = EBADF;
  1436.         return -1;
  1437.     }
  1438.     if(--up->refcnt > 0)
  1439.         return 0;    /* Others are still using it */
  1440.     usflush(s);
  1441.     if(up->ibuf != NULLBUF){
  1442.         free_p(up->ibuf);
  1443.         up->ibuf = NULLBUF;
  1444.     }
  1445.     switch(up->type){
  1446.     case TYPE_LOCAL_STREAM:
  1447.     case TYPE_LOCAL_DGRAM:
  1448.         if(up->cb.local->peer != NULLUSOCK){
  1449.             up->cb.local->peer->cb.local->peer = NULLUSOCK;
  1450.             psignal(up->cb.local->peer,0);
  1451.         }
  1452.         free_q(&up->cb.local->q);
  1453.         free(up->cb.local);
  1454.         break;
  1455.     case TYPE_TCP:
  1456.         if(up->cb.tcb != NULLTCB){    /* In case it's been reset */
  1457.             up->cb.tcb->r_upcall = trdiscard;
  1458.             /* Tell the TCP_CLOSED upcall there's no more socket */
  1459.             up->cb.tcb->user = -1;
  1460.             close_tcp(up->cb.tcb);
  1461.         }
  1462.         break;
  1463.     case TYPE_UDP:
  1464.         if(up->cb.udp != NULLUDP){
  1465.             del_udp(up->cb.udp);
  1466.         }
  1467.         break;
  1468. #ifdef    AX25
  1469.     case TYPE_AX25I:
  1470.         if(up->cb.ax25 != NULLAX25){
  1471.             /* Tell the TCP_CLOSED upcall there's no more socket */
  1472.             up->cb.ax25->user = -1;
  1473.             disc_ax25(up->cb.ax25);
  1474.         }
  1475.         break;
  1476.     case TYPE_AX25UI:
  1477.         Axui_sock = -1;
  1478.         free_q(&Bcq);
  1479.         psignal(&Bcq,0);    /* Unblock any reads */
  1480.         break;
  1481. #endif
  1482. #ifdef    NETROM
  1483.     case TYPE_NETROML3:
  1484.         del_rnr(up->cb.rnr);
  1485.         break;
  1486.     case TYPE_NETROML4:
  1487.         if(up->cb.nr4 != NULLNR4CB){
  1488.             /* Tell the TCP_CLOSED upcall there's no more socket */
  1489.             up->cb.nr4->user = -1;
  1490.             disc_nr4(up->cb.nr4);
  1491.         }
  1492.         break;
  1493. #endif
  1494.     case TYPE_RAW:
  1495.         del_ip(up->cb.rip);
  1496.         break;
  1497.     default:
  1498.         errno = EOPNOTSUPP;
  1499.         return -1;
  1500.     }
  1501. #ifdef    LZW
  1502.     if(up->zout != NULLLZW || up->zin != NULLLZW)
  1503.         lzwfree(up);
  1504. #endif
  1505.     free(up->name);
  1506.     free(up->peername);
  1507.  
  1508.     up->cb.p = NULLCHAR;
  1509.     up->name = up->peername = NULLCHAR;
  1510.     up->type = NOTUSED;
  1511.     psignal(up,0);    /* Wake up anybody doing an accept() or recv() */
  1512.     return 0;
  1513. }
  1514. /* Increment reference count for specified socket */
  1515. int
  1516. usesock(s)
  1517. int s;
  1518. {
  1519.     struct usock *up;
  1520.  
  1521.     if((up = itop(s)) == NULLUSOCK){
  1522.         errno = EBADF;
  1523.         return -1;
  1524.     }
  1525.     up->refcnt++;
  1526.     return 0;
  1527. }
  1528. /* Blow away all sockets belonging to a certain process. Used by killproc(). */
  1529. void
  1530. freesock(pp)
  1531. struct proc *pp;
  1532. {
  1533.     register struct usock *up;
  1534.     register int i;
  1535.  
  1536.     for(i=SOCKBASE;i < Nusock+SOCKBASE;i++){
  1537.         up = itop(i);
  1538.         if(up != NULLUSOCK && up->type != NOTUSED && up->owner == pp)
  1539.             shutdown(i,2);
  1540.     }
  1541. }
  1542. /* Start of internal subroutines */
  1543.  
  1544. /* Raw IP receive upcall routine */
  1545. static void
  1546. rip_recv(rp)
  1547. struct raw_ip *rp;
  1548. {
  1549.     psignal(itop(rp->user),1);
  1550.     pwait(NULL);
  1551. }
  1552.  
  1553. /* UDP receive upcall routine */
  1554. static void
  1555. s_urcall(iface,udp,cnt)
  1556. struct iface *iface;
  1557. struct udp_cb *udp;
  1558. int cnt;
  1559. {
  1560.     psignal(itop(udp->user),1);
  1561.     pwait(NULL);
  1562. }
  1563. /* TCP receive upcall routine */
  1564. static void
  1565. s_trcall(tcb,cnt)
  1566. struct tcb *tcb;
  1567. int cnt;
  1568. {
  1569.     /* Wake up anybody waiting for data, and let them run */
  1570.     psignal(itop(tcb->user),1);
  1571.     pwait(NULL);
  1572. }
  1573. /* TCP transmit upcall routine */
  1574. static void
  1575. s_ttcall(tcb,cnt)
  1576. struct tcb *tcb;
  1577. int cnt;
  1578. {
  1579.     /* Wake up anybody waiting to send data, and let them run */
  1580.     psignal(itop(tcb->user),1);
  1581.     pwait(NULL);
  1582. }
  1583. /* TCP state change upcall routine */
  1584. static void
  1585. s_tscall(tcb,old,new)
  1586. struct tcb *tcb;
  1587. int old,new;
  1588. {
  1589.     int s,ns;
  1590.     struct usock *up,*nup,*oup;
  1591.     union sp sp;
  1592.  
  1593.     s = tcb->user;
  1594.     oup = up = itop(s);
  1595.  
  1596.     switch(new){
  1597.     case TCP_CLOSED:
  1598.         /* Clean up. If the user has already closed the socket,
  1599.          * then up will be null (s was set to -1 by the close routine).
  1600.          * If not, then this is an abnormal close (e.g., a reset)
  1601.          * and clearing out the pointer in the socket structure will
  1602.          * prevent any further operations on what will be a freed
  1603.          * control block. Also wake up anybody waiting on events
  1604.          * related to this tcb so they will notice it disappearing.
  1605.          */
  1606.         if(up != NULLUSOCK){
  1607.             up->cb.tcb = NULLTCB;
  1608.             up->errcodes[0] = tcb->reason;
  1609.             up->errcodes[1] = tcb->type;
  1610.             up->errcodes[2] = tcb->code;
  1611.         }
  1612.         del_tcp(tcb);
  1613.         break;
  1614.     case TCP_SYN_RECEIVED:
  1615.         /* Handle an incoming connection. If this is a server TCB,
  1616.          * then we're being handed a "clone" TCB and we need to
  1617.          * create a new socket structure for it. In either case,
  1618.          * find out who we're talking to and wake up the guy waiting
  1619.          * for the connection.
  1620.          */
  1621.         if(tcb->flags.clone){
  1622.             /* Clone the socket */
  1623.             ns = socket(AF_INET,SOCK_STREAM,0);
  1624.             nup = itop(ns);
  1625.             ASSIGN(*nup,*up);
  1626.             tcb->user = ns;
  1627.             nup->cb.tcb = tcb;
  1628.             /* Allocate new memory for the name areas */
  1629.             nup->name = mallocw(SOCKSIZE);
  1630.             nup->peername = mallocw(SOCKSIZE);
  1631.             /* Store the new socket # in the old one */
  1632.             up->rdysock = ns;
  1633.             up = nup;
  1634.             s = ns;
  1635.         } else {
  1636.             /* Allocate space for the peer's name */
  1637.             up->peername = mallocw(SOCKSIZE);
  1638.             /* Store the old socket # in the old socket */
  1639.             up->rdysock = s;
  1640.         }
  1641.         /* Load the addresses. Memory for the name has already
  1642.          * been allocated, either above or in the original bind.
  1643.          */
  1644.         sp.p = up->name;
  1645.         sp.in->sin_family = AF_INET;
  1646.         sp.in->sin_addr.s_addr = up->cb.tcb->conn.local.address;
  1647.         sp.in->sin_port = up->cb.tcb->conn.local.port;
  1648.         up->namelen = SOCKSIZE;
  1649.  
  1650.         sp.p = up->peername;
  1651.         sp.in->sin_family = AF_INET;
  1652.         sp.in->sin_addr.s_addr = up->cb.tcb->conn.remote.address;
  1653.         sp.in->sin_port = up->cb.tcb->conn.remote.port;
  1654.         up->peernamelen = SOCKSIZE;
  1655.  
  1656.         /* Wake up the guy accepting it, and let him run */
  1657.         psignal(oup,1);
  1658.         pwait(NULL);
  1659.         break;
  1660.     default:    /* Ignore all other state transitions */
  1661.         break;
  1662.     }
  1663.     psignal(up,0);    /* In case anybody's waiting */
  1664. }
  1665. /* Discard data received on a TCP connection. Used after a receive shutdown or
  1666.  * close_s until the TCB disappears.
  1667.  */
  1668. static void
  1669. trdiscard(tcb,cnt)
  1670. struct tcb *tcb;
  1671. int cnt;
  1672. {
  1673.     struct mbuf *bp;
  1674.  
  1675.     recv_tcp(tcb,&bp,(int16)cnt);
  1676.     free_p(bp);
  1677. }
  1678. #ifdef    AX25
  1679. /* AX.25 receive upcall */
  1680. void
  1681. s_arcall(axp,cnt)
  1682. struct ax25_cb *axp;
  1683. int cnt;
  1684. {
  1685.     int ns;
  1686.     struct usock *up,*nup,*oup;
  1687.     union sp sp;
  1688.  
  1689.     up = itop(axp->user);
  1690.     /* When AX.25 data arrives for the first time the AX.25 listener
  1691.        is notified, if active. If the AX.25 listener is a server its
  1692.        socket is duplicated in the same manner as in s_tscall().
  1693.      */
  1694.     if (Axi_sock != -1 && axp->user == -1) {
  1695.         oup = up = itop(Axi_sock);
  1696.         /* From now on, use the same upcalls as the listener */
  1697.         axp->t_upcall = up->cb.ax25->t_upcall;
  1698.         axp->r_upcall = up->cb.ax25->r_upcall;
  1699.         axp->s_upcall = up->cb.ax25->s_upcall;
  1700.         if (up->cb.ax25->flags.clone) {
  1701.             /* Clone the socket */
  1702.             ns = socket(AF_AX25,SOCK_STREAM,0);
  1703.             nup = itop(ns);
  1704.             ASSIGN(*nup,*up);
  1705.             axp->user = ns;
  1706.             nup->cb.ax25 = axp;
  1707.             /* Allocate new memory for the name areas */
  1708.             nup->name = mallocw(sizeof(struct sockaddr_ax));
  1709.             nup->peername = mallocw(sizeof(struct sockaddr_ax));
  1710.             /* Store the new socket # in the old one */
  1711.             up->rdysock = ns;
  1712.             up = nup;
  1713.         } else {
  1714.             axp->user = Axi_sock;
  1715.             del_ax25(up->cb.ax25);
  1716.             up->cb.ax25 = axp;
  1717.             /* Allocate space for the peer's name */
  1718.             up->peername = mallocw(sizeof(struct sockaddr_ax));
  1719.             /* Store the old socket # in the old socket */
  1720.             up->rdysock = Axi_sock;
  1721.         }
  1722.         /* Load the addresses. Memory for the name has already
  1723.          * been allocated, either above or in the original bind.
  1724.          */
  1725.         sp.p = up->name;
  1726.         sp.ax->sax_family = AF_AX25;
  1727.         memcpy(sp.ax->ax25_addr,axp->local,AXALEN);
  1728.         memcpy(sp.ax->iface,axp->iface->name,ILEN);
  1729.         up->namelen = sizeof(struct sockaddr_ax);
  1730.  
  1731.         sp.p = up->peername;
  1732.         sp.ax->sax_family = AF_AX25;
  1733.         memcpy(sp.ax->ax25_addr,axp->remote,AXALEN);
  1734.         memcpy(sp.ax->iface,axp->iface->name,ILEN);
  1735.         up->peernamelen = sizeof(struct sockaddr_ax);
  1736.         /* Wake up the guy accepting it, and let him run */
  1737.         psignal(oup,1);
  1738.         pwait(NULL);
  1739.         return;
  1740.     }
  1741.     /* Wake up anyone waiting, and let them run */
  1742.     psignal(up,1);
  1743.     pwait(NULL);
  1744. }
  1745. /* AX.25 transmit upcall */
  1746. void
  1747. s_atcall(axp,cnt)
  1748. struct ax25_cb *axp;
  1749. int cnt;
  1750. {
  1751.     /* Wake up anyone waiting, and let them run */
  1752.     psignal(itop(axp->user),1);
  1753.     pwait(NULL);
  1754. }
  1755. /* AX25 state change upcall routine */
  1756. void
  1757. s_ascall(axp,old,new)
  1758. register struct ax25_cb *axp;
  1759. int old,new;
  1760. {
  1761.     int s;
  1762.     struct usock *up;
  1763.  
  1764.     s = axp->user;
  1765.     up = itop(s);
  1766.  
  1767.     switch(new){
  1768.     case LAPB_DISCONNECTED:
  1769.         /* Clean up. If the user has already closed the socket,
  1770.          * then up will be null (s was set to -1 by the close routine).
  1771.          * If not, then this is an abnormal close (e.g., a reset)
  1772.          * and clearing out the pointer in the socket structure will
  1773.          * prevent any further operations on what will be a freed
  1774.          * control block. Also wake up anybody waiting on events
  1775.          * related to this block so they will notice it disappearing.
  1776.          */
  1777.         if(up != NULLUSOCK){
  1778.             up->errcodes[0] = axp->reason;
  1779.             up->cb.ax25 = NULLAX25;
  1780.         }
  1781.         del_ax25(axp);
  1782.         break;
  1783.     default:    /* Other transitions are ignored */
  1784.         break;
  1785.     }
  1786.     psignal(up,0);    /* In case anybody's waiting */
  1787. }
  1788. #endif
  1789. #ifdef NETROM
  1790. /* NET/ROM receive upcall routine */
  1791. static void
  1792. s_nrcall(cb,cnt)
  1793. struct nr4cb *cb;
  1794. int cnt;
  1795. {
  1796.     /* Wake up anybody waiting for data, and let them run */
  1797.     psignal(itop(cb->user),1);
  1798.     pwait(NULL);
  1799. }
  1800. /* NET/ROM transmit upcall routine */
  1801. static void
  1802. s_ntcall(cb,cnt)
  1803. struct nr4cb *cb;
  1804. int cnt;
  1805. {
  1806.     /* Wake up anybody waiting to send data, and let them run */
  1807.     psignal(itop(cb->user),1);
  1808.     pwait(NULL);
  1809. }
  1810. /* NET/ROM state change upcall routine */
  1811. static void
  1812. s_nscall(cb,old,new)
  1813. struct nr4cb *cb;
  1814. int old,new;
  1815. {
  1816.     int s,ns;
  1817.     struct usock *up,*nup,*oup;
  1818.     union sp sp;
  1819.  
  1820.     s = cb->user;
  1821.     oup = up = itop(s);
  1822.  
  1823.      if(new == NR4STDISC && up != NULLUSOCK){
  1824.         /* Clean up. If the user has already closed the socket,
  1825.          * then up will be null (s was set to -1 by the close routine).
  1826.          * If not, then this is an abnormal close (e.g., a reset)
  1827.          * and clearing out the pointer in the socket structure will
  1828.          * prevent any further operations on what will be a freed
  1829.          * control block. Also wake up anybody waiting on events
  1830.          * related to this cb so they will notice it disappearing.
  1831.          */
  1832.          up->cb.nr4 = NULLNR4CB;
  1833.          up->errcodes[0] = cb->dreason;
  1834.      }
  1835.      if(new == NR4STCON && old == NR4STDISC){
  1836.         /* Handle an incoming connection. If this is a server cb,
  1837.          * then we're being handed a "clone" cb and we need to
  1838.          * create a new socket structure for it. In either case,
  1839.          * find out who we're talking to and wake up the guy waiting
  1840.          * for the connection.
  1841.          */
  1842.         if(cb->clone){
  1843.             /* Clone the socket */
  1844.             ns = socket(AF_NETROM,SOCK_SEQPACKET,0);
  1845.             nup = itop(ns);
  1846.             ASSIGN(*nup,*up);
  1847.             cb->user = ns;
  1848.             nup->cb.nr4 = cb;
  1849.             cb->clone = 0; /* to avoid getting here again */
  1850.             /* Allocate new memory for the name areas */
  1851.             nup->name = mallocw(sizeof(struct sockaddr_nr));
  1852.             nup->peername = mallocw(sizeof(struct sockaddr_nr));
  1853.             /* Store the new socket # in the old one */
  1854.             up->rdysock = ns;
  1855.             up = nup;
  1856.             s = ns;
  1857.         } else {
  1858.             /* Allocate space for the peer's name */
  1859.             up->peername = mallocw(sizeof(struct sockaddr_nr));
  1860.             /* Store the old socket # in the old socket */
  1861.             up->rdysock = s;
  1862.         }
  1863.         /* Load the addresses. Memory for the name has already
  1864.          * been allocated, either above or in the original bind.
  1865.          */
  1866.         sp.p = up->name;
  1867.         sp.nr->nr_family = AF_NETROM;
  1868.         ASSIGN(sp.nr->nr_addr,up->cb.nr4->local);
  1869.         up->namelen = sizeof(struct sockaddr_nr);
  1870.  
  1871.         sp.p = up->peername;
  1872.         sp.nr->nr_family = AF_NETROM;
  1873.         ASSIGN(sp.nr->nr_addr,up->cb.nr4->remote);
  1874.         up->peernamelen = sizeof(struct sockaddr_nr);
  1875.  
  1876.         /* Wake up the guy accepting it, and let him run */
  1877.         psignal(oup,1);
  1878.         pwait(NULL);
  1879.     }
  1880.      /* Ignore all other state transitions */    
  1881.     psignal(up,0);    /* In case anybody's waiting */
  1882. }
  1883. #endif
  1884.  
  1885. /* Verify address family and length according to the socket type */
  1886. static int
  1887. checkaddr(type,name,namelen)
  1888. int type;
  1889. char *name;
  1890. int namelen;
  1891. {
  1892.     union sp sp;
  1893.  
  1894.     sp.p = name;
  1895.     /* Verify length and address family according to protocol */
  1896.     switch(type){
  1897.     case TYPE_TCP:
  1898.     case TYPE_UDP:
  1899.         if(sp.in->sin_family != AF_INET
  1900.          || namelen != sizeof(struct sockaddr_in))
  1901.             return -1;
  1902.         break;
  1903. #ifdef    AX25
  1904.     case TYPE_AX25I:
  1905.     case TYPE_AX25UI:
  1906.         if(sp.ax->sax_family != AF_AX25
  1907.          || namelen != sizeof(struct sockaddr_ax))
  1908.             return -1;
  1909.         break;
  1910. #endif
  1911. #ifdef    NETROM
  1912.     case TYPE_NETROML3:
  1913.     case TYPE_NETROML4:
  1914.         if(sp.nr->nr_family != AF_NETROM
  1915.          || namelen != sizeof(struct sockaddr_nr))
  1916.             return -1;
  1917.         break;
  1918. #endif
  1919.     }
  1920.     return 0;
  1921. }
  1922. /* Issue an automatic bind of a local address */
  1923. static void
  1924. autobind(s,af)
  1925. int s,af;
  1926. {
  1927.     char buf[MAXSOCKSIZE];
  1928.     union sp sp;
  1929.  
  1930.     sp.p = buf;
  1931.     switch(af){
  1932.     case AF_INET:
  1933.         sp.in->sin_family = AF_INET;
  1934.         sp.in->sin_addr.s_addr = INADDR_ANY;
  1935.         sp.in->sin_port = Lport++;
  1936.         bind(s,sp.p,sizeof(struct sockaddr_in));
  1937.         break;
  1938. #ifdef    AX25
  1939.     case AF_AX25:
  1940.         sp.ax->sax_family = AF_AX25;
  1941.         memset(sp.ax->ax25_addr,'\0',AXALEN);
  1942.         memset(sp.ax->iface,'\0',ILEN);
  1943.         bind(s,sp.p,sizeof(struct sockaddr_ax));
  1944.         break;
  1945. #endif
  1946. #ifdef    NETROM
  1947.     case AF_NETROM:
  1948.         sp.nr->nr_family = AF_NETROM;
  1949.         memcpy(sp.nr->nr_addr.user,Mycall,AXALEN);
  1950.         memcpy(sp.nr->nr_addr.node,Mycall,AXALEN);
  1951.         bind(s,sp.p,sizeof(struct sockaddr_nr));
  1952.         break;
  1953. #endif
  1954.     }
  1955. }
  1956.  
  1957. /* Return a pair of mutually connected sockets in sv[0] and sv[1] */
  1958. int
  1959. socketpair(af,type,protocol,sv)
  1960. int af;
  1961. int type;
  1962. int protocol;
  1963. int sv[];
  1964. {
  1965.     struct usock *up0, *up1;
  1966.     if(sv == NULLINT){
  1967.         errno = EFAULT;
  1968.         return -1;
  1969.     }
  1970.     if(af != AF_LOCAL){
  1971.         errno = EAFNOSUPPORT;
  1972.         return -1;
  1973.     }
  1974.     if(type != SOCK_STREAM && type != SOCK_DGRAM){
  1975.         errno = ESOCKTNOSUPPORT;
  1976.         return -1;
  1977.     }
  1978.     if((sv[0] = socket(af,type,protocol)) == -1)
  1979.         return -1;
  1980.     if((sv[1] = socket(af,type,protocol)) == -1){
  1981.         close_s(sv[0]);
  1982.         return -1;
  1983.     }
  1984.     up0 = itop(sv[0]);
  1985.     up1 = itop(sv[1]);
  1986.     up0->cb.local->peer = up1;
  1987.     up1->cb.local->peer = up0;
  1988.     return sv[1];
  1989. }
  1990.