1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2024-11-07 10:10:41 +03:00
SoftEtherVPN/src/Mayaqua/Pack.c

1737 lines
33 KiB
C
Raw Normal View History

2014-01-04 17:00:08 +04:00
// SoftEther VPN Source Code
// Mayaqua Kernel
//
// SoftEther VPN Server, Client and Bridge are free software under GPLv2.
//
2015-07-16 18:31:57 +03:00
// Copyright (c) 2012-2015 Daiyuu Nobori.
// Copyright (c) 2012-2015 SoftEther VPN Project, University of Tsukuba, Japan.
// Copyright (c) 2012-2015 SoftEther Corporation.
2014-01-04 17:00:08 +04:00
//
// All Rights Reserved.
//
// http://www.softether.org/
//
// Author: Daiyuu Nobori
// Comments: Tetsuo Sugiyama, Ph.D.
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// version 2 as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License version 2
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
// CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
// THE LICENSE AGREEMENT IS ATTACHED ON THE SOURCE-CODE PACKAGE
// AS "LICENSE.TXT" FILE. READ THE TEXT FILE IN ADVANCE TO USE THE SOFTWARE.
//
//
// THIS SOFTWARE IS DEVELOPED IN JAPAN, AND DISTRIBUTED FROM JAPAN,
// UNDER JAPANESE LAWS. YOU MUST AGREE IN ADVANCE TO USE, COPY, MODIFY,
// MERGE, PUBLISH, DISTRIBUTE, SUBLICENSE, AND/OR SELL COPIES OF THIS
// SOFTWARE, THAT ANY JURIDICAL DISPUTES WHICH ARE CONCERNED TO THIS
// SOFTWARE OR ITS CONTENTS, AGAINST US (SOFTETHER PROJECT, SOFTETHER
// CORPORATION, DAIYUU NOBORI OR OTHER SUPPLIERS), OR ANY JURIDICAL
// DISPUTES AGAINST US WHICH ARE CAUSED BY ANY KIND OF USING, COPYING,
// MODIFYING, MERGING, PUBLISHING, DISTRIBUTING, SUBLICENSING, AND/OR
// SELLING COPIES OF THIS SOFTWARE SHALL BE REGARDED AS BE CONSTRUED AND
// CONTROLLED BY JAPANESE LAWS, AND YOU MUST FURTHER CONSENT TO
// EXCLUSIVE JURISDICTION AND VENUE IN THE COURTS SITTING IN TOKYO,
// JAPAN. YOU MUST WAIVE ALL DEFENSES OF LACK OF PERSONAL JURISDICTION
// AND FORUM NON CONVENIENS. PROCESS MAY BE SERVED ON EITHER PARTY IN
// THE MANNER AUTHORIZED BY APPLICABLE LAW OR COURT RULE.
//
2014-07-11 21:06:20 +04:00
// USE ONLY IN JAPAN. DO NOT USE THIS SOFTWARE IN ANOTHER COUNTRY UNLESS
// YOU HAVE A CONFIRMATION THAT THIS SOFTWARE DOES NOT VIOLATE ANY
// CRIMINAL LAWS OR CIVIL RIGHTS IN THAT PARTICULAR COUNTRY. USING THIS
// SOFTWARE IN OTHER COUNTRIES IS COMPLETELY AT YOUR OWN RISK. THE
// SOFTETHER VPN PROJECT HAS DEVELOPED AND DISTRIBUTED THIS SOFTWARE TO
// COMPLY ONLY WITH THE JAPANESE LAWS AND EXISTING CIVIL RIGHTS INCLUDING
// PATENTS WHICH ARE SUBJECTS APPLY IN JAPAN. OTHER COUNTRIES' LAWS OR
// CIVIL RIGHTS ARE NONE OF OUR CONCERNS NOR RESPONSIBILITIES. WE HAVE
// NEVER INVESTIGATED ANY CRIMINAL REGULATIONS, CIVIL LAWS OR
// INTELLECTUAL PROPERTY RIGHTS INCLUDING PATENTS IN ANY OF OTHER 200+
// COUNTRIES AND TERRITORIES. BY NATURE, THERE ARE 200+ REGIONS IN THE
// WORLD, WITH DIFFERENT LAWS. IT IS IMPOSSIBLE TO VERIFY EVERY
// COUNTRIES' LAWS, REGULATIONS AND CIVIL RIGHTS TO MAKE THE SOFTWARE
// COMPLY WITH ALL COUNTRIES' LAWS BY THE PROJECT. EVEN IF YOU WILL BE
// SUED BY A PRIVATE ENTITY OR BE DAMAGED BY A PUBLIC SERVANT IN YOUR
// COUNTRY, THE DEVELOPERS OF THIS SOFTWARE WILL NEVER BE LIABLE TO
// RECOVER OR COMPENSATE SUCH DAMAGES, CRIMINAL OR CIVIL
// RESPONSIBILITIES. NOTE THAT THIS LINE IS NOT LICENSE RESTRICTION BUT
// JUST A STATEMENT FOR WARNING AND DISCLAIMER.
2014-01-04 17:00:08 +04:00
//
//
2014-01-15 13:01:42 +04:00
// SOURCE CODE CONTRIBUTION
// ------------------------
//
// Your contribution to SoftEther VPN Project is much appreciated.
// Please send patches to us through GitHub.
// Read the SoftEther VPN Patch Acceptance Policy in advance:
// http://www.softether.org/5-download/src/9.patch
//
//
2014-01-04 17:00:08 +04:00
// DEAR SECURITY EXPERTS
// ---------------------
//
// If you find a bug or a security vulnerability please kindly inform us
// about the problem immediately so that we can fix the security problem
// to protect a lot of users around the world as soon as possible.
//
// Our e-mail address for security reports is:
// softether-vpn-security [at] softether.org
//
// Please note that the above e-mail address is not a technical support
// inquiry address. If you need technical assistance, please visit
// http://www.softether.org/ and ask your question on the users forum.
//
// Thank you for your cooperation.
2014-03-20 00:45:05 +04:00
//
//
// NO MEMORY OR RESOURCE LEAKS
// ---------------------------
//
// The memory-leaks and resource-leaks verification under the stress
// test has been passed before release this source code.
2014-01-04 17:00:08 +04:00
// Pack.c
// Data package code
#include <GlobalConst.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <stdarg.h>
#include <time.h>
#include <errno.h>
#include <Mayaqua/Mayaqua.h>
// Get a list of the element names in the PACK
TOKEN_LIST *GetPackElementNames(PACK *p)
{
TOKEN_LIST *ret;
UINT i;
// Validate arguments
if (p == NULL)
{
return NULL;
}
ret = ZeroMalloc(sizeof(TOKEN_LIST));
ret->NumTokens = LIST_NUM(p->elements);
ret->Token = ZeroMalloc(sizeof(char *) * ret->NumTokens);
for (i = 0;i < ret->NumTokens;i++)
{
ELEMENT *e = LIST_DATA(p->elements, i);
ret->Token[i] = CopyStr(e->name);
}
return ret;
}
// Convert the BUF to a PACK
PACK *BufToPack(BUF *b)
{
PACK *p;
// Validate arguments
if (b == NULL)
{
return NULL;
}
p = NewPack();
if (ReadPack(b, p) == false)
{
FreePack(p);
return NULL;
}
return p;
}
// Convert the PACK to the BUF
BUF *PackToBuf(PACK *p)
{
BUF *b;
// Validate arguments
if (p == NULL)
{
return NULL;
}
b = NewBuf();
WritePack(b, p);
return b;
}
// Read the PACK
bool ReadPack(BUF *b, PACK *p)
{
UINT i, num;
// Validate arguments
if (b == NULL || p == NULL)
{
return false;
}
// The number of ELEMENTs
num = ReadBufInt(b);
if (num > MAX_ELEMENT_NUM)
{
// Number exceeds
return false;
}
// Read the ELEMENT
for (i = 0;i < num;i++)
{
ELEMENT *e;
e = ReadElement(b);
if (AddElement(p, e) == false)
{
// Adding error
return false;
}
}
return true;
}
// Write down the PACK
void WritePack(BUF *b, PACK *p)
{
UINT i;
// Validate arguments
if (b == NULL || p == NULL)
{
return;
}
// The number of ELEMENTs
WriteBufInt(b, LIST_NUM(p->elements));
// Write the ELEMENT
for (i = 0;i < LIST_NUM(p->elements);i++)
{
ELEMENT *e = LIST_DATA(p->elements, i);
WriteElement(b, e);
}
}
// Read the ELEMENT
ELEMENT *ReadElement(BUF *b)
{
UINT i;
char name[MAX_ELEMENT_NAME_LEN + 1];
UINT type, num_value;
VALUE **values;
ELEMENT *e;
// Validate arguments
if (b == NULL)
{
return NULL;
}
// Name
if (ReadBufStr(b, name, sizeof(name)) == false)
{
return NULL;
}
// Type of item
type = ReadBufInt(b);
// Number of items
num_value = ReadBufInt(b);
if (num_value > MAX_VALUE_NUM)
{
// Number exceeds
return NULL;
}
// VALUE
values = (VALUE **)Malloc(sizeof(VALUE *) * num_value);
for (i = 0;i < num_value;i++)
{
values[i] = ReadValue(b, type);
}
// Create a ELEMENT
e = NewElement(name, type, num_value, values);
Free(values);
return e;
}
// Write the ELEMENT
void WriteElement(BUF *b, ELEMENT *e)
{
UINT i;
// Validate arguments
if (b == NULL || e == NULL)
{
return;
}
// Name
WriteBufStr(b, e->name);
// Type of item
WriteBufInt(b, e->type);
// Number of items
WriteBufInt(b, e->num_value);
// VALUE
for (i = 0;i < e->num_value;i++)
{
VALUE *v = e->values[i];
WriteValue(b, v, e->type);
}
}
// Read the VALUE
VALUE *ReadValue(BUF *b, UINT type)
{
UINT len;
BYTE *u;
void *data;
char *str;
wchar_t *unistr;
UINT unistr_size;
UINT size;
UINT u_size;
VALUE *v = NULL;
// Validate arguments
if (b == NULL)
{
return NULL;
}
// Data item
switch (type)
{
case VALUE_INT: // Integer
v = NewIntValue(ReadBufInt(b));
break;
case VALUE_INT64:
v = NewInt64Value(ReadBufInt64(b));
break;
case VALUE_DATA: // Data
size = ReadBufInt(b);
if (size > MAX_VALUE_SIZE)
{
// Size over
break;
}
data = Malloc(size);
if (ReadBuf(b, data, size) != size)
{
// Read failure
Free(data);
break;
}
v = NewDataValue(data, size);
Free(data);
break;
case VALUE_STR: // ANSI string
len = ReadBufInt(b);
if ((len + 1) > MAX_VALUE_SIZE)
{
// Size over
break;
}
str = Malloc(len + 1);
// String body
if (ReadBuf(b, str, len) != len)
{
// Read failure
Free(str);
break;
}
str[len] = 0;
v = NewStrValue(str);
Free(str);
break;
case VALUE_UNISTR: // Unicode string
u_size = ReadBufInt(b);
if (u_size > MAX_VALUE_SIZE)
{
// Size over
break;
}
// Reading an UTF-8 string
u = ZeroMalloc(u_size + 1);
if (ReadBuf(b, u, u_size) != u_size)
{
// Read failure
Free(u);
break;
}
// Convert to a Unicode string
unistr_size = CalcUtf8ToUni(u, u_size);
if (unistr_size == 0)
{
Free(u);
break;
}
unistr = Malloc(unistr_size);
Utf8ToUni(unistr, unistr_size, u, u_size);
Free(u);
v = NewUniStrValue(unistr);
Free(unistr);
break;
}
return v;
}
// Write the VALUE
void WriteValue(BUF *b, VALUE *v, UINT type)
{
UINT len;
BYTE *u;
UINT u_size;
// Validate arguments
if (b == NULL || v == NULL)
{
return;
}
// Data item
switch (type)
{
case VALUE_INT: // Integer
WriteBufInt(b, v->IntValue);
break;
case VALUE_INT64: // 64 bit integer
WriteBufInt64(b, v->Int64Value);
break;
case VALUE_DATA: // Data
// Size
WriteBufInt(b, v->Size);
// Body
WriteBuf(b, v->Data, v->Size);
break;
case VALUE_STR: // ANSI string
len = StrLen(v->Str);
// Length
WriteBufInt(b, len);
// String body
WriteBuf(b, v->Str, len);
break;
case VALUE_UNISTR: // Unicode string
// Convert to UTF-8
u_size = CalcUniToUtf8(v->UniStr) + 1;
u = ZeroMalloc(u_size);
UniToUtf8(u, u_size, v->UniStr);
// Size
WriteBufInt(b, u_size);
// UTF-8 string body
WriteBuf(b, u, u_size);
Free(u);
break;
}
}
// Get data size
UINT GetDataValueSize(ELEMENT *e, UINT index)
{
// Validate arguments
if (e == NULL)
{
return 0;
}
if (e->values == NULL)
{
return 0;
}
if (index >= e->num_value)
{
return 0;
}
if (e->values[index] == NULL)
{
return 0;
}
return e->values[index]->Size;
}
// Get the data
void *GetDataValue(ELEMENT *e, UINT index)
{
// Validate arguments
if (e == NULL)
{
return NULL;
}
if (e->values == NULL)
{
return NULL;
}
if (index >= e->num_value)
{
return NULL;
}
if (e->values[index] == NULL)
{
return NULL;
}
return e->values[index]->Data;
}
// Get the Unicode string type
wchar_t *GetUniStrValue(ELEMENT *e, UINT index)
{
// Validate arguments
if (e == NULL)
{
return 0;
}
if (index >= e->num_value)
{
return 0;
}
if (e->values[index] == NULL)
{
return NULL;
}
return e->values[index]->UniStr;
}
// Get the ANSI string type
char *GetStrValue(ELEMENT *e, UINT index)
{
// Validate arguments
if (e == NULL)
{
return 0;
}
if (index >= e->num_value)
{
return 0;
}
if (e->values[index] == NULL)
{
return NULL;
}
return e->values[index]->Str;
}
// Get the 64 bit integer value
UINT64 GetInt64Value(ELEMENT *e, UINT index)
{
// Validate arguments
if (e == NULL)
{
return 0;
}
if (index >= e->num_value)
{
return 0;
}
if (e->values[index] == NULL)
{
return 0;
}
return e->values[index]->Int64Value;
}
// Get the integer value
UINT GetIntValue(ELEMENT *e, UINT index)
{
// Validate arguments
if (e == NULL)
{
return 0;
}
if (index >= e->num_value)
{
return 0;
}
if (e->values[index] == NULL)
{
return 0;
}
return e->values[index]->IntValue;
}
// Function of sort for PACK
int ComparePackName(void *p1, void *p2)
{
ELEMENT *o1, *o2;
if (p1 == NULL || p2 == NULL)
{
return 0;
}
o1 = *(ELEMENT **)p1;
o2 = *(ELEMENT **)p2;
if (o1 == NULL || o2 == NULL)
{
return 0;
}
return StrCmpi(o1->name, o2->name);
}
// Delete the VALUE
void FreeValue(VALUE *v, UINT type)
{
// Validate arguments
if (v == NULL)
{
return;
}
switch (type)
{
case VALUE_INT:
case VALUE_INT64:
break;
case VALUE_DATA:
Free(v->Data);
break;
case VALUE_STR:
Free(v->Str);
break;
case VALUE_UNISTR:
Free(v->UniStr);
break;
}
// Memory release
Free(v);
}
// Create a VALUE of Unicode String type
VALUE *NewUniStrValue(wchar_t *str)
{
VALUE *v;
// Validate arguments
if (str == NULL)
{
return NULL;
}
// Memory allocation
v = Malloc(sizeof(VALUE));
// String copy
v->Size = UniStrSize(str);
v->UniStr = Malloc(v->Size);
UniStrCpy(v->UniStr, v->Size, str);
UniTrim(v->UniStr);
return v;
}
// Creation of the VALUE of ANSI string type
VALUE *NewStrValue(char *str)
{
VALUE *v;
// Validate arguments
if (str == NULL)
{
return NULL;
}
// Memory allocation
v = Malloc(sizeof(VALUE));
// String copy
v->Size = StrLen(str) + 1;
v->Str = Malloc(v->Size);
StrCpy(v->Str, v->Size, str);
Trim(v->Str);
return v;
}
// Create the VALUE of the data type
VALUE *NewDataValue(void *data, UINT size)
{
VALUE *v;
// Validate arguments
if (data == NULL)
{
return NULL;
}
// Memory allocation
v = Malloc(sizeof(VALUE));
// Data copy
v->Size = size;
v->Data = Malloc(v->Size);
Copy(v->Data, data, size);
return v;
}
// Create the VALUE of 64 bit integer type
VALUE *NewInt64Value(UINT64 i)
{
VALUE *v;
v = Malloc(sizeof(VALUE));
v->Int64Value = i;
v->Size = sizeof(UINT64);
return v;
}
// Create the VALUE of integer type
VALUE *NewIntValue(UINT i)
{
VALUE *v;
// Memory allocation
v = Malloc(sizeof(VALUE));
v->IntValue = i;
v->Size = sizeof(UINT);
return v;
}
// Delete the ELEMENT
void FreeElement(ELEMENT *e)
{
UINT i;
// Validate arguments
if (e == NULL)
{
return;
}
for (i = 0;i < e->num_value;i++)
{
FreeValue(e->values[i], e->type);
}
Free(e->values);
Free(e);
}
// Create a ELEMENT
ELEMENT *NewElement(char *name, UINT type, UINT num_value, VALUE **values)
{
ELEMENT *e;
UINT i;
// Validate arguments
if (name == NULL || num_value == 0 || values == NULL)
{
return NULL;
}
// Memory allocation
e = Malloc(sizeof(ELEMENT));
StrCpy(e->name, sizeof(e->name), name);
e->num_value = num_value;
e->type = type;
// Copy of the pointer list to the element
e->values = (VALUE **)Malloc(sizeof(VALUE *) * num_value);
for (i = 0;i < e->num_value;i++)
{
e->values[i] = values[i];
}
return e;
}
// Search and retrieve a ELEMENT from the PACK
ELEMENT *GetElement(PACK *p, char *name, UINT type)
{
ELEMENT t;
ELEMENT *e;
// Validate arguments
if (p == NULL || name == NULL)
{
return NULL;
}
// Search
StrCpy(t.name, sizeof(t.name), name);
e = Search(p->elements, &t);
if (e == NULL)
{
return NULL;
}
// Type checking
if (type != INFINITE)
{
if (e->type != type)
{
return NULL;
}
}
return e;
}
2014-07-11 21:06:20 +04:00
// Check whether the specified element exists
bool IsElement(PACK *p, char *name)
{
ELEMENT t;
ELEMENT *e;
// Validate arguments
if (p == NULL || name == NULL)
{
return false;
}
// Search
StrCpy(t.name, sizeof(t.name), name);
e = Search(p->elements, &t);
if (e == NULL)
{
return false;
}
return true;
}
2014-01-04 17:00:08 +04:00
// Remove the ELEMENT from the PACK
void DelElement(PACK *p, char *name)
{
ELEMENT *e;
// Validate arguments
if (p == NULL || name == NULL)
{
return;
}
e = GetElement(p, name, INFINITE);
if (e != NULL)
{
Delete(p->elements, e);
FreeElement(e);
}
}
// Add an ELEMENT to the PACK
bool AddElement(PACK *p, ELEMENT *e)
{
// Validate arguments
if (p == NULL || e == NULL)
{
return false;
}
// Size Check
if (LIST_NUM(p->elements) >= MAX_ELEMENT_NUM)
{
// Can not add any more
FreeElement(e);
return false;
}
// Check whether there is another item which have same name
if (GetElement(p, e->name, INFINITE))
{
// Exists
FreeElement(e);
return false;
}
if (e->num_value == 0)
{
// VALUE without any items can not be added
FreeElement(e);
return false;
}
// Adding
Add(p->elements, e);
return true;
}
// Release of the PACK object
void FreePack(PACK *p)
{
UINT i;
ELEMENT **elements;
// Validate arguments
if (p == NULL)
{
return;
}
elements = ToArray(p->elements);
for (i = 0;i < LIST_NUM(p->elements);i++)
{
FreeElement(elements[i]);
}
Free(elements);
ReleaseList(p->elements);
Free(p);
}
// Create a PACK object
PACK *NewPack()
{
PACK *p;
// Memory allocation
p = MallocEx(sizeof(PACK), true);
// Creating a List
p->elements = NewListFast(ComparePackName);
return p;
}
// Get the K from the PACK
K *PackGetK(PACK *p, char *name)
{
K *k;
BUF *b;
// Validate arguments
if (p == NULL || name == NULL)
{
return NULL;
}
b = PackGetBuf(p, name);
if (b == NULL)
{
return NULL;
}
k = BufToK(b, true, false, NULL);
FreeBuf(b);
return k;
}
// Get the X from the PACK
X *PackGetX(PACK *p, char *name)
{
X *x;
BUF *b;
// Validate arguments
if (p == NULL || name == NULL)
{
return NULL;
}
b = PackGetBuf(p, name);
if (b == NULL)
{
return NULL;
}
x = BufToX(b, false);
FreeBuf(b);
return x;
}
// Add the K to the PACK
void PackAddK(PACK *p, char *name, K *k)
{
BUF *b;
// Validate arguments
if (p == NULL || name == NULL || k == NULL)
{
return;
}
b = KToBuf(k, false, NULL);
if (b == NULL)
{
return;
}
PackAddBuf(p, name, b);
FreeBuf(b);
}
// Add an X into the PACK
void PackAddX(PACK *p, char *name, X *x)
{
BUF *b;
// Validate arguments
if (p == NULL || name == NULL || x == NULL)
{
return;
}
b = XToBuf(x, false);
if (b == NULL)
{
return;
}
PackAddBuf(p, name, b);
FreeBuf(b);
}
// Get a buffer from the PACK
BUF *PackGetBuf(PACK *p, char *name)
{
return PackGetBufEx(p, name, 0);
}
BUF *PackGetBufEx(PACK *p, char *name, UINT index)
{
UINT size;
void *tmp;
BUF *b;
// Validate arguments
if (p == NULL || name == NULL)
{
return NULL;
}
size = PackGetDataSizeEx(p, name, index);
tmp = MallocEx(size, true);
if (PackGetDataEx(p, name, tmp, index) == false)
{
Free(tmp);
return NULL;
}
b = NewBuf();
WriteBuf(b, tmp, size);
SeekBuf(b, 0, 0);
Free(tmp);
return b;
}
// Get the data from the PACK
bool PackGetData(PACK *p, char *name, void *data)
{
return PackGetDataEx(p, name, data, 0);
}
bool PackGetDataEx(PACK *p, char *name, void *data, UINT index)
{
ELEMENT *e;
// Validate arguments
if (p == NULL || name == NULL)
{
return false;
}
e = GetElement(p, name, VALUE_DATA);
if (e == NULL)
{
return false;
}
Copy(data, GetDataValue(e, index), GetDataValueSize(e, index));
return true;
}
bool PackGetData2(PACK *p, char *name, void *data, UINT size)
{
return PackGetDataEx2(p, name, data, size, 0);
}
bool PackGetDataEx2(PACK *p, char *name, void *data, UINT size, UINT index)
{
ELEMENT *e;
// Validate arguments
if (p == NULL || name == NULL)
{
return false;
}
e = GetElement(p, name, VALUE_DATA);
if (e == NULL)
{
return false;
}
if (GetDataValueSize(e, index) != size)
{
return false;
}
Copy(data, GetDataValue(e, index), GetDataValueSize(e, index));
return true;
}
// Get the data size from the PACK
UINT PackGetDataSize(PACK *p, char *name)
{
return PackGetDataSizeEx(p, name, 0);
}
UINT PackGetDataSizeEx(PACK *p, char *name, UINT index)
{
ELEMENT *e;
// Validate arguments
if (p == NULL || name == NULL)
{
return 0;
}
e = GetElement(p, name, VALUE_DATA);
if (e == NULL)
{
return 0;
}
return GetDataValueSize(e, index);
}
// Get an integer from the PACK
UINT64 PackGetInt64(PACK *p, char *name)
{
return PackGetInt64Ex(p, name, 0);
}
UINT64 PackGetInt64Ex(PACK *p, char *name, UINT index)
{
ELEMENT *e;
// Validate arguments
if (p == NULL || name == NULL)
{
return 0;
}
e = GetElement(p, name, VALUE_INT64);
if (e == NULL)
{
return 0;
}
return GetInt64Value(e, index);
}
// Get the index number from the PACK
UINT PackGetIndexCount(PACK *p, char *name)
{
ELEMENT *e;
// Validate arguments
if (p == NULL || name == NULL)
{
return 0;
}
e = GetElement(p, name, INFINITE);
if (e == NULL)
{
return 0;
}
return e->num_value;
}
// Get the number from the PACK
UINT PackGetNum(PACK *p, char *name)
{
return MIN(PackGetInt(p, name), 65536);
}
// Get a bool type from the PACK
bool PackGetBool(PACK *p, char *name)
{
return PackGetInt(p, name) == 0 ? false : true;
}
bool PackGetBoolEx(PACK *p, char *name, UINT index)
{
return PackGetIntEx(p, name, index) == 0 ? false : true;
}
// Add a bool type into the PACK
void PackAddBool(PACK *p, char *name, bool b)
{
PackAddInt(p, name, b ? 1 : 0);
}
void PackAddBoolEx(PACK *p, char *name, bool b, UINT index, UINT total)
{
PackAddIntEx(p, name, b ? 1 : 0, index, total);
}
// Add the IPV6_ADDR to the PACK
void PackAddIp6AddrEx(PACK *p, char *name, IPV6_ADDR *addr, UINT index, UINT total)
{
// Validate arguments
if (p == NULL || name == NULL || addr == NULL)
{
return;
}
PackAddDataEx(p, name, addr, sizeof(IPV6_ADDR), index, total);
}
void PackAddIp6Addr(PACK *p, char *name, IPV6_ADDR *addr)
{
PackAddIp6AddrEx(p, name, addr, 0, 1);
}
// Get an IPV6_ADDR from the PACK
bool PackGetIp6AddrEx(PACK *p, char *name, IPV6_ADDR *addr, UINT index)
{
// Validate arguments
if (p == NULL || name == NULL || addr == NULL)
{
Zero(addr, sizeof(IPV6_ADDR));
return false;
}
return PackGetDataEx2(p, name, addr, sizeof(IPV6_ADDR), index);
}
bool PackGetIp6Addr(PACK *p, char *name, IPV6_ADDR *addr)
{
return PackGetIp6AddrEx(p, name, addr, 0);
}
// Add the IP to the PACK
void PackAddIp32Ex(PACK *p, char *name, UINT ip32, UINT index, UINT total)
{
IP ip;
// Validate arguments
if (p == NULL || name == NULL)
{
return;
}
UINTToIP(&ip, ip32);
PackAddIpEx(p, name, &ip, index, total);
}
void PackAddIp32(PACK *p, char *name, UINT ip32)
{
PackAddIp32Ex(p, name, ip32, 0, 1);
}
void PackAddIpEx(PACK *p, char *name, IP *ip, UINT index, UINT total)
{
UINT i;
bool b = false;
char tmp[MAX_PATH];
// Validate arguments
if (p == NULL || name == NULL || ip == NULL)
{
return;
}
b = IsIP6(ip);
Format(tmp, sizeof(tmp), "%s@ipv6_bool", name);
PackAddBoolEx(p, tmp, b, index, total);
Format(tmp, sizeof(tmp), "%s@ipv6_array", name);
if (b)
{
PackAddDataEx(p, tmp, ip->ipv6_addr, sizeof(ip->ipv6_addr), index, total);
}
else
{
UCHAR dummy[16];
Zero(dummy, sizeof(dummy));
PackAddDataEx(p, tmp, dummy, sizeof(dummy), index, total);
}
Format(tmp, sizeof(tmp), "%s@ipv6_scope_id", name);
if (b)
{
PackAddIntEx(p, tmp, ip->ipv6_scope_id, index, total);
}
else
{
PackAddIntEx(p, tmp, 0, index, total);
}
i = IPToUINT(ip);
if (IsBigEndian())
{
i = Swap32(i);
}
PackAddIntEx(p, name, i, index, total);
}
void PackAddIp(PACK *p, char *name, IP *ip)
{
PackAddIpEx(p, name, ip, 0, 1);
}
// Get an IP from the PACK
UINT PackGetIp32Ex(PACK *p, char *name, UINT index)
{
IP ip;
// Validate arguments
if (p == NULL || name == NULL)
{
return 0;
}
if (PackGetIpEx(p, name, &ip, index) == false)
{
return 0;
}
return IPToUINT(&ip);
}
UINT PackGetIp32(PACK *p, char *name)
{
return PackGetIp32Ex(p, name, 0);
}
bool PackGetIpEx(PACK *p, char *name, IP *ip, UINT index)
{
UINT i;
char tmp[MAX_PATH];
// Validate arguments
if (p == NULL || ip == NULL || name == NULL)
{
return false;
}
Format(tmp, sizeof(tmp), "%s@ipv6_bool", name);
if (PackGetBoolEx(p, tmp, index))
{
UCHAR data[16];
UINT scope_id;
Zero(data, sizeof(data));
Format(tmp, sizeof(tmp), "%s@ipv6_array", name);
PackGetDataEx2(p, tmp, data, sizeof(data), index);
Format(tmp, sizeof(tmp), "%s@ipv6_scope_id", name);
scope_id = PackGetIntEx(p, tmp, index);
SetIP6(ip, data);
ip->ipv6_scope_id = scope_id;
}
else
{
if (GetElement(p, name, VALUE_INT) == NULL)
{
Zero(ip, sizeof(IP));
return false;
}
i = PackGetIntEx(p, name, index);
if (IsBigEndian())
{
i = Swap32(i);
}
UINTToIP(ip, i);
}
return true;
}
bool PackGetIp(PACK *p, char *name, IP *ip)
{
return PackGetIpEx(p, name, ip, 0);
}
2014-07-11 21:06:20 +04:00
// Check whether the specified value is existing on the Pack
bool PackIsValueExists(PACK *p, char *name)
{
// Validate arguments
if (p == NULL || name == NULL)
{
return false;
}
return IsElement(p, name);
}
2014-01-04 17:00:08 +04:00
// Get an integer from the PACK
UINT PackGetInt(PACK *p, char *name)
{
return PackGetIntEx(p, name, 0);
}
UINT PackGetIntEx(PACK *p, char *name, UINT index)
{
ELEMENT *e;
// Validate arguments
if (p == NULL || name == NULL)
{
return 0;
}
e = GetElement(p, name, VALUE_INT);
if (e == NULL)
{
return 0;
}
return GetIntValue(e, index);
}
// Get an Unicode string from the PACK
bool PackGetUniStr(PACK *p, char *name, wchar_t *unistr, UINT size)
{
return PackGetUniStrEx(p, name, unistr, size, 0);
}
bool PackGetUniStrEx(PACK *p, char *name, wchar_t *unistr, UINT size, UINT index)
{
ELEMENT *e;
// Validate arguments
if (p == NULL || name == NULL || unistr == NULL || size == 0)
{
return false;
}
unistr[0] = 0;
e = GetElement(p, name, VALUE_UNISTR);
if (e == NULL)
{
return false;
}
UniStrCpy(unistr, size, GetUniStrValue(e, index));
return true;
}
// Compare strings in the PACK
bool PackCmpStr(PACK *p, char *name, char *str)
{
char tmp[MAX_SIZE];
if (PackGetStr(p, name, tmp, sizeof(tmp)) == false)
{
return false;
}
if (StrCmpi(tmp, str) == 0)
{
return true;
}
return false;
}
// Get a string from the PACK
bool PackGetStr(PACK *p, char *name, char *str, UINT size)
{
return PackGetStrEx(p, name, str, size, 0);
}
bool PackGetStrEx(PACK *p, char *name, char *str, UINT size, UINT index)
{
ELEMENT *e;
// Validate arguments
if (p == NULL || name == NULL || str == NULL || size == 0)
{
return false;
}
str[0] = 0;
e = GetElement(p, name, VALUE_STR);
if (e == NULL)
{
return false;
}
StrCpy(str, size, GetStrValue(e, index));
return true;
}
// Add the buffer to the PACK (array)
void PackAddBufEx(PACK *p, char *name, BUF *b, UINT index, UINT total)
{
// Validate arguments
if (p == NULL || name == NULL || b == NULL || total == 0)
{
return;
}
PackAddDataEx(p, name, b->Buf, b->Size, index, total);
}
// Add the data to the PACK (array)
void PackAddDataEx(PACK *p, char *name, void *data, UINT size, UINT index, UINT total)
{
VALUE *v;
ELEMENT *e;
// Validate arguments
if (p == NULL || data == NULL || name == NULL || total == 0)
{
return;
}
v = NewDataValue(data, size);
e = GetElement(p, name, VALUE_DATA);
if (e != NULL)
{
if (e->num_value <= total)
{
e->values[index] = v;
}
else
{
FreeValue(v, VALUE_DATA);
}
}
else
{
e = ZeroMallocEx(sizeof(ELEMENT), true);
StrCpy(e->name, sizeof(e->name), name);
e->num_value = total;
e->type = VALUE_DATA;
e->values = ZeroMallocEx(sizeof(VALUE *) * total, true);
e->values[index] = v;
AddElement(p, e);
}
}
// Add the buffer to the PACK
void PackAddBuf(PACK *p, char *name, BUF *b)
{
// Validate arguments
if (p == NULL || name == NULL || b == NULL)
{
return;
}
PackAddData(p, name, b->Buf, b->Size);
}
// Add the data to the PACK
void PackAddData(PACK *p, char *name, void *data, UINT size)
{
VALUE *v;
// Validate arguments
if (p == NULL || data == NULL || name == NULL)
{
return;
}
v = NewDataValue(data, size);
AddElement(p, NewElement(name, VALUE_DATA, 1, &v));
}
// Add a 64 bit integer (array) to the PACK
void PackAddInt64Ex(PACK *p, char *name, UINT64 i, UINT index, UINT total)
{
VALUE *v;
ELEMENT *e;
// Validate arguments
if (p == NULL || name == NULL || total == 0)
{
return;
}
v = NewInt64Value(i);
e = GetElement(p, name, VALUE_INT64);
if (e != NULL)
{
if (e->num_value <= total)
{
e->values[index] = v;
}
else
{
FreeValue(v, VALUE_INT64);
}
}
else
{
e = ZeroMallocEx(sizeof(ELEMENT), true);
StrCpy(e->name, sizeof(e->name), name);
e->num_value = total;
e->type = VALUE_INT64;
e->values = ZeroMallocEx(sizeof(VALUE *) * total, true);
e->values[index] = v;
AddElement(p, e);
}
}
// Add an integer to the PACK (array)
void PackAddIntEx(PACK *p, char *name, UINT i, UINT index, UINT total)
{
VALUE *v;
ELEMENT *e;
// Validate arguments
if (p == NULL || name == NULL || total == 0)
{
return;
}
v = NewIntValue(i);
e = GetElement(p, name, VALUE_INT);
if (e != NULL)
{
if (e->num_value <= total)
{
e->values[index] = v;
}
else
{
FreeValue(v, VALUE_INT);
}
}
else
{
e = ZeroMallocEx(sizeof(ELEMENT), true);
StrCpy(e->name, sizeof(e->name), name);
e->num_value = total;
e->type = VALUE_INT;
e->values = ZeroMallocEx(sizeof(VALUE *) * total, true);
e->values[index] = v;
AddElement(p, e);
}
}
// Add a 64 bit integer to the PACK
void PackAddInt64(PACK *p, char *name, UINT64 i)
{
VALUE *v;
// Validate arguments
if (p == NULL || name == NULL)
{
return;
}
v = NewInt64Value(i);
AddElement(p, NewElement(name, VALUE_INT64, 1, &v));
}
// Add the number of items to the PACK
void PackAddNum(PACK *p, char *name, UINT num)
{
PackAddInt(p, name, num);
}
// Add an integer to the PACK
void PackAddInt(PACK *p, char *name, UINT i)
{
VALUE *v;
// Validate arguments
if (p == NULL || name == NULL)
{
return;
}
v = NewIntValue(i);
AddElement(p, NewElement(name, VALUE_INT, 1, &v));
}
// Add a Unicode string (array) to the PACK
void PackAddUniStrEx(PACK *p, char *name, wchar_t *unistr, UINT index, UINT total)
{
VALUE *v;
ELEMENT *e;
// Validate arguments
if (p == NULL || name == NULL || unistr == NULL || total == 0)
{
return;
}
v = NewUniStrValue(unistr);
e = GetElement(p, name, VALUE_UNISTR);
if (e != NULL)
{
if (e->num_value <= total)
{
e->values[index] = v;
}
else
{
FreeValue(v, VALUE_UNISTR);
}
}
else
{
e = ZeroMallocEx(sizeof(ELEMENT), true);
StrCpy(e->name, sizeof(e->name), name);
e->num_value = total;
e->type = VALUE_UNISTR;
e->values = ZeroMallocEx(sizeof(VALUE *) * total, true);
e->values[index] = v;
AddElement(p, e);
}
}
// Add a Unicode string to the PACK
void PackAddUniStr(PACK *p, char *name, wchar_t *unistr)
{
VALUE *v;
// Validate arguments
if (p == NULL || name == NULL || unistr == NULL)
{
return;
}
v = NewUniStrValue(unistr);
AddElement(p, NewElement(name, VALUE_UNISTR, 1, &v));
}
// Add a string to the PACK (array)
void PackAddStrEx(PACK *p, char *name, char *str, UINT index, UINT total)
{
VALUE *v;
ELEMENT *e;
// Validate arguments
if (p == NULL || name == NULL || str == NULL || total == 0)
{
return;
}
v = NewStrValue(str);
e = GetElement(p, name, VALUE_STR);
if (e != NULL)
{
if (e->num_value <= total)
{
e->values[index] = v;
}
else
{
FreeValue(v, VALUE_STR);
}
}
else
{
e = ZeroMallocEx(sizeof(ELEMENT), true);
StrCpy(e->name, sizeof(e->name), name);
e->num_value = total;
e->type = VALUE_STR;
e->values = ZeroMallocEx(sizeof(VALUE *) * total, true);
e->values[index] = v;
AddElement(p, e);
}
}
// Add a string to the PACK
void PackAddStr(PACK *p, char *name, char *str)
{
VALUE *v;
// Validate arguments
if (p == NULL || name == NULL || str == NULL)
{
return;
}
v = NewStrValue(str);
AddElement(p, NewElement(name, VALUE_STR, 1, &v));
}
// Developed by SoftEther VPN Project at University of Tsukuba in Japan.
// Department of Computer Science has dozens of overly-enthusiastic geeks.
// Join us: http://www.tsukuba.ac.jp/english/admission/