⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wspiapi.h

📁 IP协议分析工具ipdog开源代码 好东西
💻 H
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c) 2000, Microsoft Corporation

Module Name:
    wspiapi.h

Abstract:
    The file contains protocol independent API functions.

Revision History:
    Wed Jul 12 10:50:31 2000, Created

--*/

#ifndef _WSPIAPI_H_
#define _WSPIAPI_H_

#include <stdio.h>              // sprintf()
#include <stdlib.h>             // calloc(), strtoul()
#include <malloc.h>             // calloc()
#include <string.h>             // strlen(), strcmp(), strstr()

#define WspiapiMalloc(tSize)    calloc(1, (tSize))
#define WspiapiFree(p)          free(p)
#define WspiapiSwap(a, b, c)    { (c) = (a); (a) = (b); (b) = (c); }
#define getaddrinfo             WspiapiGetAddrInfo
#define getnameinfo             WspiapiGetNameInfo
#define freeaddrinfo            WspiapiFreeAddrInfo

typedef int (WINAPI *WSPIAPI_PGETADDRINFO) (
    IN  const char                      *nodename,
    IN  const char                      *servname,
    IN  const struct addrinfo           *hints,
    OUT struct addrinfo                 **res);

typedef int (WINAPI *WSPIAPI_PGETNAMEINFO) (
    IN  const struct sockaddr           *sa,
    IN  socklen_t                       salen,
    OUT char                            *host,
    IN  size_t                          hostlen,
    OUT char                            *serv,
    IN  size_t                          servlen,
    IN  int                             flags);

typedef void (WINAPI *WSPIAPI_PFREEADDRINFO) (
    IN  struct addrinfo                 *ai);



