I'm developping an OOP application in C# which takes as input a binary stream from a packet sniffer such as Wireshark. This application would parse the binary stream, identify the type of datagram and create and populate the appropriate Object.
A Ethernet Datagram can encapsulate a Network Datagram (IPv4, IPv6...) which can encapsulate a Transport Datagram (TCP, UDP...)
What would be the most suitable design pattern ?
I thought Abstract Factory could be good.
Input (assuming the application is always taking a Ethernet datagram as input)
0000 01 02 03 04 05 06 07 08 09 0A 0B 0C 08 00 45 00 ..... ..3.y/..E.
0010 00 28 df 34 40 00 80 06 ad 8a cc 05 4a ee d1 23 .(.4@.......*...
0020 05 1c f3 0b 0c 38 30 4c 7f f1 50 0d d2 7c 50 10 .....80L..P..|P.
0030 02 02 6d b6 00 00
Pseudo code :
abstract class EthernetFactory
{
public static EthernetDatagram MakeInstance(ref List<byte> stream)
{
EthernetDatagram ethernet = new EthernetDatagram();
...
ethernet.Destination = 01 02 03 04 05 06;
ethernet.Source = 07 08 09 0A 0B 0C;
switch (type)
{
case IPV4: // 0x8
ethernet.NetworkLayerDatagram = (NetworkLayerDatagram) IPv4DatagramFactory.MakeInstance(ref List<byte> stream);
break;
case IPV6:
ethernet.NetworkLayerDatagram = (NetworkLayerDatagram) IPv6DatagramFactory.MakeInstance(ref List<byte> stream);
break;
}
...
return ethernet;
}
}
abstract class IPv4DatagramFactory : NetworkLayerDatagramFactory
{
public static IPv4Datagram MakeInstance(ref List<byte> stream)
{
IPv4Datagram ipv4 = new IPv4Datagram();
ipv4.Source = cc 05 4a ee;
ipv4.Destination = d1 23 05 1c;
...
switch (type)
{
case TCP:
ipv4.TransportLayerDatagram = (TransportLayerDatagram) TCPDatagramFactory.MakeInstance(ref List<byte> stream);
break;
case UDP:
ipv4.TransportLayerDatagram = (TransportLayerDatagram) UDPDatagramFactory.MakeInstance(ref List<byte> stream);
break;
}
...
return ipv4;
}
}
abstract class IPv6DatagramFactory : NetworkLayerDatagramFactory
{
...
}
abstract class NetworkLayerDatagram
{
public ... Source = {get; private set}
public ... Destination = {get; private set}
public TransportLayerDatagram TransportLayerDatagram {get; private set}
}
class IPv4Datagram : NetworkLayerDatagram
{
}
class IPv6Datagram : NetworkLayerDatagram
{
}
abstract class TransportLayerDatagram
{
public uint SourcePort = {get; private set}
public uint DestPort = {get; private set}
public ApplicationLayerDatagram ApplicationLayerDatagram {get; private set}
}
class TCPDatagram : TransportLayerDatagram
{
}
class UDPDatagram : TransportLayerDatagram
{
}
As you can see, the top-level factory consume the stream to take a decision then pass data to a child factory etc... Is it a good practice ?
Thanks for your help...
Aucun commentaire:
Enregistrer un commentaire