/*
 * 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 is supposed to call into ws2_32's WSOCK32_socket.
         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.

         The correct answer to this problem is to make winsock.h not dependent 
         on system headers, that way all of our functions are defined consistently.
         Until that happens we need this hack.
*/
#define socket  linux_socket
/* */

#include "config.h"

#include <string.h>
#include <sys/types.h>
#include "windef.h"
#include "winbase.h"
#include "debugtools.h"
#include "winsock2.h"
#include "winnt.h"
#include "wscontrol.h"
#include <ctype.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef HAVE_SYS_SOCKIO_H
# include <sys/sockio.h>
#endif
#ifdef HAVE_NET_IF_H
# include <net/if.h>
#endif
#include <errno.h>

#ifdef __NetBSD__
#undef if_type
#endif

/* FIXME: The rest of the socket() cdecl<->stdapi stack corruption problem
          discussed above. */
#undef socket
extern SOCKET WINAPI socket(INT af, INT type, INT protocol);
/* */


DEFAULT_DEBUG_CHANNEL(winsock);


/***********************************************************************
 *      WsControl()
 *
 * 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];
                     struct ifreq ifInfo;
                     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 entrys!\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 entrys 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);
}


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