public PPacket(Packet packet, long packetNumber, TimeSpan relativeTime) { _packet = packet; _packetNumber = packetNumber; _relativeTime = relativeTime; EthernetDatagram ethernet = packet.Ethernet; if (ethernet != null) { _ethernetType = ethernet.EtherType; _ethernetTypeCode = GetEthernetTypeCode(ethernet.EtherType); //_ipv4 = packet.Ethernet.IpV4; //if (_ipv4 != null) if (ethernet.EtherType == PcapDotNet.Packets.Ethernet.EthernetType.IpV4) { _ipv4 = packet.Ethernet.IpV4; _source = _ipv4.Source; _destination = _ipv4.Destination; _ipProtocol = _ipv4.Protocol; _ipProtocolCode = GetIPProtocolCode(_ipv4.Protocol); //_tcp = _ipv4.Tcp; //if (_tcp != null) if (_ipv4.Protocol == IpV4Protocol.Tcp) { _tcp = _ipv4.Tcp; _sourcePort = _tcp.SourcePort; _destinationPort = _tcp.DestinationPort; } } } }
/// <summary> /// Writes the layer to the buffer. /// </summary> /// <param name="buffer">The buffer to write the layer to.</param> /// <param name="offset">The offset in the buffer to start writing the layer at.</param> /// <param name="payloadLength">The length of the layer's payload (the number of bytes after the layer in the packet).</param> /// <param name="previousLayer">The layer that comes before this layer. null if this is the first layer.</param> /// <param name="nextLayer">The layer that comes after this layer. null if this is the last layer.</param> public override void Write(byte[] buffer, int offset, int payloadLength, ILayer previousLayer, ILayer nextLayer) { IpV4Protocol protocol; if (Protocol == null) { if (nextLayer == null) { throw new ArgumentException("Can't determine protocol automatically from next layer because there is no next layer"); } IIpV4NextLayer ipV4NextLayer = nextLayer as IIpV4NextLayer; if (ipV4NextLayer == null) { throw new ArgumentException("Can't determine protocol automatically from next layer (" + nextLayer.GetType() + ")"); } protocol = ipV4NextLayer.PreviousLayerProtocol; } else { protocol = Protocol.Value; } IpV4Datagram.WriteHeader(buffer, offset, TypeOfService, Identification, Fragmentation, Ttl, protocol, HeaderChecksum, Source, CurrentDestination, Options, payloadLength); }
/// <summary> /// Finalizes the layer data in the buffer. /// Used for fields that must be calculated according to the layer's payload (like checksum). /// </summary> /// <param name="buffer">The buffer to finalize the layer in.</param> /// <param name="offset">The offset in the buffer the layer starts.</param> /// <param name="payloadLength">The length of the layer's payload (the number of bytes after the layer in the packet).</param> /// <param name="nextLayer">The layer that comes after this layer. null if this is the last layer.</param> public override void Finalize(byte[] buffer, int offset, int payloadLength, ILayer nextLayer) { IIpNextTransportLayer nextTransportLayer = nextLayer as IIpNextTransportLayer; if (nextTransportLayer == null || !nextTransportLayer.CalculateChecksum) return; IpV4Datagram.WriteTransportChecksum(buffer, offset, Length, (ushort)payloadLength, nextTransportLayer.ChecksumOffset, nextTransportLayer.IsChecksumOptional, nextTransportLayer.Checksum, Destination); }
/// <summary> /// Handle IPV4 packets, including TCP and UDP packets /// </summary> /// <param name="packet">The IpV4Datagram to parse</param> public static void HandleIPV4(Packet packet, IpV4Datagram ip, ref UInt64 frame_id, object[] ctrl) { ListViewItem item = new ListViewItem(frame_id.ToString()); frame_id++; List<string> packet_info = new List<string>(); ListView frames = (ListView)ctrl[0]; EthernetDatagram ethernet = packet.Ethernet; switch (ip.Protocol) { case IpV4Protocol.Udp: { UdpDatagram udp = ip.Udp; packet_info.Add(packet.Timestamp.ToString("hh:mm:ss.fff tt")); packet_info.Add(ip.Source + ":" + udp.SourcePort); packet_info.Add(ip.Destination + ":" + udp.DestinationPort); packet_info.Add(ethernet.Source.ToString()); packet_info.Add(ethernet.Destination.ToString()); packet_info.Add("UDP"); packet_info.Add(udp.Length.ToString()); break; } case IpV4Protocol.Tcp: { TcpDatagram tcp = ip.Tcp; packet_info.Add(packet.Timestamp.ToString("hh:mm:ss.fff tt")); packet_info.Add(ip.Source + ":" + tcp.SourcePort); packet_info.Add(ip.Destination + ":" + tcp.DestinationPort); packet_info.Add(ethernet.Source.ToString()); packet_info.Add(ethernet.Destination.ToString()); packet_info.Add("TCP"); packet_info.Add(tcp.Length.ToString()); break; } default: { item = null; break; } } // update UI if (item != null) { item.SubItems.AddRange(packet_info.ToArray()); object[] param = new object[2]; param[0] = frames; object[] o = new object[3]; o[0] = item; o[1] = ctrl[1]; o[2] = packet; param[1] = o; frames.BeginInvoke(new ParserHelper.UIHandlerEx(ParserHelper.UpdateFrameUI), param); } }
private void handleIPv4Packet(IpV4Datagram ip, DateTime timestamp) { //IpV4Datagram ip = packet.Ethernet.IpV4; float diff = (timestamp.Ticks - startTime) / 10000000.0f; ListViewItem li = new ListViewItem(packetCount.ToString()); li.SubItems.Add(diff.ToString()); li.SubItems.Add(ip.Source.ToString()); li.SubItems.Add(ip.Destination.ToString()); li.SubItems.Add(ip.Protocol.ToString()); listView1.Items.Add(li); //Debug.WriteLine("Protocol " + ip.Protocol.ToString() + "\n"); }
/// <summary> /// Parse an IP packet /// Dispatch TCP and UDP packets /// </summary> /// <param name="ip">The IP packet to be parsed</param> /// <param name="ctrl"></param> public static void ParseIPPacket(IpV4Datagram ip, object[] ctrl) { if (ip == null || ctrl == null || ctrl[0] == null || ctrl[1] == null) return; List<ListViewItem> items = new List<ListViewItem>(); ListViewItem item = new ListViewItem("IPV4"); string estr = "Destination = " + ip.Destination; estr += ", Source = " + ip.Source; estr += ", Next Protocol = " + ip.Protocol; estr += ", Packet ID = " + ip.Identification; estr += ", Total IP length = " + ip.Length; item.SubItems.Add(estr); items.Add(item); ListView f_details = (ListView)ctrl[0]; object[] param = new object[2]; param[0] = f_details; param[1] = items; f_details.BeginInvoke(new ParserHelper.UIHandler(ParserHelper.UpdateDetailsUI), param); switch (ip.Protocol) { case IpV4Protocol.Tcp: { TcpDatagram tcp = ip.Tcp; SnifferMain.datagram = tcp; SnifferMain.payload = tcp.Payload; ParseTcpPacket(tcp, ctrl[0]); PacketParser.DumpPacket(tcp, ctrl[1]); break; } case IpV4Protocol.Udp: { UdpDatagram udp = ip.Udp; SnifferMain.datagram = udp; SnifferMain.payload = udp.Payload; ParseUdpPacket(udp, ctrl[0]); PacketParser.DumpPacket(udp, ctrl[1]); break; } default: break; } }
private static void CompareIpV4Options(XElement element, IpV4Datagram ipV4Datagram, IpV4Options options) { int currentOptionIndex = 0; foreach (var field in element.Fields()) { if (currentOptionIndex >= options.Count) { Assert.IsFalse(options.IsValid); Assert.IsTrue(field.Show() == "Commercial IP security option" || field.Show() == "Loose source route (length byte past end of options)" || field.Show() == "Time stamp:" || field.Show().StartsWith("Unknown") || field.Show().StartsWith("Security") || field.Show().StartsWith("Router Alert (with option length = ") || field.Show().StartsWith("Stream ID (with option length = ") || field.Show().Contains("with too") || field.Show().Contains(" bytes says option goes past end of options") || field.Show().Contains("(length byte past end of options)") || XElementExtensions.Show(field.Fields().First()).StartsWith("Pointer: ") && XElementExtensions.Show(field.Fields().First()).EndsWith(" (points to middle of address)") || field.Fields().Where(value => value.Show() == "(suboption would go past end of option)").Count() != 0, field.Show()); break; } IpV4Option option = options[currentOptionIndex++]; switch (option.OptionType) { case IpV4OptionType.NoOperation: case IpV4OptionType.EndOfOptionList: field.AssertShow(option.OptionType == IpV4OptionType.EndOfOptionList ? "End of Options List (EOL)" : "No Operation (NOP)"); foreach (var subfield in field.Fields()) { if (HandleCommonOptionSubfield(subfield, option)) continue; switch (subfield.Name()) { default: throw new InvalidOperationException("Invalid subfield " + subfield.Name()); } } break; case IpV4OptionType.BasicSecurity: field.AssertShow("Security (" + option.Length + " bytes)"); var basicSecurity = (IpV4OptionBasicSecurity)option; int basicSecurityFlagsIndex = 0; foreach (var subfield in field.Fields()) { if (HandleCommonOptionSubfield(subfield, option)) continue; switch (subfield.Name()) { case "ip.opt.sec_cl": subfield.AssertNoFields(); subfield.AssertShowDecimal((byte)basicSecurity.ClassificationLevel); break; case "ip.opt.sec_prot_auth_flags": foreach (XElement flagField in subfield.Fields()) { flagField.AssertNoFields(); switch (flagField.Name()) { case "ip.opt.sec_prot_auth_genser": flagField.AssertShowDecimal((basicSecurity.ProtectionAuthorities & IpV4OptionSecurityProtectionAuthorities.Genser) == IpV4OptionSecurityProtectionAuthorities.Genser); break; case "ip.opt.sec_prot_auth_siop_esi": flagField.AssertShowDecimal((basicSecurity.ProtectionAuthorities & IpV4OptionSecurityProtectionAuthorities. SingleIntegrationOptionalPlanExtremelySensitiveInformation) == IpV4OptionSecurityProtectionAuthorities. SingleIntegrationOptionalPlanExtremelySensitiveInformation); break; case "ip.opt.sec_prot_auth_sci": flagField.AssertShowDecimal((basicSecurity.ProtectionAuthorities & IpV4OptionSecurityProtectionAuthorities.SensitiveCompartmentedInformation) == IpV4OptionSecurityProtectionAuthorities.SensitiveCompartmentedInformation); break; case "ip.opt.sec_prot_auth_nsa": flagField.AssertShowDecimal((basicSecurity.ProtectionAuthorities & IpV4OptionSecurityProtectionAuthorities.Nsa) == IpV4OptionSecurityProtectionAuthorities.Nsa); break; case "ip.opt.sec_prot_auth_doe": flagField.AssertShowDecimal((basicSecurity.ProtectionAuthorities & IpV4OptionSecurityProtectionAuthorities.DepartmentOfEnergy) == IpV4OptionSecurityProtectionAuthorities.DepartmentOfEnergy); break; case "ip.opt.sec_prot_auth_unassigned": flagField.AssertShowDecimal(0); break; case "ip.opt.sec_prot_auth_fti": flagField.AssertShowDecimal(basicSecurity.Length - basicSecurityFlagsIndex > 4); break; default: throw new InvalidOperationException("Invalid flag field " + flagField.Name()); } } ++basicSecurityFlagsIndex; break; default: throw new InvalidOperationException("Invalid subfield " + subfield.Name()); } } break; case IpV4OptionType.StreamIdentifier: field.AssertShow("Stream ID (" + option.Length + " bytes): " + ((IpV4OptionStreamIdentifier)option).Identifier); var streamIdentifier = (IpV4OptionStreamIdentifier)option; foreach (var subfield in field.Fields()) { if (HandleCommonOptionSubfield(subfield, option)) continue; switch (subfield.Name()) { case "ip.opt.sid": subfield.AssertNoFields(); subfield.AssertShowDecimal(streamIdentifier.Identifier); break; default: throw new InvalidOperationException("Invalid subfield " + subfield.Name()); } } break; case IpV4OptionType.LooseSourceRouting: field.AssertShow("Loose Source Route (" + option.Length + " bytes)"); var looseSourceRouting = (IpV4OptionLooseSourceRouting)option; int looseRouteIndex = 0; foreach (var subfield in field.Fields()) { if (HandleCommonOptionSubfield(subfield, option)) continue; switch (subfield.Name()) { case "ip.opt.ptr": subfield.AssertShowDecimal(IpV4Address.SizeOf * (looseSourceRouting.PointedAddressIndex + 1)); subfield.AssertNoFields(); break; case "ip.rec_rt": case "ip.dst": case "ip.addr": case "ip.dst_host": case "ip.src_rt": subfield.AssertShow(looseSourceRouting.Route[looseRouteIndex].ToString()); subfield.AssertNoFields(); break; case "ip.rec_rt_host": case "ip.host": case "ip.src_rt_host": subfield.AssertShow(looseSourceRouting.Route[looseRouteIndex].ToString()); subfield.AssertNoFields(); ++looseRouteIndex; break; default: throw new InvalidOperationException("Invalid subfield " + subfield.Name()); } } break; case IpV4OptionType.RecordRoute: field.AssertShow("Record Route (" + option.Length + " bytes)"); var recordRoute = (IpV4OptionRecordRoute)option; int recordRouteIndex = 0; foreach (var subfield in field.Fields()) { if (HandleCommonOptionSubfield(subfield, option)) continue; switch (subfield.Name()) { case "ip.opt.ptr": subfield.AssertShowDecimal(IpV4Address.SizeOf * (recordRoute.PointedAddressIndex + 1)); subfield.AssertNoFields(); break; case "ip.rec_rt": case "ip.empty_rt": subfield.AssertShow(recordRoute.Route[recordRouteIndex].ToString()); subfield.AssertNoFields(); break; case "ip.rec_rt_host": case "ip.empty_rt_host": subfield.AssertShow(recordRoute.Route[recordRouteIndex].ToString()); subfield.AssertNoFields(); ++recordRouteIndex; break; default: throw new InvalidOperationException("Invalid subfield " + subfield.Name()); } } break; case IpV4OptionType.StrictSourceRouting: field.AssertShow("Strict Source Route (" + option.Length + " bytes)"); var strictSourceRouting = (IpV4OptionStrictSourceRouting)option; int strictSourceRoutingIndex = 0; foreach (var subfield in field.Fields()) { if (HandleCommonOptionSubfield(subfield, option)) continue; switch (subfield.Name()) { case "ip.opt.ptr": subfield.AssertShowDecimal(IpV4Address.SizeOf * (strictSourceRouting.PointedAddressIndex + 1)); subfield.AssertNoFields(); break; case "ip.dst": case "ip.addr": case "ip.dst_host": case "ip.rec_rt": case "ip.src_rt": subfield.AssertShow(strictSourceRouting.Route[strictSourceRoutingIndex].ToString()); subfield.AssertNoFields(); break; case "ip.host": case "ip.rec_rt_host": case "ip.src_rt_host": subfield.AssertShow(strictSourceRouting.Route[strictSourceRoutingIndex].ToString()); subfield.AssertNoFields(); ++strictSourceRoutingIndex; break; default: throw new InvalidOperationException("Invalid subfield " + subfield.Name()); } } break; case IpV4OptionType.RouterAlert: var routerAlert = (IpV4OptionRouterAlert)option; field.AssertShow("Router Alert (" + option.Length + " bytes): " + ((routerAlert.Value != 0) ? "Reserved (" + routerAlert.Value + ")" : "Router shall examine packet (0)")); foreach (var subfield in field.Fields()) { if (HandleCommonOptionSubfield(subfield, option)) continue; switch (subfield.Name()) { case "ip.opt.ra": subfield.AssertNoFields(); subfield.AssertShowDecimal(routerAlert.Value); break; default: throw new InvalidOperationException("Invalid subfield " + subfield.Name()); } } break; case IpV4OptionType.TraceRoute: field.AssertShow("Traceroute (" + option.Length + " bytes)"); var traceRoute = (IpV4OptionTraceRoute)option; foreach (var subfield in field.Fields()) { if (HandleCommonOptionSubfield(subfield, option)) continue; subfield.AssertNoFields(); switch (subfield.Name()) { case "ip.opt.id_number": subfield.AssertShowDecimal(traceRoute.Identification); break; case "ip.opt.ohc": subfield.AssertShowDecimal(traceRoute.OutboundHopCount); break; case "ip.opt.rhc": subfield.AssertShowDecimal(traceRoute.ReturnHopCount); break; case "ip.opt.originator": subfield.AssertShow(traceRoute.OriginatorIpAddress.ToString()); break; default: throw new InvalidOperationException("Invalid subfield " + subfield.Name()); } } break; case IpV4OptionType.InternetTimestamp: field.AssertShow("Time Stamp (" + option.Length + " bytes)"); var timestamp = (IpV4OptionTimestamp)option; int timestampIndex = 0; foreach (var subfield in field.Fields()) { if (HandleCommonOptionSubfield(subfield, option)) continue; subfield.AssertNoFields(); switch (subfield.Name()) { case "": var subfieldParts = subfield.Show().Split(new[] { ':', '=', ',' }, StringSplitOptions.RemoveEmptyEntries); string subfieldValue = subfieldParts[1].Trim(); switch (subfieldParts[0].Trim()) { case "Pointer": Assert.AreEqual(timestamp.PointedIndex, int.Parse(subfieldValue) / 4 - 1); break; case "Overflow": Assert.AreEqual(timestamp.Overflow.ToString(), subfieldValue); break; case "Flag": switch (timestamp.TimestampType) { case IpV4OptionTimestampType.AddressAndTimestamp: Assert.AreEqual("Time stamp and address", subfieldValue); break; case IpV4OptionTimestampType.TimestampOnly: Assert.AreEqual("Time stamps only", subfieldValue); break; case IpV4OptionTimestampType.AddressPrespecified: Assert.AreEqual("Time stamps for prespecified addresses", subfieldValue); break; default: throw new InvalidOperationException("Invalid timestamp type: " + timestamp.TimestampType); } break; case "Time stamp": var timestampOnly = (IpV4OptionTimestampOnly)timestamp; Assert.AreEqual(timestampOnly.Timestamps[timestampIndex].MillisecondsSinceMidnightUniversalTime, uint.Parse(subfieldValue)); ++timestampIndex; break; case "Address": Assert.AreEqual(4, subfieldParts.Length); var timestampAndAddress = (IpV4OptionTimestampAndAddress)timestamp; Assert.AreEqual(timestampAndAddress.TimedRoute[timestampIndex].Address.ToString(), subfieldParts[1].Trim()); Assert.AreEqual("time stamp", subfieldParts[2].Trim()); Assert.AreEqual(timestampAndAddress.TimedRoute[timestampIndex].TimeOfDay.MillisecondsSinceMidnightUniversalTime, uint.Parse(subfieldParts[3])); ++timestampIndex; break; default: throw new InvalidOperationException("Invalid subfield " + subfield.Show()); } break; default: throw new InvalidOperationException("Invalid subfield " + subfield.Name()); } } break; case IpV4OptionType.QuickStart: IpV4OptionQuickStart quickStart = (IpV4OptionQuickStart)option; StringBuilder quickStartWireshark = new StringBuilder("Quick-Start (" + option.Length + " bytes): "); quickStartWireshark.Append(quickStart.QuickStartFunction == IpV4OptionQuickStartFunction.RateRequest ? "Rate request" : "Rate report"); quickStartWireshark.Append(" (" + (byte)quickStart.QuickStartFunction + ")"); quickStartWireshark.Append(", "); if (quickStart.RateKbps == 0) quickStartWireshark.Append("0 bit/s"); else if (quickStart.RateKbps < 1024) quickStartWireshark.Append(quickStart.RateKbps + " Kbit/s"); else if (quickStart.RateKbps < 1024 * 1024) quickStartWireshark.Append(((double)quickStart.RateKbps / 1000).ToString(CultureInfo.InvariantCulture) + " Mbit/s"); else quickStartWireshark.Append(((double)quickStart.RateKbps / 1000000).ToString(CultureInfo.InvariantCulture) + " Gbit/s"); if (quickStart.QuickStartFunction == IpV4OptionQuickStartFunction.RateRequest) quickStartWireshark.Append(", QS TTL " + quickStart.Ttl + ", QS TTL diff " + (256 + ipV4Datagram.Ttl - quickStart.Ttl) % 256); field.AssertShow(quickStartWireshark.ToString()); foreach (var subfield in field.Fields()) { if (HandleCommonOptionSubfield(subfield, option)) continue; subfield.AssertNoFields(); switch (subfield.Name()) { case "ip.opt.qs_func": subfield.AssertShowDecimal((byte)quickStart.QuickStartFunction); break; case "ip.opt.qs_rate": subfield.AssertShowDecimal(quickStart.Rate); break; case "ip.opt.qs_ttl": case "ip.opt.qs_unused": subfield.AssertShowDecimal(quickStart.Ttl); break; case "ip.opt.qs_ttl_diff": subfield.AssertShowDecimal((256 + ipV4Datagram.Ttl - quickStart.Ttl) % 256); break; case "ip.opt.qs_nonce": subfield.AssertShowDecimal(quickStart.Nonce); break; case "ip.opt.qs_reserved": subfield.AssertShowDecimal(0); break; default: throw new InvalidOperationException("Invalid subfield " + subfield.Name()); } } break; case IpV4OptionType.MaximumTransmissionUnitProbe: // TODO: Support MTU Proble. Assert.IsTrue(field.Show().StartsWith("MTU Probe (" + option.Length + " bytes): ")); break; case (IpV4OptionType)12: // TODO: Support 12. if (option.Length != 4) field.AssertShow("MTU Reply (with option length = " + option.Length + " bytes; should be 4)"); else Assert.IsTrue(field.Show().StartsWith("MTU Reply (4 bytes): ")); break; case (IpV4OptionType)133: // TODO: Support 133. if (option.Length >= 3) field.AssertShow("Extended Security (" + option.Length + " bytes)"); else field.AssertShow("Extended Security (with option length = " + option.Length + " bytes; should be >= 3)"); break; case (IpV4OptionType)134: // TODO: Support 134. field.AssertShow("Commercial Security " + (option.Length >= 10 ? "(" + option.Length + " bytes)" : "(with option length = " + option.Length + " bytes; should be >= 10)")); break; case (IpV4OptionType)149: // TODO: Support 149. if (option.Length >= 6) field.AssertShow("Selective Directed Broadcast (" + option.Length + " bytes)"); else field.AssertShow("Selective Directed Broadcast (with option length = " + option.Length + " bytes; should be >= 6)"); break; default: field.AssertShow("Unknown (0x" + ((byte)option.OptionType).ToString("x2") + ") (" + option.Length + " bytes)"); field.AssertNoFields(); break; } } }
bool IsIncoming(IpV4Datagram ip) => address == ip.Destination.ToValue();
/// <summary> /// /// </summary> /// <param name="guid"></param> /// <param name="outputPath"></param> /// <param name="packet"></param> public void Process(FileStream fileStream, string outputPath, IpV4Datagram packet) { UdpDatagram udp = packet.Udp; if (udp.Dns != null) { List<string> queries = new List<string>(); foreach (PcapDotNet.Packets.Dns.DnsQueryResourceRecord resourceRecord in udp.Dns.Queries) { try { if (queries.Contains(resourceRecord.ToString()) == false) { queries.Add(resourceRecord.ToString()); woanware.IO.WriteToFileStream(fileStream, "DNS Query: " + resourceRecord.ToString() + Environment.NewLine); } } catch (Exception ex) { this.Log().Error(ex.ToString()); } } List<string> answers = new List<string>(); foreach (PcapDotNet.Packets.Dns.DnsDataResourceRecord resourceRecord in udp.Dns.Answers) { try { PcapDotNet.Packets.Dns.DnsResourceData dataRecord = resourceRecord.Data; if (dataRecord.GetType() != typeof(PcapDotNet.Packets.Dns.DnsResourceDataDomainName)) { continue; } PcapDotNet.Packets.Dns.DnsResourceDataDomainName ab = (PcapDotNet.Packets.Dns.DnsResourceDataDomainName)dataRecord; if (answers.Contains(resourceRecord.DnsType.ToString() + " " + ab.Data.ToString()) == false) { answers.Add(resourceRecord.ToString()); woanware.IO.WriteToFileStream(fileStream, "DNS Answer: " + resourceRecord.DnsType.ToString() + " " + ab.Data.ToString() + Environment.NewLine); } } catch (Exception ex) { this.Log().Error(ex.ToString()); } } } }
private ushort CalculateTransportChecksum() { return(IpV4Datagram.CalculateTransportChecksum(this.Buffer, this.StartOffset, this.HeaderLength, (ushort)this.Transport.Length, this.Transport.ChecksumOffset, this.Transport.IsChecksumOptional, this.Destination)); }
internal static void WriteTransportChecksum(byte[] buffer, int offset, int headerLength, ushort transportLength, int transportChecksumOffset, bool isChecksumOptional, ushort?checksum, IpV4Address destination) { ushort?nullable = checksum; ushort num = !(nullable.HasValue ? new int?((int)nullable.GetValueOrDefault()) : new int?()).HasValue ? IpV4Datagram.CalculateTransportChecksum(buffer, offset, headerLength, transportLength, transportChecksumOffset, isChecksumOptional, destination) : checksum.Value; ByteArrayExtensions.Write(buffer, offset + headerLength + transportChecksumOffset, num, Endianity.Big); }