diff --git a/src/Cedar/IPC.c b/src/Cedar/IPC.c index 0cf2b432..e455c101 100644 --- a/src/Cedar/IPC.c +++ b/src/Cedar/IPC.c @@ -1428,7 +1428,7 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now) } } - FreePacket(pkt); + FreePacketWithData(pkt); } IPCAssociateOnArpTable(ipc, &ip_src, src_mac); @@ -1438,6 +1438,10 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now) // Place in the reception queue InsertQueue(ipc->IPv4ReceivedQueue, NewBlock(data, size, 0)); } + else + { + Free(data); // We need to free the packet if we don't save it + } } else @@ -1470,9 +1474,9 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now) { case ICMPV6_TYPE_ROUTER_ADVERTISEMENT: // We save the router advertisement data for later use - IPCIPv6AddRouterPrefix(ipc, &p->ICMPv6HeaderPacketInfo.OptionList, src_mac, &ip_src); + IPCIPv6AddRouterPrefixes(ipc, &p->ICMPv6HeaderPacketInfo.OptionList, src_mac, &ip_src); IPCIPv6AssociateOnNDTEx(ipc, &ip_src, src_mac, true); - IPCIPv6AssociateOnNDTEx(ipc, &ip_src, &p->ICMPv6HeaderPacketInfo.OptionList.SourceLinkLayer->Address, true); + IPCIPv6AssociateOnNDTEx(ipc, &ip_src, p->ICMPv6HeaderPacketInfo.OptionList.SourceLinkLayer->Address, true); break; case ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT: // We save the neighbor advertisements into NDT @@ -1495,6 +1499,10 @@ void IPCProcessL3EventsEx(IPC *ipc, UINT64 now) { InsertQueue(ipc->IPv6ReceivedQueue, NewBlock(data, size, 0)); } + else + { + Free(data); // We need to free the packet if we don't save it + } FreePacket(p); } @@ -2192,30 +2200,40 @@ bool IPCIPv6CheckExistingLinkLocal(IPC *ipc, UINT64 eui) } // RA -void IPCIPv6AddRouterPrefix(IPC *ipc, ICMPV6_OPTION_LIST *recvPrefix, UCHAR *macAddress, IP *ip) +void IPCIPv6AddRouterPrefixes(IPC *ipc, ICMPV6_OPTION_LIST *recvPrefix, UCHAR *macAddress, IP *ip) { - UINT i; - bool foundPrefix = false; - for (i = 0; i < LIST_NUM(ipc->IPv6RouterAdvs); i++) + UINT i, j; + for (i = 0; i < ICMPV6_OPTION_PREFIXES_MAX_COUNT; i++) { - IPC_IPV6_ROUTER_ADVERTISEMENT *existingRA = LIST_DATA(ipc->IPv6RouterAdvs, i); - if (Cmp(&recvPrefix->Prefix->Prefix, &existingRA->RoutedPrefix.ipv6_addr, sizeof(IPV6_ADDR)) == 0) + if (recvPrefix->Prefix[i] != NULL) + { + bool foundPrefix = false; + for (j = 0; j < LIST_NUM(ipc->IPv6RouterAdvs); j++) + { + IPC_IPV6_ROUTER_ADVERTISEMENT *existingRA = LIST_DATA(ipc->IPv6RouterAdvs, j); + if (Cmp(&recvPrefix->Prefix[i]->Prefix, &existingRA->RoutedPrefix.ipv6_addr, sizeof(IPV6_ADDR)) == 0) + { + foundPrefix = true; + break; + } + } + + if (!foundPrefix) + { + IPC_IPV6_ROUTER_ADVERTISEMENT *newRA = Malloc(sizeof(IPC_IPV6_ROUTER_ADVERTISEMENT)); + IPv6AddrToIP(&newRA->RoutedPrefix, &recvPrefix->Prefix[i]->Prefix); + IntToSubnetMask6(&newRA->RoutedMask, recvPrefix->Prefix[i]->SubnetLength); + CopyIP(&newRA->RouterAddress, ip); + Copy(newRA->RouterMacAddress, macAddress, 6); + Copy(newRA->RouterLinkLayerAddress, recvPrefix->SourceLinkLayer->Address, 6); + Add(ipc->IPv6RouterAdvs, newRA); + } + } + else { - foundPrefix = true; break; } } - - if (!foundPrefix) - { - IPC_IPV6_ROUTER_ADVERTISEMENT *newRA = Malloc(sizeof(IPC_IPV6_ROUTER_ADVERTISEMENT)); - IPv6AddrToIP(&newRA->RoutedPrefix, &recvPrefix->Prefix->Prefix); - IntToSubnetMask6(&newRA->RoutedMask, recvPrefix->Prefix->SubnetLength); - CopyIP(&newRA->RouterAddress, ip); - Copy(newRA->RouterMacAddress, macAddress, 6); - Copy(newRA->RouterLinkLayerAddress, recvPrefix->SourceLinkLayer->Address, 6); - Add(ipc->IPv6RouterAdvs, newRA); - } } bool IPCIPv6CheckUnicastFromRouterPrefix(IPC *ipc, IP *ip, IPC_IPV6_ROUTER_ADVERTISEMENT *matchedRA) @@ -2287,11 +2305,16 @@ UINT64 IPCIPv6GetServerEui(IPC *ipc) packet = BuildICMPv6RouterSoliciation(&senderV6, &destV6, ipc->MacAddress, 0); UINT64 giveup_time = Tick64() + (UINT64)(IPC_IPV6_RA_MAX_RETRIES * IPC_IPV6_RA_INTERVAL); + UINT64 timeout_retry = 0; while (LIST_NUM(ipc->IPv6RouterAdvs) == 0) { - UINT64 timeout_retry = Tick64() + (UINT64)IPC_IPV6_RA_INTERVAL; - IPCIPv6SendWithDestMacAddr(ipc, packet->Buf, packet->Size, destMacAddress); + UINT64 now = Tick64(); + if (now >= timeout_retry) + { + timeout_retry = now + (UINT64)IPC_IPV6_RA_INTERVAL; + IPCIPv6SendWithDestMacAddr(ipc, packet->Buf, packet->Size, destMacAddress); + } AddInterrupt(ipc->Interrupt, timeout_retry); @@ -2304,6 +2327,8 @@ UINT64 IPCIPv6GetServerEui(IPC *ipc) // The processing should populate the received RAs by itself IPCProcessL3Events(ipc); } + + FreeBuf(packet); } // Populating the IPv6 Server EUI for IPV6CP @@ -2379,6 +2404,10 @@ void IPCIPv6Send(IPC *ipc, void *data, UINT size) void IPCIPv6SendWithDestMacAddr(IPC *ipc, void *data, UINT size, UCHAR *dest_mac_addr) { UCHAR tmp[1514]; + + IPV6_HEADER *header = data; + + // Validate arguments if (ipc == NULL || data == NULL || size < 40 || size > 1500 || dest_mac_addr == NULL) { @@ -2397,6 +2426,60 @@ void IPCIPv6SendWithDestMacAddr(IPC *ipc, void *data, UINT size, UCHAR *dest_mac // Data Copy(tmp + 14, data, size); + // Parse the packet for ND ICMPv6 fixup + if (header->NextHeader == IP_PROTO_ICMPV6) + { + PKT *p = ParsePacketUpToICMPv6(tmp, size + 14); + if (p != NULL) + { + ICMPV6_OPTION_LINK_LAYER linkLayer; + BUF *buf; + BUF *optBuf; + BUF *packet; + // We need to rebuild the packet to + switch (p->ICMPv6HeaderPacketInfo.Type) + { + case ICMPV6_TYPE_NEIGHBOR_SOLICIATION: + if (p->ICMPv6HeaderPacketInfo.OptionList.SourceLinkLayer == NULL) + { + p->ICMPv6HeaderPacketInfo.OptionList.SourceLinkLayer = &linkLayer; + } + Copy(p->ICMPv6HeaderPacketInfo.OptionList.SourceLinkLayer->Address, ipc->MacAddress, 6); + case ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT: + if (p->ICMPv6HeaderPacketInfo.OptionList.TargetLinkLayer == NULL) + { + p->ICMPv6HeaderPacketInfo.OptionList.TargetLinkLayer = &linkLayer; + } + Copy(p->ICMPv6HeaderPacketInfo.OptionList.TargetLinkLayer->Address, ipc->MacAddress, 6); + } + switch (p->ICMPv6HeaderPacketInfo.Type) + { + case ICMPV6_TYPE_NEIGHBOR_SOLICIATION: + case ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT: + optBuf = BuildICMPv6Options(&p->ICMPv6HeaderPacketInfo.OptionList); + buf = NewBuf(); + WriteBuf(buf, p->ICMPv6HeaderPacketInfo.Headers.HeaderPointer, + p->ICMPv6HeaderPacketInfo.Type == ICMPV6_TYPE_NEIGHBOR_SOLICIATION ? sizeof(ICMPV6_NEIGHBOR_SOLICIATION_HEADER) : sizeof(ICMPV6_NEIGHBOR_ADVERTISEMENT_HEADER)); + WriteBufBuf(buf, optBuf); + packet = BuildICMPv6(&p->IPv6HeaderPacketInfo.IPv6Header->SrcAddress, + &p->IPv6HeaderPacketInfo.IPv6Header->DestAddress, + p->IPv6HeaderPacketInfo.IPv6Header->HopLimit, + p->ICMPv6HeaderPacketInfo.Type, + p->ICMPv6HeaderPacketInfo.Code, + buf->Buf, + buf->Size, + 0); + Copy(tmp + 14, packet->Buf, packet->Size); + size = packet->Size; + FreeBuf(optBuf); + FreeBuf(buf); + FreeBuf(packet); + break; + } + } + FreePacket(p); + } + // Send IPCSendL2(ipc, tmp, size + 14); } @@ -2484,13 +2567,24 @@ void IPCIPv6SendUnicast(IPC *ipc, void *data, UINT size, IP *next_ip) { // We need to send the Neighbor Solicitation and save the packet for sending later // Generate the MAC address from the multicast address + BUF *neighborSolicit; UCHAR destMacAddress[6]; - BUF *neighborSolicit = BuildICMPv6NeighborSoliciation(&header->SrcAddress, &header->DestAddress, ipc->MacAddress, 0); + IPV6_ADDR solicitAddress; + Zero(&solicitAddress, sizeof(IPV6_ADDR)); + Copy(&solicitAddress.Value[13], &header->DestAddress.Value[13], 3); + solicitAddress.Value[0] = 0xFF; + solicitAddress.Value[1] = 0x02; + solicitAddress.Value[11] = 0x01; + solicitAddress.Value[12] = 0xFF; + + neighborSolicit = BuildICMPv6NeighborSoliciation(&header->SrcAddress, &solicitAddress, ipc->MacAddress, 0); destMacAddress[0] = 0x33; destMacAddress[1] = 0x33; - Copy(&destMacAddress[2], &next_ip->ipv6_addr[12], sizeof(UINT)); + Copy(&destMacAddress[2], &solicitAddress.Value[12], sizeof(UINT)); IPCIPv6SendWithDestMacAddr(ipc, neighborSolicit->Buf, neighborSolicit->Size, destMacAddress); + FreeBuf(neighborSolicit); + CHAR tmp[MAX_SIZE]; UCHAR *copy = Clone(data, size); BLOCK *blk = NewBlock(copy, size, 0); diff --git a/src/Cedar/IPC.h b/src/Cedar/IPC.h index 654ad428..bd68c176 100644 --- a/src/Cedar/IPC.h +++ b/src/Cedar/IPC.h @@ -227,7 +227,7 @@ void IPCIPv6FlushNDT(IPC *ipc); void IPCIPv6FlushNDTEx(IPC *ipc, UINT64 now); bool IPCIPv6CheckExistingLinkLocal(IPC *ipc, UINT64 eui); // RA -void IPCIPv6AddRouterPrefix(IPC *ipc, ICMPV6_OPTION_LIST *recvPrefix, UCHAR *macAddress, IP *ip); +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 diff --git a/src/Cedar/Logging.c b/src/Cedar/Logging.c index 9b89f5f4..ff79ef48 100644 --- a/src/Cedar/Logging.c +++ b/src/Cedar/Logging.c @@ -175,7 +175,7 @@ void FreeEraseFileList(LIST *o) return; } - for (i = 0;i < LIST_NUM(o);i++) + for (i = 0; i < LIST_NUM(o); i++) { ERASE_FILE *f = LIST_DATA(o, i); Free(f->FullPath); @@ -200,7 +200,7 @@ void EnumEraseFile(LIST *o, char *dirname) // Enumeration dir = EnumDir(dirname); - for (i = 0;i < dir->NumFiles;i++) + for (i = 0; i < dir->NumFiles; i++) { DIRENT *e = dir->File[i]; Format(tmp, sizeof(tmp), "%s/%s", dirname, e->FileName); @@ -245,7 +245,7 @@ LIST *GenerateEraseFileList(ERASER *e) o = NewListFast(CompareEraseFile); // 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]; Format(dirname, sizeof(dirname), "%s/%s", e->DirName, delete_targets[i]); @@ -285,7 +285,7 @@ void EraserMain(ERASER *e) o = GenerateEraseFileList(e); // 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); @@ -626,7 +626,7 @@ void EtherIPLog(ETHERIP_SERVER *s, char *name, ...) IPToStr(client_ip, sizeof(client_ip), &s->ClientIP); UniFormat(prefix, sizeof(prefix), _UU("LE_PREFIX"), s->Id, - server_ip, s->ServerPort, client_ip, s->ClientPort); + server_ip, s->ServerPort, client_ip, s->ClientPort); va_start(args, name); UniFormatArgs(buf2, sizeof(buf2), _UU(name), args); @@ -671,17 +671,17 @@ void IPsecLog(IKE_SERVER *ike, IKE_CLIENT *c, IKE_SA *ike_sa, IPSECSA *ipsec_sa, if (ipsec_sa != NULL) { UniFormat(prefix, sizeof(prefix), _UU("LI_PREFIX_IPSEC"), - ipsec_sa->Id, c->Id, client_ip, c->ClientPort, server_ip, c->ServerPort); + ipsec_sa->Id, c->Id, client_ip, c->ClientPort, server_ip, c->ServerPort); } else if (ike_sa != NULL) { UniFormat(prefix, sizeof(prefix), _UU("LI_PREFIX_IKE"), - ike_sa->Id, c->Id, client_ip, c->ClientPort, server_ip, c->ServerPort); + ike_sa->Id, c->Id, client_ip, c->ClientPort, server_ip, c->ServerPort); } else { UniFormat(prefix, sizeof(prefix), _UU("LI_PREFIX_CLIENT"), - c->Id, client_ip, c->ClientPort, server_ip, c->ServerPort); + c->Id, client_ip, c->ClientPort, server_ip, c->ServerPort); } } @@ -755,7 +755,7 @@ void WriteHubLog(HUB *h, wchar_t *str) } if (syslog_status == SYSLOG_SERVER_AND_HUB_SECURITY_LOG - || syslog_status == SYSLOG_SERVER_AND_HUB_ALL_LOG) + || syslog_status == SYSLOG_SERVER_AND_HUB_ALL_LOG) { SiWriteSysLog(s, "SECURITY_LOG", h->Name, str); } @@ -833,7 +833,7 @@ bool PacketLog(HUB *hub, SESSION *src_session, SESSION *dest_session, PKT *packe } if (memcmp(hub->HubMacAddr, packet->MacAddressSrc, 6) == 0 || - memcmp(hub->HubMacAddr, packet->MacAddressDest, 6) == 0) + memcmp(hub->HubMacAddr, packet->MacAddressDest, 6) == 0) { return true; } @@ -1027,8 +1027,8 @@ UINT CalcPacketLoggingLevelEx(HUB_LOG *g, PKT *packet) ret = MAX(ret, g->PacketLogConfig[PACKET_LOG_TCP]); if (packet->L4.TCPHeader->Flag & TCP_SYN || - packet->L4.TCPHeader->Flag & TCP_RST || - packet->L4.TCPHeader->Flag & TCP_FIN) + packet->L4.TCPHeader->Flag & TCP_RST || + packet->L4.TCPHeader->Flag & TCP_FIN) { // TCP SYN LOG ret = MAX(ret, g->PacketLogConfig[PACKET_LOG_TCP_CONN]); @@ -1057,10 +1057,10 @@ UINT CalcPacketLoggingLevelEx(HUB_LOG *g, PKT *packet) ret = MAX(ret, g->PacketLogConfig[PACKET_LOG_TCP_CONN]); break; - case L7_DNS: - // DNS request - ret = MAX(ret, g->PacketLogConfig[PACKET_LOG_TCP_CONN]); - break; + case L7_DNS: + // DNS request + ret = MAX(ret, g->PacketLogConfig[PACKET_LOG_TCP_CONN]); + break; } break; @@ -1084,8 +1084,8 @@ UINT CalcPacketLoggingLevelEx(HUB_LOG *g, PKT *packet) ret = MAX(ret, g->PacketLogConfig[PACKET_LOG_TCP]); if (packet->L4.TCPHeader->Flag & TCP_SYN || - packet->L4.TCPHeader->Flag & TCP_RST || - packet->L4.TCPHeader->Flag & TCP_FIN) + packet->L4.TCPHeader->Flag & TCP_RST || + packet->L4.TCPHeader->Flag & TCP_FIN) { // TCP SYN LOG ret = MAX(ret, g->PacketLogConfig[PACKET_LOG_TCP_CONN]); @@ -1109,10 +1109,10 @@ UINT CalcPacketLoggingLevelEx(HUB_LOG *g, PKT *packet) ret = MAX(ret, g->PacketLogConfig[PACKET_LOG_TCP_CONN]); break; - case L7_DNS: - // DNS request - ret = MAX(ret, g->PacketLogConfig[PACKET_LOG_TCP_CONN]); - break; + case L7_DNS: + // DNS request + ret = MAX(ret, g->PacketLogConfig[PACKET_LOG_TCP_CONN]); + break; } break; @@ -1167,12 +1167,12 @@ char *BuildHttpLogStr(HTTPLOG *h) if (h->Port == 80) { Format(url, sizeof(url), "http://%s%s", - h->Hostname, h->Path); + h->Hostname, h->Path); } else { Format(url, sizeof(url), "http://%s:%u%s", - h->Hostname, h->Port, h->Path); + h->Hostname, h->Port, h->Path); } } else @@ -1180,12 +1180,12 @@ char *BuildHttpLogStr(HTTPLOG *h) if (h->Port == 443) { Format(url, sizeof(url), "https://%s/", - h->Hostname); + h->Hostname); } else { Format(url, sizeof(url), "https://%s:%u/", - h->Hostname, h->Port); + h->Hostname, h->Port); } } } @@ -1251,7 +1251,7 @@ void MakeSafeLogStr(char *str) } if (str[0] == 'h' && str[1] == 't' && str[2] == 't' && str[3] == 'p' && - ((str[4] == 's' && str[5] == ':') || (str[4] == ':'))) + ((str[4] == 's' && str[5] == ':') || (str[4] == ':'))) { is_http = true; } @@ -1259,7 +1259,7 @@ void MakeSafeLogStr(char *str) EnPrintableAsciiStr(str, '?'); len = StrLen(str); - for (i = 0;i < len;i++) + for (i = 0; i < len; i++) { if (str[i] == ',') { @@ -1284,6 +1284,7 @@ char *PacketLogParseProc(RECORD *rec) TOKEN_LIST *t; char tmp[MAX_SIZE]; bool tcp_conn; + UINT i; // Validate arguments if (rec == NULL) { @@ -1340,9 +1341,9 @@ char *PacketLogParseProc(RECORD *rec) // ARP request packet t->Token[7] = CopyStr("Request"); if (Endian16(p->L3.ARPv4Header->HardwareType) == ARP_HARDWARE_TYPE_ETHERNET && - p->L3.ARPv4Header->HardwareSize == 6 && - Endian16(p->L3.ARPv4Header->ProtocolType) == MAC_PROTO_IPV4 && - p->L3.ARPv4Header->ProtocolSize == 4) + p->L3.ARPv4Header->HardwareSize == 6 && + Endian16(p->L3.ARPv4Header->ProtocolType) == MAC_PROTO_IPV4 && + p->L3.ARPv4Header->ProtocolSize == 4) { char src_mac[16]; char src_ip[16]; @@ -1355,7 +1356,7 @@ char *PacketLogParseProc(RECORD *rec) IPToStr(src_ip, sizeof(src_ip), &src_ip_st); IPToStr(dst_ip, sizeof(dst_ip), &dst_ip_st); snprintf(tmp, sizeof(tmp), "Who has %s? Please Tell %s(%s)", - dst_ip, src_mac, src_ip); + dst_ip, src_mac, src_ip); t->Token[14] = CopyStr(tmp); } break; @@ -1364,9 +1365,9 @@ char *PacketLogParseProc(RECORD *rec) // ARP response packet t->Token[7] = CopyStr("Response"); if (Endian16(p->L3.ARPv4Header->HardwareType) == ARP_HARDWARE_TYPE_ETHERNET && - p->L3.ARPv4Header->HardwareSize == 6 && - Endian16(p->L3.ARPv4Header->ProtocolType) == MAC_PROTO_IPV4 && - p->L3.ARPv4Header->ProtocolSize == 4) + p->L3.ARPv4Header->HardwareSize == 6 && + Endian16(p->L3.ARPv4Header->ProtocolType) == MAC_PROTO_IPV4 && + p->L3.ARPv4Header->ProtocolSize == 4) { char src_mac[16]; char src_ip[16]; @@ -1379,7 +1380,7 @@ char *PacketLogParseProc(RECORD *rec) IPToStr(src_ip, sizeof(src_ip), &src_ip_st); IPToStr(dst_ip, sizeof(dst_ip), &dst_ip_st); snprintf(tmp, sizeof(tmp), "%s has %s", - src_mac, src_ip); + src_mac, src_ip); t->Token[14] = CopyStr(tmp); } break; @@ -1483,9 +1484,9 @@ char *PacketLogParseProc(RECORD *rec) IPToStr32(ip4, sizeof(ip4), p->L7.DHCPv4Header->RelayIP); snprintf(tmp, sizeof(tmp), - "TransactionId=%u ClientIP=%s YourIP=%s ServerIP=%s RelayIP=%s", - Endian32(p->L7.DHCPv4Header->TransactionId), - ip1, ip2, ip3, ip4); + "TransactionId=%u ClientIP=%s YourIP=%s ServerIP=%s RelayIP=%s", + Endian32(p->L7.DHCPv4Header->TransactionId), + ip1, ip2, ip3, ip4); t->Token[14] = CopyStr(tmp); } @@ -1514,26 +1515,26 @@ char *PacketLogParseProc(RECORD *rec) { Format(tmp, sizeof(tmp), "InitiatorCookie=%I64u ResponderCookie=%I64u " - "Version=0x%x ExchangeType=0x%x Flag=0x%x MessageId=%u MessageSize=%u", - Endian64(p->L7.IkeHeader->InitiatorCookie), - Endian64(p->L7.IkeHeader->ResponderCookie), - p->L7.IkeHeader->Version, - p->L7.IkeHeader->ExchangeType, - p->L7.IkeHeader->Flag, - Endian32(p->L7.IkeHeader->MessageId), - Endian32(p->L7.IkeHeader->MessageSize)); + "Version=0x%x ExchangeType=0x%x Flag=0x%x MessageId=%u MessageSize=%u", + Endian64(p->L7.IkeHeader->InitiatorCookie), + Endian64(p->L7.IkeHeader->ResponderCookie), + p->L7.IkeHeader->Version, + p->L7.IkeHeader->ExchangeType, + p->L7.IkeHeader->Flag, + Endian32(p->L7.IkeHeader->MessageId), + Endian32(p->L7.IkeHeader->MessageSize)); t->Token[14] = CopyStr(tmp); } } break; - - case L7_DNS: - // DNS query - t->Token[6] = CopyStr("DNSv4"); - t->Token[7] = CopyStr("DNS_Query"); - t->Token[14] = CopyStr(p->DnsQueryHost); - break; + + case L7_DNS: + // DNS query + t->Token[6] = CopyStr("DNSv4"); + t->Token[7] = CopyStr("DNS_Query"); + t->Token[14] = CopyStr(p->DnsQueryHost); + break; default: // Unknown Packet @@ -1570,145 +1571,152 @@ char *PacketLogParseProc(RECORD *rec) switch (p->TypeL4) { case L4_ICMPV6: + { + char info[MAX_SIZE]; + ICMPV6_HEADER_INFO *icmp = &p->ICMPv6HeaderPacketInfo; + ICMPV6_OPTION_LIST *ol = &icmp->OptionList; + + Zero(info, sizeof(info)); + + // ICMPv6 packet + t->Token[6] = CopyStr("ICMPv6"); + + switch (icmp->Type) { - char info[MAX_SIZE]; - ICMPV6_HEADER_INFO *icmp = &p->ICMPv6HeaderPacketInfo; - ICMPV6_OPTION_LIST *ol = &icmp->OptionList; + case ICMPV6_TYPE_ECHO_REQUEST: + // Echo request + t->Token[7] = CopyStr("Echo Request"); + snprintf(tmp, sizeof(tmp), "EchoDataSize=%u ", icmp->EchoDataSize); + StrCat(info, sizeof(info), tmp); + break; - Zero(info, sizeof(info)); + case ICMPV6_TYPE_ECHO_RESPONSE: + // Echo response + t->Token[7] = CopyStr("Echo Reply"); + snprintf(tmp, sizeof(tmp), "EchoDataSize=%u ", icmp->EchoDataSize); + StrCat(info, sizeof(info), tmp); + break; - // ICMPv6 packet - t->Token[6] = CopyStr("ICMPv6"); + case ICMPV6_TYPE_ROUTER_SOLICIATION: + { + ICMPV6_ROUTER_SOLICIATION_HEADER *h = icmp->Headers.RouterSoliciationHeader; + // Router Solicitation + t->Token[7] = CopyStr("Router Soliciation"); - switch (icmp->Type) + if (h != NULL) { - case ICMPV6_TYPE_ECHO_REQUEST: - // Echo request - t->Token[7] = CopyStr("Echo Request"); - snprintf(tmp, sizeof(tmp), "EchoDataSize=%u ", icmp->EchoDataSize); - StrCat(info, sizeof(info), tmp); - break; - - case ICMPV6_TYPE_ECHO_RESPONSE: - // Echo response - t->Token[7] = CopyStr("Echo Reply"); - snprintf(tmp, sizeof(tmp), "EchoDataSize=%u ", icmp->EchoDataSize); - StrCat(info, sizeof(info), tmp); - break; - - case ICMPV6_TYPE_ROUTER_SOLICIATION: - { - ICMPV6_ROUTER_SOLICIATION_HEADER *h = icmp->Headers.RouterSoliciationHeader; - // Router Solicitation - t->Token[7] = CopyStr("Router Soliciation"); - - if (h != NULL) - { - // No additional information - } - } - break; - - case ICMPV6_TYPE_ROUTER_ADVERTISEMENT: - { - ICMPV6_ROUTER_ADVERTISEMENT_HEADER *h = icmp->Headers.RouterAdvertisementHeader; - // Router Advertisement - t->Token[7] = CopyStr("Router Advertisement"); - - if (h != NULL) - { - snprintf(tmp, sizeof(tmp), "CurHopLimit=%u " - "Flags=0x%02X Lifetime=%u ", - h->CurHopLimit, h->Flags, Endian16(h->Lifetime)); - StrCat(info, sizeof(info), tmp); - } - } - break; - - case ICMPV6_TYPE_NEIGHBOR_SOLICIATION: - { - ICMPV6_NEIGHBOR_SOLICIATION_HEADER *h = icmp->Headers.NeighborSoliciationHeader; - // Neighbor Solicitation - t->Token[7] = CopyStr("Neighbor Soliciation"); - - if (h != NULL) - { - char tmp2[MAX_SIZE]; - - IP6AddrToStr(tmp2, sizeof(tmp2), &h->TargetAddress); - - snprintf(tmp, sizeof(tmp), "TargetAddress=%s ", - tmp2); - StrCat(info, sizeof(info), tmp); - } - } - break; - - case ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT: - { - ICMPV6_NEIGHBOR_ADVERTISEMENT_HEADER *h = icmp->Headers.NeighborAdvertisementHeader; - // Neighbor Advertisement - t->Token[7] = CopyStr("Neighbor Advertisement"); - - if (h != NULL) - { - char tmp2[MAX_SIZE]; - - IP6AddrToStr(tmp2, sizeof(tmp2), &h->TargetAddress); - - snprintf(tmp, sizeof(tmp), "TargetAddress=%s Flags=0x%02X ", - tmp2, h->Flags); - StrCat(info, sizeof(info), tmp); - } - } - break; - - default: - { - snprintf(tmp, sizeof(tmp), "Type=%u", icmp->Type); - t->Token[7] = CopyStr(tmp); - } - break; - } - - // Option data - if (ol->SourceLinkLayer != NULL) - { - char tmp2[MAX_SIZE]; - BinToStr(tmp2, sizeof(tmp2), ol->SourceLinkLayer->Address, 6); - snprintf(tmp, sizeof(tmp), "SourceLinkLayer=%s ", tmp2); - StrCat(info, sizeof(info), tmp); - } - if (ol->TargetLinkLayer != NULL) - { - char tmp2[MAX_SIZE]; - BinToStr(tmp2, sizeof(tmp2), ol->TargetLinkLayer->Address, 6); - snprintf(tmp, sizeof(tmp), "TargetLinkLayer=%s ", tmp2); - StrCat(info, sizeof(info), tmp); - } - if (ol->Prefix != NULL) - { - char tmp2[MAX_SIZE]; - IP6AddrToStr(tmp2, sizeof(tmp2), &ol->Prefix->Prefix); - snprintf(tmp, sizeof(tmp), "Prefix=%s/%u PrefixFlag=0x%02X ", tmp2, - ol->Prefix->SubnetLength, ol->Prefix->Flags); - StrCat(info, sizeof(info), tmp); - } - if (ol->Mtu != NULL) - { - snprintf(tmp, sizeof(tmp), "Mtu=%u ", Endian32(ol->Mtu->Mtu)); - StrCat(info, sizeof(info), tmp); - } - - Trim(info); - - if (IsEmptyStr(info) == false) - { - t->Token[14] = CopyStr(info); + // No additional information } } break; + case ICMPV6_TYPE_ROUTER_ADVERTISEMENT: + { + ICMPV6_ROUTER_ADVERTISEMENT_HEADER *h = icmp->Headers.RouterAdvertisementHeader; + // Router Advertisement + t->Token[7] = CopyStr("Router Advertisement"); + + if (h != NULL) + { + snprintf(tmp, sizeof(tmp), "CurHopLimit=%u " + "Flags=0x%02X Lifetime=%u ", + h->CurHopLimit, h->Flags, Endian16(h->Lifetime)); + StrCat(info, sizeof(info), tmp); + } + } + break; + + case ICMPV6_TYPE_NEIGHBOR_SOLICIATION: + { + ICMPV6_NEIGHBOR_SOLICIATION_HEADER *h = icmp->Headers.NeighborSoliciationHeader; + // Neighbor Solicitation + t->Token[7] = CopyStr("Neighbor Soliciation"); + + if (h != NULL) + { + char tmp2[MAX_SIZE]; + + IP6AddrToStr(tmp2, sizeof(tmp2), &h->TargetAddress); + + snprintf(tmp, sizeof(tmp), "TargetAddress=%s ", + tmp2); + StrCat(info, sizeof(info), tmp); + } + } + break; + + case ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT: + { + ICMPV6_NEIGHBOR_ADVERTISEMENT_HEADER *h = icmp->Headers.NeighborAdvertisementHeader; + // Neighbor Advertisement + t->Token[7] = CopyStr("Neighbor Advertisement"); + + if (h != NULL) + { + char tmp2[MAX_SIZE]; + + IP6AddrToStr(tmp2, sizeof(tmp2), &h->TargetAddress); + + snprintf(tmp, sizeof(tmp), "TargetAddress=%s Flags=0x%02X ", + tmp2, h->Flags); + StrCat(info, sizeof(info), tmp); + } + } + break; + + default: + { + snprintf(tmp, sizeof(tmp), "Type=%u", icmp->Type); + t->Token[7] = CopyStr(tmp); + } + break; + } + + // Option data + if (ol->SourceLinkLayer != NULL) + { + char tmp2[MAX_SIZE]; + BinToStr(tmp2, sizeof(tmp2), ol->SourceLinkLayer->Address, 6); + snprintf(tmp, sizeof(tmp), "SourceLinkLayer=%s ", tmp2); + StrCat(info, sizeof(info), tmp); + } + if (ol->TargetLinkLayer != NULL) + { + char tmp2[MAX_SIZE]; + BinToStr(tmp2, sizeof(tmp2), ol->TargetLinkLayer->Address, 6); + snprintf(tmp, sizeof(tmp), "TargetLinkLayer=%s ", tmp2); + StrCat(info, sizeof(info), tmp); + } + for (i = 0; i < ICMPV6_OPTION_PREFIXES_MAX_COUNT; i++) + { + if (ol->Prefix[i] != NULL) + { + char tmp2[MAX_SIZE]; + IP6AddrToStr(tmp2, sizeof(tmp2), &ol->Prefix[i]->Prefix); + snprintf(tmp, sizeof(tmp), "Prefix=%s/%u PrefixFlag=0x%02X ", tmp2, + ol->Prefix[i]->SubnetLength, ol->Prefix[i]->Flags); + StrCat(info, sizeof(info), tmp); + } + else + { + break; + } + } + if (ol->Mtu != NULL) + { + snprintf(tmp, sizeof(tmp), "Mtu=%u ", Endian32(ol->Mtu->Mtu)); + StrCat(info, sizeof(info), tmp); + } + + Trim(info); + + if (IsEmptyStr(info) == false) + { + t->Token[14] = CopyStr(info); + } + } + break; + case L4_TCP: // TCP packet tcp_conn = false; @@ -1786,26 +1794,26 @@ char *PacketLogParseProc(RECORD *rec) { Format(tmp, sizeof(tmp), "InitiatorCookie=%I64u ResponderCookie=%I64u " - "Version=0x%x ExchangeType=0x%x Flag=0x%x MessageId=%u MessageSize=%u", - Endian64(p->L7.IkeHeader->InitiatorCookie), - Endian64(p->L7.IkeHeader->ResponderCookie), - p->L7.IkeHeader->Version, - p->L7.IkeHeader->ExchangeType, - p->L7.IkeHeader->Flag, - Endian32(p->L7.IkeHeader->MessageId), - Endian32(p->L7.IkeHeader->MessageSize)); + "Version=0x%x ExchangeType=0x%x Flag=0x%x MessageId=%u MessageSize=%u", + Endian64(p->L7.IkeHeader->InitiatorCookie), + Endian64(p->L7.IkeHeader->ResponderCookie), + p->L7.IkeHeader->Version, + p->L7.IkeHeader->ExchangeType, + p->L7.IkeHeader->Flag, + Endian32(p->L7.IkeHeader->MessageId), + Endian32(p->L7.IkeHeader->MessageSize)); t->Token[14] = CopyStr(tmp); } } break; - - case L7_DNS: - // DNS query - t->Token[6] = CopyStr("DNSv6"); - t->Token[7] = CopyStr("DNS_Query"); - t->Token[14] = CopyStr(p->DnsQueryHost); - break; + + case L7_DNS: + // DNS query + t->Token[6] = CopyStr("DNSv6"); + t->Token[7] = CopyStr("DNS_Query"); + t->Token[14] = CopyStr(p->DnsQueryHost); + break; default: t->Token[6] = CopyStr("UDPv6"); @@ -1975,7 +1983,7 @@ char *GenCsvLine(TOKEN_LIST *t) } b = NewBuf(); - for (i = 0;i < t->NumTokens;i++) + for (i = 0; i < t->NumTokens; i++) { if (t->Token[i] != NULL) { @@ -2019,7 +2027,7 @@ void ReplaceForCsv(char *str) len = StrLen(str); - for (i = 0;i < len;i++) + for (i = 0; i < len; i++) { // Convert the comma to underscore if (str[i] == ',') @@ -2154,7 +2162,7 @@ void MakeLogFileNameStringFromTick(LOG *g, char *str, UINT size, UINT64 tick, UI if (g->CacheFlag) { if (g->LastTick == tick && - g->LastSwitchType == switch_type) + g->LastSwitchType == switch_type) { StrCpy(str, size, g->LastStr); return; @@ -2168,12 +2176,12 @@ void MakeLogFileNameStringFromTick(LOG *g, char *str, UINT size, UINT64 tick, UI { case LOG_SWITCH_SECOND: // Secondly basis snprintf(str, size, "_%04u%02u%02u_%02u%02u%02u", - st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); + st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); break; case LOG_SWITCH_MINUTE: // Minutely basis snprintf(str, size, "_%04u%02u%02u_%02u%02u", - st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute); + st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute); break; case LOG_SWITCH_HOUR: // Hourly basis @@ -2271,9 +2279,9 @@ bool MakeLogFileName(LOG *g, char *name, UINT size, char *dir, char *prefix, UIN } snprintf(name, size, "%s%s%s%s%s.log", dir, - StrLen(dir) == 0 ? "" : "/", - prefix, tmp, tmp2 - ); + StrLen(dir) == 0 ? "" : "/", + prefix, tmp, tmp2 + ); return ret; } @@ -2533,7 +2541,7 @@ static bool LogThreadWriteGeneral(LOG *log_object, BUF *buffer, IO **io, bool *l LockLog(log_object); { *log_date_changed = MakeLogFileName(log_object, file_name, sizeof(file_name), - log_object->DirName, log_object->Prefix, rec->Tick, log_object->SwitchType, log_object->CurrentLogNumber, current_logfile_datename); + log_object->DirName, log_object->Prefix, rec->Tick, log_object->SwitchType, log_object->CurrentLogNumber, current_logfile_datename); if (*log_date_changed) { @@ -2541,12 +2549,12 @@ static bool LogThreadWriteGeneral(LOG *log_object, BUF *buffer, IO **io, bool *l log_object->CurrentLogNumber = 0; MakeLogFileName(log_object, file_name, sizeof(file_name), - log_object->DirName, log_object->Prefix, rec->Tick, log_object->SwitchType, 0, current_logfile_datename); - for (i = 0;;i++) + log_object->DirName, log_object->Prefix, rec->Tick, log_object->SwitchType, 0, current_logfile_datename); + for (i = 0;; i++) { char tmp[MAX_SIZE]; MakeLogFileName(log_object, tmp, sizeof(tmp), - log_object->DirName, log_object->Prefix, rec->Tick, log_object->SwitchType, i, current_logfile_datename); + log_object->DirName, log_object->Prefix, rec->Tick, log_object->SwitchType, i, current_logfile_datename); if (IsFileExists(tmp) == false) { @@ -2564,7 +2572,7 @@ static bool LogThreadWriteGeneral(LOG *log_object, BUF *buffer, IO **io, bool *l if (StrCmp(current_file_name, file_name) != 0) { // If a log file is currently opened and writing to another log - // file is needed for this time, write the contents of the + // file is needed for this time, write the contents of the //buffer and close the log file. Write the contents of the buffer if (*io != NULL) { diff --git a/src/Cedar/Proto_PPP.c b/src/Cedar/Proto_PPP.c index c7af4310..5af5f0b1 100644 --- a/src/Cedar/Proto_PPP.c +++ b/src/Cedar/Proto_PPP.c @@ -365,7 +365,7 @@ void PPPThread(THREAD *thread, void *param) PPPSendPacketEx(p, pp, true); FreePPPPacketEx(pp, true); - Free(b); + Free(b); // Not FreeBlock because freed in FreePPPPacketEx } } else @@ -396,7 +396,7 @@ void PPPThread(THREAD *thread, void *param) PPPSendPacketEx(p, pp, true); FreePPPPacketEx(pp, true); - Free(b); + Free(b); // Not FreeBlock because freed in FreePPPPacketEx } } else @@ -1961,7 +1961,7 @@ bool PPPProcessIPv6CPRequestPacket(PPP_SESSION *p, PPP_PACKET *pp) { UINT64 newValue = 0; UINT64 value = READ_UINT64(t->Data); - if (!IPCIPv6CheckExistingLinkLocal(p->Ipc, value)) + if (value != 0 && !IPCIPv6CheckExistingLinkLocal(p->Ipc, value)) { t->IsAccepted = true; p->Ipc->IPv6ClientEUI = value; diff --git a/src/Mayaqua/TcpIp.c b/src/Mayaqua/TcpIp.c index 36849716..66ea1188 100644 --- a/src/Mayaqua/TcpIp.c +++ b/src/Mayaqua/TcpIp.c @@ -1140,6 +1140,7 @@ void BuildICMPv6OptionValue(BUF *b, UCHAR type, void *header_pointer, UINT total BUF *BuildICMPv6Options(ICMPV6_OPTION_LIST *o) { BUF *b; + UINT i; // Validate arguments if (o == NULL) { @@ -1156,9 +1157,16 @@ BUF *BuildICMPv6Options(ICMPV6_OPTION_LIST *o) { 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) { @@ -2402,7 +2410,15 @@ bool ParseICMPv6Options(ICMPV6_OPTION_LIST *o, UCHAR *buf, UINT size) // Prefix Information 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 { @@ -2556,6 +2572,7 @@ bool ParseICMPv6(PKT *p, UCHAR *buf, UINT size) // Release of the ICMPv6 options void FreeCloneICMPv6Options(ICMPV6_OPTION_LIST *o) { + UINT i; // Validate arguments if (o == NULL) { @@ -2564,13 +2581,19 @@ void FreeCloneICMPv6Options(ICMPV6_OPTION_LIST *o) Free(o->SourceLinkLayer); 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); } // Clone of the ICMPv6 options void CloneICMPv6Options(ICMPV6_OPTION_LIST *dst, ICMPV6_OPTION_LIST *src) { + UINT i; // Validate arguments if (dst == NULL || src == NULL) { @@ -2581,7 +2604,17 @@ void CloneICMPv6Options(ICMPV6_OPTION_LIST *dst, ICMPV6_OPTION_LIST *src) dst->SourceLinkLayer = Clone(src->SourceLinkLayer, 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)); } diff --git a/src/Mayaqua/TcpIp.h b/src/Mayaqua/TcpIp.h index 85f55c67..83a4db8e 100644 --- a/src/Mayaqua/TcpIp.h +++ b/src/Mayaqua/TcpIp.h @@ -399,12 +399,14 @@ struct ICMPV6_NEIGHBOR_ADVERTISEMENT_HEADER #define ICMPV6_NEIGHBOR_ADVERTISEMENT_FLAG_SOLICITED 0x40 // Solicited flag #define ICMPV6_NEIGHBOR_ADVERTISEMENT_FLAG_OVERWRITE 0x20 // Overwrite flag +#define ICMPV6_OPTION_PREFIXES_MAX_COUNT 10 + // ICMPv6 option list struct ICMPV6_OPTION_LIST { ICMPV6_OPTION_LINK_LAYER *SourceLinkLayer; // Source 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 } GCC_PACKED;