/// <summary> /// Scans the network for IP Addresses and MAC Addresses and prints them out /// </summary> /// <returns> /// void /// </returns> public static void TCPScan() { // run nmap for hostnames string hstcmd = "nmap -sn 192.168.1.0/24 | awk '/scan report/ {print $5}'"; var hstouput = hstcmd.ExecBash(); // Parse the hostnames out into a list List <string> hostlist = new List <string>(hstouput.Split('\n')); // For every entry, If hostname matches masterhost, add the ip foreach (var hostname in hostlist) { if (hostname == masterhost) { // Create a List for the ips List <string> iplist = new List <string>(); // Create a List for the MACs List <string> maclist = new List <string>(); // Get the ips of the recognized hostnames string getaddr = "nmap -sL 192.168.1.0/24 | grep " + masterhost + "| awk '{print $6}' | tr -d '()'"; var ipoutput = getaddr.ExecBash(); // Split the outputs and add them to the list iplist = ipoutput.Split('\n').ToList(); // Remove the last line of the list (because it's always blank) if (iplist.Any()) { iplist.RemoveAt(iplist.Count - 1); } // For each ip in the list, ping it to get the MAC address then add to the list foreach (var address in iplist) { string getresult = "arping -c 1 " + address + " | grep -o -E \'([[:xdigit:]]{1,2}:){5}[[:xdigit:]]{1,2}\'"; // use grep to pull the MAC var result = getresult.ExecBash(); if (result == "") //if no result, tell that it's not available { result = "Unavailable"; } // format the result to get rid of newline characters //string cleanresult = Regex.Replace(result, @"\n", ""); maclist.Add(result); // add it to the list } // Show entries in the lists together for (var i = 0; i < iplist.Count; i++) { Console.WriteLine("FOUND!"); Console.WriteLine("IP: " + iplist[i] + " MAC: " + maclist[i]); //Show on same line // Generate a unique ID Random rnd = new Random(); int length = 5; var str = ""; for (var j = 0; j < length; j++) { str += ((char)(rnd.Next(1, 26) + 64)).ToString(); } // Sanitize and add the mac address and its unique id to the table. string mac = maclist[i].Replace("\n", String.Empty); mac = mac.Replace(":", String.Empty); // Insert the row unless it is already present, in which case ignore it. SQLHelper addvals = new SQLHelper("INSERT OR IGNORE INTO units (mac, ip, unit_id) VALUES('" + mac + "','" + iplist[i] + "','" + str + "')"); addvals.Run_Cmd(); } } } }
public static void TcpTownClient() { // Fetch ips in a list Console.WriteLine("Fetching IPs"); SQLHelper getips = new SQLHelper("SELECT ip FROM units"); getips.Run_Cmd(); getips.SetIPs(); // Fetch unit ids in a list Console.WriteLine("Fetching IDs"); SQLHelper getids = new SQLHelper("SELECT unit_id FROM units"); getids.Run_Cmd(); getids.SetIDs(); // Make a new list for the ips and ids List <string> iplist = getips.Get_List(); List <string> idlist = getids.Get_List(); // Now go through down each ip and id in the lists and request the data foreach (var address in iplist) { foreach (var id in idlist) { // if the id is not our city identifier, proceed with asking for levels if (id.ToString() != cityID) // !potential logic error != continues code, == skips... no idea why? { //debugging //var checkme = id; // Tell who we are connecting to Console.WriteLine("Connecting to Unit" + id + "..."); // Create a new TCP Client with the address and default port number var client = new TcpClient(address, portNum); // Establish a network Stream NetworkStream ns = client.GetStream(); // Setup a byte array byte[] bytes = new byte[1024]; // Read the bytes from the network stream into the array int bytesRead = ns.Read(bytes, 0, bytes.Length); // Format to string string received = Encoding.ASCII.GetString(bytes, 0, bytesRead); // Turn the input levels to an array string[] levels = received.Split(','); // Turn each level into a double double wat = Convert.ToDouble(levels[0]); double sew = Convert.ToDouble(levels[1]); double pow = Convert.ToDouble(levels[2]); // Generate a timestamp Int32 unixTimestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds; // Insert values with associated unit id into Database SQLHelper insertcmd = new SQLHelper("INSERT INTO status VALUES(" + unixTimestamp + "," + "'" + id + "'," + wat + "," + sew + "," + pow + ")"); insertcmd.Run_Cmd(); // Report levels Console.WriteLine("Unit " + id + " reports " + wat + " water, " + sew + " sewage, " + pow + " power"); } // if we are dealing with a city, we need to send the acknowledgement message - sp spin up a server else { // echo we're ignoring Console.WriteLine("Skipping City..."); } } } }
public static void FindCity() { // Set ACK message string ackmsg = "CCNCS"; // Fetch ips in a list SQLHelper getips = new SQLHelper("SELECT ip FROM units"); getips.Run_Cmd(); getips.SetIPs(); // Fetch unit ids in a list SQLHelper getids = new SQLHelper("SELECT unit_id FROM units"); getids.Run_Cmd(); getids.SetIDs(); // Make a new list for the ips and ids List <string> iplist = getips.Get_List(); List <string> idlist = getids.Get_List(); // Now go through down each ip and id in the lists and request the data foreach (var address in iplist) { foreach (var id in idlist) { // Create a new TCP Client with the address and default port number var client = new TcpClient(address, portNum); // Establish a network Stream NetworkStream ns = client.GetStream(); // Setup a byte array byte[] incoming_msg = new byte[1024]; // Read the bytes from the network stream into the array int bytesRead = ns.Read(incoming_msg, 0, incoming_msg.Length); // Format to string string received = Encoding.ASCII.GetString(incoming_msg, 0, bytesRead); // if the message that is received is our defined acknowledement message, we have the town control. if (received == ackmsg) { //Change the unit_ID to CCNCS SQLHelper changeID = new SQLHelper("UPDATE units SET unit_id='CCNCS' WHERE ip= '" + address + "'"); changeID.Run_Cmd(); // Then send the city ACK message byte[] outgoing_msg = new byte[1024]; // populate the byte array with our acknowledgement message byte[] byte_cityack = Encoding.ASCII.GetBytes(townackmsg); // try to write the acknowledgement message try { ns.Write(byte_cityack, 0, byte_cityack.Length); ns.Close(); client.Close(); } catch (Exception e) { Console.WriteLine(e.ToString()); } } } } }
static void Main(string[] args) { #region Command Arguments // Check for user input for (int i = 0; i < args.Length; i++) { if (args[i] == "--set-unit") { ContextSwitch.SetAsUnit(); } if (args[i] == "--set-town") { ContextSwitch.SetAsTown(); } if (args[i] == "--set-city") { ContextSwitch.SetAsCity(); } if (args[i] == "--get-mode") { Console.WriteLine(ContextSwitch.GetMode()); } if (args[i] == "--tcpscan") { NetworkRW.TCPScan(); } if (args[i] == "--gendb") { SQLHelper.CreateDB(); } if (args[i] == "--refresh-city") { NetworkRW.FindCity(); } if (args[i] == "--send-errors") { NetworkRW.SendError(); } } #endregion #region DeviceDefaults // If mode is not already set, then set it by default to unit mode if (!File.Exists("mode")) { ContextSwitch.SetAsDefault(); } // Create our dummy files if (!File.Exists("water") || !File.Exists("sewage") || !File.Exists("power")) { RetrieveData.CreateFiles(); } // Create a setupstat file if (!File.Exists("setupstat")) { ContextSwitch.CreateSetup(); } #endregion #region ModeDependants if (ContextSwitch.GetMode() == 0) // if unit { // We await a connection from the Town Control // by using the TCP Unit Server in Network Read/Write Console.WriteLine("Unit Mode Detected!"); ContextSwitch.FinishSetup(); // Setup can be set to finished NetworkRW.TcpUnitServer(); } if (ContextSwitch.GetMode() == 1) // if town { Console.WriteLine("Town Mode Detected!"); string stat = ContextSwitch.GetSetup(); // if the database doesn't exist, generate it and populate it if (stat == "pending") { Console.WriteLine("Generating Database..."); SQLHelper.CreateDB(); // create the database Console.WriteLine("Scanning Network..."); NetworkRW.TCPScan(); // populate the database Console.WriteLine("Detecting City..."); NetworkRW.FindCity(); // find the city ContextSwitch.FinishSetup(); // finish the setup } // Check setup again stat = ContextSwitch.GetSetup(); if (stat == "done") { // Initiate the TCP town client Console.WriteLine("Starting town client..."); NetworkRW.TcpTownClient(); // When finished, echo the errors to city Console.WriteLine("Sending any errors to city control..."); System.Threading.Thread.Sleep(5000); // pause briefly before continuing NetworkRW.SendError(); Console.WriteLine("Successfully sent errors"); } } if (ContextSwitch.GetMode() == 2) // if city { Console.WriteLine("City Mode Detected!"); string stat = ContextSwitch.GetSetup(); // if the database doesn't exist yet generate it, but do not populate it. if (stat == "pending") { Console.WriteLine("Initializating setup:"); Console.WriteLine("Generating Database..."); SQLHelper.CreateDB(); // create the database NetworkRW.CitySetup(); // run the city setup } //check setup again stat = ContextSwitch.GetSetup(); if (stat == "done") { // just run the city server NetworkRW.CityServer(); } } #endregion }