internal static extern unsafe bool TryGetIPPacketInformation(byte* messageHeader, bool isIPv4, IPPacketInformation* packetInfo);
/// <summary> /// Extends ReceiveMessageFrom so that buffer offset of 0 and call to Array.Length are not needed. /// <example> /// socket.ReceiveMessageFrom(buffer, socketFlags, remoteEP, ipPacketInformation); /// </example> /// </summary> public static Int32 ReceiveMessageFrom(this Socket socket, Byte[] buffer, ref SocketFlags socketFlags, ref System.Net.EndPoint remoteEP, out IPPacketInformation ipPacketInformation) { if (socket == null) { throw new ArgumentNullException("socket"); } if (buffer == null) { throw new ArgumentNullException("buffer"); } return(socket.ReceiveMessageFrom(buffer, 0, buffer.Length, ref socketFlags, ref remoteEP, out ipPacketInformation)); }
public static bool op_Inequality(IPPacketInformation packetInformation1, IPPacketInformation packetInformation2) {}
public void GetHashCode_NonDefaultValue_Succes() { IPPacketInformation packetInfo = GetNonDefaultIPPacketInformation(); Assert.Equal(packetInfo.GetHashCode(), packetInfo.GetHashCode()); }
private DhcpMessage ProcessDhcpMessage(DhcpMessage request, IPEndPoint remoteEP, IPPacketInformation ipPacketInformation) { if (request.OpCode != DhcpMessageOpCode.BootRequest) { return(null); } switch (request.DhcpMessageType?.Type) { case DhcpMessageType.Discover: { Scope scope = FindScope(request, remoteEP.Address, ipPacketInformation); if (scope == null) { return(null); //no scope available; do nothing } if (scope.OfferDelayTime > 0) { Thread.Sleep(scope.OfferDelayTime); //delay sending offer } Lease offer = scope.GetOffer(request); if (offer == null) { return(null); //no offer available, do nothing } List <DhcpOption> options = scope.GetOptions(request, scope.InterfaceAddress); if (options == null) { return(null); } //log ip offer LogManager log = _log; if (log != null) { log.Write(remoteEP as IPEndPoint, "DHCP Server offered IP address [" + offer.Address.ToString() + "] to " + request.GetClientFullIdentifier() + "."); } return(new DhcpMessage(request, offer.Address, scope.InterfaceAddress, options)); } case DhcpMessageType.Request: { //request ip address lease or extend existing lease Scope scope = FindScope(request, remoteEP.Address, ipPacketInformation); if (scope == null) { return(null); //no scope available; do nothing } Lease leaseOffer; if (request.ServerIdentifier == null) { if (request.RequestedIpAddress == null) { //renewing or rebinding if (request.ClientIpAddress.Equals(IPAddress.Any)) { return(null); //client must set IP address in ciaddr; do nothing } leaseOffer = scope.GetExistingLeaseOrOffer(request); if (leaseOffer == null) { //no existing lease or offer available for client //send nak return(new DhcpMessage(request, IPAddress.Any, scope.InterfaceAddress, new DhcpOption[] { new DhcpMessageTypeOption(DhcpMessageType.Nak), new ServerIdentifierOption(scope.InterfaceAddress), DhcpOption.CreateEndOption() })); } if (!request.ClientIpAddress.Equals(leaseOffer.Address)) { //client ip is incorrect //send nak return(new DhcpMessage(request, IPAddress.Any, scope.InterfaceAddress, new DhcpOption[] { new DhcpMessageTypeOption(DhcpMessageType.Nak), new ServerIdentifierOption(scope.InterfaceAddress), DhcpOption.CreateEndOption() })); } } else { //init-reboot leaseOffer = scope.GetExistingLeaseOrOffer(request); if (leaseOffer == null) { //no existing lease or offer available for client //send nak return(new DhcpMessage(request, IPAddress.Any, scope.InterfaceAddress, new DhcpOption[] { new DhcpMessageTypeOption(DhcpMessageType.Nak), new ServerIdentifierOption(scope.InterfaceAddress), DhcpOption.CreateEndOption() })); } if (!request.RequestedIpAddress.Address.Equals(leaseOffer.Address)) { //the client's notion of its IP address is not correct - RFC 2131 //send nak return(new DhcpMessage(request, IPAddress.Any, scope.InterfaceAddress, new DhcpOption[] { new DhcpMessageTypeOption(DhcpMessageType.Nak), new ServerIdentifierOption(scope.InterfaceAddress), DhcpOption.CreateEndOption() })); } } } else { //selecting offer if (request.RequestedIpAddress == null) { return(null); //client MUST include this option; do nothing } if (!request.ServerIdentifier.Address.Equals(scope.InterfaceAddress)) { return(null); //offer declined by client; do nothing } leaseOffer = scope.GetExistingLeaseOrOffer(request); if (leaseOffer == null) { //no existing lease or offer available for client //send nak return(new DhcpMessage(request, IPAddress.Any, scope.InterfaceAddress, new DhcpOption[] { new DhcpMessageTypeOption(DhcpMessageType.Nak), new ServerIdentifierOption(scope.InterfaceAddress), DhcpOption.CreateEndOption() })); } if (!request.RequestedIpAddress.Address.Equals(leaseOffer.Address)) { //requested ip is incorrect //send nak return(new DhcpMessage(request, IPAddress.Any, scope.InterfaceAddress, new DhcpOption[] { new DhcpMessageTypeOption(DhcpMessageType.Nak), new ServerIdentifierOption(scope.InterfaceAddress), DhcpOption.CreateEndOption() })); } } List <DhcpOption> options = scope.GetOptions(request, scope.InterfaceAddress); if (options == null) { return(null); } scope.CommitLease(leaseOffer); //log ip lease LogManager log = _log; if (log != null) { log.Write(remoteEP as IPEndPoint, "DHCP Server leased IP address [" + leaseOffer.Address.ToString() + "] to " + request.GetClientFullIdentifier() + "."); } //update hostname in reserved leases if ((request.HostName != null) && (scope.ReservedLeases != null)) { foreach (Lease reservedLease in scope.ReservedLeases) { if (reservedLease.ClientIdentifier.Equals(leaseOffer.ClientIdentifier)) { reservedLease.SetHostName(request.HostName.HostName); break; } } } if (string.IsNullOrWhiteSpace(scope.DomainName)) { //update lease hostname leaseOffer.SetHostName(request.HostName?.HostName); } else { //update dns string clientDomainName = null; foreach (DhcpOption option in options) { if (option.Code == DhcpOptionCode.ClientFullyQualifiedDomainName) { clientDomainName = (option as ClientFullyQualifiedDomainNameOption).DomainName; break; } } if (string.IsNullOrWhiteSpace(clientDomainName)) { if (request.HostName != null) { clientDomainName = request.HostName.HostName.Replace(' ', '-') + "." + scope.DomainName; } } if (!string.IsNullOrWhiteSpace(clientDomainName)) { leaseOffer.SetHostName(clientDomainName.ToLower()); UpdateDnsAuthZone(true, scope, leaseOffer); } } return(new DhcpMessage(request, leaseOffer.Address, scope.InterfaceAddress, options)); } case DhcpMessageType.Decline: { //ip address is already in use as detected by client via ARP if ((request.ServerIdentifier == null) || (request.RequestedIpAddress == null)) { return(null); //client MUST include these option; do nothing } Scope scope = FindScope(request, remoteEP.Address, ipPacketInformation); if (scope == null) { return(null); //no scope available; do nothing } if (!request.ServerIdentifier.Address.Equals(scope.InterfaceAddress)) { return(null); //request not for this server; do nothing } Lease lease = scope.GetExistingLeaseOrOffer(request); if (lease == null) { return(null); //no existing lease or offer available for client; do nothing } if (!lease.Address.Equals(request.RequestedIpAddress.Address)) { return(null); //the client's notion of its IP address is not correct; do nothing } //remove lease since the IP address is used by someone else scope.ReleaseLease(lease); //log issue LogManager log = _log; if (log != null) { log.Write(remoteEP as IPEndPoint, "DHCP Server received DECLINE message: " + lease.GetClientFullIdentifier() + " detected that IP address [" + lease.Address + "] is already in use."); } //update dns UpdateDnsAuthZone(false, scope, lease); //do nothing return(null); } case DhcpMessageType.Release: { //cancel ip address lease if (request.ServerIdentifier == null) { return(null); //client MUST include this option; do nothing } Scope scope = FindScope(request, remoteEP.Address, ipPacketInformation); if (scope == null) { return(null); //no scope available; do nothing } if (!request.ServerIdentifier.Address.Equals(scope.InterfaceAddress)) { return(null); //request not for this server; do nothing } Lease lease = scope.GetExistingLeaseOrOffer(request); if (lease == null) { return(null); //no existing lease or offer available for client; do nothing } if (!lease.Address.Equals(request.ClientIpAddress)) { return(null); //the client's notion of its IP address is not correct; do nothing } //release lease scope.ReleaseLease(lease); //log ip lease release LogManager log = _log; if (log != null) { log.Write(remoteEP as IPEndPoint, "DHCP Server released IP address [" + lease.Address.ToString() + "] that was leased to " + lease.GetClientFullIdentifier() + "."); } //update dns UpdateDnsAuthZone(false, scope, lease); //do nothing return(null); } case DhcpMessageType.Inform: { //need only local config; already has ip address assigned externally/manually Scope scope = FindScope(request, remoteEP.Address, ipPacketInformation); if (scope == null) { return(null); //no scope available; do nothing } List <DhcpOption> options = scope.GetOptions(request, scope.InterfaceAddress); if (options == null) { return(null); } //log inform LogManager log = _log; if (log != null) { log.Write(remoteEP as IPEndPoint, "DHCP Server received INFORM message from " + request.GetClientFullIdentifier() + "."); } return(new DhcpMessage(request, IPAddress.Any, scope.InterfaceAddress, options)); } default: return(null); } }
public int EndReceiveMessageFrom(IAsyncResult asyncResult, ref SocketFlags socketFlags, ref EndPoint endPoint, out IPPacketInformation ipPacketInformation) { throw null; }
public static void Start(string protocol, string snifferIP, bool isIPV6) { byte[] snifferIn = new byte[4] { 1, 0, 0, 0 }; byte[] snifferOut = new byte[4] { 1, 0, 0, 0 }; byte[] snifferData = new byte[0]; byte[] snifferBuffer = new byte[1500]; Socket snifferSocket; IPEndPoint snifferIPEndPoint; EndPoint snifferEndPoint; AddressFamily addressFamily = AddressFamily.InterNetwork; if (isIPV6) { snifferEndPoint = new IPEndPoint(IPAddress.IPv6Any, 0); addressFamily = AddressFamily.InterNetworkV6; } else { snifferEndPoint = new IPEndPoint(IPAddress.Any, 0); } try { if (!isIPV6) { snifferSocket = new Socket(addressFamily, SocketType.Raw, ProtocolType.IP); snifferSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.HeaderIncluded, true); } else { if (String.Equals(protocol, "UDP")) { snifferSocket = new Socket(addressFamily, SocketType.Raw, ProtocolType.Udp); } else { snifferSocket = new Socket(addressFamily, SocketType.Raw, ProtocolType.IP); snifferSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.PacketInformation, true); } } snifferIPEndPoint = new IPEndPoint(IPAddress.Parse(snifferIP), 0); snifferSocket.ReceiveBufferSize = 4096; snifferSocket.Bind(snifferIPEndPoint); snifferSocket.IOControl(IOControlCode.ReceiveAll, snifferIn, snifferOut); } catch (Exception ex) { if (ex.Message.Equals("An attempt was made to access a socket in a way forbidden by its access permissions")) { Output.Queue(String.Format("[!] Error starting packet sniffer, check if shell has elevated privilege or set -Sniffer N for listener only mode.", Output.Timestamp())); Thread.Sleep(10); Program.isRunning = false; } else { Console.WriteLine(ex.Message); } throw; } int packetLength; while (Program.isRunning) { try { IPPacketInformation packetInformation = new IPPacketInformation(); SocketFlags socketFlags = SocketFlags.None; try { packetLength = snifferSocket.ReceiveMessageFrom(snifferBuffer, 0, snifferBuffer.Length, ref socketFlags, ref snifferEndPoint, out packetInformation); snifferData = new byte[packetLength]; Buffer.BlockCopy(snifferBuffer, 0, snifferData, 0, packetLength); } catch { packetLength = 0; } if (packetLength > 0) { IPHeader ipHeader = new IPHeader(); MemoryStream memoryStream = new MemoryStream(snifferData, 0, packetLength); BinaryReader binaryReader = new BinaryReader(memoryStream); IPAddress sourceIPAddress; int protocolNumber; string sourceIP = ""; string destinationIP = ""; int ipHeaderLength = 0; // no header for IPv6 if (!isIPV6) { ipHeader.ReadBytes(snifferData, 0); ipHeaderLength = ipHeader.IHL; byte versionHL = binaryReader.ReadByte(); protocolNumber = ipHeader.Protocol; sourceIP = ipHeader.SourceAddress.ToString(); destinationIP = ipHeader.DestinationAddress.ToString(); } else { sourceIPAddress = (snifferEndPoint as IPEndPoint).Address; sourceIP = sourceIPAddress.ToString(); destinationIP = packetInformation.Address.ToString(); if (String.Equals(protocol, "UDP")) { protocolNumber = 17; } else { protocolNumber = 6; // this doesn't keep UDP traffic out of TCP section } } switch (protocolNumber) { case 6: TCPHeader tcpHeader = new TCPHeader(); bool isTCP = true; // IPv6 workaround try { tcpHeader.ReadBytes(snifferData, ipHeaderLength); if (tcpHeader.SYN && !tcpHeader.ACK && snifferIP.Equals(destinationIP)) { Output.Queue(String.Format("[.] [{0}] TCP({1}) SYN packet from {2}:{3}", Output.Timestamp(), tcpHeader.DestinationPort, sourceIP, tcpHeader.SourcePort)); } } catch { isTCP = false; } string tcpDestinationPort = tcpHeader.DestinationPort.ToString(); string tcpSourcePort = tcpHeader.SourcePort.ToString(); if (tcpHeader.DataOffset >= 20 && isTCP) { byte[] tcpPayload = new byte[0]; try { tcpPayload = new byte[packetLength - tcpHeader.DataOffset - ipHeaderLength]; } catch { isTCP = false; } if (tcpPayload.Length > 0 && isTCP) { Buffer.BlockCopy(snifferData, ipHeaderLength + tcpHeader.DataOffset, tcpPayload, 0, tcpPayload.Length); switch (tcpHeader.DestinationPort) { case 139: ProcessSMB(tcpPayload, sourceIP, destinationIP, tcpSourcePort, tcpDestinationPort); break; case 445: ProcessSMB(tcpPayload, sourceIP, destinationIP, tcpSourcePort, tcpDestinationPort); break; } switch (tcpHeader.SourcePort) { case 139: ProcessSMB(tcpPayload, sourceIP, destinationIP, tcpSourcePort, tcpDestinationPort); break; case 445: ProcessSMB(tcpPayload, sourceIP, destinationIP, tcpSourcePort, tcpDestinationPort); break; } } } break; case 17: UDPHeader udpHeader = new UDPHeader(snifferData, ipHeaderLength); byte[] udpPayload = new byte[udpHeader.Length - 8]; Buffer.BlockCopy(snifferData, ipHeaderLength + 8, udpPayload, 0, udpPayload.Length); switch (udpHeader.DestinationPort) { case 53: { if (snifferIP.StartsWith(destinationIP)) { ProcessDNSRequest(udpPayload, sourceIP, udpHeader.SourcePort, snifferIP, 53); } } break; case 137: { if (!isIPV6) { ProcessNBNSRequest(udpPayload, sourceIP, udpHeader.SourcePort, snifferIP, 5355); } } break; case 547: { if (isIPV6) { ProcessDHCPv6Request(udpPayload, sourceIP, udpHeader.SourcePort, snifferIP, 547); } } break; case 5353: { ProcessMDNSRequest(udpPayload, sourceIP, udpHeader.SourcePort, snifferIP, 5353); } break; case 5355: { ProcessLLMNRRequest(udpPayload, sourceIP, udpHeader.SourcePort, snifferIP, 5355); } break; } break; } } } catch (Exception ex) { Output.Queue(String.Format("[-] [{0}] Packet sniffing error detected - {1}", Output.Timestamp(), ex.ToString())); } } }
public int EndReceiveMessageFrom(IAsyncResult asyncResult, ref SocketFlags socketFlags, ref EndPoint endPoint, out IPPacketInformation ipPacketInformation) { return(default(int)); }
public int ReceiveMessageFrom(byte[] buffer, int offset, int size, ref SocketFlags socketFlags, ref EndPoint remoteEP, out IPPacketInformation ipPacketInformation) { return(m_Socket.ReceiveMessageFrom(buffer, offset, size, ref socketFlags, ref remoteEP, out ipPacketInformation)); }
public int ReceiveMessageFrom(byte[] buffer, int offset, int size, SocketFlags& socketFlags, System.Net.EndPoint& remoteEPout , IPPacketInformation& ipPacketInformation) { }
public int EndReceiveMessageFrom(System.IAsyncResult asyncResult, SocketFlags& socketFlags, System.Net.EndPoint& endPointout , IPPacketInformation& ipPacketInformation) { }
private async Task ProcessDhcpRequestAsync(DhcpMessage request, IPEndPoint remoteEP, IPPacketInformation ipPacketInformation, Socket udpListener) { try { DhcpMessage response = await ProcessDhcpMessageAsync(request, remoteEP, ipPacketInformation); //send response if (response != null) { byte[] sendBuffer = new byte[1024]; MemoryStream sendBufferStream = new MemoryStream(sendBuffer); response.WriteTo(sendBufferStream); //send dns datagram if (!request.RelayAgentIpAddress.Equals(IPAddress.Any)) { //received request via relay agent so send unicast response to relay agent on port 67 await udpListener.SendToAsync(sendBuffer, 0, (int)sendBufferStream.Position, new IPEndPoint(request.RelayAgentIpAddress, 67)); } else if (!request.ClientIpAddress.Equals(IPAddress.Any)) { //client is already configured and renewing lease so send unicast response on port 68 await udpListener.SendToAsync(sendBuffer, 0, (int)sendBufferStream.Position, new IPEndPoint(request.ClientIpAddress, 68)); } else { //send response as broadcast on port 68 on appropriate interface bound socket if (!_udpListeners.TryGetValue(response.NextServerIpAddress, out Socket udpSocket)) { udpSocket = udpListener; //no appropriate socket found so use default socket } await udpSocket.SendToAsync(sendBuffer, 0, (int)sendBufferStream.Position, new IPEndPoint(IPAddress.Broadcast, 68), SocketFlags.DontRoute); //no routing for broadcast } } } catch (ObjectDisposedException) { //socket disposed } catch (Exception ex) { if ((_state == ServiceState.Stopping) || (_state == ServiceState.Stopped)) { return; //server stopping } LogManager log = _log; if (log != null) { log.Write(remoteEP, ex); } } }