Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
P
Pcap-Net
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Pcap-Net
Commits
64ffbb1d
Commit
64ffbb1d
authored
Sep 03, 2011
by
Brickner_cp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
DNS.
Separate RandomPacketExtension to different classes by protocol.
parent
066e0511
Show whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
2335 additions
and
1364 deletions
+2335
-1364
DnsTests.cs
PcapDotNet/src/PcapDotNet.Packets.Test/DnsTests.cs
+37
-10
PcapDotNet.Packets.TestUtils.csproj
...Net.Packets.TestUtils/PcapDotNet.Packets.TestUtils.csproj
+11
-0
RandomArpExtensions.cs
...t/src/PcapDotNet.Packets.TestUtils/RandomArpExtensions.cs
+26
-0
RandomDnsExtensions.cs
...t/src/PcapDotNet.Packets.TestUtils/RandomDnsExtensions.cs
+125
-0
RandomEthernetExtensions.cs
.../PcapDotNet.Packets.TestUtils/RandomEthernetExtensions.cs
+69
-0
RandomGreExtensions.cs
...t/src/PcapDotNet.Packets.TestUtils/RandomGreExtensions.cs
+100
-0
RandomHttpExtensions.cs
.../src/PcapDotNet.Packets.TestUtils/RandomHttpExtensions.cs
+323
-0
RandomIcmpExtensions.cs
.../src/PcapDotNet.Packets.TestUtils/RandomIcmpExtensions.cs
+261
-0
RandomIgmpExtensions.cs
.../src/PcapDotNet.Packets.TestUtils/RandomIgmpExtensions.cs
+114
-0
RandomIpV4Extensions.cs
.../src/PcapDotNet.Packets.TestUtils/RandomIpV4Extensions.cs
+213
-0
RandomIpV6Extensions.cs
.../src/PcapDotNet.Packets.TestUtils/RandomIpV6Extensions.cs
+14
-0
RandomPacketsExtensions.cs
...c/PcapDotNet.Packets.TestUtils/RandomPacketsExtensions.cs
+2
-1309
RandomTcpExtensions.cs
...t/src/PcapDotNet.Packets.TestUtils/RandomTcpExtensions.cs
+174
-0
RandomUdpExtensions.cs
...t/src/PcapDotNet.Packets.TestUtils/RandomUdpExtensions.cs
+20
-0
DataSegment.cs
PcapDotNet/src/PcapDotNet.Packets/DataSegment.cs
+20
-3
DnsDataResourceRecord.cs
...otNet/src/PcapDotNet.Packets/Dns/DnsDataResourceRecord.cs
+1
-1
DnsDomainName.cs
PcapDotNet/src/PcapDotNet.Packets/Dns/DnsDomainName.cs
+23
-11
DnsDomainNameCompressionData.cs
...rc/PcapDotNet.Packets/Dns/DnsDomainNameCompressionData.cs
+3
-0
DnsResourceData.cs
PcapDotNet/src/PcapDotNet.Packets/Dns/DnsResourceData.cs
+781
-17
DnsResourceDataAnything.cs
...Net/src/PcapDotNet.Packets/Dns/DnsResourceDataAnything.cs
+12
-6
DnsResourceRecord.cs
PcapDotNet/src/PcapDotNet.Packets/Dns/DnsResourceRecord.cs
+5
-6
PcapDotNet.Packets.csproj
PcapDotNet/src/PcapDotNet.Packets/PcapDotNet.Packets.csproj
+1
-1
No files found.
PcapDotNet/src/PcapDotNet.Packets.Test/DnsTests.cs
View file @
64ffbb1d
...
@@ -66,14 +66,19 @@ namespace PcapDotNet.Packets.Test
...
@@ -66,14 +66,19 @@ namespace PcapDotNet.Packets.Test
for
(
int
i
=
0
;
i
!=
1000
;
++
i
)
for
(
int
i
=
0
;
i
!=
1000
;
++
i
)
{
{
DnsLayer
dnsLayer
=
random
.
NextDnsLayer
();
DnsLayer
dnsLayer
;
do
{
dnsLayer
=
random
.
NextDnsLayer
();
}
while
(
dnsLayer
.
Length
>
65000
);
Packet
packet
=
PacketBuilder
.
Build
(
DateTime
.
Now
,
ethernetLayer
,
ipV4Layer
,
udpLayer
,
dnsLayer
);
Packet
packet
=
PacketBuilder
.
Build
(
DateTime
.
Now
,
ethernetLayer
,
ipV4Layer
,
udpLayer
,
dnsLayer
);
Assert
.
IsTrue
(
packet
.
IsValid
,
"IsValid"
);
Assert
.
IsTrue
(
packet
.
IsValid
,
"IsValid"
);
// DNS
// DNS
Assert
.
AreEqual
(
dnsLayer
,
packet
.
Ethernet
.
IpV4
.
Udp
.
Dns
.
ExtractLayer
(),
"DNS Layer"
);
DnsLayer
actualLayer
=
(
DnsLayer
)
packet
.
Ethernet
.
IpV4
.
Udp
.
Dns
.
ExtractLayer
();
Assert
.
AreEqual
(
dnsLayer
,
actualLayer
,
"DNS Layer"
);
}
}
}
}
...
@@ -92,31 +97,53 @@ namespace PcapDotNet.Packets.Test
...
@@ -92,31 +97,53 @@ namespace PcapDotNet.Packets.Test
dnsLayer
.
Queries
.
Add
(
new
DnsQueryResourceRecord
(
new
DnsDomainName
(
""
),
DnsType
.
All
,
DnsClass
.
In
));
dnsLayer
.
Queries
.
Add
(
new
DnsQueryResourceRecord
(
new
DnsDomainName
(
""
),
DnsType
.
All
,
DnsClass
.
In
));
TestDomainNameCompression
(
0
,
dnsLayer
);
TestDomainNameCompression
(
0
,
dnsLayer
);
dnsLayer
.
Answers
.
Add
(
new
DnsDataResourceRecord
(
new
DnsDomainName
(
""
),
DnsType
.
All
,
DnsClass
.
In
,
100
,
new
DnsResourceData
Unknown
(
new
DataSegment
(
new
byte
[
0
])
)));
dnsLayer
.
Answers
.
Add
(
new
DnsDataResourceRecord
(
new
DnsDomainName
(
""
),
DnsType
.
All
,
DnsClass
.
In
,
100
,
new
DnsResourceData
Anything
(
DataSegment
.
Empty
)));
TestDomainNameCompression
(
0
,
dnsLayer
);
TestDomainNameCompression
(
0
,
dnsLayer
);
dnsLayer
.
Answers
.
Add
(
new
DnsDataResourceRecord
(
new
DnsDomainName
(
"abc"
),
DnsType
.
All
,
DnsClass
.
In
,
100
,
new
DnsResourceData
Unknown
(
new
DataSegment
(
new
byte
[
0
])
)));
dnsLayer
.
Answers
.
Add
(
new
DnsDataResourceRecord
(
new
DnsDomainName
(
"abc"
),
DnsType
.
All
,
DnsClass
.
In
,
100
,
new
DnsResourceData
Anything
(
DataSegment
.
Empty
)));
TestDomainNameCompression
(
0
,
dnsLayer
);
TestDomainNameCompression
(
0
,
dnsLayer
);
dnsLayer
.
Answers
.
Add
(
new
DnsDataResourceRecord
(
new
DnsDomainName
(
"abc"
),
DnsType
.
All
,
DnsClass
.
In
,
100
,
new
DnsResourceData
Unknown
(
new
DataSegment
(
new
byte
[
0
])
)));
dnsLayer
.
Answers
.
Add
(
new
DnsDataResourceRecord
(
new
DnsDomainName
(
"abc"
),
DnsType
.
All
,
DnsClass
.
In
,
100
,
new
DnsResourceData
Anything
(
DataSegment
.
Empty
)));
TestDomainNameCompression
(
3
,
dnsLayer
);
TestDomainNameCompression
(
3
,
dnsLayer
);
dnsLayer
.
Answers
.
Add
(
new
DnsDataResourceRecord
(
new
DnsDomainName
(
"def.abc"
),
DnsType
.
All
,
DnsClass
.
In
,
100
,
new
DnsResourceData
Unknown
(
new
DataSegment
(
new
byte
[
0
])
)));
dnsLayer
.
Answers
.
Add
(
new
DnsDataResourceRecord
(
new
DnsDomainName
(
"def.abc"
),
DnsType
.
All
,
DnsClass
.
In
,
100
,
new
DnsResourceData
Anything
(
DataSegment
.
Empty
)));
TestDomainNameCompression
(
6
,
dnsLayer
);
TestDomainNameCompression
(
6
,
dnsLayer
);
dnsLayer
.
Answers
.
Add
(
new
DnsDataResourceRecord
(
new
DnsDomainName
(
"abc.def"
),
DnsType
.
All
,
DnsClass
.
In
,
100
,
new
DnsResourceData
Unknown
(
new
DataSegment
(
new
byte
[
0
])
)));
dnsLayer
.
Answers
.
Add
(
new
DnsDataResourceRecord
(
new
DnsDomainName
(
"abc.def"
),
DnsType
.
All
,
DnsClass
.
In
,
100
,
new
DnsResourceData
Anything
(
DataSegment
.
Empty
)));
TestDomainNameCompression
(
6
,
dnsLayer
);
TestDomainNameCompression
(
6
,
dnsLayer
);
dnsLayer
.
Authorities
.
Add
(
new
DnsDataResourceRecord
(
new
DnsDomainName
(
"abc.def"
),
DnsType
.
All
,
DnsClass
.
In
,
100
,
new
DnsResourceData
Unknown
(
new
DataSegment
(
new
byte
[
0
])
)));
dnsLayer
.
Authorities
.
Add
(
new
DnsDataResourceRecord
(
new
DnsDomainName
(
"abc.def"
),
DnsType
.
All
,
DnsClass
.
In
,
100
,
new
DnsResourceData
Anything
(
DataSegment
.
Empty
)));
TestDomainNameCompression
(
13
,
dnsLayer
);
TestDomainNameCompression
(
13
,
dnsLayer
);
dnsLayer
.
Authorities
.
Add
(
new
DnsDataResourceRecord
(
new
DnsDomainName
(
"abd.def"
),
DnsType
.
All
,
DnsClass
.
In
,
100
,
new
DnsResourceData
Unknown
(
new
DataSegment
(
new
byte
[
0
])
)));
dnsLayer
.
Authorities
.
Add
(
new
DnsDataResourceRecord
(
new
DnsDomainName
(
"abd.def"
),
DnsType
.
All
,
DnsClass
.
In
,
100
,
new
DnsResourceData
Anything
(
DataSegment
.
Empty
)));
TestDomainNameCompression
(
16
,
dnsLayer
);
TestDomainNameCompression
(
16
,
dnsLayer
);
dnsLayer
.
Additionals
.
Add
(
new
DnsDataResourceRecord
(
new
DnsDomainName
(
"hello.abd.def"
),
DnsType
.
All
,
DnsClass
.
In
,
100
,
new
DnsResourceData
Unknown
(
new
DataSegment
(
new
byte
[
0
])
)));
dnsLayer
.
Additionals
.
Add
(
new
DnsDataResourceRecord
(
new
DnsDomainName
(
"hello.abd.def"
),
DnsType
.
All
,
DnsClass
.
In
,
100
,
new
DnsResourceData
Anything
(
DataSegment
.
Empty
)));
TestDomainNameCompression
(
23
,
dnsLayer
);
TestDomainNameCompression
(
23
,
dnsLayer
);
}
}
[
TestMethod
]
public
void
DnsDomainNameCompressionTooLongTest
()
{
DnsLayer
dnsLayer
=
new
DnsLayer
();
TestDomainNameCompression
(
0
,
dnsLayer
);
dnsLayer
.
Queries
=
new
List
<
DnsQueryResourceRecord
>();
dnsLayer
.
Answers
=
new
List
<
DnsDataResourceRecord
>();
dnsLayer
.
Authorities
=
new
List
<
DnsDataResourceRecord
>();
dnsLayer
.
Additionals
=
new
List
<
DnsDataResourceRecord
>();
TestDomainNameCompression
(
0
,
dnsLayer
);
dnsLayer
.
Answers
.
Add
(
new
DnsDataResourceRecord
(
new
DnsDomainName
(
"aaa"
),
DnsType
.
Null
,
DnsClass
.
In
,
100
,
new
DnsResourceDataAnything
(
new
DataSegment
(
new
byte
[
20000
]))));
TestDomainNameCompression
(
0
,
dnsLayer
);
dnsLayer
.
Answers
.
Add
(
new
DnsDataResourceRecord
(
new
DnsDomainName
(
"bbb.aaa"
),
DnsType
.
Null
,
DnsClass
.
In
,
100
,
new
DnsResourceDataAnything
(
new
DataSegment
(
new
byte
[
1
]))));
TestDomainNameCompression
(
3
,
dnsLayer
);
dnsLayer
.
Answers
.
Add
(
new
DnsDataResourceRecord
(
new
DnsDomainName
(
"bbb.aaa"
),
DnsType
.
Null
,
DnsClass
.
In
,
100
,
new
DnsResourceDataAnything
(
new
DataSegment
(
new
byte
[
1
]))));
TestDomainNameCompression
(
6
,
dnsLayer
);
}
[
TestMethod
]
[
TestMethod
]
public
void
SimpleDnsTest
()
public
void
SimpleDnsTest
()
{
{
...
...
PcapDotNet/src/PcapDotNet.Packets.TestUtils/PcapDotNet.Packets.TestUtils.csproj
View file @
64ffbb1d
...
@@ -73,8 +73,19 @@
...
@@ -73,8 +73,19 @@
</ItemGroup>
</ItemGroup>
<ItemGroup>
<ItemGroup>
<Compile
Include=
"HexEncoding.cs"
/>
<Compile
Include=
"HexEncoding.cs"
/>
<Compile
Include=
"RandomArpExtensions.cs"
/>
<Compile
Include=
"RandomDnsExtensions.cs"
/>
<Compile
Include=
"RandomEthernetExtensions.cs"
/>
<Compile
Include=
"RandomGreExtensions.cs"
/>
<Compile
Include=
"RandomHttpExtensions.cs"
/>
<Compile
Include=
"RandomIcmpExtensions.cs"
/>
<Compile
Include=
"RandomIgmpExtensions.cs"
/>
<Compile
Include=
"RandomIpV4Extensions.cs"
/>
<Compile
Include=
"RandomIpV6Extensions.cs"
/>
<Compile
Include=
"RandomPacketsExtensions.cs"
/>
<Compile
Include=
"RandomPacketsExtensions.cs"
/>
<Compile
Include=
"Properties\AssemblyInfo.cs"
/>
<Compile
Include=
"Properties\AssemblyInfo.cs"
/>
<Compile
Include=
"RandomTcpExtensions.cs"
/>
<Compile
Include=
"RandomUdpExtensions.cs"
/>
</ItemGroup>
</ItemGroup>
<ItemGroup>
<ItemGroup>
<ProjectReference
Include=
"..\PcapDotNet.Base\PcapDotNet.Base.csproj"
>
<ProjectReference
Include=
"..\PcapDotNet.Base\PcapDotNet.Base.csproj"
>
...
...
PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomArpExtensions.cs
0 → 100644
View file @
64ffbb1d
using
System
;
using
PcapDotNet.Base
;
using
PcapDotNet.Packets.Arp
;
using
PcapDotNet.Packets.Ethernet
;
using
PcapDotNet.TestUtils
;
namespace
PcapDotNet.Packets.TestUtils
{
public
static
class
RandomArpExtensions
{
public
static
ArpLayer
NextArpLayer
(
this
Random
random
)
{
byte
hardwareAddressLength
=
random
.
NextByte
();
byte
protocolAddressLength
=
random
.
NextByte
();
return
new
ArpLayer
{
SenderHardwareAddress
=
random
.
NextBytes
(
hardwareAddressLength
).
AsReadOnly
(),
SenderProtocolAddress
=
random
.
NextBytes
(
protocolAddressLength
).
AsReadOnly
(),
TargetHardwareAddress
=
random
.
NextBytes
(
hardwareAddressLength
).
AsReadOnly
(),
TargetProtocolAddress
=
random
.
NextBytes
(
protocolAddressLength
).
AsReadOnly
(),
ProtocolType
=
random
.
NextEnum
<
EthernetType
>(),
Operation
=
random
.
NextEnum
<
ArpOperation
>(),
};
}
}
}
\ No newline at end of file
PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomDnsExtensions.cs
0 → 100644
View file @
64ffbb1d
using
System
;
using
System.Collections.Generic
;
using
System.Text
;
using
PcapDotNet.Base
;
using
PcapDotNet.Packets.Dns
;
using
PcapDotNet.Packets.IpV4
;
using
PcapDotNet.TestUtils
;
namespace
PcapDotNet.Packets.TestUtils
{
public
static
class
RandomDnsExtensions
{
public
static
DnsLayer
NextDnsLayer
(
this
Random
random
)
{
DnsLayer
dnsLayer
=
new
DnsLayer
();
dnsLayer
.
Id
=
random
.
NextUShort
();
dnsLayer
.
IsQuery
=
random
.
NextBool
();
dnsLayer
.
Opcode
=
random
.
NextEnum
<
DnsOpcode
>();
dnsLayer
.
IsAuthoritiveAnswer
=
random
.
NextBool
();
dnsLayer
.
IsTruncated
=
random
.
NextBool
();
dnsLayer
.
IsRecusionDesired
=
random
.
NextBool
();
dnsLayer
.
IsRecusionAvailable
=
random
.
NextBool
();
dnsLayer
.
FutureUse
=
random
.
NextByte
(
DnsDatagram
.
MaxFutureUse
+
1
);
dnsLayer
.
ResponseCode
=
random
.
NextEnum
<
DnsResponseCode
>();
dnsLayer
.
DomainNameCompressionMode
=
random
.
NextEnum
<
DnsDomainNameCompressionMode
>();
int
numQueries
=
random
.
Next
(
10
);
List
<
DnsQueryResourceRecord
>
queries
=
new
List
<
DnsQueryResourceRecord
>();
for
(
int
i
=
0
;
i
!=
numQueries
;
++
i
)
queries
.
Add
(
random
.
NextDnsQueryResourceRecord
());
dnsLayer
.
Queries
=
queries
;
int
numAnswers
=
random
.
Next
(
10
);
List
<
DnsDataResourceRecord
>
answers
=
new
List
<
DnsDataResourceRecord
>();
for
(
int
i
=
0
;
i
!=
numAnswers
;
++
i
)
answers
.
Add
(
random
.
NextDnsDataResourceRecord
());
dnsLayer
.
Answers
=
answers
;
int
numAuthorities
=
random
.
Next
(
10
);
List
<
DnsDataResourceRecord
>
authorities
=
new
List
<
DnsDataResourceRecord
>();
for
(
int
i
=
0
;
i
!=
numAuthorities
;
++
i
)
authorities
.
Add
(
random
.
NextDnsDataResourceRecord
());
dnsLayer
.
Authorities
=
authorities
;
int
numAdditionals
=
random
.
Next
(
10
);
List
<
DnsDataResourceRecord
>
additionals
=
new
List
<
DnsDataResourceRecord
>();
for
(
int
i
=
0
;
i
!=
numAdditionals
;
++
i
)
additionals
.
Add
(
random
.
NextDnsDataResourceRecord
());
dnsLayer
.
Additionals
=
additionals
;
return
dnsLayer
;
}
public
static
DnsQueryResourceRecord
NextDnsQueryResourceRecord
(
this
Random
random
)
{
DnsQueryResourceRecord
record
=
new
DnsQueryResourceRecord
(
random
.
NextDnsDomainName
(),
random
.
NextEnum
<
DnsType
>(),
random
.
NextEnum
<
DnsClass
>());
return
record
;
}
public
static
DnsDataResourceRecord
NextDnsDataResourceRecord
(
this
Random
random
)
{
DnsType
type
=
random
.
NextEnum
<
DnsType
>();
DnsDataResourceRecord
record
=
new
DnsDataResourceRecord
(
random
.
NextDnsDomainName
(),
type
,
random
.
NextEnum
<
DnsClass
>(),
random
.
Next
(),
random
.
NextDnsResourceData
(
type
));
return
record
;
}
public
static
DnsDomainName
NextDnsDomainName
(
this
Random
random
)
{
List
<
string
>
labels
=
new
List
<
string
>();
int
numLabels
=
random
.
Next
(
10
);
for
(
int
i
=
0
;
i
!=
numLabels
;
++
i
)
{
int
labelLength
=
random
.
Next
(
10
);
StringBuilder
label
=
new
StringBuilder
();
for
(
int
j
=
0
;
j
!=
labelLength
;
++
j
)
label
.
Append
(
random
.
NextChar
(
'a'
,
'z'
));
labels
.
Add
(
label
.
ToString
());
}
return
new
DnsDomainName
(
string
.
Join
(
"."
,
labels
));
}
public
static
DnsResourceData
NextDnsResourceData
(
this
Random
random
,
DnsType
type
)
{
switch
(
type
)
{
case
DnsType
.
A
:
return
new
DnsResourceDataIpV4
(
random
.
NextIpV4Address
());
case
DnsType
.
Ns
:
case
DnsType
.
Md
:
case
DnsType
.
Mf
:
case
DnsType
.
CName
:
case
DnsType
.
Mb
:
case
DnsType
.
Mg
:
case
DnsType
.
Mr
:
case
DnsType
.
Ptr
:
return
new
DnsResourceDataDomainName
(
random
.
NextDnsDomainName
());
case
DnsType
.
Soa
:
return
new
DnsResourceDataStartOfAuthority
(
random
.
NextDnsDomainName
(),
random
.
NextDnsDomainName
(),
random
.
NextUInt
(),
random
.
NextUInt
(),
random
.
NextUInt
(),
random
.
NextUInt
(),
random
.
NextUInt
());
case
DnsType
.
Null
:
return
new
DnsResourceDataAnything
(
random
.
NextDataSegment
(
random
.
Next
(
65536
)));
case
DnsType
.
Wks
:
return
new
DnsResourceDataWellKnownService
(
random
.
NextIpV4Address
(),
random
.
NextEnum
<
IpV4Protocol
>(),
random
.
NextDataSegment
(
random
.
Next
(
10
)));
case
DnsType
.
HInfo
:
return
new
DnsResourceDataHostInformation
(
random
.
NextDataSegment
(
random
.
Next
(
10
)),
random
.
NextDataSegment
(
random
.
Next
(
10
)));
case
DnsType
.
MInfo
:
return
new
DnsResourceDataMailingListInfo
(
random
.
NextDnsDomainName
(),
random
.
NextDnsDomainName
());
case
DnsType
.
Mx
:
return
new
DnsResourceDataMailExchange
(
random
.
NextUShort
(),
random
.
NextDnsDomainName
());
case
DnsType
.
Txt
:
return
new
DnsResourceDataText
(((
Func
<
DataSegment
>)(()
=>
random
.
NextDataSegment
(
random
.
Next
(
10
)))).
GenerateArray
(
10
).
AsReadOnly
());
case
DnsType
.
Rp
:
return
new
DnsResourceDataResponsiblePerson
(
random
.
NextDnsDomainName
(),
random
.
NextDnsDomainName
());
case
DnsType
.
AfsDb
:
return
new
DnsResourceDataAfsDb
(
random
.
NextUShort
(),
random
.
NextDnsDomainName
());
default
:
return
new
DnsResourceDataAnything
(
random
.
NextDataSegment
(
random
.
Next
(
100
)));
}
}
}
}
PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomEthernetExtensions.cs
0 → 100644
View file @
64ffbb1d
using
System
;
using
PcapDotNet.Packets.Ethernet
;
using
PcapDotNet.TestUtils
;
namespace
PcapDotNet.Packets.TestUtils
{
public
static
class
RandomEthernetExtensions
{
public
static
EthernetLayer
NextEthernetLayer
(
this
Random
random
,
EthernetType
etherType
)
{
return
new
EthernetLayer
{
Source
=
random
.
NextMacAddress
(),
Destination
=
random
.
NextMacAddress
(),
EtherType
=
etherType
};
}
public
static
EthernetLayer
NextEthernetLayer
(
this
Random
random
)
{
return
random
.
NextEthernetLayer
(
random
.
NextEnum
(
EthernetType
.
None
));
}
public
static
MacAddress
NextMacAddress
(
this
Random
random
)
{
return
new
MacAddress
(
random
.
NextUInt48
());
}
public
static
EthernetType
NextEthernetType
(
this
Random
random
)
{
return
random
.
NextEnum
(
EthernetType
.
None
);
}
public
static
Packet
NextEthernetPacket
(
this
Random
random
,
int
packetSize
,
DateTime
timestamp
,
MacAddress
ethernetSource
,
MacAddress
ethernetDestination
)
{
if
(
packetSize
<
EthernetDatagram
.
HeaderLength
)
throw
new
ArgumentOutOfRangeException
(
"packetSize"
,
packetSize
,
"Must be at least the ethernet header length ("
+
EthernetDatagram
.
HeaderLength
+
")"
);
return
PacketBuilder
.
Build
(
timestamp
,
new
EthernetLayer
{
Source
=
ethernetSource
,
Destination
=
ethernetDestination
,
EtherType
=
random
.
NextEthernetType
()
},
random
.
NextPayloadLayer
(
packetSize
-
EthernetDatagram
.
HeaderLength
));
}
public
static
Packet
NextEthernetPacket
(
this
Random
random
,
int
packetSize
,
DateTime
timestamp
,
string
ethernetSource
,
string
ethernetDestination
)
{
return
random
.
NextEthernetPacket
(
packetSize
,
timestamp
,
new
MacAddress
(
ethernetSource
),
new
MacAddress
(
ethernetDestination
));
}
public
static
Packet
NextEthernetPacket
(
this
Random
random
,
int
packetSize
,
MacAddress
ethernetSource
,
MacAddress
ethernetDestination
)
{
return
random
.
NextEthernetPacket
(
packetSize
,
DateTime
.
Now
,
ethernetSource
,
ethernetDestination
);
}
public
static
Packet
NextEthernetPacket
(
this
Random
random
,
int
packetSize
,
string
ethernetSource
,
string
ethernetDestination
)
{
return
random
.
NextEthernetPacket
(
packetSize
,
DateTime
.
Now
,
ethernetSource
,
ethernetDestination
);
}
public
static
Packet
NextEthernetPacket
(
this
Random
random
,
int
packetSize
)
{
return
random
.
NextEthernetPacket
(
packetSize
,
DateTime
.
Now
,
random
.
NextMacAddress
(),
random
.
NextMacAddress
());
}
}
}
\ No newline at end of file
PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomGreExtensions.cs
0 → 100644
View file @
64ffbb1d
using
System
;
using
System.Linq
;
using
PcapDotNet.Base
;
using
PcapDotNet.Packets.Ethernet
;
using
PcapDotNet.Packets.Gre
;
using
PcapDotNet.Packets.IpV4
;
using
PcapDotNet.TestUtils
;
namespace
PcapDotNet.Packets.TestUtils
{
public
static
class
RandomGreExtensions
{
public
static
GreLayer
NextGreLayer
(
this
Random
random
)
{
GreVersion
version
=
random
.
NextEnum
<
GreVersion
>();
bool
isChecksum
=
random
.
NextBool
();
GreSourceRouteEntry
[]
routing
=
null
;
ushort
?
routingOffset
=
null
;
bool
strictSourceRoute
=
false
;
EthernetType
protocolType
=
random
.
NextEnum
(
EthernetType
.
None
);
uint
?
key
=
random
.
NextBool
()
?
(
uint
?)
random
.
NextUInt
()
:
null
;
if
(
version
==
GreVersion
.
Gre
)
{
if
(
random
.
NextBool
())
{
strictSourceRoute
=
random
.
NextBool
();
routing
=
new
GreSourceRouteEntry
[
random
.
Next
(
5
)];
GreSourceRouteEntryAddressFamily
family
;
if
(
random
.
NextBool
())
family
=
random
.
NextEnum
(
GreSourceRouteEntryAddressFamily
.
None
);
else
family
=
(
GreSourceRouteEntryAddressFamily
)
random
.
NextUShort
();
for
(
int
i
=
0
;
i
!=
routing
.
Length
;
++
i
)
{
switch
(
family
)
{
case
GreSourceRouteEntryAddressFamily
.
AsSourceRoute
:
{
ushort
[]
asNumbers
=
new
ushort
[
random
.
Next
(
1
,
5
)];
for
(
int
j
=
0
;
j
!=
asNumbers
.
Length
;
++
j
)
asNumbers
[
j
]
=
random
.
NextUShort
();
routing
[
i
]
=
new
GreSourceRouteEntryAs
(
asNumbers
.
AsReadOnly
(),
random
.
Next
(
asNumbers
.
Length
+
1
));
break
;
}
case
GreSourceRouteEntryAddressFamily
.
IpSourceRoute
:
{
IpV4Address
[]
ips
=
new
IpV4Address
[
random
.
Next
(
1
,
5
)];
for
(
int
j
=
0
;
j
!=
ips
.
Length
;
++
j
)
ips
[
j
]
=
random
.
NextIpV4Address
();
routing
[
i
]
=
new
GreSourceRouteEntryIp
(
ips
.
AsReadOnly
(),
random
.
Next
(
ips
.
Length
+
1
));
break
;
}
default
:
{
int
dataLength
=
random
.
Next
(
1
,
100
);
routing
[
i
]
=
new
GreSourceRouteEntryUnknown
(
family
,
random
.
NextDatagram
(
dataLength
),
random
.
Next
(
dataLength
+
1
));
break
;
}
}
}
routingOffset
=
0
;
if
(
routing
.
Any
())
{
int
routingIndex
=
random
.
Next
(
routing
.
Length
);
for
(
int
i
=
0
;
i
!=
routingIndex
;
++
i
)
routingOffset
+=
(
ushort
)
routing
[
i
].
Length
;
}
}
}
else
{
protocolType
=
EthernetType
.
PointToPointProtocol
;
isChecksum
=
false
;
key
=
random
.
NextUInt
();
}
return
new
GreLayer
{
Version
=
version
,
ProtocolType
=
protocolType
,
ChecksumPresent
=
isChecksum
,
Checksum
=
isChecksum
&&
random
.
NextBool
()
?
(
ushort
?)
random
.
NextUShort
()
:
null
,
Key
=
key
,
SequenceNumber
=
random
.
NextBool
()
?
(
uint
?)
random
.
NextUInt
()
:
null
,
AcknowledgmentSequenceNumber
=
version
==
GreVersion
.
EnhancedGre
&&
random
.
NextBool
()
?
(
uint
?)
random
.
NextUInt
()
:
null
,
RecursionControl
=
random
.
NextByte
(
8
),
// Flags = random.NextByte(32),
Routing
=
routing
==
null
?
null
:
routing
.
AsReadOnly
(),
RoutingOffset
=
routingOffset
,
StrictSourceRoute
=
strictSourceRoute
,
};
}
}
}
\ No newline at end of file
PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomHttpExtensions.cs
0 → 100644
View file @
64ffbb1d
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Text
;
using
PcapDotNet.Base
;
using
PcapDotNet.Packets.Http
;
using
PcapDotNet.TestUtils
;
namespace
PcapDotNet.Packets.TestUtils
{
public
static
class
RandomHttpExtensions
{
public
static
HttpLayer
NextHttpLayer
(
this
Random
random
)
{
if
(
random
.
NextBool
())
{
HttpRequestLayer
httpRequestLayer
=
new
HttpRequestLayer
();
if
(
random
.
NextBool
(
10
))
{
httpRequestLayer
.
Method
=
random
.
NextHttpRequestMethod
();
httpRequestLayer
.
Uri
=
httpRequestLayer
.
Method
==
null
?
null
:
random
.
NextHttpUri
();
httpRequestLayer
.
Version
=
httpRequestLayer
.
Uri
==
null
||
random
.
NextBool
(
10
)
?
null
:
random
.
NextHttpVersion
();
httpRequestLayer
.
Header
=
httpRequestLayer
.
Version
==
null
?
null
:
random
.
NextHttpHeader
();
httpRequestLayer
.
Body
=
httpRequestLayer
.
Header
==
null
?
null
:
random
.
NextHttpBody
(
true
,
null
,
httpRequestLayer
.
Header
);
}
return
httpRequestLayer
;
}
HttpResponseLayer
httpResponseLayer
=
new
HttpResponseLayer
{
Version
=
random
.
NextHttpVersion
(),
StatusCode
=
random
.
NextBool
(
10
)
?
null
:
(
uint
?)
random
.
NextUInt
(
100
,
999
),
};
httpResponseLayer
.
ReasonPhrase
=
httpResponseLayer
.
StatusCode
==
null
?
null
:
random
.
NextHttpReasonPhrase
();
httpResponseLayer
.
Header
=
httpResponseLayer
.
ReasonPhrase
==
null
?
null
:
random
.
NextHttpHeader
();
httpResponseLayer
.
Body
=
httpResponseLayer
.
Header
==
null
?
null
:
random
.
NextHttpBody
(
false
,
httpResponseLayer
.
StatusCode
,
httpResponseLayer
.
Header
);
return
httpResponseLayer
;
}
public
static
Datagram
NextHttpReasonPhrase
(
this
Random
random
)
{
int
reasonPhraseLength
=
random
.
Next
(
100
);
StringBuilder
reasonPhrase
=
new
StringBuilder
(
reasonPhraseLength
);
for
(
int
i
=
0
;
i
!=
reasonPhraseLength
;
++
i
)
{
if
(
random
.
NextBool
())
reasonPhrase
.
Append
(
random
.
NextHttpTextChar
());
else
if
(
random
.
NextBool
())
reasonPhrase
.
Append
(
' '
);
else
reasonPhrase
.
Append
(
'\t'
);
}
return
new
Datagram
(
EncodingExtensions
.
Iso88591
.
GetBytes
(
reasonPhrase
.
ToString
()));
}
public
static
HttpRequestMethod
NextHttpRequestMethod
(
this
Random
random
)
{
HttpRequestKnownMethod
knownMethod
=
random
.
NextEnum
<
HttpRequestKnownMethod
>();
if
(
knownMethod
==
HttpRequestKnownMethod
.
Unknown
)
return
new
HttpRequestMethod
(
random
.
NextHttpToken
());
return
new
HttpRequestMethod
(
knownMethod
);
}
public
static
string
NextHttpToken
(
this
Random
random
)
{
int
tokenLength
=
random
.
Next
(
1
,
100
);
StringBuilder
stringBuilder
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
!=
tokenLength
;
++
i
)
stringBuilder
.
Append
(
random
.
NextHttpTokenChar
());
return
stringBuilder
.
ToString
();
}
public
static
char
NextHttpTokenChar
(
this
Random
random
)
{
char
result
;
do
{
result
=
random
.
NextChar
((
char
)
33
,
(
char
)
127
);
}
while
(
new
[]
{
'('
,
')'
,
'<'
,
'>'
,
'@'
,
','
,
';'
,
':'
,
'\\'
,
'"'
,
'/'
,
'['
,
']'
,
'?'
,
'='
,
'{'
,
'}'
}.
Contains
(
result
));
return
result
;
}
public
static
string
NextHttpFieldValue
(
this
Random
random
)
{
int
valueLength
=
random
.
Next
(
1
,
100
);
StringBuilder
stringBuilder
=
new
StringBuilder
();
while
(
stringBuilder
.
Length
<
valueLength
)
{
switch
(
random
.
Next
(
3
))
{
case
0
:
stringBuilder
.
Append
(
random
.
NextHttpTextChar
());
break
;
case
1
:
stringBuilder
.
Append
(
random
.
NextHttpQuotedString
());
break
;
case
2
:
if
(
stringBuilder
.
Length
>
0
&&
stringBuilder
.
Length
<
valueLength
-
3
)
stringBuilder
.
Append
(
random
.
NextHttpLinearWhiteSpace
());
break
;
}
}
return
stringBuilder
.
ToString
();
}
public
static
string
NextHttpLinearWhiteSpace
(
this
Random
random
)
{
StringBuilder
stringBuilder
=
new
StringBuilder
();
if
(
random
.
NextBool
())
stringBuilder
.
Append
(
"\r\n"
);
stringBuilder
.
Append
(
random
.
NextBool
()
?
' '
:
'\t'
);
return
stringBuilder
.
ToString
();
}
public
static
char
NextHttpTextChar
(
this
Random
random
)
{
char
text
=
random
.
NextChar
((
char
)
33
,
(
char
)
254
);
if
(
text
==
'"'
)
return
(
char
)
254
;
if
(
text
==
127
)
return
(
char
)
255
;
return
text
;
}
public
static
string
NextHttpUri
(
this
Random
random
)
{
int
uriLength
=
random
.
Next
(
100
);
StringBuilder
stringBuilder
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
!=
uriLength
;
++
i
)
stringBuilder
.
Append
(
random
.
NextChar
((
char
)
33
,
(
char
)
127
));
return
stringBuilder
.
ToString
();
}
public
static
HttpVersion
NextHttpVersion
(
this
Random
random
)
{
return
new
HttpVersion
(
random
.
NextUInt
(
10000000
),
random
.
NextUInt
(
10000000
));
}
public
static
HttpHeader
NextHttpHeader
(
this
Random
random
)
{
int
numFields
=
random
.
Next
(
100
);
List
<
HttpField
>
fields
=
new
List
<
HttpField
>(
numFields
);
HashSet
<
string
>
fieldNames
=
new
HashSet
<
string
>(
StringComparer
.
InvariantCultureIgnoreCase
);
for
(
int
i
=
0
;
i
!=
numFields
;
++
i
)
{
fields
.
Add
(
random
.
NextHttpField
(
fieldNames
));
fieldNames
.
Add
(
fields
.
Last
().
Name
);
}
return
new
HttpHeader
(
fields
);
}
public
static
HttpField
NextHttpField
(
this
Random
random
,
HashSet
<
string
>
fieldNames
)
{
const
string
unknownField
=
"Unknown Name"
;
List
<
string
>
allOptions
=
new
List
<
string
>
{
unknownField
,
HttpTransferEncodingField
.
FieldNameUpper
,
HttpContentLengthField
.
FieldNameUpper
,
HttpContentTypeField
.
FieldNameUpper
};
List
<
string
>
possibleOptions
=
new
List
<
string
>(
allOptions
.
Count
);
foreach
(
string
option
in
allOptions
)
{
if
(!
fieldNames
.
Contains
(
option
))
possibleOptions
.
Add
(
option
);
}
string
chosenOption
=
random
.
NextValue
(
possibleOptions
);
switch
(
chosenOption
)
{
case
unknownField
:
string
fieldName
;
do
{
fieldName
=
random
.
NextHttpToken
();
}
while
(
fieldNames
.
Contains
(
fieldName
));
return
HttpField
.
CreateField
(
fieldName
,
random
.
NextHttpFieldValue
());
case
HttpTransferEncodingField
.
FieldNameUpper
:
int
numTransferCodings
=
random
.
Next
(
1
,
10
);
List
<
string
>
transferCodings
=
new
List
<
string
>(
numTransferCodings
);
for
(
int
i
=
0
;
i
!=
numTransferCodings
;
++
i
)
transferCodings
.
Add
(
random
.
NextHttpTransferCoding
());
return
new
HttpTransferEncodingField
(
transferCodings
);
case
HttpContentLengthField
.
FieldNameUpper
:
return
new
HttpContentLengthField
(
random
.
NextUInt
(
1000
));
case
HttpContentTypeField
.
FieldNameUpper
:
return
new
HttpContentTypeField
(
random
.
NextHttpToken
(),
random
.
NextHttpToken
(),
random
.
NextHttpFieldParameters
());
default
:
throw
new
InvalidOperationException
(
"Invalid option "
+
chosenOption
);
}
}
public
static
HttpFieldParameters
NextHttpFieldParameters
(
this
Random
random
)
{
int
numParameters
=
random
.
Next
(
10
);
List
<
KeyValuePair
<
string
,
string
>>
parameters
=
new
List
<
KeyValuePair
<
string
,
string
>>(
numParameters
);
for
(
int
i
=
0
;
i
!=
numParameters
;
++
i
)
{
string
parameterName
=
random
.
NextHttpToken
();
while
(
parameters
.
Any
(
pair
=>
pair
.
Key
==
parameterName
))
parameterName
=
random
.
NextHttpToken
();
parameters
.
Add
(
new
KeyValuePair
<
string
,
string
>(
parameterName
,
random
.
NextBool
()
?
random
.
NextHttpToken
()
:
random
.
NextHttpQuotedString
()));
}
return
new
HttpFieldParameters
(
parameters
);
}
public
static
string
NextHttpTransferCoding
(
this
Random
random
)
{
if
(
random
.
NextBool
())
return
"chunked"
;
StringBuilder
transferCoding
=
new
StringBuilder
(
random
.
NextHttpToken
());
int
numParameters
=
random
.
Next
(
5
);
for
(
int
i
=
0
;
i
!=
numParameters
;
++
i
)
{
transferCoding
.
Append
(
';'
);
transferCoding
.
Append
(
random
.
NextHttpToken
());
transferCoding
.
Append
(
'='
);
if
(
random
.
NextBool
())
transferCoding
.
Append
(
random
.
NextHttpToken
());
else
transferCoding
.
Append
(
random
.
NextHttpQuotedString
());
}
return
transferCoding
.
ToString
();
}
public
static
string
NextHttpQuotedString
(
this
Random
random
)
{
StringBuilder
quotedString
=
new
StringBuilder
();
quotedString
.
Append
(
'"'
);
int
numQuotedValues
=
random
.
Next
(
100
);
for
(
int
i
=
0
;
i
!=
numQuotedValues
;
++
i
)
{
char
quotedValue
=
random
.
NextHttpTextChar
();
if
(
quotedValue
!=
'\\'
)
quotedString
.
Append
(
quotedValue
);
else
{
quotedString
.
Append
(
'\\'
);
quotedString
.
Append
(
random
.
NextChar
((
char
)
0
,
(
char
)
128
));
}
}
quotedString
.
Append
(
'"'
);
return
quotedString
.
ToString
();
}
public
static
Datagram
NextHttpBody
(
this
Random
random
,
bool
isRequest
,
uint
?
statusCode
,
HttpHeader
httpHeader
)
{
if
(
isRequest
&&
httpHeader
.
ContentLength
==
null
||
!
isRequest
&&
statusCode
>=
100
&&
statusCode
<=
199
||
statusCode
==
204
||
statusCode
==
205
||
statusCode
==
304
)
return
Datagram
.
Empty
;
if
(
httpHeader
.
TransferEncoding
!=
null
&&
httpHeader
.
TransferEncoding
.
TransferCodings
.
Any
(
coding
=>
coding
!=
"identity"
))
{
// chunked
List
<
byte
>
chunkedBody
=
new
List
<
byte
>();
int
numChunks
=
random
.
Next
(
10
);
for
(
int
i
=
0
;
i
!=
numChunks
;
++
i
)
{
int
chunkSize
=
random
.
Next
(
1
,
1000
);
chunkedBody
.
AddRange
(
Encoding
.
ASCII
.
GetBytes
(
chunkSize
.
ToString
(
"x"
)));
var
chunkExtension
=
random
.
NextHttpFieldParameters
();
foreach
(
var
parameter
in
chunkExtension
)
{
chunkedBody
.
Add
((
byte
)
';'
);
chunkedBody
.
AddRange
(
Encoding
.
ASCII
.
GetBytes
(
parameter
.
Key
));
chunkedBody
.
Add
((
byte
)
'='
);
chunkedBody
.
AddRange
(
EncodingExtensions
.
Iso88591
.
GetBytes
(
parameter
.
Key
));
}
chunkedBody
.
AddRange
(
Encoding
.
ASCII
.
GetBytes
(
"\r\n"
));
chunkedBody
.
AddRange
(
random
.
NextDatagram
(
chunkSize
));
chunkedBody
.
AddRange
(
Encoding
.
ASCII
.
GetBytes
(
"\r\n"
));
}
int
numZeros
=
random
.
Next
(
1
,
10
);
for
(
int
i
=
0
;
i
!=
numZeros
;
++
i
)
chunkedBody
.
Add
((
byte
)
'0'
);
var
lastChunkExtension
=
random
.
NextHttpFieldParameters
();
foreach
(
var
parameter
in
lastChunkExtension
)
{
chunkedBody
.
Add
((
byte
)
';'
);
chunkedBody
.
AddRange
(
Encoding
.
ASCII
.
GetBytes
(
parameter
.
Key
));
chunkedBody
.
Add
((
byte
)
'='
);
chunkedBody
.
AddRange
(
EncodingExtensions
.
Iso88591
.
GetBytes
(
parameter
.
Key
));
}
chunkedBody
.
AddRange
(
Encoding
.
ASCII
.
GetBytes
(
"\r\n"
));
var
trailer
=
random
.
NextHttpHeader
();
byte
[]
trailerBuffer
=
new
byte
[
trailer
.
BytesLength
];
trailer
.
Write
(
trailerBuffer
,
0
);
chunkedBody
.
AddRange
(
trailerBuffer
);
return
new
Datagram
(
chunkedBody
.
ToArray
());
}
if
(
httpHeader
.
ContentLength
!=
null
)
{
return
random
.
NextDatagram
(
random
.
Next
((
int
)(
httpHeader
.
ContentLength
.
ContentLength
+
1
)));
}
if
(
httpHeader
.
ContentType
!=
null
&&
httpHeader
.
ContentType
.
MediaType
==
"multipart"
&&
httpHeader
.
ContentType
.
MediaSubtype
==
"byteranges"
&&
httpHeader
.
ContentType
.
Parameters
[
"boundary"
]
!=
null
)
{
List
<
byte
>
boundedBody
=
new
List
<
byte
>(
random
.
NextDatagram
(
random
.
Next
(
1000
)));
boundedBody
.
AddRange
(
EncodingExtensions
.
Iso88591
.
GetBytes
(
"--"
+
httpHeader
.
ContentType
.
Parameters
[
"boundary"
]
+
"--"
));
return
new
Datagram
(
boundedBody
.
ToArray
());
}
return
random
.
NextDatagram
(
random
.
Next
(
1000
));
}
}
}
\ No newline at end of file
PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomIcmpExtensions.cs
0 → 100644
View file @
64ffbb1d
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
PcapDotNet.Packets.Icmp
;
using
PcapDotNet.Packets.IpV4
;
using
PcapDotNet.TestUtils
;
using
IEnumerableExtensions
=
PcapDotNet
.
Base
.
IEnumerableExtensions
;
namespace
PcapDotNet.Packets.TestUtils
{
public
static
class
RandomIcmpExtensions
{
public
static
IcmpLayer
NextIcmpLayer
(
this
Random
random
)
{
IcmpMessageType
icmpMessageType
=
random
.
NextEnum
(
IcmpMessageType
.
DomainNameReply
);
ushort
?
checksum
=
random
.
NextBool
()
?
(
ushort
?)
random
.
NextUShort
()
:
null
;
switch
(
icmpMessageType
)
{
case
IcmpMessageType
.
DestinationUnreachable
:
return
new
IcmpDestinationUnreachableLayer
{
Code
=
random
.
NextEnum
<
IcmpCodeDestinationUnreachable
>(),
Checksum
=
checksum
,
NextHopMaximumTransmissionUnit
=
random
.
NextUShort
(),
};
case
IcmpMessageType
.
TimeExceeded
:
return
new
IcmpTimeExceededLayer
{
Code
=
random
.
NextEnum
<
IcmpCodeTimeExceeded
>(),
Checksum
=
checksum
,
};
case
IcmpMessageType
.
ParameterProblem
:
return
new
IcmpParameterProblemLayer
{
Checksum
=
checksum
,
Pointer
=
random
.
NextByte
()
};
case
IcmpMessageType
.
SourceQuench
:
return
new
IcmpSourceQuenchLayer
{
Checksum
=
checksum
};
case
IcmpMessageType
.
Redirect
:
return
new
IcmpRedirectLayer
{
Code
=
random
.
NextEnum
<
IcmpCodeRedirect
>(),
Checksum
=
checksum
,
GatewayInternetAddress
=
random
.
NextIpV4Address
()
};
case
IcmpMessageType
.
Echo
:
return
new
IcmpEchoLayer
{
Checksum
=
checksum
,
Identifier
=
random
.
NextUShort
(),
SequenceNumber
=
random
.
NextUShort
()
};
case
IcmpMessageType
.
EchoReply
:
return
new
IcmpEchoReplyLayer
{
Checksum
=
checksum
,
Identifier
=
random
.
NextUShort
(),
SequenceNumber
=
random
.
NextUShort
()
};
case
IcmpMessageType
.
Timestamp
:
return
new
IcmpTimestampLayer
{
Checksum
=
checksum
,
Identifier
=
random
.
NextUShort
(),
SequenceNumber
=
random
.
NextUShort
(),
OriginateTimestamp
=
random
.
NextIpV4TimeOfDay
(),
ReceiveTimestamp
=
random
.
NextIpV4TimeOfDay
(),
TransmitTimestamp
=
random
.
NextIpV4TimeOfDay
()
};
case
IcmpMessageType
.
TimestampReply
:
return
new
IcmpTimestampReplyLayer
{
Checksum
=
checksum
,
Identifier
=
random
.
NextUShort
(),
SequenceNumber
=
random
.
NextUShort
(),
OriginateTimestamp
=
random
.
NextIpV4TimeOfDay
(),
ReceiveTimestamp
=
random
.
NextIpV4TimeOfDay
(),
TransmitTimestamp
=
random
.
NextIpV4TimeOfDay
()
};
case
IcmpMessageType
.
InformationRequest
:
return
new
IcmpInformationRequestLayer
{
Checksum
=
checksum
,
Identifier
=
random
.
NextUShort
(),
SequenceNumber
=
random
.
NextUShort
(),
};
case
IcmpMessageType
.
InformationReply
:
return
new
IcmpInformationReplyLayer
{
Checksum
=
checksum
,
Identifier
=
random
.
NextUShort
(),
SequenceNumber
=
random
.
NextUShort
(),
};
case
IcmpMessageType
.
RouterAdvertisement
:
return
new
IcmpRouterAdvertisementLayer
{
Entries
=
random
.
NextIcmpRouterAdvertisementEntries
(
random
.
Next
(
10
)).
ToList
().
AsReadOnly
(),
Checksum
=
checksum
,
Lifetime
=
random
.
NextTimeSpan
(
TimeSpan
.
Zero
,
TimeSpan
.
FromSeconds
(
ushort
.
MaxValue
)),
};
case
IcmpMessageType
.
RouterSolicitation
:
return
new
IcmpRouterSolicitationLayer
{
Checksum
=
checksum
,
};
case
IcmpMessageType
.
AddressMaskRequest
:
return
new
IcmpAddressMaskRequestLayer
{
Checksum
=
checksum
,
Identifier
=
random
.
NextUShort
(),
SequenceNumber
=
random
.
NextUShort
(),
AddressMask
=
random
.
NextIpV4Address
()
};
case
IcmpMessageType
.
AddressMaskReply
:
return
new
IcmpAddressMaskReplyLayer
{
Checksum
=
checksum
,
Identifier
=
random
.
NextUShort
(),
SequenceNumber
=
random
.
NextUShort
(),
AddressMask
=
random
.
NextIpV4Address
()
};
case
IcmpMessageType
.
TraceRoute
:
return
new
IcmpTraceRouteLayer
{
Code
=
random
.
NextEnum
<
IcmpCodeTraceRoute
>(),
Checksum
=
checksum
,
Identification
=
random
.
NextUShort
(),
OutboundHopCount
=
random
.
NextUShort
(),
ReturnHopCount
=
random
.
NextUShort
(),
OutputLinkSpeed
=
random
.
NextUInt
(),
OutputLinkMaximumTransmissionUnit
=
random
.
NextUInt
(),
};
case
IcmpMessageType
.
ConversionFailed
:
return
new
IcmpConversionFailedLayer
{
Code
=
random
.
NextEnum
<
IcmpCodeConversionFailed
>(),
Checksum
=
checksum
,
Pointer
=
random
.
NextUInt
(),
};
case
IcmpMessageType
.
DomainNameRequest
:
return
new
IcmpDomainNameRequestLayer
{
Checksum
=
checksum
,
Identifier
=
random
.
NextUShort
(),
SequenceNumber
=
random
.
NextUShort
(),
};
case
IcmpMessageType
.
DomainNameReply
:
throw
new
NotSupportedException
(
"Message Type "
+
icmpMessageType
+
" is not supported"
);
case
IcmpMessageType
.
SecurityFailures
:
return
new
IcmpSecurityFailuresLayer
{
Code
=
random
.
NextEnum
<
IcmpCodeSecurityFailure
>(),
Checksum
=
checksum
,
Pointer
=
random
.
NextUShort
()
};
default
:
throw
new
InvalidOperationException
(
"Invalid icmpMessageType "
+
icmpMessageType
);
}
}
public
static
IEnumerable
<
ILayer
>
NextIcmpPayloadLayers
(
this
Random
random
,
IcmpLayer
icmpLayer
)
{
IEnumerable
<
ILayer
>
icmpPayloadLayers
=
new
List
<
ILayer
>();
switch
(
icmpLayer
.
MessageType
)
{
case
IcmpMessageType
.
DestinationUnreachable
:
case
IcmpMessageType
.
TimeExceeded
:
case
IcmpMessageType
.
ParameterProblem
:
case
IcmpMessageType
.
SourceQuench
:
case
IcmpMessageType
.
Redirect
:
case
IcmpMessageType
.
SecurityFailures
:
icmpPayloadLayers
=
IEnumerableExtensions
.
Concat
(
icmpPayloadLayers
,
random
.
NextIpV4Layer
(),
random
.
NextPayloadLayer
(
IcmpIpV4HeaderPlus64BitsPayloadDatagram
.
OriginalDatagramPayloadLength
));
break
;
case
IcmpMessageType
.
ConversionFailed
:
IpV4Layer
icmpIpV4Layer
=
random
.
NextIpV4Layer
();
icmpPayloadLayers
=
IEnumerableExtensions
.
Concat
(
icmpPayloadLayers
,
icmpIpV4Layer
);
if
(
icmpLayer
.
MessageTypeAndCode
==
IcmpMessageTypeAndCode
.
ConversionFailedUnsupportedTransportProtocol
)
{
icmpPayloadLayers
=
IEnumerableExtensions
.
Concat
(
icmpPayloadLayers
,
random
.
NextPayloadLayer
(
IcmpConversionFailedDatagram
.
OriginalDatagramLengthForUnsupportedTransportProtocol
-
icmpIpV4Layer
.
Length
));
}
else
{
switch
(
icmpIpV4Layer
.
Protocol
)
{
case
IpV4Protocol
.
Udp
:
icmpPayloadLayers
=
IEnumerableExtensions
.
Concat
(
icmpPayloadLayers
,
random
.
NextUdpLayer
(),
random
.
NextPayloadLayer
(
random
.
Next
(
100
)));
break
;
case
IpV4Protocol
.
Tcp
:
icmpPayloadLayers
=
IEnumerableExtensions
.
Concat
(
icmpPayloadLayers
,
random
.
NextTcpLayer
(),
random
.
NextPayloadLayer
(
random
.
Next
(
100
)));
break
;
default
:
icmpPayloadLayers
=
IEnumerableExtensions
.
Concat
(
icmpPayloadLayers
,
random
.
NextPayloadLayer
(
random
.
Next
(
200
)));
break
;
}
}
break
;
case
IcmpMessageType
.
Echo
:
case
IcmpMessageType
.
EchoReply
:
case
IcmpMessageType
.
Timestamp
:
case
IcmpMessageType
.
TimestampReply
:
case
IcmpMessageType
.
InformationRequest
:
case
IcmpMessageType
.
InformationReply
:
case
IcmpMessageType
.
RouterAdvertisement
:
case
IcmpMessageType
.
RouterSolicitation
:
case
IcmpMessageType
.
AddressMaskRequest
:
case
IcmpMessageType
.
AddressMaskReply
:
case
IcmpMessageType
.
TraceRoute
:
case
IcmpMessageType
.
DomainNameRequest
:
break
;
case
IcmpMessageType
.
DomainNameReply
:
default
:
throw
new
InvalidOperationException
(
"Invalid icmpMessageType "
+
icmpLayer
.
MessageType
);
}
return
icmpPayloadLayers
;
}
public
static
IEnumerable
<
IcmpRouterAdvertisementEntry
>
NextIcmpRouterAdvertisementEntries
(
this
Random
random
,
int
numEntries
)
{
for
(
int
i
=
0
;
i
!=
numEntries
;
++
i
)
yield
return
new
IcmpRouterAdvertisementEntry
(
random
.
NextIpV4Address
(),
random
.
Next
());
}
}
}
\ No newline at end of file
PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomIgmpExtensions.cs
0 → 100644
View file @
64ffbb1d
using
System
;
using
System.Linq
;
using
PcapDotNet.Base
;
using
PcapDotNet.Packets.Igmp
;
using
PcapDotNet.Packets.IpV4
;
using
PcapDotNet.TestUtils
;
namespace
PcapDotNet.Packets.TestUtils
{
public
static
class
RandomIgmpExtensions
{
public
static
IgmpGroupRecord
NextIgmpGroupRecord
(
this
Random
random
)
{
IpV4Address
[]
sourceAddresses
=
random
.
NextIpV4Addresses
(
random
.
Next
(
10
));
return
new
IgmpGroupRecord
(
random
.
NextEnum
<
IgmpRecordType
>(),
random
.
NextIpV4Address
(),
sourceAddresses
,
random
.
NextDatagram
(
random
.
Next
(
10
)
*
4
));
}
public
static
IgmpGroupRecord
[]
NextIgmpGroupRecords
(
this
Random
random
,
int
count
)
{
return
((
Func
<
IgmpGroupRecord
>)
random
.
NextIgmpGroupRecord
).
GenerateArray
(
count
);
}
public
static
IgmpLayer
NextIgmpLayer
(
this
Random
random
)
{
IgmpMessageType
igmpMessageType
=
random
.
NextEnum
(
IgmpMessageType
.
None
,
IgmpMessageType
.
CreateGroupRequestVersion0
,
IgmpMessageType
.
CreateGroupReplyVersion0
,
IgmpMessageType
.
JoinGroupRequestVersion0
,
IgmpMessageType
.
JoinGroupReplyVersion0
,
IgmpMessageType
.
LeaveGroupRequestVersion0
,
IgmpMessageType
.
LeaveGroupReplyVersion0
,
IgmpMessageType
.
ConfirmGroupRequestVersion0
,
IgmpMessageType
.
ConfirmGroupReplyVersion0
,
IgmpMessageType
.
MulticastTraceRouteResponse
);
// todo support IGMP traceroute http://www.ietf.org/proceedings/48/I-D/idmr-traceroute-ipm-07.txt.
IgmpQueryVersion
igmpQueryVersion
=
IgmpQueryVersion
.
None
;
TimeSpan
igmpMaxResponseTime
=
random
.
NextTimeSpan
(
TimeSpan
.
FromSeconds
(
0.1
),
TimeSpan
.
FromSeconds
(
256
*
0.1
)
-
TimeSpan
.
FromTicks
(
1
));
IpV4Address
igmpGroupAddress
=
random
.
NextIpV4Address
();
bool
?
igmpIsSuppressRouterSideProcessing
;
byte
?
igmpQueryRobustnessVariable
;
TimeSpan
?
igmpQueryInterval
;
IpV4Address
[]
igmpSourceAddresses
;
IgmpGroupRecord
[]
igmpGroupRecords
;
switch
(
igmpMessageType
)
{
case
IgmpMessageType
.
MembershipQuery
:
igmpQueryVersion
=
random
.
NextEnum
(
IgmpQueryVersion
.
None
,
IgmpQueryVersion
.
Unknown
);
switch
(
igmpQueryVersion
)
{
case
IgmpQueryVersion
.
Version1
:
return
new
IgmpQueryVersion1Layer
{
GroupAddress
=
igmpGroupAddress
};
case
IgmpQueryVersion
.
Version2
:
return
new
IgmpQueryVersion2Layer
{
MaxResponseTime
=
igmpMaxResponseTime
,
GroupAddress
=
igmpGroupAddress
};
case
IgmpQueryVersion
.
Version3
:
igmpIsSuppressRouterSideProcessing
=
random
.
NextBool
();
igmpQueryRobustnessVariable
=
random
.
NextByte
(
8
);
igmpMaxResponseTime
=
random
.
NextTimeSpan
(
TimeSpan
.
FromSeconds
(
0.1
),
IgmpDatagram
.
MaxVersion3MaxResponseTime
-
TimeSpan
.
FromTicks
(
1
));
igmpQueryInterval
=
random
.
NextTimeSpan
(
TimeSpan
.
Zero
,
IgmpDatagram
.
MaxQueryInterval
-
TimeSpan
.
FromTicks
(
1
));
igmpSourceAddresses
=
random
.
NextIpV4Addresses
(
random
.
Next
(
1000
));
return
new
IgmpQueryVersion3Layer
{
SourceAddresses
=
igmpSourceAddresses
.
AsReadOnly
(),
MaxResponseTime
=
igmpMaxResponseTime
,
GroupAddress
=
igmpGroupAddress
,
IsSuppressRouterSideProcessing
=
igmpIsSuppressRouterSideProcessing
.
Value
,
QueryRobustnessVariable
=
igmpQueryRobustnessVariable
.
Value
,
QueryInterval
=
igmpQueryInterval
.
Value
,
};
default
:
throw
new
InvalidOperationException
(
"Invalid Query Version "
+
igmpQueryVersion
);
}
case
IgmpMessageType
.
MembershipReportVersion1
:
return
new
IgmpReportVersion1Layer
{
GroupAddress
=
igmpGroupAddress
};
case
IgmpMessageType
.
MembershipReportVersion2
:
return
new
IgmpReportVersion2Layer
{
MaxResponseTime
=
igmpMaxResponseTime
,
GroupAddress
=
igmpGroupAddress
};
case
IgmpMessageType
.
LeaveGroupVersion2
:
return
new
IgmpLeaveGroupVersion2Layer
{
MaxResponseTime
=
igmpMaxResponseTime
,
GroupAddress
=
igmpGroupAddress
};
case
IgmpMessageType
.
MembershipReportVersion3
:
igmpGroupRecords
=
random
.
NextIgmpGroupRecords
(
random
.
Next
(
100
));
if
(
igmpGroupRecords
.
Count
()
==
0
&&
random
.
NextBool
())
return
new
IgmpReportVersion3Layer
();
return
new
IgmpReportVersion3Layer
{
GroupRecords
=
igmpGroupRecords
.
AsReadOnly
()
};
default
:
throw
new
InvalidOperationException
(
"Invalid message type "
+
igmpMessageType
);
}
}
}
}
\ No newline at end of file
PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomIpV4Extensions.cs
0 → 100644
View file @
64ffbb1d
using
System
;
using
System.Collections.Generic
;
using
PcapDotNet.Base
;
using
PcapDotNet.Packets.IpV4
;
using
PcapDotNet.TestUtils
;
namespace
PcapDotNet.Packets.TestUtils
{
public
static
class
RandomIpV4Extensions
{
public
static
IpV4Layer
NextIpV4Layer
(
this
Random
random
,
IpV4Protocol
?
protocol
)
{
return
new
IpV4Layer
{
TypeOfService
=
random
.
NextByte
(),
Identification
=
random
.
NextUShort
(),
Ttl
=
random
.
NextByte
(),
Protocol
=
protocol
,
HeaderChecksum
=
random
.
NextBool
()
?
(
ushort
?)
random
.
NextUShort
()
:
null
,
Fragmentation
=
random
.
NextBool
()
?
random
.
NextIpV4Fragmentation
()
:
IpV4Fragmentation
.
None
,
Source
=
random
.
NextIpV4Address
(),
Destination
=
random
.
NextIpV4Address
(),
Options
=
random
.
NextIpV4Options
()
};
}
public
static
IpV4Layer
NextIpV4Layer
(
this
Random
random
)
{
return
random
.
NextIpV4Layer
(
random
.
NextEnum
<
IpV4Protocol
>());
}
public
static
IpV4Address
NextIpV4Address
(
this
Random
random
)
{
return
new
IpV4Address
(
random
.
NextUInt
());
}
public
static
IpV4Address
[]
NextIpV4Addresses
(
this
Random
random
,
int
count
)
{
return
((
Func
<
IpV4Address
>)
random
.
NextIpV4Address
).
GenerateArray
(
count
);
}
public
static
IpV4Fragmentation
NextIpV4Fragmentation
(
this
Random
random
)
{
IpV4FragmentationOptions
ipV4FragmentationFlags
=
random
.
NextEnum
<
IpV4FragmentationOptions
>();
ushort
ipV4FragmentationOffset
=
(
ushort
)(
random
.
NextUShort
()
/
8
*
8
);
return
new
IpV4Fragmentation
(
ipV4FragmentationFlags
,
ipV4FragmentationOffset
);
}
public
static
IpV4TimeOfDay
NextIpV4TimeOfDay
(
this
Random
random
)
{
return
new
IpV4TimeOfDay
(
random
.
NextUInt
());
}
public
static
IpV4OptionUnknown
NextIpV4OptionUnknown
(
this
Random
random
,
int
maximumOptionLength
)
{
IpV4OptionType
unknownOptionType
;
byte
unknownOptionTypeValue
;
do
{
unknownOptionTypeValue
=
random
.
NextByte
();
unknownOptionType
=
(
IpV4OptionType
)
unknownOptionTypeValue
;
}
while
(
unknownOptionType
.
ToString
()
!=
unknownOptionTypeValue
.
ToString
());
Byte
[]
unknownOptionData
=
new
byte
[
random
.
Next
(
maximumOptionLength
-
IpV4OptionUnknown
.
OptionMinimumLength
+
1
)];
random
.
NextBytes
(
unknownOptionData
);
return
new
IpV4OptionUnknown
(
unknownOptionType
,
unknownOptionData
);
}
public
static
IpV4Option
NextIpV4Option
(
this
Random
random
,
int
maximumOptionLength
)
{
if
(
maximumOptionLength
==
0
)
throw
new
ArgumentOutOfRangeException
(
"maximumOptionLength"
,
maximumOptionLength
,
"option length must be positive"
);
if
(
maximumOptionLength
>=
IpV4OptionUnknown
.
OptionMinimumLength
&&
random
.
Next
(
100
)
>
90
)
return
random
.
NextIpV4OptionUnknown
(
maximumOptionLength
);
List
<
IpV4OptionType
>
impossibleOptionTypes
=
new
List
<
IpV4OptionType
>();
if
(
maximumOptionLength
<
IpV4OptionBasicSecurity
.
OptionMinimumLength
)
impossibleOptionTypes
.
Add
(
IpV4OptionType
.
BasicSecurity
);
if
(
maximumOptionLength
<
IpV4OptionRoute
.
OptionMinimumLength
)
{
impossibleOptionTypes
.
Add
(
IpV4OptionType
.
LooseSourceRouting
);
impossibleOptionTypes
.
Add
(
IpV4OptionType
.
StrictSourceRouting
);
impossibleOptionTypes
.
Add
(
IpV4OptionType
.
RecordRoute
);
}
if
(
maximumOptionLength
<
IpV4OptionStreamIdentifier
.
OptionLength
)
impossibleOptionTypes
.
Add
(
IpV4OptionType
.
StreamIdentifier
);
if
(
maximumOptionLength
<
IpV4OptionTimestamp
.
OptionMinimumLength
)
impossibleOptionTypes
.
Add
(
IpV4OptionType
.
InternetTimestamp
);
if
(
maximumOptionLength
<
IpV4OptionTraceRoute
.
OptionLength
)
impossibleOptionTypes
.
Add
(
IpV4OptionType
.
TraceRoute
);
if
(
maximumOptionLength
<
IpV4OptionQuickStart
.
OptionLength
)
impossibleOptionTypes
.
Add
(
IpV4OptionType
.
QuickStart
);
IpV4OptionType
optionType
=
random
.
NextEnum
<
IpV4OptionType
>(
impossibleOptionTypes
);
switch
(
optionType
)
{
case
IpV4OptionType
.
EndOfOptionList
:
return
IpV4Option
.
End
;
case
IpV4OptionType
.
NoOperation
:
return
IpV4Option
.
Nop
;
case
IpV4OptionType
.
BasicSecurity
:
IpV4OptionSecurityProtectionAuthorities
protectionAuthorities
=
IpV4OptionSecurityProtectionAuthorities
.
None
;
int
protectionAuthorityLength
=
random
.
Next
(
maximumOptionLength
-
IpV4OptionBasicSecurity
.
OptionMinimumLength
);
if
(
protectionAuthorityLength
>
0
)
protectionAuthorities
=
random
.
NextEnum
<
IpV4OptionSecurityProtectionAuthorities
>();
return
new
IpV4OptionBasicSecurity
(
random
.
NextEnum
(
IpV4OptionSecurityClassificationLevel
.
None
),
protectionAuthorities
,
(
byte
)(
IpV4OptionBasicSecurity
.
OptionMinimumLength
+
protectionAuthorityLength
));
case
IpV4OptionType
.
LooseSourceRouting
:
case
IpV4OptionType
.
StrictSourceRouting
:
case
IpV4OptionType
.
RecordRoute
:
int
numAddresses
=
random
.
Next
((
maximumOptionLength
-
IpV4OptionRoute
.
OptionMinimumLength
)
/
4
+
1
);
IpV4Address
[]
addresses
=
random
.
NextIpV4Addresses
(
numAddresses
);
byte
pointedAddressIndex
;
if
(
random
.
NextBool
())
pointedAddressIndex
=
random
.
NextByte
(
IpV4OptionRoute
.
PointedAddressIndexMaxValue
+
1
);
else
pointedAddressIndex
=
random
.
NextByte
(
10
);
switch
(
optionType
)
{
case
IpV4OptionType
.
LooseSourceRouting
:
return
new
IpV4OptionLooseSourceRouting
(
addresses
,
pointedAddressIndex
);
case
IpV4OptionType
.
StrictSourceRouting
:
return
new
IpV4OptionStrictSourceRouting
(
addresses
,
pointedAddressIndex
);
case
IpV4OptionType
.
RecordRoute
:
return
new
IpV4OptionRecordRoute
(
pointedAddressIndex
,
addresses
);
default
:
throw
new
InvalidOperationException
(
"optionType = "
+
optionType
);
}
case
IpV4OptionType
.
StreamIdentifier
:
return
new
IpV4OptionStreamIdentifier
(
random
.
NextUShort
());
case
IpV4OptionType
.
InternetTimestamp
:
IpV4OptionTimestampType
timestampType
=
random
.
NextEnum
<
IpV4OptionTimestampType
>();
byte
overflow
=
random
.
NextByte
(
IpV4OptionTimestamp
.
OverflowMaxValue
+
1
);
byte
pointedIndex
;
if
(
random
.
NextBool
())
pointedIndex
=
random
.
NextByte
(
IpV4OptionTimestamp
.
PointedIndexMaxValue
+
1
);
else
pointedIndex
=
random
.
NextByte
(
10
);
switch
(
timestampType
)
{
case
IpV4OptionTimestampType
.
TimestampOnly
:
int
numTimestamps
=
random
.
Next
((
maximumOptionLength
-
IpV4OptionTimestamp
.
OptionMinimumLength
)
/
4
+
1
);
IpV4TimeOfDay
[]
timestamps
=
((
Func
<
IpV4TimeOfDay
>)
random
.
NextIpV4TimeOfDay
).
GenerateArray
(
numTimestamps
);
return
new
IpV4OptionTimestampOnly
(
overflow
,
pointedIndex
,
timestamps
);
case
IpV4OptionTimestampType
.
AddressAndTimestamp
:
case
IpV4OptionTimestampType
.
AddressPrespecified
:
int
numPairs
=
random
.
Next
((
maximumOptionLength
-
IpV4OptionTimestamp
.
OptionMinimumLength
)
/
8
+
1
);
IpV4OptionTimedAddress
[]
pairs
=
new
IpV4OptionTimedAddress
[
numPairs
];
for
(
int
i
=
0
;
i
!=
numPairs
;
++
i
)
pairs
[
i
]
=
new
IpV4OptionTimedAddress
(
random
.
NextIpV4Address
(),
random
.
NextIpV4TimeOfDay
());
return
new
IpV4OptionTimestampAndAddress
(
timestampType
,
overflow
,
pointedIndex
,
pairs
);
default
:
throw
new
InvalidOperationException
(
"timestampType = "
+
timestampType
);
}
case
IpV4OptionType
.
TraceRoute
:
return
new
IpV4OptionTraceRoute
(
random
.
NextUShort
(),
random
.
NextUShort
(),
random
.
NextUShort
(),
random
.
NextIpV4Address
());
case
IpV4OptionType
.
RouterAlert
:
return
new
IpV4OptionRouterAlert
(
random
.
NextUShort
());
case
IpV4OptionType
.
QuickStart
:
return
new
IpV4OptionQuickStart
(
random
.
NextEnum
<
IpV4OptionQuickStartFunction
>(),
random
.
NextByte
(
IpV4OptionQuickStart
.
RateMaximumValue
+
1
),
random
.
NextByte
(),
random
.
NextUInt
()
&
0xFFFFFFFC
);
default
:
throw
new
InvalidOperationException
(
"optionType = "
+
optionType
);
}
}
public
static
IpV4Options
NextIpV4Options
(
this
Random
random
)
{
int
optionsLength
=
random
.
Next
(
IpV4Options
.
MaximumBytesLength
)
/
4
*
4
;
List
<
IpV4Option
>
options
=
new
List
<
IpV4Option
>();
while
(
optionsLength
>
0
)
{
IpV4Option
option
=
random
.
NextIpV4Option
(
optionsLength
);
if
(
option
.
IsAppearsAtMostOnce
&&
options
.
FindIndex
(
option
.
Equivalent
)
!=
-
1
)
{
continue
;
}
options
.
Add
(
option
);
optionsLength
-=
option
.
Length
;
if
(
option
.
OptionType
==
IpV4OptionType
.
EndOfOptionList
)
break
;
}
return
new
IpV4Options
(
options
);
}
}
}
\ No newline at end of file
PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomIpV6Extensions.cs
0 → 100644
View file @
64ffbb1d
using
System
;
using
PcapDotNet.Packets.IpV6
;
using
PcapDotNet.TestUtils
;
namespace
PcapDotNet.Packets.TestUtils
{
public
static
class
RandomIpV6Extensions
{
public
static
IpV6Address
NextIpV6Address
(
this
Random
random
)
{
return
new
IpV6Address
(
random
.
NextUInt128
());
}
}
}
\ No newline at end of file
PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomPacketsExtensions.cs
View file @
64ffbb1d
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Text
;
using
PcapDotNet.Base
;
using
PcapDotNet.Packets.Arp
;
using
PcapDotNet.Packets.Dns
;
using
PcapDotNet.Packets.Ethernet
;
using
PcapDotNet.Packets.Gre
;
using
PcapDotNet.Packets.Http
;
using
PcapDotNet.Packets.Icmp
;
using
PcapDotNet.Packets.Igmp
;
using
PcapDotNet.Packets.IpV4
;
using
PcapDotNet.Packets.IpV6
;
using
PcapDotNet.Packets.Transport
;
using
PcapDotNet.TestUtils
;
using
PcapDotNet.TestUtils
;
namespace
PcapDotNet.Packets.TestUtils
namespace
PcapDotNet.Packets.TestUtils
...
@@ -46,1302 +32,9 @@ namespace PcapDotNet.Packets.TestUtils
...
@@ -46,1302 +32,9 @@ namespace PcapDotNet.Packets.TestUtils
};
};
}
}
// Ethernet
public
static
DataSegment
NextDataSegment
(
this
Random
random
,
int
length
)
public
static
EthernetLayer
NextEthernetLayer
(
this
Random
random
,
EthernetType
etherType
)
{
return
new
EthernetLayer
{
Source
=
random
.
NextMacAddress
(),
Destination
=
random
.
NextMacAddress
(),
EtherType
=
etherType
};
}
public
static
EthernetLayer
NextEthernetLayer
(
this
Random
random
)
{
return
random
.
NextEthernetLayer
(
random
.
NextEnum
(
EthernetType
.
None
));
}
public
static
MacAddress
NextMacAddress
(
this
Random
random
)
{
return
new
MacAddress
(
random
.
NextUInt48
());
}
public
static
EthernetType
NextEthernetType
(
this
Random
random
)
{
return
random
.
NextEnum
(
EthernetType
.
None
);
}
public
static
Packet
NextEthernetPacket
(
this
Random
random
,
int
packetSize
,
DateTime
timestamp
,
MacAddress
ethernetSource
,
MacAddress
ethernetDestination
)
{
if
(
packetSize
<
EthernetDatagram
.
HeaderLength
)
throw
new
ArgumentOutOfRangeException
(
"packetSize"
,
packetSize
,
"Must be at least the ethernet header length ("
+
EthernetDatagram
.
HeaderLength
+
")"
);
return
PacketBuilder
.
Build
(
timestamp
,
new
EthernetLayer
{
Source
=
ethernetSource
,
Destination
=
ethernetDestination
,
EtherType
=
random
.
NextEthernetType
()
},
random
.
NextPayloadLayer
(
packetSize
-
EthernetDatagram
.
HeaderLength
));
}
public
static
Packet
NextEthernetPacket
(
this
Random
random
,
int
packetSize
,
DateTime
timestamp
,
string
ethernetSource
,
string
ethernetDestination
)
{
return
random
.
NextEthernetPacket
(
packetSize
,
timestamp
,
new
MacAddress
(
ethernetSource
),
new
MacAddress
(
ethernetDestination
));
}
public
static
Packet
NextEthernetPacket
(
this
Random
random
,
int
packetSize
,
MacAddress
ethernetSource
,
MacAddress
ethernetDestination
)
{
return
random
.
NextEthernetPacket
(
packetSize
,
DateTime
.
Now
,
ethernetSource
,
ethernetDestination
);
}
public
static
Packet
NextEthernetPacket
(
this
Random
random
,
int
packetSize
,
string
ethernetSource
,
string
ethernetDestination
)
{
return
random
.
NextEthernetPacket
(
packetSize
,
DateTime
.
Now
,
ethernetSource
,
ethernetDestination
);
}
public
static
Packet
NextEthernetPacket
(
this
Random
random
,
int
packetSize
)
{
return
random
.
NextEthernetPacket
(
packetSize
,
DateTime
.
Now
,
random
.
NextMacAddress
(),
random
.
NextMacAddress
());
}
// ARP
public
static
ArpLayer
NextArpLayer
(
this
Random
random
)
{
byte
hardwareAddressLength
=
random
.
NextByte
();
byte
protocolAddressLength
=
random
.
NextByte
();
return
new
ArpLayer
{
SenderHardwareAddress
=
random
.
NextBytes
(
hardwareAddressLength
).
AsReadOnly
(),
SenderProtocolAddress
=
random
.
NextBytes
(
protocolAddressLength
).
AsReadOnly
(),
TargetHardwareAddress
=
random
.
NextBytes
(
hardwareAddressLength
).
AsReadOnly
(),
TargetProtocolAddress
=
random
.
NextBytes
(
protocolAddressLength
).
AsReadOnly
(),
ProtocolType
=
random
.
NextEnum
<
EthernetType
>(),
Operation
=
random
.
NextEnum
<
ArpOperation
>(),
};
}
// IPv4
public
static
IpV4Layer
NextIpV4Layer
(
this
Random
random
,
IpV4Protocol
?
protocol
)
{
return
new
IpV4Layer
{
TypeOfService
=
random
.
NextByte
(),
Identification
=
random
.
NextUShort
(),
Ttl
=
random
.
NextByte
(),
Protocol
=
protocol
,
HeaderChecksum
=
random
.
NextBool
()
?
(
ushort
?)
random
.
NextUShort
()
:
null
,
Fragmentation
=
random
.
NextBool
()
?
random
.
NextIpV4Fragmentation
()
:
IpV4Fragmentation
.
None
,
Source
=
random
.
NextIpV4Address
(),
Destination
=
random
.
NextIpV4Address
(),
Options
=
random
.
NextIpV4Options
()
};
}
public
static
IpV4Layer
NextIpV4Layer
(
this
Random
random
)
{
return
random
.
NextIpV4Layer
(
random
.
NextEnum
<
IpV4Protocol
>());
}
public
static
IpV4Address
NextIpV4Address
(
this
Random
random
)
{
return
new
IpV4Address
(
random
.
NextUInt
());
}
public
static
IpV4Address
[]
NextIpV4Addresses
(
this
Random
random
,
int
count
)
{
return
((
Func
<
IpV4Address
>)
random
.
NextIpV4Address
).
GenerateArray
(
count
);
}
public
static
IpV4Fragmentation
NextIpV4Fragmentation
(
this
Random
random
)
{
IpV4FragmentationOptions
ipV4FragmentationFlags
=
random
.
NextEnum
<
IpV4FragmentationOptions
>();
ushort
ipV4FragmentationOffset
=
(
ushort
)(
random
.
NextUShort
()
/
8
*
8
);
return
new
IpV4Fragmentation
(
ipV4FragmentationFlags
,
ipV4FragmentationOffset
);
}
public
static
IpV4TimeOfDay
NextIpV4TimeOfDay
(
this
Random
random
)
{
return
new
IpV4TimeOfDay
(
random
.
NextUInt
());
}
public
static
IpV4OptionUnknown
NextIpV4OptionUnknown
(
this
Random
random
,
int
maximumOptionLength
)
{
IpV4OptionType
unknownOptionType
;
byte
unknownOptionTypeValue
;
do
{
unknownOptionTypeValue
=
random
.
NextByte
();
unknownOptionType
=
(
IpV4OptionType
)
unknownOptionTypeValue
;
}
while
(
unknownOptionType
.
ToString
()
!=
unknownOptionTypeValue
.
ToString
());
Byte
[]
unknownOptionData
=
new
byte
[
random
.
Next
(
maximumOptionLength
-
IpV4OptionUnknown
.
OptionMinimumLength
+
1
)];
random
.
NextBytes
(
unknownOptionData
);
return
new
IpV4OptionUnknown
(
unknownOptionType
,
unknownOptionData
);
}
public
static
IpV4Option
NextIpV4Option
(
this
Random
random
,
int
maximumOptionLength
)
{
if
(
maximumOptionLength
==
0
)
throw
new
ArgumentOutOfRangeException
(
"maximumOptionLength"
,
maximumOptionLength
,
"option length must be positive"
);
if
(
maximumOptionLength
>=
IpV4OptionUnknown
.
OptionMinimumLength
&&
random
.
Next
(
100
)
>
90
)
return
random
.
NextIpV4OptionUnknown
(
maximumOptionLength
);
List
<
IpV4OptionType
>
impossibleOptionTypes
=
new
List
<
IpV4OptionType
>();
if
(
maximumOptionLength
<
IpV4OptionBasicSecurity
.
OptionMinimumLength
)
impossibleOptionTypes
.
Add
(
IpV4OptionType
.
BasicSecurity
);
if
(
maximumOptionLength
<
IpV4OptionRoute
.
OptionMinimumLength
)
{
impossibleOptionTypes
.
Add
(
IpV4OptionType
.
LooseSourceRouting
);
impossibleOptionTypes
.
Add
(
IpV4OptionType
.
StrictSourceRouting
);
impossibleOptionTypes
.
Add
(
IpV4OptionType
.
RecordRoute
);
}
if
(
maximumOptionLength
<
IpV4OptionStreamIdentifier
.
OptionLength
)
impossibleOptionTypes
.
Add
(
IpV4OptionType
.
StreamIdentifier
);
if
(
maximumOptionLength
<
IpV4OptionTimestamp
.
OptionMinimumLength
)
impossibleOptionTypes
.
Add
(
IpV4OptionType
.
InternetTimestamp
);
if
(
maximumOptionLength
<
IpV4OptionTraceRoute
.
OptionLength
)
impossibleOptionTypes
.
Add
(
IpV4OptionType
.
TraceRoute
);
if
(
maximumOptionLength
<
IpV4OptionQuickStart
.
OptionLength
)
impossibleOptionTypes
.
Add
(
IpV4OptionType
.
QuickStart
);
IpV4OptionType
optionType
=
random
.
NextEnum
<
IpV4OptionType
>(
impossibleOptionTypes
);
switch
(
optionType
)
{
case
IpV4OptionType
.
EndOfOptionList
:
return
IpV4Option
.
End
;
case
IpV4OptionType
.
NoOperation
:
return
IpV4Option
.
Nop
;
case
IpV4OptionType
.
BasicSecurity
:
IpV4OptionSecurityProtectionAuthorities
protectionAuthorities
=
IpV4OptionSecurityProtectionAuthorities
.
None
;
int
protectionAuthorityLength
=
random
.
Next
(
maximumOptionLength
-
IpV4OptionBasicSecurity
.
OptionMinimumLength
);
if
(
protectionAuthorityLength
>
0
)
protectionAuthorities
=
random
.
NextEnum
<
IpV4OptionSecurityProtectionAuthorities
>();
return
new
IpV4OptionBasicSecurity
(
random
.
NextEnum
(
IpV4OptionSecurityClassificationLevel
.
None
),
protectionAuthorities
,
(
byte
)(
IpV4OptionBasicSecurity
.
OptionMinimumLength
+
protectionAuthorityLength
));
case
IpV4OptionType
.
LooseSourceRouting
:
case
IpV4OptionType
.
StrictSourceRouting
:
case
IpV4OptionType
.
RecordRoute
:
int
numAddresses
=
random
.
Next
((
maximumOptionLength
-
IpV4OptionRoute
.
OptionMinimumLength
)
/
4
+
1
);
IpV4Address
[]
addresses
=
random
.
NextIpV4Addresses
(
numAddresses
);
byte
pointedAddressIndex
;
if
(
random
.
NextBool
())
pointedAddressIndex
=
random
.
NextByte
(
IpV4OptionRoute
.
PointedAddressIndexMaxValue
+
1
);
else
pointedAddressIndex
=
random
.
NextByte
(
10
);
switch
(
optionType
)
{
case
IpV4OptionType
.
LooseSourceRouting
:
return
new
IpV4OptionLooseSourceRouting
(
addresses
,
pointedAddressIndex
);
case
IpV4OptionType
.
StrictSourceRouting
:
return
new
IpV4OptionStrictSourceRouting
(
addresses
,
pointedAddressIndex
);
case
IpV4OptionType
.
RecordRoute
:
return
new
IpV4OptionRecordRoute
(
pointedAddressIndex
,
addresses
);
default
:
throw
new
InvalidOperationException
(
"optionType = "
+
optionType
);
}
case
IpV4OptionType
.
StreamIdentifier
:
return
new
IpV4OptionStreamIdentifier
(
random
.
NextUShort
());
case
IpV4OptionType
.
InternetTimestamp
:
IpV4OptionTimestampType
timestampType
=
random
.
NextEnum
<
IpV4OptionTimestampType
>();
byte
overflow
=
random
.
NextByte
(
IpV4OptionTimestamp
.
OverflowMaxValue
+
1
);
byte
pointedIndex
;
if
(
random
.
NextBool
())
pointedIndex
=
random
.
NextByte
(
IpV4OptionTimestamp
.
PointedIndexMaxValue
+
1
);
else
pointedIndex
=
random
.
NextByte
(
10
);
switch
(
timestampType
)
{
case
IpV4OptionTimestampType
.
TimestampOnly
:
int
numTimestamps
=
random
.
Next
((
maximumOptionLength
-
IpV4OptionTimestamp
.
OptionMinimumLength
)
/
4
+
1
);
IpV4TimeOfDay
[]
timestamps
=
((
Func
<
IpV4TimeOfDay
>)
random
.
NextIpV4TimeOfDay
).
GenerateArray
(
numTimestamps
);
return
new
IpV4OptionTimestampOnly
(
overflow
,
pointedIndex
,
timestamps
);
case
IpV4OptionTimestampType
.
AddressAndTimestamp
:
case
IpV4OptionTimestampType
.
AddressPrespecified
:
int
numPairs
=
random
.
Next
((
maximumOptionLength
-
IpV4OptionTimestamp
.
OptionMinimumLength
)
/
8
+
1
);
IpV4OptionTimedAddress
[]
pairs
=
new
IpV4OptionTimedAddress
[
numPairs
];
for
(
int
i
=
0
;
i
!=
numPairs
;
++
i
)
pairs
[
i
]
=
new
IpV4OptionTimedAddress
(
random
.
NextIpV4Address
(),
random
.
NextIpV4TimeOfDay
());
return
new
IpV4OptionTimestampAndAddress
(
timestampType
,
overflow
,
pointedIndex
,
pairs
);
default
:
throw
new
InvalidOperationException
(
"timestampType = "
+
timestampType
);
}
case
IpV4OptionType
.
TraceRoute
:
return
new
IpV4OptionTraceRoute
(
random
.
NextUShort
(),
random
.
NextUShort
(),
random
.
NextUShort
(),
random
.
NextIpV4Address
());
case
IpV4OptionType
.
RouterAlert
:
return
new
IpV4OptionRouterAlert
(
random
.
NextUShort
());
case
IpV4OptionType
.
QuickStart
:
return
new
IpV4OptionQuickStart
(
random
.
NextEnum
<
IpV4OptionQuickStartFunction
>(),
random
.
NextByte
(
IpV4OptionQuickStart
.
RateMaximumValue
+
1
),
random
.
NextByte
(),
random
.
NextUInt
()
&
0xFFFFFFFC
);
default
:
throw
new
InvalidOperationException
(
"optionType = "
+
optionType
);
}
}
public
static
IpV4Options
NextIpV4Options
(
this
Random
random
)
{
int
optionsLength
=
random
.
Next
(
IpV4Options
.
MaximumBytesLength
)
/
4
*
4
;
List
<
IpV4Option
>
options
=
new
List
<
IpV4Option
>();
while
(
optionsLength
>
0
)
{
IpV4Option
option
=
random
.
NextIpV4Option
(
optionsLength
);
if
(
option
.
IsAppearsAtMostOnce
&&
options
.
FindIndex
(
option
.
Equivalent
)
!=
-
1
)
{
continue
;
}
options
.
Add
(
option
);
optionsLength
-=
option
.
Length
;
if
(
option
.
OptionType
==
IpV4OptionType
.
EndOfOptionList
)
break
;
}
return
new
IpV4Options
(
options
);
}
// IPv6
public
static
IpV6Address
NextIpV6Address
(
this
Random
random
)
{
return
new
IpV6Address
(
random
.
NextUInt128
());
}
// UDP
public
static
UdpLayer
NextUdpLayer
(
this
Random
random
)
{
return
new
UdpLayer
{
Checksum
=
random
.
NextUShort
(),
SourcePort
=
random
.
NextUShort
(),
DestinationPort
=
random
.
NextUShort
(),
CalculateChecksumValue
=
random
.
NextBool
()
};
}
// TCP
public
static
TcpLayer
NextTcpLayer
(
this
Random
random
)
{
return
new
TcpLayer
{
SourcePort
=
random
.
NextUShort
(),
DestinationPort
=
random
.
NextUShort
(),
SequenceNumber
=
random
.
NextUInt
(),
AcknowledgmentNumber
=
random
.
NextUInt
(),
ControlBits
=
random
.
NextFlags
<
TcpControlBits
>(),
Window
=
random
.
NextUShort
(),
UrgentPointer
=
random
.
NextUShort
(),
Options
=
random
.
NextTcpOptions
(),
};
}
public
static
TcpOptions
NextTcpOptions
(
this
Random
random
)
{
int
optionsLength
=
random
.
Next
(
TcpOptions
.
MaximumBytesLength
)
/
4
*
4
;
List
<
TcpOption
>
options
=
new
List
<
TcpOption
>();
while
(
optionsLength
>
0
)
{
TcpOption
option
=
random
.
NextTcpOption
(
optionsLength
);
if
(
option
.
IsAppearsAtMostOnce
&&
options
.
FindIndex
(
option
.
Equivalent
)
!=
-
1
)
{
continue
;
}
options
.
Add
(
option
);
optionsLength
-=
option
.
Length
;
if
(
option
.
OptionType
==
TcpOptionType
.
EndOfOptionList
)
break
;
}
return
new
TcpOptions
(
options
);
}
public
static
TcpOptionUnknown
NextTcpOptionUnknown
(
this
Random
random
,
int
maximumOptionLength
)
{
TcpOptionType
unknownOptionType
;
byte
unknownOptionTypeValue
;
do
{
unknownOptionTypeValue
=
random
.
NextByte
();
unknownOptionType
=
(
TcpOptionType
)
unknownOptionTypeValue
;
}
while
(
unknownOptionType
.
ToString
()
!=
unknownOptionTypeValue
.
ToString
());
byte
[]
unknownOptionData
=
random
.
NextBytes
(
maximumOptionLength
-
TcpOptionUnknown
.
OptionMinimumLength
+
1
);
return
new
TcpOptionUnknown
(
unknownOptionType
,
unknownOptionData
);
}
public
static
TcpOption
NextTcpOption
(
this
Random
random
,
int
maximumOptionLength
)
{
if
(
maximumOptionLength
==
0
)
throw
new
ArgumentOutOfRangeException
(
"maximumOptionLength"
,
maximumOptionLength
,
"option length must be positive"
);
if
(
maximumOptionLength
>=
TcpOptionUnknown
.
OptionMinimumLength
&&
random
.
Next
(
100
)
>
90
)
return
random
.
NextTcpOptionUnknown
(
maximumOptionLength
);
List
<
TcpOptionType
>
impossibleOptionTypes
=
new
List
<
TcpOptionType
>();
if
(
maximumOptionLength
<
TcpOptionMaximumSegmentSize
.
OptionLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
MaximumSegmentSize
);
if
(
maximumOptionLength
<
TcpOptionWindowScale
.
OptionLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
WindowScale
);
if
(
maximumOptionLength
<
TcpOptionSelectiveAcknowledgment
.
OptionMinimumLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
SelectiveAcknowledgment
);
if
(
maximumOptionLength
<
TcpOptionSelectiveAcknowledgmentPermitted
.
OptionLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
SelectiveAcknowledgmentPermitted
);
if
(
maximumOptionLength
<
TcpOptionEcho
.
OptionLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
Echo
);
if
(
maximumOptionLength
<
TcpOptionEchoReply
.
OptionLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
EchoReply
);
if
(
maximumOptionLength
<
TcpOptionTimestamp
.
OptionLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
Timestamp
);
if
(
maximumOptionLength
<
TcpOptionPartialOrderServiceProfile
.
OptionLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
PartialOrderServiceProfile
);
if
(
maximumOptionLength
<
TcpOptionPartialOrderConnectionPermitted
.
OptionLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
PartialOrderConnectionPermitted
);
if
(
maximumOptionLength
<
TcpOptionConnectionCountBase
.
OptionLength
)
{
impossibleOptionTypes
.
Add
(
TcpOptionType
.
ConnectionCount
);
impossibleOptionTypes
.
Add
(
TcpOptionType
.
ConnectionCountNew
);
impossibleOptionTypes
.
Add
(
TcpOptionType
.
ConnectionCountEcho
);
}
if
(
maximumOptionLength
<
TcpOptionAlternateChecksumRequest
.
OptionLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
AlternateChecksumRequest
);
if
(
maximumOptionLength
<
TcpOptionAlternateChecksumData
.
OptionMinimumLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
AlternateChecksumData
);
if
(
maximumOptionLength
<
TcpOptionMd5Signature
.
OptionLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
Md5Signature
);
if
(
maximumOptionLength
<
TcpOptionMood
.
OptionMaximumLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
Mood
);
impossibleOptionTypes
.
Add
(
TcpOptionType
.
QuickStartResponse
);
impossibleOptionTypes
.
Add
(
TcpOptionType
.
UserTimeout
);
TcpOptionType
optionType
=
random
.
NextEnum
<
TcpOptionType
>(
impossibleOptionTypes
);
switch
(
optionType
)
{
case
TcpOptionType
.
EndOfOptionList
:
return
TcpOption
.
End
;
case
TcpOptionType
.
NoOperation
:
return
TcpOption
.
Nop
;
case
TcpOptionType
.
MaximumSegmentSize
:
return
new
TcpOptionMaximumSegmentSize
(
random
.
NextUShort
());
case
TcpOptionType
.
WindowScale
:
return
new
TcpOptionWindowScale
(
random
.
NextByte
());
case
TcpOptionType
.
SelectiveAcknowledgment
:
int
numBlocks
=
random
.
Next
((
maximumOptionLength
-
TcpOptionSelectiveAcknowledgment
.
OptionMinimumLength
)
/
8
+
1
);
TcpOptionSelectiveAcknowledgmentBlock
[]
blocks
=
new
TcpOptionSelectiveAcknowledgmentBlock
[
numBlocks
];
for
(
int
i
=
0
;
i
!=
numBlocks
;
++
i
)
blocks
[
i
]
=
new
TcpOptionSelectiveAcknowledgmentBlock
(
random
.
NextUInt
(),
random
.
NextUInt
());
return
new
TcpOptionSelectiveAcknowledgment
(
blocks
);
case
TcpOptionType
.
SelectiveAcknowledgmentPermitted
:
return
new
TcpOptionSelectiveAcknowledgmentPermitted
();
case
TcpOptionType
.
Echo
:
return
new
TcpOptionEcho
(
random
.
NextUInt
());
case
TcpOptionType
.
EchoReply
:
return
new
TcpOptionEchoReply
(
random
.
NextUInt
());
case
TcpOptionType
.
Timestamp
:
return
new
TcpOptionTimestamp
(
random
.
NextUInt
(),
random
.
NextUInt
());
case
TcpOptionType
.
PartialOrderServiceProfile
:
return
new
TcpOptionPartialOrderServiceProfile
(
random
.
NextBool
(),
random
.
NextBool
());
case
TcpOptionType
.
PartialOrderConnectionPermitted
:
return
new
TcpOptionPartialOrderConnectionPermitted
();
case
TcpOptionType
.
ConnectionCount
:
return
new
TcpOptionConnectionCount
(
random
.
NextUInt
());
case
TcpOptionType
.
ConnectionCountEcho
:
return
new
TcpOptionConnectionCountEcho
(
random
.
NextUInt
());
case
TcpOptionType
.
ConnectionCountNew
:
return
new
TcpOptionConnectionCountNew
(
random
.
NextUInt
());
case
TcpOptionType
.
AlternateChecksumRequest
:
return
new
TcpOptionAlternateChecksumRequest
(
random
.
NextEnum
<
TcpOptionAlternateChecksumType
>());
case
TcpOptionType
.
AlternateChecksumData
:
return
new
TcpOptionAlternateChecksumData
(
random
.
NextBytes
(
random
.
Next
(
maximumOptionLength
-
TcpOptionAlternateChecksumData
.
OptionMinimumLength
+
1
)));
case
TcpOptionType
.
Md5Signature
:
return
new
TcpOptionMd5Signature
(
random
.
NextBytes
(
TcpOptionMd5Signature
.
OptionValueLength
));
case
TcpOptionType
.
Mood
:
return
new
TcpOptionMood
(
random
.
NextEnum
(
TcpOptionMoodEmotion
.
None
));
default
:
throw
new
InvalidOperationException
(
"optionType = "
+
optionType
);
}
}
// IGMP
public
static
IgmpGroupRecord
NextIgmpGroupRecord
(
this
Random
random
)
{
IpV4Address
[]
sourceAddresses
=
random
.
NextIpV4Addresses
(
random
.
Next
(
10
));
return
new
IgmpGroupRecord
(
random
.
NextEnum
<
IgmpRecordType
>(),
random
.
NextIpV4Address
(),
sourceAddresses
,
random
.
NextDatagram
(
random
.
Next
(
10
)
*
4
));
}
public
static
IgmpGroupRecord
[]
NextIgmpGroupRecords
(
this
Random
random
,
int
count
)
{
return
((
Func
<
IgmpGroupRecord
>)
random
.
NextIgmpGroupRecord
).
GenerateArray
(
count
);
}
public
static
IgmpLayer
NextIgmpLayer
(
this
Random
random
)
{
IgmpMessageType
igmpMessageType
=
random
.
NextEnum
(
IgmpMessageType
.
None
,
IgmpMessageType
.
CreateGroupRequestVersion0
,
IgmpMessageType
.
CreateGroupReplyVersion0
,
IgmpMessageType
.
JoinGroupRequestVersion0
,
IgmpMessageType
.
JoinGroupReplyVersion0
,
IgmpMessageType
.
LeaveGroupRequestVersion0
,
IgmpMessageType
.
LeaveGroupReplyVersion0
,
IgmpMessageType
.
ConfirmGroupRequestVersion0
,
IgmpMessageType
.
ConfirmGroupReplyVersion0
,
IgmpMessageType
.
MulticastTraceRouteResponse
);
// todo support IGMP traceroute http://www.ietf.org/proceedings/48/I-D/idmr-traceroute-ipm-07.txt.
IgmpQueryVersion
igmpQueryVersion
=
IgmpQueryVersion
.
None
;
TimeSpan
igmpMaxResponseTime
=
random
.
NextTimeSpan
(
TimeSpan
.
FromSeconds
(
0.1
),
TimeSpan
.
FromSeconds
(
256
*
0.1
)
-
TimeSpan
.
FromTicks
(
1
));
IpV4Address
igmpGroupAddress
=
random
.
NextIpV4Address
();
bool
?
igmpIsSuppressRouterSideProcessing
;
byte
?
igmpQueryRobustnessVariable
;
TimeSpan
?
igmpQueryInterval
;
IpV4Address
[]
igmpSourceAddresses
;
IgmpGroupRecord
[]
igmpGroupRecords
;
switch
(
igmpMessageType
)
{
case
IgmpMessageType
.
MembershipQuery
:
igmpQueryVersion
=
random
.
NextEnum
(
IgmpQueryVersion
.
None
,
IgmpQueryVersion
.
Unknown
);
switch
(
igmpQueryVersion
)
{
case
IgmpQueryVersion
.
Version1
:
return
new
IgmpQueryVersion1Layer
{
GroupAddress
=
igmpGroupAddress
};
case
IgmpQueryVersion
.
Version2
:
return
new
IgmpQueryVersion2Layer
{
MaxResponseTime
=
igmpMaxResponseTime
,
GroupAddress
=
igmpGroupAddress
};
case
IgmpQueryVersion
.
Version3
:
igmpIsSuppressRouterSideProcessing
=
random
.
NextBool
();
igmpQueryRobustnessVariable
=
random
.
NextByte
(
8
);
igmpMaxResponseTime
=
random
.
NextTimeSpan
(
TimeSpan
.
FromSeconds
(
0.1
),
IgmpDatagram
.
MaxVersion3MaxResponseTime
-
TimeSpan
.
FromTicks
(
1
));
igmpQueryInterval
=
random
.
NextTimeSpan
(
TimeSpan
.
Zero
,
IgmpDatagram
.
MaxQueryInterval
-
TimeSpan
.
FromTicks
(
1
));
igmpSourceAddresses
=
random
.
NextIpV4Addresses
(
random
.
Next
(
1000
));
return
new
IgmpQueryVersion3Layer
{
SourceAddresses
=
igmpSourceAddresses
.
AsReadOnly
(),
MaxResponseTime
=
igmpMaxResponseTime
,
GroupAddress
=
igmpGroupAddress
,
IsSuppressRouterSideProcessing
=
igmpIsSuppressRouterSideProcessing
.
Value
,
QueryRobustnessVariable
=
igmpQueryRobustnessVariable
.
Value
,
QueryInterval
=
igmpQueryInterval
.
Value
,
};
default
:
throw
new
InvalidOperationException
(
"Invalid Query Version "
+
igmpQueryVersion
);
}
case
IgmpMessageType
.
MembershipReportVersion1
:
return
new
IgmpReportVersion1Layer
{
GroupAddress
=
igmpGroupAddress
};
case
IgmpMessageType
.
MembershipReportVersion2
:
return
new
IgmpReportVersion2Layer
{
MaxResponseTime
=
igmpMaxResponseTime
,
GroupAddress
=
igmpGroupAddress
};
case
IgmpMessageType
.
LeaveGroupVersion2
:
return
new
IgmpLeaveGroupVersion2Layer
{
MaxResponseTime
=
igmpMaxResponseTime
,
GroupAddress
=
igmpGroupAddress
};
case
IgmpMessageType
.
MembershipReportVersion3
:
igmpGroupRecords
=
random
.
NextIgmpGroupRecords
(
random
.
Next
(
100
));
if
(
igmpGroupRecords
.
Count
()
==
0
&&
random
.
NextBool
())
return
new
IgmpReportVersion3Layer
();
return
new
IgmpReportVersion3Layer
{
GroupRecords
=
igmpGroupRecords
.
AsReadOnly
()
};
default
:
throw
new
InvalidOperationException
(
"Invalid message type "
+
igmpMessageType
);
}
}
// GRE
public
static
GreLayer
NextGreLayer
(
this
Random
random
)
{
GreVersion
version
=
random
.
NextEnum
<
GreVersion
>();
bool
isChecksum
=
random
.
NextBool
();
GreSourceRouteEntry
[]
routing
=
null
;
ushort
?
routingOffset
=
null
;
bool
strictSourceRoute
=
false
;
EthernetType
protocolType
=
random
.
NextEnum
(
EthernetType
.
None
);
uint
?
key
=
random
.
NextBool
()
?
(
uint
?)
random
.
NextUInt
()
:
null
;
if
(
version
==
GreVersion
.
Gre
)
{
if
(
random
.
NextBool
())
{
strictSourceRoute
=
random
.
NextBool
();
routing
=
new
GreSourceRouteEntry
[
random
.
Next
(
5
)];
GreSourceRouteEntryAddressFamily
family
;
if
(
random
.
NextBool
())
family
=
random
.
NextEnum
(
GreSourceRouteEntryAddressFamily
.
None
);
else
family
=
(
GreSourceRouteEntryAddressFamily
)
random
.
NextUShort
();
for
(
int
i
=
0
;
i
!=
routing
.
Length
;
++
i
)
{
switch
(
family
)
{
case
GreSourceRouteEntryAddressFamily
.
AsSourceRoute
:
{
ushort
[]
asNumbers
=
new
ushort
[
random
.
Next
(
1
,
5
)];
for
(
int
j
=
0
;
j
!=
asNumbers
.
Length
;
++
j
)
asNumbers
[
j
]
=
random
.
NextUShort
();
routing
[
i
]
=
new
GreSourceRouteEntryAs
(
asNumbers
.
AsReadOnly
(),
random
.
Next
(
asNumbers
.
Length
+
1
));
break
;
}
case
GreSourceRouteEntryAddressFamily
.
IpSourceRoute
:
{
IpV4Address
[]
ips
=
new
IpV4Address
[
random
.
Next
(
1
,
5
)];
for
(
int
j
=
0
;
j
!=
ips
.
Length
;
++
j
)
ips
[
j
]
=
random
.
NextIpV4Address
();
routing
[
i
]
=
new
GreSourceRouteEntryIp
(
ips
.
AsReadOnly
(),
random
.
Next
(
ips
.
Length
+
1
));
break
;
}
default
:
{
int
dataLength
=
random
.
Next
(
1
,
100
);
routing
[
i
]
=
new
GreSourceRouteEntryUnknown
(
family
,
random
.
NextDatagram
(
dataLength
),
random
.
Next
(
dataLength
+
1
));
break
;
}
}
}
routingOffset
=
0
;
if
(
routing
.
Any
())
{
{
int
routingIndex
=
random
.
Next
(
routing
.
Length
);
return
new
DataSegment
(
random
.
NextBytes
(
length
));
for
(
int
i
=
0
;
i
!=
routingIndex
;
++
i
)
routingOffset
+=
(
ushort
)
routing
[
i
].
Length
;
}
}
}
else
{
protocolType
=
EthernetType
.
PointToPointProtocol
;
isChecksum
=
false
;
key
=
random
.
NextUInt
();
}
return
new
GreLayer
{
Version
=
version
,
ProtocolType
=
protocolType
,
ChecksumPresent
=
isChecksum
,
Checksum
=
isChecksum
&&
random
.
NextBool
()
?
(
ushort
?)
random
.
NextUShort
()
:
null
,
Key
=
key
,
SequenceNumber
=
random
.
NextBool
()
?
(
uint
?)
random
.
NextUInt
()
:
null
,
AcknowledgmentSequenceNumber
=
version
==
GreVersion
.
EnhancedGre
&&
random
.
NextBool
()
?
(
uint
?)
random
.
NextUInt
()
:
null
,
RecursionControl
=
random
.
NextByte
(
8
),
// Flags = random.NextByte(32),
Routing
=
routing
==
null
?
null
:
routing
.
AsReadOnly
(),
RoutingOffset
=
routingOffset
,
StrictSourceRoute
=
strictSourceRoute
,
};
}
// ICMP
public
static
IcmpLayer
NextIcmpLayer
(
this
Random
random
)
{
IcmpMessageType
icmpMessageType
=
random
.
NextEnum
(
IcmpMessageType
.
DomainNameReply
);
ushort
?
checksum
=
random
.
NextBool
()
?
(
ushort
?)
random
.
NextUShort
()
:
null
;
switch
(
icmpMessageType
)
{
case
IcmpMessageType
.
DestinationUnreachable
:
return
new
IcmpDestinationUnreachableLayer
{
Code
=
random
.
NextEnum
<
IcmpCodeDestinationUnreachable
>(),
Checksum
=
checksum
,
NextHopMaximumTransmissionUnit
=
random
.
NextUShort
(),
};
case
IcmpMessageType
.
TimeExceeded
:
return
new
IcmpTimeExceededLayer
{
Code
=
random
.
NextEnum
<
IcmpCodeTimeExceeded
>(),
Checksum
=
checksum
,
};
case
IcmpMessageType
.
ParameterProblem
:
return
new
IcmpParameterProblemLayer
{
Checksum
=
checksum
,
Pointer
=
random
.
NextByte
()
};
case
IcmpMessageType
.
SourceQuench
:
return
new
IcmpSourceQuenchLayer
{
Checksum
=
checksum
};
case
IcmpMessageType
.
Redirect
:
return
new
IcmpRedirectLayer
{
Code
=
random
.
NextEnum
<
IcmpCodeRedirect
>(),
Checksum
=
checksum
,
GatewayInternetAddress
=
random
.
NextIpV4Address
()
};
case
IcmpMessageType
.
Echo
:
return
new
IcmpEchoLayer
{
Checksum
=
checksum
,
Identifier
=
random
.
NextUShort
(),
SequenceNumber
=
random
.
NextUShort
()
};
case
IcmpMessageType
.
EchoReply
:
return
new
IcmpEchoReplyLayer
{
Checksum
=
checksum
,
Identifier
=
random
.
NextUShort
(),
SequenceNumber
=
random
.
NextUShort
()
};
case
IcmpMessageType
.
Timestamp
:
return
new
IcmpTimestampLayer
{
Checksum
=
checksum
,
Identifier
=
random
.
NextUShort
(),
SequenceNumber
=
random
.
NextUShort
(),
OriginateTimestamp
=
random
.
NextIpV4TimeOfDay
(),
ReceiveTimestamp
=
random
.
NextIpV4TimeOfDay
(),
TransmitTimestamp
=
random
.
NextIpV4TimeOfDay
()
};
case
IcmpMessageType
.
TimestampReply
:
return
new
IcmpTimestampReplyLayer
{
Checksum
=
checksum
,
Identifier
=
random
.
NextUShort
(),
SequenceNumber
=
random
.
NextUShort
(),
OriginateTimestamp
=
random
.
NextIpV4TimeOfDay
(),
ReceiveTimestamp
=
random
.
NextIpV4TimeOfDay
(),
TransmitTimestamp
=
random
.
NextIpV4TimeOfDay
()
};
case
IcmpMessageType
.
InformationRequest
:
return
new
IcmpInformationRequestLayer
{
Checksum
=
checksum
,
Identifier
=
random
.
NextUShort
(),
SequenceNumber
=
random
.
NextUShort
(),
};
case
IcmpMessageType
.
InformationReply
:
return
new
IcmpInformationReplyLayer
{
Checksum
=
checksum
,
Identifier
=
random
.
NextUShort
(),
SequenceNumber
=
random
.
NextUShort
(),
};
case
IcmpMessageType
.
RouterAdvertisement
:
return
new
IcmpRouterAdvertisementLayer
{
Entries
=
random
.
NextIcmpRouterAdvertisementEntries
(
random
.
Next
(
10
)).
ToList
().
AsReadOnly
(),
Checksum
=
checksum
,
Lifetime
=
random
.
NextTimeSpan
(
TimeSpan
.
Zero
,
TimeSpan
.
FromSeconds
(
ushort
.
MaxValue
)),
};
case
IcmpMessageType
.
RouterSolicitation
:
return
new
IcmpRouterSolicitationLayer
{
Checksum
=
checksum
,
};
case
IcmpMessageType
.
AddressMaskRequest
:
return
new
IcmpAddressMaskRequestLayer
{
Checksum
=
checksum
,
Identifier
=
random
.
NextUShort
(),
SequenceNumber
=
random
.
NextUShort
(),
AddressMask
=
random
.
NextIpV4Address
()
};
case
IcmpMessageType
.
AddressMaskReply
:
return
new
IcmpAddressMaskReplyLayer
{
Checksum
=
checksum
,
Identifier
=
random
.
NextUShort
(),
SequenceNumber
=
random
.
NextUShort
(),
AddressMask
=
random
.
NextIpV4Address
()
};
case
IcmpMessageType
.
TraceRoute
:
return
new
IcmpTraceRouteLayer
{
Code
=
random
.
NextEnum
<
IcmpCodeTraceRoute
>(),
Checksum
=
checksum
,
Identification
=
random
.
NextUShort
(),
OutboundHopCount
=
random
.
NextUShort
(),
ReturnHopCount
=
random
.
NextUShort
(),
OutputLinkSpeed
=
random
.
NextUInt
(),
OutputLinkMaximumTransmissionUnit
=
random
.
NextUInt
(),
};
case
IcmpMessageType
.
ConversionFailed
:
return
new
IcmpConversionFailedLayer
{
Code
=
random
.
NextEnum
<
IcmpCodeConversionFailed
>(),
Checksum
=
checksum
,
Pointer
=
random
.
NextUInt
(),
};
case
IcmpMessageType
.
DomainNameRequest
:
return
new
IcmpDomainNameRequestLayer
{
Checksum
=
checksum
,
Identifier
=
random
.
NextUShort
(),
SequenceNumber
=
random
.
NextUShort
(),
};
case
IcmpMessageType
.
DomainNameReply
:
throw
new
NotSupportedException
(
"Message Type "
+
icmpMessageType
+
" is not supported"
);
case
IcmpMessageType
.
SecurityFailures
:
return
new
IcmpSecurityFailuresLayer
{
Code
=
random
.
NextEnum
<
IcmpCodeSecurityFailure
>(),
Checksum
=
checksum
,
Pointer
=
random
.
NextUShort
()
};
default
:
throw
new
InvalidOperationException
(
"Invalid icmpMessageType "
+
icmpMessageType
);
}
}
public
static
IEnumerable
<
ILayer
>
NextIcmpPayloadLayers
(
this
Random
random
,
IcmpLayer
icmpLayer
)
{
IEnumerable
<
ILayer
>
icmpPayloadLayers
=
new
List
<
ILayer
>();
switch
(
icmpLayer
.
MessageType
)
{
case
IcmpMessageType
.
DestinationUnreachable
:
case
IcmpMessageType
.
TimeExceeded
:
case
IcmpMessageType
.
ParameterProblem
:
case
IcmpMessageType
.
SourceQuench
:
case
IcmpMessageType
.
Redirect
:
case
IcmpMessageType
.
SecurityFailures
:
icmpPayloadLayers
=
icmpPayloadLayers
.
Concat
(
random
.
NextIpV4Layer
(),
random
.
NextPayloadLayer
(
IcmpIpV4HeaderPlus64BitsPayloadDatagram
.
OriginalDatagramPayloadLength
));
break
;
case
IcmpMessageType
.
ConversionFailed
:
IpV4Layer
icmpIpV4Layer
=
random
.
NextIpV4Layer
();
icmpPayloadLayers
=
icmpPayloadLayers
.
Concat
(
icmpIpV4Layer
);
if
(
icmpLayer
.
MessageTypeAndCode
==
IcmpMessageTypeAndCode
.
ConversionFailedUnsupportedTransportProtocol
)
{
icmpPayloadLayers
=
icmpPayloadLayers
.
Concat
(
random
.
NextPayloadLayer
(
IcmpConversionFailedDatagram
.
OriginalDatagramLengthForUnsupportedTransportProtocol
-
icmpIpV4Layer
.
Length
));
}
else
{
switch
(
icmpIpV4Layer
.
Protocol
)
{
case
IpV4Protocol
.
Udp
:
icmpPayloadLayers
=
icmpPayloadLayers
.
Concat
(
random
.
NextUdpLayer
(),
random
.
NextPayloadLayer
(
random
.
Next
(
100
)));
break
;
case
IpV4Protocol
.
Tcp
:
icmpPayloadLayers
=
icmpPayloadLayers
.
Concat
(
random
.
NextTcpLayer
(),
random
.
NextPayloadLayer
(
random
.
Next
(
100
)));
break
;
default
:
icmpPayloadLayers
=
icmpPayloadLayers
.
Concat
(
random
.
NextPayloadLayer
(
random
.
Next
(
200
)));
break
;
}
}
break
;
case
IcmpMessageType
.
Echo
:
case
IcmpMessageType
.
EchoReply
:
case
IcmpMessageType
.
Timestamp
:
case
IcmpMessageType
.
TimestampReply
:
case
IcmpMessageType
.
InformationRequest
:
case
IcmpMessageType
.
InformationReply
:
case
IcmpMessageType
.
RouterAdvertisement
:
case
IcmpMessageType
.
RouterSolicitation
:
case
IcmpMessageType
.
AddressMaskRequest
:
case
IcmpMessageType
.
AddressMaskReply
:
case
IcmpMessageType
.
TraceRoute
:
case
IcmpMessageType
.
DomainNameRequest
:
break
;
case
IcmpMessageType
.
DomainNameReply
:
default
:
throw
new
InvalidOperationException
(
"Invalid icmpMessageType "
+
icmpLayer
.
MessageType
);
}
return
icmpPayloadLayers
;
}
public
static
IEnumerable
<
IcmpRouterAdvertisementEntry
>
NextIcmpRouterAdvertisementEntries
(
this
Random
random
,
int
numEntries
)
{
for
(
int
i
=
0
;
i
!=
numEntries
;
++
i
)
yield
return
new
IcmpRouterAdvertisementEntry
(
random
.
NextIpV4Address
(),
random
.
Next
());
}
// DNS
public
static
DnsLayer
NextDnsLayer
(
this
Random
random
)
{
DnsLayer
dnsLayer
=
new
DnsLayer
();
dnsLayer
.
Id
=
random
.
NextUShort
();
dnsLayer
.
IsQuery
=
random
.
NextBool
();
dnsLayer
.
Opcode
=
random
.
NextEnum
<
DnsOpcode
>();
dnsLayer
.
IsAuthoritiveAnswer
=
random
.
NextBool
();
dnsLayer
.
IsTruncated
=
random
.
NextBool
();
dnsLayer
.
IsRecusionDesired
=
random
.
NextBool
();
dnsLayer
.
IsRecusionAvailable
=
random
.
NextBool
();
dnsLayer
.
FutureUse
=
random
.
NextByte
(
DnsDatagram
.
MaxFutureUse
+
1
);
dnsLayer
.
ResponseCode
=
random
.
NextEnum
<
DnsResponseCode
>();
dnsLayer
.
DomainNameCompressionMode
=
random
.
NextEnum
<
DnsDomainNameCompressionMode
>();
int
numQueries
=
random
.
Next
(
10
);
List
<
DnsQueryResourceRecord
>
queries
=
new
List
<
DnsQueryResourceRecord
>();
for
(
int
i
=
0
;
i
!=
numQueries
;
++
i
)
queries
.
Add
(
random
.
NextDnsQueryResourceRecord
());
dnsLayer
.
Queries
=
queries
;
int
numAnswers
=
random
.
Next
(
10
);
List
<
DnsDataResourceRecord
>
answers
=
new
List
<
DnsDataResourceRecord
>();
for
(
int
i
=
0
;
i
!=
numAnswers
;
++
i
)
answers
.
Add
(
random
.
NextDnsDataResourceRecord
());
dnsLayer
.
Answers
=
answers
;
int
numAuthorities
=
random
.
Next
(
10
);
List
<
DnsDataResourceRecord
>
authorities
=
new
List
<
DnsDataResourceRecord
>();
for
(
int
i
=
0
;
i
!=
numAuthorities
;
++
i
)
authorities
.
Add
(
random
.
NextDnsDataResourceRecord
());
dnsLayer
.
Authorities
=
authorities
;
int
numAdditionals
=
random
.
Next
(
10
);
List
<
DnsDataResourceRecord
>
additionals
=
new
List
<
DnsDataResourceRecord
>();
for
(
int
i
=
0
;
i
!=
numAdditionals
;
++
i
)
additionals
.
Add
(
random
.
NextDnsDataResourceRecord
());
dnsLayer
.
Additionals
=
additionals
;
return
dnsLayer
;
}
public
static
DnsQueryResourceRecord
NextDnsQueryResourceRecord
(
this
Random
random
)
{
DnsQueryResourceRecord
record
=
new
DnsQueryResourceRecord
(
random
.
NextDnsDomainName
(),
random
.
NextEnum
<
DnsType
>(),
random
.
NextEnum
<
DnsClass
>());
return
record
;
}
public
static
DnsDataResourceRecord
NextDnsDataResourceRecord
(
this
Random
random
)
{
DnsType
type
=
random
.
NextEnum
<
DnsType
>();
DnsDataResourceRecord
record
=
new
DnsDataResourceRecord
(
random
.
NextDnsDomainName
(),
type
,
random
.
NextEnum
<
DnsClass
>(),
random
.
Next
(),
random
.
NextDnsResourceData
(
type
));
return
record
;
}
public
static
DnsDomainName
NextDnsDomainName
(
this
Random
random
)
{
List
<
string
>
labels
=
new
List
<
string
>();
int
numLabels
=
random
.
Next
(
10
);
for
(
int
i
=
0
;
i
!=
numLabels
;
++
i
)
{
int
labelLength
=
random
.
Next
(
10
);
StringBuilder
label
=
new
StringBuilder
();
for
(
int
j
=
0
;
j
!=
labelLength
;
++
j
)
label
.
Append
(
random
.
NextChar
(
'a'
,
'z'
));
labels
.
Add
(
label
.
ToString
());
}
return
new
DnsDomainName
(
string
.
Join
(
"."
,
labels
));
}
public
static
DnsResourceData
NextDnsResourceData
(
this
Random
random
,
DnsType
type
)
{
switch
(
type
)
{
case
DnsType
.
A
:
return
new
DnsResourceDataIpV4
(
random
.
NextIpV4Address
());
default
:
return
new
DnsResourceDataUnknown
(
new
DataSegment
(
random
.
NextBytes
(
random
.
Next
(
100
))));
}
}
// HTTP
public
static
HttpLayer
NextHttpLayer
(
this
Random
random
)
{
if
(
random
.
NextBool
())
{
HttpRequestLayer
httpRequestLayer
=
new
HttpRequestLayer
();
if
(
random
.
NextBool
(
10
))
{
httpRequestLayer
.
Method
=
random
.
NextHttpRequestMethod
();
httpRequestLayer
.
Uri
=
httpRequestLayer
.
Method
==
null
?
null
:
random
.
NextHttpUri
();
httpRequestLayer
.
Version
=
httpRequestLayer
.
Uri
==
null
||
random
.
NextBool
(
10
)
?
null
:
random
.
NextHttpVersion
();
httpRequestLayer
.
Header
=
httpRequestLayer
.
Version
==
null
?
null
:
random
.
NextHttpHeader
();
httpRequestLayer
.
Body
=
httpRequestLayer
.
Header
==
null
?
null
:
random
.
NextHttpBody
(
true
,
null
,
httpRequestLayer
.
Header
);
}
return
httpRequestLayer
;
}
HttpResponseLayer
httpResponseLayer
=
new
HttpResponseLayer
{
Version
=
random
.
NextHttpVersion
(),
StatusCode
=
random
.
NextBool
(
10
)
?
null
:
(
uint
?)
random
.
NextUInt
(
100
,
999
),
};
httpResponseLayer
.
ReasonPhrase
=
httpResponseLayer
.
StatusCode
==
null
?
null
:
random
.
NextHttpReasonPhrase
();
httpResponseLayer
.
Header
=
httpResponseLayer
.
ReasonPhrase
==
null
?
null
:
random
.
NextHttpHeader
();
httpResponseLayer
.
Body
=
httpResponseLayer
.
Header
==
null
?
null
:
random
.
NextHttpBody
(
false
,
httpResponseLayer
.
StatusCode
,
httpResponseLayer
.
Header
);
return
httpResponseLayer
;
}
public
static
Datagram
NextHttpReasonPhrase
(
this
Random
random
)
{
int
reasonPhraseLength
=
random
.
Next
(
100
);
StringBuilder
reasonPhrase
=
new
StringBuilder
(
reasonPhraseLength
);
for
(
int
i
=
0
;
i
!=
reasonPhraseLength
;
++
i
)
{
if
(
random
.
NextBool
())
reasonPhrase
.
Append
(
random
.
NextHttpTextChar
());
else
if
(
random
.
NextBool
())
reasonPhrase
.
Append
(
' '
);
else
reasonPhrase
.
Append
(
'\t'
);
}
return
new
Datagram
(
EncodingExtensions
.
Iso88591
.
GetBytes
(
reasonPhrase
.
ToString
()));
}
public
static
HttpRequestMethod
NextHttpRequestMethod
(
this
Random
random
)
{
HttpRequestKnownMethod
knownMethod
=
random
.
NextEnum
<
HttpRequestKnownMethod
>();
if
(
knownMethod
==
HttpRequestKnownMethod
.
Unknown
)
return
new
HttpRequestMethod
(
random
.
NextHttpToken
());
return
new
HttpRequestMethod
(
knownMethod
);
}
public
static
string
NextHttpToken
(
this
Random
random
)
{
int
tokenLength
=
random
.
Next
(
1
,
100
);
StringBuilder
stringBuilder
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
!=
tokenLength
;
++
i
)
stringBuilder
.
Append
(
random
.
NextHttpTokenChar
());
return
stringBuilder
.
ToString
();
}
public
static
char
NextHttpTokenChar
(
this
Random
random
)
{
char
result
;
do
{
result
=
random
.
NextChar
((
char
)
33
,
(
char
)
127
);
}
while
(
new
[]
{
'('
,
')'
,
'<'
,
'>'
,
'@'
,
','
,
';'
,
':'
,
'\\'
,
'"'
,
'/'
,
'['
,
']'
,
'?'
,
'='
,
'{'
,
'}'
}.
Contains
(
result
));
return
result
;
}
public
static
string
NextHttpFieldValue
(
this
Random
random
)
{
int
valueLength
=
random
.
Next
(
1
,
100
);
StringBuilder
stringBuilder
=
new
StringBuilder
();
while
(
stringBuilder
.
Length
<
valueLength
)
{
switch
(
random
.
Next
(
3
))
{
case
0
:
stringBuilder
.
Append
(
random
.
NextHttpTextChar
());
break
;
case
1
:
stringBuilder
.
Append
(
random
.
NextHttpQuotedString
());
break
;
case
2
:
if
(
stringBuilder
.
Length
>
0
&&
stringBuilder
.
Length
<
valueLength
-
3
)
stringBuilder
.
Append
(
random
.
NextHttpLinearWhiteSpace
());
break
;
}
}
return
stringBuilder
.
ToString
();
}
public
static
string
NextHttpLinearWhiteSpace
(
this
Random
random
)
{
StringBuilder
stringBuilder
=
new
StringBuilder
();
if
(
random
.
NextBool
())
stringBuilder
.
Append
(
"\r\n"
);
stringBuilder
.
Append
(
random
.
NextBool
()
?
' '
:
'\t'
);
return
stringBuilder
.
ToString
();
}
public
static
char
NextHttpTextChar
(
this
Random
random
)
{
char
text
=
random
.
NextChar
((
char
)
33
,
(
char
)
254
);
if
(
text
==
'"'
)
return
(
char
)
254
;
if
(
text
==
127
)
return
(
char
)
255
;
return
text
;
}
public
static
string
NextHttpUri
(
this
Random
random
)
{
int
uriLength
=
random
.
Next
(
100
);
StringBuilder
stringBuilder
=
new
StringBuilder
();
for
(
int
i
=
0
;
i
!=
uriLength
;
++
i
)
stringBuilder
.
Append
(
random
.
NextChar
((
char
)
33
,
(
char
)
127
));
return
stringBuilder
.
ToString
();
}
public
static
HttpVersion
NextHttpVersion
(
this
Random
random
)
{
return
new
HttpVersion
(
random
.
NextUInt
(
10000000
),
random
.
NextUInt
(
10000000
));
}
public
static
HttpHeader
NextHttpHeader
(
this
Random
random
)
{
int
numFields
=
random
.
Next
(
100
);
List
<
HttpField
>
fields
=
new
List
<
HttpField
>(
numFields
);
HashSet
<
string
>
fieldNames
=
new
HashSet
<
string
>(
StringComparer
.
InvariantCultureIgnoreCase
);
for
(
int
i
=
0
;
i
!=
numFields
;
++
i
)
{
fields
.
Add
(
random
.
NextHttpField
(
fieldNames
));
fieldNames
.
Add
(
fields
.
Last
().
Name
);
}
return
new
HttpHeader
(
fields
);
}
public
static
HttpField
NextHttpField
(
this
Random
random
,
HashSet
<
string
>
fieldNames
)
{
const
string
unknownField
=
"Unknown Name"
;
List
<
string
>
allOptions
=
new
List
<
string
>
{
unknownField
,
HttpTransferEncodingField
.
FieldNameUpper
,
HttpContentLengthField
.
FieldNameUpper
,
HttpContentTypeField
.
FieldNameUpper
};
List
<
string
>
possibleOptions
=
new
List
<
string
>(
allOptions
.
Count
);
foreach
(
string
option
in
allOptions
)
{
if
(!
fieldNames
.
Contains
(
option
))
possibleOptions
.
Add
(
option
);
}
string
chosenOption
=
random
.
NextValue
(
possibleOptions
);
switch
(
chosenOption
)
{
case
unknownField
:
string
fieldName
;
do
{
fieldName
=
random
.
NextHttpToken
();
}
while
(
fieldNames
.
Contains
(
fieldName
));
return
HttpField
.
CreateField
(
fieldName
,
random
.
NextHttpFieldValue
());
case
HttpTransferEncodingField
.
FieldNameUpper
:
int
numTransferCodings
=
random
.
Next
(
1
,
10
);
List
<
string
>
transferCodings
=
new
List
<
string
>(
numTransferCodings
);
for
(
int
i
=
0
;
i
!=
numTransferCodings
;
++
i
)
transferCodings
.
Add
(
random
.
NextHttpTransferCoding
());
return
new
HttpTransferEncodingField
(
transferCodings
);
case
HttpContentLengthField
.
FieldNameUpper
:
return
new
HttpContentLengthField
(
random
.
NextUInt
(
1000
));
case
HttpContentTypeField
.
FieldNameUpper
:
return
new
HttpContentTypeField
(
random
.
NextHttpToken
(),
random
.
NextHttpToken
(),
random
.
NextHttpFieldParameters
());
default
:
throw
new
InvalidOperationException
(
"Invalid option "
+
chosenOption
);
}
}
public
static
HttpFieldParameters
NextHttpFieldParameters
(
this
Random
random
)
{
int
numParameters
=
random
.
Next
(
10
);
List
<
KeyValuePair
<
string
,
string
>>
parameters
=
new
List
<
KeyValuePair
<
string
,
string
>>(
numParameters
);
for
(
int
i
=
0
;
i
!=
numParameters
;
++
i
)
{
string
parameterName
=
random
.
NextHttpToken
();
while
(
parameters
.
Any
(
pair
=>
pair
.
Key
==
parameterName
))
parameterName
=
random
.
NextHttpToken
();
parameters
.
Add
(
new
KeyValuePair
<
string
,
string
>(
parameterName
,
random
.
NextBool
()
?
random
.
NextHttpToken
()
:
random
.
NextHttpQuotedString
()));
}
return
new
HttpFieldParameters
(
parameters
);
}
public
static
string
NextHttpTransferCoding
(
this
Random
random
)
{
if
(
random
.
NextBool
())
return
"chunked"
;
StringBuilder
transferCoding
=
new
StringBuilder
(
random
.
NextHttpToken
());
int
numParameters
=
random
.
Next
(
5
);
for
(
int
i
=
0
;
i
!=
numParameters
;
++
i
)
{
transferCoding
.
Append
(
';'
);
transferCoding
.
Append
(
random
.
NextHttpToken
());
transferCoding
.
Append
(
'='
);
if
(
random
.
NextBool
())
transferCoding
.
Append
(
random
.
NextHttpToken
());
else
transferCoding
.
Append
(
random
.
NextHttpQuotedString
());
}
return
transferCoding
.
ToString
();
}
public
static
string
NextHttpQuotedString
(
this
Random
random
)
{
StringBuilder
quotedString
=
new
StringBuilder
();
quotedString
.
Append
(
'"'
);
int
numQuotedValues
=
random
.
Next
(
100
);
for
(
int
i
=
0
;
i
!=
numQuotedValues
;
++
i
)
{
char
quotedValue
=
random
.
NextHttpTextChar
();
if
(
quotedValue
!=
'\\'
)
quotedString
.
Append
(
quotedValue
);
else
{
quotedString
.
Append
(
'\\'
);
quotedString
.
Append
(
random
.
NextChar
((
char
)
0
,
(
char
)
128
));
}
}
quotedString
.
Append
(
'"'
);
return
quotedString
.
ToString
();
}
public
static
Datagram
NextHttpBody
(
this
Random
random
,
bool
isRequest
,
uint
?
statusCode
,
HttpHeader
httpHeader
)
{
if
(
isRequest
&&
httpHeader
.
ContentLength
==
null
||
!
isRequest
&&
statusCode
>=
100
&&
statusCode
<=
199
||
statusCode
==
204
||
statusCode
==
205
||
statusCode
==
304
)
return
Datagram
.
Empty
;
if
(
httpHeader
.
TransferEncoding
!=
null
&&
httpHeader
.
TransferEncoding
.
TransferCodings
.
Any
(
coding
=>
coding
!=
"identity"
))
{
// chunked
List
<
byte
>
chunkedBody
=
new
List
<
byte
>();
int
numChunks
=
random
.
Next
(
10
);
for
(
int
i
=
0
;
i
!=
numChunks
;
++
i
)
{
int
chunkSize
=
random
.
Next
(
1
,
1000
);
chunkedBody
.
AddRange
(
Encoding
.
ASCII
.
GetBytes
(
chunkSize
.
ToString
(
"x"
)));
var
chunkExtension
=
random
.
NextHttpFieldParameters
();
foreach
(
var
parameter
in
chunkExtension
)
{
chunkedBody
.
Add
((
byte
)
';'
);
chunkedBody
.
AddRange
(
Encoding
.
ASCII
.
GetBytes
(
parameter
.
Key
));
chunkedBody
.
Add
((
byte
)
'='
);
chunkedBody
.
AddRange
(
EncodingExtensions
.
Iso88591
.
GetBytes
(
parameter
.
Key
));
}
chunkedBody
.
AddRange
(
Encoding
.
ASCII
.
GetBytes
(
"\r\n"
));
chunkedBody
.
AddRange
(
random
.
NextDatagram
(
chunkSize
));
chunkedBody
.
AddRange
(
Encoding
.
ASCII
.
GetBytes
(
"\r\n"
));
}
int
numZeros
=
random
.
Next
(
1
,
10
);
for
(
int
i
=
0
;
i
!=
numZeros
;
++
i
)
chunkedBody
.
Add
((
byte
)
'0'
);
var
lastChunkExtension
=
random
.
NextHttpFieldParameters
();
foreach
(
var
parameter
in
lastChunkExtension
)
{
chunkedBody
.
Add
((
byte
)
';'
);
chunkedBody
.
AddRange
(
Encoding
.
ASCII
.
GetBytes
(
parameter
.
Key
));
chunkedBody
.
Add
((
byte
)
'='
);
chunkedBody
.
AddRange
(
EncodingExtensions
.
Iso88591
.
GetBytes
(
parameter
.
Key
));
}
chunkedBody
.
AddRange
(
Encoding
.
ASCII
.
GetBytes
(
"\r\n"
));
var
trailer
=
random
.
NextHttpHeader
();
byte
[]
trailerBuffer
=
new
byte
[
trailer
.
BytesLength
];
trailer
.
Write
(
trailerBuffer
,
0
);
chunkedBody
.
AddRange
(
trailerBuffer
);
return
new
Datagram
(
chunkedBody
.
ToArray
());
}
if
(
httpHeader
.
ContentLength
!=
null
)
{
return
random
.
NextDatagram
(
random
.
Next
((
int
)(
httpHeader
.
ContentLength
.
ContentLength
+
1
)));
}
if
(
httpHeader
.
ContentType
!=
null
&&
httpHeader
.
ContentType
.
MediaType
==
"multipart"
&&
httpHeader
.
ContentType
.
MediaSubtype
==
"byteranges"
&&
httpHeader
.
ContentType
.
Parameters
[
"boundary"
]
!=
null
)
{
List
<
byte
>
boundedBody
=
new
List
<
byte
>(
random
.
NextDatagram
(
random
.
Next
(
1000
)));
boundedBody
.
AddRange
(
EncodingExtensions
.
Iso88591
.
GetBytes
(
"--"
+
httpHeader
.
ContentType
.
Parameters
[
"boundary"
]
+
"--"
));
return
new
Datagram
(
boundedBody
.
ToArray
());
}
return
random
.
NextDatagram
(
random
.
Next
(
1000
));
}
}
}
}
}
}
PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomTcpExtensions.cs
0 → 100644
View file @
64ffbb1d
using
System
;
using
System.Collections.Generic
;
using
PcapDotNet.Packets.Transport
;
using
PcapDotNet.TestUtils
;
namespace
PcapDotNet.Packets.TestUtils
{
public
static
class
RandomTcpExtensions
{
public
static
TcpLayer
NextTcpLayer
(
this
Random
random
)
{
return
new
TcpLayer
{
SourcePort
=
random
.
NextUShort
(),
DestinationPort
=
random
.
NextUShort
(),
SequenceNumber
=
random
.
NextUInt
(),
AcknowledgmentNumber
=
random
.
NextUInt
(),
ControlBits
=
random
.
NextFlags
<
TcpControlBits
>(),
Window
=
random
.
NextUShort
(),
UrgentPointer
=
random
.
NextUShort
(),
Options
=
random
.
NextTcpOptions
(),
};
}
public
static
TcpOptions
NextTcpOptions
(
this
Random
random
)
{
int
optionsLength
=
random
.
Next
(
TcpOptions
.
MaximumBytesLength
)
/
4
*
4
;
List
<
TcpOption
>
options
=
new
List
<
TcpOption
>();
while
(
optionsLength
>
0
)
{
TcpOption
option
=
random
.
NextTcpOption
(
optionsLength
);
if
(
option
.
IsAppearsAtMostOnce
&&
options
.
FindIndex
(
option
.
Equivalent
)
!=
-
1
)
{
continue
;
}
options
.
Add
(
option
);
optionsLength
-=
option
.
Length
;
if
(
option
.
OptionType
==
TcpOptionType
.
EndOfOptionList
)
break
;
}
return
new
TcpOptions
(
options
);
}
public
static
TcpOptionUnknown
NextTcpOptionUnknown
(
this
Random
random
,
int
maximumOptionLength
)
{
TcpOptionType
unknownOptionType
;
byte
unknownOptionTypeValue
;
do
{
unknownOptionTypeValue
=
random
.
NextByte
();
unknownOptionType
=
(
TcpOptionType
)
unknownOptionTypeValue
;
}
while
(
unknownOptionType
.
ToString
()
!=
unknownOptionTypeValue
.
ToString
());
byte
[]
unknownOptionData
=
random
.
NextBytes
(
maximumOptionLength
-
TcpOptionUnknown
.
OptionMinimumLength
+
1
);
return
new
TcpOptionUnknown
(
unknownOptionType
,
unknownOptionData
);
}
public
static
TcpOption
NextTcpOption
(
this
Random
random
,
int
maximumOptionLength
)
{
if
(
maximumOptionLength
==
0
)
throw
new
ArgumentOutOfRangeException
(
"maximumOptionLength"
,
maximumOptionLength
,
"option length must be positive"
);
if
(
maximumOptionLength
>=
TcpOptionUnknown
.
OptionMinimumLength
&&
random
.
Next
(
100
)
>
90
)
return
random
.
NextTcpOptionUnknown
(
maximumOptionLength
);
List
<
TcpOptionType
>
impossibleOptionTypes
=
new
List
<
TcpOptionType
>();
if
(
maximumOptionLength
<
TcpOptionMaximumSegmentSize
.
OptionLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
MaximumSegmentSize
);
if
(
maximumOptionLength
<
TcpOptionWindowScale
.
OptionLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
WindowScale
);
if
(
maximumOptionLength
<
TcpOptionSelectiveAcknowledgment
.
OptionMinimumLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
SelectiveAcknowledgment
);
if
(
maximumOptionLength
<
TcpOptionSelectiveAcknowledgmentPermitted
.
OptionLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
SelectiveAcknowledgmentPermitted
);
if
(
maximumOptionLength
<
TcpOptionEcho
.
OptionLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
Echo
);
if
(
maximumOptionLength
<
TcpOptionEchoReply
.
OptionLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
EchoReply
);
if
(
maximumOptionLength
<
TcpOptionTimestamp
.
OptionLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
Timestamp
);
if
(
maximumOptionLength
<
TcpOptionPartialOrderServiceProfile
.
OptionLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
PartialOrderServiceProfile
);
if
(
maximumOptionLength
<
TcpOptionPartialOrderConnectionPermitted
.
OptionLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
PartialOrderConnectionPermitted
);
if
(
maximumOptionLength
<
TcpOptionConnectionCountBase
.
OptionLength
)
{
impossibleOptionTypes
.
Add
(
TcpOptionType
.
ConnectionCount
);
impossibleOptionTypes
.
Add
(
TcpOptionType
.
ConnectionCountNew
);
impossibleOptionTypes
.
Add
(
TcpOptionType
.
ConnectionCountEcho
);
}
if
(
maximumOptionLength
<
TcpOptionAlternateChecksumRequest
.
OptionLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
AlternateChecksumRequest
);
if
(
maximumOptionLength
<
TcpOptionAlternateChecksumData
.
OptionMinimumLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
AlternateChecksumData
);
if
(
maximumOptionLength
<
TcpOptionMd5Signature
.
OptionLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
Md5Signature
);
if
(
maximumOptionLength
<
TcpOptionMood
.
OptionMaximumLength
)
impossibleOptionTypes
.
Add
(
TcpOptionType
.
Mood
);
impossibleOptionTypes
.
Add
(
TcpOptionType
.
QuickStartResponse
);
impossibleOptionTypes
.
Add
(
TcpOptionType
.
UserTimeout
);
TcpOptionType
optionType
=
random
.
NextEnum
<
TcpOptionType
>(
impossibleOptionTypes
);
switch
(
optionType
)
{
case
TcpOptionType
.
EndOfOptionList
:
return
TcpOption
.
End
;
case
TcpOptionType
.
NoOperation
:
return
TcpOption
.
Nop
;
case
TcpOptionType
.
MaximumSegmentSize
:
return
new
TcpOptionMaximumSegmentSize
(
random
.
NextUShort
());
case
TcpOptionType
.
WindowScale
:
return
new
TcpOptionWindowScale
(
random
.
NextByte
());
case
TcpOptionType
.
SelectiveAcknowledgment
:
int
numBlocks
=
random
.
Next
((
maximumOptionLength
-
TcpOptionSelectiveAcknowledgment
.
OptionMinimumLength
)
/
8
+
1
);
TcpOptionSelectiveAcknowledgmentBlock
[]
blocks
=
new
TcpOptionSelectiveAcknowledgmentBlock
[
numBlocks
];
for
(
int
i
=
0
;
i
!=
numBlocks
;
++
i
)
blocks
[
i
]
=
new
TcpOptionSelectiveAcknowledgmentBlock
(
random
.
NextUInt
(),
random
.
NextUInt
());
return
new
TcpOptionSelectiveAcknowledgment
(
blocks
);
case
TcpOptionType
.
SelectiveAcknowledgmentPermitted
:
return
new
TcpOptionSelectiveAcknowledgmentPermitted
();
case
TcpOptionType
.
Echo
:
return
new
TcpOptionEcho
(
random
.
NextUInt
());
case
TcpOptionType
.
EchoReply
:
return
new
TcpOptionEchoReply
(
random
.
NextUInt
());
case
TcpOptionType
.
Timestamp
:
return
new
TcpOptionTimestamp
(
random
.
NextUInt
(),
random
.
NextUInt
());
case
TcpOptionType
.
PartialOrderServiceProfile
:
return
new
TcpOptionPartialOrderServiceProfile
(
random
.
NextBool
(),
random
.
NextBool
());
case
TcpOptionType
.
PartialOrderConnectionPermitted
:
return
new
TcpOptionPartialOrderConnectionPermitted
();
case
TcpOptionType
.
ConnectionCount
:
return
new
TcpOptionConnectionCount
(
random
.
NextUInt
());
case
TcpOptionType
.
ConnectionCountEcho
:
return
new
TcpOptionConnectionCountEcho
(
random
.
NextUInt
());
case
TcpOptionType
.
ConnectionCountNew
:
return
new
TcpOptionConnectionCountNew
(
random
.
NextUInt
());
case
TcpOptionType
.
AlternateChecksumRequest
:
return
new
TcpOptionAlternateChecksumRequest
(
random
.
NextEnum
<
TcpOptionAlternateChecksumType
>());
case
TcpOptionType
.
AlternateChecksumData
:
return
new
TcpOptionAlternateChecksumData
(
random
.
NextBytes
(
random
.
Next
(
maximumOptionLength
-
TcpOptionAlternateChecksumData
.
OptionMinimumLength
+
1
)));
case
TcpOptionType
.
Md5Signature
:
return
new
TcpOptionMd5Signature
(
random
.
NextBytes
(
TcpOptionMd5Signature
.
OptionValueLength
));
case
TcpOptionType
.
Mood
:
return
new
TcpOptionMood
(
random
.
NextEnum
(
TcpOptionMoodEmotion
.
None
));
default
:
throw
new
InvalidOperationException
(
"optionType = "
+
optionType
);
}
}
}
}
\ No newline at end of file
PcapDotNet/src/PcapDotNet.Packets.TestUtils/RandomUdpExtensions.cs
0 → 100644
View file @
64ffbb1d
using
System
;
using
PcapDotNet.Packets.Transport
;
using
PcapDotNet.TestUtils
;
namespace
PcapDotNet.Packets.TestUtils
{
public
static
class
RandomUdpExtensions
{
public
static
UdpLayer
NextUdpLayer
(
this
Random
random
)
{
return
new
UdpLayer
{
Checksum
=
random
.
NextUShort
(),
SourcePort
=
random
.
NextUShort
(),
DestinationPort
=
random
.
NextUShort
(),
CalculateChecksumValue
=
random
.
NextBool
()
};
}
}
}
\ No newline at end of file
PcapDotNet/src/PcapDotNet.Packets/DataSegment.cs
View file @
64ffbb1d
...
@@ -130,9 +130,17 @@ namespace PcapDotNet.Packets
...
@@ -130,9 +130,17 @@ namespace PcapDotNet.Packets
return
encoding
.
GetString
(
Buffer
,
StartOffset
,
Length
);
return
encoding
.
GetString
(
Buffer
,
StartOffset
,
Length
);
}
}
internal
void
Write
(
byte
[]
buffer
,
int
offset
)
public
static
DataSegment
Empty
{
get
{
return
_empty
;
}
}
internal
void
Write
(
byte
[]
buffer
,
ref
int
offset
)
{
{
Buffer
.
BlockCopy
(
StartOffset
,
buffer
,
offset
,
Length
);
Buffer
.
BlockCopy
(
StartOffset
,
buffer
,
offset
,
Length
);
offset
+=
Length
;
}
internal
void
Write
(
byte
[]
buffer
,
int
offset
)
{
Write
(
buffer
,
ref
offset
);
}
}
/// <summary>
/// <summary>
...
@@ -157,9 +165,16 @@ namespace PcapDotNet.Packets
...
@@ -157,9 +165,16 @@ namespace PcapDotNet.Packets
return
Buffer
.
ReadBytes
(
StartOffset
+
offset
,
length
);
return
Buffer
.
ReadBytes
(
StartOffset
+
offset
,
length
);
}
}
internal
DataSegment
SubSegment
(
ref
int
offset
,
int
length
)
{
DataSegment
subSegemnt
=
new
DataSegment
(
Buffer
,
StartOffset
+
offset
,
length
);
offset
+=
length
;
return
subSegemnt
;
}
internal
DataSegment
SubSegment
(
int
offset
,
int
length
)
internal
DataSegment
SubSegment
(
int
offset
,
int
length
)
{
{
return
new
DataSegment
(
Buffer
,
StartOffset
+
offset
,
length
);
return
SubSegment
(
ref
offset
,
length
);
}
}
internal
bool
ReadBool
(
int
offset
,
byte
mask
)
internal
bool
ReadBool
(
int
offset
,
byte
mask
)
...
@@ -198,7 +213,7 @@ namespace PcapDotNet.Packets
...
@@ -198,7 +213,7 @@ namespace PcapDotNet.Packets
/// <param name="endianity">The endianity to use to translate the bytes to the value.</param>
/// <param name="endianity">The endianity to use to translate the bytes to the value.</param>
/// <returns>The value converted from the read bytes according to the endianity.</returns>
/// <returns>The value converted from the read bytes according to the endianity.</returns>
[
System
.
Diagnostics
.
CodeAnalysis
.
SuppressMessage
(
"Microsoft.Naming"
,
"CA1720:IdentifiersShouldNotContainTypeNames"
,
MessageId
=
"uint"
)]
[
System
.
Diagnostics
.
CodeAnalysis
.
SuppressMessage
(
"Microsoft.Naming"
,
"CA1720:IdentifiersShouldNotContainTypeNames"
,
MessageId
=
"uint"
)]
protected
uint
ReadUInt
(
int
offset
,
Endianity
endianity
)
internal
uint
ReadUInt
(
int
offset
,
Endianity
endianity
)
{
{
return
Buffer
.
ReadUInt
(
StartOffset
+
offset
,
endianity
);
return
Buffer
.
ReadUInt
(
StartOffset
+
offset
,
endianity
);
}
}
...
@@ -278,5 +293,7 @@ namespace PcapDotNet.Packets
...
@@ -278,5 +293,7 @@ namespace PcapDotNet.Packets
sum
+=
(
ushort
)(
buffer
[
offset
]
<<
8
);
sum
+=
(
ushort
)(
buffer
[
offset
]
<<
8
);
return
sum
;
return
sum
;
}
}
private
static
readonly
DataSegment
_empty
=
new
DataSegment
(
new
byte
[
0
]);
}
}
}
}
\ No newline at end of file
PcapDotNet/src/PcapDotNet.Packets/Dns/DnsDataResourceRecord.cs
View file @
64ffbb1d
...
@@ -68,7 +68,7 @@ namespace PcapDotNet.Packets.Dns
...
@@ -68,7 +68,7 @@ namespace PcapDotNet.Packets.Dns
numBytesRead
+=
MinimumLengthAfterBase
;
numBytesRead
+=
MinimumLengthAfterBase
;
if
(
offsetInDns
+
numBytesRead
+
dataLength
>
dns
.
Length
)
if
(
offsetInDns
+
numBytesRead
+
dataLength
>
dns
.
Length
)
return
null
;
return
null
;
DnsResourceData
data
=
DnsResourceData
.
Read
(
type
,
dnsClass
,
dns
.
SubSegment
(
offsetInDns
+
numBytesRead
,
dataLength
)
);
DnsResourceData
data
=
DnsResourceData
.
Read
(
dns
,
type
,
dnsClass
,
offsetInDns
+
numBytesRead
,
dataLength
);
if
(
data
==
null
)
if
(
data
==
null
)
return
null
;
return
null
;
numBytesRead
+=
dataLength
;
numBytesRead
+=
dataLength
;
...
...
PcapDotNet/src/PcapDotNet.Packets/Dns/DnsDomainName.cs
View file @
64ffbb1d
...
@@ -13,7 +13,7 @@ namespace PcapDotNet.Packets.Dns
...
@@ -13,7 +13,7 @@ namespace PcapDotNet.Packets.Dns
{
{
private
const
byte
MaxLabelLength
=
63
;
private
const
byte
MaxLabelLength
=
63
;
private
const
ushort
CompressionMarker
=
0xC000
;
private
const
ushort
CompressionMarker
=
0xC000
;
private
const
ushort
OffsetMask
=
0x3FFF
;
internal
const
ushort
OffsetMask
=
0x3FFF
;
private
static
readonly
char
[]
Colon
=
new
[]
{
'.'
};
private
static
readonly
char
[]
Colon
=
new
[]
{
'.'
};
public
DnsDomainName
(
string
domainName
)
public
DnsDomainName
(
string
domainName
)
...
@@ -22,6 +22,8 @@ namespace PcapDotNet.Packets.Dns
...
@@ -22,6 +22,8 @@ namespace PcapDotNet.Packets.Dns
_labels
=
labels
.
Select
(
label
=>
new
DataSegment
(
Encoding
.
UTF8
.
GetBytes
(
label
))).
ToList
();
_labels
=
labels
.
Select
(
label
=>
new
DataSegment
(
Encoding
.
UTF8
.
GetBytes
(
label
))).
ToList
();
}
}
public
static
DnsDomainName
Root
{
get
{
return
_root
;
}
}
public
int
NumLabels
public
int
NumLabels
{
{
get
get
...
@@ -61,11 +63,16 @@ namespace PcapDotNet.Packets.Dns
...
@@ -61,11 +63,16 @@ namespace PcapDotNet.Packets.Dns
return
length
+
sizeof
(
byte
);
return
length
+
sizeof
(
byte
);
}
}
internal
static
DnsDomainName
Parse
(
DnsDatagram
dns
,
int
offsetInDns
,
out
int
numBytesRead
)
internal
static
bool
TryParse
(
DnsDatagram
dns
,
int
offsetInDns
,
int
maximumLength
,
out
DnsDomainName
domainName
,
out
int
numBytesRead
)
{
{
List
<
DataSegment
>
labels
=
new
List
<
DataSegment
>();
List
<
DataSegment
>
labels
=
new
List
<
DataSegment
>();
ReadLabels
(
dns
,
offsetInDns
,
out
numBytesRead
,
labels
);
if
(!
TryReadLabels
(
dns
,
offsetInDns
,
out
numBytesRead
,
labels
)
||
numBytesRead
>
maximumLength
)
return
new
DnsDomainName
(
labels
);
{
domainName
=
null
;
return
false
;
}
domainName
=
new
DnsDomainName
(
labels
);
return
true
;
}
}
internal
int
Write
(
byte
[]
buffer
,
int
dnsOffset
,
DnsDomainNameCompressionData
compressionData
,
int
offsetInDns
)
internal
int
Write
(
byte
[]
buffer
,
int
dnsOffset
,
DnsDomainNameCompressionData
compressionData
,
int
offsetInDns
)
...
@@ -95,40 +102,45 @@ namespace PcapDotNet.Packets.Dns
...
@@ -95,40 +102,45 @@ namespace PcapDotNet.Packets.Dns
_labels
=
labels
;
_labels
=
labels
;
}
}
private
static
void
ReadLabels
(
DnsDatagram
dns
,
int
offsetInDns
,
out
int
numBytesRead
,
List
<
DataSegment
>
labels
)
private
static
bool
Try
ReadLabels
(
DnsDatagram
dns
,
int
offsetInDns
,
out
int
numBytesRead
,
List
<
DataSegment
>
labels
)
{
{
numBytesRead
=
0
;
numBytesRead
=
0
;
byte
labelLength
;
byte
labelLength
;
do
do
{
{
if
(
offsetInDns
>=
dns
.
Length
)
if
(
offsetInDns
>=
dns
.
Length
)
return
;
return
false
;
// Can't read label's length.
labelLength
=
dns
[
offsetInDns
];
labelLength
=
dns
[
offsetInDns
];
++
numBytesRead
;
++
numBytesRead
;
if
(
labelLength
>
MaxLabelLength
)
if
(
labelLength
>
MaxLabelLength
)
{
{
// Compression.
// Compression.
if
(
offsetInDns
+
1
>=
dns
.
Length
)
if
(
offsetInDns
+
1
>=
dns
.
Length
)
return
;
return
false
;
// Can't read compression pointer.
offsetInDns
=
dns
.
ReadUShort
(
offsetInDns
,
Endianity
.
Big
)
&
OffsetMask
;
int
newOffsetInDns
=
dns
.
ReadUShort
(
offsetInDns
,
Endianity
.
Big
)
&
OffsetMask
;
if
(
newOffsetInDns
>=
offsetInDns
)
return
false
;
// Can't handle pointers that are not back pointers.
++
numBytesRead
;
++
numBytesRead
;
int
internalBytesRead
;
int
internalBytesRead
;
ReadLabels
(
dns
,
offsetInDns
,
out
internalBytesRead
,
labels
);
return
TryReadLabels
(
dns
,
newOffsetInDns
,
out
internalBytesRead
,
labels
);
return
;
}
}
if
(
labelLength
!=
0
)
if
(
labelLength
!=
0
)
{
{
++
offsetInDns
;
++
offsetInDns
;
if
(
offsetInDns
+
labelLength
>=
dns
.
Length
)
if
(
offsetInDns
+
labelLength
>=
dns
.
Length
)
return
;
return
false
;
// Can't read label.
labels
.
Add
(
dns
.
SubSegment
(
offsetInDns
,
labelLength
));
labels
.
Add
(
dns
.
SubSegment
(
offsetInDns
,
labelLength
));
numBytesRead
+=
labelLength
;
numBytesRead
+=
labelLength
;
offsetInDns
+=
labelLength
;
offsetInDns
+=
labelLength
;
}
}
}
while
(
labelLength
!=
0
);
}
while
(
labelLength
!=
0
);
return
true
;
}
}
private
static
readonly
DnsDomainName
_root
=
new
DnsDomainName
(
""
);
private
readonly
List
<
DataSegment
>
_labels
;
private
readonly
List
<
DataSegment
>
_labels
;
private
string
_ascii
;
private
string
_ascii
;
}
}
...
...
PcapDotNet/src/PcapDotNet.Packets/Dns/DnsDomainNameCompressionData.cs
View file @
64ffbb1d
...
@@ -36,6 +36,9 @@ namespace PcapDotNet.Packets.Dns
...
@@ -36,6 +36,9 @@ namespace PcapDotNet.Packets.Dns
public
void
AddCompressionData
(
ListSegment
<
DataSegment
>
labels
,
int
dnsOffset
)
public
void
AddCompressionData
(
ListSegment
<
DataSegment
>
labels
,
int
dnsOffset
)
{
{
if
(
dnsOffset
>
DnsDomainName
.
OffsetMask
)
return
;
switch
(
DomainNameCompressionMode
)
switch
(
DomainNameCompressionMode
)
{
{
case
DnsDomainNameCompressionMode
.
All
:
case
DnsDomainNameCompressionMode
.
All
:
...
...
PcapDotNet/src/PcapDotNet.Packets/Dns/DnsResourceData.cs
View file @
64ffbb1d
using
System
;
using
System
;
using
System.Collections.Generic
;
using
System.Collections.Generic
;
using
System.Collections.ObjectModel
;
using
System.Linq
;
using
System.Linq
;
using
System.Reflection
;
using
System.Reflection
;
using
PcapDotNet.Base
;
using
PcapDotNet.Base
;
using
PcapDotNet.Packets.IpV4
;
using
PcapDotNet.Packets.IpV4
;
namespace
PcapDotNet.Packets.Dns
namespace
PcapDotNet.Packets.Dns
{
{
[
AttributeUsage
(
AttributeTargets
.
Class
,
AllowMultiple
=
true
)]
internal
class
DnsTypeRegistrationAttribute
:
Attribute
internal
class
DnsTypeRegistrationAttribute
:
Attribute
{
{
public
DnsType
Type
{
get
;
set
;
}
public
DnsType
Type
{
get
;
set
;
}
...
@@ -34,15 +35,15 @@ namespace PcapDotNet.Packets.Dns
...
@@ -34,15 +35,15 @@ namespace PcapDotNet.Packets.Dns
internal
abstract
int
WriteData
(
byte
[]
buffer
,
int
dnsOffset
,
int
offsetInDns
,
DnsDomainNameCompressionData
compressionData
);
internal
abstract
int
WriteData
(
byte
[]
buffer
,
int
dnsOffset
,
int
offsetInDns
,
DnsDomainNameCompressionData
compressionData
);
internal
static
DnsResourceData
Read
(
Dns
Type
type
,
DnsClass
dnsClass
,
DataSegment
data
)
internal
static
DnsResourceData
Read
(
Dns
Datagram
dns
,
DnsType
type
,
DnsClass
dnsClass
,
int
offsetInDns
,
int
length
)
{
{
DnsResourceData
prototype
=
TryGetPrototype
(
type
,
dnsClass
);
DnsResourceData
prototype
=
TryGetPrototype
(
type
,
dnsClass
);
if
(
prototype
!=
null
)
if
(
prototype
!=
null
)
return
prototype
.
CreateInstance
(
d
ata
);
return
prototype
.
CreateInstance
(
d
ns
,
offsetInDns
,
length
);
return
new
DnsResourceData
Unknown
(
data
);
return
new
DnsResourceData
Anything
(
dns
.
SubSegment
(
offsetInDns
,
length
)
);
}
}
internal
abstract
DnsResourceData
CreateInstance
(
D
ataSegment
data
);
internal
abstract
DnsResourceData
CreateInstance
(
D
nsDatagram
dns
,
int
offsetInDns
,
int
length
);
private
static
DnsResourceData
TryGetPrototype
(
DnsType
type
,
DnsClass
dnsClass
)
private
static
DnsResourceData
TryGetPrototype
(
DnsType
type
,
DnsClass
dnsClass
)
{
{
...
@@ -56,11 +57,11 @@ namespace PcapDotNet.Packets.Dns
...
@@ -56,11 +57,11 @@ namespace PcapDotNet.Packets.Dns
{
{
var
prototypes
=
var
prototypes
=
from
type
in
Assembly
.
GetExecutingAssembly
().
GetTypes
()
from
type
in
Assembly
.
GetExecutingAssembly
().
GetTypes
()
where
typeof
(
DnsResourceData
).
IsAssignableFrom
(
type
)
&&
from
attribute
in
type
.
GetCustomAttributes
<
DnsTypeRegistrationAttribute
>(
false
)
type
.
GetCustomAttributes
<
DnsTypeRegistrationAttribute
>(
false
).
Any
(
)
where
typeof
(
DnsResourceData
).
IsAssignableFrom
(
type
)
select
new
select
new
{
{
type
.
GetCustomAttributes
<
DnsTypeRegistrationAttribute
>(
false
).
First
()
.
Type
,
attribute
.
Type
,
Prototype
=
(
DnsResourceData
)
Activator
.
CreateInstance
(
type
),
Prototype
=
(
DnsResourceData
)
Activator
.
CreateInstance
(
type
),
};
};
...
@@ -96,12 +97,20 @@ namespace PcapDotNet.Packets.Dns
...
@@ -96,12 +97,20 @@ namespace PcapDotNet.Packets.Dns
}
}
internal
abstract
void
WriteDataSimple
(
byte
[]
buffer
,
int
offset
);
internal
abstract
void
WriteDataSimple
(
byte
[]
buffer
,
int
offset
);
internal
sealed
override
DnsResourceData
CreateInstance
(
DnsDatagram
dns
,
int
offsetInDns
,
int
length
)
{
return
CreateInstance
(
dns
.
SubSegment
(
offsetInDns
,
length
));
}
internal
abstract
DnsResourceData
CreateInstance
(
DataSegment
data
);
}
}
[
DnsTypeRegistration
(
Type
=
DnsType
.
A
)]
[
DnsTypeRegistration
(
Type
=
DnsType
.
A
)]
public
class
DnsResourceDataIpV4
:
DnsResourceDataSimple
,
IEquatable
<
DnsResourceDataIpV4
>
public
sealed
class
DnsResourceDataIpV4
:
DnsResourceDataSimple
,
IEquatable
<
DnsResourceDataIpV4
>
{
{
public
DnsResourceDataIpV4
()
public
DnsResourceDataIpV4
()
:
this
(
IpV4Address
.
Zero
)
{
{
}
}
...
@@ -117,25 +126,780 @@ namespace PcapDotNet.Packets.Dns
...
@@ -117,25 +126,780 @@ namespace PcapDotNet.Packets.Dns
return
other
!=
null
&&
Data
.
Equals
(
other
.
Data
);
return
other
!=
null
&&
Data
.
Equals
(
other
.
Data
);
}
}
public
sealed
override
bool
Equals
(
DnsResourceData
other
)
public
override
bool
Equals
(
DnsResourceData
other
)
{
{
return
Equals
(
other
as
DnsResourceDataIpV4
);
return
Equals
(
other
as
DnsResourceDataIpV4
);
}
}
internal
sealed
override
int
GetLength
()
internal
override
int
GetLength
()
{
{
return
IpV4Address
.
SizeOf
;
return
IpV4Address
.
SizeOf
;
}
}
internal
sealed
override
void
WriteDataSimple
(
byte
[]
buffer
,
int
offset
)
internal
override
void
WriteDataSimple
(
byte
[]
buffer
,
int
offset
)
{
{
buffer
.
Write
(
offset
,
Data
,
Endianity
.
Big
);
buffer
.
Write
(
offset
,
Data
,
Endianity
.
Big
);
}
}
internal
sealed
override
DnsResourceData
CreateInstance
(
DataSegment
data
)
internal
override
DnsResourceData
CreateInstance
(
DataSegment
data
)
{
{
if
(
data
.
Length
!=
IpV4Address
.
SizeOf
)
return
null
;
return
new
DnsResourceDataIpV4
(
data
.
ReadIpV4Address
(
0
,
Endianity
.
Big
));
return
new
DnsResourceDataIpV4
(
data
.
ReadIpV4Address
(
0
,
Endianity
.
Big
));
}
}
}
[
DnsTypeRegistration
(
Type
=
DnsType
.
Ns
)]
[
DnsTypeRegistration
(
Type
=
DnsType
.
Md
)]
[
DnsTypeRegistration
(
Type
=
DnsType
.
Mf
)]
[
DnsTypeRegistration
(
Type
=
DnsType
.
CName
)]
[
DnsTypeRegistration
(
Type
=
DnsType
.
Mb
)]
[
DnsTypeRegistration
(
Type
=
DnsType
.
Mg
)]
[
DnsTypeRegistration
(
Type
=
DnsType
.
Mr
)]
[
DnsTypeRegistration
(
Type
=
DnsType
.
Ptr
)]
public
sealed
class
DnsResourceDataDomainName
:
DnsResourceData
,
IEquatable
<
DnsResourceDataDomainName
>
{
public
DnsResourceDataDomainName
()
:
this
(
DnsDomainName
.
Root
)
{
}
public
DnsResourceDataDomainName
(
DnsDomainName
data
)
{
Data
=
data
;
}
public
DnsDomainName
Data
{
get
;
private
set
;
}
public
bool
Equals
(
DnsResourceDataDomainName
other
)
{
return
other
!=
null
&&
Data
.
Equals
(
other
.
Data
);
}
public
override
bool
Equals
(
DnsResourceData
other
)
{
return
Equals
(
other
as
DnsResourceDataDomainName
);
}
internal
override
int
GetLength
(
DnsDomainNameCompressionData
compressionData
,
int
offsetInDns
)
{
return
Data
.
GetLength
(
compressionData
,
offsetInDns
);
}
internal
override
int
WriteData
(
byte
[]
buffer
,
int
dnsOffset
,
int
offsetInDns
,
DnsDomainNameCompressionData
compressionData
)
{
return
Data
.
Write
(
buffer
,
dnsOffset
,
compressionData
,
offsetInDns
);
}
internal
override
DnsResourceData
CreateInstance
(
DnsDatagram
dns
,
int
offsetInDns
,
int
length
)
{
int
numBytesRead
;
DnsDomainName
domainName
;
if
(!
DnsDomainName
.
TryParse
(
dns
,
offsetInDns
,
length
,
out
domainName
,
out
numBytesRead
))
return
null
;
length
-=
numBytesRead
;
if
(
length
!=
0
)
return
null
;
return
new
DnsResourceDataDomainName
(
domainName
);
}
}
/// <summary>
/// +-------+---------+
/// | bit | 0-31 |
/// +-------+---------+
/// | 0 | MNAME |
/// +-------+---------+
/// | X | RNAME |
/// +-------+---------+
/// | Y | SERIAL |
/// +-------+---------+
/// | Y+32 | REFRESH |
/// +-------+---------+
/// | Y+64 | RETRY |
/// +-------+---------+
/// | Y+96 | EXPIRE |
/// +-------+---------+
/// | Y+128 | MINIMUM |
/// +-------+---------+
/// </summary>
[
DnsTypeRegistration
(
Type
=
DnsType
.
Soa
)]
public
sealed
class
DnsResourceDataStartOfAuthority
:
DnsResourceData
,
IEquatable
<
DnsResourceDataStartOfAuthority
>
{
private
static
class
Offset
{
public
const
int
Serial
=
0
;
public
const
int
Refresh
=
Serial
+
sizeof
(
uint
);
public
const
int
Retry
=
Refresh
+
sizeof
(
uint
);
public
const
int
Expire
=
Retry
+
sizeof
(
uint
);
public
const
int
MinimumTtl
=
Expire
+
sizeof
(
uint
);
}
private
const
int
ConstantPartLength
=
Offset
.
MinimumTtl
+
sizeof
(
uint
);
public
DnsResourceDataStartOfAuthority
()
:
this
(
DnsDomainName
.
Root
,
DnsDomainName
.
Root
,
0
,
0
,
0
,
0
,
0
)
{
}
public
DnsResourceDataStartOfAuthority
(
DnsDomainName
mainNameServer
,
DnsDomainName
responsibleMailBox
,
uint
serial
,
uint
refresh
,
uint
retry
,
uint
expire
,
uint
minimumTtl
)
{
MainNameServer
=
mainNameServer
;
ResponsibleMailBox
=
responsibleMailBox
;
Serial
=
serial
;
Refresh
=
refresh
;
Retry
=
retry
;
Expire
=
expire
;
MinimumTtl
=
minimumTtl
;
}
/// <summary>
/// The domain-name of the name server that was the original or primary source of data for this zone.
/// </summary>
public
DnsDomainName
MainNameServer
{
get
;
private
set
;
}
/// <summary>
/// A domain-name which specifies the mailbox of the person responsible for this zone.
/// </summary>
public
DnsDomainName
ResponsibleMailBox
{
get
;
private
set
;
}
/// <summary>
/// The unsigned 32 bit version number of the original copy of the zone.
/// Zone transfers preserve this value.
/// This value wraps and should be compared using sequence space arithmetic.
/// </summary>
public
uint
Serial
{
get
;
private
set
;
}
/// <summary>
/// A 32 bit time interval before the zone should be refreshed.
/// </summary>
public
uint
Refresh
{
get
;
private
set
;
}
/// <summary>
/// A 32 bit time interval that should elapse before a failed refresh should be retried.
/// </summary>
public
uint
Retry
{
get
;
private
set
;
}
/// <summary>
/// A 32 bit time value that specifies the upper limit on the time interval that can elapse before the zone is no longer authoritative.
/// </summary>
public
uint
Expire
{
get
;
private
set
;
}
/// <summary>
/// The unsigned 32 bit minimum TTL field that should be exported with any RR from this zone.
/// </summary>
public
uint
MinimumTtl
{
get
;
private
set
;
}
public
bool
Equals
(
DnsResourceDataStartOfAuthority
other
)
{
return
other
!=
null
&&
MainNameServer
.
Equals
(
other
.
MainNameServer
)
&&
ResponsibleMailBox
.
Equals
(
other
.
ResponsibleMailBox
)
&&
Serial
.
Equals
(
other
.
Serial
)
&&
Refresh
.
Equals
(
other
.
Refresh
)
&&
Retry
.
Equals
(
other
.
Retry
)
&&
Expire
.
Equals
(
other
.
Expire
)
&&
MinimumTtl
.
Equals
(
other
.
MinimumTtl
);
}
public
override
bool
Equals
(
DnsResourceData
other
)
{
return
Equals
(
other
as
DnsResourceDataStartOfAuthority
);
}
internal
override
int
GetLength
(
DnsDomainNameCompressionData
compressionData
,
int
offsetInDns
)
{
return
MainNameServer
.
GetLength
(
compressionData
,
offsetInDns
)
+
ResponsibleMailBox
.
GetLength
(
compressionData
,
offsetInDns
)
+
ConstantPartLength
;
}
internal
override
int
WriteData
(
byte
[]
buffer
,
int
dnsOffset
,
int
offsetInDns
,
DnsDomainNameCompressionData
compressionData
)
{
int
numBytesWritten
=
MainNameServer
.
Write
(
buffer
,
dnsOffset
,
compressionData
,
offsetInDns
);
numBytesWritten
+=
ResponsibleMailBox
.
Write
(
buffer
,
dnsOffset
,
compressionData
,
offsetInDns
+
numBytesWritten
);
buffer
.
Write
(
dnsOffset
+
offsetInDns
+
numBytesWritten
+
Offset
.
Serial
,
Serial
,
Endianity
.
Big
);
buffer
.
Write
(
dnsOffset
+
offsetInDns
+
numBytesWritten
+
Offset
.
Refresh
,
Refresh
,
Endianity
.
Big
);
buffer
.
Write
(
dnsOffset
+
offsetInDns
+
numBytesWritten
+
Offset
.
Retry
,
Retry
,
Endianity
.
Big
);
buffer
.
Write
(
dnsOffset
+
offsetInDns
+
numBytesWritten
+
Offset
.
Expire
,
Expire
,
Endianity
.
Big
);
buffer
.
Write
(
dnsOffset
+
offsetInDns
+
numBytesWritten
+
Offset
.
MinimumTtl
,
MinimumTtl
,
Endianity
.
Big
);
return
numBytesWritten
+
ConstantPartLength
;
}
internal
override
DnsResourceData
CreateInstance
(
DnsDatagram
dns
,
int
offsetInDns
,
int
length
)
{
DnsDomainName
mainNameServer
;
int
domainNameLength
;
if
(!
DnsDomainName
.
TryParse
(
dns
,
offsetInDns
,
length
,
out
mainNameServer
,
out
domainNameLength
))
return
null
;
offsetInDns
+=
domainNameLength
;
length
-=
domainNameLength
;
DnsDomainName
responsibleMailBox
;
if
(!
DnsDomainName
.
TryParse
(
dns
,
offsetInDns
,
length
,
out
responsibleMailBox
,
out
domainNameLength
))
return
null
;
offsetInDns
+=
domainNameLength
;
length
-=
domainNameLength
;
if
(
length
!=
ConstantPartLength
)
return
null
;
uint
serial
=
dns
.
ReadUInt
(
offsetInDns
+
Offset
.
Serial
,
Endianity
.
Big
);
;
uint
refresh
=
dns
.
ReadUInt
(
offsetInDns
+
Offset
.
Refresh
,
Endianity
.
Big
);
;
uint
retry
=
dns
.
ReadUInt
(
offsetInDns
+
Offset
.
Retry
,
Endianity
.
Big
);
;
uint
expire
=
dns
.
ReadUInt
(
offsetInDns
+
Offset
.
Expire
,
Endianity
.
Big
);
;
uint
minimumTtl
=
dns
.
ReadUInt
(
offsetInDns
+
Offset
.
MinimumTtl
,
Endianity
.
Big
);
;
return
new
DnsResourceDataStartOfAuthority
(
mainNameServer
,
responsibleMailBox
,
serial
,
refresh
,
retry
,
expire
,
minimumTtl
);
}
}
/// <summary>
/// +-----+----------+---------+
/// | bit | 0-7 | 8-31 |
/// +-----+----------+---------+
/// | 0 | Address |
/// +-----+----------+---------+
/// | 32 | Protocol | Bit Map | (Bit Map is variable multiple of 8 bits length)
/// +-----+----------+---------+
/// </summary>
[
DnsTypeRegistration
(
Type
=
DnsType
.
Wks
)]
public
sealed
class
DnsResourceDataWellKnownService
:
DnsResourceDataSimple
,
IEquatable
<
DnsResourceDataWellKnownService
>
{
private
static
class
Offset
{
public
const
int
Address
=
0
;
public
const
int
Protocol
=
Address
+
IpV4Address
.
SizeOf
;
public
const
int
BitMap
=
Protocol
+
sizeof
(
byte
);
}
private
const
int
ConstantPartLength
=
Offset
.
BitMap
;
public
DnsResourceDataWellKnownService
()
:
this
(
IpV4Address
.
Zero
,
IpV4Protocol
.
Ip
,
DataSegment
.
Empty
)
{
}
public
DnsResourceDataWellKnownService
(
IpV4Address
address
,
IpV4Protocol
protocol
,
DataSegment
bitMap
)
{
Address
=
address
;
Protocol
=
protocol
;
BitMap
=
bitMap
;
}
/// <summary>
/// The service address.
/// </summary>
public
IpV4Address
Address
{
get
;
private
set
;
}
/// <summary>
/// Specifies an IP protocol number.
/// </summary>
public
IpV4Protocol
Protocol
{
get
;
private
set
;
}
/// <summary>
/// Has one bit per port of the specified protocol.
/// </summary>
public
DataSegment
BitMap
{
get
;
private
set
;
}
public
bool
Equals
(
DnsResourceDataWellKnownService
other
)
{
return
other
!=
null
&&
Address
.
Equals
(
other
.
Address
)
&&
Protocol
.
Equals
(
other
.
Protocol
)
&&
BitMap
.
Equals
(
other
.
BitMap
);
}
public
override
bool
Equals
(
DnsResourceData
other
)
{
return
Equals
(
other
as
DnsResourceDataWellKnownService
);
}
internal
override
int
GetLength
()
{
return
ConstantPartLength
+
BitMap
.
Length
;
}
internal
override
void
WriteDataSimple
(
byte
[]
buffer
,
int
offset
)
{
buffer
.
Write
(
offset
+
Offset
.
Address
,
Address
,
Endianity
.
Big
);
buffer
.
Write
(
offset
+
Offset
.
Protocol
,
(
byte
)
Protocol
);
BitMap
.
Write
(
buffer
,
offset
+
Offset
.
BitMap
);
}
internal
override
DnsResourceData
CreateInstance
(
DataSegment
data
)
{
if
(
data
.
Length
<
ConstantPartLength
)
return
null
;
IpV4Address
address
=
data
.
ReadIpV4Address
(
Offset
.
Address
,
Endianity
.
Big
);
IpV4Protocol
protocol
=
(
IpV4Protocol
)
data
[
Offset
.
Protocol
];
DataSegment
bitMap
=
data
.
SubSegment
(
Offset
.
BitMap
,
data
.
Length
-
Offset
.
BitMap
);
return
new
DnsResourceDataWellKnownService
(
address
,
protocol
,
bitMap
);
}
}
public
abstract
class
DnsResourceDataStrings
:
DnsResourceDataSimple
,
IEquatable
<
DnsResourceDataStrings
>
{
public
bool
Equals
(
DnsResourceDataStrings
other
)
{
return
other
!=
null
&&
GetType
()
==
other
.
GetType
()
&&
Strings
.
SequenceEqual
(
other
.
Strings
);
}
public
sealed
override
bool
Equals
(
DnsResourceData
other
)
{
return
Equals
(
other
as
DnsResourceDataStrings
);
}
internal
DnsResourceDataStrings
(
ReadOnlyCollection
<
DataSegment
>
strings
)
{
Strings
=
strings
;
}
internal
DnsResourceDataStrings
(
params
DataSegment
[]
strings
)
:
this
(
strings
.
AsReadOnly
())
{
}
internal
ReadOnlyCollection
<
DataSegment
>
Strings
{
get
;
private
set
;
}
internal
sealed
override
int
GetLength
()
{
return
Strings
.
Sum
(
str
=>
sizeof
(
byte
)
+
str
.
Length
);
}
internal
sealed
override
void
WriteDataSimple
(
byte
[]
buffer
,
int
offset
)
{
foreach
(
DataSegment
str
in
Strings
)
{
buffer
.
Write
(
ref
offset
,
(
byte
)
str
.
Length
);
str
.
Write
(
buffer
,
ref
offset
);
}
}
internal
static
List
<
DataSegment
>
ReadStrings
(
DataSegment
data
,
int
numExpected
=
0
)
{
List
<
DataSegment
>
strings
=
new
List
<
DataSegment
>(
numExpected
);
int
offset
=
0
;
while
(
offset
!=
data
.
Length
)
{
int
stringLength
=
data
[
offset
++];
if
(
data
.
Length
<
offset
+
stringLength
)
return
null
;
strings
.
Add
(
data
.
SubSegment
(
ref
offset
,
stringLength
));
}
return
strings
;
}
}
/// <summary>
/// +-----+
/// | CPU |
/// +-----+
/// | OS |
/// +-----+
/// </summary>
[
DnsTypeRegistration
(
Type
=
DnsType
.
HInfo
)]
public
sealed
class
DnsResourceDataHostInformation
:
DnsResourceDataStrings
{
private
const
int
NumStrings
=
2
;
public
DnsResourceDataHostInformation
()
:
this
(
DataSegment
.
Empty
,
DataSegment
.
Empty
)
{
}
public
DnsResourceDataHostInformation
(
DataSegment
cpu
,
DataSegment
os
)
:
base
(
cpu
,
os
)
{
}
public
DataSegment
Cpu
{
get
{
return
Strings
[
0
];
}
}
public
DataSegment
Os
{
get
{
return
Strings
[
1
];
}
}
internal
override
DnsResourceData
CreateInstance
(
DataSegment
data
)
{
List
<
DataSegment
>
strings
=
ReadStrings
(
data
,
NumStrings
);
if
(
strings
==
null
||
strings
.
Count
!=
NumStrings
)
return
null
;
return
new
DnsResourceDataHostInformation
(
strings
[
0
],
strings
[
1
]);
}
}
public
abstract
class
DnsResourceDataDomainNames
:
DnsResourceData
,
IEquatable
<
DnsResourceDataDomainNames
>
{
public
bool
Equals
(
DnsResourceDataDomainNames
other
)
{
return
other
!=
null
&&
GetType
()
==
other
.
GetType
()
&&
DomainNames
.
SequenceEqual
(
other
.
DomainNames
);
}
public
sealed
override
bool
Equals
(
DnsResourceData
other
)
{
return
Equals
(
other
as
DnsResourceDataDomainNames
);
}
internal
DnsResourceDataDomainNames
(
ReadOnlyCollection
<
DnsDomainName
>
domainNames
)
{
DomainNames
=
domainNames
;
}
internal
DnsResourceDataDomainNames
(
params
DnsDomainName
[]
domainNames
)
:
this
(
domainNames
.
AsReadOnly
())
{
}
internal
ReadOnlyCollection
<
DnsDomainName
>
DomainNames
{
get
;
private
set
;
}
internal
override
int
GetLength
(
DnsDomainNameCompressionData
compressionData
,
int
offsetInDns
)
{
int
totalLength
=
0
;
foreach
(
DnsDomainName
domainName
in
DomainNames
)
{
int
length
=
domainName
.
GetLength
(
compressionData
,
offsetInDns
);
offsetInDns
+=
length
;
totalLength
+=
length
;
}
return
totalLength
;
}
internal
override
int
WriteData
(
byte
[]
buffer
,
int
dnsOffset
,
int
offsetInDns
,
DnsDomainNameCompressionData
compressionData
)
{
int
numBytesWritten
=
0
;
foreach
(
DnsDomainName
domainName
in
DomainNames
)
numBytesWritten
+=
domainName
.
Write
(
buffer
,
dnsOffset
,
compressionData
,
offsetInDns
+
numBytesWritten
);
return
numBytesWritten
;
}
internal
static
List
<
DnsDomainName
>
ReadDomainNames
(
DnsDatagram
dns
,
int
offsetInDns
,
int
length
,
int
numExpected
=
0
)
{
List
<
DnsDomainName
>
domainNames
=
new
List
<
DnsDomainName
>(
numExpected
);
while
(
length
!=
0
)
{
DnsDomainName
domainName
;
int
domainNameLength
;
if
(!
DnsDomainName
.
TryParse
(
dns
,
offsetInDns
,
length
,
out
domainName
,
out
domainNameLength
))
return
null
;
offsetInDns
+=
domainNameLength
;
length
-=
domainNameLength
;
domainNames
.
Add
(
domainName
);
}
return
domainNames
;
}
}
public
abstract
class
DnsResourceData2DomainNames
:
DnsResourceDataDomainNames
{
private
const
int
NumDomains
=
2
;
public
DnsResourceData2DomainNames
(
DnsDomainName
first
,
DnsDomainName
second
)
:
base
(
first
,
second
)
{
}
internal
DnsDomainName
First
{
get
{
return
DomainNames
[
0
];
}
}
internal
DnsDomainName
Second
{
get
{
return
DomainNames
[
1
];
}
}
internal
static
bool
TryRead
(
out
DnsDomainName
first
,
out
DnsDomainName
second
,
DnsDatagram
dns
,
int
offsetInDns
,
int
length
)
{
List
<
DnsDomainName
>
domainNames
=
ReadDomainNames
(
dns
,
offsetInDns
,
length
,
NumDomains
);
if
(
domainNames
==
null
||
domainNames
.
Count
!=
NumDomains
)
{
first
=
null
;
second
=
null
;
return
false
;
}
first
=
domainNames
[
0
];
second
=
domainNames
[
1
];
return
true
;
}
}
/// <summary>
/// +---------+
/// | RMAILBX |
/// +---------+
/// | EMAILBX |
/// +---------+
/// </summary>
[
DnsTypeRegistration
(
Type
=
DnsType
.
MInfo
)]
public
sealed
class
DnsResourceDataMailingListInfo
:
DnsResourceData2DomainNames
{
public
DnsResourceDataMailingListInfo
()
:
this
(
DnsDomainName
.
Root
,
DnsDomainName
.
Root
)
{
}
public
DnsResourceDataMailingListInfo
(
DnsDomainName
mailingList
,
DnsDomainName
errorMailBox
)
:
base
(
mailingList
,
errorMailBox
)
{
}
/// <summary>
/// Specifies a mailbox which is responsible for the mailing list or mailbox.
/// If this domain name names the root, the owner of the MINFO RR is responsible for itself.
/// Note that many existing mailing lists use a mailbox X-request for the RMAILBX field of mailing list X, e.g., Msgroup-request for Msgroup.
/// This field provides a more general mechanism.
/// </summary>
public
DnsDomainName
MailingList
{
get
{
return
First
;
}
}
/// <summary>
/// Specifies a mailbox which is to receive error messages related to the mailing list or mailbox specified by the owner of the MINFO RR
/// (similar to the ERRORS-TO: field which has been proposed).
/// If this domain name names the root, errors should be returned to the sender of the message.
/// </summary>
public
DnsDomainName
ErrorMailBox
{
get
{
return
Second
;
}
}
internal
override
DnsResourceData
CreateInstance
(
DnsDatagram
dns
,
int
offsetInDns
,
int
length
)
{
DnsDomainName
mailingList
;
DnsDomainName
errorMailBox
;
if
(!
TryRead
(
out
mailingList
,
out
errorMailBox
,
dns
,
offsetInDns
,
length
))
return
null
;
return
new
DnsResourceDataMailingListInfo
(
mailingList
,
errorMailBox
);
}
}
/// <summary>
/// +-----+--------+
/// | bit | 0-15 |
/// +-----+--------+
/// | 0 | Value |
/// +-----+--------+
/// | 16 | Domain |
/// +-----+--------+
/// </summary>
public
abstract
class
DnsResourceDataUShortDomainName
:
DnsResourceData
,
IEquatable
<
DnsResourceDataUShortDomainName
>
{
private
static
class
Offset
{
public
const
int
Value
=
0
;
public
const
int
DomainName
=
Value
+
sizeof
(
ushort
);
}
private
const
int
ConstantPartLength
=
Offset
.
DomainName
;
public
bool
Equals
(
DnsResourceDataUShortDomainName
other
)
{
return
other
!=
null
&&
GetType
().
Equals
(
other
.
GetType
())
&&
Value
.
Equals
(
other
.
Value
)
&&
DomainName
.
Equals
(
other
.
DomainName
);
}
public
override
bool
Equals
(
DnsResourceData
other
)
{
return
Equals
(
other
as
DnsResourceDataUShortDomainName
);
}
internal
DnsResourceDataUShortDomainName
(
ushort
value
,
DnsDomainName
domainName
)
{
Value
=
value
;
DomainName
=
domainName
;
}
internal
ushort
Value
{
get
;
private
set
;
}
internal
DnsDomainName
DomainName
{
get
;
private
set
;
}
internal
override
int
GetLength
(
DnsDomainNameCompressionData
compressionData
,
int
offsetInDns
)
{
return
ConstantPartLength
+
DomainName
.
GetLength
(
compressionData
,
offsetInDns
);
}
internal
override
int
WriteData
(
byte
[]
buffer
,
int
dnsOffset
,
int
offsetInDns
,
DnsDomainNameCompressionData
compressionData
)
{
buffer
.
Write
(
dnsOffset
+
offsetInDns
+
Offset
.
Value
,
Value
,
Endianity
.
Big
);
int
numBytesWritten
=
DomainName
.
Write
(
buffer
,
dnsOffset
,
compressionData
,
offsetInDns
+
Offset
.
DomainName
);
return
ConstantPartLength
+
numBytesWritten
;
}
internal
static
bool
TryRead
(
out
ushort
value
,
out
DnsDomainName
domainName
,
DnsDatagram
dns
,
int
offsetInDns
,
int
length
)
{
if
(
length
<
ConstantPartLength
)
{
value
=
0
;
domainName
=
null
;
return
false
;
}
value
=
dns
.
ReadUShort
(
offsetInDns
+
Offset
.
Value
,
Endianity
.
Big
);
length
-=
ConstantPartLength
;
int
domainNameLength
;
if
(!
DnsDomainName
.
TryParse
(
dns
,
offsetInDns
+
Offset
.
DomainName
,
length
,
out
domainName
,
out
domainNameLength
))
return
false
;
length
-=
domainNameLength
;
if
(
length
!=
0
)
return
false
;
return
true
;
}
}
/// <summary>
/// +-----+------------+
/// | bit | 0-15 |
/// +-----+------------+
/// | 0 | PREFERENCE |
/// +-----+------------+
/// | 16 | EXCHANGE |
/// +-----+------------+
/// </summary>
[
DnsTypeRegistration
(
Type
=
DnsType
.
Mx
)]
public
sealed
class
DnsResourceDataMailExchange
:
DnsResourceDataUShortDomainName
{
public
DnsResourceDataMailExchange
()
:
this
(
0
,
DnsDomainName
.
Root
)
{
}
public
DnsResourceDataMailExchange
(
ushort
preference
,
DnsDomainName
mailExchangeHost
)
:
base
(
preference
,
mailExchangeHost
)
{
}
public
ushort
Preference
{
get
{
return
Value
;
}
}
public
DnsDomainName
MailExchangeHost
{
get
{
return
DomainName
;
}
}
internal
override
DnsResourceData
CreateInstance
(
DnsDatagram
dns
,
int
offsetInDns
,
int
length
)
{
ushort
preference
;
DnsDomainName
mailExchangeHost
;
if
(!
TryRead
(
out
preference
,
out
mailExchangeHost
,
dns
,
offsetInDns
,
length
))
return
null
;
return
new
DnsResourceDataMailExchange
(
preference
,
mailExchangeHost
);
}
}
/// <summary>
/// +---------+
/// | Strings |
/// +---------+
/// </summary>
[
DnsTypeRegistration
(
Type
=
DnsType
.
Txt
)]
public
sealed
class
DnsResourceDataText
:
DnsResourceDataStrings
{
public
DnsResourceDataText
()
{
}
public
DnsResourceDataText
(
ReadOnlyCollection
<
DataSegment
>
strings
)
:
base
(
strings
)
{
}
public
ReadOnlyCollection
<
DataSegment
>
Text
{
get
{
return
Strings
;
}
}
internal
override
DnsResourceData
CreateInstance
(
DataSegment
data
)
{
List
<
DataSegment
>
strings
=
ReadStrings
(
data
);
return
new
DnsResourceDataText
(
strings
.
AsReadOnly
());
}
}
/// <summary>
/// +------------+
/// | mbox-dname |
/// +------------+
/// | txt-dname |
/// +------------+
/// </summary>
[
DnsTypeRegistration
(
Type
=
DnsType
.
Rp
)]
public
sealed
class
DnsResourceDataResponsiblePerson
:
DnsResourceData2DomainNames
{
public
DnsResourceDataResponsiblePerson
()
:
this
(
DnsDomainName
.
Root
,
DnsDomainName
.
Root
)
{
}
public
DnsResourceDataResponsiblePerson
(
DnsDomainName
mailBox
,
DnsDomainName
textDomain
)
:
base
(
mailBox
,
textDomain
)
{
}
/// <summary>
/// A domain name that specifies the mailbox for the responsible person.
/// Its format in master files uses the DNS convention for mailbox encoding, identical to that used for the RNAME mailbox field in the SOA RR.
/// The root domain name (just ".") may be specified for MailBox to indicate that no mailbox is available.
/// </summary>
public
DnsDomainName
MailBox
{
get
{
return
First
;
}
}
/// <summary>
/// A domain name for which TXT RR's exist.
/// A subsequent query can be performed to retrieve the associated TXT resource records at TextDomain.
/// This provides a level of indirection so that the entity can be referred to from multiple places in the DNS.
/// The root domain name (just ".") may be specified for TextDomain to indicate that the TXT_DNAME is absent, and no associated TXT RR exists.
/// </summary>
public
DnsDomainName
TextDomain
{
get
{
return
Second
;
}
}
internal
override
DnsResourceData
CreateInstance
(
DnsDatagram
dns
,
int
offsetInDns
,
int
length
)
{
DnsDomainName
mailBox
;
DnsDomainName
textDomain
;
if
(!
TryRead
(
out
mailBox
,
out
textDomain
,
dns
,
offsetInDns
,
length
))
return
null
;
return
new
DnsResourceDataResponsiblePerson
(
mailBox
,
textDomain
);
}
}
/// <summary>
/// +-----+----------+
/// | bit | 0-15 |
/// +-----+----------+
/// | 0 | subtype |
/// +-----+----------+
/// | 16 | hostname |
/// +-----+----------+
/// </summary>
[
DnsTypeRegistration
(
Type
=
DnsType
.
AfsDb
)]
public
sealed
class
DnsResourceDataAfsDb
:
DnsResourceDataUShortDomainName
{
public
DnsResourceDataAfsDb
()
:
this
(
0
,
DnsDomainName
.
Root
)
{
}
public
DnsResourceDataAfsDb
(
ushort
subType
,
DnsDomainName
hostname
)
:
base
(
subType
,
hostname
)
{
}
public
ushort
SubType
{
get
{
return
Value
;
}
}
public
DnsDomainName
Hostname
{
get
{
return
DomainName
;
}
}
internal
override
DnsResourceData
CreateInstance
(
DnsDatagram
dns
,
int
offsetInDns
,
int
length
)
{
ushort
subType
;
DnsDomainName
hostName
;
if
(!
TryRead
(
out
subType
,
out
hostName
,
dns
,
offsetInDns
,
length
))
return
null
;
return
new
DnsResourceDataAfsDb
(
subType
,
hostName
);
}
}
}
}
}
PcapDotNet/src/PcapDotNet.Packets/Dns/DnsResourceData
Unknown
.cs
→
PcapDotNet/src/PcapDotNet.Packets/Dns/DnsResourceData
Anything
.cs
View file @
64ffbb1d
...
@@ -2,23 +2,29 @@
...
@@ -2,23 +2,29 @@
namespace
PcapDotNet.Packets.Dns
namespace
PcapDotNet.Packets.Dns
{
{
public
sealed
class
DnsResourceDataUnknown
:
DnsResourceDataSimple
,
IEquatable
<
DnsResourceDataUnknown
>
[
DnsTypeRegistration
(
Type
=
DnsType
.
Null
)]
public
sealed
class
DnsResourceDataAnything
:
DnsResourceDataSimple
,
IEquatable
<
DnsResourceDataAnything
>
{
{
public
DnsResourceDataUnknown
(
DataSegment
data
)
public
DnsResourceDataAnything
()
{
Data
=
DataSegment
.
Empty
;
}
public
DnsResourceDataAnything
(
DataSegment
data
)
{
{
Data
=
data
;
Data
=
data
;
}
}
public
DataSegment
Data
{
get
;
private
set
;
}
public
DataSegment
Data
{
get
;
private
set
;
}
public
bool
Equals
(
DnsResourceData
Unknown
other
)
public
bool
Equals
(
DnsResourceData
Anything
other
)
{
{
return
other
!=
null
&&
Data
.
Equals
(
other
.
Data
);
return
other
!=
null
&&
Data
.
Equals
(
other
.
Data
);
}
}
public
sealed
override
bool
Equals
(
DnsResourceData
other
)
public
override
bool
Equals
(
DnsResourceData
other
)
{
{
return
Equals
(
other
as
DnsResourceData
Unknown
);
return
Equals
(
other
as
DnsResourceData
Anything
);
}
}
internal
override
int
GetLength
()
internal
override
int
GetLength
()
...
@@ -33,7 +39,7 @@ namespace PcapDotNet.Packets.Dns
...
@@ -33,7 +39,7 @@ namespace PcapDotNet.Packets.Dns
internal
override
DnsResourceData
CreateInstance
(
DataSegment
data
)
internal
override
DnsResourceData
CreateInstance
(
DataSegment
data
)
{
{
return
new
DnsResourceData
Unknown
(
data
);
return
new
DnsResourceData
Anything
(
data
);
}
}
}
}
}
}
\ No newline at end of file
PcapDotNet/src/PcapDotNet.Packets/Dns/DnsResourceRecord.cs
View file @
64ffbb1d
...
@@ -51,7 +51,7 @@ namespace PcapDotNet.Packets.Dns
...
@@ -51,7 +51,7 @@ namespace PcapDotNet.Packets.Dns
/// <summary>
/// <summary>
/// Two octets containing one of the RR TYPE codes.
/// Two octets containing one of the RR TYPE codes.
/// </summary>
/// </summary>
public
DnsType
Type
{
get
;
private
set
;}
public
DnsType
Type
{
get
;
private
set
;
}
public
DnsClass
DnsClass
{
get
;
private
set
;
}
public
DnsClass
DnsClass
{
get
;
private
set
;
}
...
@@ -90,8 +90,7 @@ namespace PcapDotNet.Packets.Dns
...
@@ -90,8 +90,7 @@ namespace PcapDotNet.Packets.Dns
{
{
type
=
DnsType
.
All
;
type
=
DnsType
.
All
;
dnsClass
=
DnsClass
.
Any
;
dnsClass
=
DnsClass
.
Any
;
domainName
=
DnsDomainName
.
Parse
(
dns
,
offsetInDns
,
out
numBytesRead
);
if
(!
DnsDomainName
.
TryParse
(
dns
,
offsetInDns
,
dns
.
Length
-
offsetInDns
,
out
domainName
,
out
numBytesRead
))
if
(
domainName
==
null
)
return
false
;
return
false
;
if
(
offsetInDns
+
numBytesRead
+
MinimumLengthAfterDomainName
>
dns
.
Length
)
if
(
offsetInDns
+
numBytesRead
+
MinimumLengthAfterDomainName
>
dns
.
Length
)
...
...
PcapDotNet/src/PcapDotNet.Packets/PcapDotNet.Packets.csproj
View file @
64ffbb1d
...
@@ -103,7 +103,7 @@
...
@@ -103,7 +103,7 @@
<Compile
Include=
"Dns\DnsOpcode.cs"
/>
<Compile
Include=
"Dns\DnsOpcode.cs"
/>
<Compile
Include=
"Dns\DnsQueryResourceRecord.cs"
/>
<Compile
Include=
"Dns\DnsQueryResourceRecord.cs"
/>
<Compile
Include=
"Dns\DnsResourceData.cs"
/>
<Compile
Include=
"Dns\DnsResourceData.cs"
/>
<Compile
Include=
"Dns\DnsResourceData
Unknown
.cs"
/>
<Compile
Include=
"Dns\DnsResourceData
Anything
.cs"
/>
<Compile
Include=
"Dns\DnsResourceRecord.cs"
/>
<Compile
Include=
"Dns\DnsResourceRecord.cs"
/>
<Compile
Include=
"Dns\DnsResponseCode.cs"
/>
<Compile
Include=
"Dns\DnsResponseCode.cs"
/>
<Compile
Include=
"Dns\DnsType.cs"
/>
<Compile
Include=
"Dns\DnsType.cs"
/>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment