public bool TryGetOperatingSystems(out IList <DeviceFingerprint> osList, IEnumerable <Packets.AbstractPacket> packetList) { try { //throw new Exception("The method or operation is not implemented."); Packets.DhcpPacket dhcpPacket = null; Packets.IPv4Packet ipPacket = null; foreach (Packets.AbstractPacket p in packetList) { if (p.GetType() == typeof(Packets.DhcpPacket)) { dhcpPacket = (Packets.DhcpPacket)p; } else if (p.GetType() == typeof(Packets.IPv4Packet)) { ipPacket = (Packets.IPv4Packet)p; } } if (dhcpPacket != null)//It is OK if the ipPacket is null (which is unlikely) //osList=new List<string>(); { osList = new List <DeviceFingerprint>(); int osListWeight = 3;//in order to avoid getting hits on tests with weight 1 and 2 foreach (DhcpFingerprint f in this.fingerprintList) { int w = f.GetHighestMatchWeight(dhcpPacket, ipPacket); if (w > osListWeight) { osListWeight = w; osList.Clear(); //osList.Add(f.ToString()); osList.Add(new DeviceFingerprint(f.ToString(false), f.DeviceType, f.DeviceVendor)); } else if (w == osListWeight) { //osList.Add(f.ToString()); osList.Add(new DeviceFingerprint(f.ToString(false), f.DeviceType, f.DeviceVendor)); } } if (osList.Count > 0) { //packetList=osList; return(true); } } } catch (Exception e) { SharedUtils.Logger.Log("Satori DHCP exception. " + e.ToString(), SharedUtils.Logger.EventLogEntryType.Warning); //System.Diagnostics.Debug.Print(e.ToString()); } osList = null; return(false); }
//returns -1 if there was no match internal int GetHighestMatchWeight(Packets.DhcpPacket dhcpPacket, Packets.IPv4Packet ipPacket) { int highestWeight = -1; foreach (Test t in testList) { if (t.Weight > highestWeight && t.Matches(dhcpPacket, ipPacket)) { highestWeight = t.Weight; } } return(highestWeight); }
private void ExtractData(ref NetworkHost sourceHost, NetworkHost destinationHost, Packets.DhcpPacket dhcpPacket) { if (dhcpPacket.OpCode == Packets.DhcpPacket.OpCodeValue.BootRequest && (sourceHost.MacAddress == null || dhcpPacket.ClientMacAddress != sourceHost.MacAddress)) { sourceHost.MacAddress = dhcpPacket.ClientMacAddress; } else if (dhcpPacket.OpCode == Packets.DhcpPacket.OpCodeValue.BootReply && (destinationHost.MacAddress == null || dhcpPacket.ClientMacAddress != destinationHost.MacAddress)) { destinationHost.MacAddress = dhcpPacket.ClientMacAddress; } if (dhcpPacket.OpCode == Packets.DhcpPacket.OpCodeValue.BootReply && (dhcpPacket.GatewayIpAddress != null && dhcpPacket.GatewayIpAddress != System.Net.IPAddress.None && dhcpPacket.GatewayIpAddress.Address > 0)) { destinationHost.ExtraDetailsList["Default Gateway"] = dhcpPacket.GatewayIpAddress.ToString(); } System.Collections.Specialized.NameValueCollection optionParameterList = new System.Collections.Specialized.NameValueCollection(); //now check all the DHCP options //byte dhcpMessageType=0x00;//1=Discover, 2=Offer, 3=Request, 5=Ack, 8=Inform foreach (Packets.DhcpPacket.Option option in dhcpPacket.OptionList) { //TODO: Add option to Parameters list if (option.OptionCode == 12)//hostname { string hostname = Utils.ByteConverter.ReadString(option.OptionValue); sourceHost.AddHostName(hostname); optionParameterList.Add("DHCP Option 12 Hostname", hostname); } else if (option.OptionCode == 15)//Domain Name { string domain = Utils.ByteConverter.ReadString(option.OptionValue); sourceHost.AddDomainName(domain); optionParameterList.Add("DHCP Option 15 Domain", domain); } else if (option.OptionCode == 50) //requested IP address { if (dhcpPacket.DhcpMessageType == 3) //Must be a DHCP Request { System.Net.IPAddress requestedIpAddress = new System.Net.IPAddress(option.OptionValue); if (sourceHost.IPAddress != requestedIpAddress) { if (!base.MainPacketHandler.NetworkHostList.ContainsIP(requestedIpAddress)) { NetworkHost clonedHost = new NetworkHost(requestedIpAddress); clonedHost.MacAddress = sourceHost.MacAddress; //foreach(string hostname in sourceHost.HostNameList) // clonedHost.AddHostName(hostname); lock (base.MainPacketHandler.NetworkHostList) base.MainPacketHandler.NetworkHostList.Add(clonedHost); //now change the host to the cloned one (and hope it works out...) sourceHost = clonedHost; } else { sourceHost = base.MainPacketHandler.NetworkHostList.GetNetworkHost(requestedIpAddress); if (dhcpPacket.OpCode == Packets.DhcpPacket.OpCodeValue.BootRequest && (sourceHost.MacAddress == null || dhcpPacket.ClientMacAddress != sourceHost.MacAddress)) { sourceHost.MacAddress = dhcpPacket.ClientMacAddress; } } } if (sourceHost.MacAddress != null && previousIpList.ContainsKey(sourceHost.MacAddress.ToString())) { //if(previousIpList.ContainsKey(sourceHost.MacAddress.ToString())) { sourceHost.AddNumberedExtraDetail("Previous IP", previousIpList[sourceHost.MacAddress.ToString()].ToString()); //sourceHost.ExtraDetailsList["Previous IP"]=previousIpList[sourceHost.MacAddress.ToString()].ToString(); previousIpList.Remove(sourceHost.MacAddress.ToString()); } } else if (dhcpPacket.DhcpMessageType == 1)//DHCP discover //see which IP address the client hade previously //They normally requests the same IP as they hade before... { System.Net.IPAddress requestedIpAddress = new System.Net.IPAddress(option.OptionValue); this.previousIpList[sourceHost.MacAddress.ToString()] = requestedIpAddress; } } /* * else if(option.OptionCode==53) {//DHCP message type * if(option.OptionValue!=null && option.OptionValue.Length==1) * dhcpMessageType=option.OptionValue[0]; * }/*/ else if (option.OptionCode == 60)//vendor class identifier { string vendorCode = Utils.ByteConverter.ReadString(option.OptionValue); sourceHost.AddDhcpVendorCode(vendorCode); optionParameterList.Add("DHCP Option 60 Vendor Code", vendorCode); } else if (option.OptionCode == 81) //Client Fully Qualified Domain Name { string domain = Utils.ByteConverter.ReadString(option.OptionValue, 3, option.OptionValue.Length - 3); sourceHost.AddHostName(domain); optionParameterList.Add("DHCP Option 81 Domain", domain); } else if (option.OptionCode == 125) //V-I Vendor-specific Information http://tools.ietf.org/html/rfc3925 { uint enterpriceNumber = Utils.ByteConverter.ToUInt32(option.OptionValue, 0); optionParameterList.Add("DHCP Option 125 Enterprise Number", enterpriceNumber.ToString()); byte dataLen = option.OptionValue[4]; if (dataLen > 0 && option.OptionValue.Length >= 5 + dataLen) { string optionData = Utils.ByteConverter.ReadString(option.OptionValue, 5, dataLen); optionParameterList.Add("DHCP Option 125 Data", optionData); } } else { string optionValueString = Utils.ByteConverter.ReadString(option.OptionValue); if (!System.Text.RegularExpressions.Regex.IsMatch(optionValueString, @"[^\u0020-\u007E]")) { optionParameterList.Add("DHCP Option " + option.OptionCode.ToString(), optionValueString); } } } if (optionParameterList.Count > 0) { //try to get the udp packet string sourcePort = "UNKNOWN"; string destinationPort = "UNKNOWN"; foreach (Packets.AbstractPacket p in dhcpPacket.ParentFrame.PacketList) { if (p.GetType() == typeof(Packets.UdpPacket)) { Packets.UdpPacket udpPacket = (Packets.UdpPacket)p; sourcePort = "UDP " + udpPacket.SourcePort; destinationPort = "UDP " + udpPacket.DestinationPort; break; } } Events.ParametersEventArgs ea = new Events.ParametersEventArgs(dhcpPacket.ParentFrame.FrameNumber, sourceHost, destinationHost, sourcePort, destinationPort, optionParameterList, dhcpPacket.ParentFrame.Timestamp, "DHCP Option"); MainPacketHandler.OnParametersDetected(ea); } }
internal bool Matches(Packets.DhcpPacket dhcpPacket, Packets.IPv4Packet ipPacket) { foreach (string key in attributeList.Keys) { if (key == "weight") { //do nothing } else if (key == "matchtype") { //do nothing, I will alway require an exact match } else if (key == "dhcptype") { //1 DHCPDISCOVER [RFC2132] //2 DHCPOFFER [RFC2132] //3 DHCPREQUEST [RFC2132] //4 DHCPDECLINE [RFC2132] //5 DHCPACK [RFC2132] //6 DHCPNAK [RFC2132] //7 DHCPRELEASE [RFC2132] //8 DHCPINFORM [RFC2132] if (dhcpPacket.DhcpMessageType == 1 && attributeList[key] != "Discover") { return(false); } else if (dhcpPacket.DhcpMessageType == 2 && attributeList[key] != "Offer") { return(false); } else if (dhcpPacket.DhcpMessageType == 3 && attributeList[key] != "Request") { return(false); } else if (dhcpPacket.DhcpMessageType == 4 && attributeList[key] != "Decline") { return(false); } else if (dhcpPacket.DhcpMessageType == 5 && attributeList[key] != "ACK") { return(false); } else if (dhcpPacket.DhcpMessageType == 6 && attributeList[key] != "NAK") { return(false); } else if (dhcpPacket.DhcpMessageType == 7 && attributeList[key] != "Release") { return(false); } else if (dhcpPacket.DhcpMessageType == 8 && attributeList[key] != "Inform") { return(false); } } else if (key == "dhcpoptions") { //Typical format: 53,61,12,60,55 StringBuilder optionSB = new StringBuilder(); foreach (Packets.DhcpPacket.Option op in dhcpPacket.OptionList) { optionSB.Append(op.OptionCode); optionSB.Append(","); } if (optionSB.Length < 1) { return(false); } else if (optionSB.ToString(0, optionSB.Length - 1) != attributeList[key]) { return(false); } } else if (key == "dhcpvendorcode") { //find OptionCode 60 (vendor class identifier) and compare its value to attributeList[key] //can be for example: MSFT 5.0 Packets.DhcpPacket.Option option60 = null; foreach (Packets.DhcpPacket.Option o in dhcpPacket.OptionList) { if (o.OptionCode == 60) { option60 = o; } } if (option60 == null) { return(false); } else if (Utils.ByteConverter.ReadString(option60.OptionValue) != attributeList[key]) { return(false); } } else if (key == "dhcpttl") { //this is for IP packets! if (ipPacket == null) { return(false); } else if (ipPacket.TimeToLive.ToString() != attributeList[key]) { return(false); } } else if (key == "dhcpoption51") { uint tmpUInt; //IP Address Lease Time //for example: 77760000 (really?) or 43200 //It could also be 0xffffffff = "infinite" lease time Packets.DhcpPacket.Option option51 = null; foreach (Packets.DhcpPacket.Option o in dhcpPacket.OptionList) { if (o.OptionCode == 51) { option51 = o; } } if (option51 == null) { return(false); } else if (UInt32.TryParse(attributeList[key], out tmpUInt) && Utils.ByteConverter.ToUInt32(option51.OptionValue) != tmpUInt) { return(false); } else if (Utils.ByteConverter.ToUInt32(option51.OptionValue) == UInt32.MaxValue && attributeList[key] != "infinite") { return(false); } } else if (key == "dhcpoption55") { //Parameter Request List //For example: 1,3,6,15,28,12,7,9,42,48,49 Packets.DhcpPacket.Option option55 = null; foreach (Packets.DhcpPacket.Option o in dhcpPacket.OptionList) { if (o.OptionCode == 55) { option55 = o; } } if (option55 == null) { return(false); } else { StringBuilder sb = new StringBuilder(); foreach (byte b in option55.OptionValue) { sb.Append(b.ToString()); sb.Append(","); } if (sb.Length < 1) { return(false); } else if (sb.ToString(0, sb.Length - 1) != attributeList[key]) { return(false); } } } else if (key == "dhcpoption57") { //DHCP Maximum Message Size //For example: 548 or 590 or 1500 Packets.DhcpPacket.Option option57 = null; foreach (Packets.DhcpPacket.Option o in dhcpPacket.OptionList) { if (o.OptionCode == 57) { option57 = o; } } if (option57 == null) { return(false); } else if (Utils.ByteConverter.ToUInt16(option57.OptionValue) != Convert.ToUInt16(attributeList[key])) { return(false); } } else if (key == "ipttl") { if (ipPacket.TimeToLive.ToString() != attributeList[key]) { return(false); } } } //since no mis-match was found I guess it was a match... return(true); }