1 // License: BSD/LGPL 2 // Copyright (C) 2011-2018 Thomas d'Otreppe 3 using System; 4 5 namespace WirelessPanda.Readers 6 { 7 public class KismetCsvReader : Reader 8 { 9 /// <summary> 10 /// Date format (Same format for Kismet CSV and NetXML) 11 /// </summary> 12 protected override string DATE_FORMAT 13 { 14 get 15 { 16 return "ddd MMM dd HH:mm:ss yyyy"; 17 } 18 } 19 20 /// <summary> 21 /// Date format (Same format for Kismet CSV and NetXML) 22 /// </summary> 23 protected override string ALT_DATE_FORMAT 24 { 25 get 26 { 27 return "ddd MMM d HH:mm:ss yyyy"; 28 } 29 } 30 31 32 /// <summary> 33 /// Reader type 34 /// </summary> 35 public override string ReaderType 36 { 37 get 38 { 39 return "Kismet CSV"; 40 } 41 } 42 43 /// <summary> 44 /// Constructor 45 /// </summary> 46 /// <param name="filename">Filename (doesn't need to exist now but MUST when using Read() )</param> KismetCsvReader(string filename)47 public KismetCsvReader(string filename) : base(filename) { } 48 49 /// <summary> 50 /// Read/Update the content of the file 51 /// </summary> 52 /// <returns>true if successful</returns> 53 /// <exception cref="FormatException">Airodump-ng CSV format unknown</exception> Read()54 public override bool Read() 55 { 56 // Reset parsing status 57 this.ParseSuccess = false; 58 59 // Get the content of the file 60 string[] content = this.getStrippedFileContent(); 61 62 // Check if this is really a kismet CSV file 63 if (content.Length == 0) 64 { 65 throw new FormatException("Empty file"); 66 } 67 68 this.ParseSuccess = (content[0] == "Network;NetType;ESSID;BSSID;Info;Channel;Cloaked;Encryption;Decrypted;MaxRate;MaxSeenRate;Beacon;LLC;Data;Crypt;Weak;Total;Carrier;Encoding;FirstTime;LastTime;BestQuality;BestSignal;BestNoise;GPSMinLat;GPSMinLon;GPSMinAlt;GPSMinSpd;GPSMaxLat;GPSMaxLon;GPSMaxAlt;GPSMaxSpd;GPSBestLat;GPSBestLon;GPSBestAlt;DataSize;IPType;IP;"); 69 if (!this.ParseSuccess) 70 { 71 throw new FormatException("Not a Kismet CSV file"); 72 } 73 74 // Parse content 75 for (int i = 1; i < content.Length && !string.IsNullOrEmpty(content[i]); i++) 76 { 77 string [] splitted = content[i].Split(';'); 78 79 // Check if there are enough elements 80 if (splitted.Length < 39) 81 { 82 continue; 83 } 84 85 AccessPoint ap = new AccessPoint(); 86 87 // Skip first element which is the network number (if someone cares about it, email me) 88 ap.NetworkType = splitted[1].Trim(); 89 ap.ESSID = splitted[2].Trim(); 90 ap.ESSIDLength = (byte)splitted[2].Length; 91 ap.BSSID = splitted[3].Trim(); 92 ap.Info = splitted[4].Trim(); 93 ap.Channel = int.Parse(splitted[5]); 94 ap.Cloaked = (splitted[6].Trim().ToLower() == "yes"); 95 ap.Encryption = splitted[7].Trim(); 96 ap.Decrypted = (splitted[8].Trim().ToLower() == "yes"); 97 ap.MaxRate = double.Parse(splitted[9]); 98 ap.MaxSeenRate = double.Parse(splitted[10]); 99 ap.Beacon = ulong.Parse(splitted[11]); 100 ap.LLC = ulong.Parse(splitted[12]); 101 ap.DataFrames = ulong.Parse(splitted[13]); 102 ap.Crypt = ulong.Parse(splitted[14]); 103 ap.Weak = ulong.Parse(splitted[15]); 104 ap.Total = ulong.Parse(splitted[16]); 105 ap.Carrier = splitted[17].Trim(); 106 ap.Encoding = splitted[18].Trim(); 107 ap.FirstTimeSeen = this.parseDateTime(splitted[19]); 108 ap.LastTimeSeen = this.parseDateTime(splitted[20]); 109 ap.BestQuality = int.Parse(splitted[21]); 110 ap.BestSignal = int.Parse(splitted[22]); 111 ap.BestNoise = int.Parse(splitted[23]); 112 ap.MinLocation = new Coordinates(splitted[24], splitted[25], splitted[26], splitted[27]); 113 ap.MaxLocation = new Coordinates(splitted[28], splitted[29], splitted[30], splitted[31]); 114 ap.BestLocation = new Coordinates(splitted[32], splitted[33], splitted[34], ""); 115 ap.DataSize = ulong.Parse(splitted[35]); 116 ap.IPType = int.Parse(splitted[36]); 117 ap.IP = splitted[37].Replace(" ", ""); 118 119 this.addAccessPoint(ap); 120 } 121 122 // No need to link stations and access points together since there are only access points. 123 124 return true; 125 } 126 127 128 } 129 } 130