home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 113 / EnigmaAmiga113CD.iso / software / sviluppo / glquake_src / net_bsdsocket.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-12-29  |  10.0 KB  |  412 lines

  1. /* 
  2. **  net_bsdsocket.c
  3. */
  4.  
  5. /* Quake includes */
  6. #include "quakedef.h"
  7.  
  8. /* Amiga includes */
  9. #include <exec/types.h>
  10. #include <exec/libraries.h>
  11. #include <amitcp/socketbasetags.h>
  12. #include <proto/exec.h>
  13. #include <proto/socket.h>
  14.  
  15. /* standard net includes */
  16. #include <sys/socket.h>
  17. #include <netinet/in.h>
  18. #include <netdb.h>
  19. #include <sys/param.h>
  20. #include <sys/ioctl.h>
  21. #include <errno.h>
  22.  
  23.  
  24. struct Library *SocketBase = NULL;  /* bsdsocket.library */
  25. #define SOCKETVERSION 4             /* required version */
  26.  
  27. extern cvar_t hostname;
  28.  
  29. static int net_acceptsocket = -1;        // socket for fielding new connections
  30. static int net_controlsocket;
  31. static int net_broadcastsocket = 0;
  32. static struct qsockaddr broadcastaddr;
  33.  
  34. static unsigned long myAddr;
  35.  
  36. #include "net_udp.h"
  37.  
  38.  
  39. //=============================================================================
  40.  
  41. char *inet_ntoa(struct in_addr addr)
  42. {
  43.   return Inet_NtoA(addr.s_addr);
  44. }
  45.  
  46. //=============================================================================
  47.  
  48. int UDP_Init (void)
  49. {
  50.     int        p;
  51.     struct hostent *local;
  52.     char    buff[MAXHOSTNAMELEN];
  53.     struct qsockaddr addr;
  54.     char *colon;
  55.     
  56.   if (COM_CheckParm ("-noudp"))
  57.     return (-1);
  58.  
  59.   /* Amiga socket initialization */
  60.   if (!(SocketBase = OpenLibrary("bsdsocket.library",SOCKETVERSION)))
  61.     return (-1);
  62.   if (SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))),&errno,
  63.                          SBTM_SETVAL(SBTC_LOGTAGPTR),"QuakeAmiga UDP",
  64.                          TAG_END)) {
  65.     CloseLibrary(SocketBase);
  66.     return (-1);
  67.   }
  68.  
  69.     p = COM_CheckParm ("-udpport");
  70.     if (p == 0)
  71.         net_hostport = DEFAULTnet_hostport;
  72.     else if (p < com_argc-1)
  73.         net_hostport = Q_atoi (com_argv[p+1]);
  74.     else
  75.         Sys_Error ("UDP_Init: you must specify a number after -udpport");
  76.  
  77.     // determine my name & address
  78.     gethostname(buff, MAXHOSTNAMELEN);
  79.     local = gethostbyname(buff);
  80.     myAddr = *(int *)local->h_addr_list[0];
  81.  
  82.     // if the quake hostname isn't set, set it to the machine name
  83.     if (Q_strcmp(hostname.string, "UNNAMED") == 0)
  84.     {
  85.         buff[15] = 0;
  86.         Cvar_Set ("hostname", buff);
  87.     }
  88.  
  89.     if ((net_controlsocket = UDP_OpenSocket (0)) == -1)
  90.         Sys_Error("UDP_Init: Unable to open control socket\n");
  91.  
  92.     ((struct sockaddr_in *)&broadcastaddr)->sin_family = AF_INET;
  93.     ((struct sockaddr_in *)&broadcastaddr)->sin_addr.s_addr = INADDR_BROADCAST;
  94.     ((struct sockaddr_in *)&broadcastaddr)->sin_port = htons(net_hostport);
  95.  
  96.     UDP_GetSocketAddr (net_controlsocket, &addr);
  97.     Q_strcpy(my_tcpip_address,  UDP_AddrToString (&addr));
  98.     colon = Q_strrchr (my_tcpip_address, ':');
  99.     if (colon)
  100.         *colon = 0;
  101.  
  102.   Con_Printf("bsdsocket.library V%d TCP/IP\n",SOCKETVERSION);
  103.   tcpipAvailable = true;
  104.  
  105.   return net_controlsocket;
  106. }
  107.  
  108. //=============================================================================
  109.  
  110. void UDP_Shutdown (void)
  111. {
  112.   if (SocketBase) {
  113.     UDP_Listen (false);
  114.     UDP_CloseSocket (net_controlsocket);
  115.     CloseLibrary(SocketBase);
  116.   }
  117. }
  118.  
  119. //=============================================================================
  120.  
  121. void UDP_Listen (qboolean state)
  122. {
  123.     // enable listening
  124.     if (state)
  125.     {
  126.         if (net_acceptsocket != -1)
  127.             return;
  128.         if ((net_acceptsocket = UDP_OpenSocket (net_hostport)) == -1)
  129.             Sys_Error ("UDP_Listen: Unable to open accept socket\n");
  130.         return;
  131.     }
  132.  
  133.     // disable listening
  134.     if (net_acceptsocket == -1)
  135.         return;
  136.     UDP_CloseSocket (net_acceptsocket);
  137.     net_acceptsocket = -1;
  138. }
  139.  
  140. //=============================================================================
  141.  
  142. int UDP_OpenSocket (int port)
  143. {
  144.     int newsocket;
  145.     struct sockaddr_in address;
  146.     qboolean _true = true;
  147.  
  148.     if ((newsocket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
  149.         return -1;
  150.  
  151.     if (IoctlSocket (newsocket, FIONBIO, (char *)&_true) == -1)
  152.         goto ErrorReturn;
  153.  
  154.     address.sin_family = AF_INET;
  155.     address.sin_addr.s_addr = INADDR_ANY;
  156.     address.sin_port = htons(port);
  157.     if( bind (newsocket, (void *)&address, sizeof(address)) == -1)
  158.         goto ErrorReturn;
  159.  
  160.     return newsocket;
  161.  
  162. ErrorReturn:
  163.   CloseSocket(newsocket);
  164.     return -1;
  165. }
  166.  
  167. //=============================================================================
  168.  
  169. int UDP_CloseSocket (int socket)
  170. {
  171.     if (socket == net_broadcastsocket)
  172.         net_broadcastsocket = 0;
  173.   return (CloseSocket(socket));
  174. }
  175.  
  176.  
  177. //=============================================================================
  178. /*
  179. ============
  180. PartialIPAddress
  181.  
  182. this lets you type only as much of the net address as required, using
  183. the local network components to fill in the rest
  184. ============
  185. */
  186. static int PartialIPAddress (char *in, struct qsockaddr *hostaddr)
  187. {
  188.     char buff[256];
  189.     char *b;
  190.     int addr;
  191.     int num;
  192.     int mask;
  193.     
  194.     buff[0] = '.';
  195.     b = buff;
  196.     strcpy(buff+1, in);
  197.     if (buff[1] == '.') b++;
  198.  
  199.     addr = 0;
  200.     mask=-1;
  201.     while (*b == '.')
  202.     {
  203.         num = 0;
  204.         if (*++b < '0' || *b > '9') return -1;
  205.         while (!( *b < '0' || *b > '9'))
  206.           num = num*10 + *(b++) - '0';
  207.         mask<<=8;
  208.         addr = (addr<<8) + num;
  209.     }
  210.     
  211.     hostaddr->sa_family = AF_INET;
  212.     ((struct sockaddr_in *)hostaddr)->sin_port = htons(net_hostport);    
  213.     ((struct sockaddr_in *)hostaddr)->sin_addr.s_addr = (myAddr & htonl(mask)) | htonl(addr);
  214.     
  215.     return 0;
  216. }
  217. //=============================================================================
  218.  
  219. int UDP_Connect (int socket, struct qsockaddr *addr)
  220. {
  221.     return 0;
  222. }
  223.  
  224. //=============================================================================
  225.  
  226. int UDP_CheckNewConnections (void)
  227. {
  228.     char buf[4];
  229.  
  230.     if (net_acceptsocket == -1)
  231.         return -1;
  232.  
  233.     if (recvfrom (net_acceptsocket, buf, 4, MSG_PEEK, NULL, NULL) > 0)
  234.         return net_acceptsocket;
  235.     return -1;
  236. }
  237.  
  238. //=============================================================================
  239.  
  240. int UDP_Read (int socket, byte *buf, int len, struct qsockaddr *addr)
  241. {
  242.     LONG addrlen = sizeof (struct qsockaddr);
  243.     int ret;
  244.  
  245.     ret = recvfrom (socket, buf, len, 0, (struct sockaddr *)addr, &addrlen);
  246.     if (ret == -1 && (errno == EWOULDBLOCK || errno == ECONNREFUSED))
  247.         return 0;
  248.     return ret;
  249. }
  250.  
  251. //=============================================================================
  252.  
  253. int UDP_MakeSocketBroadcastCapable (int socket)
  254. {
  255.     int                i = 1;
  256.  
  257.     // make this socket broadcast capable
  258.     if (setsockopt(socket, SOL_SOCKET, SO_BROADCAST, &i, sizeof(i)) < 0)
  259.         return -1;
  260.     net_broadcastsocket = socket;
  261.  
  262.     return 0;
  263. }
  264.  
  265. //=============================================================================
  266.  
  267. int UDP_Broadcast (int socket, byte *buf, int len)
  268. {
  269.     int ret;
  270.  
  271.     if (socket != net_broadcastsocket)
  272.     {
  273.         if (net_broadcastsocket != 0)
  274.             Sys_Error("Attempted to use multiple broadcasts sockets\n");
  275.         ret = UDP_MakeSocketBroadcastCapable (socket);
  276.         if (ret == -1)
  277.         {
  278.             Con_Printf("Unable to make socket broadcast capable\n");
  279.             return ret;
  280.         }
  281.     }
  282.  
  283.     return UDP_Write (socket, buf, len, &broadcastaddr);
  284. }
  285.  
  286. //=============================================================================
  287.  
  288. int UDP_Write (int socket, byte *buf, int len, struct qsockaddr *addr)
  289. {
  290.     int ret;
  291.  
  292.     ret = sendto (socket, buf, len, 0, (struct sockaddr *)addr, sizeof(struct qsockaddr));
  293.     if (ret == -1 && errno == EWOULDBLOCK)
  294.         return 0;
  295.     return ret;
  296. }
  297.  
  298. //=============================================================================
  299.  
  300. char *UDP_AddrToString (struct qsockaddr *addr)
  301. {
  302.     static char buffer[22];
  303.     int haddr;
  304.  
  305.   haddr = ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr);
  306.   sprintf(buffer, "%d.%d.%d.%d:%d", (haddr >> 24) & 0xff,
  307.           (haddr >> 16) & 0xff, (haddr >> 8) & 0xff, haddr & 0xff, 
  308.           (int)ntohs(((struct sockaddr_in *)addr)->sin_port));
  309.   return buffer;
  310. }
  311.  
  312. //=============================================================================
  313.  
  314. int UDP_StringToAddr (char *string, struct qsockaddr *addr)
  315. {
  316.     int ha1, ha2, ha3, ha4, hp;
  317.     int ipaddr;
  318.  
  319.     sscanf(string, "%d.%d.%d.%d:%d", &ha1, &ha2, &ha3, &ha4, &hp);
  320.     ipaddr = (ha1 << 24) | (ha2 << 16) | (ha3 << 8) | ha4;
  321.  
  322.     addr->sa_family = AF_INET;
  323.     ((struct sockaddr_in *)addr)->sin_addr.s_addr = htonl(ipaddr);
  324.     ((struct sockaddr_in *)addr)->sin_port = htons(hp);
  325.     return 0;
  326. }
  327.  
  328. //=============================================================================
  329.  
  330. int UDP_GetSocketAddr (int socket, struct qsockaddr *addr)
  331. {
  332.     LONG addrlen = sizeof(struct qsockaddr);
  333.     unsigned int a;
  334.  
  335.     Q_memset(addr, 0, sizeof(struct qsockaddr));
  336.     getsockname(socket, (struct sockaddr *)addr, &addrlen);
  337.     a = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
  338.     if (a == 0 || a == inet_addr("127.0.0.1"))
  339.         ((struct sockaddr_in *)addr)->sin_addr.s_addr = myAddr;
  340.  
  341.     return 0;
  342. }
  343.  
  344. //=============================================================================
  345.  
  346. int UDP_GetNameFromAddr (struct qsockaddr *addr, char *name)
  347. {
  348.     struct hostent *hostentry;
  349.  
  350.     hostentry = (struct hostent *)gethostbyaddr ((char *)&((struct sockaddr_in *)addr)->sin_addr, sizeof(struct in_addr), AF_INET);
  351.     if (hostentry)
  352.     {
  353.         Q_strncpy (name, (char *)hostentry->h_name, NET_NAMELEN - 1);
  354.         return 0;
  355.     }
  356.  
  357.     Q_strcpy (name, UDP_AddrToString (addr));
  358.     return 0;
  359. }
  360.  
  361. //=============================================================================
  362.  
  363. int UDP_GetAddrFromName(char *name, struct qsockaddr *addr)
  364. {
  365.     struct hostent *hostentry;
  366.  
  367.     if (name[0] >= '0' && name[0] <= '9')
  368.         return PartialIPAddress (name, addr);
  369.     
  370.     hostentry = gethostbyname (name);
  371.     if (!hostentry)
  372.         return -1;
  373.  
  374.     addr->sa_family = AF_INET;
  375.     ((struct sockaddr_in *)addr)->sin_port = htons(net_hostport);    
  376.     ((struct sockaddr_in *)addr)->sin_addr.s_addr = *(int *)hostentry->h_addr_list[0];
  377.  
  378.     return 0;
  379. }
  380.  
  381. //=============================================================================
  382.  
  383. int UDP_AddrCompare (struct qsockaddr *addr1, struct qsockaddr *addr2)
  384. {
  385.     if ((addr1->sa_family&0xff) != (addr2->sa_family&0xff))
  386.         return -1;
  387.  
  388.     if (((struct sockaddr_in *)addr1)->sin_addr.s_addr != ((struct sockaddr_in *)addr2)->sin_addr.s_addr)
  389.         return -1;
  390.  
  391.     if (((struct sockaddr_in *)addr1)->sin_port != ((struct sockaddr_in *)addr2)->sin_port)
  392.         return 1;
  393.  
  394.     return 0;
  395. }
  396.  
  397. //=============================================================================
  398.  
  399. int UDP_GetSocketPort (struct qsockaddr *addr)
  400. {
  401.     return ntohs(((struct sockaddr_in *)addr)->sin_port);
  402. }
  403.  
  404.  
  405. int UDP_SetSocketPort (struct qsockaddr *addr, int port)
  406. {
  407.     ((struct sockaddr_in *)addr)->sin_port = htons(port);
  408.     return 0;
  409. }
  410.  
  411. //=============================================================================
  412.