1
0
mirror of https://github.com/SoftEtherVPN/SoftEtherVPN.git synced 2025-04-03 18:00:08 +03:00

Merge pull request #1125 from Evengard/ppp-ipv6

IPv6 support for the PPP stack
This commit is contained in:
Ilya Shipitsin 2020-05-19 17:09:09 +05:00 committed by GitHub
commit 1a8e1385cf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 2865 additions and 1597 deletions

View File

@ -232,12 +232,12 @@ TOKEN_LIST *GetEthListSolaris()
lifc.lifc_family = AF_INET; lifc.lifc_family = AF_INET;
lifc.lifc_flags = 0; lifc.lifc_flags = 0;
lifc.lifc_len = bufsize; lifc.lifc_len = bufsize;
lifc.lifc_buf = (char*) buf; lifc.lifc_buf = (char *) buf;
if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) >= 0) if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) >= 0)
{ {
for (i = 0; i<numifs; i++) for (i = 0; i<numifs; i++)
{ {
if(StartWith(buf[i].lifr_name, "lo") == false){ if(StartWith(buf[i].lifr_name, "lo") == false) {
Add(o, CopyStr(buf[i].lifr_name)); Add(o, CopyStr(buf[i].lifr_name));
} }
} }
@ -253,7 +253,7 @@ TOKEN_LIST *GetEthListSolaris()
t->NumTokens = LIST_NUM(o); t->NumTokens = LIST_NUM(o);
t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens); t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
for (i = 0;i < LIST_NUM(o);i++) for (i = 0; i < LIST_NUM(o); i++)
{ {
char *name = LIST_DATA(o, i); char *name = LIST_DATA(o, i);
t->Token[i] = name; t->Token[i] = name;
@ -287,7 +287,7 @@ TOKEN_LIST *GetEthListLinux(bool enum_normal, bool enum_rawip)
if (s != INVALID_SOCKET) if (s != INVALID_SOCKET)
{ {
n = 0; n = 0;
for (i = 0;;i++) for (i = 0;; i++)
{ {
Zero(&ifr, sizeof(ifr)); Zero(&ifr, sizeof(ifr));
ifr.ifr_ifindex = i; ifr.ifr_ifindex = i;
@ -332,7 +332,7 @@ TOKEN_LIST *GetEthListLinux(bool enum_normal, bool enum_rawip)
t->NumTokens = LIST_NUM(o) + (enum_rawip ? 1 : 0); t->NumTokens = LIST_NUM(o) + (enum_rawip ? 1 : 0);
t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens); t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
for (i = 0;i < LIST_NUM(o);i++) for (i = 0; i < LIST_NUM(o); i++)
{ {
char *name = LIST_DATA(o, i); char *name = LIST_DATA(o, i);
t->Token[i] = name; t->Token[i] = name;
@ -374,7 +374,7 @@ TOKEN_LIST *GetEthListPcap()
int datalink = pcap_datalink(p); int datalink = pcap_datalink(p);
// Debug("type:%s\n",pcap_datalink_val_to_name(datalink)); // Debug("type:%s\n",pcap_datalink_val_to_name(datalink));
pcap_close(p); pcap_close(p);
if(datalink == DLT_EN10MB){ if(datalink == DLT_EN10MB) {
// Enumerate only Ethernet type device // Enumerate only Ethernet type device
Add(o, CopyStr(dev->name)); Add(o, CopyStr(dev->name));
} }
@ -388,7 +388,7 @@ TOKEN_LIST *GetEthListPcap()
t = ZeroMalloc(sizeof(TOKEN_LIST)); t = ZeroMalloc(sizeof(TOKEN_LIST));
t->NumTokens = LIST_NUM(o); t->NumTokens = LIST_NUM(o);
t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens); t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
for (i = 0;i < LIST_NUM(o);i++) for (i = 0; i < LIST_NUM(o); i++)
{ {
t->Token[i] = LIST_DATA(o, i); t->Token[i] = LIST_DATA(o, i);
} }
@ -415,7 +415,7 @@ TOKEN_LIST *GetEthListBpf()
struct ifaddrs *ifadr = ifadrs; struct ifaddrs *ifadr = ifadrs;
while(ifadr) while(ifadr)
{ {
sockadr = (struct sockaddr_dl*)ifadr->ifa_addr; sockadr = (struct sockaddr_dl *)ifadr->ifa_addr;
if(sockadr->sdl_family == AF_LINK && sockadr->sdl_type == IFT_ETHER) if(sockadr->sdl_family == AF_LINK && sockadr->sdl_type == IFT_ETHER)
{ {
// Is this Ethernet device? // Is this Ethernet device?
@ -434,7 +434,7 @@ TOKEN_LIST *GetEthListBpf()
t = ZeroMalloc(sizeof(TOKEN_LIST)); t = ZeroMalloc(sizeof(TOKEN_LIST));
t->NumTokens = LIST_NUM(o); t->NumTokens = LIST_NUM(o);
t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens); t->Token = ZeroMalloc(sizeof(char *) * t->NumTokens);
for (i = 0;i < LIST_NUM(o);i++) for (i = 0; i < LIST_NUM(o); i++)
{ {
t->Token[i] = LIST_DATA(o, i); t->Token[i] = LIST_DATA(o, i);
} }
@ -1070,7 +1070,7 @@ bool ParseUnixEthDeviceName(char *dst_devname, UINT dst_devname_size, char *src_
#if defined(BRIDGE_BPF) || defined(BRIDGE_PCAP) #if defined(BRIDGE_BPF) || defined(BRIDGE_PCAP)
// Initialize captured packet data structure // Initialize captured packet data structure
struct CAPTUREBLOCK *NewCaptureBlock(UCHAR *data, UINT size){ struct CAPTUREBLOCK *NewCaptureBlock(UCHAR *data, UINT size) {
struct CAPTUREBLOCK *block = Malloc(sizeof(struct CAPTUREBLOCK)); struct CAPTUREBLOCK *block = Malloc(sizeof(struct CAPTUREBLOCK));
block->Buf = data; block->Buf = data;
block->Size = size; block->Size = size;
@ -1078,7 +1078,7 @@ struct CAPTUREBLOCK *NewCaptureBlock(UCHAR *data, UINT size){
} }
// Free captured packet data structure // Free captured packet data structure
void FreeCaptureBlock(struct CAPTUREBLOCK *block){ void FreeCaptureBlock(struct CAPTUREBLOCK *block) {
Free(block); Free(block);
} }
#endif // BRIDGE_BPF || BRIDGE_PCAP #endif // BRIDGE_BPF || BRIDGE_PCAP
@ -1087,7 +1087,7 @@ void FreeCaptureBlock(struct CAPTUREBLOCK *block){
// Callback function to receive arriving packet (Pcap) // Callback function to receive arriving packet (Pcap)
void PcapHandler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes) void PcapHandler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
{ {
ETH *e = (ETH*) user; ETH *e = (ETH *) user;
struct CAPTUREBLOCK *block; struct CAPTUREBLOCK *block;
UCHAR *data; UCHAR *data;
@ -1096,7 +1096,7 @@ void PcapHandler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
block = NewCaptureBlock(data, h->caplen); block = NewCaptureBlock(data, h->caplen);
LockQueue(e->Queue); LockQueue(e->Queue);
// Discard arriving packet when queue filled // Discard arriving packet when queue filled
if(e->QueueSize < BRIDGE_MAX_QUEUE_SIZE){ if(e->QueueSize < BRIDGE_MAX_QUEUE_SIZE) {
InsertQueue(e->Queue, block); InsertQueue(e->Queue, block);
e->QueueSize += h->caplen; e->QueueSize += h->caplen;
} }
@ -1108,7 +1108,7 @@ void PcapHandler(u_char *user, const struct pcap_pkthdr *h, const u_char *bytes)
// Relay thread for captured packet (Pcap) // Relay thread for captured packet (Pcap)
void PcapThread(THREAD *thread, void *param) void PcapThread(THREAD *thread, void *param)
{ {
ETH *e = (ETH*)param; ETH *e = (ETH *)param;
pcap_t *p = e->Pcap; pcap_t *p = e->Pcap;
int ret; int ret;
@ -1116,8 +1116,8 @@ void PcapThread(THREAD *thread, void *param)
NoticeThreadInit(thread); NoticeThreadInit(thread);
// Return -1:Error -2:Terminated externally // Return -1:Error -2:Terminated externally
ret = pcap_loop(p, -1, PcapHandler, (u_char*) e); ret = pcap_loop(p, -1, PcapHandler, (u_char *) e);
if(ret == -1){ if(ret == -1) {
e->Socket = INVALID_SOCKET; e->Socket = INVALID_SOCKET;
pcap_perror(p, "capture"); pcap_perror(p, "capture");
} }
@ -1181,7 +1181,7 @@ ETH *OpenEthPcap(char *name, bool local, bool tapmode, char *tapaddr)
// Relay thread for captured packet (BPF) // Relay thread for captured packet (BPF)
void BpfThread(THREAD *thread, void *param) void BpfThread(THREAD *thread, void *param)
{ {
ETH *e = (ETH*)param; ETH *e = (ETH *)param;
int fd = e->Socket; int fd = e->Socket;
int len; int len;
int rest; // Rest size in buffer int rest; // Rest size in buffer
@ -1196,14 +1196,14 @@ void BpfThread(THREAD *thread, void *param)
// Notify initialize completed // Notify initialize completed
NoticeThreadInit(thread); NoticeThreadInit(thread);
while(1){ while(1) {
// Determining to exit loop // Determining to exit loop
if(e->Socket == INVALID_SOCKET){ if(e->Socket == INVALID_SOCKET) {
break; break;
} }
rest = read(fd, buf, e->BufSize); rest = read(fd, buf, e->BufSize);
if(rest < 0 && errno != EAGAIN){ if(rest < 0 && errno != EAGAIN) {
// Error // Error
close(fd); close(fd);
e->Socket = INVALID_SOCKET; e->Socket = INVALID_SOCKET;
@ -1213,12 +1213,12 @@ void BpfThread(THREAD *thread, void *param)
} }
next = buf; next = buf;
LockQueue(e->Queue); LockQueue(e->Queue);
while(rest>0){ while(rest>0) {
// Cut out a packet // Cut out a packet
hdr = (struct bpf_hdr*)next; hdr = (struct bpf_hdr *)next;
// Discard arriving packet when queue filled // Discard arriving packet when queue filled
if(e->QueueSize < BRIDGE_MAX_QUEUE_SIZE){ if(e->QueueSize < BRIDGE_MAX_QUEUE_SIZE) {
data = Malloc(hdr->bh_caplen); data = Malloc(hdr->bh_caplen);
Copy(data, next+(hdr->bh_hdrlen), hdr->bh_caplen); Copy(data, next+(hdr->bh_hdrlen), hdr->bh_caplen);
block = NewCaptureBlock(data, hdr->bh_caplen); block = NewCaptureBlock(data, hdr->bh_caplen);
@ -1253,31 +1253,31 @@ ETH *OpenEthBpf(char *name, bool local, bool tapmode, char *tapaddr)
struct timeval to; struct timeval to;
// Find unused bpf device and open it // Find unused bpf device and open it
do{ do {
Format(devname, sizeof(devname), "/dev/bpf%d", n++); Format(devname, sizeof(devname), "/dev/bpf%d", n++);
fd = open (devname, O_RDWR); fd = open (devname, O_RDWR);
if(fd<0){ if(fd<0) {
perror("open"); perror("open");
} }
}while(fd < 0 && errno == EBUSY); } while(fd < 0 && errno == EBUSY);
// No free bpf device was found // No free bpf device was found
if(fd < 0){ if(fd < 0) {
Debug("BPF: No minor number are free.\n"); Debug("BPF: No minor number are free.\n");
return NULL; return NULL;
} }
// Enlarge buffer size // Enlarge buffer size
n = 524288; // Somehow(In libpcap, this size is 32768) n = 524288; // Somehow(In libpcap, this size is 32768)
while(true){ while(true) {
// Specify buffer size // Specify buffer size
ioctl(fd, BIOCSBLEN, &n); ioctl(fd, BIOCSBLEN, &n);
// Bind to the network device // Bind to the network device
StrCpy(ifr.ifr_name, IFNAMSIZ, name); StrCpy(ifr.ifr_name, IFNAMSIZ, name);
ret = ioctl(fd, BIOCSETIF, &ifr); ret = ioctl(fd, BIOCSETIF, &ifr);
if(ret < 0){ if(ret < 0) {
if(ret == ENOBUFS && n>1500){ if(ret == ENOBUFS && n>1500) {
// Inappropriate buffer size // Inappropriate buffer size
// Retry with half buffer size // Retry with half buffer size
// If buffer size is under 1500 bytes, something goes wrong // If buffer size is under 1500 bytes, something goes wrong
@ -1287,15 +1287,15 @@ ETH *OpenEthBpf(char *name, bool local, bool tapmode, char *tapaddr)
Debug("bpf: binding network failed.\n"); Debug("bpf: binding network failed.\n");
close(fd); close(fd);
return NULL; return NULL;
}else{ } else {
break; break;
} }
} }
bufsize = n; bufsize = n;
// Set to promiscuous mode // Set to promiscuous mode
if(local == false){ if(local == false) {
if (ioctl(fd, BIOCPROMISC, NULL) < 0){ if (ioctl(fd, BIOCPROMISC, NULL) < 0) {
printf("bpf: promisc mode failed.\n"); printf("bpf: promisc mode failed.\n");
close(fd); close(fd);
return NULL; return NULL;
@ -1305,7 +1305,7 @@ ETH *OpenEthBpf(char *name, bool local, bool tapmode, char *tapaddr)
// Set to immediate mode (Return immediately when packet arrives) // Set to immediate mode (Return immediately when packet arrives)
n = 1; n = 1;
if (ioctl(fd, BIOCIMMEDIATE, &n) < 0){ if (ioctl(fd, BIOCIMMEDIATE, &n) < 0) {
Debug("BPF: non-block mode failed.\n"); Debug("BPF: non-block mode failed.\n");
close(fd); close(fd);
return NULL; return NULL;
@ -1313,7 +1313,7 @@ ETH *OpenEthBpf(char *name, bool local, bool tapmode, char *tapaddr)
// Set receiving self sending packet // Set receiving self sending packet
n = 1; n = 1;
if (ioctl(fd, BIOCGSEESENT, &n) < 0){ if (ioctl(fd, BIOCGSEESENT, &n) < 0) {
Debug("BPF: see sent mode failed.\n"); Debug("BPF: see sent mode failed.\n");
close(fd); close(fd);
return NULL; return NULL;
@ -1321,7 +1321,7 @@ ETH *OpenEthBpf(char *name, bool local, bool tapmode, char *tapaddr)
// Header complete mode (Generate whole header of sending packet) // Header complete mode (Generate whole header of sending packet)
n = 1; n = 1;
if (ioctl(fd, BIOCSHDRCMPLT, &n) < 0){ if (ioctl(fd, BIOCSHDRCMPLT, &n) < 0) {
Debug("BPF: Header complete mode failed.\n"); Debug("BPF: Header complete mode failed.\n");
close(fd); close(fd);
return NULL; return NULL;
@ -1330,7 +1330,7 @@ ETH *OpenEthBpf(char *name, bool local, bool tapmode, char *tapaddr)
// Set timeout delay to 1 second // Set timeout delay to 1 second
to.tv_sec = 1; to.tv_sec = 1;
to.tv_usec = 0; to.tv_usec = 0;
if (ioctl(fd, BIOCSRTIMEOUT, &to) < 0){ if (ioctl(fd, BIOCSRTIMEOUT, &to) < 0) {
Debug("BPF: Read timeout setting failed.\n"); Debug("BPF: Read timeout setting failed.\n");
close(fd); close(fd);
return NULL; return NULL;
@ -1401,7 +1401,7 @@ ETH *OpenEthBSD(char *name, bool local, bool tapmode, char *tapaddr)
return e; return e;
#else // NO_VLAN #else // NO_VLAN
return NULL: return NULL:
#endif // NO_VLAN #endif // NO_VLAN
} }
@ -1471,7 +1471,7 @@ void CloseEth(ETH *e)
WaitThread(e->CaptureThread, INFINITE); WaitThread(e->CaptureThread, INFINITE);
ReleaseThread(e->CaptureThread); ReleaseThread(e->CaptureThread);
pcap_close(e->Pcap); pcap_close(e->Pcap);
while (block = GetNext(e->Queue)){ while (block = GetNext(e->Queue)) {
Free(block->Buf); Free(block->Buf);
FreeCaptureBlock(block); FreeCaptureBlock(block);
} }
@ -1488,7 +1488,7 @@ void CloseEth(ETH *e)
WaitThread(e->CaptureThread, INFINITE); WaitThread(e->CaptureThread, INFINITE);
ReleaseThread(e->CaptureThread); ReleaseThread(e->CaptureThread);
e->Socket = fd; // restore to close after e->Socket = fd; // restore to close after
while (block = GetNext(e->Queue)){ while (block = GetNext(e->Queue)) {
Free(block->Buf); Free(block->Buf);
FreeCaptureBlock(block); FreeCaptureBlock(block);
} }
@ -1772,14 +1772,14 @@ UINT EthGetPacketPcap(ETH *e, void **data)
LockQueue(e->Queue); LockQueue(e->Queue);
block = GetNext(e->Queue); block = GetNext(e->Queue);
if(block != NULL){ if(block != NULL) {
e->QueueSize -= block->Size; e->QueueSize -= block->Size;
} }
UnlockQueue(e->Queue); UnlockQueue(e->Queue);
if(block == NULL){ if(block == NULL) {
*data = NULL; *data = NULL;
if(e->Socket == INVALID_SOCKET){ if(e->Socket == INVALID_SOCKET) {
return INFINITE; return INFINITE;
} }
return 0; return 0;
@ -1802,14 +1802,14 @@ UINT EthGetPacketBpf(ETH *e, void **data)
LockQueue(e->Queue); LockQueue(e->Queue);
block = GetNext(e->Queue); block = GetNext(e->Queue);
if(block != NULL){ if(block != NULL) {
e->QueueSize -= block->Size; e->QueueSize -= block->Size;
} }
UnlockQueue(e->Queue); UnlockQueue(e->Queue);
if(block == NULL){ if(block == NULL) {
*data = NULL; *data = NULL;
if(e->Socket == INVALID_SOCKET){ if(e->Socket == INVALID_SOCKET) {
return INFINITE; return INFINITE;
} }
return 0; return 0;
@ -1826,11 +1826,11 @@ UINT EthGetPacketBpf(ETH *e, void **data)
{ {
struct bpf_hdr *hdr; struct bpf_hdr *hdr;
if(e->Rest<=0){ if(e->Rest<=0) {
e->Rest = read(e->Socket, e->Buffer, e->BufSize); e->Rest = read(e->Socket, e->Buffer, e->BufSize);
if(e->Rest < 0){ if(e->Rest < 0) {
*data = NULL; *data = NULL;
if(errno != EAGAIN){ if(errno != EAGAIN) {
// Error // Error
return INFINITE; return INFINITE;
} }
@ -1840,7 +1840,7 @@ UINT EthGetPacketBpf(ETH *e, void **data)
e->Next = e->Buffer; e->Next = e->Buffer;
} }
// Cut out a packet // Cut out a packet
hdr = (struct bpf_hdr*)e->Next; hdr = (struct bpf_hdr *)e->Next;
*data = Malloc(hdr->bh_caplen); *data = Malloc(hdr->bh_caplen);
Copy(*data, e->Next+(hdr->bh_hdrlen), hdr->bh_caplen); Copy(*data, e->Next+(hdr->bh_hdrlen), hdr->bh_caplen);
@ -1864,7 +1864,7 @@ void EthPutPackets(ETH *e, UINT num, void **datas, UINT *sizes)
return; return;
} }
for (i = 0;i < num;i++) for (i = 0; i < num; i++)
{ {
EthPutPacket(e, datas[i], sizes[i]); EthPutPacket(e, datas[i], sizes[i]);
} }
@ -1910,7 +1910,7 @@ void EthPutPacket(ETH *e, void *data, UINT size)
// Send to device // Send to device
#ifdef BRIDGE_PCAP #ifdef BRIDGE_PCAP
ret = pcap_inject(e->Pcap, data, size); ret = pcap_inject(e->Pcap, data, size);
if( ret == -1 ){ if( ret == -1 ) {
#ifdef _DEBUG #ifdef _DEBUG
pcap_perror(e->Pcap, "inject"); pcap_perror(e->Pcap, "inject");
#endif // _DEBUG #endif // _DEBUG
@ -2183,7 +2183,7 @@ LABEL_RETRY:
if (p->TypeL4 == L4_TCP) if (p->TypeL4 == L4_TCP)
{ {
TCP_HEADER *tcp = p->L4.TCPHeader; TCP_HEADER *tcp = p->L4.TCPHeader;
/* /*
if (Endian16(tcp->SrcPort) == 80) if (Endian16(tcp->SrcPort) == 80)
{ {
IP a, b; IP a, b;
@ -2589,13 +2589,13 @@ void EthPutPacketLinuxIpRaw(ETH *e, void *data, UINT size)
if (p->BroadcastPacket || Cmp(p->MacAddressDest, e->RawIpMyMacAddr, 6) == 0) if (p->BroadcastPacket || Cmp(p->MacAddressDest, e->RawIpMyMacAddr, 6) == 0)
{ {
if (IsValidUnicastMacAddress(p->MacAddressSrc)) if (IsMacUnicast(p->MacAddressSrc))
{ {
Copy(e->RawIpYourMacAddr, p->MacAddressSrc, 6); Copy(e->RawIpYourMacAddr, p->MacAddressSrc, 6);
} }
} }
if (IsZero(e->RawIpYourMacAddr, 6) || IsValidUnicastMacAddress(p->MacAddressSrc) == false || if (IsZero(e->RawIpYourMacAddr, 6) || IsMacUnicast(p->MacAddressSrc) == false ||
(p->BroadcastPacket == false && Cmp(p->MacAddressDest, e->RawIpMyMacAddr, 6) != 0)) (p->BroadcastPacket == false && Cmp(p->MacAddressDest, e->RawIpMyMacAddr, 6) != 0))
{ {
Free(data); Free(data);

View File

@ -582,6 +582,8 @@ typedef struct IPC_PARAM IPC_PARAM;
typedef struct IPC_DHCP_RELEASE_QUEUE IPC_DHCP_RELEASE_QUEUE; typedef struct IPC_DHCP_RELEASE_QUEUE IPC_DHCP_RELEASE_QUEUE;
typedef struct IPC_MSCHAP_V2_AUTHINFO IPC_MSCHAP_V2_AUTHINFO; typedef struct IPC_MSCHAP_V2_AUTHINFO IPC_MSCHAP_V2_AUTHINFO;
typedef struct IPC_SESSION_SHARED_BUFFER_DATA IPC_SESSION_SHARED_BUFFER_DATA; typedef struct IPC_SESSION_SHARED_BUFFER_DATA IPC_SESSION_SHARED_BUFFER_DATA;
typedef struct IPC_IPV6_ROUTER_ADVERTISEMENT IPC_IPV6_ROUTER_ADVERTISEMENT;
typedef struct IPC_DHCPV4_AWAIT IPC_DHCPV4_AWAIT;
// ============================================================== // ==============================================================

File diff suppressed because it is too large Load Diff

View File

@ -24,6 +24,22 @@
#define IPC_LAYER_2 2 #define IPC_LAYER_2 2
#define IPC_LAYER_3 3 #define IPC_LAYER_3 3
// IPv6 constants
#define IPC_IPV6_NDT_LIFETIME (30 * 1000) // as per REACHABLE_TIME constant of RFC4861
#define IPC_IPV6_NDT_GIVEUPTIME (3 * 1000) // as per MAX_MULTICAST_SOLICIT * RETRANS_TIMER constants of RFC4861
#define IPC_IPV6_RA_INTERVAL (2 * 1000) // Windows gets stuck if it is bigger
#define IPC_IPV6_RA_MAX_RETRIES 2 // Windows seems to be stuck when it doesn't receive an answer in due time
// Protocol status
#define IPC_PROTO_STATUS_CLOSED 0x0
#define IPC_PROTO_STATUS_CONFIG 0x1
#define IPC_PROTO_STATUS_CONFIG_WAIT 0x2
#define IPC_PROTO_STATUS_OPENED 0x10
#define IPC_PROTO_STATUS_REJECTED 0x100
#define IPC_PROTO_SET_STATUS(ipc, proto, value) ((ipc) != NULL ? ((ipc->proto) = (value)) : 0)
#define IPC_PROTO_GET_STATUS(ipc, proto) ((ipc) != NULL ? (ipc->proto) : IPC_PROTO_STATUS_REJECTED)
// ARP table entry // ARP table entry
struct IPC_ARP struct IPC_ARP
{ {
@ -72,6 +88,15 @@ struct IPC_PARAM
UINT Layer; UINT Layer;
}; };
// DHCPv4 response awaiter
struct IPC_DHCPV4_AWAIT
{
bool IsAwaiting;
DHCPV4_DATA *DhcpData;
UINT TransCode;
UINT OpCode;
};
// IPC_ASYNC object // IPC_ASYNC object
struct IPC_ASYNC struct IPC_ASYNC
{ {
@ -111,12 +136,22 @@ struct IPC
UCHAR Padding[2]; UCHAR Padding[2];
LIST *ArpTable; // ARP table LIST *ArpTable; // ARP table
QUEUE *IPv4ReceivedQueue; // IPv4 reception queue QUEUE *IPv4ReceivedQueue; // IPv4 reception queue
UINT IPv4State;
IPC_DHCPV4_AWAIT DHCPv4Awaiter;
TUBE_FLUSH_LIST *FlushList; // Tube Flush List TUBE_FLUSH_LIST *FlushList; // Tube Flush List
UCHAR MsChapV2_ServerResponse[20]; // Server response UCHAR MsChapV2_ServerResponse[20]; // Server response
DHCP_CLASSLESS_ROUTE_TABLE ClasslessRoute; // Classless routing table DHCP_CLASSLESS_ROUTE_TABLE ClasslessRoute; // Classless routing table
SHARED_BUFFER *IpcSessionSharedBuffer; // A shared buffer between IPC and Session SHARED_BUFFER *IpcSessionSharedBuffer; // A shared buffer between IPC and Session
IPC_SESSION_SHARED_BUFFER_DATA *IpcSessionShared; // Shared data between IPC and Session IPC_SESSION_SHARED_BUFFER_DATA *IpcSessionShared; // Shared data between IPC and Session
UINT Layer; UINT Layer;
// IPv6 stuff
QUEUE *IPv6ReceivedQueue; // IPv6 reception queue
UINT IPv6State;
LIST *IPv6NeighborTable; // Neighbor Discovery Table
LIST *IPv6RouterAdvs; // Router offered prefixes
UINT64 IPv6ClientEUI; // The EUI of the client (for the SLAAC autoconf)
UINT64 IPv6ServerEUI; // The EUI of the server (from the RA discovery)
}; };
// MS-CHAPv2 authentication information // MS-CHAPv2 authentication information
@ -129,6 +164,15 @@ struct IPC_MSCHAP_V2_AUTHINFO
EAP_CLIENT *MsChapV2_EapClient; // EAP client EAP_CLIENT *MsChapV2_EapClient; // EAP client
}; };
struct IPC_IPV6_ROUTER_ADVERTISEMENT
{
IP RoutedPrefix;
IP RoutedMask;
IP RouterAddress;
UCHAR RouterMacAddress[6];
UCHAR RouterLinkLayerAddress[6];
};
IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password, IPC *NewIPC(CEDAR *cedar, char *client_name, char *postfix, char *hubname, char *username, char *password,
UINT *error_code, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port, UINT *error_code, IP *client_ip, UINT client_port, IP *server_ip, UINT server_port,
char *client_hostname, char *crypt_name, char *client_hostname, char *crypt_name,
@ -144,6 +188,7 @@ void IPCSendIPv4(IPC *ipc, void *data, UINT size);
BLOCK *IPCRecvL2(IPC *ipc); BLOCK *IPCRecvL2(IPC *ipc);
BLOCK *IPCRecvIPv4(IPC *ipc); BLOCK *IPCRecvIPv4(IPC *ipc);
void IPCProcessInterrupts(IPC *ipc); void IPCProcessInterrupts(IPC *ipc);
void IPCProcessL3EventsIPv4Only(IPC *ipc);
void IPCProcessL3Events(IPC *ipc); void IPCProcessL3Events(IPC *ipc);
void IPCProcessL3EventsEx(IPC *ipc, UINT64 now); void IPCProcessL3EventsEx(IPC *ipc, UINT64 now);
bool IPCSetIPv4Parameters(IPC *ipc, IP *ip, IP *subnet, IP *gw, DHCP_CLASSLESS_ROUTE_TABLE *rt); bool IPCSetIPv4Parameters(IPC *ipc, IP *ip, IP *subnet, IP *gw, DHCP_CLASSLESS_ROUTE_TABLE *rt);
@ -151,15 +196,15 @@ IPC_ARP *IPCNewARP(IP *ip, UCHAR *mac_address);
void IPCFreeARP(IPC_ARP *a); void IPCFreeARP(IPC_ARP *a);
int IPCCmpArpTable(void *p1, void *p2); int IPCCmpArpTable(void *p1, void *p2);
void IPCSendIPv4Unicast(IPC *ipc, void *data, UINT size, IP *next_ip); void IPCSendIPv4Unicast(IPC *ipc, void *data, UINT size, IP *next_ip);
IPC_ARP *IPCSearchArpTable(IPC *ipc, IP *ip); IPC_ARP *IPCSearchArpTable(LIST *arpTable, IP *ip);
void IPCSendIPv4WithDestMacAddr(IPC *ipc, void *data, UINT size, UCHAR *dest_mac_addr); void IPCSendIPv4WithDestMacAddr(IPC *ipc, void *data, UINT size, UCHAR *dest_mac_addr);
void IPCFlushArpTable(IPC *ipc); void IPCFlushArpTable(IPC *ipc);
void IPCFlushArpTableEx(IPC *ipc, UINT64 now); void IPCFlushArpTableEx(IPC *ipc, UINT64 now);
void IPCProcessArp(IPC *ipc, BLOCK *b); void IPCProcessArp(IPC *ipc, BLOCK *b);
void IPCAssociateOnArpTable(IPC *ipc, IP *ip, UCHAR *mac_address); void IPCAssociateOnArpTable(IPC *ipc, IP *ip, UCHAR *mac_address);
bool IsValidUnicastMacAddress(UCHAR *mac);
bool IsValidUnicastIPAddress4(IP *ip);
bool IsValidUnicastIPAddressUINT4(UINT ip);
DHCPV4_DATA *IPCSendDhcpRequest(IPC *ipc, IP *dest_ip, UINT tran_id, DHCP_OPTION_LIST *opt, UINT expecting_code, UINT timeout, TUBE *discon_poll_tube); DHCPV4_DATA *IPCSendDhcpRequest(IPC *ipc, IP *dest_ip, UINT tran_id, DHCP_OPTION_LIST *opt, UINT expecting_code, UINT timeout, TUBE *discon_poll_tube);
BUF *IPCBuildDhcpRequest(IPC *ipc, IP *dest_ip, UINT tran_id, DHCP_OPTION_LIST *opt); BUF *IPCBuildDhcpRequest(IPC *ipc, IP *dest_ip, UINT tran_id, DHCP_OPTION_LIST *opt);
BUF *IPCBuildDhcpRequestOptions(IPC *ipc, DHCP_OPTION_LIST *opt); BUF *IPCBuildDhcpRequestOptions(IPC *ipc, DHCP_OPTION_LIST *opt);
@ -171,6 +216,26 @@ IPC_ASYNC *NewIPCAsync(CEDAR *cedar, IPC_PARAM *param, SOCK_EVENT *sock_event);
void IPCAsyncThreadProc(THREAD *thread, void *param); void IPCAsyncThreadProc(THREAD *thread, void *param);
void FreeIPCAsync(IPC_ASYNC *a); void FreeIPCAsync(IPC_ASYNC *a);
// IPv6 stuff
// Memory management
void IPCIPv6Init(IPC *ipc);
void IPCIPv6Free(IPC *ipc);
// NDT
void IPCIPv6AssociateOnNDT(IPC *ipc, IP *ip, UCHAR *mac_address);
void IPCIPv6AssociateOnNDTEx(IPC *ipc, IP *ip, UCHAR *mac_address, bool isNeighborAdv);
void IPCIPv6FlushNDT(IPC *ipc);
void IPCIPv6FlushNDTEx(IPC *ipc, UINT64 now);
bool IPCIPv6CheckExistingLinkLocal(IPC *ipc, UINT64 eui);
// RA
void IPCIPv6AddRouterPrefixes(IPC *ipc, ICMPV6_OPTION_LIST *recvPrefix, UCHAR *macAddress, IP *ip);
bool IPCIPv6CheckUnicastFromRouterPrefix(IPC *ipc, IP *ip, IPC_IPV6_ROUTER_ADVERTISEMENT *matchedRA);
UINT64 IPCIPv6GetServerEui(IPC *ipc);
// Data flow
BLOCK *IPCIPv6Recv(IPC *ipc);
void IPCIPv6Send(IPC *ipc, void *data, UINT size);
void IPCIPv6SendWithDestMacAddr(IPC *ipc, void *data, UINT size, UCHAR *dest_mac_addr);
void IPCIPv6SendUnicast(IPC *ipc, void *data, UINT size, IP *next_ip);
bool ParseAndExtractMsChapV2InfoFromPassword(IPC_MSCHAP_V2_AUTHINFO *d, char *password); bool ParseAndExtractMsChapV2InfoFromPassword(IPC_MSCHAP_V2_AUTHINFO *d, char *password);
#endif // IPC_H #endif // IPC_H

View File

@ -175,7 +175,7 @@ void FreeEraseFileList(LIST *o)
return; return;
} }
for (i = 0;i < LIST_NUM(o);i++) for (i = 0; i < LIST_NUM(o); i++)
{ {
ERASE_FILE *f = LIST_DATA(o, i); ERASE_FILE *f = LIST_DATA(o, i);
Free(f->FullPath); Free(f->FullPath);
@ -200,7 +200,7 @@ void EnumEraseFile(LIST *o, char *dirname)
// Enumeration // Enumeration
dir = EnumDir(dirname); dir = EnumDir(dirname);
for (i = 0;i < dir->NumFiles;i++) for (i = 0; i < dir->NumFiles; i++)
{ {
DIRENT *e = dir->File[i]; DIRENT *e = dir->File[i];
Format(tmp, sizeof(tmp), "%s/%s", dirname, e->FileName); Format(tmp, sizeof(tmp), "%s/%s", dirname, e->FileName);
@ -245,7 +245,7 @@ LIST *GenerateEraseFileList(ERASER *e)
o = NewListFast(CompareEraseFile); o = NewListFast(CompareEraseFile);
// Scan for each directory // Scan for each directory
for (i = 0;i < sizeof(delete_targets) / sizeof(delete_targets[0]);i++) for (i = 0; i < sizeof(delete_targets) / sizeof(delete_targets[0]); i++)
{ {
char dirname[MAX_PATH]; char dirname[MAX_PATH];
Format(dirname, sizeof(dirname), "%s/%s", e->DirName, delete_targets[i]); Format(dirname, sizeof(dirname), "%s/%s", e->DirName, delete_targets[i]);
@ -285,7 +285,7 @@ void EraserMain(ERASER *e)
o = GenerateEraseFileList(e); o = GenerateEraseFileList(e);
// Try to delete one by one in order from oldest file // Try to delete one by one in order from oldest file
for (i = 0;i < LIST_NUM(o);i++) for (i = 0; i < LIST_NUM(o); i++)
{ {
ERASE_FILE *f = LIST_DATA(o, i); ERASE_FILE *f = LIST_DATA(o, i);
@ -1259,7 +1259,7 @@ void MakeSafeLogStr(char *str)
EnPrintableAsciiStr(str, '?'); EnPrintableAsciiStr(str, '?');
len = StrLen(str); len = StrLen(str);
for (i = 0;i < len;i++) for (i = 0; i < len; i++)
{ {
if (str[i] == ',') if (str[i] == ',')
{ {
@ -1284,6 +1284,7 @@ char *PacketLogParseProc(RECORD *rec)
TOKEN_LIST *t; TOKEN_LIST *t;
char tmp[MAX_SIZE]; char tmp[MAX_SIZE];
bool tcp_conn; bool tcp_conn;
UINT i;
// Validate arguments // Validate arguments
if (rec == NULL) if (rec == NULL)
{ {
@ -1686,14 +1687,21 @@ char *PacketLogParseProc(RECORD *rec)
snprintf(tmp, sizeof(tmp), "TargetLinkLayer=%s ", tmp2); snprintf(tmp, sizeof(tmp), "TargetLinkLayer=%s ", tmp2);
StrCat(info, sizeof(info), tmp); StrCat(info, sizeof(info), tmp);
} }
if (ol->Prefix != NULL) for (i = 0; i < ICMPV6_OPTION_PREFIXES_MAX_COUNT; i++)
{
if (ol->Prefix[i] != NULL)
{ {
char tmp2[MAX_SIZE]; char tmp2[MAX_SIZE];
IP6AddrToStr(tmp2, sizeof(tmp2), &ol->Prefix->Prefix); IP6AddrToStr(tmp2, sizeof(tmp2), &ol->Prefix[i]->Prefix);
snprintf(tmp, sizeof(tmp), "Prefix=%s/%u PrefixFlag=0x%02X ", tmp2, snprintf(tmp, sizeof(tmp), "Prefix=%s/%u PrefixFlag=0x%02X ", tmp2,
ol->Prefix->SubnetLength, ol->Prefix->Flags); ol->Prefix[i]->SubnetLength, ol->Prefix[i]->Flags);
StrCat(info, sizeof(info), tmp); StrCat(info, sizeof(info), tmp);
} }
else
{
break;
}
}
if (ol->Mtu != NULL) if (ol->Mtu != NULL)
{ {
snprintf(tmp, sizeof(tmp), "Mtu=%u ", Endian32(ol->Mtu->Mtu)); snprintf(tmp, sizeof(tmp), "Mtu=%u ", Endian32(ol->Mtu->Mtu));
@ -1975,7 +1983,7 @@ char *GenCsvLine(TOKEN_LIST *t)
} }
b = NewBuf(); b = NewBuf();
for (i = 0;i < t->NumTokens;i++) for (i = 0; i < t->NumTokens; i++)
{ {
if (t->Token[i] != NULL) if (t->Token[i] != NULL)
{ {
@ -2019,7 +2027,7 @@ void ReplaceForCsv(char *str)
len = StrLen(str); len = StrLen(str);
for (i = 0;i < len;i++) for (i = 0; i < len; i++)
{ {
// Convert the comma to underscore // Convert the comma to underscore
if (str[i] == ',') if (str[i] == ',')
@ -2542,7 +2550,7 @@ static bool LogThreadWriteGeneral(LOG *log_object, BUF *buffer, IO **io, bool *l
log_object->CurrentLogNumber = 0; log_object->CurrentLogNumber = 0;
MakeLogFileName(log_object, file_name, sizeof(file_name), MakeLogFileName(log_object, file_name, sizeof(file_name),
log_object->DirName, log_object->Prefix, rec->Tick, log_object->SwitchType, 0, current_logfile_datename); log_object->DirName, log_object->Prefix, rec->Tick, log_object->SwitchType, 0, current_logfile_datename);
for (i = 0;;i++) for (i = 0;; i++)
{ {
char tmp[MAX_SIZE]; char tmp[MAX_SIZE];
MakeLogFileName(log_object, tmp, sizeof(tmp), MakeLogFileName(log_object, tmp, sizeof(tmp),

View File

@ -644,7 +644,7 @@ void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p, UINT protocol)
OvsLog(s, se, c, "LO_NEW_CHANNEL"); OvsLog(s, se, c, "LO_NEW_CHANNEL");
} }
} }
/* else if (recv_packet->OpCode == OPENVPN_P_CONTROL_SOFT_RESET_V1) /* else if (recv_packet->OpCode == OPENVPN_P_CONTROL_SOFT_RESET_V1)
{ {
// Response to soft reset request packet // Response to soft reset request packet
OPENVPN_PACKET *p; OPENVPN_PACKET *p;
@ -656,7 +656,7 @@ void OvsProceccRecvPacket(OPENVPN_SERVER *s, UDPPACKET *p, UINT protocol)
OvsFreePacket(p); OvsFreePacket(p);
} }
*/ */
if (c != NULL) if (c != NULL)
{ {
// Delete the send packet list by looking the packet ID in the ACK list of arrived packet // Delete the send packet list by looking the packet ID in the ACK list of arrived packet
@ -743,12 +743,12 @@ void OvsDeleteFromSendingControlPacketList(OPENVPN_CHANNEL *c, UINT num_acks, UI
} }
o = NewListFast(NULL); o = NewListFast(NULL);
for (i = 0;i < num_acks;i++) for (i = 0; i < num_acks; i++)
{ {
UINT ack = acks[i]; UINT ack = acks[i];
UINT j; UINT j;
for (j = 0;j < LIST_NUM(c->SendControlPacketList);j++) for (j = 0; j < LIST_NUM(c->SendControlPacketList); j++)
{ {
OPENVPN_CONTROL_PACKET *p = LIST_DATA(c->SendControlPacketList, j); OPENVPN_CONTROL_PACKET *p = LIST_DATA(c->SendControlPacketList, j);
@ -759,7 +759,7 @@ void OvsDeleteFromSendingControlPacketList(OPENVPN_CHANNEL *c, UINT num_acks, UI
} }
} }
for (i = 0;i < LIST_NUM(o);i++) for (i = 0; i < LIST_NUM(o); i++)
{ {
OPENVPN_CONTROL_PACKET *p = LIST_DATA(o, i); OPENVPN_CONTROL_PACKET *p = LIST_DATA(o, i);
@ -1119,7 +1119,7 @@ UINT OvsPeekStringFromFifo(FIFO *f, char *str, UINT str_size)
StrCpy(str, str_size, ""); StrCpy(str, str_size, "");
for (i = 0;i < MIN(str_size, FifoSize(f));i++) for (i = 0; i < MIN(str_size, FifoSize(f)); i++)
{ {
char c = *(((char *)FifoPtr(f)) + i); char c = *(((char *)FifoPtr(f)) + i);
@ -1637,7 +1637,7 @@ UINT OvsGetAckReplyList(OPENVPN_CHANNEL *c, UINT *ret)
num = MIN(LIST_NUM(c->AckReplyList), OPENVPN_MAX_NUMACK); num = MIN(LIST_NUM(c->AckReplyList), OPENVPN_MAX_NUMACK);
for (i = 0;i < num;i++) for (i = 0; i < num; i++)
{ {
UINT *v = LIST_DATA(c->AckReplyList, i); UINT *v = LIST_DATA(c->AckReplyList, i);
@ -1651,7 +1651,7 @@ UINT OvsGetAckReplyList(OPENVPN_CHANNEL *c, UINT *ret)
ret[i] = *v; ret[i] = *v;
} }
for (i = 0;i < LIST_NUM(o);i++) for (i = 0; i < LIST_NUM(o); i++)
{ {
UINT *v = LIST_DATA(o, i); UINT *v = LIST_DATA(o, i);
@ -1682,7 +1682,7 @@ void OvsFreeChannel(OPENVPN_CHANNEL *c)
ReleaseIntList(c->AckReplyList); ReleaseIntList(c->AckReplyList);
for (i = 0;i < LIST_NUM(c->SendControlPacketList);i++) for (i = 0; i < LIST_NUM(c->SendControlPacketList); i++)
{ {
OPENVPN_CONTROL_PACKET *p = LIST_DATA(c->SendControlPacketList, i); OPENVPN_CONTROL_PACKET *p = LIST_DATA(c->SendControlPacketList, i);
@ -1758,7 +1758,7 @@ UINT64 OvsNewServerSessionId(OPENVPN_SERVER *s)
continue; continue;
} }
for (i = 0;i < LIST_NUM(s->SessionList);i++) for (i = 0; i < LIST_NUM(s->SessionList); i++)
{ {
OPENVPN_SESSION *se = LIST_DATA(s->SessionList, i); OPENVPN_SESSION *se = LIST_DATA(s->SessionList, i);
if (se->ServerSessionId == id) if (se->ServerSessionId == id)
@ -1882,7 +1882,7 @@ BUF *OvsBuildPacket(OPENVPN_PACKET *p)
{ {
UINT i; UINT i;
for (i = 0;i < num_ack;i++) for (i = 0; i < num_ack; i++)
{ {
WriteBufInt(b, (UCHAR)p->AckPacketId[i]); WriteBufInt(b, (UCHAR)p->AckPacketId[i]);
} }
@ -1970,7 +1970,7 @@ OPENVPN_PACKET *OvsParsePacket(UCHAR *data, UINT size)
goto LABEL_ERROR; goto LABEL_ERROR;
} }
for (i = 0;i < ret->NumAck;i++) for (i = 0; i < ret->NumAck; i++)
{ {
UINT ui; UINT ui;
@ -2066,7 +2066,7 @@ UINT OvsGetNumSessionByClientIp(OPENVPN_SERVER *s, IP *ip)
return 0; return 0;
} }
for (i = 0;i < LIST_NUM(s->SessionList);i++) for (i = 0; i < LIST_NUM(s->SessionList); i++)
{ {
OPENVPN_SESSION *se = LIST_DATA(s->SessionList, i); OPENVPN_SESSION *se = LIST_DATA(s->SessionList, i);
@ -2159,13 +2159,14 @@ void OvsFreeSession(OPENVPN_SESSION *se)
UINTToIP(&dhcp_ip, se->IpcAsync->L3ClientAddressOption.ServerAddress); UINTToIP(&dhcp_ip, se->IpcAsync->L3ClientAddressOption.ServerAddress);
IPCDhcpFreeIP(se->Ipc, &dhcp_ip); IPCDhcpFreeIP(se->Ipc, &dhcp_ip);
IPCProcessL3Events(se->Ipc); IPC_PROTO_SET_STATUS(se->Ipc, IPv6State, IPC_PROTO_STATUS_CLOSED);
IPCProcessL3EventsIPv4Only(se->Ipc);
} }
} }
} }
// Release the channel // Release the channel
for (i = 0;i < OPENVPN_NUM_CHANNELS;i++) for (i = 0; i < OPENVPN_NUM_CHANNELS; i++)
{ {
OPENVPN_CHANNEL *c = se->Channels[i]; OPENVPN_CHANNEL *c = se->Channels[i];
@ -2225,7 +2226,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
s->Now = Tick64(); s->Now = Tick64();
// Process for all sessions // Process for all sessions
for (i = 0;i < LIST_NUM(s->SessionList);i++) for (i = 0; i < LIST_NUM(s->SessionList); i++)
{ {
OPENVPN_SESSION *se = LIST_DATA(s->SessionList, i); OPENVPN_SESSION *se = LIST_DATA(s->SessionList, i);
@ -2240,7 +2241,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
} }
// Process received packets // Process received packets
for (i = 0;i < LIST_NUM(recv_packet_list);i++) for (i = 0; i < LIST_NUM(recv_packet_list); i++)
{ {
UDPPACKET *p = LIST_DATA(recv_packet_list, i); UDPPACKET *p = LIST_DATA(recv_packet_list, i);
@ -2248,7 +2249,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
} }
// Treat for all sessions and all channels // Treat for all sessions and all channels
for (i = 0;i < LIST_NUM(s->SessionList);i++) for (i = 0; i < LIST_NUM(s->SessionList); i++)
{ {
OPENVPN_CHANNEL *latest_channel = NULL; OPENVPN_CHANNEL *latest_channel = NULL;
UINT64 max_tick = 0; UINT64 max_tick = 0;
@ -2259,11 +2260,11 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
{ {
if (se->Mode == OPENVPN_MODE_L3) if (se->Mode == OPENVPN_MODE_L3)
{ {
IPCProcessL3Events(se->Ipc); IPCProcessL3EventsIPv4Only(se->Ipc);
} }
} }
for (j = 0;j < OPENVPN_NUM_CHANNELS;j++) for (j = 0; j < OPENVPN_NUM_CHANNELS; j++)
{ {
OPENVPN_CHANNEL *c = se->Channels[j]; OPENVPN_CHANNEL *c = se->Channels[j];
@ -2454,7 +2455,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
if (cao->ClasslessRoute.NumExistingRoutes >= 1) if (cao->ClasslessRoute.NumExistingRoutes >= 1)
{ {
UINT i; UINT i;
for (i = 0;i < MAX_DHCP_CLASSLESS_ROUTE_ENTRIES;i++) for (i = 0; i < MAX_DHCP_CLASSLESS_ROUTE_ENTRIES; i++)
{ {
DHCP_CLASSLESS_ROUTE *r = &cao->ClasslessRoute.Entries[i]; DHCP_CLASSLESS_ROUTE *r = &cao->ClasslessRoute.Entries[i];
@ -2594,7 +2595,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
UINT k; UINT k;
// Packet transmission // Packet transmission
for (k = 0;k < LIST_NUM(c->SendControlPacketList);k++) for (k = 0; k < LIST_NUM(c->SendControlPacketList); k++)
{ {
OPENVPN_CONTROL_PACKET *cp = LIST_DATA(c->SendControlPacketList, k); OPENVPN_CONTROL_PACKET *cp = LIST_DATA(c->SendControlPacketList, k);
@ -2656,14 +2657,14 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
} }
} }
IPCProcessL3Events(se->Ipc); IPCProcessL3EventsIPv4Only(se->Ipc);
} }
IPCProcessInterrupts(se->Ipc); IPCProcessInterrupts(se->Ipc);
} }
// Choose the latest channel in all established channels // Choose the latest channel in all established channels
for (j = 0;j < OPENVPN_NUM_CHANNELS;j++) for (j = 0; j < OPENVPN_NUM_CHANNELS; j++)
{ {
OPENVPN_CHANNEL *c = se->Channels[j]; OPENVPN_CHANNEL *c = se->Channels[j];
@ -2765,7 +2766,7 @@ void OvsRecvPacket(OPENVPN_SERVER *s, LIST *recv_packet_list, UINT protocol)
{ {
UINT i; UINT i;
for (i = 0;i < LIST_NUM(delete_session_list);i++) for (i = 0; i < LIST_NUM(delete_session_list); i++)
{ {
OPENVPN_SESSION *se = LIST_DATA(delete_session_list, i); OPENVPN_SESSION *se = LIST_DATA(delete_session_list, i);
@ -2798,7 +2799,7 @@ void OvsSendPacketNow(OPENVPN_SERVER *s, OPENVPN_SESSION *se, OPENVPN_PACKET *p)
if (p->NumAck >= 1) if (p->NumAck >= 1)
{ {
Debug("Sending ACK Packet IDs (c=%u): ", p->KeyId); Debug("Sending ACK Packet IDs (c=%u): ", p->KeyId);
for (i = 0;i < p->NumAck;i++) for (i = 0; i < p->NumAck; i++)
{ {
Debug("%u ", p->AckPacketId[i]); Debug("%u ", p->AckPacketId[i]);
} }
@ -2861,7 +2862,7 @@ OPENVPN_PACKET *OvsNewControlPacket(UCHAR opcode, UCHAR key_id, UINT64 my_channe
p->MySessionId = my_channel_id; p->MySessionId = my_channel_id;
p->NumAck = num_ack; p->NumAck = num_ack;
for (i = 0;i < MIN(num_ack, OPENVPN_MAX_NUMACK);i++) for (i = 0; i < MIN(num_ack, OPENVPN_MAX_NUMACK); i++)
{ {
p->AckPacketId[i] = ack_packet_ids[i]; p->AckPacketId[i] = ack_packet_ids[i];
} }

View File

@ -12,9 +12,6 @@ void PPPThread(THREAD *thread, void *param)
{ {
PPP_SESSION *p = (PPP_SESSION *)param; PPP_SESSION *p = (PPP_SESSION *)param;
UINT i; UINT i;
PPP_LCP *c;
USHORT us;
UINT ui;
USHORT next_protocol = 0; USHORT next_protocol = 0;
bool ret = false; bool ret = false;
char ipstr1[128], ipstr2[128]; char ipstr1[128], ipstr2[128];
@ -32,8 +29,6 @@ void PPPThread(THREAD *thread, void *param)
Debug("PPP Initialize"); Debug("PPP Initialize");
PPPSetStatus(p, PPP_STATUS_CONNECTED); PPPSetStatus(p, PPP_STATUS_CONNECTED);
p->IPv4_State = PPP_PROTO_STATUS_CLOSED;
p->IPv6_State = PPP_PROTO_STATUS_CLOSED;
p->Eap_Protocol = PPP_UNSPECIFIED; p->Eap_Protocol = PPP_UNSPECIFIED;
@ -181,7 +176,8 @@ void PPPThread(THREAD *thread, void *param)
{ {
UINT64 nowL; UINT64 nowL;
// Here client to server // Here client to server
if (p->CurrentPacket->Protocol == PPP_PROTOCOL_IP && p->IPv4_State == PPP_PROTO_STATUS_OPENED) if (p->CurrentPacket->Protocol == PPP_PROTOCOL_IP &&
IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_OPENED)
{ {
receivedPacketProcessed = true; receivedPacketProcessed = true;
IPCSendIPv4(p->Ipc, p->CurrentPacket->Data, p->CurrentPacket->DataSize); IPCSendIPv4(p->Ipc, p->CurrentPacket->Data, p->CurrentPacket->DataSize);
@ -190,10 +186,11 @@ void PPPThread(THREAD *thread, void *param)
{ {
Debug("Got IPv4 packet before IPv4 ready!\n"); Debug("Got IPv4 packet before IPv4 ready!\n");
} }
else if (p->CurrentPacket->Protocol == PPP_PROTOCOL_IPV6 && p->IPv6_State == PPP_PROTO_STATUS_OPENED) else if (p->CurrentPacket->Protocol == PPP_PROTOCOL_IPV6 &&
IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) == IPC_PROTO_STATUS_OPENED)
{ {
receivedPacketProcessed = true; receivedPacketProcessed = true;
Debug("IPv6 to be implemented\n"); IPCIPv6Send(p->Ipc, p->CurrentPacket->Data, p->CurrentPacket->DataSize);
} }
else if (p->CurrentPacket->Protocol == PPP_PROTOCOL_IPV6) else if (p->CurrentPacket->Protocol == PPP_PROTOCOL_IPV6)
{ {
@ -318,6 +315,8 @@ void PPPThread(THREAD *thread, void *param)
if (p->PPPStatus == PPP_STATUS_NETWORK_LAYER) if (p->PPPStatus == PPP_STATUS_NETWORK_LAYER)
{ {
UINT64 timeBeforeLoop; UINT64 timeBeforeLoop;
if (IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_OPENED)
{
if (p->DhcpAllocated) if (p->DhcpAllocated)
{ {
if (now >= p->DhcpNextRenewTime) if (now >= p->DhcpNextRenewTime)
@ -332,6 +331,7 @@ void PPPThread(THREAD *thread, void *param)
IPCDhcpRenewIP(p->Ipc, &ip); IPCDhcpRenewIP(p->Ipc, &ip);
} }
} }
}
IPCProcessL3Events(p->Ipc); IPCProcessL3Events(p->Ipc);
@ -340,13 +340,19 @@ void PPPThread(THREAD *thread, void *param)
while (true) while (true)
{ {
UINT64 nowL; UINT64 nowL;
bool no4packets = false;
bool no6packets = false;
if (IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_OPENED)
{
BLOCK *b = IPCRecvIPv4(p->Ipc); BLOCK *b = IPCRecvIPv4(p->Ipc);
PPP_PACKET *pp;
PPP_PACKET tmp;
if (b == NULL) if (b == NULL)
{ {
break; no4packets = true;
} }
else
{
PPP_PACKET *pp;
PPP_PACKET tmp;
// Since receiving the IP packet, send it to the client by PPP // Since receiving the IP packet, send it to the client by PPP
pp = &tmp; pp = &tmp;
@ -359,11 +365,48 @@ void PPPThread(THREAD *thread, void *param)
PPPSendPacketEx(p, pp, true); PPPSendPacketEx(p, pp, true);
FreePPPPacketEx(pp, true); FreePPPPacketEx(pp, true);
Free(b); Free(b); // Not FreeBlock because freed in FreePPPPacketEx
}
}
else
{
no4packets = true;
}
if (IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) == IPC_PROTO_STATUS_OPENED)
{
BLOCK *b = IPCIPv6Recv(p->Ipc);
if (b == NULL)
{
no6packets = true;
}
else
{
PPP_PACKET *pp;
PPP_PACKET tmp;
// Since receiving the IP packet, send it to the client by PPP
pp = &tmp;
pp->IsControl = false;
pp->Protocol = PPP_PROTOCOL_IPV6;
pp->Lcp = NULL;
pp->Data = b->Buf;
pp->DataSize = b->Size;
PPPSendPacketEx(p, pp, true);
FreePPPPacketEx(pp, true);
Free(b); // Not FreeBlock because freed in FreePPPPacketEx
}
}
else
{
no6packets = true;
}
// Let's break out of the loop once in a while so we don't get stuck here endlessly // Let's break out of the loop once in a while so we don't get stuck here endlessly
nowL = Tick64(); nowL = Tick64();
if (nowL > timeBeforeLoop + PPP_PACKET_RESEND_INTERVAL) if (nowL > timeBeforeLoop + PPP_PACKET_RESEND_INTERVAL || (no4packets && no6packets))
{ {
break; break;
} }
@ -743,7 +786,7 @@ bool PPPProcessResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req)
return PPPProcessIPCPResponsePacket(p, pp, req); return PPPProcessIPCPResponsePacket(p, pp, req);
break; break;
case PPP_PROTOCOL_IPV6CP: case PPP_PROTOCOL_IPV6CP:
Debug("IPv6CP to be implemented\n"); return PPPProcessIPv6CPResponsePacket(p, pp, req);
break; break;
case PPP_PROTOCOL_EAP: case PPP_PROTOCOL_EAP:
return PPPProcessEAPResponsePacket(p, pp, req); return PPPProcessEAPResponsePacket(p, pp, req);
@ -786,11 +829,11 @@ bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
USHORT *protocol = pp->Lcp->Data; USHORT *protocol = pp->Lcp->Data;
if (*protocol == PPP_PROTOCOL_IPCP || *protocol == PPP_PROTOCOL_IP) if (*protocol == PPP_PROTOCOL_IPCP || *protocol == PPP_PROTOCOL_IP)
{ {
p->IPv4_State = PPP_PROTO_STATUS_REJECTED; IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_REJECTED);
} }
if (*protocol == PPP_PROTOCOL_IPV6CP || *protocol == PPP_PROTOCOL_IPV6) if (*protocol == PPP_PROTOCOL_IPV6CP || *protocol == PPP_PROTOCOL_IPV6)
{ {
p->IPv6_State = PPP_PROTO_STATUS_REJECTED; IPC_PROTO_SET_STATUS(p->Ipc, IPv6State, IPC_PROTO_STATUS_REJECTED);
} }
} }
} }
@ -864,7 +907,7 @@ bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
WHERE; WHERE;
return false; return false;
} }
if (opt->DataSize == sizeof(USHORT) && *((USHORT*)(opt->Data)) == Endian16(PPP_LCP_AUTH_EAP)) if (opt->DataSize == sizeof(USHORT) && *((USHORT *)(opt->Data)) == Endian16(PPP_LCP_AUTH_EAP))
{ {
// Try to request MS-CHAPv2 then // Try to request MS-CHAPv2 then
if (!isAccepted) if (!isAccepted)
@ -877,7 +920,7 @@ bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
ms_chap_v2_code[2] = PPP_CHAP_ALG_MS_CHAP_V2; ms_chap_v2_code[2] = PPP_CHAP_ALG_MS_CHAP_V2;
Copy(&offer, ms_chap_v2_code, sizeof(ms_chap_v2_code)); Copy(&offer, ms_chap_v2_code, sizeof(ms_chap_v2_code));
Debug("NACK proto with code = 0x%x, cypher = 0x%x, offered cypher = 0x%x\n", pp->Lcp->Code, *((USHORT*)(opt->Data)), offer); Debug("NACK proto with code = 0x%x, cypher = 0x%x, offered cypher = 0x%x\n", pp->Lcp->Code, *((USHORT *)(opt->Data)), offer);
Debug("Request MSCHAPv2\n"); Debug("Request MSCHAPv2\n");
Add(c->OptionList, NewPPPOption(PPP_LCP_OPTION_AUTH, &ms_chap_v2_code, sizeof(ms_chap_v2_code))); Add(c->OptionList, NewPPPOption(PPP_LCP_OPTION_AUTH, &ms_chap_v2_code, sizeof(ms_chap_v2_code)));
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_LCP, c)) if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_LCP, c))
@ -903,7 +946,7 @@ bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0); PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0);
USHORT proto = Endian16(PPP_LCP_AUTH_PAP); USHORT proto = Endian16(PPP_LCP_AUTH_PAP);
Copy(&offer, t->Data, t->DataSize > sizeof(UINT64) ? sizeof(UINT64) : t->DataSize); Copy(&offer, t->Data, t->DataSize > sizeof(UINT64) ? sizeof(UINT64) : t->DataSize);
Debug("NACK proto with code = 0x%x, cypher = 0x%x, offered cypher = 0x%x\n", pp->Lcp->Code, *((USHORT*)(opt->Data)), offer); Debug("NACK proto with code = 0x%x, cypher = 0x%x, offered cypher = 0x%x\n", pp->Lcp->Code, *((USHORT *)(opt->Data)), offer);
Debug("Request PAP\n"); Debug("Request PAP\n");
Add(c->OptionList, NewPPPOption(PPP_LCP_OPTION_AUTH, &proto, sizeof(USHORT))); Add(c->OptionList, NewPPPOption(PPP_LCP_OPTION_AUTH, &proto, sizeof(USHORT)));
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_LCP, c)) if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_LCP, c))
@ -921,14 +964,14 @@ bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
} }
} }
else if (opt->DataSize == sizeof(USHORT) && *((USHORT*)(opt->Data)) == Endian16(PPP_LCP_AUTH_PAP)) else if (opt->DataSize == sizeof(USHORT) && *((USHORT *)(opt->Data)) == Endian16(PPP_LCP_AUTH_PAP))
{ {
// We couldn't agree on auth proto, failing connection // We couldn't agree on auth proto, failing connection
if (!isAccepted) if (!isAccepted)
{ {
UINT64 offer = 0; UINT64 offer = 0;
Copy(&offer, t->Data, t->DataSize > sizeof(UINT64) ? sizeof(UINT64) : t->DataSize); Copy(&offer, t->Data, t->DataSize > sizeof(UINT64) ? sizeof(UINT64) : t->DataSize);
Debug("NACK proto with code = 0x%x, cypher = 0x%x, offered cypher = 0x%x\n", pp->Lcp->Code, *((USHORT*)(opt->Data)), offer); Debug("NACK proto with code = 0x%x, cypher = 0x%x, offered cypher = 0x%x\n", pp->Lcp->Code, *((USHORT *)(opt->Data)), offer);
Debug("Couldn't agree on auth protocol!\n"); Debug("Couldn't agree on auth protocol!\n");
PPPLog(p, "LP_PAP_MSCHAPV2_REJECTED"); PPPLog(p, "LP_PAP_MSCHAPV2_REJECTED");
PPPSetStatus(p, PPP_STATUS_FAIL); PPPSetStatus(p, PPP_STATUS_FAIL);
@ -1082,7 +1125,7 @@ bool PPPProcessIPCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *re
if (!PPPGetIPAddressValueFromLCP(pp->Lcp, PPP_IPCP_OPTION_IP, &addrStruct) || pp->Lcp->Code == PPP_LCP_CODE_REJECT || pp->Lcp->Code == PPP_LCP_CODE_CODE_REJECT) if (!PPPGetIPAddressValueFromLCP(pp->Lcp, PPP_IPCP_OPTION_IP, &addrStruct) || pp->Lcp->Code == PPP_LCP_CODE_REJECT || pp->Lcp->Code == PPP_LCP_CODE_CODE_REJECT)
{ {
Debug("Unsupported IPCP protocol"); Debug("Unsupported IPCP protocol");
p->IPv4_State = PPP_PROTO_STATUS_REJECTED; IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_REJECTED);
PPPRejectUnsupportedPacketEx(p, pp, true); PPPRejectUnsupportedPacketEx(p, pp, true);
return false; return false;
} }
@ -1096,14 +1139,14 @@ bool PPPProcessIPCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *re
Debug("Accepted server IP address of %s\n", addrStr); Debug("Accepted server IP address of %s\n", addrStr);
// We already configured client address, now server address is also confirmed, ready for IPv4 data flow // We already configured client address, now server address is also confirmed, ready for IPv4 data flow
if (p->IPv4_State == PPP_PROTO_STATUS_CONFIG) if (IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_CONFIG)
{ {
p->IPv4_State = PPP_PROTO_STATUS_CONFIG_WAIT; IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_CONFIG_WAIT);
} }
return true; return true;
} }
p->IPv4_State = PPP_PROTO_STATUS_CONFIG; IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_CONFIG);
PPPGetIPAddressValueFromLCP(req->Lcp, PPP_IPCP_OPTION_IP, &prevAddrStruct); PPPGetIPAddressValueFromLCP(req->Lcp, PPP_IPCP_OPTION_IP, &prevAddrStruct);
prevAddr = IPToUINT(&prevAddrStruct); prevAddr = IPToUINT(&prevAddrStruct);
@ -1115,7 +1158,7 @@ bool PPPProcessIPCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *re
if (prevAddr == Endian32(0xc0000008)) if (prevAddr == Endian32(0xc0000008))
{ {
Debug("We already tried the fallback IP of 192.0.0.8, giving up\n"); Debug("We already tried the fallback IP of 192.0.0.8, giving up\n");
p->IPv4_State = PPP_PROTO_STATUS_REJECTED; IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_REJECTED);
PPPRejectUnsupportedPacketEx(p, pp, true); PPPRejectUnsupportedPacketEx(p, pp, true);
return false; return false;
} }
@ -1205,6 +1248,31 @@ bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
return false; return false;
} }
// Process IPv6CP responses
bool PPPProcessIPv6CPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req)
{
bool isAccepted = !PPP_LCP_CODE_IS_NEGATIVE(pp->Lcp->Code);
// If we got a reject or a NACK, we just reject the whole IPv6 configuration, there is no way we can recover even from a NACK as we can't change the link-local address of an already existing router
if (!isAccepted)
{
Debug("Unsupported IPv6CP protocol");
IPC_PROTO_SET_STATUS(p->Ipc, IPv6State, IPC_PROTO_STATUS_REJECTED);
PPPRejectUnsupportedPacketEx(p, pp, true);
return false;
}
if (IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) != IPC_PROTO_STATUS_CONFIG)
{
Debug("We got an early IPv6CP response, ignoring for now...\n");
return false;
}
Debug("Accepted server IPv6CP handshake\n");
IPC_PROTO_SET_STATUS(p->Ipc, IPv6State, IPC_PROTO_STATUS_CONFIG_WAIT);
return true;
}
// Processes request packets // Processes request packets
bool PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) bool PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
@ -1227,8 +1295,7 @@ bool PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
return PPPProcessIPCPRequestPacket(p, pp); return PPPProcessIPCPRequestPacket(p, pp);
break; break;
case PPP_PROTOCOL_IPV6CP: case PPP_PROTOCOL_IPV6CP:
PPPRejectUnsupportedPacketEx(p, pp, true); return PPPProcessIPv6CPRequestPacket(p, pp);
Debug("IPv6CP to be implemented\n");
break; break;
case PPP_PROTOCOL_EAP: case PPP_PROTOCOL_EAP:
return PPPProcessEAPRequestPacket(p, pp); return PPPProcessEAPRequestPacket(p, pp);
@ -1265,12 +1332,12 @@ bool PPPProcessLCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
{ {
case PPP_LCP_OPTION_AUTH: case PPP_LCP_OPTION_AUTH:
t->IsSupported = true; t->IsSupported = true;
if (t->DataSize == sizeof(USHORT) && *((USHORT*)t->Data) == PPP_LCP_AUTH_EAP && p->AuthProtocol == PPP_UNSPECIFIED) if (t->DataSize == sizeof(USHORT) && *((USHORT *)t->Data) == PPP_LCP_AUTH_EAP && p->AuthProtocol == PPP_UNSPECIFIED)
{ {
t->IsAccepted = true; t->IsAccepted = true;
NegotiatedAuthProto = PPP_PROTOCOL_EAP; NegotiatedAuthProto = PPP_PROTOCOL_EAP;
} }
else if (t->DataSize == sizeof(USHORT) && *((USHORT*)t->Data) == PPP_LCP_AUTH_PAP && p->AuthProtocol == PPP_UNSPECIFIED) else if (t->DataSize == sizeof(USHORT) && *((USHORT *)t->Data) == PPP_LCP_AUTH_PAP && p->AuthProtocol == PPP_UNSPECIFIED)
{ {
t->IsAccepted = true; t->IsAccepted = true;
NegotiatedAuthProto = PPP_PROTOCOL_PAP; NegotiatedAuthProto = PPP_PROTOCOL_PAP;
@ -1547,9 +1614,8 @@ bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
bool ok = true; bool ok = true;
bool processed = false; bool processed = false;
bool isEmptyIpAddress = false; bool isEmptyIpAddress = false;
PPP_LCP *c;
if (p->IPv4_State == PPP_PROTO_STATUS_REJECTED) if (IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_REJECTED)
{ {
Debug("We got an IPCP packet after we had it rejected\n"); Debug("We got an IPCP packet after we had it rejected\n");
return PPPRejectUnsupportedPacketEx(p, pp, true); return PPPRejectUnsupportedPacketEx(p, pp, true);
@ -1823,7 +1889,7 @@ bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
// We will delay this packet ACK and send the server IP first, then wait for a reparse // We will delay this packet ACK and send the server IP first, then wait for a reparse
// it is kind of dirty but fixes issues on some clients (namely VPN Client Pro on Android) // it is kind of dirty but fixes issues on some clients (namely VPN Client Pro on Android)
if (p->IPv4_State == PPP_PROTO_STATUS_CLOSED && p->ClientAddressOption.ServerAddress != 0 && ok) if (IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_CLOSED && p->ClientAddressOption.ServerAddress != 0 && ok)
{ {
PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0); PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0);
UINT ui = p->ClientAddressOption.ServerAddress; UINT ui = p->ClientAddressOption.ServerAddress;
@ -1834,7 +1900,7 @@ bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
WHERE; WHERE;
return false; return false;
} }
p->IPv4_State = PPP_PROTO_STATUS_CONFIG; IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_CONFIG);
if (!processed) if (!processed)
{ {
PPPAddNextPacket(p, pp, 1); PPPAddNextPacket(p, pp, 1);
@ -1843,7 +1909,8 @@ bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
} }
// We still haven't received any answer from client about server IP, keep waiting... // We still haven't received any answer from client about server IP, keep waiting...
if ((p->IPv4_State == PPP_PROTO_STATUS_CONFIG || p->IPv4_State == PPP_PROTO_STATUS_CLOSED) && !processed) if ((IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_CONFIG ||
IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_CLOSED) && !processed)
{ {
PPPAddNextPacket(p, pp, 1); PPPAddNextPacket(p, pp, 1);
return false; return false;
@ -1856,9 +1923,9 @@ bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
} }
Debug("ACKed IPCP options ID = 0x%x\n", pp->Lcp->Id); Debug("ACKed IPCP options ID = 0x%x\n", pp->Lcp->Id);
if (ok && p->IPv4_State == PPP_PROTO_STATUS_CONFIG_WAIT) if (ok && IPC_PROTO_GET_STATUS(p->Ipc, IPv4State) == IPC_PROTO_STATUS_CONFIG_WAIT)
{ {
p->IPv4_State = PPP_PROTO_STATUS_OPENED; IPC_PROTO_SET_STATUS(p->Ipc, IPv4State, IPC_PROTO_STATUS_OPENED);
Debug("IPv4 OPENED\n"); Debug("IPv4 OPENED\n");
} }
return ok; return ok;
@ -1871,6 +1938,116 @@ bool PPPProcessEAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
return false; return false;
} }
// Process IPv6CP request packets
bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp)
{
UINT i;
bool processed = false;
if (IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) == IPC_PROTO_STATUS_REJECTED)
{
Debug("We got an IPv6CP packet after we had it rejected\n");
return PPPRejectUnsupportedPacketEx(p, pp, true);
}
for (i = 0; i < LIST_NUM(pp->Lcp->OptionList); i++)
{
PPP_OPTION *t = LIST_DATA(pp->Lcp->OptionList, i);
switch (t->Type)
{
case PPP_IPV6CP_OPTION_EUI:
t->IsSupported = true;
if (t->DataSize == sizeof(UINT64))
{
UINT64 newValue = 0;
UINT64 value = READ_UINT64(t->Data);
if (value != 0 && !IPCIPv6CheckExistingLinkLocal(p->Ipc, value))
{
t->IsAccepted = true;
p->Ipc->IPv6ClientEUI = value;
}
else
{
t->IsAccepted = false;
GenerateEui64Address6((UCHAR *)&newValue, p->Ipc->MacAddress);
if (newValue != value && !IPCIPv6CheckExistingLinkLocal(p->Ipc, newValue))
{
WRITE_UINT64(t->AltData, newValue);
t->AltDataSize = sizeof(UINT64);
}
else
{
while (true)
{
newValue = Rand64();
if (!IPCIPv6CheckExistingLinkLocal(p->Ipc, newValue))
{
WRITE_UINT64(t->AltData, newValue);
t->AltDataSize = sizeof(UINT64);
break;
}
}
}
}
}
break;
default:
t->IsSupported = false;
break;
}
}
if (PPPRejectLCPOptionsEx(p, pp, processed))
{
Debug("Rejected IPv6CP options ID = 0x%x\n", pp->Lcp->Id);
processed = true;
}
if (PPPNackLCPOptionsEx(p, pp, processed))
{
Debug("NACKed IPv6CP options ID = 0x%x\n", pp->Lcp->Id);
processed = true;
}
if (p->Ipc->IPv6ClientEUI != 0 && IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) == IPC_PROTO_STATUS_CLOSED)
{
PPP_LCP *c = NewPPPLCP(PPP_LCP_CODE_REQ, 0);
UINT64 serverEui = IPCIPv6GetServerEui(p->Ipc);
if (serverEui != 0 && serverEui != p->Ipc->IPv6ClientEUI)
{
Add(c->OptionList, NewPPPOption(PPP_IPV6CP_OPTION_EUI, &serverEui, sizeof(UINT64)));
}
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_IPV6CP, c))
{
PPPSetStatus(p, PPP_STATUS_FAIL);
WHERE;
return false;
}
IPC_PROTO_SET_STATUS(p->Ipc, IPv6State, IPC_PROTO_STATUS_CONFIG);
}
if (IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) == IPC_PROTO_STATUS_CONFIG && !processed)
{
PPPAddNextPacket(p, pp, 1);
return false;
}
if (!PPPAckLCPOptionsEx(p, pp, processed))
{
return false;
}
Debug("ACKed IPv6CP options ID = 0x%x\n", pp->Lcp->Id);
if (IPC_PROTO_GET_STATUS(p->Ipc, IPv6State) == IPC_PROTO_STATUS_CONFIG_WAIT)
{
IPC_PROTO_SET_STATUS(p->Ipc, IPv6State, IPC_PROTO_STATUS_OPENED);
Debug("IPv6 OPENED\n");
}
return true;
}
// LCP option based packets utility // LCP option based packets utility
bool PPPRejectLCPOptions(PPP_SESSION *p, PPP_PACKET *pp) bool PPPRejectLCPOptions(PPP_SESSION *p, PPP_PACKET *pp)
{ {
@ -2128,7 +2305,7 @@ LABEL_LOOP:
if (async == false) if (async == false)
{ {
d = TubeRecvSync(p->TubeRecv, p->PacketRecvTimeout); d = TubeRecvSync(p->TubeRecv, (UINT)p->PacketRecvTimeout);
} }
else else
{ {
@ -2241,7 +2418,6 @@ PPP_PACKET *PPPGetNextPacket(PPP_SESSION *p)
void PPPAddNextPacket(PPP_SESSION *p, PPP_PACKET *pp, UINT delay) void PPPAddNextPacket(PPP_SESSION *p, PPP_PACKET *pp, UINT delay)
{ {
PPP_DELAYED_PACKET *t = ZeroMalloc(sizeof(PPP_DELAYED_PACKET)); PPP_DELAYED_PACKET *t = ZeroMalloc(sizeof(PPP_DELAYED_PACKET));
UINT i;
if (p->CurrentPacket == pp) if (p->CurrentPacket == pp)
{ {
p->CurrentPacket = NULL; p->CurrentPacket = NULL;
@ -2262,7 +2438,7 @@ void PPPAddNextPacket(PPP_SESSION *p, PPP_PACKET *pp, UINT delay)
Debug("after sorting delayeds end\n");*/ Debug("after sorting delayeds end\n");*/
} }
int PPPDelayedPacketsComparator(const void *a, const void *b) int PPPDelayedPacketsComparator(void *a, void *b)
{ {
PPP_DELAYED_PACKET *first = a; PPP_DELAYED_PACKET *first = a;
PPP_DELAYED_PACKET *second = b; PPP_DELAYED_PACKET *second = b;
@ -2675,7 +2851,7 @@ bool PPPParseMSCHAP2ResponsePacket(PPP_SESSION *p, PPP_PACKET *pp)
ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password, ipc = NewIPC(p->Cedar, p->ClientSoftwareName, p->Postfix, hub, id, password,
&error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort, &error_code, &p->ClientIP, p->ClientPort, &p->ServerIP, p->ServerPort,
p->ClientHostname, p->CryptName, false, p->AdjustMss, p->EapClient, NULL, p->ClientHostname, p->CryptName, false, p->AdjustMss, p->EapClient, NULL,
+ IPC_LAYER_3); + IPC_LAYER_3);
if (ipc != NULL) if (ipc != NULL)
{ {
@ -3009,12 +3185,11 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
UCHAR *dataBuffer; UCHAR *dataBuffer;
UINT dataSize; UINT dataSize;
UINT tlsLength = 0; UINT tlsLength = 0;
UINT i;
bool isFragmented = false; bool isFragmented = false;
PPP_LCP *lcp; PPP_LCP *lcp;
PPP_EAP *eap; PPP_EAP *eap;
UCHAR flags = PPP_EAP_TLS_FLAG_NONE; UCHAR flags = PPP_EAP_TLS_FLAG_NONE;
UINT64 sizeLeft = 0; UINT sizeLeft = 0;
Debug("Got EAP-TLS size=%i\n", eapTlsSize); Debug("Got EAP-TLS size=%i\n", eapTlsSize);
if (eapTlsSize == 1) if (eapTlsSize == 1)
{ {
@ -3024,7 +3199,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
// We got an ACK to transmit the next fragmented message // We got an ACK to transmit the next fragmented message
dataSize = p->Mru1 - 8 - 1 - 1; // Calculating the maximum payload size (without TlsLength) dataSize = p->Mru1 - 8 - 1 - 1; // Calculating the maximum payload size (without TlsLength)
sizeLeft = GetMemSize(p->Eap_TlsCtx.CachedBufferSend); sizeLeft = GetMemSize(p->Eap_TlsCtx.CachedBufferSend);
sizeLeft -= p->Eap_TlsCtx.CachedBufferSendPntr - p->Eap_TlsCtx.CachedBufferSend; sizeLeft -= (UINT)(p->Eap_TlsCtx.CachedBufferSendPntr - p->Eap_TlsCtx.CachedBufferSend);
flags = PPP_EAP_TLS_FLAG_FRAGMENTED; // M flag flags = PPP_EAP_TLS_FLAG_FRAGMENTED; // M flag
if (dataSize > sizeLeft) if (dataSize > sizeLeft)
@ -3035,7 +3210,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
lcp = BuildEAPTlsRequest(p->Eap_PacketId++, dataSize, flags); lcp = BuildEAPTlsRequest(p->Eap_PacketId++, dataSize, flags);
eap = lcp->Data; eap = lcp->Data;
Copy(eap->Tls.TlsDataWithoutLength, p->Eap_TlsCtx.CachedBufferSendPntr, dataSize); Copy(eap->Tls.TlsDataWithoutLength, p->Eap_TlsCtx.CachedBufferSendPntr, dataSize);
p->Eap_TlsCtx.CachedBufferSendPntr += dataSize; p->Eap_TlsCtx.CachedBufferSendPntr += (UINT64)dataSize;
if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp)) if (!PPPSendAndRetransmitRequest(p, PPP_PROTOCOL_EAP, lcp))
{ {
@ -3192,7 +3367,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
p->Eap_TlsCtx.CachedBufferRecvPntr = p->Eap_TlsCtx.CachedBufferRecv; p->Eap_TlsCtx.CachedBufferRecvPntr = p->Eap_TlsCtx.CachedBufferRecv;
} }
sizeLeft = GetMemSize(p->Eap_TlsCtx.CachedBufferRecv); sizeLeft = GetMemSize(p->Eap_TlsCtx.CachedBufferRecv);
sizeLeft -= p->Eap_TlsCtx.CachedBufferRecvPntr - p->Eap_TlsCtx.CachedBufferRecv; sizeLeft -= (UINT)(p->Eap_TlsCtx.CachedBufferRecvPntr - p->Eap_TlsCtx.CachedBufferRecv);
Copy(p->Eap_TlsCtx.CachedBufferRecvPntr, dataBuffer, MIN(sizeLeft, dataSize)); Copy(p->Eap_TlsCtx.CachedBufferRecvPntr, dataBuffer, MIN(sizeLeft, dataSize));
@ -3206,7 +3381,7 @@ bool PPPProcessEAPTlsResponse(PPP_SESSION *p, PPP_EAP *eap_packet, UINT eapTlsSi
dataSize = GetMemSize(p->Eap_TlsCtx.CachedBufferRecv); dataSize = GetMemSize(p->Eap_TlsCtx.CachedBufferRecv);
if (dataSize == MAX_BUFFERING_PACKET_SIZE) if (dataSize == MAX_BUFFERING_PACKET_SIZE)
{ {
dataSize = p->Eap_TlsCtx.CachedBufferRecvPntr - p->Eap_TlsCtx.CachedBufferRecv; dataSize = (UINT)(p->Eap_TlsCtx.CachedBufferRecvPntr - p->Eap_TlsCtx.CachedBufferRecv);
} }
} }
@ -3684,7 +3859,7 @@ void GenerateNtPasswordHash(UCHAR *dst, char *password)
tmp = ZeroMalloc(tmp_size); tmp = ZeroMalloc(tmp_size);
for (i = 0;i < len;i++) for (i = 0; i < len; i++)
{ {
tmp[i * 2] = password[i]; tmp[i * 2] = password[i];
} }
@ -3852,7 +4027,7 @@ char *MsChapV2DoBruteForce(IPC_MSCHAP_V2_AUTHINFO *d, LIST *password_list)
return NULL; return NULL;
} }
for (i = 0;i < LIST_NUM(password_list);i++) for (i = 0; i < LIST_NUM(password_list); i++)
{ {
char *s = LIST_DATA(password_list, i); char *s = LIST_DATA(password_list, i);
char tmp[MAX_SIZE]; char tmp[MAX_SIZE];
@ -3864,7 +4039,7 @@ char *MsChapV2DoBruteForce(IPC_MSCHAP_V2_AUTHINFO *d, LIST *password_list)
len = StrLen(tmp); len = StrLen(tmp);
max = Power(2, MIN(len, 9)); max = Power(2, MIN(len, 9));
for (j = 0;j < max;j++) for (j = 0; j < max; j++)
{ {
SetStrCaseAccordingToBits(tmp, j); SetStrCaseAccordingToBits(tmp, j);
if (MsChapV2VerityPassword(d, tmp)) if (MsChapV2VerityPassword(d, tmp))

View File

@ -95,7 +95,7 @@
#define PPP_IPCP_OPTION_WINS2 132 #define PPP_IPCP_OPTION_WINS2 132
// IPV6CP option type // IPV6CP option type
#define PPP_IPV6CP_OPTION_IID 1 #define PPP_IPV6CP_OPTION_EUI 1
// EAP codes // EAP codes
#define PPP_EAP_CODE_REQUEST 1 #define PPP_EAP_CODE_REQUEST 1
@ -135,13 +135,6 @@
#define PPP_STATUS_FAIL 0x1000 #define PPP_STATUS_FAIL 0x1000
#define PPP_STATUS_AUTH_FAIL 0x1010 #define PPP_STATUS_AUTH_FAIL 0x1010
// Protocol status
#define PPP_PROTO_STATUS_CLOSED 0x0
#define PPP_PROTO_STATUS_CONFIG 0x1
#define PPP_PROTO_STATUS_CONFIG_WAIT 0x2
#define PPP_PROTO_STATUS_OPENED 0x10
#define PPP_PROTO_STATUS_REJECTED 0x100
#define PPP_UNSPECIFIED 0xFFFF #define PPP_UNSPECIFIED 0xFFFF
//// Type //// Type
@ -301,8 +294,6 @@ struct PPP_SESSION
UCHAR ClientInterfaceId[8]; // Client IPv6CP Interface Identifier UCHAR ClientInterfaceId[8]; // Client IPv6CP Interface Identifier
UINT PPPStatus; UINT PPPStatus;
UINT IPv4_State;
UINT IPv6_State;
// EAP contexts // EAP contexts
UINT Eap_Protocol; // Current EAP Protocol used UINT Eap_Protocol; // Current EAP Protocol used
@ -344,12 +335,14 @@ bool PPPProcessLCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req
bool PPPProcessCHAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req); bool PPPProcessCHAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req);
bool PPPProcessIPCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req); bool PPPProcessIPCPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req);
bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req); bool PPPProcessEAPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req);
bool PPPProcessIPv6CPResponsePacket(PPP_SESSION *p, PPP_PACKET *pp, PPP_PACKET *req);
// Request packets // Request packets
bool PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *pp); bool PPPProcessRequestPacket(PPP_SESSION *p, PPP_PACKET *pp);
bool PPPProcessLCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp); bool PPPProcessLCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp);
bool PPPProcessPAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp); bool PPPProcessPAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp);
bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp); bool PPPProcessIPCPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp);
bool PPPProcessEAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp); bool PPPProcessEAPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp);
bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp);
// LCP option based packets utility // LCP option based packets utility
bool PPPRejectLCPOptions(PPP_SESSION *p, PPP_PACKET *pp); bool PPPRejectLCPOptions(PPP_SESSION *p, PPP_PACKET *pp);
@ -369,7 +362,7 @@ PPP_PACKET *PPPRecvPacket(PPP_SESSION *p, bool async);
// Helpers for delaying packets // Helpers for delaying packets
PPP_PACKET *PPPGetNextPacket(PPP_SESSION *p); PPP_PACKET *PPPGetNextPacket(PPP_SESSION *p);
void PPPAddNextPacket(PPP_SESSION *p, PPP_PACKET *pp, UINT delay); void PPPAddNextPacket(PPP_SESSION *p, PPP_PACKET *pp, UINT delay);
int PPPDelayedPacketsComparator(const void *a, const void *b); int PPPDelayedPacketsComparator(void *a, void *b);
char PPPRelatedPacketComparator(PPP_PACKET *a, PPP_PACKET *b); char PPPRelatedPacketComparator(PPP_PACKET *a, PPP_PACKET *b);
// PPP utility functions // PPP utility functions

View File

@ -98,7 +98,7 @@ NATIVE_NAT_ENTRY *NnGetOldestNatEntryOfIp(NATIVE_NAT *t, UINT ip, UINT protocol)
return NULL; return NULL;
} }
for (i = 0;i < LIST_NUM(t->NatTableForRecv->AllList);i++) for (i = 0; i < LIST_NUM(t->NatTableForRecv->AllList); i++)
{ {
NATIVE_NAT_ENTRY *e = LIST_DATA(t->NatTableForRecv->AllList, i); NATIVE_NAT_ENTRY *e = LIST_DATA(t->NatTableForRecv->AllList, i);
@ -129,7 +129,7 @@ UINT NnGetNumNatEntriesPerIp(NATIVE_NAT *t, UINT src_ip, UINT protocol)
return 0; return 0;
} }
for (i = 0;i < LIST_NUM(t->NatTableForRecv->AllList);i++) for (i = 0; i < LIST_NUM(t->NatTableForRecv->AllList); i++)
{ {
NATIVE_NAT_ENTRY *e = LIST_DATA(t->NatTableForRecv->AllList, i); NATIVE_NAT_ENTRY *e = LIST_DATA(t->NatTableForRecv->AllList, i);
@ -160,7 +160,7 @@ void NnDeleteOldSessions(NATIVE_NAT *t)
o = NULL; o = NULL;
now = t->v->Now; now = t->v->Now;
for (i = 0;i < LIST_NUM(t->NatTableForSend->AllList);i++) for (i = 0; i < LIST_NUM(t->NatTableForSend->AllList); i++)
{ {
NATIVE_NAT_ENTRY *e = LIST_DATA(t->NatTableForSend->AllList, i); NATIVE_NAT_ENTRY *e = LIST_DATA(t->NatTableForSend->AllList, i);
UINT64 timeout; UINT64 timeout;
@ -188,7 +188,7 @@ void NnDeleteOldSessions(NATIVE_NAT *t)
if (o != NULL) if (o != NULL)
{ {
for (i = 0;i < LIST_NUM(o);i++) for (i = 0; i < LIST_NUM(o); i++)
{ {
NATIVE_NAT_ENTRY *e = LIST_DATA(o, i); NATIVE_NAT_ENTRY *e = LIST_DATA(o, i);
@ -246,7 +246,7 @@ void NnPollingIpCombine(NATIVE_NAT *t)
// Discard the old combining object // Discard the old combining object
o = NULL; o = NULL;
for (i = 0;i < LIST_NUM(t->IpCombine);i++) for (i = 0; i < LIST_NUM(t->IpCombine); i++)
{ {
IP_COMBINE *c = LIST_DATA(t->IpCombine, i); IP_COMBINE *c = LIST_DATA(t->IpCombine, i);
@ -262,7 +262,7 @@ void NnPollingIpCombine(NATIVE_NAT *t)
if (o != NULL) if (o != NULL)
{ {
for (i = 0;i < LIST_NUM(o);i++) for (i = 0; i < LIST_NUM(o); i++)
{ {
IP_COMBINE *c = LIST_DATA(o, i); IP_COMBINE *c = LIST_DATA(o, i);
@ -336,7 +336,7 @@ void NnCombineIp(NATIVE_NAT *t, IP_COMBINE *c, UINT offset, void *data, UINT siz
// Check the overlap between the region which is represented by the offset and size of the // Check the overlap between the region which is represented by the offset and size of the
// existing received list and the region which is represented by the offset and size // existing received list and the region which is represented by the offset and size
for (i = 0;i < LIST_NUM(c->IpParts);i++) for (i = 0; i < LIST_NUM(c->IpParts); i++)
{ {
UINT moving_size; UINT moving_size;
IP_PART *p = LIST_DATA(c->IpParts, i); IP_PART *p = LIST_DATA(c->IpParts, i);
@ -393,7 +393,7 @@ void NnCombineIp(NATIVE_NAT *t, IP_COMBINE *c, UINT offset, void *data, UINT siz
UINT total_size = 0; UINT total_size = 0;
UINT i; UINT i;
for (i = 0;i < LIST_NUM(c->IpParts);i++) for (i = 0; i < LIST_NUM(c->IpParts); i++)
{ {
IP_PART *p = LIST_DATA(c->IpParts, i); IP_PART *p = LIST_DATA(c->IpParts, i);
@ -431,7 +431,7 @@ void NnFreeIpCombine(NATIVE_NAT *t, IP_COMBINE *c)
Free(c->Data); Free(c->Data);
// Release the partial list // Release the partial list
for (i = 0;i < LIST_NUM(c->IpParts);i++) for (i = 0; i < LIST_NUM(c->IpParts); i++)
{ {
IP_PART *p = LIST_DATA(c->IpParts, i); IP_PART *p = LIST_DATA(c->IpParts, i);
@ -525,7 +525,7 @@ void NnFreeIpCombineList(NATIVE_NAT *t)
return; return;
} }
for (i = 0;i < LIST_NUM(t->IpCombine);i++) for (i = 0; i < LIST_NUM(t->IpCombine); i++)
{ {
IP_COMBINE *c = LIST_DATA(t->IpCombine, i); IP_COMBINE *c = LIST_DATA(t->IpCombine, i);
@ -1562,7 +1562,7 @@ UINT NnMapNewPublicPort(NATIVE_NAT *t, UINT protocol, UINT dest_ip, UINT dest_po
base_port = Rand32() % (port_end - port_start) + port_start; base_port = Rand32() % (port_end - port_start) + port_start;
for (i = 0;i < (port_end - port_start);i++) for (i = 0; i < (port_end - port_start); i++)
{ {
UINT port; UINT port;
NATIVE_NAT_ENTRY tt; NATIVE_NAT_ENTRY tt;
@ -1753,7 +1753,7 @@ LABEL_RESTART:
UnlockQueue(t->SendQueue); UnlockQueue(t->SendQueue);
// Happy processing // Happy processing
IPCProcessL3Events(ipc); IPCProcessL3EventsIPv4Only(ipc);
LockQueue(t->RecvQueue); LockQueue(t->RecvQueue);
{ {
@ -2220,7 +2220,7 @@ bool NnParseDnsResponsePacket(UCHAR *data, UINT size, IP *ret_ip)
UINT num_answers = Endian16(h.AnswerRRs); UINT num_answers = Endian16(h.AnswerRRs);
UINT i; UINT i;
for (i = 0;i < num_questions;i++) for (i = 0; i < num_questions; i++)
{ {
BUF *r = NnReadDnsRecord(buf, false, NULL, NULL); BUF *r = NnReadDnsRecord(buf, false, NULL, NULL);
@ -2234,7 +2234,7 @@ bool NnParseDnsResponsePacket(UCHAR *data, UINT size, IP *ret_ip)
} }
} }
for (i = 0;i < num_answers;i++) for (i = 0; i < num_answers; i++)
{ {
USHORT tp, cl; USHORT tp, cl;
BUF *r = NnReadDnsRecord(buf, true, &tp, &cl); BUF *r = NnReadDnsRecord(buf, true, &tp, &cl);
@ -2370,7 +2370,7 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube)
} }
// Happy processing // Happy processing
IPCProcessL3Events(ipc); IPCProcessL3EventsIPv4Only(ipc);
while (true) while (true)
{ {
@ -2479,7 +2479,7 @@ bool NnTestConnectivity(NATIVE_STACK *a, TUBE *halt_tube)
} }
// Happy procedure // Happy procedure
IPCProcessL3Events(ipc); IPCProcessL3EventsIPv4Only(ipc);
while (true) while (true)
{ {
@ -3203,7 +3203,7 @@ void FreeNativeNat(NATIVE_NAT *t)
ReleaseCancel(t->Cancel); ReleaseCancel(t->Cancel);
// Release the NAT table // Release the NAT table
for (i = 0;i < LIST_NUM(t->NatTableForSend->AllList);i++) for (i = 0; i < LIST_NUM(t->NatTableForSend->AllList); i++)
{ {
NATIVE_NAT_ENTRY *e = LIST_DATA(t->NatTableForSend->AllList, i); NATIVE_NAT_ENTRY *e = LIST_DATA(t->NatTableForSend->AllList, i);
@ -3254,7 +3254,7 @@ NAT_ENTRY *GetOldestNatEntryOfIp(VH *v, UINT ip, UINT protocol)
return NULL; return NULL;
} }
for (i = 0;i < LIST_NUM(v->NatTable);i++) for (i = 0; i < LIST_NUM(v->NatTable); i++)
{ {
NAT_ENTRY *e = LIST_DATA(v->NatTable, i); NAT_ENTRY *e = LIST_DATA(v->NatTable, i);
@ -3291,7 +3291,7 @@ UINT GetNumNatEntriesPerIp(VH *v, UINT ip, UINT protocol, bool tcp_syn_sent)
return 0; return 0;
} }
for (i = 0;i < LIST_NUM(v->NatTable);i++) for (i = 0; i < LIST_NUM(v->NatTable); i++)
{ {
NAT_ENTRY *e = LIST_DATA(v->NatTable, i); NAT_ENTRY *e = LIST_DATA(v->NatTable, i);
@ -3425,7 +3425,7 @@ void NatThreadMain(VH *v)
LIST_ELEMENT_DELETED: LIST_ELEMENT_DELETED:
num = LIST_NUM(v->NatTable); num = LIST_NUM(v->NatTable);
for (i = 0;i < num;i++) for (i = 0; i < num; i++)
{ {
NAT_ENTRY *n = LIST_DATA(v->NatTable, i); NAT_ENTRY *n = LIST_DATA(v->NatTable, i);
@ -3484,7 +3484,7 @@ LIST_ELEMENT_DELETED:
NAT_ENTRY **nn = ToArray(v->NatTable); NAT_ENTRY **nn = ToArray(v->NatTable);
UINT i; UINT i;
for (i = 0;i < num;i++) for (i = 0; i < num; i++)
{ {
NAT_ENTRY *n = nn[i]; NAT_ENTRY *n = nn[i];
n->DisconnectNow = true; n->DisconnectNow = true;
@ -3695,7 +3695,7 @@ bool ArpaToIP(IP *ip, char *str)
// Convert the token [0, 1, 2, 3] to IP // Convert the token [0, 1, 2, 3] to IP
UINT i; UINT i;
Zero(ip, sizeof(IP)); Zero(ip, sizeof(IP));
for (i = 0;i < 4;i++) for (i = 0; i < 4; i++)
{ {
ip->addr[i] = (UCHAR)ToInt(token->Token[3 - i]); ip->addr[i] = (UCHAR)ToInt(token->Token[3 - i]);
} }
@ -4234,7 +4234,7 @@ bool NatTransactUdp(VH *v, NAT_ENTRY *n)
// Transfer by rewriting it properly // Transfer by rewriting it properly
UINT i; UINT i;
for (i = 0;i < LIST_NUM(local_ip_list);i++) for (i = 0; i < LIST_NUM(local_ip_list); i++)
{ {
IP *my_ip = LIST_DATA(local_ip_list, i); IP *my_ip = LIST_DATA(local_ip_list, i);
@ -4582,7 +4582,7 @@ void DeleteNatTcp(VH *v, NAT_ENTRY *n)
if (n->TcpRecvList != NULL) if (n->TcpRecvList != NULL)
{ {
UINT i; UINT i;
for (i = 0;i < LIST_NUM(n->TcpRecvList);i++) for (i = 0; i < LIST_NUM(n->TcpRecvList); i++)
{ {
IP_PART *p = LIST_DATA(n->TcpRecvList, i); IP_PART *p = LIST_DATA(n->TcpRecvList, i);
Free(p); Free(p);
@ -5234,7 +5234,7 @@ TCP_RESET:
me = ZeroMalloc(sizeof(IP_PART)); me = ZeroMalloc(sizeof(IP_PART));
me->Offset = offset; me->Offset = offset;
me->Size = size; me->Size = size;
for (i = 0;i < LIST_NUM(n->TcpRecvList);i++) for (i = 0; i < LIST_NUM(n->TcpRecvList); i++)
{ {
IP_PART *p = LIST_DATA(n->TcpRecvList, i); IP_PART *p = LIST_DATA(n->TcpRecvList, i);
// If there are overlapped region, remove these // If there are overlapped region, remove these
@ -5273,7 +5273,7 @@ TCP_RESET:
} }
KILL_NULL_FIRST: KILL_NULL_FIRST:
// Remove all blank items from reception list // Remove all blank items from reception list
for (i = 0;i < LIST_NUM(n->TcpRecvList);i++) for (i = 0; i < LIST_NUM(n->TcpRecvList); i++)
{ {
IP_PART *p = LIST_DATA(n->TcpRecvList, i); IP_PART *p = LIST_DATA(n->TcpRecvList, i);
if (p->Size == 0) if (p->Size == 0)
@ -5285,7 +5285,7 @@ KILL_NULL_FIRST:
} }
SCAN_FIRST: SCAN_FIRST:
// Extract if there is something starting at offset 0 in the received list // Extract if there is something starting at offset 0 in the received list
for (i = 0;i < LIST_NUM(n->TcpRecvList);i++) for (i = 0; i < LIST_NUM(n->TcpRecvList); i++)
{ {
IP_PART *p = LIST_DATA(n->TcpRecvList, i); IP_PART *p = LIST_DATA(n->TcpRecvList, i);
UINT sz; UINT sz;
@ -5301,7 +5301,7 @@ SCAN_FIRST:
Free(p); Free(p);
ReadFifo(n->TcpRecvWindow, NULL, sz); ReadFifo(n->TcpRecvWindow, NULL, sz);
// Slide all the items to the left // Slide all the items to the left
for (i = 0;i < LIST_NUM(n->TcpRecvList);i++) for (i = 0; i < LIST_NUM(n->TcpRecvList); i++)
{ {
p = LIST_DATA(n->TcpRecvList, i); p = LIST_DATA(n->TcpRecvList, i);
p->Offset -= sz; p->Offset -= sz;
@ -5678,7 +5678,7 @@ void PoolingNat(VH *v)
} }
// Process by scanning the all NAT entries // Process by scanning the all NAT entries
for (i = 0;i < LIST_NUM(v->NatTable);i++) for (i = 0; i < LIST_NUM(v->NatTable); i++)
{ {
NAT_ENTRY *n = LIST_DATA(v->NatTable, i); NAT_ENTRY *n = LIST_DATA(v->NatTable, i);
@ -6106,7 +6106,7 @@ void EncodeNetBiosName(UCHAR *dst, char *src)
return; return;
} }
for (i = 0;i < 16;i++) for (i = 0; i < 16; i++)
{ {
tmp[i] = ' '; tmp[i] = ' ';
} }
@ -6124,7 +6124,7 @@ void EncodeNetBiosName(UCHAR *dst, char *src)
tmp[15] = 0; tmp[15] = 0;
for (i = 0;i < 16;i++) for (i = 0; i < 16; i++)
{ {
char c = tmp[i]; char c = tmp[i];
char *s = CharToNetBiosStr(c); char *s = CharToNetBiosStr(c);
@ -6141,67 +6141,128 @@ char *CharToNetBiosStr(char c)
switch (c) switch (c)
{ {
case '\0': return "AA"; case '\0':
case 'A': return "EB"; return "AA";
case 'B': return "EC"; case 'A':
case 'C': return "ED"; return "EB";
case 'D': return "EE"; case 'B':
case 'E': return "EF"; return "EC";
case 'F': return "EG"; case 'C':
case 'G': return "EH"; return "ED";
case 'H': return "EI"; case 'D':
case 'I': return "EJ"; return "EE";
case 'J': return "EK"; case 'E':
case 'K': return "EL"; return "EF";
case 'L': return "EM"; case 'F':
case 'M': return "EN"; return "EG";
case 'N': return "EO"; case 'G':
case 'O': return "EP"; return "EH";
case 'P': return "FA"; case 'H':
case 'Q': return "FB"; return "EI";
case 'R': return "FC"; case 'I':
case 'S': return "FD"; return "EJ";
case 'T': return "FE"; case 'J':
case 'U': return "FF"; return "EK";
case 'V': return "FG"; case 'K':
case 'W': return "FH"; return "EL";
case 'X': return "FI"; case 'L':
case 'Y': return "FJ"; return "EM";
case 'Z': return "FK"; case 'M':
case '0': return "DA"; return "EN";
case '1': return "DB"; case 'N':
case '2': return "DC"; return "EO";
case '3': return "DD"; case 'O':
case '4': return "DE"; return "EP";
case '5': return "DF"; case 'P':
case '6': return "DG"; return "FA";
case '7': return "DH"; case 'Q':
case '8': return "DI"; return "FB";
case '9': return "DJ"; case 'R':
case ' ': return "CA"; return "FC";
case '!': return "CB"; case 'S':
case '\"': return "CC"; return "FD";
case '#': return "CD"; case 'T':
case '$': return "CE"; return "FE";
case '%': return "CF"; case 'U':
case '&': return "CG"; return "FF";
case '\'': return "CH"; case 'V':
case '(': return "CI"; return "FG";
case ')': return "CJ"; case 'W':
case '*': return "CK"; return "FH";
case '+': return "CL"; case 'X':
case ',': return "CM"; return "FI";
case '-': return "CN"; case 'Y':
case '.': return "CO"; return "FJ";
case '=': return "DN"; case 'Z':
case ':': return "DK"; return "FK";
case ';': return "DL"; case '0':
case '@': return "EA"; return "DA";
case '^': return "FO"; case '1':
case '_': return "FP"; return "DB";
case '{': return "HL"; case '2':
case '}': return "HN"; return "DC";
case '~': return "HO"; case '3':
return "DD";
case '4':
return "DE";
case '5':
return "DF";
case '6':
return "DG";
case '7':
return "DH";
case '8':
return "DI";
case '9':
return "DJ";
case ' ':
return "CA";
case '!':
return "CB";
case '\"':
return "CC";
case '#':
return "CD";
case '$':
return "CE";
case '%':
return "CF";
case '&':
return "CG";
case '\'':
return "CH";
case '(':
return "CI";
case ')':
return "CJ";
case '*':
return "CK";
case '+':
return "CL";
case ',':
return "CM";
case '-':
return "CN";
case '.':
return "CO";
case '=':
return "DN";
case ':':
return "DK";
case ';':
return "DL";
case '@':
return "EA";
case '^':
return "FO";
case '_':
return "FP";
case '{':
return "HL";
case '}':
return "HN";
case '~':
return "HO";
} }
return "CA"; return "CA";
@ -6316,7 +6377,7 @@ bool ProcessNetBiosNameQueryPacketForMyself(VH *v, UINT src_ip, UINT src_port, U
UINT i; UINT i;
// Return only private IP if there is a private IP // Return only private IP if there is a private IP
for (i = 0;i < LIST_NUM(ip_list);i++) for (i = 0; i < LIST_NUM(ip_list); i++)
{ {
IP *ip = LIST_DATA(ip_list, i); IP *ip = LIST_DATA(ip_list, i);
@ -6338,7 +6399,7 @@ bool ProcessNetBiosNameQueryPacketForMyself(VH *v, UINT src_ip, UINT src_port, U
if (found == false) if (found == false)
{ {
// Return all IP if no private IP are found // Return all IP if no private IP are found
for (i = 0;i < LIST_NUM(ip_list);i++) for (i = 0; i < LIST_NUM(ip_list); i++)
{ {
IP *ip = LIST_DATA(ip_list, i); IP *ip = LIST_DATA(ip_list, i);
@ -6741,7 +6802,7 @@ BUF *BuildDnsHostName(char *hostname)
b = NewBuf(); b = NewBuf();
// Add a host string // Add a host string
for (i = 0;i < token->NumTokens;i++) for (i = 0; i < token->NumTokens; i++)
{ {
size = (UCHAR)StrLen(token->Token[i]); size = (UCHAR)StrLen(token->Token[i]);
WriteBuf(b, &size, 1); WriteBuf(b, &size, 1);
@ -7147,7 +7208,7 @@ void PollingIpCombine(VH *v)
// Discard the old combining object // Discard the old combining object
o = NULL; o = NULL;
for (i = 0;i < LIST_NUM(v->IpCombine);i++) for (i = 0; i < LIST_NUM(v->IpCombine); i++)
{ {
IP_COMBINE *c = LIST_DATA(v->IpCombine, i); IP_COMBINE *c = LIST_DATA(v->IpCombine, i);
@ -7163,7 +7224,7 @@ void PollingIpCombine(VH *v)
if (o != NULL) if (o != NULL)
{ {
for (i = 0;i < LIST_NUM(o);i++) for (i = 0; i < LIST_NUM(o); i++)
{ {
IP_COMBINE *c = LIST_DATA(o, i); IP_COMBINE *c = LIST_DATA(o, i);
@ -7534,7 +7595,7 @@ void CombineIp(VH *v, IP_COMBINE *c, UINT offset, void *data, UINT size, bool la
// Check the overlap between the region which is represented by the offset and size of the // Check the overlap between the region which is represented by the offset and size of the
// existing received list and the region which is represented by the offset and size // existing received list and the region which is represented by the offset and size
for (i = 0;i < LIST_NUM(c->IpParts);i++) for (i = 0; i < LIST_NUM(c->IpParts); i++)
{ {
UINT moving_size; UINT moving_size;
IP_PART *p = LIST_DATA(c->IpParts, i); IP_PART *p = LIST_DATA(c->IpParts, i);
@ -7591,7 +7652,7 @@ void CombineIp(VH *v, IP_COMBINE *c, UINT offset, void *data, UINT size, bool la
UINT total_size = 0; UINT total_size = 0;
UINT i; UINT i;
for (i = 0;i < LIST_NUM(c->IpParts);i++) for (i = 0; i < LIST_NUM(c->IpParts); i++)
{ {
IP_PART *p = LIST_DATA(c->IpParts, i); IP_PART *p = LIST_DATA(c->IpParts, i);
@ -7628,7 +7689,7 @@ void FreeIpCombine(VH *v, IP_COMBINE *c)
Free(c->Data); Free(c->Data);
// Release the partial list // Release the partial list
for (i = 0;i < LIST_NUM(c->IpParts);i++) for (i = 0; i < LIST_NUM(c->IpParts); i++)
{ {
IP_PART *p = LIST_DATA(c->IpParts, i); IP_PART *p = LIST_DATA(c->IpParts, i);
@ -7722,7 +7783,7 @@ void FreeIpCombineList(VH *v)
return; return;
} }
for (i = 0;i < LIST_NUM(v->IpCombine);i++) for (i = 0; i < LIST_NUM(v->IpCombine); i++)
{ {
IP_COMBINE *c = LIST_DATA(v->IpCombine, i); IP_COMBINE *c = LIST_DATA(v->IpCombine, i);
@ -7894,7 +7955,7 @@ void SendWaitingIp(VH *v, UCHAR *mac, UINT dest_ip)
} }
// Get a target list // Get a target list
for (i = 0;i < LIST_NUM(v->IpWaitTable);i++) for (i = 0; i < LIST_NUM(v->IpWaitTable); i++)
{ {
IP_WAIT *w = LIST_DATA(v->IpWaitTable, i); IP_WAIT *w = LIST_DATA(v->IpWaitTable, i);
@ -7911,7 +7972,7 @@ void SendWaitingIp(VH *v, UCHAR *mac, UINT dest_ip)
// Send the target packets at once // Send the target packets at once
if (o != NULL) if (o != NULL)
{ {
for (i = 0;i < LIST_NUM(o);i++) for (i = 0; i < LIST_NUM(o); i++)
{ {
IP_WAIT *w = LIST_DATA(o, i); IP_WAIT *w = LIST_DATA(o, i);
@ -7942,7 +8003,7 @@ void DeleteOldIpWaitTable(VH *v)
} }
// Get the deleting list // Get the deleting list
for (i = 0;i < LIST_NUM(v->IpWaitTable);i++) for (i = 0; i < LIST_NUM(v->IpWaitTable); i++)
{ {
IP_WAIT *w = LIST_DATA(v->IpWaitTable, i); IP_WAIT *w = LIST_DATA(v->IpWaitTable, i);
@ -7959,7 +8020,7 @@ void DeleteOldIpWaitTable(VH *v)
// Delete all at once // Delete all at once
if (o != NULL) if (o != NULL)
{ {
for (i = 0;i < LIST_NUM(o);i++) for (i = 0; i < LIST_NUM(o); i++)
{ {
IP_WAIT *w = LIST_DATA(o, i); IP_WAIT *w = LIST_DATA(o, i);
@ -8023,7 +8084,7 @@ void FreeIpWaitTable(VH *v)
return; return;
} }
for (i = 0;i < LIST_NUM(v->IpWaitTable);i++) for (i = 0; i < LIST_NUM(v->IpWaitTable); i++)
{ {
IP_WAIT *w = LIST_DATA(v->IpWaitTable, i); IP_WAIT *w = LIST_DATA(v->IpWaitTable, i);
@ -8068,7 +8129,7 @@ void PollingArpWaitTable(VH *v)
o = NULL; o = NULL;
// Scan whole ARP waiting list // Scan whole ARP waiting list
for (i = 0;i < LIST_NUM(v->ArpWaitTable);i++) for (i = 0; i < LIST_NUM(v->ArpWaitTable); i++)
{ {
ARP_WAIT *w = LIST_DATA(v->ArpWaitTable, i); ARP_WAIT *w = LIST_DATA(v->ArpWaitTable, i);
@ -8099,7 +8160,7 @@ void PollingArpWaitTable(VH *v)
// Remove if there is a ARP waiting record to be deleted // Remove if there is a ARP waiting record to be deleted
if (o != NULL) if (o != NULL)
{ {
for (i = 0;i < LIST_NUM(o);i++) for (i = 0; i < LIST_NUM(o); i++)
{ {
ARP_WAIT *w = LIST_DATA(o, i); ARP_WAIT *w = LIST_DATA(o, i);
@ -8210,7 +8271,7 @@ void FreeArpWaitTable(VH *v)
return; return;
} }
for (i = 0;i < LIST_NUM(v->ArpWaitTable);i++) for (i = 0; i < LIST_NUM(v->ArpWaitTable); i++)
{ {
ARP_WAIT *w = LIST_DATA(v->ArpWaitTable, i); ARP_WAIT *w = LIST_DATA(v->ArpWaitTable, i);
@ -8220,46 +8281,6 @@ void FreeArpWaitTable(VH *v)
ReleaseList(v->ArpWaitTable); ReleaseList(v->ArpWaitTable);
} }
// Check whether the MAC address is valid
bool IsMacInvalid(UCHAR *mac)
{
UINT i;
// Validate arguments
if (mac == NULL)
{
return false;
}
for (i = 0;i < 6;i++)
{
if (mac[i] != 0x00)
{
return false;
}
}
return true;
}
// Check whether the MAC address is a broadcast address
bool IsMacBroadcast(UCHAR *mac)
{
UINT i;
// Validate arguments
if (mac == NULL)
{
return false;
}
for (i = 0;i < 6;i++)
{
if (mac[i] != 0xff)
{
return false;
}
}
return true;
}
// Insert an entry in the ARP table // Insert an entry in the ARP table
void InsertArpTable(VH *v, UCHAR *mac, UINT ip) void InsertArpTable(VH *v, UCHAR *mac, UINT ip)
{ {
@ -8325,7 +8346,7 @@ void RefreshArpTable(VH *v)
} }
o = NewListFast(NULL); o = NewListFast(NULL);
for (i = 0;i < LIST_NUM(v->ArpTable);i++) for (i = 0; i < LIST_NUM(v->ArpTable); i++)
{ {
ARP_ENTRY *e = LIST_DATA(v->ArpTable, i); ARP_ENTRY *e = LIST_DATA(v->ArpTable, i);
@ -8338,7 +8359,7 @@ void RefreshArpTable(VH *v)
} }
// Remove expired entries at once // Remove expired entries at once
for (i = 0;i < LIST_NUM(o);i++) for (i = 0; i < LIST_NUM(o); i++)
{ {
ARP_ENTRY *e = LIST_DATA(o, i); ARP_ENTRY *e = LIST_DATA(o, i);
@ -8388,7 +8409,7 @@ void FreeArpTable(VH *v)
} }
// Delete all entries // Delete all entries
for (i = 0;i < LIST_NUM(v->ArpTable);i++) for (i = 0; i < LIST_NUM(v->ArpTable); i++)
{ {
ARP_ENTRY *e = LIST_DATA(v->ArpTable, i); ARP_ENTRY *e = LIST_DATA(v->ArpTable, i);
Free(e); Free(e);
@ -9302,7 +9323,7 @@ UINT GetFreeDhcpIpAddress(VH *v)
ip_start = Endian32(v->DhcpIpStart); ip_start = Endian32(v->DhcpIpStart);
ip_end = Endian32(v->DhcpIpEnd); ip_end = Endian32(v->DhcpIpEnd);
for (i = ip_start; i <= ip_end;i++) for (i = ip_start; i <= ip_end; i++)
{ {
UINT ip = Endian32(i); UINT ip = Endian32(i);
if (SearchDhcpLeaseByIp(v, ip) == NULL && SearchDhcpPendingLeaseByIp(v, ip) == NULL) if (SearchDhcpLeaseByIp(v, ip) == NULL && SearchDhcpPendingLeaseByIp(v, ip) == NULL)
@ -9339,7 +9360,7 @@ UINT GetFreeDhcpIpAddressByRandom(VH *v, UCHAR *mac)
num_retry = (ip_end - ip_start + 1) * 2; num_retry = (ip_end - ip_start + 1) * 2;
num_retry = MIN(num_retry, 65536 * 2); num_retry = MIN(num_retry, 65536 * 2);
for (i = 0;i < num_retry;i++) for (i = 0; i < num_retry; i++)
{ {
UCHAR rand_seed[sizeof(UINT) + 6]; UCHAR rand_seed[sizeof(UINT) + 6];
UCHAR hash[16]; UCHAR hash[16];
@ -9964,7 +9985,7 @@ void SetVirtualHostOption(VH *v, VH_OPTION *vo)
LockVirtual(v); LockVirtual(v);
{ {
// Set the MAC address // Set the MAC address
for (i = 0;i < 6;i++) for (i = 0; i < 6; i++)
{ {
if (vo->MacAddress[i] != 0) if (vo->MacAddress[i] != 0)
{ {

View File

@ -409,8 +409,6 @@ ARP_ENTRY *SearchArpTable(VH *v, UINT ip);
void RefreshArpTable(VH *v); void RefreshArpTable(VH *v);
void PollingArpTable(VH *v); void PollingArpTable(VH *v);
void InsertArpTable(VH *v, UCHAR *mac, UINT ip); void InsertArpTable(VH *v, UCHAR *mac, UINT ip);
bool IsMacBroadcast(UCHAR *mac);
bool IsMacInvalid(UCHAR *mac);
void InitArpWaitTable(VH *v); void InitArpWaitTable(VH *v);
void FreeArpWaitTable(VH *v); void FreeArpWaitTable(VH *v);
int CompareArpWaitTable(void *p1, void *p2); int CompareArpWaitTable(void *p1, void *p2);

File diff suppressed because it is too large Load Diff

View File

@ -357,7 +357,7 @@ typedef struct SOCKLIST
// Parameters for timeout thread for Solaris // Parameters for timeout thread for Solaris
typedef struct SOCKET_TIMEOUT_PARAM{ typedef struct SOCKET_TIMEOUT_PARAM {
SOCK *sock; SOCK *sock;
CANCEL *cancel; CANCEL *cancel;
THREAD *thread; THREAD *thread;
@ -1302,6 +1302,15 @@ void IPAnd4(IP *dst, IP *a, IP *b);
bool IsInSameNetwork4(IP *a1, IP *a2, IP *subnet); bool IsInSameNetwork4(IP *a1, IP *a2, IP *subnet);
bool IsInSameNetwork4Standard(IP *a1, IP *a2); bool IsInSameNetwork4Standard(IP *a1, IP *a2);
// Utility functions about IP and MAC address types
bool IsValidUnicastIPAddress4(IP *ip);
bool IsValidUnicastIPAddressUINT4(UINT ip);
bool IsValidUnicastIPAddress6(IP *ip);
bool IsMacUnicast(UCHAR *mac);
bool IsMacBroadcast(UCHAR *mac);
bool IsMacMulticast(UCHAR *mac);
bool IsMacInvalid(UCHAR *mac);
bool ParseIpAndSubnetMask4(char *src, UINT *ip, UINT *mask); bool ParseIpAndSubnetMask4(char *src, UINT *ip, UINT *mask);
bool ParseIpAndSubnetMask46(char *src, IP *ip, IP *mask); bool ParseIpAndSubnetMask46(char *src, IP *ip, IP *mask);
bool ParseIpAndMask4(char *src, UINT *ip, UINT *mask); bool ParseIpAndMask4(char *src, UINT *ip, UINT *mask);

View File

@ -804,7 +804,7 @@ bool VLanRemoveTag(void **packet_data, UINT *packet_size, UINT vlan_id, UINT vla
UINT dest_size = src_size - 4; UINT dest_size = src_size - 4;
UINT i; UINT i;
for (i = 12;i < dest_size;i++) for (i = 12; i < dest_size; i++)
{ {
src_data[i] = src_data[i + 4]; src_data[i] = src_data[i + 4];
} }
@ -889,6 +889,44 @@ BUF *BuildICMPv6NeighborSoliciation(IPV6_ADDR *src_ip, IPV6_ADDR *target_ip, UCH
return ret; return ret;
} }
BUF *BuildICMPv6RouterSoliciation(IPV6_ADDR *src_ip, IPV6_ADDR *target_ip, UCHAR *my_mac_address, UINT id)
{
ICMPV6_OPTION_LIST opt;
ICMPV6_OPTION_LINK_LAYER link;
ICMPV6_ROUTER_SOLICIATION_HEADER header;
BUF *b;
BUF *b2;
BUF *ret;
if (src_ip == NULL || target_ip == NULL || my_mac_address == NULL)
{
return NULL;
}
Zero(&link, sizeof(link));
Copy(link.Address, my_mac_address, 6);
Zero(&opt, sizeof(opt));
opt.SourceLinkLayer = &link;
b = BuildICMPv6Options(&opt);
Zero(&header, sizeof(header));
b2 = NewBuf();
WriteBuf(b2, &header, sizeof(header));
WriteBufBuf(b2, b);
ret = BuildICMPv6(src_ip, target_ip, 255,
ICMPV6_TYPE_ROUTER_SOLICIATION, 0, b2->Buf, b2->Size, id);
FreeBuf(b);
FreeBuf(b2);
return ret;
}
// Get the next header number from the queue // Get the next header number from the queue
UCHAR IPv6GetNextHeaderFromQueue(QUEUE *q) UCHAR IPv6GetNextHeaderFromQueue(QUEUE *q)
{ {
@ -1102,6 +1140,7 @@ void BuildICMPv6OptionValue(BUF *b, UCHAR type, void *header_pointer, UINT total
BUF *BuildICMPv6Options(ICMPV6_OPTION_LIST *o) BUF *BuildICMPv6Options(ICMPV6_OPTION_LIST *o)
{ {
BUF *b; BUF *b;
UINT i;
// Validate arguments // Validate arguments
if (o == NULL) if (o == NULL)
{ {
@ -1118,9 +1157,16 @@ BUF *BuildICMPv6Options(ICMPV6_OPTION_LIST *o)
{ {
BuildICMPv6OptionValue(b, ICMPV6_OPTION_TYPE_TARGET_LINK_LAYER, o->TargetLinkLayer, sizeof(ICMPV6_OPTION_LINK_LAYER)); BuildICMPv6OptionValue(b, ICMPV6_OPTION_TYPE_TARGET_LINK_LAYER, o->TargetLinkLayer, sizeof(ICMPV6_OPTION_LINK_LAYER));
} }
if (o->Prefix != NULL) for (i = 0; i < ICMPV6_OPTION_PREFIXES_MAX_COUNT; i++)
{ {
BuildICMPv6OptionValue(b, ICMPV6_OPTION_TYPE_PREFIX, o->Prefix, sizeof(ICMPV6_OPTION_PREFIX)); if (o->Prefix[i] != NULL)
{
BuildICMPv6OptionValue(b, ICMPV6_OPTION_TYPE_PREFIX, o->Prefix[i], sizeof(ICMPV6_OPTION_PREFIX));
}
else
{
break;
}
} }
if (o->Mtu != NULL) if (o->Mtu != NULL)
{ {
@ -1452,6 +1498,12 @@ PKT *ClonePacket(PKT *p, bool copy_data)
return ret; return ret;
} }
// Parse the packet but without data layer except for ICMP
PKT *ParsePacketUpToICMPv6(UCHAR *buf, UINT size)
{
return ParsePacketEx5(buf, size, false, 0, true, true, false, true);
}
// Parse the contents of the packet // Parse the contents of the packet
PKT *ParsePacket(UCHAR *buf, UINT size) PKT *ParsePacket(UCHAR *buf, UINT size)
{ {
@ -1470,6 +1522,10 @@ PKT *ParsePacketEx3(UCHAR *buf, UINT size, bool no_l3, UINT vlan_type_id, bool b
return ParsePacketEx4(buf, size, no_l3, vlan_type_id, bridge_id_as_mac_address, false, false); return ParsePacketEx4(buf, size, no_l3, vlan_type_id, bridge_id_as_mac_address, false, false);
} }
PKT *ParsePacketEx4(UCHAR *buf, UINT size, bool no_l3, UINT vlan_type_id, bool bridge_id_as_mac_address, bool no_http, bool correct_checksum) PKT *ParsePacketEx4(UCHAR *buf, UINT size, bool no_l3, UINT vlan_type_id, bool bridge_id_as_mac_address, bool no_http, bool correct_checksum)
{
return ParsePacketEx5(buf, size, no_l3, vlan_type_id, bridge_id_as_mac_address, no_http, correct_checksum, false);
}
PKT *ParsePacketEx5(UCHAR *buf, UINT size, bool no_l3, UINT vlan_type_id, bool bridge_id_as_mac_address, bool no_http, bool correct_checksum, bool no_l3_l4_except_icmpv6)
{ {
PKT *p; PKT *p;
USHORT vlan_type_id_16; USHORT vlan_type_id_16;
@ -1559,7 +1615,7 @@ PKT *ParsePacketEx4(UCHAR *buf, UINT size, bool no_l3, UINT vlan_type_id, bool b
} }
// Do parse // Do parse
if (ParsePacketL2Ex(p, buf, size, no_l3) == false) if (ParsePacketL2Ex(p, buf, size, no_l3, no_l3_l4_except_icmpv6) == false)
{ {
// Parsing failure // Parsing failure
FreePacket(p); FreePacket(p);
@ -1929,7 +1985,7 @@ HTTPLOG *ParseHttpAccessLog(PKT *pkt)
// Layer-2 parsing // Layer-2 parsing
bool ParsePacketL2Ex(PKT *p, UCHAR *buf, UINT size, bool no_l3) bool ParsePacketL2Ex(PKT *p, UCHAR *buf, UINT size, bool no_l3, bool no_l3_l4_except_icmpv6)
{ {
UINT i; UINT i;
bool b1, b2; bool b1, b2;
@ -1956,7 +2012,7 @@ bool ParsePacketL2Ex(PKT *p, UCHAR *buf, UINT size, bool no_l3)
p->BroadcastPacket = true; p->BroadcastPacket = true;
b1 = true; b1 = true;
b2 = true; b2 = true;
for (i = 0;i < 6;i++) for (i = 0; i < 6; i++)
{ {
if (p->MacHeader->DestAddress[i] != 0xff) if (p->MacHeader->DestAddress[i] != 0xff)
{ {
@ -1994,7 +2050,7 @@ bool ParsePacketL2Ex(PKT *p, UCHAR *buf, UINT size, bool no_l3)
switch (type_id_16) switch (type_id_16)
{ {
case MAC_PROTO_ARPV4: // ARPv4 case MAC_PROTO_ARPV4: // ARPv4
if (no_l3) if (no_l3 || no_l3_l4_except_icmpv6)
{ {
return true; return true;
} }
@ -2002,7 +2058,7 @@ bool ParsePacketL2Ex(PKT *p, UCHAR *buf, UINT size, bool no_l3)
return ParsePacketARPv4(p, buf, size); return ParsePacketARPv4(p, buf, size);
case MAC_PROTO_IPV4: // IPv4 case MAC_PROTO_IPV4: // IPv4
if (no_l3) if (no_l3 || no_l3_l4_except_icmpv6)
{ {
return true; return true;
} }
@ -2015,7 +2071,7 @@ bool ParsePacketL2Ex(PKT *p, UCHAR *buf, UINT size, bool no_l3)
return true; return true;
} }
return ParsePacketIPv6(p, buf, size); return ParsePacketIPv6(p, buf, size, no_l3_l4_except_icmpv6);
default: // Unknown default: // Unknown
if (type_id_16 == p->VlanTypeID) if (type_id_16 == p->VlanTypeID)
@ -2354,7 +2410,15 @@ bool ParseICMPv6Options(ICMPV6_OPTION_LIST *o, UCHAR *buf, UINT size)
// Prefix Information // Prefix Information
if (header_total_size >= sizeof(ICMPV6_OPTION_PREFIX)) if (header_total_size >= sizeof(ICMPV6_OPTION_PREFIX))
{ {
o->Prefix = (ICMPV6_OPTION_PREFIX *)header_pointer; UINT i;
for (i = 0; i < ICMPV6_OPTION_PREFIXES_MAX_COUNT; i++)
{
if (o->Prefix[i] == NULL)
{
o->Prefix[i] = (ICMPV6_OPTION_PREFIX *)header_pointer;
break;
}
}
} }
else else
{ {
@ -2508,6 +2572,7 @@ bool ParseICMPv6(PKT *p, UCHAR *buf, UINT size)
// Release of the ICMPv6 options // Release of the ICMPv6 options
void FreeCloneICMPv6Options(ICMPV6_OPTION_LIST *o) void FreeCloneICMPv6Options(ICMPV6_OPTION_LIST *o)
{ {
UINT i;
// Validate arguments // Validate arguments
if (o == NULL) if (o == NULL)
{ {
@ -2516,13 +2581,19 @@ void FreeCloneICMPv6Options(ICMPV6_OPTION_LIST *o)
Free(o->SourceLinkLayer); Free(o->SourceLinkLayer);
Free(o->TargetLinkLayer); Free(o->TargetLinkLayer);
Free(o->Prefix);
for (i = 0; i < ICMPV6_OPTION_PREFIXES_MAX_COUNT; i++)
{
Free(o->Prefix[i]);
o->Prefix[i] = NULL;
}
Free(o->Mtu); Free(o->Mtu);
} }
// Clone of the ICMPv6 options // Clone of the ICMPv6 options
void CloneICMPv6Options(ICMPV6_OPTION_LIST *dst, ICMPV6_OPTION_LIST *src) void CloneICMPv6Options(ICMPV6_OPTION_LIST *dst, ICMPV6_OPTION_LIST *src)
{ {
UINT i;
// Validate arguments // Validate arguments
if (dst == NULL || src == NULL) if (dst == NULL || src == NULL)
{ {
@ -2533,12 +2604,22 @@ void CloneICMPv6Options(ICMPV6_OPTION_LIST *dst, ICMPV6_OPTION_LIST *src)
dst->SourceLinkLayer = Clone(src->SourceLinkLayer, sizeof(ICMPV6_OPTION_LINK_LAYER)); dst->SourceLinkLayer = Clone(src->SourceLinkLayer, sizeof(ICMPV6_OPTION_LINK_LAYER));
dst->TargetLinkLayer = Clone(src->TargetLinkLayer, sizeof(ICMPV6_OPTION_LINK_LAYER)); dst->TargetLinkLayer = Clone(src->TargetLinkLayer, sizeof(ICMPV6_OPTION_LINK_LAYER));
dst->Prefix = Clone(src->Prefix, sizeof(ICMPV6_OPTION_PREFIX)); for (i = 0; i < ICMPV6_OPTION_PREFIXES_MAX_COUNT; i++)
{
if (src->Prefix[i] != NULL)
{
dst->Prefix[i] = Clone(src->Prefix[i], sizeof(ICMPV6_OPTION_PREFIX));
}
else
{
break;
}
}
dst->Mtu = Clone(src->Mtu, sizeof(ICMPV6_OPTION_MTU)); dst->Mtu = Clone(src->Mtu, sizeof(ICMPV6_OPTION_MTU));
} }
// IPv6 parsing // IPv6 parsing
bool ParsePacketIPv6(PKT *p, UCHAR *buf, UINT size) bool ParsePacketIPv6(PKT *p, UCHAR *buf, UINT size, bool no_l3_l4_except_icmpv6)
{ {
// Validate arguments // Validate arguments
if (p == NULL || buf == NULL) if (p == NULL || buf == NULL)
@ -2585,9 +2666,17 @@ bool ParsePacketIPv6(PKT *p, UCHAR *buf, UINT size)
} }
case IP_PROTO_TCP: // TCP case IP_PROTO_TCP: // TCP
if (no_l3_l4_except_icmpv6)
{
return true;
}
return ParseTCP(p, buf, size); return ParseTCP(p, buf, size);
case IP_PROTO_UDP: // UDP case IP_PROTO_UDP: // UDP
if (no_l3_l4_except_icmpv6)
{
return true;
}
return ParseUDP(p, buf, size); return ParseUDP(p, buf, size);
default: // Unknown default: // Unknown
@ -3247,7 +3336,7 @@ BUF *BuildDhcpOptionsBuf(LIST *o)
} }
b = NewBuf(); b = NewBuf();
for (i = 0;i < LIST_NUM(o);i++) for (i = 0; i < LIST_NUM(o); i++)
{ {
DHCP_OPTION *d = LIST_DATA(o, i); DHCP_OPTION *d = LIST_DATA(o, i);
UINT current_size = d->Size; UINT current_size = d->Size;
@ -3556,7 +3645,7 @@ void BuildClasslessRouteTableStr(char *str, UINT str_size, DHCP_CLASSLESS_ROUTE_
return; return;
} }
for (i = 0;i < MAX_DHCP_CLASSLESS_ROUTE_ENTRIES;i++) for (i = 0; i < MAX_DHCP_CLASSLESS_ROUTE_ENTRIES; i++)
{ {
DHCP_CLASSLESS_ROUTE *r = &t->Entries[i]; DHCP_CLASSLESS_ROUTE *r = &t->Entries[i];
@ -3628,7 +3717,7 @@ bool ParseClasslessRouteTableStr(DHCP_CLASSLESS_ROUTE_TABLE *d, char *str)
{ {
UINT i; UINT i;
for (i = 0;i < t->NumTokens;i++) for (i = 0; i < t->NumTokens; i++)
{ {
DHCP_CLASSLESS_ROUTE r; DHCP_CLASSLESS_ROUTE r;
@ -3728,7 +3817,7 @@ BUF *DhcpBuildClasslessRouteData(DHCP_CLASSLESS_ROUTE_TABLE *t)
b = NewBuf(); b = NewBuf();
for (i = 0;i < MAX_DHCP_CLASSLESS_ROUTE_ENTRIES;i++) for (i = 0; i < MAX_DHCP_CLASSLESS_ROUTE_ENTRIES; i++)
{ {
DHCP_CLASSLESS_ROUTE *r = &t->Entries[i]; DHCP_CLASSLESS_ROUTE *r = &t->Entries[i];
@ -3827,7 +3916,7 @@ void DhcpParseClasslessRouteData(DHCP_CLASSLESS_ROUTE_TABLE *t, void *data, UINT
Copy(&r.SubnetMask, &mask, sizeof(IP)); Copy(&r.SubnetMask, &mask, sizeof(IP));
r.SubnetMaskLen = subnet_mask_len; r.SubnetMaskLen = subnet_mask_len;
for (i = 0;i < MAX_DHCP_CLASSLESS_ROUTE_ENTRIES;i++) for (i = 0; i < MAX_DHCP_CLASSLESS_ROUTE_ENTRIES; i++)
{ {
if (Cmp(&t->Entries[i], &r, sizeof(DHCP_CLASSLESS_ROUTE)) == 0) if (Cmp(&t->Entries[i], &r, sizeof(DHCP_CLASSLESS_ROUTE)) == 0)
{ {
@ -3863,7 +3952,7 @@ DHCP_OPTION *GetDhcpOption(LIST *o, UINT id)
return NULL; return NULL;
} }
for (i = 0;i < LIST_NUM(o);i++) for (i = 0; i < LIST_NUM(o); i++)
{ {
DHCP_OPTION *opt = LIST_DATA(o, i); DHCP_OPTION *opt = LIST_DATA(o, i);
if (opt->Id == id) if (opt->Id == id)
@ -3891,7 +3980,7 @@ DHCP_CLASSLESS_ROUTE *GetBestClasslessRoute(DHCP_CLASSLESS_ROUTE_TABLE *t, IP *i
return NULL; return NULL;
} }
for (i = 0;i < MAX_DHCP_CLASSLESS_ROUTE_ENTRIES;i++) for (i = 0; i < MAX_DHCP_CLASSLESS_ROUTE_ENTRIES; i++)
{ {
DHCP_CLASSLESS_ROUTE *e = &t->Entries[i]; DHCP_CLASSLESS_ROUTE *e = &t->Entries[i];
@ -3921,7 +4010,7 @@ void FreeDhcpOptions(LIST *o)
return; return;
} }
for (i = 0;i < LIST_NUM(o);i++) for (i = 0; i < LIST_NUM(o); i++)
{ {
DHCP_OPTION *opt = LIST_DATA(o, i); DHCP_OPTION *opt = LIST_DATA(o, i);
Free(opt->Data); Free(opt->Data);
@ -4127,7 +4216,7 @@ BUF *DhcpModify(DHCP_MODIFY_OPTION *m, void *data, UINT size)
// Rebuilding the options list // Rebuilding the options list
opt_list2 = NewListFast(NULL); opt_list2 = NewListFast(NULL);
for (i = 0;i < LIST_NUM(opt_list);i++) for (i = 0; i < LIST_NUM(opt_list); i++)
{ {
DHCP_OPTION *o = LIST_DATA(opt_list, i); DHCP_OPTION *o = LIST_DATA(opt_list, i);
DHCP_OPTION *o2 = NULL; DHCP_OPTION *o2 = NULL;

View File

@ -399,12 +399,14 @@ struct ICMPV6_NEIGHBOR_ADVERTISEMENT_HEADER
#define ICMPV6_NEIGHBOR_ADVERTISEMENT_FLAG_SOLICITED 0x40 // Solicited flag #define ICMPV6_NEIGHBOR_ADVERTISEMENT_FLAG_SOLICITED 0x40 // Solicited flag
#define ICMPV6_NEIGHBOR_ADVERTISEMENT_FLAG_OVERWRITE 0x20 // Overwrite flag #define ICMPV6_NEIGHBOR_ADVERTISEMENT_FLAG_OVERWRITE 0x20 // Overwrite flag
#define ICMPV6_OPTION_PREFIXES_MAX_COUNT 10
// ICMPv6 option list // ICMPv6 option list
struct ICMPV6_OPTION_LIST struct ICMPV6_OPTION_LIST
{ {
ICMPV6_OPTION_LINK_LAYER *SourceLinkLayer; // Source link-layer address ICMPV6_OPTION_LINK_LAYER *SourceLinkLayer; // Source link-layer address
ICMPV6_OPTION_LINK_LAYER *TargetLinkLayer; // Target link-layer address ICMPV6_OPTION_LINK_LAYER *TargetLinkLayer; // Target link-layer address
ICMPV6_OPTION_PREFIX *Prefix; // Prefix Information ICMPV6_OPTION_PREFIX *Prefix[ICMPV6_OPTION_PREFIXES_MAX_COUNT]; // Prefix Information - may be multiple in one request
ICMPV6_OPTION_MTU *Mtu; // MTU ICMPV6_OPTION_MTU *Mtu; // MTU
} GCC_PACKED; } GCC_PACKED;
@ -745,6 +747,8 @@ PKT *ParsePacketEx(UCHAR *buf, UINT size, bool no_l3);
PKT *ParsePacketEx2(UCHAR *buf, UINT size, bool no_l3, UINT vlan_type_id); PKT *ParsePacketEx2(UCHAR *buf, UINT size, bool no_l3, UINT vlan_type_id);
PKT *ParsePacketEx3(UCHAR *buf, UINT size, bool no_l3, UINT vlan_type_id, bool bridge_id_as_mac_address); PKT *ParsePacketEx3(UCHAR *buf, UINT size, bool no_l3, UINT vlan_type_id, bool bridge_id_as_mac_address);
PKT *ParsePacketEx4(UCHAR *buf, UINT size, bool no_l3, UINT vlan_type_id, bool bridge_id_as_mac_address, bool no_http, bool correct_checksum); PKT *ParsePacketEx4(UCHAR *buf, UINT size, bool no_l3, UINT vlan_type_id, bool bridge_id_as_mac_address, bool no_http, bool correct_checksum);
PKT *ParsePacketEx5(UCHAR *buf, UINT size, bool no_l3, UINT vlan_type_id, bool bridge_id_as_mac_address, bool no_http, bool correct_checksum, bool no_l3_l4_except_icmpv6);
PKT *ParsePacketUpToICMPv6(UCHAR *buf, UINT size);
void FreePacket(PKT *p); void FreePacket(PKT *p);
void FreePacketWithData(PKT *p); void FreePacketWithData(PKT *p);
void FreePacketIPv4(PKT *p); void FreePacketIPv4(PKT *p);
@ -754,7 +758,7 @@ void FreePacketUDPv4(PKT *p);
void FreePacketTCPv4(PKT *p); void FreePacketTCPv4(PKT *p);
void FreePacketICMPv4(PKT *p); void FreePacketICMPv4(PKT *p);
void FreePacketDHCPv4(PKT *p); void FreePacketDHCPv4(PKT *p);
bool ParsePacketL2Ex(PKT *p, UCHAR *buf, UINT size, bool no_l3); bool ParsePacketL2Ex(PKT *p, UCHAR *buf, UINT size, bool no_l3, bool no_l3_l4_except_icmpv6);
bool ParsePacketARPv4(PKT *p, UCHAR *buf, UINT size); bool ParsePacketARPv4(PKT *p, UCHAR *buf, UINT size);
bool ParsePacketIPv4(PKT *p, UCHAR *buf, UINT size); bool ParsePacketIPv4(PKT *p, UCHAR *buf, UINT size);
bool ParsePacketBPDU(PKT *p, UCHAR *buf, UINT size); bool ParsePacketBPDU(PKT *p, UCHAR *buf, UINT size);
@ -770,7 +774,7 @@ void FreeClonePacket(PKT *p);
void CorrectChecksum(PKT *p); void CorrectChecksum(PKT *p);
bool ParsePacketIPv6(PKT *p, UCHAR *buf, UINT size); bool ParsePacketIPv6(PKT *p, UCHAR *buf, UINT size, bool no_l3_l4_except_icmpv6);
bool ParsePacketIPv6Header(IPV6_HEADER_PACKET_INFO *info, UCHAR *buf, UINT size); bool ParsePacketIPv6Header(IPV6_HEADER_PACKET_INFO *info, UCHAR *buf, UINT size);
bool ParseIPv6ExtHeader(IPV6_HEADER_PACKET_INFO *info, UCHAR next_header, UCHAR *buf, UINT size); bool ParseIPv6ExtHeader(IPV6_HEADER_PACKET_INFO *info, UCHAR next_header, UCHAR *buf, UINT size);
bool ParseICMPv6Options(ICMPV6_OPTION_LIST *o, UCHAR *buf, UINT size); bool ParseICMPv6Options(ICMPV6_OPTION_LIST *o, UCHAR *buf, UINT size);
@ -786,6 +790,7 @@ BUF *BuildIPv6PacketHeader(IPV6_HEADER_PACKET_INFO *info, UINT *bytes_before_pay
UCHAR IPv6GetNextHeaderFromQueue(QUEUE *q); UCHAR IPv6GetNextHeaderFromQueue(QUEUE *q);
void BuildAndAddIPv6PacketOptionHeader(BUF *b, IPV6_OPTION_HEADER *opt, UCHAR next_header, UINT size); void BuildAndAddIPv6PacketOptionHeader(BUF *b, IPV6_OPTION_HEADER *opt, UCHAR next_header, UINT size);
BUF *BuildICMPv6NeighborSoliciation(IPV6_ADDR *src_ip, IPV6_ADDR *target_ip, UCHAR *my_mac_address, UINT id); BUF *BuildICMPv6NeighborSoliciation(IPV6_ADDR *src_ip, IPV6_ADDR *target_ip, UCHAR *my_mac_address, UINT id);
BUF *BuildICMPv6RouterSoliciation(IPV6_ADDR *src_ip, IPV6_ADDR *target_ip, UCHAR *my_mac_address, UINT id);
BUF *BuildICMPv6(IPV6_ADDR *src_ip, IPV6_ADDR *dest_ip, UCHAR hop_limit, UCHAR type, UCHAR code, void *data, UINT size, UINT id); BUF *BuildICMPv6(IPV6_ADDR *src_ip, IPV6_ADDR *dest_ip, UCHAR hop_limit, UCHAR type, UCHAR code, void *data, UINT size, UINT id);
bool VLanRemoveTag(void **packet_data, UINT *packet_size, UINT vlan_id, UINT vlan_tpid); bool VLanRemoveTag(void **packet_data, UINT *packet_size, UINT vlan_id, UINT vlan_tpid);