📄 ilibparsers.c
字号:
/*
* INTEL CONFIDENTIAL
* Copyright (c) 2002, 2003 Intel Corporation. All rights reserved.
*
* The source code contained or described herein and all documents
* related to the source code ("Material") are owned by Intel
* Corporation or its suppliers or licensors. Title to the
* Material remains with Intel Corporation or its suppliers and
* licensors. The Material contains trade secrets and proprietary
* and confidential information of Intel or its suppliers and
* licensors. The Material is protected by worldwide copyright and
* trade secret laws and treaty provisions. No part of the Material
* may be used, copied, reproduced, modified, published, uploaded,
* posted, transmitted, distributed, or disclosed in any way without
* Intel's prior express written permission.
* No license under any patent, copyright, trade secret or other
* intellectual property right is granted to or conferred upon you
* by disclosure or delivery of the Materials, either expressly, by
* implication, inducement, estoppel or otherwise. Any license
* under such intellectual property rights must be express and
* approved by Intel in writing.
*
* $Workfile: ILibParsers.c
* $Revision: #1.0.1868.18043
* $Author: Intel Corporation, Intel Device Builder
* $Date: Wednesday, April 06, 2005
*
*
*
*/
#if defined(WINSOCK2)
#include <winsock2.h>
#include <ws2tcpip.h>
#elif defined(WINSOCK1)
#include <winsock.h>
#include <wininet.h>
#endif
#if defined(WIN32)
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>
#endif
#include "ILibParsers.h"
#ifdef MALLOC
#include "ti_dmalloc.h"
#include "dmalloc.h"
#endif
//#include <linux/pr.h>
#define DEBUGSTATEMENT(x)
#define MINPORTNUMBER 50000
#define PORTNUMBERRANGE 15000
#define UPNP_MAX_WAIT 86400 // 24 Hours
#if defined(WIN32) || defined(_WIN32_WCE)
static sem_t ILibChainLock = NULL;
#else
extern int errno;
static sem_t ILibChainLock;
#endif
static int ILibChainLock_RefCounter = 0;
static int malloc_counter = 0;
void* dbg_malloc(int sz)
{
++malloc_counter;
return((void*)malloc(sz));
}
void dbg_free(void* ptr)
{
--malloc_counter;
free(ptr);
}
int dbg_GetCount()
{
return(malloc_counter);
}
//
// All of the following structures are meant to be private internal structures
//
struct ILibStackNode
{
void *Data;
struct ILibStackNode *Next;
};
struct ILibQueueNode
{
struct ILibStackNode *Head;
struct ILibStackNode *Tail;
sem_t LOCK;
};
struct HashNode_Root
{
struct HashNode *Root;
sem_t LOCK;
};
struct HashNode
{
struct HashNode *Next;
struct HashNode *Prev;
int KeyHash;
char *KeyValue;
int KeyLength;
char *Data;
};
struct HashNodeEnumerator
{
struct HashNode *node;
};
struct ILibLinkedListNode
{
void *Data;
struct ILibLinkedListNode_Root *Root;
struct ILibLinkedListNode *Next;
struct ILibLinkedListNode *Previous;
};
struct ILibLinkedListNode_Root
{
sem_t LOCK;
long count;
struct ILibLinkedListNode *Head;
struct ILibLinkedListNode *Tail;
};
#ifdef WINSOCK2
int ILibGetLocalIPAddressNetMask(int address)
{
SOCKET s;
DWORD bytesReturned;
SOCKADDR_IN* pAddrInet;
INTERFACE_INFO localAddr[10]; // Assume there will be no more than 10 IP interfaces
int numLocalAddr;
int i;
if((s = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, 0)) == INVALID_SOCKET)
{
fprintf (stderr, "Socket creation failed\n");
return(0);
}
// Enumerate all IP interfaces
if(WSAIoctl(s, SIO_GET_INTERFACE_LIST, NULL, 0, &localAddr,
sizeof(localAddr), &bytesReturned, NULL, NULL) == SOCKET_ERROR)
{
fprintf(stderr, "WSAIoctl fails with error %d\n", GetLastError());
closesocket(s);
return(0);
}
closesocket(s);
// Display interface information
numLocalAddr = (bytesReturned/sizeof(INTERFACE_INFO));
for (i=0; i<numLocalAddr; i++)
{
pAddrInet = (SOCKADDR_IN*)&localAddr[i].iiAddress;
if(pAddrInet->sin_addr.S_un.S_addr == address)
{
pAddrInet = (SOCKADDR_IN*)&localAddr[i].iiNetmask;
return(pAddrInet->sin_addr.s_addr);
}
}
return(0);
}
#endif
/*! \fn ILibGetLocalIPAddressList(int** pp_int)
\brief Gets a list of IP Addresses
\para
\b NOTE: \a pp_int must be freed
\param[out] pp_int Array of IP Addresses
\returns Number of IP Addresses returned
*/
int ILibGetLocalIPAddressList(int** pp_int)
{
//
// Winsock2 will use an Ioctl call to fetch the IPAddress list
//
#if defined(WINSOCK2)
int i;
char buffer[16*sizeof(SOCKET_ADDRESS_LIST)];
DWORD bufferSize;
SOCKET TempSocket = socket(AF_INET,SOCK_DGRAM,0);
WSAIoctl(TempSocket,SIO_ADDRESS_LIST_QUERY,NULL,0,buffer,16*sizeof(SOCKET_ADDRESS_LIST),&bufferSize,NULL,NULL);
*pp_int = (int*)malloc(sizeof(int)*(1+((SOCKET_ADDRESS_LIST*)buffer)->iAddressCount));
for (i = 0;i < ((SOCKET_ADDRESS_LIST*)buffer)->iAddressCount;++i)
{
(*pp_int)[i] = ((struct sockaddr_in*)(((SOCKET_ADDRESS_LIST*)buffer)->Address[i].lpSockaddr))->sin_addr.s_addr;
}
(*pp_int)[i] = inet_addr("127.0.0.1");
closesocket(TempSocket);
return(1+((SOCKET_ADDRESS_LIST*)buffer)->iAddressCount);
#elif defined(WINSOCK1)
//
// Winsock1 will use gethostbyname to fetch the IPAddress List
//
char name[256];
int i = 0;
int num = 0;
struct hostent *entry;
unsigned int pr_mark = CFGMGR_PR_MARK;
gethostname(name,256);
/* Adding an option which allows to pass a mark value for a particular
* socket. */
#if 0
entry = (struct hostent*)gethostbyname(name);
#else
entry = (struct hostent*)ti_gethostbyname(name, pr_mark);
#endif
if (entry->h_length != 4) return 0;
while (entry->h_addr_list[num]!=0) ++num;
*pp_int = (int*)malloc(sizeof(int)*num);
for (i = 0;i < num;++i)
{
(*pp_int)[i] = *((u_long*)entry->h_addr_list[i]);
}
return num;
#elif _POSIX
//
// Posix will also use an Ioctl call to get the IPAddress List
//
char szBuffer[16*sizeof(struct ifreq)];
struct ifconf ifConf;
struct ifreq ifReq;
int nResult;
int LocalSock;
struct sockaddr_in LocalAddr;
int tempresults[16];
int ctr=0;
int i;
/* Create an unbound datagram socket to do the SIOCGIFADDR ioctl on. */
if ((LocalSock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
{
DEBUGSTATEMENT(printf("Can't do that\r\n"));
exit(1);
}
/* Get the interface configuration information... */
ifConf.ifc_len = sizeof szBuffer;
ifConf.ifc_ifcu.ifcu_buf = (caddr_t)szBuffer;
nResult = ioctl(LocalSock, SIOCGIFCONF, &ifConf);
if (nResult < 0)
{
DEBUGSTATEMENT(printf("ioctl error\r\n"));
exit(1);
}
/* Cycle through the list of interfaces looking for IP addresses. */
for (i = 0;(i < ifConf.ifc_len);)
{
struct ifreq *pifReq = (struct ifreq *)((caddr_t)ifConf.ifc_req + i);
i += sizeof *pifReq;
/* See if this is the sort of interface we want to deal with. */
strcpy (ifReq.ifr_name, pifReq -> ifr_name);
if (ioctl (LocalSock, SIOCGIFFLAGS, &ifReq) < 0)
{
DEBUGSTATEMENT(printf("Can't get flags\r\n"));
exit(1);
}
/* Skip loopback, point-to-point and down interfaces, */
/* except don't skip down interfaces */
/* if we're trying to get a list of configurable interfaces. */
if ((ifReq.ifr_flags & IFF_LOOPBACK) || (!(ifReq.ifr_flags & IFF_UP)))
{
continue;
}
if (pifReq -> ifr_addr.sa_family == AF_INET)
{
/* Get a pointer to the address... */
memcpy (&LocalAddr, &pifReq -> ifr_addr, sizeof pifReq -> ifr_addr);
if (LocalAddr.sin_addr.s_addr != htonl (INADDR_LOOPBACK))
{
tempresults[ctr] = LocalAddr.sin_addr.s_addr;
++ctr;
}
}
}
close(LocalSock);
*pp_int = (int*)malloc(sizeof(int)*(ctr));
memcpy(*pp_int,tempresults,sizeof(int)*ctr);
return(ctr);
#endif
return 0;
}
struct ILibChain
{
void (*PreSelect)(void* object,fd_set *readset, fd_set *writeset, fd_set *errorset, int* blocktime);
void (*PostSelect)(void* object,int slct, fd_set *readset, fd_set *writeset, fd_set *errorset);
void (*Destroy)(void* object);
};
struct LifeTimeMonitorData
{
unsigned long ExpirationTick;
void *data;
void (*CallbackPtr)(void *data);
void (*DestroyPtr)(void *data);
struct LifeTimeMonitorData *Prev;
struct LifeTimeMonitorData *Next;
};
struct ILibLifeTime
{
void (*PreSelect)(void* object,fd_set *readset, fd_set *writeset, fd_set *errorset, int* blocktime);
void (*PostSelect)(void* object,int slct, fd_set *readset, fd_set *writeset, fd_set *errorset);
void (*Destroy)(void* object);
struct LifeTimeMonitorData *LM;
void *Chain;
void *Reserved;
sem_t SyncLock;
};
struct ILibBaseChain
{
int TerminateFlag;
#if defined(WIN32) || defined(_WIN32_WCE)
SOCKET Terminate;
#else
FILE *TerminateReadPipe;
FILE *TerminateWritePipe;
#endif
void *Object;
void *Next;
};
//
// Do not Modify this method.
// This decompresses compressed string blocks, which is used to store the
// various description documents
//
char* ILibDecompressString(unsigned char* CurrentCompressed, const int bufferLength, const int DecompressedLength)
{
unsigned char *RetVal = (char*)malloc(DecompressedLength+1);
unsigned char *CurrentUnCompressed = RetVal;
unsigned char *EndPtr = RetVal + DecompressedLength;
int offset,length;
do
{
/* UnCompressed Data Block */
memcpy(CurrentUnCompressed,CurrentCompressed+1,(int)*CurrentCompressed);
MEMCHECK(assert((int)*CurrentCompressed <= (DecompressedLength+1) );)
CurrentUnCompressed += (int)*CurrentCompressed;
CurrentCompressed += 1+((int)*CurrentCompressed);
/* CompressedBlock */
#ifdef REQUIRES_MEMORY_ALIGNMENT
length = (unsigned short)((*(CurrentCompressed)) & 63);
offset = ((unsigned short)(*(CurrentCompressed+1))<<2) + (((unsigned short)(*(CurrentCompressed))) >> 6);
#else
length = (*((unsigned short*)(CurrentCompressed)))&((unsigned short)63);
offset = (*((unsigned short*)(CurrentCompressed)))>>6;
#endif
memcpy(CurrentUnCompressed,CurrentUnCompressed-offset,length);
MEMCHECK(assert(length <= (DecompressedLength+1)-(CurrentUnCompressed - RetVal));)
CurrentCompressed += 2;
CurrentUnCompressed += length;
} while(CurrentUnCompressed < EndPtr);
RetVal[DecompressedLength] = 0;
return(RetVal);
}
/*! \fn ILibCreateChain()
\brief Creates an empty Chain
\returns Chain
*/
void *ILibCreateChain()
{
struct ILibBaseChain *RetVal = (struct ILibBaseChain*)malloc(sizeof(struct ILibBaseChain));
#if defined(WIN32) || defined(_WIN32_WCE)
WORD wVersionRequested;
WSADATA wsaData;
#ifdef WINSOCK1
wVersionRequested = MAKEWORD( 1, 1 );
#elif WINSOCK2
wVersionRequested = MAKEWORD( 2, 0 );
#endif
if (WSAStartup( wVersionRequested, &wsaData ) != 0) {exit(1);}
RetVal->Terminate = socket(AF_INET, SOCK_DGRAM, 0);
#endif
memset(RetVal,0,sizeof(struct ILibBaseChain));
srand((unsigned int)time(NULL));
RetVal->Object = NULL;
RetVal->Next = NULL;
RetVal->TerminateFlag = 0;
#if defined(WIN32) || defined(_WIN32_WCE)
RetVal->Terminate = socket(AF_INET, SOCK_DGRAM, 0);
#endif
if(ILibChainLock_RefCounter==0)
{
sem_init(&ILibChainLock,0,1);
}
return(RetVal);
}
/*! \fn ILibAddToChain(void *Chain, void *object)
\brief Add links to the chain
\para
\b Note: All objects added to the chain must extend/implement ILibChain
\param Chain The chain to add the link to
\param object The link to add to the chain
*/
void ILibAddToChain(void *Chain, void *object)
{
struct ILibBaseChain *chain = (struct ILibBaseChain*)Chain;
//
// Add link to the end of the chain (Linked List)
//
while(chain->Next!=NULL)
{
chain = chain->Next;
}
if(chain->Object!=NULL)
{
chain->Next = (struct ILibBaseChain*)malloc(sizeof(struct ILibBaseChain));
chain = chain->Next;
}
chain->Object = object;
chain->Next = NULL;
}
/*! \fn ILibForceUnBlockChain(void *Chain)
\brief Forces a Chain to unblock, and check for pending operations
\param Chain The chain to unblock
*/
void ILibForceUnBlockChain(void *Chain)
{
struct ILibBaseChain *c = (struct ILibBaseChain*)Chain;
#if defined(WIN32) || defined(_WIN32_WCE)
SOCKET temp;
#endif
sem_wait(&ILibChainLock);
#if defined(WIN32) || defined(_WIN32_WCE)
//
// Closing the socket will trigger the select on Windows
//
temp = c->Terminate;
c->Terminate = ~0;
closesocket(temp);
#else
//
// Writing data on the pipe will trigger the select on Posix
//
if(c->TerminateWritePipe!=NULL)
{
fprintf(c->TerminateWritePipe," ");
fflush(c->TerminateWritePipe);
}
#endif
sem_post(&ILibChainLock);
}
/*! \fn ILibStartChain(void *Chain)
\brief Starts a Chain
\para
This method will use the current thread. This thread will be refered to as the
microstack thread. All events and processing will be done on this thread. This method
will not return until ILibStopChain is called.
\param Chain The chain to start
*/
void ILibStartChain(void *Chain)
{
struct ILibBaseChain *c = (struct ILibBaseChain*)Chain;
struct ILibBaseChain *temp;
fd_set readset;
fd_set errorset;
fd_set writeset;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -