T168_111\system\Ethernet\pro:第23~34

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

  • 8
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值