⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 en_encap.c

📁 基于EthernetIP协议的应用程序,可以读取AB公司Controllogix系列Ethernetip协议PLC数据. 此软件代码可用于工业控制.
💻 C
📖 第 1 页 / 共 5 页
字号:
      **  it can be output as T=>O tag after the FWD_OPEN_REPLY.
      */

      UC_CopyMem( &sa->sTransmit, &map->sMc_addr, sizeof( struct sockaddr_in ) );
   }
   else
   {
      /*
      **  copy the source address to the ECE TO socket save area so
      **  it can be copied to the transport record
      */

      UC_CopyMem( &psConnRecord->sEce.sSa.sTransmit, &psConnRecord->sEce.sAddr,
                  sizeof( struct sockaddr_in ) );

      /*
      **  If a port was specified in the T-O Sockaddr data tag use it, otherwise pick up the default
      */
      if ( sa->sTransmit.sin_port )
      {
         psConnRecord->sEce.sSa.sTransmit.sin_port = sa->sTransmit.sin_port;
      }
      else
      {
         psConnRecord->sEce.sSa.sTransmit.sin_port = htons( CLASS1_UDP_PORT );
      }

      /*
      **  copy the source address in the connection record to the PKTBUF so
      **  it can be output as T=>O tag after the FWD_OPEN_REPLY.
      */
      UC_CopyMem( &sa->sTransmit, &psConnRecord->sEce.sSa.sTransmit, sizeof( struct sockaddr_in ) );
   }

   /*
   **  setup the IP addr and default port so that it can be output as the
   **  O=>T tag after the FWD_OPEN_REPLY.
   */

   UC_SetMem( ( caddr_t ) & sa->sReceive, 0, sizeof( struct sockaddr_in ) );
#ifndef WIN32
	   sa->sReceive.sin_len = sizeof( struct sockaddr_in );
#endif
   sa->sReceive.sin_family = AF_INET;
   sa->sReceive.sin_port = htons( CLASS1_UDP_PORT );
}                                       /* end en_cd_SaveSendToAddress( ) */






/*---------------------------------------------------------------------------
** en_cd_AllocMcastAddress( )
**---------------------------------------------------------------------------
*/

MCAST_P en_cd_AllocMcastAddress( void )
{
   int             i;

   MCAST_P          map = ( MCAST_P ) NULL;

   /*
   ** Check valid flag first to make sure the table has been set up
   */

   if ( sMcast_table.lValid )
   {

      /*
      ** The table is relatively small so a simple linear search is enough
      */

      for ( i = 0, map = &sMcast_table.asMcast[ 0 ]; i < NUM_MCAST_BLOCKS; i++, map++ )
         if ( map->lFree )
         {
            map->lFree = 0;
            break;
         }
   }

   return ( ( i == NUM_MCAST_BLOCKS ) ? ( MCAST_P ) NULL : map );

}                                       /* end en_cd_AllocMcastAddress( ) */




/*---------------------------------------------------------------------------
** en_cd_IFGetConfig( )
**---------------------------------------------------------------------------
*/

INT32  en_cd_IFGetConfig( struct in_addr * psIPAddr,
                  struct in_addr * psSubnet,
                  struct in_addr * psBroadCast )
{

   /*
   ** 1/2/01 jjw
   ** Major change in the way the interface name is retrieved.
   ** Prior version found the interface name through a socket
   ** SIOCGIFCONF call.  However, this call returns interfaces
   ** in a somewhat random order, possibly returning the loopback
   ** interface before the NIC interface.  Alos, in cases where
   ** multiple interfaces existed there is still ambiguity as to
   ** which interface to use.  As a result interfaces will now be
   ** "defined" in ab_cfg.h
   */
   register struct sockaddr_in *psSin;

   INT32           lSockFd;
   INT32           lError;
   struct ifconf   ifc;
   static struct ifreq ifr;
   static struct ifreq *pifr;
   UINT8           buf[ 128 ];

   /*
   ** Get a socket for talking to the network interface driver.
   */

   if ( ( lSockFd = socket( AF_INET, SOCK_DGRAM, 0 ) ) == OE_ERROR )
   {
      return ( lSockFd );
   }

    /*
    ** Here SIOCGIFCONF option is used to obtain the name of the network
    ** interface.
    */

