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