Beispiel #1
0
///////////////////////////////////////////////////////
// Build the send the first message (RRQ or WRQ)
// All Data are in sTC struct
///////////////////////////////////////////////////////
static BOOL TftpSendConnect (char *szBlkSize, BOOL bFullPath)
{
ADDRINFO Hints, *ai;
int              Rc;
char             szPort[NI_MAXSERV];

	// preparte a data packet (either RRQ or WRQ)
	PopulateXRQPacket (szBlkSize, bFullPath);

    // resolve host name
	memset (& Hints, 0, sizeof Hints);
	Hints.ai_family   = AF_UNSPEC;
	Hints.ai_socktype = SOCK_DGRAM;
	Hints.ai_protocol = IPPROTO_UDP;

	// first use port given as parameter, 
	if (sTC.nPort==0)
		  lstrcpy (szPort, "tftp");
	else
	{
		 wsprintf (szPort, "%d", sTC.nPort), 	
		 Hints.ai_flags    = AI_NUMERICSERV;
	}
    Rc = getaddrinfo (sTC.szHost, szPort, & Hints, &ai );
	// last chance : use default tftp port 69
	if (Rc==WSASERVICE_NOT_FOUND)
	{
	    Hints.ai_flags    = AI_NUMERICSERV;
		Rc = getaddrinfo (sTC.szHost, DEFAULT_TFTP_PORT, & Hints, &ai );
	}
	if (Rc!=0)
        return BadEndOfTransfer ("Host is unknown or invalid. Error %d", GetLastError());
    sTC.s = socket( ai->ai_family,ai->ai_socktype, ai->ai_protocol ) ;
	if (sTC.s == INVALID_SOCKET)
	{
		freeaddrinfo (ai);
        return BadEndOfTransfer ( "Can't create client socket.\nError code %d (%s)", 
			                      WSAGetLastError (), LastErrorText());
	}
    
    // since remote port will change do not use either bind or connect 
	Rc = sendto (sTC.s, sTC.BufSnd, sTC.nToSend , 0, ai->ai_addr, ai->ai_addrlen );
	if (Rc == SOCKET_ERROR)
	{
		freeaddrinfo (ai);
        return BadEndOfTransfer  ("can not send data packet.\n%s\nError code %d (%s)", 
                                  "Tftp server may have been stopped",
                                  WSAGetLastError (), LastErrorText());
	}
	freeaddrinfo (ai);
return TRUE;
} // TftpSendConnect
Beispiel #2
0
////////////////////////////
// Attach and destroy icon to the TaskTray
void TrayMessage(HWND hDlg, DWORD dwMessage, HICON hIcon, int TaskTrayId, int uCallBckMsg)
{
NOTIFYICONDATA IconData;

LogToMonitor ("TrayMessage Call : msg %d <%s>, wnd %d, id %d\n", dwMessage,
			  dwMessage==NIM_ADD ? "ADD" : dwMessage==NIM_DELETE ? "DELETE" : "OTHER",
			  hDlg, TaskTrayId );
   memset (& IconData, 0, sizeof IconData);
   // IconData.cbSize = NOTIFYICONDATA_V1_SIZE;

   IconData.cbSize = sizeof IconData;

   IconData.hWnd = hDlg;
   IconData.uID = TaskTrayId ;
   if (dwMessage != NIM_DELETE)
   {
	   IconData.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP;
	   IconData.uCallbackMessage = uCallBckMsg;
	   IconData.hIcon = hIcon;
	   GetWindowText (hDlg, IconData.szTip, sizeof IconData.szTip - 1);
   }
		
   if ( ! Shell_NotifyIcon (dwMessage, &IconData) )
	   LogToMonitor ("error %d in Shell_NotifyIcon <%s>\n", 
					 GetLastError (), LastErrorText () );
} // TrayMessage
Beispiel #3
0
void ListenDhcpMessage (void *lpVoid)
{
struct dhcp_packet      sDhcpPkt;
char szHostname [128], *p;
int                     Rc, nSize;
struct S_WorkerParam   *pParam = lpVoid;
struct sockaddr_in      SockFrom;
int                     nFromLen = sizeof SockFrom;
BOOL                    bUniCast;
int True = 1;

    DHCPReadConfig ();
    Sleep (1000);
    
	 //NJW Prompt to see if we should discover via ping before we start doing DHCP
	 if(scanforleases)
// && IDYES == CMsgBox(pParam->hWnd, "Should I reset the lease file and rediscover devices?", "Discover Devices", MB_YESNO))
	 {
		struct in_addr addr;
		int count;
		SetHourglass(TRUE);
		ReadKey(TFTPD32_DHCP_KEY, KEY_DHCP_POOL, & addr.s_addr, sizeof(addr.s_addr), REG_DWORD, szTftpd32IniFile);
		ReadKey(TFTPD32_DHCP_KEY, KEY_DHCP_POOLSIZE, &count, sizeof(count), REG_DWORD, szTftpd32IniFile);
		SetNumAllocated(0);
		FreeLeases(FALSE);
		if (sSettings.bPersLeases)  LoadLeases ();
		if (sSettings.bPing)        PingRange (&addr, count);
		// DHCPSaveConfig ();
		SetHourglass(FALSE);
		SVC_WARNING ("Lease file updated.\nDiscover Devices");
	 }

   // add broadcast permission to socket
   if (setsockopt (tThreads[TH_DHCP].skt, SOL_SOCKET, SO_BROADCAST, (char *) & True, sizeof True) != 0)
   {
	   LOG (1, "can't set broadcast option.\nPlease, suppress DHCP server in the settings window");
	   LogToMonitor ("can't set broadcast option.\n");
	   tThreads[TH_DHCP].gRunning = FALSE; 
   }

   while ( tThreads[TH_DHCP].gRunning )
   {
        // send leases to GUI
        Dhcp_Send_Leases (tFirstIP, nAllocatedIP);

        memset (& sDhcpPkt, 0, sizeof sDhcpPkt);
        Rc = recvfrom ( tThreads[TH_DHCP].skt,
                        (char *) & sDhcpPkt,
                        sizeof sDhcpPkt,
                        0,
                        (struct sockaddr *) & SockFrom,
                        & nFromLen);
      // recv error
      // since Tftpd32 sends broadcasts, it receives its own message, just ignore it
        if (Rc < 0)
        {
             if (GetLastError () != WSAECONNRESET)
              {
                 LOG (1, "Recv error %d", GetLastError ());
                 Sleep (500);
              }
              continue;
        } // recv failed

        // if msg is too short
        // If all bootP fields have been read
        if (Rc < offsetof ( struct dhcp_packet, options ))
        {
           LOG (5, "Message truncated (length was %d)", Rc);
           if ( tThreads[TH_DHCP].gRunning ) Sleep (500);
           continue;
        }

        // if pool is empty and MAC address not statically assigned : ignore request
        if (    sParamDHCP.nPoolSize == 0  
            &&  DHCP_StaticAssignation (& sDhcpPkt)==INADDR_NONE )
        {
           Sleep (100);
           continue;
        }

        // handle only nul-terminated strings
        sDhcpPkt.sname[sizeof sDhcpPkt.sname - 1] = 0;
        sDhcpPkt.file [sizeof sDhcpPkt.file  - 1] = 0;

        // read host name, truncate it
        if (gethostname (szHostname , sizeof szHostname )==SOCKET_ERROR)
              lstrcpy (szHostname, "Tftpd32DchpServer");
        if ((p=strchr (szHostname, '.'))!=NULL)  *p=0;
        szHostname [sizeof sDhcpPkt.sname - 1] = 0;

        if (sDhcpPkt.sname[0]!=0  && lstrcmp (sDhcpPkt.sname, szHostname)!=0)
        {
           LOG (2, "Packet addressed to %s", sDhcpPkt.sname);
            continue;
        }

        // we have only to answer to BOOTREQUEST msg
        if (sDhcpPkt.op != BOOTREQUEST)
        {
            LOG (2, "%d Request %d not processed", GetCurrentThreadId (),sDhcpPkt.op);
            continue ;
        }

        // if request OK and answer ready
        bUniCast =  (     SockFrom.sin_addr.s_addr!=htonl (INADDR_NONE)
                      &&  SockFrom.sin_addr.s_addr!=htonl (INADDR_ANY)
                      // fix 5/02/2006 : 127.0.0.2 should be handle as a broadcast
                      &&  SockFrom.sin_addr.S_un.S_un_b.s_b1 != 127 ) ; // class A 127
        if (ProcessDHCPMessage ( & sDhcpPkt, & nSize ) )
        {struct servent *lpServEnt;
//            BinDump ((char *)&sDhcpPkt, sizeof sDhcpPkt, "DHCP");
           SockFrom.sin_family = AF_INET;
           // if no source address was specified reply with a broadcast
           if (!bUniCast)  SockFrom.sin_addr.s_addr = htonl (INADDR_NONE);

		   // Added : DHCP relay detection --> send replies to port 67 and 68
		   // Colin and others point ourt that this is wrong. I guess they are right.
		   // However it should not be an issue and i am sure that the host receive an address !
           if (sDhcpPkt.giaddr.s_addr!=htonl(INADDR_ANY)  || sDhcpPkt.giaddr.s_addr!=htonl(INADDR_NONE))
           {
			  // sends to port 67
              lpServEnt = getservbyname ("bootps", "udp") ;
              SockFrom.sin_port =  (lpServEnt != NULL) ?  lpServEnt->s_port : htons (BOOTPS_PORT);
	          Rc = sendto (tThreads[TH_DHCP].skt,
		                    (char *) & sDhcpPkt,
			                 nSize,
				             0,
					        (struct sockaddr *) & SockFrom,
						    sizeof SockFrom);
			  // and prepare for port 68
              lpServEnt = getservbyname ("bootpc", "udp") ;
              SockFrom.sin_port =  (lpServEnt != NULL) ?  lpServEnt->s_port : htons (BOOTPC_PORT);
           }

           LOG (15, "Thread 0x%X: send %d bytes", GetCurrentThreadId(), nSize );
           Rc = sendto (tThreads[TH_DHCP].skt,
                        (char *) & sDhcpPkt,
                         nSize,
                         0,
                        (struct sockaddr *) & SockFrom,
                        sizeof SockFrom);
           if (Rc<nSize)
                LOG (1, "sendto error %d: %s", GetLastError(), LastErrorText ());
        }  // ProcessDHCPMessage

   } // do it eternally

LogToMonitor ("DHCP thread ends here\n");
    _endthread ();
} // ListenDhcpMessage
Beispiel #4
0
/////////////////////////////
// Fenetre Background gestion des appels TCP
//
LRESULT CALLBACK TftpClientProc (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
DWORD          nbWrt;
struct tftphdr *tpr, *tps;
time_t            dNow;
int             Ark;
HWND            hCBWnd, hParentWnd;

  time (&dNow);
  switch (message)
  {

    /////////////////////////
    // Message Windows

    case WM_INITCLIENT :
      // only one client transfer available
      hTftpClientSemaphore = CreateSemaphore(NULL, 1, 1, TFTP_CLIENT_SEMAPHORE);

         hTftpClientWnd = hWnd;
        hParentWnd = GetParent (hWnd);
         EnableWindow (GetDlgItem (hParentWnd, IDC_CLIENT_BREAK_BUTTON), FALSE);
         SetDlgItemText (hParentWnd, IDC_CLIENT_BLOCK, "");

       // populate combo with proposed block sizes
        hCBWnd = GetDlgItem (hParentWnd, IDC_CB_DATASEG);
      for (Ark=0 ;  Ark<SizeOfTab (tBlkSize); Ark++)
                ComboBox_AddString (hCBWnd, tBlkSize[Ark].szBlkSize);
       ComboBox_SetCurSel (hCBWnd, 0);

       // uncheck "Send full path to server"
      SendDlgItemMessage (hParentWnd, IDC_CLIENT_FULL_PATH, BM_SETCHECK, BST_UNCHECKED, 0);   

      // edittext IDC_CLIENT_FILE will accept dropped file (works only because it is on the top in Z-Order
       DragAcceptFiles (GetDlgItem (hParentWnd, IDC_CLIENT_LOCALFILE), TRUE);
          // fEditBoxProc = (WNDPROC) SetWindowLong (GetDlgItem (hParentWnd, IDC_CLIENT_LOCALFILE), GWL_WNDPROC, (LONG) TftpClientFileNameProc);
          fEditBoxProc = (WNDPROC) SetWindowLongPtr (GetDlgItem (hParentWnd, IDC_CLIENT_LOCALFILE), GWLP_WNDPROC, (LONG_PTR) TftpClientFileNameProc);
//    SetWindowLong (GetDlgItem (hParentWnd, IDC_CLIENT_FILE), GWL_USERDATA, (LONG) TftpClientFileNameProc);
    SetWindowLongPtr (GetDlgItem (hParentWnd, IDC_CLIENT_LOCALFILE), GWLP_USERDATA, (LONG_PTR) TftpClientFileNameProc);
         break;

    case WM_CLOSE :
LogToMonitor ("GUI: Closing Tftp Client");
         CloseHandle (hTftpClientSemaphore);
         CloseHandle (sTC.hFile);
         closesocket (sTC.s);
         break;

    case WM_COMMAND :
          Handle_VM_Command (hWnd, wParam, lParam);
          break;


    case WM_TIMER :
         KillTimer(hWnd, wParam);
         PostMessage (hWnd, wParam, 0, (LPARAM) -1);    // pour pas confondre
         break;

      //////////////////////
      // Download : fichier envoyé par le serveur
     case WM_CLIENT_DATA :
        // WSAAsyncSelect (sTC.s, hWnd, 0, 0);  A SUPPRIMER
        KillTimer(hWnd, wParam);
        if (sTC.bBreak) return FALSE;
        sTC.nRcvd = 0;
        // On est reveillé par un message reçu
        tpr = (struct tftphdr *) sTC.BufRcv;
        if (WSAGETSELECTEVENT(lParam) == FD_READ)
        {
            if (! UdpRecv ())
                return BadEndOfTransfer ("Error in Recv.\nError code is %d (%s)", WSAGetLastError (), LastErrorText() );
          // parcours des codes retours
          switch (htons (tpr->th_opcode))
            {
              case TFTP_ERROR :
                   return BadEndOfTransfer ("Server stops the transfer.\nError #%d: %s", htons (tpr->th_code), tpr->th_msg);
             case TFTP_OACK :
                    if (sTC.nCount==0) TftpProcessOACK ();
                     break;
                case TFTP_DATA :
                   // a data packet has been received. Check #block
                   if ( htons (tpr->th_block) == (unsigned short) (sTC.nCount+1) )
                    {
                      if (     !WriteFile (sTC.hFile, tpr->th_data, sTC.nRcvd - TFTP_DATA_HEADERSIZE, & nbWrt, NULL)
                          ||  sTC.nRcvd-TFTP_DATA_HEADERSIZE!=nbWrt)
                            return BadEndOfTransfer ("Error in writing file.\nError code is %d (%s)", GetLastError(), LastErrorText());
                       sTC.nCount++;
                       sTC.nRetransmit = 0;
                       // prepare Ack block
                       tps = (struct tftphdr *) sTC.BufSnd;
                       tps->th_opcode = htons (TFTP_ACK),  tps->th_block = htons ((unsigned short) sTC.nCount);
                       sTC.nToSend = TFTP_DATA_HEADERSIZE;
                       // compute MD5
                       MD5Update (& sTC.m.ctx, tpr->th_data, nbWrt);
                    }
                  break;
             default :
                 return BadEndOfTransfer ("Server sent illegal opcode %d", htons (tpr->th_opcode));
          } // switch opcode
        } // il y a un message à recevoir
        // La comparaison marche si le paquet est le bon ou une répétition du précédent message
        if ( htons (tpr->th_block) == (unsigned short) sTC.nCount)
        {
           if (sTC.nRetransmit)  sTC.nTotRetrans ++;
           if (sTC.nRetransmit++ > TFTP_RETRANSMIT)
                return BadEndOfTransfer ("Timeout waiting block #%d", sTC.nCount+1);
            send (sTC.s, sTC.BufSnd, sTC.nToSend, 0);
            SetTimer (hWnd, WM_CLIENT_DATA, sTC.dwTimeout, NULL);
        }
      // sTC.nRcvd ne peut être inférieur que si on a reçu un block
        if (  htons (tpr->th_opcode)==TFTP_DATA
          &&  sTC.nRcvd!=0
           && sTC.nRcvd < sTC.nPktSize + TFTP_DATA_HEADERSIZE)
                    return TransferOK (dNow);
      Statistics (dNow);
        break;

     ////////////////////////
    // Upload : server sends ACK
     case WM_CLIENT_ACK :
        KillTimer(hWnd, wParam);
       if (sTC.bBreak  ||  sTC.s==INVALID_SOCKET) return FALSE;
       
       // socket not closed by StopTransfer
        tpr = (struct tftphdr *) sTC.BufRcv;
        if ( WSAGETSELECTEVENT(lParam) == FD_READ )
        {
            if (! UdpRecv ())
                return BadEndOfTransfer ("Error in Recv.\nError code is %d (%s)", WSAGetLastError (), LastErrorText() );
            switch (htons (tpr->th_opcode))
            {
              case TFTP_ERROR :
                   return BadEndOfTransfer ("Server stops the transfer.\nError #%d: %s", htons (tpr->th_code), tpr->th_msg);

                case TFTP_OACK :
                    if (sTC.nCount!=0)  break; // ignore message
                   TftpProcessOACK ();
                    tpr->th_block = htons(0);  // pour passer en dessous
                   // Fall through

              case TFTP_ACK :
                    if ( htons (tpr->th_block) == (unsigned short) sTC.nCount )
                    {
                      // prepare Data block
                       tps = (struct tftphdr *) sTC.BufSnd;
                       if ( !ReadFile (sTC.hFile, tps->th_data, sTC.nPktSize, & sTC.nRcvd, NULL) )
                       {
                          if (sTC.nToSend == TFTP_DATA_HEADERSIZE + sTC.nPktSize)  // file was exactly N * PkSize
                                  return TransferOK (dNow);
                            else  return BadEndOfTransfer ("Error in reading file.\nError code is %d (%s)", GetLastError(), LastErrorText());
                       }
                       if (sTC.nRcvd == 0) // EOF 
                        {
                          if (sTC.nToSend < TFTP_DATA_HEADERSIZE + sTC.nPktSize) 
                                return TransferOK (dNow);
                      }
                      sTC.nCount++;
                      sTC.nRetransmit = 0;
                      tps->th_opcode = htons (TFTP_DATA),  tps->th_block = htons ((unsigned short) sTC.nCount);
                      sTC.nToSend = TFTP_DATA_HEADERSIZE + sTC.nRcvd;
                      // compute MD5
                      MD5Update (& sTC.m.ctx, tps->th_data, sTC.nRcvd);
                    }
                  break;
             default :
                   return BadEndOfTransfer ("Server sent illegal opcode %d", htons (tpr->th_opcode));
            } // switch opcode
        } // il y a un message à recevoir

        // Timeout or ack of previous block
        else if ( htons (tpr->th_block) == (unsigned short) (sTC.nCount-1) )
        {
           if (sTC.nRetransmit)  sTC.nTotRetrans ++;
           if (sTC.nRetransmit++ > TFTP_RETRANSMIT)
                return BadEndOfTransfer ("Timeout while waiting ack block #%d", sTC.nCount);
            // une possibilité : on est au dernier message et le serveur TFTP n'a pas acquitté
            // --> on renvoie, mais sur Timeout, on signale un transfert OK
            if (sTC.nToSend < TFTP_DATA_HEADERSIZE + sTC.nPktSize  &&  sTC.nRetransmit<TFTP_RETRANSMIT)
                return TransferOK (dNow);
        }

        send (sTC.s, sTC.BufSnd, sTC.nToSend, 0);
        SetTimer (hWnd, WM_CLIENT_ACK, sTC.dwTimeout, NULL);
      Statistics (dNow);
        break;
   } // switch message

return DefWindowProc (hWnd, message, wParam, lParam);
} // TftpProc
Beispiel #5
0
///////////////////////////////////////////////////////
// open the file
///////////////////////////////////////////////////////
BOOL TftpCliOpenFile (void)
{

    // creation fichier ou lecture
    switch (sTC.opcode)
    {
       case TFTP_WRQ :
            sTC.hFile = CreateFile ( sTC.szFile,
                                 GENERIC_READ,
                                 FILE_SHARE_READ,
                                 NULL,
                                 OPEN_EXISTING,
                                 FILE_ATTRIBUTE_ARCHIVE | FILE_FLAG_SEQUENTIAL_SCAN ,
                                 NULL );
            if (sTC.hFile == INVALID_HANDLE_VALUE)
                 return BadEndOfTransfer ("Error opening file %s for reading\nreturn code is %d (%s)", sTC.szFile, GetLastError (), LastErrorText() );
            sTC.dwFileSize = GetFileSize (sTC.hFile, NULL);
            break;

        case TFTP_RRQ :
           sTC.hFile = CreateFile ( sTC.szFile,
                                 GENERIC_WRITE,
                                 0,
                                 NULL,
                                 CREATE_NEW,
                                 FILE_ATTRIBUTE_ARCHIVE | FILE_FLAG_SEQUENTIAL_SCAN ,
                                 NULL );
            if (    sTC.hFile==INVALID_HANDLE_VALUE
                 && GetLastError()==ERROR_FILE_EXISTS
                 && CMsgBox (hTftpClientWnd, "File exists, overwrite it ?", APPLICATION, MB_YESNOCANCEL) == IDYES )
            {
               sTC.hFile = CreateFile ( sTC.szFile,
                                     GENERIC_WRITE,
                                     0,
                                     NULL,
                                     CREATE_ALWAYS,
                                     FILE_ATTRIBUTE_ARCHIVE | FILE_FLAG_SEQUENTIAL_SCAN ,
                                     NULL );
               if (sTC.hFile == INVALID_HANDLE_VALUE)
                  return BadEndOfTransfer ("Error opening file %s for writing\nreturn code is %d (%s)", sTC.szFile, GetLastError (), LastErrorText() );
          }
             break;
        } //switch opcode

return sTC.hFile!=INVALID_HANDLE_VALUE;
} // TftpCliOpenFile
Beispiel #6
0
// bind the thread socket 
static SOCKET BindServiceSocket (const char *name, int type, const char *service, int def_port, int rfc_port, const char *sz_if)
{
struct sockaddr_in SockAddr;
SOCKET             sListenSocket = INVALID_SOCKET;
int                Rc;
struct servent *lpServEnt;

   sListenSocket = socket (AF_INET, type, 0);
   if (sListenSocket == INVALID_SOCKET)
   {
         SVC_ERROR ("Error : Can't create socket\nError %d (%s)", GetLastError(), LastErrorText() );
         return sListenSocket;
   }

   	// REUSEADDR option in order to allow thread to open 69 port
	if (sSettings.bPortOption && lstrcmp (service, "tftp")==0)
	{int True=1;
		Rc = setsockopt (sListenSocket, SOL_SOCKET, SO_REUSEADDR, (char *) & True, sizeof True);
		LogToMonitor (Rc==0 ? "Port %d may be reused" : "setsockopt error", sSettings.Port);
	}

   memset (& SockAddr, 0, sizeof SockAddr);
   SockAddr.sin_family = AF_INET;
   // get the port number: read it from conf or from /etc/services files else take default port
   if (def_port != rfc_port) // config has modified port
		SockAddr.sin_port =  htons ( (short) def_port );
   else
   {	// use /etc/services
		lpServEnt = getservbyname (service, type==SOCK_DGRAM ? "udp" : "tcp") ;
		SockAddr.sin_port =  (lpServEnt != NULL) ?  lpServEnt->s_port : htons ((short) rfc_port);
   }
   // bind the socket to the active interface
   // if no interface has been specified szLocalIP is empty
   // all interfaces are activated.
   SockAddr.sin_addr.s_addr = (sz_if==NULL || sz_if[0]==0) ? INADDR_ANY : inet_addr (sz_if);
   Rc = bind (sListenSocket, (struct sockaddr *) & SockAddr, sizeof SockAddr);
   if (Rc == INVALID_SOCKET)
   {
	   // 3 causes : access violation, socket already bound, bind on an adress 
	   switch (GetLastError ())
	   {
			case WSAEADDRNOTAVAIL :   // 10049
	  		    SVC_ERROR ("Error %d\n%s\n\n"
					   "Tftpd32 tried to bind the %s port\n"
					   "to the interface %s\nwhich is not available for this host\n"
					   "Either remove the %s service or suppress %s interface assignation",
 					    GetLastError (), LastErrorText (),
						name, sz_if, name, sz_if); 
				break;
			case WSAEINVAL :
			case WSAEADDRINUSE :
	  		    SVC_ERROR ("Error %d\n%s\n\n"
					   "Tftpd32 can not bind the %s port\n"
					   "an application is already listening on this port",
 					    GetLastError (), LastErrorText (),
						name );
				break;
			default :
				SVC_ERROR ("Bind error %d\n%s",
 					    GetLastError (), LastErrorText () );
				break;
	   } // switch error type
       closesocket (sListenSocket);
	   LogToMonitor ("bind port to %s port %d failed\n", 
			  inet_ntoa (SockAddr.sin_addr),
			  htons (SockAddr.sin_port) );

        return INVALID_SOCKET;
   }
return   sListenSocket;
} // BindServiceSocket