📄 en_encap.c
字号:
** 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 + -