Example on how to set DSCP using QOS_DS_CLASS
I would thank anyone who could post a complete code example or point me to a place where I can get one.
Thank you.
I would thank anyone who could post a complete code example or point me to a place where I can get one.
Thank you.
// Initialize call back functions.
TCI_CLIENT_FUNC_LIST QoSFunctions;
QoSFunctions.ClAddFlowCompleteHandler = NULL;
QoSFunctions.ClDeleteFlowCompleteHandler = NULL;
QoSFunctions.ClModifyFlowCompleteHandler = NULL;
QoSFunctions.ClNotifyHandler = (TCI_NOTIFY_HANDLER)MyClNotifyHandler;
//Register call back functions with Traffic control interface.
long result = TcRegisterClient(CURRENT_TCI_VERSION, NULL, &QoSFunctions , &ClientHandle);
if (result!= NO_ERROR)
{
m_pLogFile->LogError(_T("Error number %d reported by TcRegisterClient"),MODULE,result);
return E_FAIL;
}
TC_IFC_DESCRIPTOR InterfaceBuffer[20];
PTC_IFC_DESCRIPTOR pInterfaceBuffer = &InterfaceBuffer[0];
ULONG BufferSize = 20* sizeof(TC_IFC_DESCRIPTOR);
// Find traffic control enabled interfaces on the cmachine
//Enumerate the available protocols
result = TcEnumerateInterfaces (ClientHandle, &BufferSize,pInterfaceBuffer);
if (result != NO_ERROR)
{
m_pLogFile->LogError(_T("Error number %d reported by TcEnumerateInterfaces"),MODULE,result);
return E_FAIL;
}
if (BufferSize == 0)
{
m_pLogFile->LogError(_T("no traffic control interfaces are available. QOS Packet Scheduler is not installed"),MODULE);
return E_FAIL;
}
// TCHAR interfaceName[500];
//get the first interface name that supports Traffic Control
// function maps a wide-character string to a new character string
//WideCharToMultiByte(CP_UTF8,0,InterfaceBuffer[0].pInterfaceName, -1,interfaceName,sizeof(interfaceName), 0, 0 );
m_pLogFile->LogInfo(_T("Using traffic control interface: %s"),MODULE,InterfaceBuffer[0].pInterfaceName);
// The TcOpenInterface function identifies and opens an interface based on its text
// string, which is available from a call to TcEnumerateInterfaces
result = TcOpenInterface(InterfaceBuffer[0].pInterfaceName, ClientHandle, NULL, &ifcHandle );
if (result!= NO_ERROR)
{
m_pLogFile->LogError(_T("Error number %d reported by TcOpenInterface"),MODULE,result);
return E_FAIL;
}
// Creating of Traffic flow headers
int curSize = sizeof (TC_GEN_FLOW )+ sizeof (QOS_DS_CLASS) + sizeof(QOS_OBJECT_HDR);
char *bufFlow = new char[curSize];
PTC_GEN_FLOW newFlow = ( PTC_GEN_FLOW )bufFlow;
// Create the new temp flow.
LPQOS_OBJECT_HDR objHdr = NULL;
//Set the Flow Spec
newFlow->ReceivingFlowspec.DelayVariation = QOS_NOT_SPECIFIED;
newFlow->ReceivingFlowspec.Latency = QOS_NOT_SPECIFIED;
newFlow->ReceivingFlowspec.MaxSduSize = QOS_NOT_SPECIFIED;
newFlow->ReceivingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED;
newFlow->ReceivingFlowspec.PeakBandwidth = QOS_NOT_SPECIFIED;
newFlow->ReceivingFlowspec.ServiceType = SERVICETYPE_BESTEFFORT;
newFlow->ReceivingFlowspec.TokenBucketSize = QOS_NOT_SPECIFIED;
newFlow->ReceivingFlowspec.TokenRate =QOS_NOT_SPECIFIED;
newFlow->SendingFlowspec.DelayVariation = QOS_NOT_SPECIFIED;
newFlow->SendingFlowspec.Latency = QOS_NOT_SPECIFIED;
newFlow->SendingFlowspec.MaxSduSize = QOS_NOT_SPECIFIED;
newFlow->SendingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED;
newFlow->SendingFlowspec.PeakBandwidth = QOS_NOT_SPECIFIED;
newFlow->SendingFlowspec.ServiceType=SERVICETYPE_BESTEFFORT;
newFlow->SendingFlowspec.TokenBucketSize = QOS_NOT_SPECIFIED;
newFlow->SendingFlowspec.TokenRate = QOS_NOT_SPECIFIED;
newFlow->TcObjectsLength =sizeof QOS_DS_CLASS + sizeof QOS_OBJECT_HDR;
//DSCP
LPQOS_DS_CLASS pQOSClass = (LPQOS_DS_CLASS)(&(newFlow->TcObjects[0]));
pQOSClass->ObjectHdr.ObjectType = QOS_OBJECT_DS_CLASS;
pQOSClass->ObjectHdr.ObjectLength = sizeof QOS_DS_CLASS;
pQOSClass->DSField = ulDSCPValue;
objHdr = (LPQOS_OBJECT_HDR)((char *)&(newFlow->TcObjects[0]) + sizeof(QOS_DS_CLASS));
// Set the end of the list
objHdr->ObjectType = QOS_OBJECT_END_OF_LIST;
objHdr->ObjectLength = sizeof QOS_OBJECT_HDR;
// adds a new flow on the specified interface. The flow is like a channel,
// that determines how to shape the traffic if it tunnelled through it.
int retCode = TcAddFlow(ifcHandle, /*ClientHandle*/NULL, 0, newFlow, &flowHandle );
if(retCode != NO_ERROR)
{
m_pLogFile->LogError(_T("Error %d reported by TcAddFlow"),MODULE,retCode);
return E_FAIL;
}
// Create a filter. All traffic matching the filter will pass through the flow
TC_GEN_FILTER GenericFilter;
IP_PATTERN Pattern, Mask;
memset(&Pattern,0,sizeof(IP_PATTERN));
memset(&Mask,0,sizeof(IP_PATTERN));
GenericFilter.AddressType = NDIS_PROTOCOL_ID_TCP_IP; // Protocol stack is TCP/IP
GenericFilter.PatternSize = sizeof(IP_PATTERN);
GenericFilter.Pattern = &Pattern; // pattern to match, defined below
GenericFilter.Mask = &Mask;
// Filter pattern. This is where you can tweak the flow filter parameters
// configured to match on all outgoing UDP packets.
Pattern.Reserved1 = 0;
Pattern.Reserved2 = 0;
Pattern.SrcAddr = inet_addr("0.0.0.0"); //IP_ADDRESS;
Pattern.DstAddr = inet_addr(W2CA(m_IPAddress.m_str)); //IP_ADDRESS;
Pattern.tcSrcPort = 0;
Pattern.tcDstPort = htons(m_PortNumber);
Pattern.ProtocolId = IPPROTO_UDP;
Pattern.Reserved3[0] = 0;
Pattern.Reserved3[1] = 0;
Pattern.Reserved3[2] = 0;
// Patterns mask
Mask.Reserved1 = 0;
Mask.Reserved2 = 0;
Mask.SrcAddr = htonl( 0 );
Mask.DstAddr = 0xFFFFFFFF;
Mask.tcSrcPort = 0;
Mask.tcDstPort = 0xFFFF;
Mask.ProtocolId = 0xFF;
Mask.Reserved3[0] = 0;
Mask.Reserved3[1] = 0;
Mask.Reserved3[2] = 0;
// Add filter to the flow. This point onwards all traffic matching the filter, will pass through the flow.
retCode = TcAddFilter(flowHandle, &GenericFilter, &FilterHandle);
if (retCode!= NO_ERROR)
{
m_pLogFile->LogError(_T("Error %d reported by in TcAddFilter"),MODULE,retCode);
return E_FAIL;
}
m_pLogFile->LogInfo(_T("Added traffic control filter for IP Address: %s DSCP value: %d"),MODULE,m_IPAddress.m_str,ulDSCPValue);