    ifc.ifc_len = sizeof ( buf );
    memset( buf, 0, sizeof buf );
    ifc.ifc_buf = buf;
    if ( ioctl ( lSockFd, SIOCGIFCONF, ( INT32 )&ifc ) == OE_ERROR )
        {
        GS_LogEvent( EN_SOCKET_ERR,
                  OE_SOCKET_ERRNO,
                  0,
                  FATAL );
        }

   pifr = ifc.ifc_req;

   /*
   ** Return IP address if caller requested it
   */

   if ( psIPAddr )
   {
      strncpy( ifr.ifr_name, ETHERNET_INTERFACE_INSTANCE, sizeof( ifr.ifr_name ) );
      if ( ( lError = ioctl( lSockFd, SIOCGIFADDR, ( INT32 ) & ifr ) ) == OE_ERROR )
      {
         return ( lError );
      }
      else
      {
         psSin = ( struct sockaddr_in * ) & ifr.ifr_addr;
         psIPAddr->s_addr = psSin->sin_addr.s_addr;
      }
   }
   if ( psSubnet )
   {
      strncpy( ifr.ifr_name, ETHERNET_INTERFACE_INSTANCE, sizeof( ifr.ifr_name ) );
      if ( ( lError = ioctl( lSockFd, SIOCGIFNETMASK, ( INT32 ) & ifr ) ) == OE_ERROR )
      {
         return ( lError );
      }
      else
      {
         psSubnet->s_addr =
            ( ( struct sockaddr_in * ) & ifr.ifr_addr )->sin_addr.s_addr;
      }
   }
   if ( psBroadCast )
   {
      strncpy( ifr.ifr_name, ETHERNET_INTERFACE_INSTANCE, sizeof( ifr.ifr_name ) );
      if ( ( lError = ioctl( lSockFd, SIOCGIFBRDADDR, ( INT32 ) & ifr ) ) == OE_ERROR )
      {
         return ( lError );
      }
      else
      {
         psSin = ( struct sockaddr_in * ) & ifr.ifr_addr;
         if ( psSin->sin_addr.s_addr != 0 )
            psBroadCast->s_addr = psSin->sin_addr.s_addr;
      }
   }

   /*
   ** All done with getting network parameters.  Close the socket.
   */
   close( lSockFd );

   return ( 0 );
}                                       /* end en_cd_IFGetConfig( ) */



/*---------------------------------------------------------------------------
** en_cd_SendEncapCommand( )
**---------------------------------------------------------------------------
*/

void  en_cd_SendEncapCommand( PKTBUF_P psPktBuf )
{
   UINT32          nStatus;

   EnCdMessageType EnCdMessage;

   /*
   ** Tell how to handle this message
   */

   EnCdMessage.Command = SENDINCORPMESSAGE;

   EnCdMessage.PacketBuf = psPktBuf;

   nStatus = OE_MsgQSend( psPktBuf->sOutputQ,
                          ( char * ) &EnCdMessage.Command,
                          sizeof EnCdMessage,
                          WAIT_FOREVER,
                          MSG_PRI_NORMAL );

   if ( nStatus == OE_ERROR )
   {
      PktBufFree( psPktBuf );
   }

}                                       /* end en_cd_SendEncapCommand */


/*---------------------------------------------------------------------------
** en_cd_ListServicesRequest( )
**---------------------------------------------------------------------------
*/

void  en_cd_ListServicesRequest( ECE * psEce )
{

   PKTBUF_P        psPktbuf;

   if ( psPktbuf = PktBufAlloc( ) )
   {
      psPktbuf->sEncap.sHdr.iEncaph_command = ENCAP_CMD_LISTSERVICES;
      psPktbuf->sEncap.sHdr.lEncaph_status = 0;
      psPktbuf->sEncap.sHdr.lEncaph_session = 0;
      psPktbuf->sEncap.sHdr.alEncaph_context[ 0 ] = 0;
      psPktbuf->sEncap.sHdr.alEncaph_context[ 1 ] = 0;
      psPktbuf->sEncap.sHdr.iEncaph_length = 0;
      psPktbuf->sEncap.lValid = 0;
      psPktbuf->lLength = 0;
   }
   psPktbuf->sOutputQ = psEce->sOutputQ;
   en_cd_SendEncapCommand( psPktbuf );

}                                       /* end en_cd_ListServicesRequest( ) */




/*---------------------------------------------------------------------------
** en_cd_LookupHost( )
**---------------------------------------------------------------------------
*/

UINT32 en_cd_LookupHost( UINT8 * pchDestHost, struct in_addr * IP_Server )
{

   /*
   ** Warning, the hostGetByName call uses a LOT of memory - about 7k! Make sure any
   ** tasks that call this routine have enough stack allocated.  Also note that
   ** name lookup with DNS is potentially very time consuming.  The timeout for
   ** name lookup is about 2 minutes.  This might occur if the routers are
   ** confgured erroniously etc.
   */

   if ( ( IP_Server->s_addr = inet_addr( pchDestHost ) ) == OE_ERROR )
   {
      /*
      ** Look up the name, assumed initially it is in dotted format.
      ** If it wasn't dotted, maybe it's a symbolic name
      */

      IP_Server->s_addr = hostGetByName( pchDestHost );
      if ( IP_Server->s_addr == OE_ERROR )
      {
         GS_LogEvent( EN_UNKNOWN_HOST,
                      0,
                      0,
                      TRIVIAL );

         return OE_ERROR;
      }
   }                                    /* End else not dot notation */
   return OK;

}                                       /* end en_cd_LookupHost( ) */



/*---------------------------------------------------------------------------
** en_cd_HostCompare( )
**---------------------------------------------------------------------------
*/

INT32 en_cd_HostCompare( struct sockaddr_in * Key, ECE * HostEntry )
{

   /*
   ** Comparison routine to find a host entry that might already be opened to the
   ** specified socket
   */

   if ( ( Key->sin_addr.s_addr == HostEntry->sAddr.sin_addr.s_addr ) &&
        ( Key->sin_port == HostEntry->sAddr.sin_port ) )
   {
      return 0;                         /* Found a match */
   }

   return -1;

}                                       /* end en_cd_HostCompare( ) */



/*---------------------------------------------------------------------------
** en_cd_GetOutboundTcpPort( )
**---------------------------------------------------------------------------
*/

UINT32 en_cd_GetOutboundTcpPort( UINT8 * cp, UINT16 * port )
{
   register UINT32 val;
   register UINT32 base;
   register UINT8  c;
   c = *cp;

   /*
   ** Collect number up to NULL Values are specified as for C: 0x=hex, 0=octal,
   ** isdigit=decimal.
   */

   if ( !isdigit( c ) )
      return ( OE_ERROR );
   val = 0;
   base = 10;
   if ( c == '0' )
   {
      c = *++cp;
      if ( c == 'x' || c == 'X' )
         base = 16, c = *++cp;
      else
         base = 8;
   }
   for ( ;; )
   {
      if ( isascii( c ) && isdigit( c ) )
      {
         val = ( val * base ) + ( c - '0' );
         c = *++cp;
      }
      else if ( base == 16 && isascii( c ) && isxdigit( c ) )
      {
         val = ( val << 4 ) |
            ( c + 10 - ( islower( c ) ? 'a' : 'A' ) );
         c = *++cp;
      }
      else
         break;
   }

   /*
   ** Check for trailing characters.
   */

   if ( c != '\0' && ( !isascii( c ) || !isspace( c ) ) )
      return ( OE_ERROR );

   /*
   ** Range check final value
   */

   if ( val > USHRT_MAX )
      return ( OE_ERROR );

   *port = htons( ( unsigned short ) val );
   return ( OK );

}                                       /* end en_cd_GetOutboundTcpPort( ) */



/*---------------------------------------------------------------------------
** en_cd_GetOutboundAddress( )
**---------------------------------------------------------------------------
*/

INT32 en_cd_GetOutboundAddress( UINT8 * tcpip_address, UINT8 * ip_addr, UINT16 * tcp_port )
{

#define TCP_PORT_DELIM	':'

   register UINT8 *s, *d;
   register UINT8  c;

   s = tcpip_address;
   d = ip_addr;

   do
   {
      c = ( unsigned char ) *s++;

      if ( c == TCP_PORT_DELIM )
      {
         *d = '\0';
      }
      else
         *d++ = c;

   } while ( ( c != TCP_PORT_DELIM ) && ( c != '\0' ) );

   if ( c == TCP_PORT_DELIM )
      return ( en_cd_GetOutboundTcpPort( s, tcp_port ) );

   return ( OK );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -