snmp_api.c 。。。。。。。。。。。。。。。。。。。。。。。。。。
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define SNMP_API_C
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include <string.h>
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "Common.h"
#include "XCore.h"
#include "snmp_api.h"
#if defined(NUTNET)
/******************************************************************************
* *
* L O C A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L T Y P E D E F S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L I N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L U N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/*
* generic statistics counter functions
*/
static u_long statistics[SNMP_STAT_MAX];
/*!
* \brief Compare object identifiers up to a specified length.
*
* \param name1 First object identifier.
* \param name2 Second object identifier.
* \param len Number of sub identifiers to compare.
*/
int SnmpOidLenCmp(CONST OID * name1, CONST OID * name2, size_t len)
{
/* Find first non-matching element. */
while (len--) {
if (*name1 < *name2) {
/* First is lower than second. */
return -1;
}
if (*name1++ > *name2++) {
/* First is larger than second. */
return 1;
}
}
/* Elements match up to the given length. */
return 0;
}
/*!
* \brief Compare object identifiers.
*
* \param name1 First object identifier.
* \param len1 Length of first object identifier.
* \param name2 Second object identifier.
* \param len2 Length of second object identifier.
*
* \return 0 if both are equal, 1 if first element is larger or -1
* if first element is lower than the second one.
*/
int SnmpOidCmp(CONST OID * name1, size_t len1, CONST OID * name2, size_t len2)
{
/* Compare elements up to the length of shortest name. */
int rc = SnmpOidLenCmp(name1, name2, (len1 < len2) ? len1 : len2);
/* If equal, compare lengths. */
if (rc == 0) {
if (len1 < len2) {
rc = -1;
} else if (len1 > len2) {
rc = 1;
}
}
return rc;
}
/*!
* \brief Compare object identifier with tree element.
*
* \param name1 Object identifier.
* \param len1 Length of object identifier.
* \param name2 Tree identifier.
* \param len2 Length of tree identifier.
*
* \return 0 if the object identifier is part of the subtree, -1 if it
* is located before the tree element or 1 if it is located
* after the tree element.
*/
int SnmpOidTreeCmp(CONST OID * objid, size_t objlen, CONST OID * treeid, size_t treelen)
{
/* Compare elements up to the length of shortest name. */
int rc = SnmpOidLenCmp(objid, treeid, (objlen < treelen) ? objlen : treelen);
/* If equal, compare lengths. */
if (rc == 0 && objlen < treelen) {
rc = -1;
}
return rc;
}
/*!
* \brief Compare object identifiers with index added.
*
* \param name1 First object identifier.
* \param len1 Length of first object identifier.
* \param name2 Second object identifier.
* \param len2 Length of second object identifier.
* \param index Index sub identifier.
*
* \return 0 if both are equal, 1 if first element is larger or -1
* if first element is lower than the second one.
*/
int SnmpOidCmpIdx(CONST OID * name1, size_t len1, CONST OID * name2, size_t len2, OID index)
{
size_t len = (len1 < len2) ? len1 : len2;
/* Compare elements up to the length of shortest name. */
int rc = SnmpOidLenCmp(name1, name2, len);
/* If equal, compare lengths. */
if (rc == 0) {
if (len1 < len2) {
rc = -1;
} else if (len1 > len2) {
if (*(name1 + len) < index) {
/* First is lower than second. */
rc = -1;
} else if (*(name1 + len) > index) {
/* First is larger than second. */
rc = 1;
} else if (len1 > len2 + 1) {
rc = 1;
}
}
}
return rc;
}
/*
* This should be faster than doing a SnmpOidCmp for different
* length OIDs, since the length is checked first and if != returns
* immediately.
*
* Might be very slighly faster if lengths are ==.
*
* \param name1 A pointer to the first OID.
* \param len1 Length of the first OID.
* \param name2 A pointer to the second OID.
* \param len2 Length of the second OID.
*
* \return 0 if they are equal, -1 if they are not.
*/
int SnmpOidEquals(CONST OID * name1, size_t len1, CONST OID * name2, size_t len2)
{
if (len1 != len2 || memcmp(name1, name2, len1)) {
return -1;
}
return 0;
}
void SnmpStatsInc(int which)
{
if (which >= 0 && which < SNMP_STAT_MAX) {
statistics[which]++;
}
}
u_long SnmpStatsGet(int which)
{
if (which >= 0 && which < SNMP_STAT_MAX) {
return statistics[which];
}
return 0;
}
#endif
snmp_api.h 。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef SNMP_API_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define SNMP_API_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "asn1.h"
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
#define SNMP_MAX_MSG_SIZE 1472 /* ethernet MTU minus IP/UDP header */
/*
* SNMP statistic counters.
*/
#define SNMP_STAT_INPKTS 0
#define SNMP_STAT_OUTPKTS 1
#define SNMP_STAT_INBADVERSIONS 2
#define SNMP_STAT_INBADCOMMUNITYNAMES 3
#define SNMP_STAT_INBADCOMMUNITYUSES 4
#define SNMP_STAT_INASNPARSEERRS 5
#define SNMP_STAT_INTOOBIGS 6
#define SNMP_STAT_INNOSUCHNAMES 7
#define SNMP_STAT_INBADVALUES 8
#define SNMP_STAT_INREADONLYS 9
#define SNMP_STAT_INGENERRS 10
#define SNMP_STAT_INTOTALREQVARS 11
#define SNMP_STAT_INTOTALSETVARS 12
#define SNMP_STAT_INGETREQUESTS 13
#define SNMP_STAT_INGETNEXTS 14
#define SNMP_STAT_INSETREQUESTS 15
#define SNMP_STAT_INGETRESPONSES 16
#define SNMP_STAT_INTRAPS 17
#define SNMP_STAT_OUTTOOBIGS 18
#define SNMP_STAT_OUTNOSUCHNAMES 19
#define SNMP_STAT_OUTBADVALUES 20
#define SNMP_STAT_OUTGENERRS 21
#define SNMP_STAT_OUTGETREQUESTS 22
#define SNMP_STAT_OUTGETNEXTS 23
#define SNMP_STAT_OUTSETREQUESTS 24
#define SNMP_STAT_OUTGETRESPONSES 25
#define SNMP_STAT_OUTTRAPS 26
#define SNMP_STAT_ENABLEAUTHENTRAPS 27
#define SNMP_STAT_MAX 28
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
extern int SnmpOidCmp(CONST OID *, size_t, CONST OID *, size_t);
extern int SnmpOidLenCmp(CONST OID *name1, CONST OID *name2, size_t len);
extern int SnmpOidTreeCmp(CONST OID *, size_t, CONST OID *, size_t);
extern int SnmpOidCmpIdx(CONST OID *name1, size_t len1, CONST OID *name2, size_t len2, OID index);
extern int SnmpOidEquals(CONST OID *, size_t, CONST OID *, size_t);
extern void SnmpStatsInc(int);
extern u_long SnmpStatsGet(int);
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif
snmp_auth.c 。。。。。。。。。。。。。。。。。。。。。。。。。。
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define SNMP_AUTH_C
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include <stdlib.h>
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "Common.h"
#include "XCore.h"
#include "snmp.h"
#include "snmp_agent.h"
#include "snmp_auth.h"
#if defined(NUTNET)
/******************************************************************************
* *
* L O C A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L T Y P E D E F S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L I N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L U N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/*!
* \brief Parse header of community string based message.
*
* Retrieves version and community.
*
* \param data Points to the message.
* \param length Bytes left in message.
* \param sidp Pointer to a buffer that receives the community string.
* \param slen Length of the community string.
* \param version Message version
*/
CONST u_char *SnmpAuthParse(CONST u_char * data, size_t * length, u_char * sidp, size_t * slen, long *version)
{
u_char type = ASN_SEQUENCE | ASN_CONSTRUCTOR;
/* Check header type. */
if ((data = AsnSequenceParse(data, length, type)) == NULL) {
return NULL;
}
/* Get SNMP version. */
if ((data = AsnIntegerParse(data, length, &type, version)) == NULL) {
return NULL;
}
/* Get SNMP community. */
if ((data = AsnOctetStringParse(data, length, &type, sidp, slen)) == NULL) {
return NULL;
}
if (*version == SNMP_VERSION_1) {
sidp[*slen] = '\0';
}
return data;
}
/*!
* \brief Build header of community string based message.
*/
u_char *SnmpAuthBuild(SNMP_SESSION * session, u_char * data, size_t * length, size_t messagelen)
{
data = AsnSequenceBuild(data, length, ASN_SEQUENCE | ASN_CONSTRUCTOR, messagelen + session->sess_id_len + 5);
if (data == NULL) {
return NULL;
}
data = AsnIntegerBuild(data, length, ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER, (long *) &session->sess_version);
if (data == NULL) {
return NULL;
}
data = AsnOctetStringBuild(data, length, ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_OCTET_STR, session->sess_id, session->sess_id_len);
if (data == NULL) {
return NULL;
}
return data;
}
#endif
snmp_auth.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef SNMP_AUTH_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define SNMP_AUTH_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "snmp_agent.h"
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
extern CONST u_char *SnmpAuthParse(CONST u_char *, size_t *, u_char *, size_t *, long *);
extern u_char *SnmpAuthBuild(SNMP_SESSION *, u_char *, size_t *, size_t);
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif
snmp_config.c 。。。。。。。。。。。。。。。。。。。。。。。。。
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define SNMP_CONFIG_C
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include <string.h>
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "Common.h"
#include "XCore.h"
#include "XNutOS.h"
#include "snmp_config.h"
#if defined(NUTNET)
/******************************************************************************
* *
* L O C A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L T Y P E D E F S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L I N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L U N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
static VIEW_LIST *views;
static COMMUNITY_LIST *communities;
/*!
* \param name Symbolic name of this view.
* \param type Either SNMP_VIEW_INCLUDED or SNMP_VIEW_EXCLUDED.
*
* \return View index on success. Otherwise -1 is returned.
*/
int SnmpViewCreate(CONST char *name, CONST OID * subtree, size_t subtreelen, int type)
{
static int nextview = 1;
VIEW_LIST *vp;
VIEW_LIST *nvp;
VIEW_LIST *prev = NULL;
size_t i;
/* Check name length. */
if (strlen(name) > (sizeof(vp->view_name) - 1)) {
return -1;
}
/* Check if this name exists already. */
for (vp = views; vp; prev = vp, vp = vp->next) {
if (strcmp(name, vp->view_name) == 0) {
break;
}
}
/* Allocate a new view entry. */
nvp = NutHeapAlloc(sizeof(VIEW_LIST));
memset(nvp, 0, sizeof(VIEW_LIST));
strcpy(nvp->view_name, name);
nvp->view_type = type;
nvp->view_subtree_len = subtreelen;
for (i = 0; i < subtreelen; i++) {
nvp->view_subtree[i] = subtree[i];
}
/* Set index, either of the existing entry or a new one. */
nvp->view_index = vp ? vp->view_index : nextview++;
/* Add the new entry to the linked list. */
if (views) {
for (; vp; prev = vp, vp = vp->next);
prev->next = nvp;
} else {
views = nvp;
}
return nvp->view_index;
}
int SnmpViewFind(char *name)
{
VIEW_LIST *vp;
if (strcmp(name, "-") == 0) {
return 0;
}
for (vp = views; vp; vp = vp->next) {
if (strcmp(vp->view_name, name) == 0) {
return vp->view_index;
}
}
return -1;
}
/*!
* \brief Find community entry by name.
*
* \param name Community name.
* \param readView Pointer to a variable that receives the view index
* for read access.
* \param writeView Pointer to a variable that receives the view index
* for write access.
*
* \return 0 on success, -1 otherwise.
*/
int SnmpCommunityFind(CONST char *name, int *readView, int *writeView)
{
COMMUNITY_LIST *cp;
for (cp = communities; cp; cp = cp->next) {
if (strcmp(cp->comm_name, name) == 0) {
if (readView) {
*readView = cp->comm_read_view;
}
if (writeView) {
*writeView = cp->comm_write_view;
}
return 0;
}
}
return -1;
}
/*!
* \brief Create a community entry.
*
* \param name Community name.
* \param readView View index for read access, obtained from a previous
* call to SnmpViewCreate().
* \param writeView View index for write access, obtained from a previous
* call to SnmpViewCreate().
*
* \return 0 on success, -1 otherwise.
*/
int SnmpCommunityCreate(CONST char *name, int readView, int writeView)
{
COMMUNITY_LIST *cp;
COMMUNITY_LIST *prev = 0;
if (strlen(name) > (sizeof(cp->comm_name) - 1)) {
return -1;
}
for (cp = communities; cp; cp = cp->next) {
if (strcmp(name, cp->comm_name) == 0) {
return 0;
}
prev = cp;
}
cp = NutHeapAlloc(sizeof(COMMUNITY_LIST));
memset(cp, 0, sizeof(COMMUNITY_LIST));
strcpy(cp->comm_name, name);
cp->comm_read_view = readView;
cp->comm_write_view = writeView;
if (prev) {
prev->next = cp;
} else {
communities = cp;
}
return 0;
}
#endif
snmp_config.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef SNMP_CONFIG_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define SNMP_CONFIG_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "snmp.h"
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
/*
* View types.
*/
#define SNMP_VIEW_INCLUDED 1
#define SNMP_VIEW_EXCLUDED 2
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
typedef struct _viewEntry {
struct _viewEntry *next;
int view_index;
int view_type;
size_t view_subtree_len;
OID view_subtree[MAX_OID_LEN];
char view_name[16];
} VIEW_LIST;
typedef struct _communityEntry {
struct _communityEntry *next;
int comm_read_view;
int comm_write_view;
char comm_name[16];
} COMMUNITY_LIST;
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
extern int SnmpViewCreate(CONST char *, CONST OID *, size_t, int);
extern int SnmpViewFind(char *);
extern int SnmpCommunityCreate(CONST char *, int, int);
extern int SnmpCommunityFind(CONST char *, int *, int *);
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif
snmp_mib.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。。
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define SNMP_MIB_C
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include <string.h>
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "Common.h"
#include "XCore.h"
#include "XNutOS.h"
#include "snmp.h"
#include "snmp_api.h"
#include "snmp_mib.h"
#if defined(NUTNET)
/******************************************************************************
* *
* L O C A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L T Y P E D E F S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L I N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L U N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/*
* The subtree structure contains a subtree prefix which applies to
* all variables in the associated variable list.
*
* No subtree may be a subtree of another subtree in this list.
* i.e.: 1.2
* 1.2.0
*/
typedef struct _SUBTREE {
/*! \brief Pointer to the next branch. */
struct _SUBTREE *sub_next;
/*! \brief Number of variables. */
int sub_numvars;
/*! \brief Pointer to the array of variables. */
SNMPVAR *sub_vars;
/*! \brief Length of the base name. */
size_t sub_namelen;
/*! \brief Base name of this branch. */
OID sub_name[MAX_OID_LEN];
} SUBTREE;
static SUBTREE *mibtree;
/*!
* \brief Register MIB variables.
*/
int SnmpMibRegister(OID basename[], size_t baselen, SNMPVAR * vars, int num)
{
SUBTREE **tpp;
SUBTREE *branch;
/* Create a new branch. */
if ((branch = NutHeapAlloc(sizeof(SUBTREE))) == NULL) {
return -1;
}
branch->sub_numvars = num;
branch->sub_vars = vars;
branch->sub_namelen = baselen;
memcpy(branch->sub_name, basename, baselen * sizeof(OID));
/* Locate the new branch's insertion point. */
for (tpp = &mibtree; *tpp; tpp = &(*tpp)->sub_next) {
if (SnmpOidCmp((*tpp)->sub_name, (*tpp)->sub_namelen, branch->sub_name, branch->sub_namelen) > 0) {
break;
}
}
/* Insert the branch. */
branch->sub_next = *tpp;
*tpp = branch;
return 0;
}
/*!
* \brief Find MIB variable.
*
* \param name
* \param namelen
* \param type
* \param len
* \param acl
* \param exact
* \param wmethod
* \param no_obj
*/
u_char *SnmpMibFind(OID * name, size_t * namelen, u_char * type, size_t * len, u_short * acl, int exact, WMETHOD ** wmethod,
int *no_obj)
{
SUBTREE *tp;
SNMPVAR *vp = 0;
int i;
u_char *access = NULL;
int rc;
OID *suffix;
size_t sufflen;
OID *ori_oid = NULL;
size_t ori_len = 0;
int found = 0;
/*
* If not looking for an exact match, keep a copy of the original name.
*/
if (!exact) {
if ((ori_oid = NutHeapAlloc(*namelen * sizeof(OID))) == NULL) {
return NULL;
}
memcpy(ori_oid, name, *namelen * sizeof(OID));
ori_len = *namelen;
}
*wmethod = NULL;
/*
* Walk along the linked list of subtrees.
*/
for (tp = mibtree; tp; tp = tp->sub_next) {
/*
* Check if name is part of this subtree. Or, if we don't need an exact match,
* if the name is in front of the subtree.
*/
rc = SnmpOidTreeCmp(name, *namelen, tp->sub_name, tp->sub_namelen);
if (rc == 0 || (rc < 0 && !exact)) {
sufflen = *namelen - tp->sub_namelen;
suffix = name + tp->sub_namelen;
for (i = 0, vp = tp->sub_vars; i < tp->sub_numvars; i++, vp++) {
if (vp->var_namelen && (exact || rc >= 0)) {
rc = SnmpOidTreeCmp(suffix, sufflen, vp->var_name, vp->var_namelen);
}
if ((exact && rc == 0) || (!exact && rc <= 0) || vp->var_namelen == 0) {
access = (*(vp->var_get)) (vp, name, namelen, exact, len, wmethod);
if (wmethod) {
*acl = vp->var_acl;
}
if (exact) {
found = 1;
}
if (access) {
break;
}
}
if (exact && rc <= 0) {
*type = vp->var_type;
*acl = vp->var_acl;
*no_obj = !found;
return NULL;
}
}
if (access) {
break;
}
}
}
if (tp == NULL) {
if (!access && !exact) {
memcpy(name, ori_oid, ori_len * sizeof(OID));
*namelen = ori_len;
NutHeapFree(ori_oid);
}
*no_obj = !found;
return NULL;
}
if (ori_oid) {
NutHeapFree(ori_oid);
}
/*
* vp now points to the approprate struct.
*/
*type = vp->var_type;
*acl = vp->var_acl;
return access;
}
#endif
snmp_mib.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef SNMP_MIB_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define SNMP_MIB_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "asn1.h"
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
typedef int (WMETHOD)(int, u_char *, u_char, size_t, OID *, size_t);
typedef struct _SNMPVAR {
/*! \brief Internal magic identifier. */
u_char var_magic;
/*! \brief Type of this variable. */
char var_type;
/*! \brief Access control. */
u_short var_acl;
/*! \brief Variable access funtion. */
u_char *(*var_get)(CONST struct _SNMPVAR*, OID*, size_t*, int, size_t*, WMETHOD **);
/*! \brief Number of sub-IDs in the name. */
size_t var_namelen;
/*! \brief Name (object identifier) of the variable. */
OID var_name[MAX_OID_LEN];
} SNMPVAR;
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
extern int SnmpMibRegister(OID[], size_t, SNMPVAR *, int);
extern u_char *SnmpMibFind(OID *, size_t *, u_char *, size_t *, u_short *, int, WMETHOD **, int *);
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif
ssi.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define SSI_C
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "Common.h"
#include "XCore.h"
#include "XNutOS.h"
#include "XLib.h"
#include "httpd.h"
#include "ssi.h"
#include "httpd_p.h"
#include "dencode.h"
#if defined(NUTNET)
/******************************************************************************
* *
* L O C A L D E F I N E S *
* *
******************************************************************************/
#define BUFSIZE 512
#define SSI_TYPE_FILE 0x01
#define SSI_TYPE_VIRTUAL 0x02
#define SSI_TYPE_EXEC 0x03
/******************************************************************************
* *
* L O C A L T Y P E D E F S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L I N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
static const char rsp_not_found[] = "404 Not found: %s\r\n";
static const char rsp_intern_err[] = "500 Internal error\r\n";
static const char rsp_bad_req[] = "400 Bad request\r\n";
/******************************************************************************
* *
* L O C A L U N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
extern char *cgiBinPath;
/*!
* \brief Send included file to the stream
*
* Load a file from filesystem and send ("include") it to the http-stream
*
* \param stream Stream of the socket connection, previously opened for
* binary read and write.
* \param filename Name of the included file. e.g."UROM:test.txt"
*/
static void NutSsiProcessFile(FILE * stream, char *filename)
{
int fd;
int n;
char *data;
int size;
long file_len;
fd = _open(filename, _O_BINARY | _O_RDONLY);
if (fd == -1) { // No such file found... send a 404 string.
fprintf(stream, rsp_not_found, filename);
return;
}
file_len = _filelength(fd);
size = 512;
if ((data = NutHeapAlloc(size)) != 0) {
while (file_len) {
if (file_len < 512L)
size = (int) file_len;
n = _read(fd, data, size);
if (fwrite(data, 1, n, stream) == 0)
break;
file_len -= (long) n;
}
NutHeapFree(data);
}
_close(fd);
}
/*!
* \brief Send a file or cgi with a path relativ to http-root
*
* Processes an included local url with a path relativ to http-root. This could also be a
* cgi script. Nearly the same as NutHttpProcessFileRequest
*
* \param stream Stream of the socket connection, previously opened for
* binary read and write.
* \param url URL of the file to be included e.g. "/include/test.js"
* \param http_root The root path of the http-deamon
* \param orig_req The http request struct of the top most http_request
*/
static void NutSsiProcessVirtual(FILE * stream, char *url, char* http_root, REQUEST *orig_req)
{
int fd;
int i;
int n;
char *data;
int size;
long file_len;
char *filename = NULL;
MIMEHANDLER handler;
char *cp;
REQUEST * req;
CONST char *cgi_bin = cgiBinPath ? cgiBinPath : "cgi-bin/";
CONST char * tmp;
size_t len;
tmp = (char *)cgi_bin;
if (NutDecodePath(url) == 0) {
fprintf(stream, rsp_bad_req);
return;
}
/*
* Process CGI.
*/
while (tmp) {
/* Skip leading path separators. */
while (*cgi_bin == ';')
cgi_bin++;
/* Determine the length of the next path component. */
for (len = 0, cp = (char *)cgi_bin; *cp && *cp != ';'; len++, cp++);
tmp = (char *)cgi_bin;
if (len && strncmp(url, tmp, len) == 0) {
if ((req = NutHeapAllocClear(sizeof(REQUEST))) == 0) {
fprintf(stream, rsp_intern_err);
return;
}
req->req_method = METHOD_GET;
req->req_version = orig_req->req_version;
req->req_length = 0;
if (orig_req->req_agent != NULL) {
if ((req->req_agent = NutHeapAlloc((strlen(orig_req->req_agent) + 1))) == 0) {
fprintf(stream, rsp_intern_err);
DestroyRequestInfo(req);
return;
}
strcpy(req->req_agent, orig_req->req_agent);
}
if (orig_req->req_cookie!= NULL) {
if ((req->req_cookie = NutHeapAlloc((strlen(orig_req->req_cookie) + 1))) == 0) {
fprintf(stream, rsp_intern_err);
DestroyRequestInfo(req);
return;
}
strcpy(req->req_cookie, orig_req->req_cookie);
}
if ((cp = strchr(url, '?')) != 0) {
*cp++ = 0;
if (strcmp(cp, "$QUERY_STRING") == 0) {
u_short size;
size = 1; /* At least 1 for empty requests. */
for (i = 0; i < orig_req->req_numqptrs*2; i ++) {
size += strlen(orig_req->req_qptrs[i]) + 1;
}
if ((req->req_query = NutHeapAlloc(size)) == 0) {
fprintf(stream, rsp_intern_err);
DestroyRequestInfo(req);
return;
}
req->req_query[0] = 0;
for (i = 0; i < (orig_req->req_numqptrs * 2); i++) {
if(i) {
strcat (req->req_query, "&");
}
strcat (req->req_query, orig_req->req_qptrs[i]);
strcat (req->req_query, "=");
i++;
strcat (req->req_query, orig_req->req_qptrs[i]);
}
} else {
if ((req->req_query = NutHeapAlloc(strlen(cp) + 1)) == 0) {
fprintf(stream, rsp_intern_err);
DestroyRequestInfo(req);
return;
}
strcpy(req->req_query, cp);
}
NutHttpProcessQueryString(req);
}
if ((req->req_url = NutHeapAlloc(strlen(url) + 1)) == 0) {
fprintf(stream, rsp_intern_err);
DestroyRequestInfo(req);
return;
}
strcpy(req->req_url, url);
NutCgiProcessRequest(stream, req, len);
DestroyRequestInfo(req);
return;
}
cgi_bin += len;
if (*cgi_bin == '\0') {
break;
}
}
/*
* Process file.
*/
for (n = 0, fd = -1; default_files[n]; n++) {
filename = CreateFilePath(url, default_files[n]);
if (filename == NULL) {
fprintf(stream, rsp_intern_err);
return;
}
/*
* Note, that simple file systems may not provide stat() or access(),
* thus trying to open the file is the only way to check for existence.
* Another problem is, that PHAT allows to open directories. We use
* the file length to ensure, that we got a normal file.
*/
if ((fd = _open(filename, _O_BINARY | _O_RDONLY)) != -1) {
if (_filelength(fd)) {
break;
}
_close(fd);
}
NutHeapFree(filename);
}
if (fd == -1) {
fprintf(stream, rsp_not_found, filename);
return;
}
file_len = _filelength(fd);
handler = NutGetMimeHandler(filename);
NutHeapFree(filename);
if (handler == NULL) {
size = 512; // If we have not registered a mime handler handle default.
if ((data = NutHeapAlloc(size)) != 0) {
while (file_len) {
if (file_len < 512L) {
size = (int) file_len;
}
n = _read(fd, data, size);
if (fwrite(data, 1, n, stream) == 0) {
break;
}
file_len -= (long) n;
}
NutHeapFree(data);
}
} else handler(stream, fd, file_len, http_root, orig_req);
_close(fd);
return;
}
/*!
* \brief Skip whitespaces in a string from the given position on
*
* Whitespaces are defined as \n \r \t and space. Pos will be set to the first character which is not a whitespace
*
* \param buffer String to work on
* \param pos Start position of the search
* \param end last position we should check for
* \return Nothing. pos is set to the first character which is not a white space
*/
static void NutSsiSkipWhitespace(char *buffer, u_short *pos, u_short end)
{
while ((*pos < end) && (
(buffer[*pos] == '\n') || (buffer[*pos] == '\r') ||
(buffer[*pos] == '\t') || (buffer[*pos] == ' ')))
(*pos) ++;
}
/*!
* \brief Check if a comment is a ssi directive
*
* Check if a comment is a ssi directive and replace the directive by the included data.
* Allowed directives are:
*
* <!--#include virtual="/news/news.htm" -->
* <!--#include file="UROM:/news/news.htm" -->
* <!--#exec cgi="/cgi-bin/counter.cgi" -->
*
* \param stream Stream of the socket connection, previously opened for
* binary read and write.
* \param buffer Current file buffer so search in. The buffer is set to the start of a html comment
* \param end End position of the comment.
* \param http_root The root path of the http-deamon
* \param req The http request struct of the top most http_request
*/
static u_char NutSsiCheckForSsi(FILE *stream, char *buffer, u_short end, char* http_root, REQUEST *req)
{
u_short pos = 4; // First character after comment start
char * filename;
u_char type;
pos = 4;
NutSsiSkipWhitespace(buffer, &pos, end); // Skip whitespaces after comment start
if (pos == end) return 0;
if (strncmp(&buffer[pos], "#include", 8) == 0) { // Search include directive
pos += 8;
type = SSI_TYPE_VIRTUAL;
} else
if (strncmp(&buffer[pos], "#exec", 5) == 0) { // Search include or exec directive
pos += 5;
type = SSI_TYPE_EXEC;
} else return 0; // No include or exec found. Skip the rest of this comment...
if (pos >= end) return 0;
NutSsiSkipWhitespace(buffer, &pos, end); // Skip whitespaces after #include directive
if (pos == end) return 0;
if (type == SSI_TYPE_VIRTUAL) {
if (strncmp(&buffer[pos], "virtual", 7) == 0) { // Search virtual directive
pos += 7;
} else // No virtual found. Test for file...
if (strncmp(&buffer[pos], "file", 4) == 0) { // Search file directive
pos += 4;
type = SSI_TYPE_FILE;
} else return 0; // No file found. Test for file...
} else {
if (strncmp(&buffer[pos], "cgi", 3) == 0) { // Search cgi directive
pos += 3;
} else return 0; // No cgi found. return...
}
if (pos >= end) return 0;
NutSsiSkipWhitespace(buffer, &pos, end); // Skip whitespaces after virtual, file or cgi directive
if (pos == end) return 0;
if (buffer[pos] != '=') return 0; // check for assertion
pos ++;
NutSsiSkipWhitespace(buffer, &pos, end); // Skip whitespaces after assertion
if (pos == end) return 0;
if (buffer[pos] == '"') { // Search for filename and pass to output function
pos ++;
if (pos == end) return 0;
filename = &buffer[pos];
while (buffer[pos] != '"') {
pos ++;
if (pos == end) return 0;
}
buffer[pos] = '\0';
switch (type) {
case SSI_TYPE_FILE:
NutSsiProcessFile(stream, filename);
break;
case SSI_TYPE_VIRTUAL:
NutSsiProcessVirtual(stream, filename, http_root, req);
break;
case SSI_TYPE_EXEC:
NutSsiProcessVirtual(stream, filename, http_root, req);
break;
}
}
return 1;
}
/*!
* \brief Check a file for html comments
*
* Check a file for html comments and then call NutSsiCheckForSsi to seach a ssi directive
* Allowed diretives are:
*
* <!--#include virtual="/news/news.htm" -->
* <!--#include file="UROM:/news/news.htm" -->
* <!--#exec cgi="/cgi-bin/counter.cgi" -->
*
* \param stream Stream of the socket connection, previously opened for
* binary read and write.
* \param fd Filedescriptor pointing to a just opened file.
* \param file_len length of this file
* \param http_root The root path of the http-deamon
* \param req The http request struct of the top most http_request
*/
static void NutHttpProcessSHTML(FILE * stream, int fd, int file_len, char* http_root, REQUEST *req)
{
char * buffer;
u_char in_comment;
int buffsize;
int fpos;
int n;
char *index;
u_char found;
buffsize = MIN(BUFSIZE, file_len);
buffer = NutHeapAlloc(buffsize+1);
in_comment = 0;
fpos = 0;
while (file_len != fpos) {
memset(buffer, 0, buffsize+1);
n = _read(fd, buffer, MIN(buffsize, file_len-fpos));
if (!in_comment) {
index = strstr(buffer, "<!--");
if (index == NULL) { // Nothing found. print next 412 characters, seek to next startpoint.
if (file_len > buffsize) {
fwrite(buffer, 1, MIN(buffsize-100, n), stream);
fpos += MIN(buffsize-100, n);
_seek(fd, fpos, SEEK_SET);
} else {
fwrite(buffer, 1, n, stream);
fpos += n;
}
} else {
found = (int)index - (int)buffer; // We have found a comment initializer. Seek to the startpoint and print the beginning of the buffer.
fwrite (buffer, 1, found, stream);
fpos += found;
_seek(fd, fpos, SEEK_SET);
in_comment = 1;
}
} else { // Ok, we assume we are "into" a comment.
index = strstr(buffer, "-->");
if (index == NULL) { // We have not found the end of the comment in the next 512 characters. Byepass this comment.
fwrite(buffer, 1, MIN(buffsize, n), stream);
fpos += MIN(buffsize, n);
in_comment = 0;
} else { // Ok. This seems to be a comment with maximum length of 512 bytes. We now search for ssi code.
found = (int)index - (int)buffer;
if (!NutSsiCheckForSsi(stream, buffer, found, http_root, req)) {
fwrite(buffer, 1, found+3, stream);
}
fpos += found+3;
_seek(fd, fpos, SEEK_SET);
in_comment = 0;
}
}
}
NutHeapFree(buffer);
}
/*!
* \brief Register SSI handler for shtml files.
*
* shtml files may use the following ssi commands:
*
* <!--#include virtual="/news/news.htm" -->
* <!--#include file="UROM:/news/news.htm" -->
* <!--#exec cgi="/cgi-bin/counter.cgi" -->
*/
void NutRegisterSsi(void)
{
NutSetMimeHandler(".shtml", NutHttpProcessSHTML);
}
#endif
ssi.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef SSI_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define SSI_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
extern void NutRegisterSsi(void);
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif
wins.c 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
/* ********************************************************* */
/*
Netbios WINS (RFC 1002) Name Query.
Only Query Request Client Routine sending/Positive Name Query Response receiving
are implemented.
When the Netbios Name Query request UDP datagram is on the ethernet network, asking
"Who is 'name'?", NutWinsNameQuery answers with the specified 'ipaddr' Ethernut IP address.
Answer to Microsoft Windows/Internet Explorer calls by "http://name" command line
(and even directly "name" as command line if "name" is not a shared folder).
*/
/* ********************************************************* */
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define WINS_C
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include <ctype.h>
#include <string.h>
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#include "Common.h"
#include "XCore.h"
#include "XNutOS.h"
#include "..\net\socket.h"
#include "..\net\sock_var.h"
#include "..\net\in.h"
#include "wins.h"
#if defined(NUTNET)
/******************************************************************************
* *
* L O C A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L T Y P E D E F S *
* *
******************************************************************************/
typedef struct {
u_short id;
u_short flags;
u_short quests;
u_short answers;
u_short authrr;
u_short addrr;
u_char namelen;
u_char name[33];
u_short type;
u_short class; /* end of request */
u_char ttl[4];
u_short len_rep;
u_char node_flags;
u_char node_type;
u_char ip_addr[4]; /* end of answer */
} WINSQUERY;
/******************************************************************************
* *
* L O C A L F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L I N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* L O C A L U N I T I A L I Z E D D A T A D E F I N I T I O N S *
* *
******************************************************************************/
static void NutCompressedName(u_char * encoded, char * name, u_char last)
{
u_char car;
int i, j;
j = 0;
for (i = 0; i < 16; i++) { /* label 'compression' */
car = toupper(i < strlen(name) ? name[i] : ' ');
if (i == 15)
car = last;
encoded[j] = (car >> 4) + 'A';
encoded[j + 1] = (car & 0xf) + 'A';
j += 2;
}
encoded[j] = 0;
}
/* ********************************************************* */
/* name : netbios label (15 chars max), ipaddr : network ordered IP address bytes */
int NutWinsNameQuery(char * name, u_long ipaddr)
{
WINSQUERY *pkt = NULL;
u_char *encoded = NULL;
UDPSOCKET *sock;
u_long raddr;
u_short rport;
if (strlen(name) > 15)
return -1;
if (((pkt = NutHeapAllocClear(sizeof(WINSQUERY))) == NULL) || /* */
((encoded = NutHeapAllocClear(33)) == NULL) || /* */
((sock = NutUdpCreateSocket(137)) == 0) /* NETBIOS UDP port */
) {
if (pkt != NULL)
NutHeapFree(pkt);
if (encoded != NULL)
NutHeapFree(encoded);
return -1;
}
NutCompressedName(encoded, name, 0);
for (;;) { /* infinite loop / Netbios deamon */
NutUdpReceiveFrom(sock, &raddr, &rport, pkt, sizeof(WINSQUERY), 0);
/* RFC1002 Name Query Request verification */
if (((ntohs(pkt->flags) & 0xf800) != 0) || /* */
(ntohs(pkt->quests) != 1) || /* */
(pkt->namelen != 0x20) || /* */
(ntohs(pkt->type) != 32) || /* */
(ntohs(pkt->class) != 1) || /* */
(strcmp((char *)pkt->name, (char *)encoded)))
continue; /* bad request, try again */
/* build RFC1002 Positive Name Query Response */
pkt->flags = htons(0x8580); /* Response flags */
pkt->answers = htons(1);
pkt->ttl[0] = 0;
pkt->ttl[1] = 0;
pkt->ttl[2] = 0;
pkt->ttl[3] = 60; /* 60 seconds validity */
pkt->len_rep = htons(6);
pkt->node_flags = pkt->node_type = pkt->quests = 0; /* B-type node, etc... */
pkt->ip_addr[0] = (ipaddr & 0xff); /* Returned IP Address, end of answer */
pkt->ip_addr[1] = (ipaddr & 0xff00) >> 8;
pkt->ip_addr[2] = (ipaddr & 0xff0000) >> 16;
pkt->ip_addr[3] = (ipaddr & 0xff000000) >> 24;
NutUdpSendTo(sock, raddr, 137, pkt, sizeof(WINSQUERY)); /* send to netbios port */
memset(pkt, 0, sizeof(WINSQUERY));
}
}
#endif
wins.h 。。。。。。。。。。。。。。。。。。。。。。。。。。。
#ifndef WINS_H
/******************************************************************************
* *
* M O D U L E D E F I N E *
* *
******************************************************************************/
#define WINS_H
/******************************************************************************
* *
* C O M P I L E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* U S E R D E F I N E D I N C L U D E F I L E S *
* *
******************************************************************************/
#ifdef __cplusplus
extern "C" { /* Assume C declarations for C++ */
#endif /* __cplusplus */
/******************************************************************************
* *
* G L O B A L D E F I N E S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* S T R U C T U R E D E F I N I T I O N S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - N O I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* G L O B A L V A R I A B L E S - I N I T I A L I Z E R S *
* *
******************************************************************************/
/* None */
/******************************************************************************
* *
* F U N C T I O N P R O T O T Y P E S *
* *
******************************************************************************/
int NutWinsNameQuery(char * name, u_long ipaddr);
#ifdef __cplusplus
} /* End of extern "C" { */
#endif /* __cplusplus */
#endif