home *** CD-ROM | disk | FTP | other *** search
/ What PC? 1996 April / WHAT_PC_APR_96.ISO / internet / twinsock / src / commands.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-24  |  21.5 KB  |  996 lines

  1. /*
  2.  *  TwinSock - "Troy's Windows Sockets"
  3.  *
  4.  *  Copyright (C) 1994-1995  Troy Rollo <troy@cbme.unsw.EDU.AU>
  5.  *
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the license in the file LICENSE.TXT included
  8.  *  with the TwinSock distribution.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
  13.  */
  14.  
  15. #include <stdio.h>
  16. #include <sys/types.h>
  17. #include <netinet/in.h>
  18. #include <netdb.h>
  19. #include <errno.h>
  20. #include <sys/socket.h>
  21. #include "twinsock.h"
  22. #include "tx.h"
  23. #include "wserror.h"
  24.  
  25. #ifdef NEED_H_ERRNO
  26. extern int h_errno;
  27. #endif
  28. #ifdef NO_H_ERRNO
  29. #define h_errno errno
  30. #endif
  31.  
  32. #ifndef AF_UNSPEC
  33. #define    AF_UNSPEC    0
  34. #endif
  35. #ifndef AF_UNIX
  36. #define AF_UNIX        -1
  37. #endif
  38. #ifndef AF_INET
  39. #define AF_INET        -1
  40. #endif
  41. #ifndef AF_IMPLINK
  42. #define AF_IMPLINK      -1
  43. #endif
  44. #ifndef AF_PUP
  45. #define AF_PUP          -1
  46. #endif
  47. #ifndef AF_CHAOS
  48. #define AF_CHAOS        -1
  49. #endif
  50. #ifndef AF_NS
  51. #define AF_NS          -1
  52. #endif
  53. #ifndef AF_ISO
  54. #define AF_ISO          -1
  55. #endif
  56. #ifndef AF_ECMA
  57. #define AF_ECMA         -1
  58. #endif
  59. #ifndef AF_DATAKIT
  60. #define AF_DATAKIT      -1
  61. #endif
  62. #ifndef AF_CCITT
  63. #define AF_CCITT        -1
  64. #endif
  65. #ifndef AF_SNA
  66. #define AF_SNA          -1
  67. #endif
  68. #ifndef AF_DECnet
  69. #define AF_DECnet       -1
  70. #endif
  71. #ifndef AF_DLI
  72. #define AF_DLI          -1
  73. #endif
  74. #ifndef AF_LAT
  75. #define AF_LAT          -1
  76. #endif
  77. #ifndef AF_HYLINK
  78. #define AF_HYLINK       -1
  79. #endif
  80. #ifndef AF_APPLETALK
  81. #define AF_APPLETALK    -1
  82. #endif
  83. #ifndef AF_NETBIOS
  84. #define AF_NETBIOS    -1
  85. #endif
  86.  
  87. #define    rangeof(x)    (sizeof(x) / sizeof(x[0]))
  88.  
  89. static int HostSocketFamily[] =
  90. {
  91.     AF_UNSPEC,                    /* unspecified */
  92.     AF_UNIX,                    /* local to host (pipes, portals) */
  93.     AF_INET,                    /* internetwork: UDP, TCP, etc. */
  94.     AF_IMPLINK,                    /* arpanet imp addresses */
  95.     AF_PUP,                         /* pup protocols: e.g. BSP */
  96.     AF_CHAOS,                    /* mit CHAOS protocols */
  97.     AF_NS,                         /* NS, IPX and SPX */
  98.     AF_ISO,                         /* ISO protocols */
  99.     AF_ECMA,                    /* european computer manufacturers */
  100.     AF_DATAKIT,                    /* datakit protocols */
  101.     AF_CCITT,                    /* CCITT protocols, X.25 etc */
  102.     AF_SNA,                            /* IBM SNA */
  103.     AF_DECnet,                    /* DECnet */
  104.     AF_DLI,                            /* Direct data link interface */
  105.     AF_LAT,                            /* LAT */
  106.     AF_HYLINK,                    /* NSC Hyperchannel */
  107.     AF_APPLETALK,                    /* AppleTalk */
  108.     AF_NETBIOS                    /* NetBios-style addresses */
  109. };
  110.  
  111. static int HostSocketType[] =
  112. {
  113.     0,
  114.     SOCK_STREAM,
  115.     SOCK_DGRAM,
  116.     SOCK_RAW,
  117.         SOCK_RDM,
  118.     SOCK_SEQPACKET
  119. };
  120.  
  121. #ifndef IPPROTO_IP
  122. #define IPPROTO_IP 0
  123. #endif
  124. #ifndef IPPROTO_ICMP
  125. #define IPPROTO_ICMP 1
  126. #endif
  127. #ifndef IPPROTO_GGP
  128. #define IPPROTO_GGP 2
  129. #endif
  130. #ifndef IPPROTO_TCP
  131. #define IPPROTO_TCP 6
  132. #endif
  133. #ifndef IPPROTO_PUP
  134. #define IPPROTO_PUP 12
  135. #endif
  136. #ifndef IPPROTO_UDP
  137. #define IPPROTO_UDP 18
  138. #endif
  139. #ifndef IPPROTO_ND
  140. #define IPPROTO_ND 77
  141. #endif
  142.  
  143. static int HostSocketProtocol[] =
  144. {
  145.     IPPROTO_IP, IPPROTO_ICMP, IPPROTO_GGP, 3, 4,
  146.     5, IPPROTO_TCP, 7, 8, 9,
  147.     10, 11, IPPROTO_PUP, 13, 14, 15, 16, IPPROTO_UDP, 18, 19,
  148.     20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
  149.     30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
  150.     40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
  151.     50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
  152.     60, 61, 62, 63, 64, 65, 66, 67, 68, 69,
  153.     70, 71, 72, 73, 74, 75, 76, IPPROTO_ND, 78, 79
  154. };
  155.  
  156.  
  157. #ifndef SO_ACCEPTCONN
  158. #define    SO_ACCEPTCONN 0
  159. #endif
  160. #ifndef SO_USELOOPBACK
  161. #define    SO_USELOOPBACK 0
  162. #endif
  163.  
  164. static struct
  165. {
  166.  int iWindows;
  167.  int iHost;
  168. } HostSocketOption[] =
  169. {
  170.     { 0x0001,    SO_DEBUG    },
  171.     { 0x0002,    SO_ACCEPTCONN    },
  172.     { 0x0004,    SO_REUSEADDR    },
  173.     { 0x0008,    SO_KEEPALIVE    },
  174.     { 0x0010,    SO_DONTROUTE    },
  175.     { 0x0020,    SO_BROADCAST    },
  176.     { 0x0040,    SO_USELOOPBACK    },
  177.     { 0x0080,    SO_LINGER    },
  178.     { 0x0100,    SO_OOBINLINE    }
  179. };
  180.  
  181. static int
  182. GetFamily(int x)
  183. {
  184.     return (x < rangeof(HostSocketFamily)) ? HostSocketFamily[x] : x;
  185. }
  186.  
  187. static int
  188. RevFamily(int x)
  189. {
  190.     int i;
  191.  
  192.     for (i = 0; i < rangeof(HostSocketFamily); i++)
  193.     {
  194.         if (HostSocketFamily[i] == x)
  195.             return i;
  196.     }
  197.     return x;
  198. }
  199.  
  200. static int
  201. GetType(int x)
  202. {
  203.     return (x < rangeof(HostSocketType)) ? HostSocketType[x] : x;
  204. }
  205.  
  206. static int
  207. GetProtocol(int x)
  208. {
  209.     return (x < rangeof(HostSocketProtocol)) ? HostSocketProtocol[x] : x;
  210. }
  211.  
  212. static    int
  213. GetOption(int x)
  214. {
  215.     int    iOption = 0;
  216.     int    i;
  217.  
  218.     for (i = 0; i < rangeof(HostSocketOption); i++)
  219.     {
  220.         if (x & HostSocketOption[i].iWindows)
  221.             iOption |= HostSocketOption[i].iHost;
  222.     }
  223.     return iOption;
  224. }
  225.  
  226. extern void PacketTransmitData (void *pvData, int iDataLen, int iStream);
  227.  
  228. struct
  229. {
  230.     int    iErrnoHost;
  231.     int    iErrnoDos;
  232. } error_mappings[] =
  233. {
  234.     { 0,        0        },
  235.     { EINTR,    WSAEINTR    },
  236.     { EBADF,    WSAEBADF    },
  237.     { EINVAL,    WSAEINVAL    },
  238.     { EMFILE,    WSAEMFILE    },
  239.     { EWOULDBLOCK,    WSAEWOULDBLOCK    },
  240.     { EINPROGRESS,    WSAEINPROGRESS    },
  241.     { EALREADY,    WSAEALREADY    },
  242.     { ENOTSOCK,    WSAENOTSOCK    },
  243.     { EDESTADDRREQ,    WSAEDESTADDRREQ },
  244.     { EMSGSIZE,    WSAEMSGSIZE    },
  245.     { EPROTOTYPE,    WSAEPROTOTYPE    },
  246.     { ENOPROTOOPT,    WSAENOPROTOOPT    },
  247.     { EPROTONOSUPPORT, WSAEPROTONOSUPPORT },
  248.     { ESOCKTNOSUPPORT, WSAESOCKTNOSUPPORT },
  249.     { EOPNOTSUPP,    WSAEOPNOTSUPP    },
  250.     { EPFNOSUPPORT,    WSAEPFNOSUPPORT },
  251.     { EAFNOSUPPORT, WSAEAFNOSUPPORT },
  252.     { EADDRINUSE,    WSAEADDRINUSE    },
  253.     { EADDRNOTAVAIL,WSAEADDRNOTAVAIL },
  254.     { ENETDOWN,    WSAENETDOWN    },
  255.     { ENETUNREACH,    WSAENETUNREACH    },
  256.     { ENETRESET,    WSAENETRESET    },
  257.     { ECONNABORTED,    WSAECONNABORTED    },
  258.     { ECONNRESET,    WSAECONNRESET    },
  259.     { ENOBUFS,    WSAENOBUFS    },
  260.     { EISCONN,    WSAEISCONN    },
  261.     { ENOTCONN,    WSAENOTCONN    },
  262.     { ESHUTDOWN,    WSAESHUTDOWN    },
  263.     { ETOOMANYREFS,    WSAETOOMANYREFS    },
  264.     { ETIMEDOUT,    WSAETIMEDOUT    },
  265.     { ECONNREFUSED,    WSAECONNREFUSED    },
  266.     { ELOOP,    WSAELOOP,    },
  267.     { ENAMETOOLONG,    WSAENAMETOOLONG    },
  268.     { EHOSTDOWN,    WSAEHOSTDOWN    },
  269.     { EHOSTUNREACH,    WSAEHOSTUNREACH    },
  270.     { -1,        -1        }
  271. }, h_error_mappings[] =
  272.     { 0,        0        },
  273.     { HOST_NOT_FOUND, WSAHOST_NOT_FOUND },
  274.     { TRY_AGAIN,    WSATRY_AGAIN    },
  275.     { NO_RECOVERY,    WSANO_RECOVERY    },
  276.     { NO_DATA,    WSANO_DATA    },
  277.     { -1,        -1        }
  278. };
  279.  
  280. /* some functions to allow us to copy integer data
  281.  * to and from unaligned addresses
  282.  */
  283.  
  284. static unsigned short
  285. ToShort(char *pchData)
  286. {
  287.     short    n;
  288.  
  289.     memcpy(&n, pchData, sizeof(short));
  290.     return n;
  291. }
  292.  
  293. static long
  294. ToLong(char *pchData)
  295. {
  296.     long n;
  297.  
  298.     memcpy(&n, pchData, sizeof(long));
  299.     return n;
  300. }
  301.  
  302. static void
  303. FromShort(char *pchData, unsigned short n)
  304. {
  305.     memcpy(pchData, &n, sizeof(short));
  306. }
  307.  
  308. static void
  309. FromLong(char *pchData, long n)
  310. {
  311.     memcpy(pchData, &n, sizeof(long));
  312. }
  313.  
  314. static long
  315. GetIntVal(struct func_arg *pfa)
  316. {
  317.     switch(pfa->at)
  318.     {
  319.     case AT_Int16:
  320.     case AT_Int16Ptr:
  321.         return ntohs(ToShort(pfa->pvData));
  322.  
  323.     case AT_Int32:
  324.     case AT_Int32Ptr:
  325.         return ntohl(ToLong(pfa->pvData));
  326.     }
  327. }
  328.  
  329. void
  330. SetIntVal(struct func_arg *pfa, long iVal)
  331. {
  332.     switch(pfa->at)
  333.     {
  334.     case AT_Int16:
  335.     case AT_Int16Ptr:
  336.         FromShort(pfa->pvData,htons((short) iVal));
  337.         return;
  338.  
  339.     case AT_Int32:
  340.     case AT_Int32Ptr:
  341.         FromLong(pfa->pvData, htonl((short) iVal));
  342.         return;
  343.     }
  344. };
  345.  
  346. struct sockaddr *
  347. ConvertSA(struct func_arg *pfa, struct sockaddr_in *sin)
  348. {
  349.     u_short tmp;
  350.  
  351.     memcpy(sin, pfa->pvData, sizeof(*sin));
  352.     tmp = *(u_short *) sin;
  353.     *(u_short *) sin = 0;
  354.     sin->sin_family = GetFamily(ntohs(tmp));
  355.     return (struct sockaddr *) sin;
  356. }
  357.  
  358. int
  359. MapError(int iError)
  360. {
  361.     int    i;
  362.  
  363.     for (i = 0; error_mappings[i].iErrnoHost != -1; i++)
  364.     {
  365.         if (error_mappings[i].iErrnoHost == iError)
  366.             return error_mappings[i].iErrnoDos;
  367.     }
  368.     return WSAEFAULT;
  369. }
  370.  
  371. int
  372. MapHError(int iError)
  373. {
  374.     int    i;
  375.  
  376.     for (i = 0; h_error_mappings[i].iErrnoHost != -1; i++)
  377.     {
  378.         if (h_error_mappings[i].iErrnoHost == iError)
  379.             return h_error_mappings[i].iErrnoDos;
  380.     }
  381.     return WSAEFAULT;
  382. }
  383.  
  384. int
  385. CopyString(void *pvData, char *pchString, int iMax)
  386. {
  387.     char    *pchData;
  388.     int    iLen;
  389.  
  390.     pchData = (char *) pvData;
  391.     iLen = strlen(pchString);
  392.     if (iLen + 1 > iMax - 1)
  393.         return 0;
  394.     strcpy(pchData,    pchString);
  395.     return iLen + 1;
  396. }
  397.  
  398. void
  399. CopyHostEnt(void *pvData, struct hostent *phe)
  400. {
  401.     int    iLocation;
  402.     char    *pchData;
  403.     int    i;
  404.  
  405.     pchData = (char *) pvData;
  406.     FromShort(pchData, htons(phe->h_addrtype));
  407.     FromShort(pchData + sizeof(short), htons(phe->h_length));
  408.     for (i = 0; phe->h_addr_list[i]; i++);
  409.     FromShort(pchData + sizeof(short) * 2, htons(i));
  410.     iLocation = sizeof(short) * 3;
  411.     for (i = 0; phe->h_addr_list[i]; i++)
  412.     {
  413.         memcpy(pchData + iLocation, phe->h_addr_list[i], 4);
  414.         iLocation += 4;
  415.     }
  416.     iLocation += CopyString(pchData + iLocation,
  417.                 phe->h_name,
  418.                 MAX_HOST_ENT - iLocation);
  419.     for (i = 0; phe->h_aliases[i]; i++)
  420.     {
  421.         iLocation += CopyString(pchData + iLocation,
  422.                     phe->h_aliases[i],
  423.                     MAX_HOST_ENT - iLocation);
  424.     }
  425.     pchData[iLocation] = 0;
  426. }
  427.  
  428. void
  429. CopyNetEnt(void *pvData, struct netent *pne)
  430. {
  431.     int    iLocation;
  432.     char    *pchData;
  433.     int    i;
  434.  
  435.     pchData = (char *) pvData;
  436.     FromShort(pchData, htons(pne->n_addrtype));
  437.     FromLong(pchData + sizeof(short), pne->n_net);
  438.     iLocation = sizeof(short) + sizeof(long);
  439.     iLocation += CopyString(pchData + iLocation,
  440.                 pne->n_name,
  441.                 MAX_HOST_ENT - iLocation);
  442.     for (i = 0; pne->n_aliases[i]; i++)
  443.     {
  444.         iLocation += CopyString(pchData + iLocation,
  445.                     pne->n_aliases[i],
  446.                     MAX_HOST_ENT - iLocation);
  447.     }
  448.     pchData[iLocation] = 0;
  449. }
  450.  
  451. void
  452. CopyServEnt(void *pvData, struct servent *pse)
  453. {
  454.     int    iLocation;
  455.     char    *pchData;
  456.     int    i;
  457.  
  458.     pchData = (char *) pvData;
  459.     FromShort(pchData, pse->s_port); /* No htons - already in network order */
  460.     iLocation = sizeof(short);
  461.     iLocation += CopyString(pchData + iLocation,
  462.                 pse->s_proto,
  463.                 MAX_HOST_ENT - iLocation);
  464.     iLocation += CopyString(pchData + iLocation,
  465.                 pse->s_name,
  466.                 MAX_HOST_ENT - iLocation);
  467.     for (i = 0; pse->s_aliases[i]; i++)
  468.     {
  469.         iLocation += CopyString(pchData + iLocation,
  470.                     pse->s_aliases[i],
  471.                     MAX_HOST_ENT - iLocation);
  472.     }
  473.     pchData[iLocation] = 0;
  474. }
  475.  
  476. void
  477. CopyProtoEnt(void *pvData, struct protoent *ppe)
  478. {
  479.     int    iLocation;
  480.     char    *pchData;
  481.     int    i;
  482.  
  483.     pchData = (char *) pvData;
  484.     FromShort(pchData, htons(ppe->p_proto));
  485.     iLocation = sizeof(short);
  486.     iLocation += CopyString(pchData + iLocation,
  487.                 ppe->p_name,
  488.                 MAX_HOST_ENT - iLocation);
  489.     for (i = 0; ppe->p_aliases[i]; i++)
  490.     {
  491.         iLocation += CopyString(pchData + iLocation,
  492.                     ppe->p_aliases[i],
  493.                     MAX_HOST_ENT - iLocation);
  494.     }
  495.     pchData[iLocation] = 0;
  496. }
  497.  
  498. void
  499. SwapSockOptIn(    struct func_arg *pfa,
  500.         int    iOpt)
  501. {
  502.     int    iValue;
  503.     char    *pchData;
  504.  
  505.     pchData = (char *) pfa->pvData;
  506.     if (iOpt == SO_LINGER)
  507.     {
  508.         FromShort(pchData, ntohs(ToShort(pchData)));
  509.         FromShort(pchData + sizeof(short),
  510.                 ntohs(ToShort(pchData + sizeof(short))));
  511.     }
  512.     else
  513.     {
  514.         FromLong(pchData, ntohl(ToLong(pchData)));
  515.     }
  516. }
  517.  
  518. void
  519. SwapSockOptOut(    struct func_arg *pfa,
  520.         int    iOpt)
  521. {
  522.     int    iValue;
  523.     char    *pchData;
  524.  
  525.     pchData = (char *) pfa->pvData;
  526.     if (iOpt == SO_LINGER)
  527.     {
  528.         FromShort(pchData, htons(ToShort(pchData)));
  529.         FromShort(pchData + sizeof(short),
  530.                 htons(ToShort(pchData + sizeof(short))));
  531.     }
  532.     else
  533.     {
  534.         FromLong(pchData, htonl(ToLong(pchData)));
  535.     }
  536. }
  537.  
  538.  
  539. int
  540. CompressArg(    struct    tx_request *ptxr,
  541.         struct    func_arg *pfaArgs,
  542.         int    nArgs,
  543.         struct    func_arg *pfaResult,
  544.         int    iArg)
  545. {
  546.     struct    func_arg *pfaNow;
  547.     char    *pchNewData, *pchData;
  548.     int    i, j;
  549.     int    nLen;
  550.  
  551.     pchData = pchNewData = ptxr->pchData;
  552.     for (i = 0; i <= nArgs; i++)
  553.     {
  554.         if (i < nArgs)
  555.             pfaNow = pfaArgs + i;
  556.         else
  557.             pfaNow = pfaResult;
  558.         for (j = 0; j < pfaNow->iLen + 4; j++)
  559.             pchNewData[j] = pchData[j];
  560.         pchData += pfaNow->iLen + 4;
  561.         if (i == iArg)
  562.         {
  563.             pfaNow->iLen = 0;
  564.             *(short *) (pchNewData + 2) = 0;
  565.         }
  566.         pchNewData += pfaNow->iLen + 4;
  567.     }
  568.     nLen = pchNewData - ptxr->pchData + 10;
  569.     ptxr->nLen = htons((short) nLen);
  570.     return nLen;
  571. }
  572.  
  573.  
  574. void
  575. GetPortRange(    short    iInPort,
  576.         short    *piStartPort,
  577.         short    *piEndPort)
  578. {
  579.     char    achBuffer[1024];
  580.     char    achPort[20];
  581.     char    *pchComma;
  582.  
  583.     sprintf(achPort, "%d", (int) iInPort);
  584.     GetTwinSockSetting("Mappings",
  585.             achPort,
  586.             "",
  587.             achBuffer,
  588.             sizeof(achBuffer));
  589.     if (!*achBuffer || !(pchComma = (char *) strchr(achBuffer, ',')))
  590.     {
  591.         *piStartPort = *piEndPort = iInPort;
  592.         return;
  593.     }
  594.     *pchComma++ = 0;
  595.     *piStartPort = atoi(achBuffer);
  596.     *piEndPort = atoi(pchComma);
  597. }
  598.  
  599. void
  600. SendRemapMessage(    short    iFrom,
  601.             short    iTo)
  602. {
  603.     char    achBuffer[1024];
  604.     char    achPortDesc[50];
  605.     char    achPort[20];
  606.     struct    tx_request *ptxr;
  607.  
  608.     sprintf(achPortDesc, "Port %d", (int) iFrom);
  609.     sprintf(achPort, "%d", (int) iFrom);
  610.     GetTwinSockSetting("PortNames",
  611.             achPort,
  612.             achPortDesc,
  613.             achBuffer,
  614.             sizeof(achBuffer));
  615.     strcat(achBuffer, " remapped to ");
  616.     sprintf(achPortDesc, "Port %d", (int) iTo);
  617.     sprintf(achPort, "%d", (int) iTo);
  618.     GetTwinSockSetting("PortNames",
  619.             achPort,
  620.             achPortDesc,
  621.             achBuffer + strlen(achBuffer),
  622.             sizeof(achBuffer) - strlen(achBuffer));
  623.     ptxr = (struct tx_request *) malloc(11 + strlen(achBuffer));
  624.         ptxr->iType = htons(FN_Message);
  625.         ptxr->nArgs = 0;
  626.         ptxr->nLen = htons(11 + strlen(achBuffer));
  627.         ptxr->id = -1;
  628.         ptxr->nError = 0;
  629.     strcpy(ptxr->pchData, achBuffer);
  630.         PacketTransmitData(ptxr, 10 + strlen(achBuffer) + 1, -2);
  631.     free(ptxr);
  632. }
  633.  
  634. void
  635. ResponseReceived(struct tx_request *ptxr_)
  636. {
  637.     enum Functions ft;
  638.     short    nArgs;
  639.     short    nLen;
  640.     short    id;
  641.     short    iInPort;
  642.     short    iStartPort;
  643.     short    iEndPort;
  644.     short    iPort;
  645.     int    iLen;
  646.     int    iValue;
  647.     int    iSocket;
  648.     int    nOptName;
  649.     int    nOptVal;
  650.     short    nError;
  651.     struct    tx_request *ptxr;
  652.     struct    func_arg *pfaArgs;
  653.     struct    func_arg faResult;
  654.     struct    sockaddr_in sin;
  655.     char    *pchData;
  656.     int    i;
  657.     int    iErrorSent;
  658.     int    iOffset;
  659.     struct    hostent *phe;
  660.     struct    netent *pne;
  661.     struct    servent *pse;
  662.     struct    protoent *ppe;
  663.  
  664.     nLen = ntohs(ptxr_->nLen);
  665.     ptxr = (struct tx_request *) malloc(nLen);
  666.     memcpy(ptxr, ptxr_, nLen);
  667.     ft = (enum Functions) ntohs(ptxr->iType);
  668.     nArgs = ntohs(ptxr->nArgs);
  669.  
  670.     pfaArgs = (struct func_arg *) malloc(sizeof(struct func_arg) * nArgs);
  671.     pchData = ptxr->pchData;
  672.     for (i = 0; i < nArgs; i++)
  673.     {
  674.         pfaArgs[i].at = (enum arg_type) ntohs(ToShort(pchData));
  675.         pchData += sizeof(short);
  676.         pfaArgs[i].iLen = ntohs(ToShort(pchData));
  677.         pchData += sizeof(short);
  678.         pfaArgs[i].pvData = pchData;
  679.         pchData += pfaArgs[i].iLen;
  680.     }
  681.     faResult.at = (enum arg_type) ntohs(ToShort(pchData));
  682.     pchData += sizeof(short);
  683.     faResult.iLen = ntohs(ToShort(pchData));
  684.     pchData += sizeof(short);
  685.     faResult.pvData = pchData;
  686.  
  687.     iErrorSent = 0;
  688.     errno = 0;
  689.     h_errno = 0;
  690.  
  691.     switch(ft)
  692.     {
  693.     case FN_IOCtl:
  694.     case FN_Accept:
  695.     case FN_Select:
  696.     case FN_Data:
  697.         ptxr->nError = htons(WSAEOPNOTSUPP);
  698.         ptxr->nLen = htons(sizeof(short) * 5);
  699.         PacketTransmitData(ptxr, sizeof(short) * 5, -2);
  700.         iErrorSent = 1;
  701.         break;
  702.  
  703.     case FN_Send:
  704.         SetIntVal(&faResult,
  705.             send(GetIntVal(&pfaArgs[0]),
  706.                  pfaArgs[1].pvData,
  707.                  GetIntVal(&pfaArgs[2]),
  708.                  GetIntVal(&pfaArgs[3])));
  709.         nLen = CompressArg(ptxr, pfaArgs, nArgs, &faResult, 1);
  710.         break;
  711.  
  712.     case FN_SendTo:
  713.         SetIntVal(&faResult,
  714.             sendto(GetIntVal(&pfaArgs[0]),
  715.                    pfaArgs[1].pvData,
  716.                    GetIntVal(&pfaArgs[2]),
  717.                    GetIntVal(&pfaArgs[3]),
  718.                    ConvertSA(&pfaArgs[4], &sin),
  719.                    GetIntVal(&pfaArgs[5])));
  720.         nLen = CompressArg(ptxr, pfaArgs, nArgs, &faResult, 1);
  721.         break;
  722.  
  723.     case FN_Bind:
  724.         ConvertSA(&pfaArgs[1], &sin);
  725.         iInPort = ntohs(sin.sin_port);
  726.         GetPortRange(iInPort, &iStartPort, &iEndPort);
  727.         for (iPort = iStartPort; iPort <= iEndPort; iPort++)
  728.         {
  729.             errno = 0;
  730.             sin.sin_port = htons(iPort);
  731.             iValue = bind(GetIntVal(&pfaArgs[0]),
  732.                     (struct sockaddr *) &sin,
  733.                          GetIntVal(&pfaArgs[2]));
  734.             if (!iValue)
  735.             {
  736.                 if (iPort != iInPort)
  737.                     SendRemapMessage(iInPort, iPort);
  738.                 break;
  739.             }
  740.         }
  741.         SetIntVal(&faResult, iValue);
  742.         break;
  743.  
  744.     case FN_Connect:
  745.         iSocket = GetIntVal(&pfaArgs[0]);
  746.         iValue = connect(iSocket,
  747.                 ConvertSA(&pfaArgs[1], &sin),
  748.                 GetIntVal(&pfaArgs[2]));
  749.         SetIntVal(&faResult, iValue);
  750.         if (iValue != -1)
  751.             BumpLargestFD(iSocket);
  752.         break;
  753.  
  754.     case FN_Close:
  755.         SetIntVal(&faResult,
  756.             close(GetIntVal(&pfaArgs[0])));
  757.         FlushStream(GetIntVal(&pfaArgs[0]));
  758.         SetClosed(GetIntVal(&pfaArgs[0]));
  759.         break;
  760.  
  761.     case FN_Shutdown:
  762.         SetIntVal(&faResult,
  763.             shutdown(GetIntVal(&pfaArgs[0]),
  764.                  GetIntVal(&pfaArgs[1])));
  765.         if (GetIntVal(&pfaArgs[1]) != 1)
  766.             SetClosed(GetIntVal(&pfaArgs[0]));
  767.         break;
  768.  
  769.     case FN_Listen:
  770.         iSocket = GetIntVal(&pfaArgs[0]);
  771.         iValue = listen(iSocket,
  772.                 GetIntVal(&pfaArgs[1]));
  773.         SetIntVal(&faResult, iValue);
  774.         if (iValue != -1)
  775.         {
  776.             BumpLargestFD(iSocket);
  777.             SetListener(iSocket);
  778.         }
  779.         break;
  780.  
  781.     case FN_Socket:
  782.         iSocket = socket(GetFamily(GetIntVal(&pfaArgs[0])),
  783.                 GetType(GetIntVal(&pfaArgs[1])),
  784.                 GetProtocol(GetIntVal(&pfaArgs[2])));
  785.         SetIntVal(&faResult,iSocket);
  786.         if (iSocket != -1)
  787.         {
  788.             BumpLargestFD(iSocket);
  789.             nOptVal = 1;
  790.             iLen = sizeof(nOptVal);
  791.             setsockopt(iSocket,
  792.                     SOL_SOCKET,
  793.                     SO_OOBINLINE,
  794.                     (char *) &nOptVal,
  795.                     iLen);
  796.             errno = 0;
  797.         }
  798.         break;
  799.  
  800.     case FN_GetPeerName:
  801.         iLen = GetIntVal(&pfaArgs[2]);
  802.         iValue = getpeername(GetIntVal(&pfaArgs[0]),
  803.                      (struct sockaddr *) pfaArgs[1].pvData,
  804.                      &iLen);
  805.         if (iValue != -1)
  806.         {
  807.             SetIntVal(&faResult, iValue);
  808.             SetIntVal(&pfaArgs[2], iValue);
  809.             iValue = ((struct sockaddr *) pfaArgs[1].pvData)->
  810.                         sa_family;
  811.             iValue = RevFamily(iValue);
  812.             iValue = htons((short) iValue);
  813.             ((struct sockaddr *) pfaArgs[1].pvData)->sa_family =
  814.                         (short) iValue;
  815.         }
  816.         break;
  817.  
  818.     case FN_GetSockName:
  819.         iLen = GetIntVal(&pfaArgs[2]);
  820.         iValue = getsockname(GetIntVal(&pfaArgs[0]),
  821.                      (struct sockaddr *) pfaArgs[1].pvData,
  822.                      &iLen);
  823.         if (iValue != -1)
  824.         {
  825.             SetIntVal(&faResult, iValue);
  826.             SetIntVal(&pfaArgs[2], iValue);
  827.             iValue = ((struct sockaddr *) pfaArgs[1].pvData)->
  828.                         sa_family;
  829.             iValue = RevFamily(iValue);
  830.             iValue = htons((short) iValue);
  831.             ((struct sockaddr *) pfaArgs[1].pvData)->sa_family =
  832.                         (short) iValue;
  833.         }
  834.         break;
  835.  
  836.     case FN_GetSockOpt:
  837.         iLen = GetIntVal(&pfaArgs[4]);
  838.         nOptName = GetOption(GetIntVal(&pfaArgs[2]));
  839.         iValue = getsockopt(    GetIntVal(&pfaArgs[0]),
  840.                     GetIntVal(&pfaArgs[1]),
  841.                     nOptName,
  842.                     (char *) pfaArgs[3].pvData,
  843.                     &iLen);
  844.         if (iValue != -1)
  845.         {
  846.             SwapSockOptOut(&pfaArgs[3],
  847.                     nOptName);
  848.             SetIntVal(&pfaArgs[4], iLen);
  849.         }
  850.         SetIntVal(&faResult, iValue);
  851.         break;
  852.  
  853.     case FN_SetSockOpt:
  854.         iLen = GetIntVal(&pfaArgs[4]);
  855.         nOptName = GetOption(GetIntVal(&pfaArgs[2]));
  856.         SwapSockOptIn(&pfaArgs[3],
  857.                 nOptName);
  858.         iValue = setsockopt(    GetIntVal(&pfaArgs[0]),
  859.                     SOL_SOCKET,
  860.                     nOptName,
  861.                     (char *) pfaArgs[3].pvData,
  862.                     iLen);
  863.         SwapSockOptOut(&pfaArgs[3],
  864.                 nOptName);
  865.         SetIntVal(&faResult, iValue);
  866.         break;
  867.  
  868.     case FN_GetHostName:
  869.         SetIntVal(&faResult,
  870.             gethostname((char *) pfaArgs[0].pvData,
  871.                     GetIntVal(&pfaArgs[1])));
  872.         break;
  873.  
  874.     case FN_HostByAddr:
  875.         phe = gethostbyaddr((char *) pfaArgs[0].pvData,
  876.                     GetIntVal(&pfaArgs[1]),
  877.                     GetIntVal(&pfaArgs[2]));
  878.         if (phe)
  879.         {
  880.             h_errno = 0;
  881.             CopyHostEnt(faResult.pvData, phe);
  882.         }
  883.         break;
  884.  
  885.     case FN_HostByName:
  886.         phe = gethostbyname((char *) pfaArgs[0].pvData);
  887.         if (phe)
  888.         {
  889.             h_errno = 0;
  890.             CopyHostEnt(faResult.pvData, phe);
  891.         }
  892.         else if (!h_errno)
  893.         {
  894.             h_errno = TRY_AGAIN;
  895.         }
  896.         break;
  897.  
  898.     case FN_ServByPort:
  899.         if (pfaArgs[0].at == AT_Int16)
  900.             iValue = *(short *) pfaArgs[0].pvData;
  901.         else
  902.             iValue = *(long *) pfaArgs[0].pvData;
  903.         pse = getservbyport(iValue,
  904.                     (char *) pfaArgs[1].pvData);
  905.         if (pse)
  906.         {
  907.             h_errno = 0;
  908.             CopyServEnt(faResult.pvData, pse);
  909.         }
  910.         else
  911.         {
  912.             h_errno = NO_DATA;
  913.         }
  914.         break;
  915.  
  916.     case FN_ServByName:
  917.         pse = getservbyname((char *) pfaArgs[0].pvData,
  918.                     (char *) pfaArgs[1].pvData);
  919.         if (pse)
  920.         {
  921.             h_errno = 0;
  922.             CopyServEnt(faResult.pvData, pse);
  923.         }
  924.         else
  925.         {
  926.             h_errno = NO_DATA;
  927.         }
  928.         break;
  929.  
  930.     case FN_ProtoByNumber:
  931.         ppe = getprotobynumber(GetIntVal(&pfaArgs[0]));
  932.         if (ppe)
  933.         {
  934.             h_errno = 0;
  935.             CopyProtoEnt(faResult.pvData, ppe);
  936.         }
  937.         else
  938.         {
  939.             h_errno = NO_DATA;
  940.         }
  941.         break;
  942.  
  943.     case FN_ProtoByName:
  944.         ppe = getprotobyname((char *) pfaArgs[0].pvData);
  945.         if (ppe)
  946.         {
  947.             h_errno = 0;
  948.             CopyProtoEnt(faResult.pvData, ppe);
  949.         }
  950.         else
  951.         {
  952.             h_errno = NO_DATA;
  953.         }
  954.         break;
  955.     }
  956.     if (!iErrorSent)
  957.     {
  958.         if (ft >= FN_HostByAddr && ft <= FN_ProtoByName)
  959.             ptxr->nError = htons(MapHError(h_errno));
  960.         else
  961.             ptxr->nError = htons(MapError(errno));
  962.         PacketTransmitData(ptxr, nLen, -2);
  963.     }
  964.     free(ptxr);
  965.     free(pfaArgs);
  966. }
  967.  
  968. void
  969. SendSocketData(int iSocket,
  970.         void    *pvData,
  971.         int    iLen,
  972.         struct sockaddr_in *psa,
  973.         int    iAddrLen,
  974.         enum Functions ft)
  975. {
  976.     struct    tx_request *ptxr;
  977.     int    iDataLen;
  978.     struct    sockaddr_in sa;
  979.  
  980.     iDataLen = sizeof(struct sockaddr_in) + iLen;
  981.     sa = *psa;
  982.     sa.sin_family = htons(RevFamily(sa.sin_family));
  983.     ptxr = (struct tx_request *) malloc(sizeof(short) * 5 + iDataLen);
  984.     ptxr->nLen = htons(iDataLen + sizeof(short) * 5);
  985.     ptxr->id = htons(iSocket);
  986.     ptxr->nArgs = 0;
  987.     ptxr->nError = 0;
  988.     ptxr->iType = htons(ft);
  989.     memcpy(ptxr->pchData, &sa, sizeof(sa));
  990.     memcpy(ptxr->pchData + sizeof(sa), pvData, iLen);
  991.     PacketTransmitData(ptxr, sizeof(short) * 5 + iDataLen,
  992.         (ft == FN_Data) ? iSocket : -2);
  993.     free(ptxr);
  994. }
  995.