349 lines
8 KiB
C++
349 lines
8 KiB
C++
/*
|
|
|
|
Copyright (c) 1997-1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
sdpconn.cpp
|
|
|
|
Abstract:
|
|
|
|
|
|
Author:
|
|
|
|
*/
|
|
|
|
#include "sdppch.h"
|
|
|
|
#include "sdpconn.h"
|
|
#include "sdpltran.h"
|
|
|
|
|
|
|
|
|
|
// limited character strings
|
|
const CHAR *LIMITED_NETWORK_TYPES[] = {INTERNET_STRING};
|
|
const BYTE NUM_NETWORK_TYPES = sizeof(LIMITED_NETWORK_TYPES)/sizeof(CHAR *);
|
|
|
|
const CHAR *LIMITED_ADDRESS_TYPES[] = {IP4_STRING};
|
|
const BYTE NUM_ADDRESS_TYPES = sizeof(LIMITED_ADDRESS_TYPES)/sizeof(CHAR *);
|
|
|
|
|
|
|
|
// line transition states
|
|
enum CONNECTION_TRANSITION_STATES
|
|
{
|
|
CONNECTION_START,
|
|
CONNECTION_NETWORK_TYPE,
|
|
CONNECTION_ADDRESS_TYPE,
|
|
CONNECTION_MCAST_ADDRESS,
|
|
CONNECTION_UCAST_ADDRESS,
|
|
CONNECTION_TTL,
|
|
CONNECTION_TTL_NUM_ADDRESSES,
|
|
CONNECTION_NUM_ADDRESSES
|
|
};
|
|
|
|
|
|
|
|
// table for connection line transitions
|
|
|
|
const LINE_TRANSITION g_ConnectionStartTransitions[] = {
|
|
{CHAR_BLANK, CONNECTION_NETWORK_TYPE }
|
|
};
|
|
|
|
const LINE_TRANSITION g_ConnectionNetworkTypeTransitions[] = {
|
|
{CHAR_BLANK, CONNECTION_ADDRESS_TYPE }
|
|
};
|
|
|
|
const LINE_TRANSITION g_ConnectionAddressTypeTransitions[] = {
|
|
{CHAR_BACK_SLASH, CONNECTION_MCAST_ADDRESS},
|
|
{CHAR_NEWLINE, CONNECTION_UCAST_ADDRESS}
|
|
};
|
|
|
|
const LINE_TRANSITION g_ConnectionMcastAddressTransitions[] = {
|
|
{CHAR_BACK_SLASH, CONNECTION_TTL_NUM_ADDRESSES},
|
|
{CHAR_NEWLINE, CONNECTION_TTL }
|
|
};
|
|
|
|
|
|
/* no transitions */
|
|
const LINE_TRANSITION *g_ConnectionUcastAddressTransitions = NULL;
|
|
|
|
|
|
/* no transitions */
|
|
const LINE_TRANSITION *g_ConnectionTtlTransitions = NULL;
|
|
|
|
|
|
const LINE_TRANSITION g_ConnectionTtlNumAddressesTransitions[] ={
|
|
{CHAR_NEWLINE, CONNECTION_NUM_ADDRESSES}
|
|
};
|
|
|
|
|
|
/* no transitions */
|
|
const LINE_TRANSITION *g_ConnectionNumAddressesTransitions = NULL;
|
|
|
|
|
|
LINE_TRANSITION_INFO g_ConnectionTransitionInfo[] = {
|
|
LINE_TRANSITION_ENTRY(CONNECTION_START, g_ConnectionStartTransitions),
|
|
|
|
LINE_TRANSITION_ENTRY(CONNECTION_NETWORK_TYPE, g_ConnectionNetworkTypeTransitions),
|
|
|
|
LINE_TRANSITION_ENTRY(CONNECTION_ADDRESS_TYPE, g_ConnectionAddressTypeTransitions),
|
|
|
|
LINE_TRANSITION_ENTRY(CONNECTION_MCAST_ADDRESS, g_ConnectionMcastAddressTransitions),
|
|
|
|
LINE_TRANSITION_ENTRY(CONNECTION_UCAST_ADDRESS, g_ConnectionUcastAddressTransitions),
|
|
|
|
LINE_TRANSITION_ENTRY(CONNECTION_TTL, g_ConnectionTtlTransitions),
|
|
|
|
LINE_TRANSITION_ENTRY(CONNECTION_TTL_NUM_ADDRESSES, g_ConnectionTtlNumAddressesTransitions),
|
|
|
|
LINE_TRANSITION_ENTRY(CONNECTION_NUM_ADDRESSES, g_ConnectionNumAddressesTransitions)
|
|
};
|
|
|
|
|
|
|
|
|
|
SDP_LINE_TRANSITION g_ConnectionTransition(
|
|
g_ConnectionTransitionInfo,
|
|
sizeof(g_ConnectionTransitionInfo)/sizeof(LINE_TRANSITION_INFO)
|
|
);
|
|
|
|
|
|
|
|
SDP_CONNECTION::SDP_CONNECTION(
|
|
)
|
|
: SDP_VALUE(SDP_INVALID_CONNECTION_FIELD, CONNECTION_STRING, &g_ConnectionTransition),
|
|
m_NetworkType(LIMITED_NETWORK_TYPES, NUM_NETWORK_TYPES),
|
|
m_AddressType(LIMITED_ADDRESS_TYPES, NUM_ADDRESS_TYPES)
|
|
{
|
|
m_NumAddresses.SetValue(1);
|
|
}
|
|
|
|
|
|
|
|
void
|
|
SDP_CONNECTION::InternalReset(
|
|
)
|
|
{
|
|
m_NetworkType.Reset();
|
|
m_AddressType.Reset();
|
|
m_StartAddress.Reset();
|
|
m_Ttl.Reset();
|
|
m_NumAddresses.Reset();
|
|
}
|
|
|
|
|
|
|
|
HRESULT
|
|
SDP_CONNECTION::SetConnection(
|
|
IN BSTR StartAddress,
|
|
IN ULONG NumAddresses,
|
|
IN BYTE Ttl
|
|
)
|
|
{
|
|
// validate the address
|
|
HRESULT ToReturn = m_StartAddress.SetAddress(StartAddress);
|
|
if ( FAILED(ToReturn) )
|
|
{
|
|
return ToReturn;
|
|
}
|
|
|
|
// if multicast, valid number of addresses and ttl values are expected
|
|
// set the num addresses and
|
|
if ( m_StartAddress.IsMulticast() )
|
|
{
|
|
if ( (0 == NumAddresses) || (0 == Ttl) )
|
|
{
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
m_NumAddresses.SetValueAndFlag(NumAddresses);
|
|
m_Ttl.SetValueAndFlag(Ttl);
|
|
}
|
|
else // invalidate the num addresses and ttl fields
|
|
{
|
|
m_NumAddresses.Reset();
|
|
m_Ttl.Reset();
|
|
}
|
|
|
|
// if the network type is not valid, parse in the default IN network type
|
|
if ( !m_NetworkType.IsValid() )
|
|
{
|
|
if ( !m_NetworkType.ParseToken("IN") )
|
|
{
|
|
return HRESULT_FROM_ERROR_CODE(GetLastError());
|
|
}
|
|
}
|
|
|
|
// if the address type is not valid, parse in the default IP4 address type
|
|
if ( !m_AddressType.IsValid() )
|
|
{
|
|
if ( !m_AddressType.ParseToken("IP4") )
|
|
{
|
|
return HRESULT_FROM_ERROR_CODE(GetLastError());
|
|
}
|
|
}
|
|
|
|
// clear the field and separator arrays
|
|
m_FieldArray.RemoveAll();
|
|
m_SeparatorCharArray.RemoveAll();
|
|
|
|
// fill in the field, separator char arrays with network/address type and
|
|
// the address, if required
|
|
if ( 0 == m_FieldArray.GetSize() )
|
|
{
|
|
try
|
|
{
|
|
m_FieldArray.SetAtGrow(0, &m_NetworkType);
|
|
m_SeparatorCharArray.SetAtGrow(0, CHAR_BLANK);
|
|
|
|
m_FieldArray.SetAtGrow(1, &m_AddressType);
|
|
m_SeparatorCharArray.SetAtGrow(1, CHAR_BLANK);
|
|
|
|
m_FieldArray.SetAtGrow(2, &m_StartAddress);
|
|
}
|
|
catch(...)
|
|
{
|
|
m_FieldArray.RemoveAll();
|
|
m_SeparatorCharArray.RemoveAll();
|
|
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
|
|
ASSERT(3 <= m_FieldArray.GetSize());
|
|
|
|
// if multicast address, fill in the next three fields
|
|
if ( m_StartAddress.IsMulticast() )
|
|
{
|
|
if ( 4 > m_FieldArray.GetSize() )
|
|
{
|
|
// ZoltanS bugfix: m_Ttl and m_NumAddresses were reversed below!
|
|
|
|
try
|
|
{
|
|
m_SeparatorCharArray.SetAtGrow(2, CHAR_BACK_SLASH);
|
|
|
|
m_FieldArray.SetAtGrow(3, &m_Ttl);
|
|
m_SeparatorCharArray.SetAtGrow(3, CHAR_BACK_SLASH);
|
|
|
|
m_FieldArray.SetAtGrow(4, &m_NumAddresses);
|
|
m_SeparatorCharArray.SetAtGrow(4, CHAR_NEWLINE);
|
|
}
|
|
catch(...)
|
|
{
|
|
m_FieldArray.RemoveAll();
|
|
m_SeparatorCharArray.RemoveAll();
|
|
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
}
|
|
|
|
ASSERT(5 == m_FieldArray.GetSize());
|
|
}
|
|
else
|
|
{
|
|
// else, unicast, fill in the next field and remove from the next two
|
|
try
|
|
{
|
|
m_SeparatorCharArray.SetAtGrow(2, CHAR_NEWLINE);
|
|
}
|
|
catch(...)
|
|
{
|
|
m_FieldArray.RemoveAll();
|
|
m_SeparatorCharArray.RemoveAll();
|
|
|
|
return E_OUTOFMEMORY;
|
|
}
|
|
|
|
if ( 4 <= m_FieldArray.GetSize() )
|
|
{
|
|
ASSERT(5 == m_FieldArray.GetSize());
|
|
|
|
m_FieldArray.RemoveAt(3);
|
|
m_SeparatorCharArray.RemoveAt(3);
|
|
|
|
m_FieldArray.RemoveAt(4);
|
|
m_SeparatorCharArray.RemoveAt(4);
|
|
}
|
|
|
|
ASSERT(3 == m_FieldArray.GetSize());
|
|
}
|
|
|
|
// if the address is not a multicast address, the other params are ignored
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOL
|
|
SDP_CONNECTION::GetField(
|
|
OUT SDP_FIELD *&Field,
|
|
OUT BOOL &AddToArray
|
|
)
|
|
{
|
|
// add in all cases by default
|
|
AddToArray = TRUE;
|
|
|
|
switch(m_LineState)
|
|
{
|
|
case CONNECTION_NETWORK_TYPE:
|
|
{
|
|
Field = &m_NetworkType;
|
|
}
|
|
|
|
break;
|
|
|
|
case CONNECTION_ADDRESS_TYPE:
|
|
{
|
|
Field = &m_AddressType;
|
|
}
|
|
|
|
break;
|
|
|
|
case CONNECTION_MCAST_ADDRESS:
|
|
{
|
|
m_StartAddress.SetMulticast(TRUE);
|
|
Field = &m_StartAddress;
|
|
}
|
|
|
|
break;
|
|
|
|
case CONNECTION_UCAST_ADDRESS:
|
|
{
|
|
m_StartAddress.SetMulticast(FALSE);
|
|
Field = &m_StartAddress;
|
|
}
|
|
|
|
break;
|
|
|
|
case CONNECTION_TTL:
|
|
case CONNECTION_TTL_NUM_ADDRESSES:
|
|
{
|
|
Field = &m_Ttl;
|
|
}
|
|
|
|
break;
|
|
|
|
case CONNECTION_NUM_ADDRESSES:
|
|
{
|
|
Field = &m_NumAddresses;
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
{
|
|
SetLastError(m_ErrorCode);
|
|
return FALSE;
|
|
}
|
|
|
|
break;
|
|
};
|
|
|
|
return TRUE;
|
|
}
|
|
|