SAMINFO.H
/*++ 
 
Copyright (c) 1997  Microsoft Corporation 
 
Module Name: 
 
    sample\saminfo.h 
 
Abstract: 
    Public defines and structures exposed by the Sample Routing Protocol DLL 
 
Revision History: 
 
 
--*/ 
 
#ifndef __SAMPLE_INFO_H__ 
#define __SAMPLE_INFO_H__ 
 
#define ANY_SIZE    1 
 
#define SAMPLE_PROTOCOL_NAME        "Sample IP Routing Protocol" 
 
// 
// The IP Protocol number for this protocol. This is assuming that this  
// protocol runs over Raw IP 
// 
 
#define SAMPLE_PROTOCOL_ROUTE_ID    100 
 
// 
// Assuming this is an IETF protocol with protocol ID 200 
// 
 
#define SAMPLE_PROTOCOL_IP_ID   \ 
    PROTOCOL_ID(PROTO_TYPE_UNICAST, 0, 0, 200) 
 
 
////////////////////////////////////////////////////////////////////////////// 
//                                                                          // 
// It is highly recommended that implementors provide their own versioning  // 
// scheme.  This sample uses information structures whose first DWORD is    // 
// the version number.  This allows extensibility in the future             // 
//                                                                          // 
////////////////////////////////////////////////////////////////////////////// 
 
#define SAMPLE_PROTOCOL_VERSION     0x00000001 
 
#define SAMPLE_PROTOCOL_MULTICAST_GROUP1    ((DWORD)0x640000E0) // 224.0.0.100 
#define SAMPLE_PROTOCOL_MULTICAST_GROUP2    ((DWORD)0x650000E0) // 224.0.0.101 
 
 
////////////////////////////////////////////////////////////////////////////// 
//                                                                          // 
// The Global Info                                                          // 
//                                                                          // 
////////////////////////////////////////////////////////////////////////////// 
 
#define PROTO_LOGGING_NONE  ((DWORD) 0) 
#define PROTO_LOGGING_ERROR ((DWORD) 1) 
#define PROTO_LOGGING_WARN  ((DWORD) 2) 
#define PROTO_LOGGING_INFO  ((DWORD) 3) 
 
typedef struct _SAMPLE_PROTOCOL_GLOBAL_INFO 
{ 
    DWORD   dwVersion; 
    DWORD   dwLogLevel; 
}SAMPLE_PROTOCOL_GLOBAL_INFO, *PSAMPLE_PROTOCOL_GLOBAL_INFO; 
 
////////////////////////////////////////////////////////////////////////////// 
//                                                                          // 
// An interface an have mutliple addresses. The Sample Routing Protocol     // 
// allows the admin. to configure parameters for each address.              // 
// Each Address (or rather <address,mask>) is called a BINDING - for        // 
// reasons that will be obvious in the code.  When there are multiple       // 
// bindings on an interface, then the IP Addresses are known before         // 
// hand and do not change while the router is running.  If there is         // 
// only one address, it may or may not be known before the router           // 
// starts, hence is assumed to be 0.0.0.0. The actual address only          // 
// becomes available when the IP Router Manager calls the protocol's        // 
// BindInterface() function.  Also such address MAY be dynamic - we         // 
// say MAY because if the interface has a single static IP Address,         // 
// it will not change while the router is running. On the other hand,       // 
// if the interface has a DHCP address (which can only be a SINGLE          // 
// address) then an ipconfig /release /renew could change the address       // 
// while the router is running. Since by looking at a single IP address     // 
// we can not say whether it is dynamic or not, we say that it MAY          // 
// change.                                                                  // 
// This fact (that address's change) has a bearing on SNMP MIB indices.     // 
// If the interface has a single IP address, your protocol should be        // 
// able to handle the information being indexed via the actual address      // 
// or via 0.0.0.0.  This means that the ADDRESS BY ITSELF CAN NOT BE        // 
// AN INDEX.  That is, the interface index MUST be one of the indices       // 
//                                                                          // 
////////////////////////////////////////////////////////////////////////////// 
 
////////////////////////////////////////////////////////////////////////////// 
//                                                                          // 
// The only information per binding is whether it is enabled or not         // 
// Hey, this is a SAMPLE, what did you expect - OSPF?                       // 
//                                                                          // 
////////////////////////////////////////////////////////////////////////////// 
  
typedef struct _BINDING_INFO 
{ 
    DWORD   dwAddress; 
    DWORD   dwMask;  
    BOOL    bEnabled; 
}BINDING_INFO, *PBINDING_INFO; 
 
////////////////////////////////////////////////////////////////////////////// 
//                                                                          // 
// So the per interface information consists of the information             // 
// that applies across bindings and information for each binding            // 
//                                                                          // 
////////////////////////////////////////////////////////////////////////////// 
 
typedef struct _SAMPLE_PROTOCOL_INTERFACE_INFO 
{ 
    DWORD           dwVersion; 
    ULONG           ulNumBindings; 
    BINDING_INFO    rgbiInfo[ANY_SIZE]; 
}SAMPLE_PROTOCOL_INTERFACE_INFO, *PSAMPLE_PROTOCOL_INTERFACE_INFO; 
 
#define SIZEOF_PROTO_IF_INFO(X)                                     \ 
    (FIELD_OFFSET(SAMPLE_PROTOCOL_INTERFACE_INFO, rgbiInfo[0])  +   \ 
     ((X) * sizeof(BINDING_INFO))) 
 
 
////////////////////////////////////////////////////////////////////////////// 
//                                                                          // 
// MIB related information                                                  // 
//                                                                          // 
// The Sample Routing Protocol only supports queries (Get/GetFirst/GetNext) // 
// via the MIB calls. No Sets/Deletes/Creates are supported.  The           // 
// SetInterface/GlobalInfo() calls should be used for that.  The reason     // 
// is to avoid exposing two different interfaces for sets since keeping     // 
// those in synch is generally difficult. This is a VERY GOOD guideline to  // 
// follow.  EITHER DONT ALLOW ANY SETS THROUGH MIB CALLS OR ONLY ALLOW      // 
// THOSE VARIABLES TO BE SET THAT ARE NOT SET VIA INTERFACE/GLOBAL INFO     // 
// CALLS.  A case in point being the TTL field exposed via MIB-II. The      // 
// IP Router Manager allows this field to be set since it is not exposed    // 
// via the other calls.  IN GENERAL USE THE MIB CALLS FOR STATISTICS.       // 
// This will make coding the admin DLL for the protocol a lot easier.       // 
//                                                                          // 
////////////////////////////////////////////////////////////////////////////// 
 
#define PROTO_MIB_GLOBAL_ID     0 
#define PROTO_MIB_INTF_ID       PROTO_MIB_GLOBAL_ID + 1 
 
////////////////////////////////////////////////////////////////////////////// 
//                                                                          // 
// The following structure is used to query the MIB. The Oid field is       // 
// one of the IDs #defined above.  The index is stored in a variable        // 
// sized array.  All the indices are DWORDs for this protocol.  This is     // 
// generally a good thing.  It wouldn't be the brightest thing to have      // 
// a string as an index.                                                    // 
// The number of indices are calculated from the size of the query          // 
// structure that is passed in to the MibXXX calls.                         // 
//                                                                          // 
////////////////////////////////////////////////////////////////////////////// 
 
typedef struct _PROTO_MIB_QUERY 
{ 
    DWORD   dwOid; 
    DWORD   rgdwIndex[ANY_SIZE]; 
}PROTO_MIB_QUERY, *PPROTO_MIB_QUERY; 
 
////////////////////////////////////////////////////////////////////////////// 
//                                                                          // 
// Macro to figure out the number of indices given the query size           // 
//                                                                          // 
////////////////////////////////////////////////////////////////////////////// 
 
#define NUM_INDICES(X)  ((X)/sizeof(DWORD) - 1) 
 
////////////////////////////////////////////////////////////////////////////// 
//                                                                          // 
// The following structures are the information returned by the protocol in // 
// response to a MIB query.  Currently they are the same as the             // 
// Interface/Global structures. However if this were a real protocol, the   // 
// statistics would go in here and would not be present in the other        // 
// structures.                                                              // 
//                                                                          // 
////////////////////////////////////////////////////////////////////////////// 
 
////////////////////////////////////////////////////////////////////////////// 
//                                                                          // 
// The Global info is a scalar and has no index.  Unlike SNMP we dont       // 
// expect a scalar to be indexed by 0                                       // 
//                                                                          // 
////////////////////////////////////////////////////////////////////////////// 
 
typedef struct _PROTO_MIB_GLOBAL 
{ 
    DWORD   dwLogLevel; 
}PROTO_MIB_GLOBAL, *PPROTO_MIB_GLOBAL; 
 
////////////////////////////////////////////////////////////////////////////// 
//                                                                          // 
// The Interface info is indexed by the ifIndex                             // 
//                                                                          // 
////////////////////////////////////////////////////////////////////////////// 
 
typedef struct _MIB_BIND 
{ 
    DWORD   dwAddress; 
    DWORD   dwMask; 
    BOOL    bEnabled; 
}MIB_BIND, *PMIB_BIND; 
 
typedef struct _PROTO_MIB_INTF 
{ 
    DWORD       dwIfIndex; 
    ULONG       ulNumAddress; 
    MIB_BIND    rgmbBindInfo[ANY_SIZE]; 
}PROTO_MIB_INTF, *PPROTO_MIB_INTF; 
 
#define SIZEOF_MIB_INTF_INFO(X)     \ 
    (FIELD_OFFSET(PROTO_MIB_INTF, rgmbBindInfo[0])  + \ 
     ((X) * sizeof(MIB_BIND))) 
 
 
typedef struct _PROTO_MIB_RESPONSE 
{ 
    DWORD   dwOid; 
    union 
    { 
        PROTO_MIB_GLOBAL    mgGlobal; 
        PROTO_MIB_INTF      miIntf; 
    }; 
}PROTO_MIB_RESPONSE, *PPROTO_MIB_RESPONSE; 
 
#endif // __SAMPLE_INFO_H__