/*
 * WSOCK32 specific functions
 *
 * Copyright (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka.
 */


/* FIXME: This hack is fixing a problem in WsControl.  When we call socket(),
 * it will call into ws2_32's WSOCK32_socket (because of the redirection in 
 * our own .spec file).
 * The problem is that socket() is predefined in a linux system header that 
 * we are including, which is different from the WINE definition.
 * (cdecl vs. stdapi).  The result is stack corruption.
 * Furthermore WsControl uses Unix macros and types. This forces us to include 
 * the Unix headers which then conflict with the winsock headers. This forces
 * us to use USE_WS_PREFIX but then ioctlsocket is called WS_ioctlsocket, 
 * which causes link problems. The correct solution is to implement 
 * WsControl using calls to WSAIoctl. Then we should no longer need to use the 
 * Unix headers. This would also have the advantage of reducing code 
 * duplication.
 * Until that happens we need this ugly hack.
 */
#define USE_WS_PREFIX

#define socket  linux_socket
#define recv    linux_recv
/* */

#include "config.h"

#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ioctl.h>

#include <sys/types.h>
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_SYS_SOCKIO_H
# include <sys/sockio.h>
#endif
#ifdef HAVE_NET_IF_H
# include <net/if.h>
#endif

#include "windef.h"
#include "winbase.h"
#include "debugtools.h"
#include "winsock2.h"
#include "winnt.h"
#include "wscontrol.h"

/* FIXME: The rest of the socket() cdecl<->stdapi stack corruption problem
 * discussed above.
 */
#undef socket
#undef recv
extern SOCKET WINAPI socket(INT af, INT type, INT protocol);
extern SOCKET WINAPI recv(SOCKET,char*,int,int);
/* Plus some missing prototypes, due to the WS_ prefixing */
extern int    WINAPI closesocket(SOCKET);
extern int    WINAPI ioctlsocket(SOCKET,long,u_long*);
/* */


DEFAULT_DEBUG_CHANNEL(winsock);


/***********************************************************************
 *		WsControl (WSOCK32.1001)
 *
 * WsControl seems to be an undocumented Win95 function. A lot of 
 * discussion about WsControl can be found on the net, e.g.
 * Subject:      Re: WSOCK32.DLL WsControl Exported Function
 * From:         "Peter Rindfuss" <rindfuss-s@medea.wz-berlin.de>
 * Date:         1997/08/17
 *
 * WSCNTL_TCPIP_QUERY_INFO option is partially implemeted based
 * on observing the behaviour of WsControl with an app in 
 * Windows 98.  It is not fully implemented, and there could
 * be (are?) errors due to incorrect assumptions made.
 *
 *
 * WsControl returns WSCTL_SUCCESS on success.
 * STATUS_BUFFER_TOO_SMALL is returned if the output buffer length
 * (*pcbResponseInfoLen) is too small, otherwise errors return -1.
 *
 * It doesn't seem to generate errors that can be retrieved by 
 * WSAGetLastError().
 *
 */

DWORD WINAPI WsControl(DWORD protocoll,
                       DWORD action,
                       LPVOID pRequestInfo,
                       LPDWORD pcbRequestInfoLen,
                       LPVOID pResponseInfo,
                       LPDWORD pcbResponseInfoLen) 
{
   /* Get the command structure into a pointer we can use,
      rather than void */
   TDIObjectID *pcommand = (TDIObjectID *)pRequestInfo;
  
   TRACE ("   WsControl TOI_ID=>0x%lx<, {TEI_ENTITY=0x%lx, TEI_INSTANCE=0x%lx}, TOI_CLASS=0x%lx, TOI_TYPE=0x%lx\n",
          pcommand->toi_id, pcommand->toi_entity.tei_entity, pcommand->toi_entity.tei_instance,
          pcommand->toi_class, pcommand->toi_type );
  


   switch (action) 
   {
      case WSCNTL_TCPIP_QUERY_INFO: 
      {
         switch (pcommand->toi_id)
         {
            /* 
               ENTITY_LIST_ID seems to get number of adapters in the system.
               (almost like an index to be used when calling other WsControl options)
            */
            case ENTITY_LIST_ID: 
            {
               TDIEntityID *baseptr = pResponseInfo;
               int numInt = 0, i;

               if (pcommand->toi_class != INFO_CLASS_GENERIC &&
                   pcommand->toi_type != INFO_TYPE_PROVIDER) 
               { 
                  FIXME ("Unexpected Option for ENTITY_LIST_ID request -> toi_class=0x%lx, toi_type=0x%lx\n",
                       pcommand->toi_class, pcommand->toi_type);
                  return (WSAEOPNOTSUPP); 
               }
           
               numInt = WSCNTL_GetEntryCount(WSCNTL_COUNT_INTERFACES); 
               if (numInt < 0)
               {
                  ERR ("Unable to open /proc filesystem to determine number of network interfaces!\n");
                  return (-1); 
               }

               if (*pcbResponseInfoLen < sizeof(TDIEntityID)*(numInt*2) ) 
               {
                  return (STATUS_BUFFER_TOO_SMALL);
               }
           
               /* 0 it out first */
               memset(baseptr, 0, sizeof(TDIEntityID)*(numInt*2)); 
               
               for (i=0; i<numInt; i++)
               {
                  /* tei_instance is an network interface identifier.
                     I'm not quite sure what the difference is between tei_entity values of 
                     CL_NL_ENTITY and IF_ENTITY */
                  baseptr->tei_entity = CL_NL_ENTITY;  baseptr->tei_instance = i; baseptr++;
                  baseptr->tei_entity = IF_ENTITY;     baseptr->tei_instance = i; baseptr++; 
               }

               /* Calculate size of out buffer */
               *pcbResponseInfoLen = sizeof(TDIEntityID)*(numInt*2);
            
               break;
            }
          
          
            /* ENTITY_TYPE_ID is used to obtain simple information about a 
               network card, such as MAC Address, description, interface type,
               number of network addresses, etc. */
            case ENTITY_TYPE_ID:  /* ALSO: IP_MIB_STATS_ID */
            {
               if (pcommand->toi_class == INFO_CLASS_GENERIC && pcommand->toi_type == INFO_TYPE_PROVIDER) 
               {
                  if (pcommand->toi_entity.tei_entity == IF_ENTITY)
                  {
                     * ((ULONG *)pResponseInfo) = IF_MIB; 

                     /* Calculate size of out buffer */
                     *pcbResponseInfoLen = sizeof (ULONG);

                  }
                  else if (pcommand->toi_entity.tei_entity == CL_NL_ENTITY) 
                  {
                     * ((ULONG *)pResponseInfo) = CL_NL_IP;  

                     /* Calculate size of out buffer */
                     *pcbResponseInfoLen = sizeof (ULONG); 
                  }
               }
               else if (pcommand->toi_class == INFO_CLASS_PROTOCOL &&
                        pcommand->toi_type == INFO_TYPE_PROVIDER)
               {
                  if (pcommand->toi_entity.tei_entity == IF_ENTITY)
                  {
                     /* In this case, we are requesting specific information about a 
                        a particular network adapter. (MAC Address, speed, data transmitted/received,
                        etc.)
                     */ 
                     IFEntry *IntInfo = (IFEntry *) pResponseInfo;
                     char ifName[512];
#if defined(SIOCGIFHWADDR) || defined(SIOCGENADDR)
                     struct ifreq ifInfo;
#endif
                     SOCKET sock;


                     if (!WSCNTL_GetInterfaceName(pcommand->toi_entity.tei_instance, ifName))
                     {
                        ERR ("Unable to parse /proc filesystem!\n");
                        return (-1);
                     }

                     /* Get a socket so that we can use ioctl */
                     if ( (sock = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
                     {
                        ERR ("Error creating socket!\n");
                        return (-1);
                     }

                     /* 0 out return structure first */
                     memset (IntInfo, 0, sizeof(IFEntry));

                     /* Interface ID */
                     IntInfo->if_index = pcommand->toi_entity.tei_instance;

                     /* MAC Address - Let's try to do this in a cross-platform way... */
#if defined(SIOCGIFHWADDR) /* Linux */
                        strcpy(ifInfo.ifr_name, ifName);
                        if (ioctlsocket(sock, SIOCGIFHWADDR, (ULONG*)&ifInfo) < 0)
                        {
                           ERR ("Error obtaining MAC Address!\n");
                           closesocket(sock);
                           return (-1);
                        }
                        else
                        {
                           /* FIXME: Is it correct to assume size of 6? */
                           memcpy(IntInfo->if_physaddr, ifInfo.ifr_hwaddr.sa_data, 6);
                           IntInfo->if_physaddrlen=6;
                        }
#elif defined(SIOCGENADDR) /* Solaris */
                        if (ioctlsocket(sock, SIOCGENADDR, (ULONG*)&ifInfo) < 0)
                        {
                           ERR ("Error obtaining MAC Address!\n");
                           closesocket(sock);
                           return (-1);
                        }
                        else
                        {
                           /* FIXME: Is it correct to assume size of 6? */
                           memcpy(IntInfo->if_physaddr, ifInfo.ifr_enaddr, 6);
                           IntInfo->if_physaddrlen=6;
                        }
#else
                        memset (IntInfo->if_physaddr, 0, 6);
                        ERR ("Unable to determine MAC Address on your platform!\n");
#endif


                     /* Interface name and length */
                     strcpy (IntInfo->if_descr, ifName);
                     IntInfo->if_descrlen= strlen (IntInfo->if_descr);

                     /* Obtain bytes transmitted/received for interface */
                     if ( (WSCNTL_GetTransRecvStat(pcommand->toi_entity.tei_instance, 
                           &IntInfo->if_inoctets, &IntInfo->if_outoctets)) < 0)
                     {
                        ERR ("Error obtaining transmit/receive stats for the network interface!\n");
                        closesocket(sock);
                        return (-1);
                     }


                     /* FIXME: How should the below be properly calculated? ******************/
                     IntInfo->if_type =  0x6; /* Ethernet (?) */
                     IntInfo->if_speed = 1000000; /* Speed of interface (bits per second?) */
                     /************************************************************************/

                     closesocket(sock);
                     *pcbResponseInfoLen = sizeof (IFEntry) + IntInfo->if_descrlen; 
                  }
                  else if (pcommand->toi_entity.tei_entity == CL_NL_ENTITY) 
                  {
                     IPSNMPInfo *infoStruc = (IPSNMPInfo *) pResponseInfo;
                     int numInt, numRoutes;
                     
                     /* This case is used to obtain general statistics about the 
                        network */
                     
                     if (*pcbResponseInfoLen < sizeof(IPSNMPInfo) )
                     {
                        return (STATUS_BUFFER_TOO_SMALL);
                     }
                     else
                     {
                        /* 0 it out first */
                        memset(infoStruc, 0, sizeof(IPSNMPInfo));
            
                        /* Get the number of interfaces */
                        numInt = WSCNTL_GetEntryCount(WSCNTL_COUNT_INTERFACES); 
                        if (numInt < 0)
                        {
                           ERR ("Unable to open /proc filesystem to determine number of network interfaces!\n");
                           return (-1); 
                        }
                        /* Get the number of routes */
                        numRoutes = WSCNTL_GetEntryCount(WSCNTL_COUNT_ROUTES); 
                        if (numRoutes < 0)
                        {
                           ERR ("Unable to open /proc filesystem to determine number of network routes!\n");
                           return (-1); 
                        }

                        infoStruc->ipsi_numif           = numInt; /* # of interfaces */
                        infoStruc->ipsi_numaddr         = numInt; /* # of addresses */
                        infoStruc->ipsi_numroutes       = numRoutes; /* # of routes */

                        /* FIXME: How should the below be properly calculated? ******************/
                        infoStruc->ipsi_forwarding      = 0x0;
                        infoStruc->ipsi_defaultttl      = 0x0;
                        infoStruc->ipsi_inreceives      = 0x0;
                        infoStruc->ipsi_inhdrerrors     = 0x0;
                        infoStruc->ipsi_inaddrerrors    = 0x0;
                        infoStruc->ipsi_forwdatagrams   = 0x0;
                        infoStruc->ipsi_inunknownprotos = 0x0;
                        infoStruc->ipsi_indiscards      = 0x0;
                        infoStruc->ipsi_indelivers      = 0x0;
                        infoStruc->ipsi_outrequests     = 0x0;
                        infoStruc->ipsi_routingdiscards = 0x0;
                        infoStruc->ipsi_outdiscards     = 0x0;
                        infoStruc->ipsi_outnoroutes     = 0x0;
                        infoStruc->ipsi_reasmtimeout    = 0x0;
                        infoStruc->ipsi_reasmreqds      = 0x0;
                        infoStruc->ipsi_reasmoks        = 0x0;
                        infoStruc->ipsi_reasmfails      = 0x0;
                        infoStruc->ipsi_fragoks         = 0x0;
                        infoStruc->ipsi_fragfails       = 0x0;
                        infoStruc->ipsi_fragcreates     = 0x0;
                        /************************************************************************/
                      
                        /* Calculate size of out buffer */
                        *pcbResponseInfoLen = sizeof(IPSNMPInfo);
                     }
                  }
               }
               else
               {
                  FIXME ("Unexpected Option for ENTITY_TYPE_ID request -> toi_class=0x%lx, toi_type=0x%lx\n",
                       pcommand->toi_class, pcommand->toi_type);
                  
                  return (WSAEOPNOTSUPP); 
               }

               break;
            }


            /* IP_MIB_ADDRTABLE_ENTRY_ID is used to obtain more detailed information about a 
               particular network adapter */
            case IP_MIB_ADDRTABLE_ENTRY_ID: 
            {
               IPAddrEntry *baseIPInfo = (IPAddrEntry *) pResponseInfo;
               char ifName[IFNAMSIZ+1];
               struct ifreq ifInfo;
               SOCKET sock;

               if (*pcbResponseInfoLen < sizeof(IPAddrEntry))
               {
                  return (STATUS_BUFFER_TOO_SMALL); 
               }
               
               if (!WSCNTL_GetInterfaceName(pcommand->toi_entity.tei_instance, ifName))
               {
                  ERR ("Unable to parse /proc filesystem!\n");
                  return (-1);
               }
               
               
               /* Get a socket so we can use ioctl */
               if ( (sock = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
               {
                  ERR ("Error creating socket!\n");
                  return (-1);
               }
	       
               /* 0 it out first */
               memset(baseIPInfo, 0, sizeof(IPAddrEntry) );
               
               /* Interface Id */
               baseIPInfo->iae_index     = pcommand->toi_entity.tei_instance;
               
               /* IP Address */
               strcpy (ifInfo.ifr_name, ifName);
	       ifInfo.ifr_addr.sa_family = AF_INET;
	       if (ioctlsocket(sock, SIOCGIFADDR, (ULONG*)&ifInfo) < 0)
               {
                  baseIPInfo->iae_addr = 0x0;
               }
               else
               {
                  struct WS_sockaddr_in* ipTemp = (struct WS_sockaddr_in*)&ifInfo.ifr_addr;
                  baseIPInfo->iae_addr = ipTemp->sin_addr.S_un.S_addr;
               }
               
               /* Broadcast Address */
               strcpy (ifInfo.ifr_name, ifName);
	       if (ioctlsocket(sock, SIOCGIFBRDADDR, (ULONG *)&ifInfo) < 0)
               {
                  baseIPInfo->iae_bcastaddr = 0x0;
               }
	       else
               {
                  struct WS_sockaddr_in* ipTemp = (struct WS_sockaddr_in*)&ifInfo.ifr_broadaddr;
                  baseIPInfo->iae_bcastaddr = ipTemp->sin_addr.S_un.S_addr;
               }

               /* Subnet Mask */
	       strcpy(ifInfo.ifr_name, ifName);
	       if (ioctlsocket(sock, SIOCGIFNETMASK, (ULONG *)&ifInfo) < 0)
               {
                  baseIPInfo->iae_mask = 0x0;
	       }
               else
	       {
                  /* Trying to avoid some compile problems across platforms.
                     (Linux, FreeBSD, Solaris...) */
                  #ifndef ifr_netmask
                     #ifndef ifr_addr
                        baseIPInfo->iae_mask = 0;
                        ERR ("Unable to determine Netmask on your platform!\n");
                     #else
                        struct WS_sockaddr_in* ipTemp = (struct WS_sockaddr_in*)&ifInfo.ifr_addr;
                        baseIPInfo->iae_mask = ipTemp->sin_addr.S_un.S_addr;
                     #endif
                  #else
                     struct WS_sockaddr_in* ipTemp = (struct WS_sockaddr_in*)&ifInfo.ifr_netmask;
                     baseIPInfo->iae_mask = ipTemp->sin_addr.S_un.S_addr;
                  #endif
               }

               /* FIXME: How should the below be properly calculated? ******************/
               baseIPInfo->iae_reasmsize = 0x0;
               baseIPInfo->iae_context   = 0x0;
               baseIPInfo->iae_pad       = 0x0;
               /************************************************************************/
             
               /* Calculate size of out buffer */
               *pcbResponseInfoLen = sizeof(IPAddrEntry);
               closesocket(sock);
               break;
            }


	    /* This call returns the routing table.
	     * No official documentation found, even the name of the command is unknown.
	     * Work is based on
	     * http://www.cyberport.com/~tangent/programming/winsock/articles/wscontrol.html
	     * and testings done with winipcfg.exe, route.exe and ipconfig.exe.
	     * pcommand->toi_entity.tei_instance seems to be the interface number
	     * but route.exe outputs only the information for the last interface
	     * if only the routes for the pcommand->toi_entity.tei_instance
	     * interface are returned. */
	    case IP_MIB_ROUTETABLE_ENTRY_ID:	/* FIXME: not real name. Value is 0x101 */
	    {
		int numRoutes, foundRoutes;
		wscntl_routeentry *routeTable, *routePtr;	/* route table */
	        
                IPRouteEntry *winRouteTable  = (IPRouteEntry *) pResponseInfo;

		/* Get the number of routes */
		numRoutes = WSCNTL_GetEntryCount(WSCNTL_COUNT_ROUTES); 
		if (numRoutes < 0)
		{
		    ERR ("Unable to open /proc filesystem to determine number of network routes!\n");
		    return (-1); 
		}

		if (*pcbResponseInfoLen < (sizeof(IPRouteEntry) * numRoutes))
		{
		    return (STATUS_BUFFER_TOO_SMALL); 
		}
		
		/* malloc space for the routeTable */
		routeTable = (wscntl_routeentry *) malloc(sizeof(wscntl_routeentry) * numRoutes);
		if (!routeTable)
	       	{
		    ERR ("couldn't malloc space for routeTable!\n");
		}

		/* get the route table */
		foundRoutes = WSCNTL_GetRouteTable(numRoutes, routeTable);
		if (foundRoutes < 0)
		{
		    ERR ("Unable to open /proc filesystem to parse the route entries!\n");
		    free(routeTable);
		    return -1;
		}
		routePtr = routeTable;
		    
                /* first 0 out the output buffer */
                memset(winRouteTable, 0, *pcbResponseInfoLen);
               
		/* calculate the length of the data in the output buffer */
                *pcbResponseInfoLen = sizeof(IPRouteEntry) * foundRoutes;
		
		for ( ; foundRoutes > 0; foundRoutes--)
		{
		    winRouteTable->ire_addr = routePtr->wre_dest;
		    winRouteTable->ire_index = routePtr->wre_intf;
		    winRouteTable->ire_metric = routePtr->wre_metric;
		    /* winRouteTable->ire_option4 =
		    winRouteTable->ire_option5 =
		    winRouteTable->ire_option6 = */
		    winRouteTable->ire_gw = routePtr->wre_gw;
		    /* winRouteTable->ire_option8 =
		    winRouteTable->ire_option9 =
		    winRouteTable->ire_option10 = */
		    winRouteTable->ire_mask = routePtr->wre_mask;
		    /* winRouteTable->ire_option12 = */

		    winRouteTable++;
		    routePtr++;
		}
						    
		free(routeTable);
                break;
	    }
	    

            default: 
            {
               FIXME ("Command ID Not Supported -> toi_id=0x%lx, toi_entity={tei_entity=0x%lx, tei_instance=0x%lx}, toi_class=0x%lx, toi_type=0x%lx\n",
                       pcommand->toi_id, pcommand->toi_entity.tei_entity, pcommand->toi_entity.tei_instance, 
                       pcommand->toi_class, pcommand->toi_type);
              
               return (WSAEOPNOTSUPP); 
            }
         }
      
         break;
      }
    
      case WSCNTL_TCPIP_ICMP_ECHO:
      {
         unsigned int addr = *(unsigned int*)pRequestInfo;
         #if 0
            int timeout= *(unsigned int*)(inbuf+4);
            short x1 = *(unsigned short*)(inbuf+8);
            short sendbufsize = *(unsigned short*)(inbuf+10);
            char x2 = *(unsigned char*)(inbuf+12);
            char ttl = *(unsigned char*)(inbuf+13);
            char service = *(unsigned char*)(inbuf+14);
            char type= *(unsigned char*)(inbuf+15); /* 0x2: don't fragment*/
         #endif      
      
         FIXME("(ICMP_ECHO) to 0x%08x stub \n", addr);
         break;
      }

      default:
      {
         FIXME("Protocoll Not Supported -> protocoll=0x%lx, action=0x%lx, Request=%p, RequestLen=%p, Response=%p, ResponseLen=%p\n",
	       protocoll, action, pRequestInfo, pcbRequestInfoLen, pResponseInfo, pcbResponseInfoLen);
      
         return (WSAEOPNOTSUPP); 
      }
   }
   
   
   return (WSCTL_SUCCESS); 
}



/* 
  Helper function for WsControl - Get count of the number of interfaces
  or routes by parsing /proc filesystem.
*/
int WSCNTL_GetEntryCount(const int entrytype)
{
   char *filename;
   int 	fd;
   char buf[512];  /* Size optimized for a typical workstation */
   char	*ptr;
   int  count;
   int	chrread;
 
 
   switch (entrytype)
   {
       case WSCNTL_COUNT_INTERFACES:
       {
	   filename = PROCFS_NETDEV_FILE;
	   count = -2;	/* two haeder lines */
	   break;
       };

       case WSCNTL_COUNT_ROUTES:
       {
	   filename = PROCFS_ROUTE_FILE;
	   count = -1;	/* one haeder line */
	   break;
       };

       default:
       {
	   return -1;
       };
   }

   /* open /proc filesystem file */
   fd = open(filename, O_RDONLY);
   if (fd < 0) {
       return -1;
   }

   /* read the file and count the EOL's */
   while ((chrread = read(fd, buf, sizeof(buf))) != 0) 
   {
       ptr = buf;
       if (chrread < 0) 
       {
	   if (errno == EINTR) 
	   {
	       continue;	/* read interupted by a signal, try to read again */
	   }
	   else
	   {
	       close(fd);
	       return -1;
	   }
       }
       while ((ptr = memchr(ptr, '\n', chrread - (int) (ptr -  buf))) > 0)
       {
	   count++;
	   ptr++;
       }
   }

   close(fd);
   return count;
}


/*
   Helper function for WsControl - Get name of device from interface number
   by parsing /proc filesystem.
*/
int WSCNTL_GetInterfaceName(int intNumber, char *intName)
{
   FILE *procfs;
   char buf[512]; /* Size doesn't matter, something big */
   int  i;

   /* Open /proc filesystem file for network devices */ 
   procfs = fopen(PROCFS_NETDEV_FILE, "r");
   if (!procfs) 
   {
      /* If we can't open the file, return an error */
      return (-1);
   }
   
   /* Omit first two lines, they are only headers */
   fgets(buf, sizeof(buf), procfs);	
   fgets(buf, sizeof(buf), procfs);

   for (i=0; i<intNumber; i++)
   {
      /* Skip the lines that don't interest us. */
      fgets(buf, sizeof(buf), procfs);
   }
   fgets(buf, sizeof(buf), procfs); /* This is the line we want */

   
   /* Parse out the line, grabbing only the name of the device
      to the intName variable 
      
      The Line comes in like this: (we only care about the device name)
      lo:   21970 377 0 0 0 0 0 0 21970 377 0 0 0 0 0 0
   */
   i=0; 
   while (isspace(buf[i])) /* Skip initial space(s) */
   {
      i++;
   }

   while (buf[i]) 
   {
      if (isspace(buf[i]))
      {
         break;
      }
      
      if (buf[i] == ':')  /* FIXME: Not sure if this block (alias detection) works properly */
      {
         /* This interface could be an alias... */
         int hold = i;
         char *dotname = intName;
         *intName++ = buf[i++];
         
         while (isdigit(buf[i]))
         {
            *intName++ = buf[i++];
         }
         
         if (buf[i] != ':') 
         {
            /* ... It wasn't, so back up */
            i = hold;
            intName = dotname;
         }
 
         if (buf[i] == '\0')
         {
            fclose(procfs);
            return(FALSE);
         }
         
         i++;
         break;
      }
      
      *intName++ = buf[i++];
   }
   *intName++ = '\0';

   fclose(procfs);
   return(TRUE);
}


/*
   Helper function for WsControl - This function returns the bytes (octets) transmitted
   and received for the supplied interface number from the /proc fs. 
*/
int WSCNTL_GetTransRecvStat(int intNumber, unsigned long *transBytes, unsigned long *recvBytes)
{
   FILE *procfs;
   char buf[512], result[512]; /* Size doesn't matter, something big */
   int  i, bufPos, resultPos;

   /* Open /proc filesystem file for network devices */ 
   procfs = fopen(PROCFS_NETDEV_FILE, "r");
   if (!procfs) 
   {
      /* If we can't open the file, return an error */
      return (-1);
   }
   
   /* Omit first two lines, they are only headers */
   fgets(buf, sizeof(buf), procfs);	
   fgets(buf, sizeof(buf), procfs);

   for (i=0; i<intNumber; i++)
   {
      /* Skip the lines that don't interest us. */
      fgets(buf, sizeof(buf), procfs);
   }
   fgets(buf, sizeof(buf), procfs); /* This is the line we want */



   /* Parse out the line, grabbing the number of bytes transmitted
      and received on the interface.
      
      The Line comes in like this: (we care about columns 2 and 10)
      lo:   21970 377 0 0 0 0 0 0 21970 377 0 0 0 0 0 0
   */

   /* Start at character 0 in the buffer */
   bufPos=0;
   
   /* Skip initial space(s) */ 
   while (isspace(buf[bufPos])) 
      bufPos++;


   /* Skip the name and its trailing spaces (if any) */
   while (buf[bufPos]) 
   {
      if (isspace(buf[bufPos]))
         break;
 
      if (buf[bufPos] == ':') /* Could be an alias */
      {
         int hold = bufPos;

         while(isdigit (buf[bufPos]))
            bufPos++;
         if (buf[bufPos] != ':')
            bufPos = hold;
         if (buf[bufPos] == '\0')
         {
            fclose(procfs);
            return(FALSE);
         }
         
         bufPos++;
         break;
      }

      bufPos++;
   }
   while (isspace(buf[bufPos]))
      bufPos++;


   /* This column (#2) is the number of bytes received. */
   resultPos = 0;
   while (!isspace(buf[bufPos]))
   {
      result[resultPos] = buf[bufPos];
      result[resultPos+1]='\0';
      resultPos++; bufPos++;
   }
   *recvBytes = strtoul (result, NULL, 10); /* convert string to unsigned long, using base 10 */

   
   /* Skip columns #3 to #9 (Don't need them) */
   for  (i=0; i<7; i++)
   {
      while (isspace(buf[bufPos]))
         bufPos++;
      while (!isspace(buf[bufPos])) 
         bufPos++;
   }


   /* This column (#10) is the number of bytes transmitted */
   while (isspace(buf[bufPos]))
       bufPos++;

   resultPos = 0;
   while (!isspace(buf[bufPos]))
   {
      result[resultPos] = buf[bufPos];
      result[resultPos+1]='\0';
      resultPos++; bufPos++;
   }
   *transBytes = strtoul (result, NULL, 10); /* convert string to unsigned long, using base 10 */


   fclose(procfs);
   return(TRUE);
}


/* Parse the procfs route file and put the datas into routeTable.
 * Return value is the number of found routes */
int WSCNTL_GetRouteTable(int numRoutes, wscntl_routeentry *routeTable)
{
    int nrIntf;		/* total number of interfaces */
    char buf[256];	/* temporary buffer */
    char *ptr;		/* pointer to temporary buffer */
    FILE *file;		/* file handle for procfs route file */
    int foundRoutes = 0;	/* number of found routes */
    typedef struct interface_t {
	char intfName[IFNAMSIZ+1];	/* the name of the interface */
	int intfNameLen;	/* length of interface name */
    } interface_t;
    interface_t *interface;
    int intfNr;		/* the interface number */

    wscntl_routeentry *routePtr = routeTable;

    /* get the number of interfaces */
    nrIntf = WSCNTL_GetEntryCount(WSCNTL_COUNT_INTERFACES);
    if (nrIntf < 0)
    {
	ERR ("Unable to open /proc filesystem to determine number of network interfaces!\n");
	return (-1);
    }

    /* malloc space for the interface struct array */
    interface = (interface_t *) malloc(sizeof(interface_t) * nrIntf);
    if (!routeTable)
    {
	ERR ("couldn't malloc space for interface!\n");
    }

    for (intfNr = 0; intfNr < nrIntf; intfNr++) {
	if (WSCNTL_GetInterfaceName(intfNr, interface[intfNr].intfName) < 0)
	{
	    ERR ("Unable to open /proc filesystem to determine the name of network interfaces!\n");
	    free(interface);
	    return (-1);
	}
	interface[intfNr].intfNameLen = strlen(interface[intfNr].intfName);
    }

    /* Open /proc filesystem file for routes */ 
    file = fopen(PROCFS_ROUTE_FILE, "r");
    if (!file) 
    {
       	/* If we can't open the file, return an error */
	free(interface);
	return (-1);
    }
    
    /* skip the header line */
    fgets(buf, sizeof(buf), file);

    /* parse the rest of the file and put the matching entries into routeTable.
       Format of procfs route entry:
       Iface Destination Gateway Flags RefCnt Use Metric Mask  MTU Window IRTT
       lo 0000007F 00000000 0001 0 0 0 000000FF 0 0 0
    */
    while (fgets(buf, sizeof(buf), file)) {
	intfNr = 0;
	/* find the interface of the route */
	while ((strncmp(buf, interface[intfNr].intfName, interface[intfNr].intfNameLen) != 0) 
		&& (intfNr < nrIntf))
	{
	    intfNr++;
	}
	if (intfNr < nrIntf) {
	    foundRoutes++;
	    if (foundRoutes > numRoutes) {
		/* output buffer is to small */
		ERR("buffer to small to fit all routes found into it!\n");
		free(interface);
		fclose(file);
		return -1;
	    }
	    ptr = buf;
	    ptr += interface[intfNr].intfNameLen;
	    routePtr->wre_intf = intfNr;
	    routePtr->wre_dest = strtoul(ptr, &ptr, 16);	/* destination */
	    routePtr->wre_gw = strtoul(ptr, &ptr, 16);	/* gateway */
	    strtoul(ptr, &ptr, 16);	/* Flags; unused */
	    strtoul(ptr, &ptr, 16);	/* RefCnt; unused */
	    strtoul(ptr, &ptr, 16);	/* Use; unused */
	    routePtr->wre_metric = strtoul(ptr, &ptr, 16);	/* metric */
	    routePtr->wre_mask = strtoul(ptr, &ptr, 16);	/* mask */
	    /* strtoul(ptr, &ptr, 16);	MTU; unused */
	    /* strtoul(ptr, &ptr, 16);	Window; unused */
	    /* strtoul(ptr, &ptr, 16);	IRTT; unused */

	    routePtr++;
	}
	else
	{
	    /* this should never happen */
	    WARN("Skipping route with unknown interface\n");
	}
    }

    free(interface);
    fclose(file);
    return foundRoutes;
}


/***********************************************************************
 *		WSARecvEx			(WSOCK32.1107)
 *
 * WSARecvEx is a Microsoft specific extension to winsock that is identical to recv
 * except that has an in/out argument call flags that has the value MSG_PARTIAL ored
 * into the flags parameter when a partial packet is read. This only applies to
 * sockets using the datagram protocol. This method does not seem to be implemented
 * correctly by microsoft as the winsock implementation does not set the MSG_PARTIAL
 * flag when a fragmented packet arrives.
 */
INT WINAPI WSARecvEx(SOCKET s, char *buf, INT len, INT *flags)
{
    FIXME("(WSARecvEx) partial packet return value not set \n");
    return recv(s, buf, len, *flags);
}


/***********************************************************************
 *       s_perror         (WSOCK32.1108)
 */
void WINAPI s_perror(LPCSTR message)
{
    FIXME("(%s): stub\n",message);
    return;
}