#ifdef __cplusplus
extern "C" {
#endif
    
////////////////////////////////////////////////////////////
// v4 only versions of getaddrinfo and friends.
// NOTE: gai_strerror is inlined in ws2tcpip.h
////////////////////////////////////////////////////////////

_inline    
char *
WINAPI
WspiapiStrdup (
	IN  const char *                    pszString)
/*++

Routine Description
    allocates enough storage via calloc() for a copy of the string,
    copies the string into the new memory, and returns a pointer to it.

Arguments
    pszString       string to copy into new memory

Return Value
    a pointer to the newly allocated storage with the string in it.
    NULL if enough memory could not be allocated, or string was NULL.

--*/    
{
    char    *pszMemory;

    if (!pszString)
        return(NULL);

    pszMemory = (char *) WspiapiMalloc(strlen(pszString) + 1);
    if (!pszMemory)
        return(NULL);

    return(strcpy(pszMemory, pszString));
}

    
    
__inline
BOOL
WINAPI
WspiapiParseV4Address (
    IN  const char *                    pszAddress,
    OUT PDWORD                          pdwAddress)
/*++

Routine Description
    get the IPv4 address (in network byte order) from its string
    representation.  the syntax should be a.b.c.d.
    
Arguments
    pszArgument         string representation of the IPv4 address
    ptAddress           pointer to the resulting IPv4 address

Return Value
    Returns FALSE if there is an error, TRUE for success.
    
--*/
{
    DWORD       dwAddress   = 0;
    const char  *pcNext     = NULL;
    int         iCount      = 0;

    // ensure there are 3 '.' (periods)
    for (pcNext = pszAddress; *pcNext != '\0'; pcNext++)
        if (*pcNext == '.')
            iCount++;
    if (iCount != 3)
        return FALSE;

    // return an error if dwAddress is INADDR_NONE (255.255.255.255)
    // since this is never a valid argument to getaddrinfo.
    dwAddress = inet_addr(pszAddress);
    if (dwAddress == INADDR_NONE)
        return FALSE;

    *pdwAddress = dwAddress;
    return TRUE;
}



__inline
struct addrinfo *
WINAPI
WspiapiNewAddrInfo (
    IN  int                             iSocketType,
    IN  int                             iProtocol,
    IN  WORD                            wPort,
    IN  DWORD                           dwAddress)
/*++

Routine Description
    allocate an addrinfo structure and populate fields.
    IPv4 specific internal function, not exported.
    
Arguments
    iSocketType         SOCK_*.  can be wildcarded (zero).
    iProtocol           IPPROTO_*.  can be wildcarded (zero).
    wPort               port number of service (in network order).
    dwAddress           IPv4 address (in network order).
    
Return Value
    returns an addrinfo struct, or NULL if out of memory.

--*/    
{
    struct addrinfo     *ptNew;
    struct sockaddr_in  *ptAddress;

    // allocate a new addrinfo structure.
    ptNew       =
        (struct addrinfo *) WspiapiMalloc(sizeof(struct addrinfo));
    if (!ptNew)
        return NULL;

    ptAddress   =
        (struct sockaddr_in *) WspiapiMalloc(sizeof(struct sockaddr_in));
    if (!ptAddress)
    {
        WspiapiFree(ptNew);
        return NULL;
    }
    ptAddress->sin_family       = AF_INET;
    ptAddress->sin_port         = wPort;
    ptAddress->sin_addr.s_addr  = dwAddress;
    
    // fill in the fields...
    ptNew->ai_family            = PF_INET;
    ptNew->ai_socktype          = iSocketType;
    ptNew->ai_protocol          = iProtocol;
    ptNew->ai_addrlen           = sizeof(struct sockaddr_in);
    ptNew->ai_addr              = (struct sockaddr *) ptAddress;

    return ptNew;
}



__inline
int
WINAPI
WspiapiQueryDNS(
    IN  const char                      *pszNodeName,
    IN  int                             iSocketType,
    IN  int                             iProtocol,  
    IN  WORD                            wPort,      
    OUT char                            *pszAlias,
    OUT struct addrinfo                 **pptResult)
/*++

Routine Description
    helper routine for WspiapiLookupNode.
    performs name resolution by querying the DNS for A records.
    *pptResult would need to be freed if an error is returned.
    
Arguments
    pszNodeName         name of node to resolve.
    iSocketType         SOCK_*.  can be wildcarded (zero).
    iProtocol           IPPROTO_*.  can be wildcarded (zero).
    wPort               port number of service (in network order).
    pszAlias            where to return the alias.
    pptResult           where to return the result.
    
Return Value
    Returns 0 on success, an EAI_* style error value otherwise.

--*/    
{
    struct addrinfo **pptNext   = pptResult;
    struct hostent  *ptHost     = NULL;
    char            **ppAddresses;

    *pptNext    = NULL;
    pszAlias[0] = '\0';

    ptHost = gethostbyname(pszNodeName);
    if (ptHost)
    {
        if ((ptHost->h_addrtype == AF_INET)     &&
            (ptHost->h_length   == sizeof(struct in_addr)))
        {
            for (ppAddresses    = ptHost->h_addr_list;
                 *ppAddresses   != NULL;
                 ppAddresses++)
            {
                // create an addrinfo structure...
                *pptNext = WspiapiNewAddrInfo(
                    iSocketType,
                    iProtocol,
                    wPort,
                    ((struct in_addr *) *ppAddresses)->s_addr);
                if (!*pptNext)
                    return EAI_MEMORY;

                pptNext = &((*pptNext)->ai_next);
            }
        }

        // pick up the canonical name.
        strcpy(pszAlias, ptHost->h_name);
        return 0;
    }
    
    switch (WSAGetLastError())
    {
        case WSAHOST_NOT_FOUND: return EAI_NONAME;
        case WSATRY_AGAIN:      return EAI_AGAIN;
        case WSANO_RECOVERY:    return EAI_FAIL;
        case WSANO_DATA:        return EAI_NODATA;
        default:                return EAI_NONAME;
    }
}



__inline
int
WINAPI
WspiapiLookupNode(
    IN  const char                      *pszNodeName,
    IN  int                             iSocketType,
    IN  int                             iProtocol,  
    IN  WORD                            wPort,      
    IN  BOOL                            bAI_CANONNAME,
    OUT struct addrinfo                 **pptResult)
/*++

Routine Description
    resolve a nodename and return a list of addrinfo structures.
    IPv4 specific internal function, not exported.
    *pptResult would need to be freed if an error is returned.
    
    NOTE: if bAI_CANONNAME is true, the canonical name should be
          returned in the first addrinfo structure.
    
Arguments
    pszNodeName         name of node to resolve.
    iSocketType         SOCK_*.  can be wildcarded (zero).
    iProtocol           IPPROTO_*.  can be wildcarded (zero).
    wPort               port number of service (in network order).
    bAI_CANONNAME       whether the AI_CANONNAME flag is set.
    pptResult           where to return result.
    
Return Value
    Returns 0 on success, an EAI_* style error value otherwise.

--*/
{
    int     iError              = 0;
    int     iAliasCount         = 0;

    char    szFQDN1[NI_MAXHOST] = "";
    char    szFQDN2[NI_MAXHOST] = "";
    char    *pszName            = szFQDN1;
    char    *pszAlias           = szFQDN2;
    char    *pszScratch         = NULL;
    strcpy(pszName, pszNodeName);

    for (;;)
    {
        iError = WspiapiQueryDNS(pszNodeName,
                                 iSocketType,
                                 iProtocol,
                                 wPort,
                                 pszAlias,
                                 pptResult);
        if (iError)
            break;

        // if we found addresses, then we are done.
        if (*pptResult)
            break;

        // stop infinite loops due to DNS misconfiguration.  there appears
        // to be no particular recommended limit in RFCs 1034 and 1035.
        if ((!strlen(pszAlias))             ||
            (!strcmp(pszName, pszAlias))    ||
            (++iAliasCount == 16))
        {
            iError = EAI_FAIL;
            break;
        }

        // there was a new CNAME, look again.
        WspiapiSwap(pszName, pszAlias, pszScratch);
    }

    if (!iError && bAI_CANONNAME)
    {
        (*pptResult)->ai_canonname = WspiapiStrdup(pszAlias);
        if (!(*pptResult)->ai_canonname)
            iError = EAI_MEMORY;
    }

    return iError;
}



__inline
int
WINAPI
WspiapiClone (
    IN  WORD                            wPort,      
    IN  struct addrinfo                 *ptResult)
/*++

Routine Description
    clone every addrinfo structure in ptResult for the UDP service.
    ptResult would need to be freed if an error is returned.
    
Arguments
    wPort               port number of UDP service.
    ptResult            list of addrinfo structures, each
                        of whose node needs to be cloned.

Return Value
    Returns 0 on success, an EAI_MEMORY on allocation failure.

--*/
{
    struct addrinfo *ptNext = NULL;
    struct addrinfo *ptNew  = NULL;

    for (ptNext = ptResult; ptNext != NULL; )
    {
        // create an addrinfo structure...
        ptNew = WspiapiNewAddrInfo(
            SOCK_DGRAM,
            ptNext->ai_protocol,
            wPort,
            ((struct sockaddr_in *) ptNext->ai_addr)->sin_addr.s_addr);
        if (!ptNew)
            break;

        // link the cloned addrinfo
        ptNew->ai_next  = ptNext->ai_next;
        ptNext->ai_next = ptNew;
        ptNext          = ptNew->ai_next;
    }

    if (ptNext != NULL)
        return EAI_MEMORY;
    
    return 0;
}



__inline
void
WINAPI
WspiapiLegacyFreeAddrInfo (
    IN  struct addrinfo                 *ptHead)
/*++

Routine Description
    Free an addrinfo structure (or chain of structures).
    As specified in RFC 2553, Section 6.4.
    
Arguments
    ptHead              structure (chain) to free
    
--*/    
{
    struct addrinfo *ptNext;    // next strcture to free

    for (ptNext = ptHead; ptNext != NULL; ptNext = ptHead)
    {
        if (ptNext->ai_canonname)
            WspiapiFree(ptNext->ai_canonname);
        
        if (ptNext->ai_addr)
            WspiapiFree(ptNext->ai_addr);

        ptHead = ptNext->ai_next;
        WspiapiFree(ptNext);
    }
}



__inline
int
WINAPI
WspiapiLegacyGetAddrInfo(
    IN const char                       *pszNodeName,
    IN const char                       *pszServiceName,
    IN const struct addrinfo            *ptHints,
    OUT struct addrinfo                 **pptResult)
/*++

Routine Description
    Protocol-independent name-to-address translation.
    As specified in RFC 2553, Section 6.4.
    This is the hacked version that only supports IPv4.
    
Arguments
    pszNodeName         node name to lookup.
    pszServiceName      service name to lookup.
    ptHints             hints about how to process request.
    pptResult           where to return result.
    
Return Value
    returns zero if successful, an EAI_* error code if not.

--*/    
{
    int                 iError      = 0;
    int                 iFlags      = 0;
    int                 iFamily     = PF_UNSPEC;
    int                 iSocketType = 0;
    int                 iProtocol   = 0;
    WORD                wPort       = 0;
    DWORD               dwAddress   = 0;

    struct servent      *ptService  = NULL;
    char                *pc         = NULL;
    BOOL                bClone      = FALSE;
    WORD                wTcpPort    = 0;
    WORD                wUdpPort    = 0;
    
    
    // initialize pptResult with default return value.
    *pptResult  = NULL;


    ////////////////////////////////////////
    // validate arguments...
    //
    
    // both the node name and the service name can't be NULL.
    if ((!pszNodeName) && (!pszServiceName))
        return EAI_NONAME;

    // validate hints.
    if (ptHints)
    {
        // all members other than ai_flags, ai_family, ai_socktype
        // and ai_protocol must be zero or a null pointer.
        if ((ptHints->ai_addrlen    != 0)       ||
            (ptHints->ai_canonname  != NULL)    ||
            (ptHints->ai_addr       != NULL)    ||
            (ptHints->ai_next       != NULL))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -