1 // SoftEther UT-VPN SourceCode
\r
3 // Copyright (C) 2004-2010 SoftEther Corporation.
\r
4 // Copyright (C) 2004-2010 University of Tsukuba, Japan.
\r
5 // Copyright (C) 2003-2010 Daiyuu Nobori.
\r
6 // All Rights Reserved.
\r
8 // http://utvpn.tsukuba.ac.jp/
\r
10 // This program is free software; you can redistribute it and/or
\r
11 // modify it under the terms of the GNU General Public License
\r
12 // version 2 as published by the Free Software Foundation.
\r
14 // This program is distributed in the hope that it will be useful,
\r
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
17 // GNU General Public License for more details.
\r
19 // You should have received a copy of the GNU General Public License version 2
\r
20 // along with this program; if not, write to the Free Software
\r
21 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
\r
23 // このファイルは GPL バージョン 2 ライセンスで公開されています。
\r
24 // 誰でもこのファイルの内容を複製、改変したり、改変したバージョンを再配布
\r
25 // することができます。ただし、原著作物を改変した場合は、原著作物の著作権表示
\r
26 // を除去することはできません。改変した著作物を配布する場合は、改変実施者の
\r
27 // 著作権表示を原著作物の著作権表示に付随して記載するようにしてください。
\r
29 // この SoftEther UT-VPN オープンソース・プロジェクトは、日本国の
\r
30 // ソフトイーサ株式会社 (SoftEther Corporation, http://www.softether.co.jp/ )
\r
31 // および筑波大学 (University of Tsukuba, http://www.tsukuba.ac.jp/ ) によって
\r
33 // 本プログラムの配布者は、本プログラムを、業としての利用以外のため、
\r
34 // および、試験または研究のために利用が行われることを想定して配布
\r
36 // SoftEther UT-VPN プロジェクトの Web サイトは http://utvpn.tsukuba.ac.jp/ に
\r
38 // 本ソフトウェアの不具合の修正、機能改良、セキュリティホールの修復などのコード
\r
39 // の改変を行った場合で、その成果物を SoftEther UT-VPN プロジェクトに提出して
\r
40 // いただける場合は、 http://utvpn.tsukuba.ac.jp/ までソースコードを送付して
\r
41 // ください。SoftEther UT-VPN プロジェクトの本体リリースまたはブランチリリース
\r
44 // GPL に基づいて原著作物が提供される本ソフトウェアの改良版を配布、販売する
\r
45 // 場合は、そのソースコードを GPL に基づいて誰にでも開示する義務が生じます。
\r
47 // 本ソフトウェアに関連する著作権、特許権、商標権はソフトイーサ株式会社
\r
48 // (SoftEther Corporation) およびその他の著作権保持者が保有しています。
\r
49 // ソフトイーサ株式会社等はこれらの権利を放棄していません。本ソフトウェアの
\r
50 // 二次著作物を配布、販売する場合は、これらの権利を侵害しないようにご注意
\r
53 // お願い: どのような通信ソフトウェアにも通常は必ず未発見の
\r
54 // セキュリティホールが潜んでいます。本ソースコードをご覧いただいた結果、
\r
55 // UT-VPN にセキュリティホールを発見された場合は、当該セキュリティホールの
\r
56 // 情報を不特定多数に開示される前に、必ず、ソフトイーサ株式会社
\r
57 // および脆弱性情報の届出を受け付ける公的機関まで通報いただき、
\r
58 // 公益保護にご協力いただきますようお願い申し上げます。
\r
60 // ソフトイーサ株式会社は、当該セキュリティホールについて迅速に対処を
\r
61 // 行い、UT-VPN および UT-VPN に関連するソフトウェアのユーザー・顧客
\r
64 // ソフトイーサへの届出先: http://www.softether.co.jp/jp/contact/
\r
65 // 日本国内の脆弱性情報届出受付公的機関:
\r
67 // http://www.ipa.go.jp/security/vuln/report/
\r
69 // 上記各事項について不明な点は、ソフトイーサ株式会社までご連絡ください。
\r
70 // 連絡先: http://www.softether.co.jp/jp/contact/
\r
72 // -----------------------------------------------
\r
75 // 新規リリース by SoftEther
\r
76 // -----------------------------------------------
\r
79 // TCP/IP プロトコル パケットアナライザ
\r
81 #include "CedarPch.h"
\r
83 // パケットに VLAN タグを埋め込む
\r
84 void VLanInsertTag(void **packet_data, UINT *packet_size, UINT vlan_id)
\r
90 USHORT vlan_ushort = Endian16(((USHORT)vlan_id) & 0xFFF);
\r
92 if (packet_data == NULL || *packet_data == NULL || packet_size == NULL ||
\r
93 *packet_size < 14 || vlan_id == 0)
\r
98 src_size = *packet_size;
\r
99 src_data = (UCHAR *)(*packet_data);
\r
101 dest_size = src_size + 4;
\r
102 dest_data = Malloc(dest_size);
\r
104 dest_data[12] = 0x81;
\r
105 dest_data[13] = 0x00;
\r
106 Copy(&dest_data[14], &vlan_ushort, sizeof(USHORT));
\r
108 Copy(&dest_data[0], &src_data[0], 12);
\r
109 Copy(&dest_data[16], &src_data[12], src_size - 12);
\r
111 *packet_size = dest_size;
\r
112 *packet_data = dest_data;
\r
117 // パケットから VLAN タグを取り除く
\r
118 bool VLanRemoveTag(void **packet_data, UINT *packet_size, UINT vlan_id)
\r
120 bool has_vlan_tag = false;
\r
124 if (packet_data == NULL || *packet_data == NULL || packet_size == NULL ||
\r
130 src_data = (UCHAR *)(*packet_data);
\r
131 src_size = *packet_size;
\r
133 if (src_data[12] == 0x81 && src_data[13] == 0x00)
\r
135 if (src_size >= 18)
\r
137 USHORT vlan_ushort;
\r
139 vlan_ushort = Endian16(*((USHORT *)&src_data[14]));
\r
140 vlan_ushort = vlan_ushort & 0xFFF;
\r
142 if (vlan_id == 0 || (vlan_ushort == vlan_id))
\r
144 UINT dest_size = src_size - 4;
\r
147 for (i = 12;i < dest_size;i++)
\r
149 src_data[i] = src_data[i + 4];
\r
152 *packet_size = dest_size;
\r
163 BUF *BuildICMPv6(IPV6_ADDR *src_ip, IPV6_ADDR *dest_ip, UCHAR hop_limit, UCHAR type, UCHAR code, void *data, UINT size, UINT id)
\r
169 if (src_ip == NULL || dest_ip == NULL || data == NULL)
\r
175 icmp = ZeroMalloc(sizeof(ICMP_HEADER) + size);
\r
176 data_buf = ((UCHAR *)icmp) + sizeof(ICMP_HEADER);
\r
177 Copy(data_buf, data, size);
\r
181 icmp->Checksum = CalcChecksumForIPv6(src_ip, dest_ip, IP_PROTO_ICMPV6, icmp,
\r
182 sizeof(ICMP_HEADER) + size);
\r
184 ret = BuildIPv6(dest_ip, src_ip, id, IP_PROTO_ICMPV6, hop_limit, icmp,
\r
185 sizeof(ICMP_HEADER) + size);
\r
192 // ICMPv6 近隣要請パケットのビルド
\r
193 BUF *BuildICMPv6NeighborSoliciation(IPV6_ADDR *src_ip, IPV6_ADDR *target_ip, UCHAR *my_mac_address, UINT id)
\r
195 ICMPV6_OPTION_LIST opt;
\r
196 ICMPV6_OPTION_LINK_LAYER link;
\r
197 ICMPV6_NEIGHBOR_SOLICIATION_HEADER header;
\r
202 if (src_ip == NULL || target_ip == NULL || my_mac_address == NULL)
\r
207 Zero(&link, sizeof(link));
\r
208 Copy(link.Address, my_mac_address, 6);
\r
210 Zero(&opt, sizeof(opt));
\r
211 opt.SourceLinkLayer = &link;
\r
213 b = BuildICMPv6Options(&opt);
\r
215 Zero(&header, sizeof(header));
\r
216 Copy(&header.TargetAddress, target_ip, sizeof(IPV6_ADDR));
\r
220 WriteBuf(b2, &header, sizeof(header));
\r
221 WriteBufBuf(b2, b);
\r
223 ret = BuildICMPv6(src_ip, target_ip, 255,
\r
224 ICMPV6_TYPE_NEIGHBOR_SOLICIATION, 0, b2->Buf, b2->Size, id);
\r
233 UCHAR IPv6GetNextHeaderFromQueue(QUEUE *q)
\r
240 return IPV6_HEADER_NONE;
\r
243 p = (UINT *)GetNext(q);
\r
250 // IPv6 拡張オプションヘッダ (可変長) の追加
\r
251 void BuildAndAddIPv6PacketOptionHeader(BUF *b, IPV6_OPTION_HEADER *opt, UCHAR next_header, UINT size)
\r
253 IPV6_OPTION_HEADER *h;
\r
256 if (b == NULL || opt == NULL)
\r
262 if ((total_size % 8) != 0)
\r
264 total_size = ((total_size / 8) + 1) * 8;
\r
267 h = ZeroMalloc(total_size);
\r
268 Copy(h, opt, size);
\r
269 h->Size = (total_size / 8) - 1;
\r
270 h->NextHeader = next_header;
\r
272 WriteBuf(b, h, total_size);
\r
278 BUF *BuildIPv6(IPV6_ADDR *dest_ip, IPV6_ADDR *src_ip, UINT id, UCHAR protocol, UCHAR hop_limit, void *data,
\r
281 IPV6_HEADER_PACKET_INFO info;
\r
282 IPV6_HEADER ip_header;
\r
284 UINT size_for_headers;
\r
286 if (dest_ip == NULL || src_ip == NULL || data == NULL)
\r
290 if (hop_limit == 0)
\r
296 Zero(&ip_header, sizeof(ip_header));
\r
297 IPV6_SET_VERSION(&ip_header, 6);
\r
298 ip_header.HopLimit = hop_limit;
\r
299 Copy(&ip_header.SrcAddress, src_ip, sizeof(IPV6_ADDR));
\r
300 Copy(&ip_header.DestAddress, dest_ip, sizeof(IPV6_ADDR));
\r
303 Zero(&info, sizeof(info));
\r
304 info.IPv6Header = &ip_header;
\r
305 info.Protocol = protocol;
\r
306 info.Payload = data;
\r
307 info.PayloadSize = size;
\r
309 buf = BuildIPv6PacketHeader(&info, &size_for_headers);
\r
318 // IPv6 パケットヘッダ部のビルド
\r
319 BUF *BuildIPv6PacketHeader(IPV6_HEADER_PACKET_INFO *info, UINT *bytes_before_payload)
\r
331 q = NewQueueFast();
\r
334 if (info->HopHeader != NULL)
\r
336 InsertQueueInt(q, IPV6_HEADER_HOP);
\r
338 if (info->EndPointHeader != NULL)
\r
340 InsertQueueInt(q, IPV6_HEADER_ENDPOINT);
\r
342 if (info->RoutingHeader != NULL)
\r
344 InsertQueueInt(q, IPV6_HEADER_ROUTING);
\r
346 if (info->FragmentHeader != NULL)
\r
348 InsertQueueInt(q, IPV6_HEADER_FRAGMENT);
\r
350 InsertQueueInt(q, info->Protocol);
\r
353 info->IPv6Header->NextHeader = IPv6GetNextHeaderFromQueue(q);
\r
354 WriteBuf(b, info->IPv6Header, sizeof(IPV6_HEADER));
\r
356 // ホップバイホップオプションヘッダ
\r
357 if (info->HopHeader != NULL)
\r
359 BuildAndAddIPv6PacketOptionHeader(b, info->HopHeader,
\r
360 IPv6GetNextHeaderFromQueue(q), info->HopHeaderSize);
\r
364 if (info->EndPointHeader != NULL)
\r
366 BuildAndAddIPv6PacketOptionHeader(b, info->EndPointHeader,
\r
367 IPv6GetNextHeaderFromQueue(q), info->EndPointHeaderSize);
\r
371 if (info->RoutingHeader != NULL)
\r
373 BuildAndAddIPv6PacketOptionHeader(b, info->RoutingHeader,
\r
374 IPv6GetNextHeaderFromQueue(q), info->RoutingHeaderSize);
\r
378 if (info->FragmentHeader != NULL)
\r
380 info->FragmentHeader->NextHeader = IPv6GetNextHeaderFromQueue(q);
\r
381 WriteBuf(b, info->FragmentHeader, sizeof(IPV6_FRAGMENT_HEADER));
\r
385 if (info->FragmentHeader == NULL)
\r
387 bbp += sizeof(IPV6_FRAGMENT_HEADER);
\r
391 if (info->Protocol != IPV6_HEADER_NONE)
\r
393 WriteBuf(b, info->Payload, info->PayloadSize);
\r
401 ((IPV6_HEADER *)b->Buf)->PayloadLength = Endian16(b->Size - (USHORT)sizeof(IPV6_HEADER));
\r
403 if (bytes_before_payload != NULL)
\r
405 // ペイロードの直前までの長さ (ただしフラグメントヘッダは必ず含まれると仮定)
\r
407 *bytes_before_payload = bbp;
\r
413 // ICMPv6 パケットのオプション値のビルド
\r
414 void BuildICMPv6OptionValue(BUF *b, UCHAR type, void *header_pointer, UINT total_size)
\r
418 ICMPV6_OPTION *opt;
\r
420 if (b == NULL || header_pointer == NULL)
\r
425 packet_size = ((total_size + 7) / 8) * 8;
\r
426 packet = ZeroMalloc(packet_size);
\r
428 Copy(packet, header_pointer, total_size);
\r
429 opt = (ICMPV6_OPTION *)packet;
\r
430 opt->Length = (UCHAR)(packet_size / 8);
\r
433 WriteBuf(b, packet, packet_size);
\r
438 // ICMPv6 パケットのオプションのビルド
\r
439 BUF *BuildICMPv6Options(ICMPV6_OPTION_LIST *o)
\r
450 if (o->SourceLinkLayer != NULL)
\r
452 BuildICMPv6OptionValue(b, ICMPV6_OPTION_TYPE_SOURCE_LINK_LAYER, o->SourceLinkLayer, sizeof(ICMPV6_OPTION_LINK_LAYER));
\r
454 if (o->TargetLinkLayer != NULL)
\r
456 BuildICMPv6OptionValue(b, ICMPV6_OPTION_TYPE_TARGET_LINK_LAYER, o->TargetLinkLayer, sizeof(ICMPV6_OPTION_LINK_LAYER));
\r
458 if (o->Prefix != NULL)
\r
460 BuildICMPv6OptionValue(b, ICMPV6_OPTION_TYPE_PREFIX, o->Prefix, sizeof(ICMPV6_OPTION_PREFIX));
\r
462 if (o->Mtu != NULL)
\r
464 BuildICMPv6OptionValue(b, ICMPV6_OPTION_TYPE_MTU, o->Mtu, sizeof(ICMPV6_OPTION_MTU));
\r
473 USHORT CalcChecksumForIPv6(IPV6_ADDR *src_ip, IPV6_ADDR *dest_ip, UCHAR protocol, void *data, UINT size)
\r
477 IPV6_PSEUDO_HEADER *ph;
\r
480 if (data == NULL && size != 0)
\r
485 tmp_size = size + sizeof(IPV6_PSEUDO_HEADER);
\r
486 tmp = ZeroMalloc(tmp_size);
\r
488 ph = (IPV6_PSEUDO_HEADER *)tmp;
\r
489 Copy(&ph->SrcAddress, src_ip, sizeof(IPV6_ADDR));
\r
490 Copy(&ph->DestAddress, dest_ip, sizeof(IPV6_ADDR));
\r
491 ph->UpperLayerPacketSize = Endian32(size);
\r
492 ph->NextHeader = protocol;
\r
494 Copy(((UCHAR *)tmp) + sizeof(IPV6_PSEUDO_HEADER), data, size);
\r
496 ret = IpChecksum(tmp, tmp_size);
\r
503 // クローンされたパケットを解放する
\r
504 void FreeClonePacket(PKT *p)
\r
512 Free(p->IPv6HeaderPacketInfo.IPv6Header);
\r
513 Free(p->IPv6HeaderPacketInfo.HopHeader);
\r
514 Free(p->IPv6HeaderPacketInfo.EndPointHeader);
\r
515 Free(p->IPv6HeaderPacketInfo.RoutingHeader);
\r
516 Free(p->IPv6HeaderPacketInfo.FragmentHeader);
\r
517 Free(p->IPv6HeaderPacketInfo.Payload);
\r
518 Free(p->ICMPv6HeaderPacketInfo.Data);
\r
519 Free(p->ICMPv6HeaderPacketInfo.EchoData);
\r
520 Free(p->ICMPv6HeaderPacketInfo.Headers.HeaderPointer);
\r
521 FreeCloneICMPv6Options(&p->ICMPv6HeaderPacketInfo.OptionList);
\r
522 Free(p->L3.PointerL3);
\r
523 Free(p->L4.PointerL4);
\r
524 Free(p->L7.PointerL7);
\r
525 Free(p->PacketData);
\r
526 Free(p->MacHeader);
\r
531 PKT *ClonePacket(PKT *p, bool copy_data)
\r
540 ret = ZeroMallocFast(sizeof(PKT));
\r
541 ret->PacketSize = p->PacketSize;
\r
544 ret->MacHeader = MallocFast(sizeof(MAC_HEADER));
\r
545 Copy(ret->MacHeader, p->MacHeader, sizeof(MAC_HEADER));
\r
548 ret->BroadcastPacket = p->BroadcastPacket;
\r
549 ret->InvalidSourcePacket = p->InvalidSourcePacket;
\r
552 Copy(&ret->IPv6HeaderPacketInfo, &p->IPv6HeaderPacketInfo, sizeof(IPV6_HEADER_PACKET_INFO));
\r
553 Copy(&ret->ICMPv6HeaderPacketInfo, &p->ICMPv6HeaderPacketInfo, sizeof(ICMPV6_HEADER_INFO));
\r
556 ret->TypeL3 = p->TypeL3;
\r
557 switch (ret->TypeL3)
\r
561 ret->L3.ARPv4Header = MallocFast(sizeof(ARPV4_HEADER));
\r
562 Copy(ret->L3.ARPv4Header, p->L3.ARPv4Header, sizeof(ARPV4_HEADER));
\r
567 ret->L3.IPv4Header = MallocFast(sizeof(IPV4_HEADER));
\r
568 Copy(ret->L3.IPv4Header, p->L3.IPv4Header, sizeof(IPV4_HEADER));
\r
573 ret->L3.IPv6Header = MallocFast(sizeof(IPV6_HEADER));
\r
574 Copy(ret->L3.IPv6Header, p->L3.IPv6Header, sizeof(IPV6_HEADER));
\r
576 ret->IPv6HeaderPacketInfo.IPv6Header = Clone(p->IPv6HeaderPacketInfo.IPv6Header,
\r
577 sizeof(IPV6_HEADER));
\r
579 ret->IPv6HeaderPacketInfo.HopHeader = Clone(p->IPv6HeaderPacketInfo.HopHeader,
\r
580 sizeof(IPV6_OPTION_HEADER));
\r
582 ret->IPv6HeaderPacketInfo.EndPointHeader = Clone(p->IPv6HeaderPacketInfo.EndPointHeader,
\r
583 sizeof(IPV6_OPTION_HEADER));
\r
585 ret->IPv6HeaderPacketInfo.RoutingHeader = Clone(p->IPv6HeaderPacketInfo.RoutingHeader,
\r
586 sizeof(IPV6_OPTION_HEADER));
\r
588 ret->IPv6HeaderPacketInfo.FragmentHeader = Clone(p->IPv6HeaderPacketInfo.FragmentHeader,
\r
589 sizeof(IPV6_FRAGMENT_HEADER));
\r
591 ret->IPv6HeaderPacketInfo.Payload = Clone(p->IPv6HeaderPacketInfo.Payload,
\r
592 p->IPv6HeaderPacketInfo.PayloadSize);
\r
597 ret->TypeL4 = p->TypeL4;
\r
598 switch (ret->TypeL4)
\r
602 ret->L4.ICMPHeader = MallocFast(sizeof(ICMP_HEADER));
\r
603 Copy(ret->L4.ICMPHeader, p->L4.ICMPHeader, sizeof(ICMP_HEADER));
\r
608 ret->L4.ICMPHeader = MallocFast(sizeof(ICMP_HEADER));
\r
609 Copy(ret->L4.ICMPHeader, p->L4.ICMPHeader, sizeof(ICMP_HEADER));
\r
611 ret->ICMPv6HeaderPacketInfo.Data = Clone(p->ICMPv6HeaderPacketInfo.Data,
\r
612 p->ICMPv6HeaderPacketInfo.DataSize);
\r
614 ret->ICMPv6HeaderPacketInfo.EchoData = Clone(p->ICMPv6HeaderPacketInfo.EchoData,
\r
615 p->ICMPv6HeaderPacketInfo.EchoDataSize);
\r
617 switch (ret->ICMPv6HeaderPacketInfo.Type)
\r
619 case ICMPV6_TYPE_ECHO_REQUEST:
\r
620 case ICMPV6_TYPE_ECHO_RESPONSE:
\r
623 case ICMPV6_TYPE_ROUTER_SOLICIATION:
\r
624 ret->ICMPv6HeaderPacketInfo.Headers.RouterSoliciationHeader =
\r
625 Clone(p->ICMPv6HeaderPacketInfo.Headers.RouterSoliciationHeader,
\r
626 sizeof(ICMPV6_ROUTER_SOLICIATION_HEADER));
\r
629 case ICMPV6_TYPE_ROUTER_ADVERTISEMENT:
\r
630 ret->ICMPv6HeaderPacketInfo.Headers.RouterAdvertisementHeader =
\r
631 Clone(p->ICMPv6HeaderPacketInfo.Headers.RouterAdvertisementHeader,
\r
632 sizeof(ICMPV6_ROUTER_ADVERTISEMENT_HEADER));
\r
635 case ICMPV6_TYPE_NEIGHBOR_SOLICIATION:
\r
636 ret->ICMPv6HeaderPacketInfo.Headers.NeighborSoliciationHeader =
\r
637 Clone(p->ICMPv6HeaderPacketInfo.Headers.NeighborSoliciationHeader,
\r
638 sizeof(ICMPV6_NEIGHBOR_SOLICIATION_HEADER));
\r
641 case ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT:
\r
642 ret->ICMPv6HeaderPacketInfo.Headers.NeighborAdvertisementHeader =
\r
643 Clone(p->ICMPv6HeaderPacketInfo.Headers.NeighborAdvertisementHeader,
\r
644 sizeof(ICMPV6_NEIGHBOR_ADVERTISEMENT_HEADER));
\r
648 CloneICMPv6Options(&ret->ICMPv6HeaderPacketInfo.OptionList,
\r
649 &p->ICMPv6HeaderPacketInfo.OptionList);
\r
654 ret->L4.TCPHeader = MallocFast(sizeof(TCP_HEADER));
\r
655 Copy(ret->L4.TCPHeader, p->L4.TCPHeader, sizeof(TCP_HEADER));
\r
660 ret->L4.UDPHeader = MallocFast(sizeof(UDP_HEADER));
\r
661 Copy(ret->L4.UDPHeader, p->L4.UDPHeader, sizeof(UDP_HEADER));
\r
666 ret->TypeL7 = p->TypeL7;
\r
667 switch (ret->TypeL7)
\r
671 ret->L7.DHCPv4Header = MallocFast(sizeof(DHCPV4_HEADER));
\r
672 Copy(ret->L7.DHCPv4Header, p->L7.DHCPv4Header, sizeof(DHCPV4_HEADER));
\r
677 ret->MacAddressSrc = ret->MacHeader->SrcAddress;
\r
678 ret->MacAddressDest = ret->MacHeader->DestAddress;
\r
683 ret->PacketData = MallocFast(p->PacketSize);
\r
684 Copy(ret->PacketData, p->PacketData, p->PacketSize);
\r
691 PKT *ParsePacket(UCHAR *buf, UINT size)
\r
693 return ParsePacketEx(buf, size, false);
\r
695 PKT *ParsePacketEx(UCHAR *buf, UINT size, bool no_l3)
\r
697 return ParsePacketEx2(buf, size, no_l3, 0);
\r
699 PKT *ParsePacketEx2(UCHAR *buf, UINT size, bool no_l3, UINT vlan_type_id)
\r
701 return ParsePacketEx3(buf, size, no_l3, vlan_type_id, true);
\r
703 PKT *ParsePacketEx3(UCHAR *buf, UINT size, bool no_l3, UINT vlan_type_id, bool bridge_id_as_mac_address)
\r
707 if (buf == NULL || size == 0)
\r
712 if (vlan_type_id == 0)
\r
714 vlan_type_id = MAC_PROTO_TAGVLAN;
\r
717 p = ZeroMallocFast(sizeof(PKT));
\r
719 p->VlanTypeID = vlan_type_id;
\r
722 if (ParsePacketL2Ex(p, buf, size, no_l3) == false)
\r
729 p->PacketData = buf;
\r
730 p->PacketSize = size;
\r
732 p->MacAddressSrc = p->MacHeader->SrcAddress;
\r
733 p->MacAddressDest = p->MacHeader->DestAddress;
\r
735 if (bridge_id_as_mac_address)
\r
737 if (p->TypeL3 == L3_BPDU)
\r
739 if (p->L3.BpduHeader != NULL)
\r
741 p->MacAddressSrc = p->L3.BpduHeader->BridgeMacAddress;
\r
752 bool ParsePacketL2(PKT *p, UCHAR *buf, UINT size)
\r
754 return ParsePacketL2Ex(p, buf, size, false);
\r
756 bool ParsePacketL2Ex(PKT *p, UCHAR *buf, UINT size, bool no_l3)
\r
762 if (p == NULL || buf == NULL)
\r
768 if (size < sizeof(MAC_HEADER))
\r
774 p->MacHeader = (MAC_HEADER *)buf;
\r
776 buf += sizeof(MAC_HEADER);
\r
777 size -= sizeof(MAC_HEADER);
\r
780 p->BroadcastPacket = true;
\r
783 for (i = 0;i < 6;i++)
\r
785 if (p->MacHeader->DestAddress[i] != 0xff)
\r
787 p->BroadcastPacket = false;
\r
789 if (p->MacHeader->SrcAddress[i] != 0xff)
\r
793 if (p->MacHeader->SrcAddress[i] != 0x00)
\r
798 if (b1 || b2 || (Cmp(p->MacHeader->SrcAddress, p->MacHeader->DestAddress, 6) == 0))
\r
800 p->InvalidSourcePacket = true;
\r
804 p->InvalidSourcePacket = false;
\r
807 if (p->MacHeader->DestAddress[0] & 0x01)
\r
809 p->BroadcastPacket = true;
\r
813 type_id_16 = Endian16(p->MacHeader->Protocol);
\r
815 if (type_id_16 > 1500)
\r
817 // 通常の Ethernet フレーム
\r
818 switch (type_id_16)
\r
820 case MAC_PROTO_ARPV4: // ARPv4
\r
826 return ParsePacketARPv4(p, buf, size);
\r
828 case MAC_PROTO_IPV4: // IPv4
\r
834 return ParsePacketIPv4(p, buf, size);
\r
836 case MAC_PROTO_IPV6: // IPv6
\r
842 return ParsePacketIPv6(p, buf, size);
\r
845 if (type_id_16 == p->VlanTypeID)
\r
848 return ParsePacketTAGVLAN(p, buf, size);
\r
858 // IEEE 802.3 の古い (パケットのペイロード長が書いてある) フレーム
\r
859 // (BPDU 等で使われていることがある)
\r
860 UINT length = (UINT)type_id_16;
\r
863 // 長さが残っているかどうかチェック
\r
864 if (size < length || size < sizeof(LLC_HEADER))
\r
870 llc = (LLC_HEADER *)buf;
\r
871 buf += sizeof(LLC_HEADER);
\r
872 size -= sizeof(LLC_HEADER);
\r
874 // DSAP, SSAP の値によってプロトコルを判定する
\r
875 if (llc->Dsap == LLC_DSAP_BPDU && llc->Ssap == LLC_SSAP_BPDU)
\r
877 // BPDU (Spanning Tree) である
\r
878 return ParsePacketBPDU(p, buf, size);
\r
889 bool ParsePacketTAGVLAN(PKT *p, UCHAR *buf, UINT size)
\r
891 USHORT vlan_ushort;
\r
893 if (p == NULL || buf == NULL)
\r
899 if (size < sizeof(TAGVLAN_HEADER))
\r
905 p->L3.TagVlanHeader = (TAGVLAN_HEADER *)buf;
\r
906 p->TypeL3 = L3_TAGVLAN;
\r
908 buf += sizeof(TAGVLAN_HEADER);
\r
909 size -= sizeof(TAGVLAN_HEADER);
\r
911 vlan_ushort = Endian16(*((USHORT *)p->L3.TagVlanHeader->Data));
\r
912 vlan_ushort = vlan_ushort & 0xFFF;
\r
914 p->VlanId = vlan_ushort;
\r
920 bool ParsePacketBPDU(PKT *p, UCHAR *buf, UINT size)
\r
923 if (p == NULL || buf == NULL)
\r
929 if (size < sizeof(BPDU_HEADER))
\r
935 p->L3.BpduHeader = (BPDU_HEADER *)buf;
\r
936 p->TypeL3 = L3_BPDU;
\r
938 buf += sizeof(BPDU_HEADER);
\r
939 size -= sizeof(BPDU_HEADER);
\r
945 bool ParsePacketARPv4(PKT *p, UCHAR *buf, UINT size)
\r
948 if (p == NULL || buf == NULL)
\r
954 if (size < sizeof(ARPV4_HEADER))
\r
960 p->L3.ARPv4Header = (ARPV4_HEADER *)buf;
\r
961 p->TypeL3 = L3_ARPV4;
\r
963 buf += sizeof(ARPV4_HEADER);
\r
964 size -= sizeof(ARPV4_HEADER);
\r
970 bool ParseIPv6ExtHeader(IPV6_HEADER_PACKET_INFO *info, UCHAR next_header, UCHAR *buf, UINT size)
\r
973 IPV6_OPTION_HEADER *option_header;
\r
974 UINT option_header_size;
\r
975 UCHAR next_header_2 = IPV6_HEADER_NONE;
\r
977 if (info == NULL || buf == NULL)
\r
982 info->IsFragment = false;
\r
988 next_header_2 = *((UCHAR *)buf);
\r
991 switch (next_header)
\r
993 case IPV6_HEADER_HOP:
\r
994 case IPV6_HEADER_ENDPOINT:
\r
995 case IPV6_HEADER_ROUTING:
\r
1002 option_header = (IPV6_OPTION_HEADER *)buf;
\r
1003 option_header_size = (option_header->Size + 1) * 8;
\r
1004 if (size < option_header_size)
\r
1009 switch (next_header)
\r
1011 case IPV6_HEADER_HOP:
\r
1012 info->HopHeader = (IPV6_OPTION_HEADER *)buf;
\r
1013 info->HopHeaderSize = option_header_size;
\r
1016 case IPV6_HEADER_ENDPOINT:
\r
1017 info->EndPointHeader = (IPV6_OPTION_HEADER *)buf;
\r
1018 info->EndPointHeaderSize = option_header_size;
\r
1021 case IPV6_HEADER_ROUTING:
\r
1022 info->RoutingHeader = (IPV6_OPTION_HEADER *)buf;
\r
1023 info->RoutingHeaderSize = option_header_size;
\r
1027 buf += option_header_size;
\r
1028 size -= option_header_size;
\r
1031 case IPV6_HEADER_FRAGMENT:
\r
1032 // フラグメントヘッダ (固定長)
\r
1033 if (size < sizeof(IPV6_FRAGMENT_HEADER))
\r
1038 info->FragmentHeader = (IPV6_FRAGMENT_HEADER *)buf;
\r
1040 if (IPV6_GET_FRAGMENT_OFFSET(info->FragmentHeader) != 0)
\r
1042 info->IsFragment = true;
\r
1045 buf += sizeof(IPV6_FRAGMENT_HEADER);
\r
1046 size -= sizeof(IPV6_FRAGMENT_HEADER);
\r
1051 if (next_header != IPV6_HEADER_NONE)
\r
1053 info->Payload = buf;
\r
1054 info->PayloadSize = size;
\r
1058 info->Payload = NULL;
\r
1059 info->PayloadSize = 0;
\r
1061 info->Protocol = next_header;
\r
1065 next_header = next_header_2;
\r
1070 bool ParsePacketIPv6Header(IPV6_HEADER_PACKET_INFO *info, UCHAR *buf, UINT size)
\r
1073 if (info == NULL || buf == NULL)
\r
1078 Zero(info, sizeof(IPV6_HEADER_PACKET_INFO));
\r
1081 if (size < sizeof(IPV6_HEADER))
\r
1087 info->IPv6Header = (IPV6_HEADER *)buf;
\r
1088 buf += sizeof(IPV6_HEADER);
\r
1089 size -= sizeof(IPV6_HEADER);
\r
1091 if (IPV6_GET_VERSION(info->IPv6Header) != 6)
\r
1098 return ParseIPv6ExtHeader(info, info->IPv6Header->NextHeader, buf, size);
\r
1101 // ICMPv6 パケットのオプションの解析
\r
1102 bool ParseICMPv6Options(ICMPV6_OPTION_LIST *o, UCHAR *buf, UINT size)
\r
1105 if (o == NULL || buf == NULL)
\r
1110 Zero(o, sizeof(ICMPV6_OPTION_LIST));
\r
1115 ICMPV6_OPTION *option_header;
\r
1116 UINT header_total_size;
\r
1117 UCHAR *header_pointer;
\r
1118 if (size < sizeof(ICMPV6_OPTION))
\r
1124 option_header = (ICMPV6_OPTION *)buf;
\r
1126 header_total_size = option_header->Length * 8;
\r
1127 if (header_total_size == 0)
\r
1132 if (size < header_total_size)
\r
1138 header_pointer = buf;
\r
1139 buf += header_total_size;
\r
1140 size -= header_total_size;
\r
1142 switch (option_header->Type)
\r
1144 case ICMPV6_OPTION_TYPE_SOURCE_LINK_LAYER:
\r
1145 case ICMPV6_OPTION_TYPE_TARGET_LINK_LAYER:
\r
1146 // ソース or ターゲットリンクレイヤオプション
\r
1147 if (header_total_size >= sizeof(ICMPV6_OPTION_LINK_LAYER))
\r
1149 if (option_header->Type == ICMPV6_OPTION_TYPE_SOURCE_LINK_LAYER)
\r
1151 o->SourceLinkLayer = (ICMPV6_OPTION_LINK_LAYER *)header_pointer;
\r
1155 o->TargetLinkLayer = (ICMPV6_OPTION_LINK_LAYER *)header_pointer;
\r
1165 case ICMPV6_OPTION_TYPE_PREFIX:
\r
1167 if (header_total_size >= sizeof(ICMPV6_OPTION_PREFIX))
\r
1169 o->Prefix = (ICMPV6_OPTION_PREFIX *)header_pointer;
\r
1177 case ICMPV6_OPTION_TYPE_MTU:
\r
1179 if (header_total_size >= sizeof(ICMPV6_OPTION_MTU))
\r
1181 o->Mtu = (ICMPV6_OPTION_MTU *)header_pointer;
\r
1193 bool ParseICMPv6(PKT *p, UCHAR *buf, UINT size)
\r
1195 ICMPV6_HEADER_INFO icmp_info;
\r
1196 ICMP_HEADER *icmp;
\r
1200 if (p == NULL || buf == NULL)
\r
1205 Zero(&icmp_info, sizeof(icmp_info));
\r
1207 if (size < sizeof(ICMP_HEADER))
\r
1212 icmp = (ICMP_HEADER *)buf;
\r
1213 p->L4.ICMPHeader = icmp;
\r
1215 msg_size = size - sizeof(ICMP_HEADER);
\r
1217 icmp_info.Type = icmp->Type;
\r
1218 icmp_info.Code = icmp->Code;
\r
1219 icmp_info.Data = ((UCHAR *)buf) + sizeof(ICMP_HEADER);
\r
1220 icmp_info.DataSize = msg_size;
\r
1222 switch (icmp_info.Type)
\r
1224 case ICMPV6_TYPE_ECHO_REQUEST:
\r
1225 case ICMPV6_TYPE_ECHO_RESPONSE:
\r
1226 // ICMP Echo Request / Response
\r
1227 if (icmp_info.DataSize < sizeof(ICMP_ECHO))
\r
1232 echo = (ICMP_ECHO *)icmp_info.Data;
\r
1234 icmp_info.EchoHeader.Identifier = Endian16(echo->Identifier);
\r
1235 icmp_info.EchoHeader.SeqNo = Endian16(echo->SeqNo);
\r
1236 icmp_info.EchoData = (UCHAR *)echo + sizeof(ICMP_ECHO);
\r
1237 icmp_info.EchoDataSize = icmp_info.DataSize - sizeof(ICMP_ECHO);
\r
1241 case ICMPV6_TYPE_ROUTER_SOLICIATION:
\r
1243 if (icmp_info.DataSize < sizeof(ICMPV6_ROUTER_SOLICIATION_HEADER))
\r
1248 icmp_info.Headers.RouterSoliciationHeader =
\r
1249 (ICMPV6_ROUTER_SOLICIATION_HEADER *)(((UCHAR *)icmp_info.Data));
\r
1251 if (ParseICMPv6Options(&icmp_info.OptionList, ((UCHAR *)icmp_info.Headers.HeaderPointer) + sizeof(ICMPV6_ROUTER_SOLICIATION_HEADER),
\r
1252 icmp_info.DataSize - sizeof(ICMPV6_ROUTER_SOLICIATION_HEADER)) == false)
\r
1259 case ICMPV6_TYPE_ROUTER_ADVERTISEMENT:
\r
1261 if (icmp_info.DataSize < sizeof(ICMPV6_ROUTER_ADVERTISEMENT_HEADER))
\r
1266 icmp_info.Headers.RouterAdvertisementHeader =
\r
1267 (ICMPV6_ROUTER_ADVERTISEMENT_HEADER *)(((UCHAR *)icmp_info.Data));
\r
1269 if (ParseICMPv6Options(&icmp_info.OptionList, ((UCHAR *)icmp_info.Headers.HeaderPointer) + sizeof(ICMPV6_ROUTER_ADVERTISEMENT_HEADER),
\r
1270 icmp_info.DataSize - sizeof(ICMPV6_ROUTER_ADVERTISEMENT_HEADER)) == false)
\r
1277 case ICMPV6_TYPE_NEIGHBOR_SOLICIATION:
\r
1279 if (icmp_info.DataSize < sizeof(ICMPV6_NEIGHBOR_SOLICIATION_HEADER))
\r
1284 icmp_info.Headers.NeighborSoliciationHeader =
\r
1285 (ICMPV6_NEIGHBOR_SOLICIATION_HEADER *)(((UCHAR *)icmp_info.Data));
\r
1287 if (ParseICMPv6Options(&icmp_info.OptionList, ((UCHAR *)icmp_info.Headers.HeaderPointer) + sizeof(ICMPV6_NEIGHBOR_SOLICIATION_HEADER),
\r
1288 icmp_info.DataSize - sizeof(ICMPV6_NEIGHBOR_SOLICIATION_HEADER)) == false)
\r
1295 case ICMPV6_TYPE_NEIGHBOR_ADVERTISEMENT:
\r
1297 if (icmp_info.DataSize < sizeof(ICMPV6_NEIGHBOR_ADVERTISEMENT_HEADER))
\r
1302 icmp_info.Headers.NeighborAdvertisementHeader =
\r
1303 (ICMPV6_NEIGHBOR_ADVERTISEMENT_HEADER *)(((UCHAR *)icmp_info.Data));
\r
1305 if (ParseICMPv6Options(&icmp_info.OptionList, ((UCHAR *)icmp_info.Headers.HeaderPointer) + sizeof(ICMPV6_NEIGHBOR_ADVERTISEMENT_HEADER),
\r
1306 icmp_info.DataSize - sizeof(ICMPV6_NEIGHBOR_ADVERTISEMENT_HEADER)) == false)
\r
1314 p->TypeL4 = L4_ICMPV6;
\r
1315 Copy(&p->ICMPv6HeaderPacketInfo, &icmp_info, sizeof(ICMPV6_HEADER_INFO));
\r
1320 // ICMPv6 オプションの解放
\r
1321 void FreeCloneICMPv6Options(ICMPV6_OPTION_LIST *o)
\r
1329 Free(o->SourceLinkLayer);
\r
1330 Free(o->TargetLinkLayer);
\r
1335 // ICMPv6 オプションのクローン
\r
1336 void CloneICMPv6Options(ICMPV6_OPTION_LIST *dst, ICMPV6_OPTION_LIST *src)
\r
1339 if (dst == NULL || src == NULL)
\r
1344 Zero(dst, sizeof(ICMPV6_OPTION_LIST));
\r
1346 dst->SourceLinkLayer = Clone(src->SourceLinkLayer, sizeof(ICMPV6_OPTION_LINK_LAYER));
\r
1347 dst->TargetLinkLayer = Clone(src->TargetLinkLayer, sizeof(ICMPV6_OPTION_LINK_LAYER));
\r
1348 dst->Prefix = Clone(src->Prefix, sizeof(ICMPV6_OPTION_PREFIX));
\r
1349 dst->Mtu = Clone(src->Mtu, sizeof(ICMPV6_OPTION_MTU));
\r
1353 bool ParsePacketIPv6(PKT *p, UCHAR *buf, UINT size)
\r
1356 if (p == NULL || buf == NULL)
\r
1361 if (ParsePacketIPv6Header(&p->IPv6HeaderPacketInfo, buf, size) == false)
\r
1366 p->TypeL3 = L3_IPV6;
\r
1367 p->L3.IPv6Header = p->IPv6HeaderPacketInfo.IPv6Header;
\r
1369 if (p->IPv6HeaderPacketInfo.Payload == NULL)
\r
1375 buf = p->IPv6HeaderPacketInfo.Payload;
\r
1376 size = p->IPv6HeaderPacketInfo.PayloadSize;
\r
1378 if (p->IPv6HeaderPacketInfo.IsFragment)
\r
1380 // フラグメントパケットであるからこれ以上解釈しない
\r
1381 p->TypeL4 = L4_FRAGMENT;
\r
1386 switch (p->IPv6HeaderPacketInfo.Protocol)
\r
1388 case IP_PROTO_ICMPV6: // ICMPv6
\r
1389 if (ParseICMPv6(p, buf, size) == false)
\r
1391 // ICMPv6 のパースに失敗しても true を返す
\r
1399 case IP_PROTO_TCP: // TCP
\r
1400 return ParseTCP(p, buf, size);
\r
1402 case IP_PROTO_UDP: // UDP
\r
1403 return ParseUDP(p, buf, size);
\r
1413 bool ParsePacketIPv4(PKT *p, UCHAR *buf, UINT size)
\r
1417 if (p == NULL || buf == NULL)
\r
1423 if (size < sizeof(IPV4_HEADER))
\r
1429 p->L3.IPv4Header = (IPV4_HEADER *)buf;
\r
1430 p->TypeL3 = L3_IPV4;
\r
1433 header_size = IPV4_GET_HEADER_LEN(p->L3.IPv4Header) * 4;
\r
1434 if (header_size < sizeof(IPV4_HEADER) || size < header_size)
\r
1437 p->L3.IPv4Header = NULL;
\r
1438 p->TypeL3= L3_UNKNOWN;
\r
1442 if (IPV4_GET_OFFSET(p->L3.IPv4Header) != 0)
\r
1444 // フラグメント化されているからこれ以上解析しない
\r
1445 p->TypeL4 = L4_FRAGMENT;
\r
1449 buf += header_size;
\r
1450 size -= header_size;
\r
1453 switch (p->L3.IPv4Header->Protocol)
\r
1455 case IP_PROTO_ICMPV4: // ICMPv4
\r
1456 return ParseICMPv4(p, buf, size);
\r
1458 case IP_PROTO_UDP: // UDP
\r
1459 return ParseUDP(p, buf, size);
\r
1461 case IP_PROTO_TCP: // TCP
\r
1462 return ParseTCP(p, buf, size);
\r
1470 bool ParseICMPv4(PKT *p, UCHAR *buf, UINT size)
\r
1473 if (p == NULL || buf == NULL)
\r
1479 if (size < sizeof(ICMP_HEADER))
\r
1486 p->L4.ICMPHeader = (ICMP_HEADER *)buf;
\r
1487 p->TypeL4 = L4_ICMPV4;
\r
1489 buf += sizeof(ICMP_HEADER);
\r
1490 size -= sizeof(ICMP_HEADER);
\r
1496 bool ParseTCP(PKT *p, UCHAR *buf, UINT size)
\r
1500 if (p == NULL || buf == NULL)
\r
1506 if (size < sizeof(TCP_HEADER))
\r
1513 p->L4.TCPHeader = (TCP_HEADER *)buf;
\r
1514 p->TypeL4 = L4_TCP;
\r
1517 header_size = TCP_GET_HEADER_SIZE(p->L4.TCPHeader) * 4;
\r
1518 if (header_size < sizeof(TCP_HEADER) || size < header_size)
\r
1521 p->L4.TCPHeader = NULL;
\r
1522 p->TypeL4 = L4_UNKNOWN;
\r
1526 buf += header_size;
\r
1527 size -= header_size;
\r
1533 bool ParseUDP(PKT *p, UCHAR *buf, UINT size)
\r
1535 USHORT src_port, dst_port;
\r
1537 if (p == NULL || buf == NULL)
\r
1543 if (size < sizeof(UDP_HEADER))
\r
1550 p->L4.UDPHeader = (UDP_HEADER *)buf;
\r
1551 p->TypeL4 = L4_UDP;
\r
1553 buf += sizeof(UDP_HEADER);
\r
1554 size -= sizeof(UDP_HEADER);
\r
1557 src_port = Endian16(p->L4.UDPHeader->SrcPort);
\r
1558 dst_port = Endian16(p->L4.UDPHeader->DstPort);
\r
1560 if ((src_port == 67 && dst_port == 68) ||
\r
1561 (src_port == 68 && dst_port == 67))
\r
1563 if (p->TypeL3 == L3_IPV4)
\r
1566 ParseDHCPv4(p, buf, size);
\r
1574 void ParseDHCPv4(PKT *p, UCHAR *buf, UINT size)
\r
1577 if (p == NULL || buf == NULL)
\r
1583 if (size < sizeof(DHCPV4_HEADER))
\r
1590 p->L7.DHCPv4Header = (DHCPV4_HEADER *)buf;
\r
1591 p->TypeL7 = L7_DHCPV4;
\r
1595 void FreePacket(PKT *p)
\r
1603 if (p->MacHeader != NULL)
\r
1605 switch (p->TypeL3)
\r
1608 FreePacketIPv4(p);
\r
1612 FreePacketARPv4(p);
\r
1616 FreePacketTagVlan(p);
\r
1624 // IPv4 パケットのメモリを解放する
\r
1625 void FreePacketIPv4(PKT *p)
\r
1633 switch (p->TypeL4)
\r
1636 FreePacketICMPv4(p);
\r
1640 FreePacketTCPv4(p);
\r
1644 FreePacketUDPv4(p);
\r
1648 p->L3.IPv4Header = NULL;
\r
1649 p->TypeL3 = L3_UNKNOWN;
\r
1652 // タグ VLAN パケットのメモリを解放する
\r
1653 void FreePacketTagVlan(PKT *p)
\r
1661 p->L3.TagVlanHeader = NULL;
\r
1662 p->TypeL3 = L3_UNKNOWN;
\r
1665 // ARPv4 パケットのメモリを解放する
\r
1666 void FreePacketARPv4(PKT *p)
\r
1674 p->L3.ARPv4Header = NULL;
\r
1675 p->TypeL3 = L3_UNKNOWN;
\r
1678 // UDPv4 パケットのメモリを解放する
\r
1679 void FreePacketUDPv4(PKT *p)
\r
1687 switch (p->TypeL7)
\r
1690 FreePacketDHCPv4(p);
\r
1694 p->L4.UDPHeader = NULL;
\r
1695 p->TypeL4 = L4_UNKNOWN;
\r
1698 // TCPv4 パケットのメモリを解放する
\r
1699 void FreePacketTCPv4(PKT *p)
\r
1707 p->L4.TCPHeader = NULL;
\r
1708 p->TypeL4 = L4_UNKNOWN;
\r
1711 // ICMPv4 パケットのメモリを解放する
\r
1712 void FreePacketICMPv4(PKT *p)
\r
1720 p->L4.ICMPHeader = NULL;
\r
1721 p->TypeL4 = L4_UNKNOWN;
\r
1724 // DHCPv4 パケットのメモリを解放する
\r
1725 void FreePacketDHCPv4(PKT *p)
\r
1733 p->L7.DHCPv4Header = NULL;
\r
1734 p->TypeL7 = L7_UNKNOWN;
\r