📄 printqos.c
字号:
// Module Name: printqos.c
//
// Description:
// This file contains routines used to print out the QOS data
// structure from top to bottom. This includes the provider
// specific structures. This file contains only support routines.
//
// Compile:
// cl /c printqos.c
//
#include <winsock2.h>
#include <windows.h>
#include <qos.h>
#include <qossp.h>
#include "printqos.h"
#include <stdio.h>
#include <stdlib.h>
#define MAX_INDENT 128
//
// Function: PrintQos
//
// Description:
// This is the top level function. It prints out the sending and
// receiving FLOWSPEC structures and initiates printing of the
// provider specific data.
//
void PrintQos(QOS *pqos)
{
if (pqos == NULL)
return;
printf("Sending Flowspec:\n");
PrintFlowspec(&pqos->SendingFlowspec, 1);
printf("Receiving Flowspec:\n");
PrintFlowspec(&pqos->ReceivingFlowspec, 1);
printf("Provider Specific (len = %d bytes):\n", pqos->ProviderSpecific.len);
PrintProviderSpecific(&pqos->ProviderSpecific, 1);
printf("\n\n");
}
//
// Function: PrintFlowspec
//
// Description:
// Prints the FLOWSPEC structure.
//
void PrintFlowspec(FLOWSPEC *pflow, int indent)
{
char szIndent[MAX_INDENT];
memset(szIndent, ' ', MAX_INDENT);
szIndent[indent * 3] = 0;
if (pflow->TokenRate == QOS_NOT_SPECIFIED)
printf("%sTokenRate = QOS_NOT_SPECIFIED\n", szIndent);
else
printf("%sTokenRate = %d bytes/sec\n", szIndent, pflow->TokenRate);
if (pflow->TokenBucketSize == QOS_NOT_SPECIFIED)
printf("%sTokenBucketSize = QOS_NOT_SPECIFIED\n", szIndent);
else
printf("%sTokenBucketSize = %d bytes\n", szIndent, pflow->TokenBucketSize);
if (pflow->PeakBandwidth == QOS_NOT_SPECIFIED)
printf("%sPeakBandwidth = QOS_NOT_SPECIFIED\n", szIndent);
else
printf("%sPeakBandwidth = %d bytes/sec\n", szIndent, pflow->PeakBandwidth);
if (pflow->Latency == QOS_NOT_SPECIFIED)
printf("%sLatency = QOS_NOT_SPECIFIED\n", szIndent);
else
printf("%sLatency = %d microseconds\n", szIndent, pflow->Latency);
if (pflow->DelayVariation == QOS_NOT_SPECIFIED)
printf("%sDelayVariation = QOS_NOT_SPECIFIED\n", szIndent);
else
printf("%sDelayVariation = %d microseconds\n", szIndent, pflow->DelayVariation);
printf("%sServiceType = %s\n", szIndent, GetServiceTypeStr(pflow->ServiceType));
if (pflow->MaxSduSize == QOS_NOT_SPECIFIED)
printf("%sMaxSduSize = QOS_NOT_SPECIFIED\n", szIndent);
else
printf("%sMaxSduSize = %d bytes\n", szIndent, pflow->MaxSduSize);
if (pflow->MinimumPolicedSize == QOS_NOT_SPECIFIED)
printf("%sMinimumPolicedSize = QOS_NOT_SPECIFIED\n", szIndent);
else
printf("%sMinimumPolicedSize = %d bytes\n", szIndent, pflow->MinimumPolicedSize);
}
//
// Function: PrintProviderSpecific
//
// Description:
// Prints provider specific data. This is done by looking at
// the WSABUF structure. If the len is 0 there is no data.
// Otherwise, the first structure in the data is a QOS_OBJECT_HDR
// so we can cast the pointer as this object and find out
// specifically what object it is. Each header has its length
// so we can find the start of the next QOS_OBJECT_HDR.
//
static void PrintProviderSpecific(WSABUF *provider, int indent)
{
QOS_OBJECT_HDR *objhdr=NULL;
char *bufptr=NULL,
szIndent[MAX_INDENT];
BOOL bDone = FALSE;
DWORD objcount=0;
memset(szIndent, ' ', MAX_INDENT);
szIndent[indent * 3] = 0;
//
// If the buffer is empy, exit
//
if (provider->len == 0)
{
printf("%sEmpty Provider Specific\n", szIndent);
return;
}
// Setup some pointers to the first object header
//
bufptr = (char *)provider->buf;
objhdr = (QOS_OBJECT_HDR *)bufptr;
//
// Loop until we run out of objects
//
while (!bDone)
{
// Decode which object is present and call the appropriate
// print routine.
//
switch (objhdr->ObjectType)
{
case RSVP_OBJECT_STATUS_INFO:
PrintRsvpStatus((RSVP_STATUS_INFO *)objhdr, indent+1);
break;
case RSVP_OBJECT_RESERVE_INFO:
PrintRsvpResv((RSVP_RESERVE_INFO *)objhdr, indent+1);
break;
case RSVP_OBJECT_ADSPEC:
PrintRsvpAdspec((RSVP_ADSPEC *)objhdr, indent+1);
break;
case RSVP_OBJECT_POLICY_INFO:
PrintRsvpPolicy((RSVP_POLICY_INFO *)objhdr, indent+1);
break;
case QOS_OBJECT_PRIORITY:
PrintQosPriority((QOS_PRIORITY *)objhdr, indent+1);
break;
case QOS_OBJECT_SD_MODE:
PrintQosSDMode((QOS_SD_MODE *)objhdr, indent+1);
break;
case QOS_OBJECT_TRAFFIC_CLASS:
PrintQosTrafficClass((QOS_TRAFFIC_CLASS *)objhdr, indent+1);
break;
case QOS_OBJECT_DESTADDR:
PrintQosDestAddr((QOS_DESTADDR *)objhdr, indent+1);
break;
case QOS_OBJECT_END_OF_LIST:
bDone = TRUE;
break;
default:
break;
}
// Update the pointers to the next object
//
bufptr += objhdr->ObjectLength;
objcount += objhdr->ObjectLength;
objhdr = (QOS_OBJECT_HDR *)bufptr;
//
// Check to see if we've exceeded the length of the object
//
if (objcount >= provider->len)
bDone = TRUE;
}
return;
}
//
// Function: GetServiceTypeStr
//
// Description:
// This function is used by the PrintFlowspec call. It simply
// returns a string for the ServiceType as opposed to printing
// the integer value.
//
static char *GetServiceTypeStr(SERVICETYPE type)
{
static char szServiceType[SERVICETYPE_STR_LEN];
if (type == NULL_QOS_TYPE)
{
strcpy(szServiceType, "NULL_QOS_TYPE");
return szServiceType;
}
if ((type & SERVICETYPE_BESTEFFORT) == SERVICETYPE_BESTEFFORT)
strcpy(szServiceType, "SERVICETYPE_BESTEFFORT");
else if ((type & SERVICETYPE_CONTROLLEDLOAD) == SERVICETYPE_CONTROLLEDLOAD)
strcpy(szServiceType, "SERVICETYPE_CONTROLLEDLOAD");
else if ((type & SERVICETYPE_GUARANTEED) == SERVICETYPE_GUARANTEED)
strcpy(szServiceType, "SERVICETYPE_GUARANTEED");
else if ((type & SERVICETYPE_NETWORK_UNAVAILABLE) == SERVICETYPE_NETWORK_UNAVAILABLE)
strcpy(szServiceType, "SERVICETYPE_NETWORK_UNAVAILABLE");
else if ((type & SERVICETYPE_GENERAL_INFORMATION) == SERVICETYPE_GENERAL_INFORMATION)
strcpy(szServiceType, "SERVICETYPE_GENERAL_INFORMATION");
else if ((type & SERVICETYPE_NOCHANGE) == SERVICETYPE_NOCHANGE)
strcpy(szServiceType, "SERVICETYPE_NOCHANGE");
else if ((type & SERVICETYPE_NONCONFORMING) == SERVICETYPE_NONCONFORMING)
strcpy(szServiceType, "SERVICETYPE_NONCONFORMING");
else if ((type & SERVICETYPE_NOTRAFFIC) == SERVICETYPE_NOTRAFFIC)
strcpy(szServiceType, "SERVICETYPE_NOTRAFFIC");
else
strcpy(szServiceType, "Unknown");
if ((type & SERVICE_NO_TRAFFIC_CONTROL) == SERVICE_NO_TRAFFIC_CONTROL)
strcat(szServiceType, " | SERVICE_NO_TRAFFIC_CONTROL");
else if ((type & SERVICE_NO_QOS_SIGNALING) == SERVICE_NO_QOS_SIGNALING)
strcat(szServiceType, " | SERVICE__NO_QOS_SIGNALING");
return szServiceType;
}
//
// Function: PrintRsvpStatus
//
// Description:
// Prints the RSVP_STATUS_INFO object.
//
static void PrintRsvpStatus(RSVP_STATUS_INFO *status, int indent)
{
char szIndent[MAX_INDENT];
memset(szIndent, ' ', MAX_INDENT);
szIndent[indent * 3] = 0;
printf("%sStatus Code = ", szIndent);
switch (status->StatusCode)
{
case WSA_QOS_RECEIVERS: // at least one RESV has arrived
printf("WSA_QOS_RECEIVERS\n");
break;
case WSA_QOS_SENDERS: // at least one PATH has arrived
printf("WSA_QOS_SENDERS\n");
break;
case WSA_QOS_NO_SENDERS: // there are no senders
printf("WSA_QOS_NO_SENDERS\n");
break;
case WSA_QOS_NO_RECEIVERS: // there are no receivers
printf("WSA_QOS_NO_RECEIVERS\n");
break;
case WSA_QOS_REQUEST_CONFIRMED: // Reserve has been confirmed
printf("WSA_QOS_REQUEST_CONFIRMED\n");
break;
case WSA_QOS_ADMISSION_FAILURE: // error due to lack of resources
printf("WSA_QOS_ADMISSION_FAILURE\n");
break;
case WSA_QOS_POLICY_FAILURE: // rejected for admin reasons
printf("WSA_QOS_POLICY_FAILURE\n");
break;
case WSA_QOS_BAD_STYLE: // unknown or conflicting style
printf("WSA_QOS_BAD_STYLE\n");
break;
case WSA_QOS_BAD_OBJECT: // problem with some part of the
// filterspec/providerspecific
// buffer in general
printf("WSA_QOS_BAD_OBJECT\n");
break;
case WSA_QOS_TRAFFIC_CTRL_ERROR: // problem with some part of the
// flowspec
printf("WSA_QOS_TRAFFIC_CTRL_ERROR\n");
break;
case WSA_QOS_GENERIC_ERROR: // general error
printf("WSA_QOS_GENERIC_ERROR\n");
break;
default:
printf("Unknown RSVP StatusCode %lu\n", status->StatusCode);
break;
}
printf("%sExtendedStatus1=%lu\n", szIndent, status->ExtendedStatus1);
printf("%sExtendedStatus2=%lu\n", szIndent, status->ExtendedStatus2);
return;
}
//
// Function: PrintRsvpResv
//
// Description:
// Prints the RSVP_RESERVE_INFO object.
//
static void PrintRsvpResv(RSVP_RESERVE_INFO *resv, int indent)
{
SOCKADDR_IN addr;
DWORD dwIPv6Len,
i, j;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -