📄 en_encap.c
字号:
sEncapStats.lRepliesReceivedErrs++;
PktBufFree( psPktBuf );
break;
/*
** Not sure how this could happen, but we should crash on the error.
*/
default:
GS_LogEvent( CD_UNSUPPORTED_CONFIG_REQUEST, /* Incorrect type code specified in ECE */
ECE_TYPE( psEce->sEid ),
0,
FATAL );
break;
}
}
/*---------------------------------------------------------------------------
** en_cd_CreateMcastTable( )
**---------------------------------------------------------------------------
*/
void en_cd_CreateMcastTable( struct in_addr * NET_ipaddr, struct in_addr * NET_subnet )
{
MCAST_P map;
UINT32 netmask;
UINT32 ipaddr;
INT32 i;
UINT32 host;
UINT32 ma;
ipaddr = htonl( NET_ipaddr->s_addr );
/*
** If subnet mask is set, then net and hosts are determined by the mask
*/
if ( NET_subnet->s_addr )
netmask = htonl( NET_subnet->s_addr );
else
{
if ( IN_CLASSA( ipaddr ) )
netmask = IN_CLASSA_NET;
else if ( IN_CLASSB( ipaddr ) )
netmask = IN_CLASSB_NET;
else
netmask = IN_CLASSC_NET;
}
host = ipaddr & ( ~netmask );
/*
** Mask host number, shift and add to base address.
*/
ma = CIP_MCAST_BASE + ( ( host & CIP_MCAST_HMASK ) << CIP_MCAST_BSHIFT );
for ( i = 0, map = &sMcast_table.asMcast[ 0 ]; i < NUM_MCAST_BLOCKS; i++, map++, ma++ )
{
map->lFree = 1;
UC_SetMem( ( caddr_t ) &map->sMc_addr, 0, sizeof( struct sockaddr_in ) );
#ifndef WIN32
map->sMc_addr.sin_len = sizeof( struct sockaddr_in );
#endif
map->sMc_addr.sin_family = AF_INET;
map->sMc_addr.sin_port = htons( CLASS1_UDP_PORT );
map->sMc_addr.sin_addr.s_addr = htonl( ma ); /* ma is host order, put in net order */
}
sMcast_table.lValid = 1;
}
/*---------------------------------------------------------------------------
** en_cd_InitTargetData( )
**---------------------------------------------------------------------------
*/
void en_cd_InitTargetData( void )
{
struct in_addr NET_ipaddr; /* IP address assigned to the module */
struct in_addr NET_subnet; /* IP subnet mask ( if any ) assigned to
* the module */
UINT32 nStatus;
INT32 nNameLen;
u_char *p;
list_target_data.sS.s_sock.iSin_family = htons( AF_INET );
list_target_data.sS.s_sock.iSin_port = htons( lEncapServerPort );
/*
** Default IP address on primary interface
*/
list_target_data.sS.s_sock.lSin_addr = htonl( 0 );
en_cd_IFGetConfig( &NET_ipaddr, &NET_subnet, 0 );
list_target_data.sS.s_sock.lSin_addr = NET_ipaddr.s_addr;
/*
** Ugly but........
*/
nStatus = gethostname( list_target_data.sS.achS_name, sizeof list_target_data.sS.achS_name );
list_target_data.sS.achS_name[ sizeof( list_target_data.sS.achS_name ) - 1 ] = '\0';
nNameLen = strlen( list_target_data.sS.achS_name ) + 1; /* Include the NULL */
p = ( u_char * ) & list_target_data.sS.s_sock.lSin_addr;
sprintf( IPAddress, "%d.%d.%d.%d", p[ 0 ], p[ 1 ], p[ 2 ], p[ 3 ] );
if ( ( nStatus != OK ) || ( nNameLen < 2 ) || ( nNameLen >= sizeof( list_target_data.sS.achS_name ) ) )
{
/*
** no name assigned ? Use the IP address
*/
sprintf( &list_target_data.sS.achS_name[ 0 ], "%d.%d.%d.%d", p[ 0 ], p[ 1 ], p[ 2 ], p[ 3 ] );
list_target_data.sS.achS_name[ sizeof( list_target_data.sS.achS_name ) - 1 ] = '\0';
}
/*
** create the multicast table based on IP address
*/
en_cd_CreateMcastTable( &NET_ipaddr, &NET_subnet );
}
#undef PROC
#define PROC "en_cd_ListTargetsReceived"
/*---------------------------------------------------------------------------
** en_cd_ListTargetsReceived( )
**---------------------------------------------------------------------------
*/
void en_cd_ListTargetsReceived( ECE * psEce, PKTBUF_P psPktBuf )
{
ENCAPH *psEncapHdr = ( ENCAPH * ) ( &psPktBuf->sEncap.sHdr );
switch ( ECE_TYPE( psEce->sEid ) )
{
/*
** Process a request from a client for target ( server ) information
*/
case ECE_TYPE_INBOUND:
sEncapStats.lCommandsReceived++;
/*
** Check length of command specific data. There shouldn't be any.
*/
if ( psEncapHdr->iEncaph_length != 0 )
{
sEncapStats.lErrBadData++;
en_cd_EncapErrorReply( psPktBuf, ENCAP_E_BADDATA, NULL, 0 );
}
else
{
if ( psEncapHdr->lEncaph_status == ENCAP_E_SUCCESS )
{
UC_CopyMem( ( caddr_t ) &psPktBuf->abData[ 0 ], ( caddr_t ) &list_target_data,
sizeof( list_target_data ) );
psPktBuf->lLength = sizeof( list_target_data );
psPktBuf->sEncap.sObj_list.iO_count = 1;
psPktBuf->sEncap.lValid = PKTBUF_ENCAPV_OBJ;
psEncapHdr->lEncaph_status = 0;
psEncapHdr->iEncaph_length = ENCAP_OBJ_LIST_SIZE + psPktBuf->lLength;
sEncapStats.lRepliesSent++;
en_cd_SendEncapCommand( psPktBuf );
}
else
PktBufFree( psPktBuf );
}
break;
/*
** Silently ignore the command
*/
case ECE_TYPE_OUTBOUND:
if ( psEncapHdr->lEncaph_status == ENCAP_E_SUCCESS )
sEncapStats.lRepliesReceived++;
else
sEncapStats.lRepliesReceivedErrs++;
PktBufFree( psPktBuf );
break;
/*
** Not sure how this could happen, but we should crash on the error.
*/
default:
GS_LogEvent( CD_UNSUPPORTED_CONFIG_REQUEST, /* Incorrect type code specified in ECE */
ECE_TYPE( psEce->sEid ),
0,
FATAL );
break;
}
}
#undef PROC
#define PROC "en_cd_ListIdentityReceived"
/*---------------------------------------------------------------------------
** en_cd_ListIdentityReceived( )
**---------------------------------------------------------------------------
*/
extern struct id_DataType id_s;
extern INT32 lEncapServerPort;
void en_cd_ListIdentityReceived( ECE * psEce, PKTBUF_P psPktBuf )
{
ENCAPH *psEncapHdr = ( ENCAPH * ) ( &psPktBuf->sEncap.sHdr );
int aHdrSize;
int aFSDataSize;
int aProductNameSize;
typedef struct s_list_identity_data_header{
UINT16 ItemTypeCode;
UINT16 ItemLength;
}s_list_identity_data_header;
typedef struct s_list_identity_data_without_ProductName{
UINT16 EncapsulationProtocolVersion;
/* struct s_SocketAddress{ */
INT16 sin_family;
UINT16 sin_port;
UINT32 sin_addr;
INT8 sin_zero[8];
/* }SocketAddress; */
UINT16 VendorId;
UINT16 DeviceType;
UINT16 ProductCode;
INT8 Revision[2];
UINT16 Status;
UINT32 SerialNumber;
}s_list_identity_data_without_ProductName;
struct s_list_identity_data{
s_list_identity_data_header Hdr;
s_list_identity_data_without_ProductName FSData;
INT8 ProductNameSize;
INT8 ProductName[128+1];
}list_identity_data;
switch ( ECE_TYPE( psEce->sEid ) )
{
/*
** Process a request from a client for a list of our identities
*/
case ECE_TYPE_INBOUND:
sEncapStats.lCommandsReceived++;
/*
** Check length of command specific data. There shouldn't be any.
*/
if ( psEncapHdr->iEncaph_length != 0 )
{
sEncapStats.lErrBadData++;
en_cd_EncapErrorReply( psPktBuf, ENCAP_E_BADDATA, NULL, 0 );
}
else
{
if ( psEncapHdr->lEncaph_status == ENCAP_E_SUCCESS )
{
/* list services
** UC_CopyMem( ( caddr_t ) &psPktBuf->abData[ 0 ], ( caddr_t ) &list_services_data,
** sizeof( list_services_data ) );
**
** psPktBuf->sEncap.sObj_list.iO_count = 1;
** psPktBuf->lLength = sizeof( list_services_data );
** psPktBuf->sEncap.lValid = PKTBUF_ENCAPV_OBJ;
** psEncapHdr->lEncaph_status = 0;
** psEncapHdr->iEncaph_length = ENCAP_OBJ_LIST_SIZE + psPktBuf->lLength;
** list interfaces
** psPktBuf->sEncap.sObj_list.iO_count = 0; /* Currently not implemented *//*
** psPktBuf->lLength = psPktBuf->sEncap.sObj_list.iO_count * ENCAP_OBJ_TARGET_SIZE;
** psPktBuf->sEncap.lValid = PKTBUF_ENCAPV_OBJ;
** psEncapHdr->lEncaph_status = 0;
** psEncapHdr->iEncaph_length = ENCAP_OBJ_LIST_SIZE + psPktBuf->lLength;
**
** list targets
** UC_CopyMem( ( caddr_t ) &psPktBuf->abData[ 0 ], ( caddr_t ) &list_target_data,
** sizeof( list_target_data ) );
**
** psPktBuf->sEncap.sObj_list.iO_count = 1;
** psPktBuf->lLength = sizeof( list_target_data );
** psPktBuf->sEncap.lValid = PKTBUF_ENCAPV_OBJ;
** psEncapHdr->lEncaph_status = 0;
** psEncapHdr->iEncaph_length = ENCAP_OBJ_LIST_SIZE + psPktBuf->lLength;
*/
/* ! */
aHdrSize = sizeof( list_identity_data.Hdr );
aFSDataSize = sizeof( list_identity_data.FSData );
aProductNameSize = strlen( id_s.abProductName );
/* ! */
memset( &list_identity_data, 0, sizeof( list_identity_data ) );
list_identity_data.Hdr.ItemTypeCode = 0x0c;
list_identity_data.Hdr.ItemLength = aFSDataSize + 1 + aProductNameSize; /* ! size of items that follows */
list_identity_data.FSData.EncapsulationProtocolVersion = ENCAP_PROTOCOL_VERSION;
list_identity_data.FSData.sin_family = htons(AF_INET);
list_identity_data.FSData.sin_port = htons(lEncapServerPort);
list_identity_data.FSData.sin_addr = list_target_data.sS.s_sock.lSin_addr;
/* list_identity_data.FSData.sin_zero = ; */
list_identity_data.FSData.VendorId = id_s.iVendorId;
list_identity_data.FSData.DeviceType = id_s.iProductType;
list_identity_data.FSData.ProductCode = id_s.iProductCode;
list_identity_data.FSData.Revision[0] = id_s.bMajorRev;
list_identity_data.FSData.Revision[1] = id_s.bMinorRev;
list_identity_data.FSData.Status = id_s.iStatus;
list_identity_data.FSData.SerialNumber = id_s.lSerialNumber;
list_identity_data.ProductNameSize = aProductNameSize;
strcpy(list_identity_data.ProductName, id_s.abProductName );
/* ! */
UC_CopyMem( ( caddr_t ) &psPktBuf->abData[ 0 ], ( caddr_t ) &list_identity_data, aHdrSize+aFSDataSize+1+aProductNameSize );
psPktBuf->sEncap.sObj_list.iO_count = 1;
psPktBuf->lLength = aHdrSize+aFSDataSize+1+aProductNameSize;
psPktBuf->sEncap.lValid = PKTBUF_ENCAPV_OBJ;
psEncapHdr->lEncaph_status = 0;
psEncapHdr->iEncaph_length = ENCAP_OBJ_LIST_SIZE + psPktBuf->lLength;
sEncapStats.lRepliesSent++;
en_cd_SendEncapCommand( psPktBuf );
}
else
PktBufFree( psPktBuf );
}
break;
/*
** Silently ignore the command...
*/
case ECE_TYPE_OUTBOUND:
if ( psEncapHdr->lEncaph_status == ENCAP_E_SUCCESS )
sEncapStats.lRepliesReceived++;
else
sEncapStats.lRepliesReceivedErrs++;
PktBufFree( psPktBuf );
break;
/*
** Not sure how this could happen, but we should crash on the error.
*/
default:
GS_LogEvent( CD_UNSUPPORTED_CONFIG_REQUEST, /* Incorrect type code specified in ECE */
ECE_TYPE( psEce->sEid ),
0,
FATAL );
break;
}
}
#undef PROC
#define PROC "en_cd_RegisterReceived"
/*---------------------------------------------------------------------------
** en_cd_RegisterReceived( )
**---------------------------------------------------------------------------
*/
void en_cd_RegisterReceived( ECE * psEce, PKTBUF_P psPktBuf )
{
ENCAPH *psEncapHdr = ( ENCAPH * ) ( &psPktBuf->sEncap.sHdr );
EnCdMessageType EnCdMessage;
OE_Q_ID sOutputQ;
switch ( ECE_TYPE( psEce->sEid ) )
{
/*
** Process a request from a client to register
*/
case ECE_TYPE_INBOUND:
{
void *data = NULL;
INT32 data_len = 0;
ENCAP_RC_DATA *rc = psPktBuf->pData;
INT32 status = ENCAP_E_SUCCESS;
sEncapStats.lCommandsReceived++;
if ( psEncapHdr->lEncaph_status != ENCAP_E_SUCCESS )
{
PktBufFree( psPktBuf );
return;
}
do
{
/*
** Check the length of command specific data. If the length is
** correct, assume that the length in the ENCAP header matches the
** length for the PKTBUF data area.
*/
if ( psEncapHdr->iEncaph_length != ENCAP_RC_DATA_SIZE )
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -