/*
 * WSOCK32 specific functions
 *
 * Copyright (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


/* 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>
#ifdef HAVE_SYS_IOCTL_H
# include <sys/ioctl.h>
#endif

#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 "wine/debug.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*);
/* */


WINE_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;
}
