Advertisement
Tatantyler

CRFv3.1

May 18th, 2013
1,179
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 55.46 KB | None | 0 0
  1. -- Common Routing Framework, Version 3.1
  2. -- This version adds Local Area Networks, allowing multiple computers to be added to the network with a minimum of resource usage.
  3. -- The clients in a LAN are shown to other hosts as routers with only one neighbor: the router that is hosting the LAN.
  4. -- The router then intercepts packets addressed to LAN clients and sends them as LAN data packets.
  5. -- This functionality can also be used to bridge wired and wireless networks.
  6. -- LAN encryption is supported; as with most things involving encryption, it requires the AES and SHA2 libraries.
  7. -- WAN encryption is supported; again, it also requires the AES/SHA2 libraries.
  8.  
  9. -- Packet structure (CRF and LAN):
  10. -- [1] : Identification String ("CRFv3" for CRF packets, "LAN" for LAN packets)
  11. -- [2] : Sender
  12. -- [3] : Packet Type
  13. -- [4+]: Data
  14.  
  15. -- Packet Types / Structure:
  16. -- "ping" / "pong" : Reachability Protocol packets, has one field: the Multicast Group List. CRF only.
  17. --  * Multicast Group List: A list of groups this router is listening to.
  18. -- "lsa" : Link State Advertisement, used to inform other routers about potential routes. Has one data field, containing the LSA itself. CRF only.
  19. --  * LSA Format:
  20. --   * Originator: The ID of the computer who originally generated the LSA.
  21. --   * ID: A 32 bit number that is different for each LSA sent out by a particular host. LSAs from the same host with duplicate IDs are ignored.
  22. --   * Recipient List: A list of computers who have received a particular LSA. Used to detect duplicate LSAs.
  23. --   * Host List: A list of computers directly linked to the Originator (wirelessly or otherwise). Used to calculate routing tables.
  24. -- "data" : Data. Has four data fields:
  25. --  * Source: The computer sending the packet. Not present in LAN data packets; the "Sender" field takes care of this.
  26. --  * Recipient: The computer receiving the packet. In LAN data packets, a "Recipient" field of -1 indicates a broadcast packet.
  27. --  * Message: The data sent.
  28. --  * Next-hop: The computer the packet is being forwarded to. Not present in LAN data packets.
  29. --  * Multicast ID: A unique (for each source router) number used to filter out duplicate multicast packets. This is similar to LSA IDs.
  30.  
  31. -- LAN-only packets:
  32. -- "encrypted_data": An encrypted data packet. Field 5 is a table containing the encrypted bytes of a serialized table of the format: {recipient, data}.
  33. -- "auth_required":
  34. --  * From client to server: A message asking if authentication is required.
  35. --  * From server to client: A message confirming that authentication is required.
  36. -- "auth_not_required": A message confirming that authentication is not required.
  37. -- "auth_req" : A request to authenticate.
  38. -- "auth_challenge" : A challenge issued by an AP to a client, in response to an "auth_req" message.
  39. -- "auth_response" : A response to a challenge contained in a "auth_challenge" message.
  40. -- "auth_good" : An indication that the response matched what was expected and that the client is now clear to associate.
  41. -- "auth_fail" : An indication that the response did not match what was expected.
  42. -- "assoc" : A request to join a particular Local Area Network.
  43. -- "assoc_ack" : An acknowledgement of the above packet.
  44. -- "assoc_fail": An indication that the requestor is already a part of the indicated LAN.
  45. -- "disassoc" : A request to leave a particular Local Area Network.
  46. -- "disassoc_ack" : An acknowledgement of the above packet.
  47. -- "disassoc_fail": An indication that the disassociation packet is invalid (came from the wrong interface) or that the requestor was never a part of the LAN in the first place.
  48. -- "id_list": A (request for) a listing of every client the router knows of, including other routers and their LANs.
  49. -- "lan_list": A (request for) a listing of every client on the requestor's Local Area Network.
  50. -- "join_group": A request to register for multicast listening.
  51. -- "leave_group": A request to unregister for multicast listening.
  52. -- "group_ack": A positive acknowlegement for the above two packets.
  53. -- "group_fail": A negative acknowlegement for the above group join/leave requests.
  54.  
  55. -- On Multicast:
  56. -- Multicast is indicated by a negative "Recipient" address in packets.
  57. -- The "group" the packet belongs to is defined as abs(recipient); for example, a "recipient" value of -5 indicates a group of 5. Multicast group 1 (recipient address -1) is reserved for the local (LAN) broadcast group.
  58. -- Groups are used to indicate which routers want which packets.
  59. -- Routers and LAN Clients indicate that they wish to join a particular group. Any multicast packets passing through that belong to that group are replicated and sent both to any adjecent routers who have indicated that they wish to receive that packet, and
  60. -- any those local clients.
  61.  
  62. -- On WAN encryption:
  63. -- WAN encryption runs on top of the normal router. It defines one additional packet type, identified by the string "encrypted_packet".
  64. -- structure: {crf_ident, local sender, "encrypted_packet", encrypted data, iv, src, rec, next_hop, key_ident, hmac, recv_list }
  65. -- hmac is hmac( textutils.serialize( {decrypted_data, encrypted_data, iv, key_ident, src, rec} ) )
  66.  
  67. if not fs.exists("AES") then
  68.     print("AES library does not exist, attempting to download...")
  69.     if http then
  70.         local wHandle = http.get("http://pastebin.com/raw.php?i=rCYDnCxn")
  71.         if wHandle then
  72.             local fHandle = fs.open("AES", "w")
  73.             if fHandle then
  74.                 fHandle.write(wHandle.readAll())
  75.                 fHandle.close()
  76.                 haveSoftware_AES = true
  77.             else
  78.                 print("Could not open AES for writing.")
  79.             end
  80.             wHandle.close()
  81.         else
  82.             print("Could not connect to pastebin.")
  83.         end
  84.     else
  85.         print("HTTP is disabled.")
  86.     end
  87. end
  88.  
  89. if not fs.exists("SHA2") then
  90.     print("SHA2 library does not exist, attempting to download...")
  91.     if http then
  92.         local wHandle = http.get("http://pastebin.com/raw.php?i=9c1h7812")
  93.         if wHandle then
  94.             local fHandle = fs.open("SHA2", "w")
  95.             if fHandle then
  96.                 fHandle.write(wHandle.readAll())
  97.                 fHandle.close()
  98.                 haveSoftware_SHA2 = true
  99.             else
  100.                 print("Could not open SHA2 for writing.")
  101.             end
  102.             wHandle.close()
  103.         else
  104.             print("Could not connect to pastebin.")
  105.         end
  106.     else
  107.         print("HTTP is disabled.")
  108.     end
  109. end
  110.  
  111. local securityEnabled = true
  112.  
  113. if (not ((AES ~= nil) or os.loadAPI("AES"))) or (not ((SHA2 ~= nil) or os.loadAPI("SHA2"))) then
  114.     print("Could not load encryption libraries; encrypted LAN/WAN functionality disabled!")
  115.     securityEnabled = true
  116. end
  117.  
  118. local args = {...}
  119.  
  120. -- Static Variables:
  121. local crf_freq = 0xE110
  122. local crf_identStr = "CRFv3"
  123. local crf_pongStr = textutils.serialize( {crf_identStr, os.computerID(), "pong"} )
  124. local crf_running = false
  125.  
  126. local wan_enc_routers = {} -- Routers using the same key as we are
  127. local wan_enc_routers_local = {} -- Local routers using the same key as we are
  128. local wan_key = {}
  129. local wan_key_ident = ""
  130. local wan_verify_inbound = true -- Check verification HMAC for incoming packets
  131. local wan_verify_outbound = true -- Add verification HMAC to outgoing packets
  132. _G["CRF"] = {}
  133.  
  134. local lan_freq = 0xC01D
  135. local lan_identStr = "LAN"
  136. local lan_clients = {}
  137. local lan_auth = {} -- Client authentication list; contains challenge text and authentication state.
  138. local lan_key = {}
  139. local lan_name = "Network #"..os.computerID()
  140. local lan_running = false
  141. local lan_multicast = {} -- Multicast group list. Stored as a dictionary; lan_multicast[5] corresponds to multicast group 5.
  142. _G["LAN"] = {}
  143.  
  144. local debugFlags = {
  145.     ["events"]     = 0x01, -- Routing events (LSA / Ping recieved, data incoming), automatically assumes all other "event" flags ("timed", "dataEvents", "pingEvents", and "lsaEvents")
  146.     ["timed"]      = 0x02, -- Timing events (Ping/LSACheck/LSAForce timers)
  147.     ["timing"]     = 0x02, -- alias for "timed"
  148.     ["routeGen"]   = 0x04, -- Route generation (Interface bindings, etc.)
  149.     ["bfs"]        = 0x08, -- Breadth-first search function info (currentnode=1, etc)
  150.     ["dataEvents"] = 0x10, -- Incoming data only
  151.     ["pingEvents"] = 0x20, -- Reachability Protocol only
  152.     ["lsaEvents"]  = 0x40, -- LSAs only
  153.     ["LANEvents"]  = 0x80, -- LAN protocol events (associations, disassociations, list requests, etc.)
  154.     ["all"]        = 0xFF, -- Sets all event bits.
  155. }
  156.  
  157. -- Dynamic Variables:
  158.  
  159. -- We need two lists, because some hosts may only be reachable through one interface.
  160. local wirelessModem = {} -- Only need one wireless modem.
  161. local wiredModems = {}
  162. local modem = {} -- For convenience.
  163.  
  164. local routingTable = {} -- Holds next-hop interfaces for each reachable host.
  165. local localHosts = {} -- Holds host/interface bindings for all directly-reachable hosts.
  166. local allHosts = {} -- Holds host/interface bindings for all hosts on all attached networks.
  167.  
  168. local multicast_downstream = {} -- Holds a list of multicast groups we need to keep track of. Stored by adjecent router. Example: multicast_downstream[5] is a list of all multicast groups router 5 is listening to.
  169. local multicast_ids = {} -- Holds a list of packet IDs for multicast groups we're keeping track of. Stored by group.
  170.  
  171. local lastLSAs = {}
  172.  
  173. for i,v in ipairs(rs.getSides()) do
  174.     if peripheral.getType(v) == "modem" then
  175.         local iModem = peripheral.wrap(v)
  176.         iModem["side"] = v
  177.         if iModem.isWireless() and (not wirelessModem.open) then
  178.             wirelessModem = iModem
  179.             wirelessModem.open(crf_freq)
  180.             wirelessModem.open(lan_freq)
  181.         else
  182.             iModem.open(crf_freq)
  183.             iModem.open(lan_freq)
  184.             wiredModems[v] = iModem
  185.             table.insert(wiredModems, iModem)
  186.         end
  187.         modem[v] = iModem
  188.     end
  189. end
  190.  
  191. local function bfs(list, start, dest, debug)
  192.     local queue = { start }
  193.     local paths = {}
  194.     local route = {}
  195.     local visited = { [start] = true }
  196.     while true do
  197.         local current = table.remove(queue, 1)
  198.         if current == dest then
  199.             break
  200.         end
  201.         if (type(debug) == "number") and (bit.band(debug, debugFlags["bfs"]) > 0) then
  202.             print("bfs: current="..current)
  203.         end
  204.         for node, side in pairs(list[current]) do
  205.             if (type(debug) == "number") and (bit.band(debug, debugFlags["bfs"]) > 0) then
  206.                 print("bfs: current node="..node)
  207.             end
  208.             if not visited[node] and list[node] then
  209.                 visited[node] = true
  210.                 paths[node] = current
  211.                 table.insert(queue, node)
  212.             end
  213.         end
  214.         if #queue == 0 then
  215.             break
  216.         end
  217.         os.queueEvent("CRF_routegen")
  218.         os.pullEvent("CRF_routegen")
  219.     end
  220.     if dest then
  221.         local c = dest
  222.         while true do
  223.             table.insert(route, 1, c)
  224.             c = paths[c]
  225.             if not c then
  226.                 break
  227.             end
  228.             os.queueEvent("CRF_routegen")
  229.             os.pullEvent("CRF_routegen")
  230.         end
  231.     end
  232.     return route, paths
  233. end
  234.  
  235. local function generateRoutingTable(debug)
  236.     for i,v in pairs(lan_clients) do
  237.         localHosts[i] = v
  238.         allHosts[i] = v
  239.     end
  240.     local hostLSAs = { [os.computerID()] = localHosts }
  241.     for i,v in pairs(lastLSAs) do
  242.         hostLSAs[i] = v[2]
  243.     end
  244.     if (type(debug) == "number") and bit.band(debug, debugFlags["routeGen"]) > 0 then
  245.         print("Generating routing tables...")
  246.     end
  247.     local _, paths = bfs(hostLSAs, os.computerID(), nil, debug) -- get paths to all nodes
  248.     local hostDict = {}
  249.     for i,v in pairs(paths) do
  250.         if (type(debug) == "number") and (bit.band(debug, debugFlags["routeGen"]) > 0) then
  251.             print("Path found for "..i.." and "..v)
  252.         end
  253.         hostDict[i] = true
  254.         hostDict[v] = true
  255.         os.queueEvent("CRF_routegen")
  256.         os.pullEvent("CRF_routegen")
  257.     end
  258.     for i,v in pairs(hostDict) do
  259.         --local route = bfs(hostLSAs, os.computerID(), i, debug)
  260.         --routingTable[i] = {localHosts[route[2]], route[2]}
  261.         if (type(debug) == "number") and (bit.band(debug, debugFlags["routeGen"]) > 0) then
  262.             print("Determining interface for "..i)
  263.         end
  264.         if i ~= os.computerID() then
  265.             if localHosts[i] then -- We're directly connected to the host, so we can just look in localHosts instead of following the link chain
  266.                 if (type(debug) == "number") and (bit.band(debug, debugFlags["routeGen"]) > 0) then
  267.                     print("Interface for "..i..": "..localHosts[i].." (local)")
  268.                 end
  269.                 routingTable[i] = { localHosts[i], i }
  270.             else
  271.                 local route = {}
  272.                 local c = i
  273.                 local step = 0
  274.                 while true do
  275.                     table.insert(route, 1, c)
  276.                     c = paths[c]
  277.                     if not c then
  278.                         break
  279.                     end
  280.                     if (type(debug) == "number") and bit.band(debug, debugFlags["routeGen"]) > 0 then
  281.                         print("Determining interface for "..i..". c: "..c)
  282.                     end
  283.                 end
  284.                 if localHosts[route[2]] then
  285.                     routingTable[i] = { localHosts[route[2]], route[2] }
  286.                     if (type(debug) == "number") and (bit.band(debug, debugFlags["routeGen"]) > 0) then
  287.                         print("Interface for "..i.." is "..localHosts[route[2]]..", via "..route[2])
  288.                     end
  289.                 elseif (type(debug) == "number") and (bit.band(debug, debugFlags["routeGen"]) > 0) then
  290.                     print("Interface for "..os.computerID().."->"..route[2].." is unknown")
  291.                 end
  292.             end
  293.         end
  294.         if (type(debug) == "number") and (bit.band(debug, debugFlags["routeGen"]) > 0) then
  295.             print("Finished determining interface for "..i)
  296.         end
  297.     end
  298. end
  299.  
  300. local function transmitLSA(debug)
  301.     for i,v in pairs(lan_clients) do
  302.         localHosts[i] = v
  303.         allHosts[i] = v
  304.         wan_enc_routers_local[i] = wan_key_ident
  305.     end
  306.     local lsa = {os.computerID(), 0, {}, localHosts, wan_enc_routers_local } -- transmit our ID, the LSA ID, the list of hosts we're connected to, and a dict matching keys to entries in localHosts
  307.     while true do
  308.         local cand = math.random(1, (2^30))
  309.         if not lastLSAs[os.computerID()] or lastLSAs[os.computerID()][1] ~= cand then
  310.             lsa[2] = cand
  311.             lastLSAs[os.computerID()] = { cand, localHosts }
  312.             break
  313.         end
  314.     end
  315.     if (type(debug) == "number") and ((bit.band(debug, debugFlags["lsaEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  316.         print("Sending LSAs on all interfaces...")
  317.     end
  318.     if wirelessModem.transmit then
  319.         wirelessModem.transmit( crf_freq, crf_freq, textutils.serialize( {crf_identStr, os.computerID(), "lsa", lsa} ) )
  320.     end
  321.     for i=1, #wiredModems do
  322.         wiredModems[i].transmit(crf_freq, crf_freq, textutils.serialize( { crf_identStr, os.computerID(), "lsa", lsa } ))
  323.     end
  324.     generateRoutingTable(debug)
  325. end
  326.  
  327. local function raw_encrypted_send(side, packetTo, sender, packetData)
  328.     if (type(packetData) ~= "string") then
  329.         error("encrypted_send: data type must be string!", 2)
  330.     end
  331.     if (#lan_key ~= 0) then
  332.         local plain_data = {}
  333.         local plain_data_str = textutils.serialize({sender, packetData})
  334.         local iv = {}
  335.         for i=1, 16 do
  336.             iv[i] = math.random(0, 255)
  337.         end
  338.         for i=1, #plain_data_str do
  339.             plain_data[i] = string.byte(plain_data_str, i, i)
  340.         end
  341.         local enc_packet = AES.encrypt_bytestream(plain_data, lan_key, iv)
  342.         --print(side)
  343.         modem[side].transmit(lan_freq, lan_freq, textutils.serialize( {lan_identStr, os.computerID(), "encrypted_data", packetTo, iv, enc_packet} ))
  344.     end
  345. end
  346.  
  347. local function encrypted_wan_send(msg, from, to)
  348.     -- structure: {crf_ident, local sender, "encrypted_packet", encrypted data, iv, src, rec, next_hop, hmac, recv_list }
  349.     -- hmac is hmac( textutils.serialize( {decrypted_data, iv, src, rec} ) )
  350.     local dec_data = {}
  351.     for i=1, #msg do
  352.         dec_data[i] = string.byte(msg, i, i)
  353.     end
  354.     local iv = {}
  355.     for i=1, 16 do
  356.         iv[i] = math.random(0, 255)
  357.     end
  358.     local enc_data = AES.encrypt_bytestream(dec_data, wan_key, iv)
  359.     local hmac = {}
  360.     if wan_verify_outbound then
  361.         local verify_data_str = "" --textutils.serialize({dec_data, iv, from, to})
  362.         for i=1, #enc_data do
  363.             verify_data_str = verify_data_str..string.char(enc_data[i])
  364.         end
  365.         for i=1, #iv do
  366.             verify_data_str = verify_data_str..string.format("%X", iv[i])
  367.         end
  368.         verify_data_str = verify_data_str..from
  369.         verify_data_str = verify_data_str..to
  370.         local verify_data = {}
  371.         for i=1, #verify_data_str do
  372.             verify_data[i] = string.byte(verify_data_str, i, i)
  373.         end
  374.         hmac = SHA2.hashToBytes(SHA2.hmac(verify_data, wan_key))
  375.         local h1_str = ""
  376.         if (type(debug) == "number") and ((bit.band(debug, debugFlags["dataEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  377.             for i=1, #hmac do
  378.                 h1_str = h1_str..string.format("%X", hmac[i])
  379.             end
  380.             local iv_str = ""
  381.             for i=1, #iv do
  382.                 iv_str = iv_str..string.format("%X", iv[i])
  383.             end
  384.             print("CRF: HMAC is: "..h1_str)
  385.             print("CRF: Verify string is: "..verify_data_str)
  386.             print("CRF: Init vector is: "..iv_str)
  387.         end
  388.     else
  389.         hmac = nil
  390.     end
  391.     modem[routingTable[to][1]].transmit(crf_freq, crf_freq, textutils.serialize( {crf_identStr, os.computerID(), "encrypted_packet", enc_data, iv, from, to, routingTable[to][2], hmac, [10] = { [os.computerID()] = true } } ))
  392. end
  393.  
  394. local function handle_datagram(side, data, packetTo, packetData)
  395.     local sender = data[2]
  396.     if packetTo == -1 then -- Broadcast
  397.         for client_id, client_side in pairs(lan_clients) do
  398.             if data[3] == "encrypted_data" then
  399.                 raw_encrypted_send(client_side, client_id, sender, packetData)
  400.             else
  401.                 modem[client_side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "data", client_id, sender, packetData } ))
  402.             end
  403.         end
  404.         modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "data_ack", sender} ))
  405.         if (type(debug) == "number") and ((bit.band(debug, debugFlags["LANEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  406.             print("LAN: Broadcast message from "..sender.." received.")
  407.         end
  408.     elseif packetTo < -1 then -- Multicast
  409.         local cand = math.random(0, 2^30)
  410.         while true do
  411.             if multicast_ids[math.abs(packetTo)] ~= cand then
  412.                 break
  413.             else
  414.                 cand = math.random(0, 2^30)
  415.             end
  416.         end
  417.         multicast_ids[math.abs(packetTo)] = cand
  418.         for i,v in pairs(modem) do -- Broadcast the inital multicast packet to all routers we're connected to. Surely one of them will know what to do with it..
  419.             v.transmit(crf_freq, crf_freq, textutils.serialize( { crf_identStr, os.computerID(), "data", sender, packetTo, packetData, nil, cand, { [os.computerID()] = true } } ))
  420.         end
  421.         local groupID = math.abs(packetTo)
  422.         if lan_multicast[groupID] then
  423.             for i,v in pairs(lan_multicast[groupID]) do
  424.                 if i ~= sender then
  425.                     if data[3] == "encrypted_data" then
  426.                         raw_encrypted_send(lan_clients[i], i, sender, packetData)
  427.                     else
  428.                         modem[lan_clients[i]].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "data", i, sender, packetData} ))
  429.                     end
  430.                 end
  431.             end
  432.         end
  433.         modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "data_ack", sender } ))
  434.     elseif routingTable[packetTo] then -- Not a LAN client
  435.         if wan_enc_routers[packetTo] == wan_key_ident then
  436.             print("CRF/LAN: Endpoint is using the same key as us, sending encrypted...")
  437.             encrypted_wan_send(packetData, sender, packetTo)
  438.             modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "data_ack", sender} ))
  439.         else
  440.             print("CRF/LAN: Endpoint is not using the same key as us, sending unencrypted...")
  441.             modem[routingTable[packetTo][1]].transmit(crf_freq, crf_freq, textutils.serialize( { crf_identStr, os.computerID(), "data", sender, packetTo, packetData, routingTable[packetTo][2] } ))
  442.             modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "data_ack", sender} ))
  443.         end
  444.         if (type(debug) == "number") and ((bit.band(debug, debugFlags["LANEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  445.             print("LAN: Packet addressed to non-local host "..packetTo.." from "..sender.." received.")
  446.         end
  447.     elseif lan_clients[packetTo] then -- LAN client
  448.         if data[3] == "encrypted_data" then
  449.             raw_encrypted_send(lan_clients[packetTo], packetTo, sender, packetData)
  450.         else
  451.             modem[lan_clients[packetTo]].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "data", packetTo, sender, packetData } ))
  452.         end
  453.         modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "data_ack", sender} ))
  454.         if (type(debug) == "number") and ((bit.band(debug, debugFlags["LANEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  455.             print("LAN: Packet addressed to LAN client "..packetTo.." from "..sender.." received.")
  456.         end
  457.     else
  458.         if (type(debug) == "number") and ((bit.band(debug, debugFlags["LANEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  459.             print("LAN: Packet to unknown recipient "..packetTo.." from "..sender.." received.")
  460.         end
  461.         modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "data_fail", sender} ))
  462.     end
  463. end
  464.  
  465. local function crf_listenerLoop(debug)
  466.     local pingTime = math.random(1, 10)
  467.     local lsaCheckTime = pingTime+1
  468.     local lsaForceTime = lsaCheckTime+math.random(1,10)
  469.     local pingTimer = os.startTimer(pingTime)
  470.     local lsaCheckTimer = os.startTimer(lsaCheckTime)
  471.     --local lsaForceTimer = os.startTimer(lsaForceTime)
  472.     local LANBeaconTimer = os.startTimer(15)
  473.     local lastHostlist = {}
  474.     if (type(debug) == "number") and ((bit.band(debug, debugFlags["timing"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  475.         print("Timers:")
  476.         print("Ping: t+"..pingTime.." seconds")
  477.         print("LSACheck: t+"..lsaCheckTime.." seconds")
  478.         print("LSAForce: t+"..lsaForceTime.." seconds")
  479.     end
  480.     if (type(debug) == "number") and ((bit.band(debug, debugFlags["LANEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  481.         print("LAN: Key size is "..#lan_key)
  482.         print("LAN: Network name is "..lan_name)
  483.     end
  484.     crf_running = true
  485.     lan_running = true
  486.     while true do
  487.         local event, side, tFreq, rFreq, data = os.pullEvent()
  488.         if event == "modem_message" then
  489.             local mType = 0
  490.             if wiredModems[side] then
  491.                 mType = 1
  492.             elseif wirelessModem["side"] == side then
  493.                 mType = 2
  494.             end
  495.             if ((tFreq == crf_freq) or (tFreq == lan_freq)) and mType > 0 then
  496.                 if type(textutils.unserialize(data)) == "table" then
  497.                     data = textutils.unserialize(data)
  498.                     if data[1] == crf_identStr then
  499.                         if data[3] == "ping" then
  500.                             if (type(debug) == "number") and ((bit.band(debug, debugFlags["pingEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  501.                                 print("Recieved ping from "..data[2].." on "..side.." interface.")
  502.                             end
  503.                             if not localHosts[data[2]] then
  504.                                 localHosts[data[2]] = side
  505.                             end
  506.                             if (data[5] and (data[5] ~= "")) then
  507.                                 wan_enc_routers_local[data[2]] = data[5]
  508.                             end
  509.                             if mType == 1 then
  510.                                 wiredModems[side].transmit(crf_freq, crf_freq, crf_pongStr)
  511.                             elseif mType == 2 then
  512.                                 wirelessModem.transmit(crf_freq, crf_freq, crf_pongStr)
  513.                             end
  514.                             multicast_downstream[data[2]] = data[4]
  515.                         elseif data[3] == "pong" then
  516.                             if (type(debug) == "number") and ((bit.band(debug, debugFlags["pingEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  517.                                 print("Recieved pong from "..data[2].." on "..side.." interface.")
  518.                             end
  519.                             if not localHosts[data[2]] then
  520.                                 localHosts[data[2]] = side
  521.                             end
  522.                         elseif data[3] == "lsa" then
  523.                             local lsa = data[4]
  524.                             local origin = lsa[1]
  525.                             local id = lsa[2]
  526.                             local recv = lsa[3]
  527.                             local list = lsa[4]
  528.                             if (type(debug) == "number") and ((bit.band(debug, debugFlags["lsaEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  529.                                 print("Recieved LSA from "..data[2].." on "..side.." interface.")
  530.                                 if lastLSAs[origin] and lastLSAs[origin][1] then
  531.                                     print("Originator: "..origin.." ID: "..id.." (last: "..lastLSAs[origin][1]..")")
  532.                                 else
  533.                                     print("Originator: "..origin.." ID: "..id.." (last: none)")
  534.                                 end
  535.                             end
  536.                             if not lastLSAs[origin] then
  537.                                 lastLSAs[origin] = {}
  538.                             end
  539.                             if not allHosts[origin] then
  540.                                 allHosts[origin] = side
  541.                             end
  542.                             if id ~= lastLSAs[origin][1] and not recv[os.computerID()] then
  543.                                 if (type(debug) == "number") and ((bit.band(debug, debugFlags["lsaEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  544.                                     print("Valid LSA received. Connected hosts: "..#list..".")
  545.                                 end
  546.                                 lsa[3][os.computerID()] = true
  547.                                 lastLSAs[origin][1] = id
  548.                                 lastLSAs[origin][2] = list
  549.                                 -- Transmit new LSA on all networks:
  550.                                 if wirelessModem.transmit then
  551.                                     wirelessModem.transmit(crf_freq, crf_freq, textutils.serialize( { crf_identStr, os.computerID(), "lsa", lsa } ))
  552.                                 end
  553.                                 for i=1, #wiredModems do
  554.                                     wiredModems[i].transmit(crf_freq, crf_freq, textutils.serialize( { crf_identStr, os.computerID(), "lsa", lsa } ))
  555.                                 end
  556.                                 -- Fill in the blanks (for LAN-only hosts):
  557.                                 for id, interfaceSide in pairs(list) do
  558.                                     if not lastLSAs[id] then
  559.                                         lastLSAs[id] = {-1, { data[2] } }
  560.                                     end
  561.                                 end
  562.                                 -- Add routers using encryption to our list:
  563.                                 local enc_routers = lsa[5]
  564.                                 if enc_routers then
  565.                                     for i,v in pairs(enc_routers) do
  566.                                         if (type(debug) == "number") and ((bit.band(debug, debugFlags["lsaEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  567.                                             print("Host "..i.."("..type(i)..") is using key ident "..v)
  568.                                         end
  569.                                         wan_enc_routers[i] = v
  570.                                     end
  571.                                 elseif (type(debug) == "number") and ((bit.band(debug, debugFlags["lsaEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  572.                                     print("Host "..origin.." did not send router key ident list, skipping....")
  573.                                 end
  574.                                 generateRoutingTable(debug)
  575.                             end
  576.                         elseif data[3] == "data" then
  577.                             local from = data[4]
  578.                             local to = data[5]
  579.                             local msg = data[6]
  580.                             local next = data[7]
  581.                             if to == os.computerID() then
  582.                                 if (type(debug) == "number") and ((bit.band(debug, debugFlags["dataEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  583.                                     print("Got data from "..from.." via "..next.." on interface "..side..".")
  584.                                     print("Message: "..msg)
  585.                                 end
  586.                                 os.queueEvent("routed_message", from, msg)
  587.                             elseif to < -1 then
  588.                                 local groupID = math.abs(to)
  589.                                 local packetID = data[8]
  590.                                 local recvList = data[9]
  591.                                 if (multicast_ids[groupID] ~= packetID) and (not recvList[os.computerID()]) then
  592.                                     multicast_ids[groupID] = packetID
  593.                                     recvList[os.computerID()] = true
  594.                                     for i,v in pairs(multicast_downstream) do
  595.                                         if v[groupID] then
  596.                                             modem[localHosts[i]].transmit(crf_freq, crf_freq, textutils.serialize( { crf_identStr, os.computerID(), "data", data[4], data[5], data[6], i, packetID, recvList } ))
  597.                                         end
  598.                                     end
  599.                                     if lan_multicast[groupID] then
  600.                                         for i,v in pairs(lan_multicast[groupID]) do
  601.                                             modem[lan_clients[i]].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "data", i, from, msg} ))
  602.                                         end
  603.                                     end
  604.                                 end
  605.                             elseif next == os.computerID() then
  606.                                 if lan_clients[to] then
  607.                                     if (type(debug) == "number") and ((bit.band(debug, debugFlags["dataEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  608.                                         print("Relaying data from "..from.." to LAN client "..to.." via interface "..lan_clients[to]..".")
  609.                                     end
  610.                                     if (#lan_key ~= 0) then
  611.                                         raw_encrypted_send(lan_clients[to], to, from, msg)
  612.                                     else
  613.                                         peripheral.wrap( lan_clients[to] ).transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "data", to, from, msg} ))
  614.                                     end
  615.                                 elseif routingTable[to] then
  616.                                     if (type(debug) == "number") and ((bit.band(debug, debugFlags["dataEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  617.                                         print("Relaying data from "..from.." via "..next.." on interface "..side..".")
  618.                                         print("Sending to "..routingTable[to][2].." on interface "..routingTable[to][1]..".")
  619.                                     end
  620.                                     peripheral.wrap( routingTable[to][1] ).transmit(crf_freq, crf_freq, textutils.serialize( { crf_identStr, os.computerID(), "data", data[4], data[5], data[6], routingTable[to][2] } ))
  621.                                 elseif (type(debug) == "number") and ((bit.band(debug, debugFlags["dataEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  622.                                     print("Unknown-destination packet from "..from.." via "..next.." on interface "..side..".")
  623.                                     print("Destination: "..to)
  624.                                 end
  625.                             end
  626.                         elseif data[3] == "encrypted_packet"then
  627.                             -- structure: {crf_ident, local sender, "encrypted_packet", encrypted data, iv, src, rec, next_hop, hmac, recv_list }
  628.                             -- hmac is hmac( textutils.serialize( {decrypted_data, encrypted_data, iv, src, rec} ) )
  629.                             local enc_data = data[4]
  630.                             local iv       = data[5]
  631.                             local from     = data[6]
  632.                             local to       = data[7]
  633.                             local next     = data[8]
  634.                             local hmac     = data[9]
  635.                             local valid = true
  636.                             local dec_data_str = ""
  637.                            
  638.                             if (#wan_key ~= 0) then
  639.                            
  640.                                 -- Message decryption / validation:
  641.                                 local dec_data = AES.decrypt_bytestream(enc_data, wan_key, iv)
  642.                                 local hmac_data_str = "" --textutils.serialize({enc_data, iv, from, to})
  643.                                 for i=1, #dec_data do
  644.                                     dec_data_str = dec_data_str..string.char(dec_data[i])
  645.                                 end
  646.                                
  647.                                 for i=1, #enc_data do
  648.                                     hmac_data_str = hmac_data_str..string.char(enc_data[i])
  649.                                 end
  650.                                
  651.                                 if wan_verify_inbound then
  652.                                     if (hmac ~= nil) then
  653.                                         for i=1, #iv do
  654.                                             hmac_data_str = hmac_data_str..string.format("%X", iv[i])
  655.                                         end
  656.                                         hmac_data_str = hmac_data_str..from
  657.                                         hmac_data_str = hmac_data_str..to
  658.                                         local hmac_data = {}
  659.                                         local lastPause = os.clock()
  660.                                         for i=1, #hmac_data_str do
  661.                                             hmac_data[i] = string.byte(hmac_data_str, i, i)
  662.                                             if os.clock() - lastPause >= 2.80 then
  663.                                                 os.queueEvent("")
  664.                                                 os.pullEvent("")
  665.                                                 lastPause = os.clock()
  666.                                             end
  667.                                         end
  668.                                         local calc_hmac = SHA2.hashToBytes(SHA2.hmac(hmac_data, wan_key))
  669.                                         for i=1, math.max(#hmac, #calc_hmac) do
  670.                                             if calc_hmac[i] ~= hmac[i] then
  671.                                                 valid = false
  672.                                                 break
  673.                                             end
  674.                                         end
  675.                                         if valid then
  676.                                             if (type(debug) == "number") and ((bit.band(debug, debugFlags["dataEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  677.                                                 local h2_str = ""
  678.                                                 for i=1, #calc_hmac do
  679.                                                     h2_str = h2_str..string.format("%X", calc_hmac[i])
  680.                                                 end
  681.                                                 print("Message validation from "..from.." succeeded: got hash "..h2_str)
  682.                                             end
  683.                                         else
  684.                                             if (type(debug) == "number") and ((bit.band(debug, debugFlags["dataEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  685.                                                 local h1_str = ""
  686.                                                 local h2_str = ""
  687.                                                 for i=1, #hmac do
  688.                                                     h1_str = h1_str..string.format("%X", hmac[i])
  689.                                                 end
  690.                                                 for i=1, #calc_hmac do
  691.                                                     h2_str = h2_str..string.format("%X", calc_hmac[i])
  692.                                                 end
  693.                                                 for i=1, #dec_data do
  694.                                                     dec_data_str = dec_data_str..string.char(dec_data[i])
  695.                                                 end
  696.                                                 local iv_str = ""
  697.                                                 for i=1, #iv do
  698.                                                     iv_str = iv_str..string.format("%X", iv[i])
  699.                                                 end
  700.                                                 print("Message validation from "..from.." failed: got hash "..h1_str..", expected "..h2_str)
  701.                                                 print("Message data would be "..dec_data_str)
  702.                                                 print("Init vector would be "..iv_str)
  703.                                                 print("HMAC validation string is "..hmac_data_str)
  704.                                             end
  705.                                         end
  706.                                     else
  707.                                         valid = false
  708.                                         if (type(debug) == "number") and ((bit.band(debug, debugFlags["dataEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  709.                                             print("Message validation from "..from.." failed: no HMAC sent!")
  710.                                         end
  711.                                     end
  712.                                 end
  713.                                
  714.                             else
  715.                                 valid = false
  716.                             end
  717.                            
  718.                             if to == os.computerID() then
  719.                                 if valid then
  720.                                     if (type(debug) == "number") and ((bit.band(debug, debugFlags["dataEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  721.                                         print("Got data from "..from.." via "..next.." on interface "..side..".")
  722.                                         print("Message: "..dec_data_str)
  723.                                     end
  724.                                     os.queueEvent("routed_message", from, dec_data_str)
  725.                                 end
  726.                             elseif to < -1 then
  727.                                 local groupID = math.abs(to)
  728.                                 local packetID = bit.bor( iv[1], bit.bor( bit.blshift(iv[2], 8), bit.bor( bit.blshift(iv[3], 16), bit.blshift(iv[4], 24) ) ) )
  729.                                 local recvList = data[10]
  730.                                 if (multicast_ids[groupID] ~= packetID) and (not recvList[os.computerID()]) then
  731.                                     multicast_ids[groupID] = packetID
  732.                                     recvList[os.computerID()] = true
  733.                                     for i,v in pairs(multicast_downstream) do
  734.                                         if v[groupID] then
  735.                                             modem[localHosts[i]].transmit(crf_freq, crf_freq, textutils.serialize( { crf_identStr, os.computerID(), "encrypted_packet", data[4], data[5], data[6], data[7], data[8], data[9], data[10], recvList } ))
  736.                                         end
  737.                                     end
  738.                                     if valid then
  739.                                         if lan_multicast[groupID] then
  740.                                             for i,v in pairs(lan_multicast[groupID]) do
  741.                                                 if #lan_key ~= 0 then
  742.                                                     raw_encrypted_send(lan_clients[i], to, from, dec_data_str)
  743.                                                 else
  744.                                                     modem[lan_clients[i]].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "data", i, from, dec_data_str} ))
  745.                                                 end
  746.                                             end
  747.                                         end
  748.                                     end
  749.                                 end
  750.                             elseif next == os.computerID() then
  751.                                 if lan_clients[to] then
  752.                                     if valid then
  753.                                         if (#lan_key ~= 0) then
  754.                                             raw_encrypted_send(lan_clients[to], to, from, dec_data_str)
  755.                                             --raw_encrypted_send(lan_clients[i], i, sender, packetData)
  756.                                         else
  757.                                             peripheral.wrap( lan_clients[to] ).transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "data", to, from, dec_data_str} ))
  758.                                         end
  759.                                     end
  760.                                 elseif routingTable[to] then
  761.                                     if (type(debug) == "number") and ((bit.band(debug, debugFlags["dataEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  762.                                         print("Relaying data from "..from.." via "..next.." on interface "..side..".")
  763.                                         print("Sending to "..routingTable[to][2].." on interface "..routingTable[to][1]..".")
  764.                                     end
  765.                                     -- structure: {crf_ident, local sender, "encrypted_packet", encrypted data, iv, src, rec, next_hop, key_ident, hmac, recv_list }
  766.                                     peripheral.wrap( routingTable[to][1] ).transmit(crf_freq, crf_freq, textutils.serialize( { crf_identStr, os.computerID(), "encrypted_packet", data[4], data[5], data[6], data[7], routingTable[to][2], data[9], data[10]} ))
  767.                                 elseif (type(debug) == "number") and ((bit.band(debug, debugFlags["dataEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  768.                                     print("Unknown-destination packet from "..from.." via "..next.." on interface "..side..".")
  769.                                     print("Destination: "..to)
  770.                                 end
  771.                             end
  772.                         end
  773.                     elseif (data[1] == lan_identStr) and (data[4] == os.computerID()) then
  774.                         local sender = data[2]
  775.                         if (type(debug) == "number") and ((bit.band(debug, debugFlags["LANEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  776.                             print("LAN: Received LAN message from "..data[2]..".")
  777.                             print("LAN: Data type: "..data[3])
  778.                         end
  779.                         if data[3] == "assoc" then
  780.                             --print("Received message type: "..data[3])
  781.                             if ((#lan_key == 0) or ((lan_auth[sender]) and (lan_auth[sender][3]))) then
  782.                                 if ((lan_clients[sender] == nil) or (lan_clients[sender] == side)) then
  783.                                     lan_clients[sender] = side
  784.                                     modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "assoc_ack", sender} ))
  785.                                     if (type(debug) == "number") and ((bit.band(debug, debugFlags["LANEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  786.                                         print("LAN: "..sender.." has joined the LAN.")
  787.                                     end
  788.                                 else
  789.                                     modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "assoc_fail", sender} ))
  790.                                     if (type(debug) == "number") and ((bit.band(debug, debugFlags["LANEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  791.                                         print("LAN: "..sender.." failed to join the LAN.")
  792.                                     end
  793.                                 end
  794.                             end
  795.                         elseif data[3] == "disassoc" then
  796.                             --print("Received message type: "..data[3])
  797.                             local deauthed = false
  798.                             if lan_auth[sender] then
  799.                                 lan_auth[sender] = nil
  800.                                 deauthed = true
  801.                             end
  802.                             if lan_clients[sender] == side then
  803.                                 lan_clients[sender] = nil
  804.                                 modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "disassoc_ack", sender} ))
  805.                                 if (type(debug) == "number") and ((bit.band(debug, debugFlags["LANEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  806.                                     print("LAN: "..sender.." has left the LAN.")
  807.                                 end
  808.                             elseif deauthed then
  809.                                 modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "disassoc_ack", sender} ))
  810.                                 if (type(debug) == "number") and ((bit.band(debug, debugFlags["LANEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  811.                                     print("LAN: "..sender.." canceled an authentication request.")
  812.                                 end
  813.                             else
  814.                                 modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "disassoc_fail", sender} ))
  815.                                 if (type(debug) == "number") and ((bit.band(debug, debugFlags["LANEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  816.                                     print("LAN: "..sender.." failed to leave the LAN.")
  817.                                 end
  818.                             end
  819.                         elseif data[3] == "auth_req" then
  820.                             --print("Received message type: "..data[3])
  821.                             if (#lan_key ~= 0) then
  822.                                 local challenge = {}
  823.                                 for i=1, 16 do
  824.                                     challenge[i] = math.random(0, 255)
  825.                                 end
  826.                                 local enc_challenge = AES.encrypt_block(challenge, lan_key)
  827.                                 lan_auth[sender] = {challenge, enc_challenge, false}
  828.                                 modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "auth_challenge", sender, challenge} ))
  829.                             else
  830.                                 modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "auth_fail", sender, 1} ))
  831.                                 lan_auth[sender] = nil
  832.                             end
  833.                         elseif data[3] == "auth_response" then
  834.                             --print("Got authentication response from "..sender)
  835.                             if (#lan_key ~= 0) then
  836.                                 local response = data[5]
  837.                                 if lan_auth[sender] and (not lan_auth[sender][3]) then
  838.                                     local auth_ok = true
  839.                                     for i=1, #lan_auth[sender][2] do
  840.                                         if lan_auth[sender][2][i] ~= response[i] then
  841.                                             auth_ok = false
  842.                                             break
  843.                                         end
  844.                                     end
  845.                                     if auth_ok then
  846.                                         modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "auth_good", sender} ))
  847.                                         lan_auth[sender][3] = true
  848.                                     else
  849.                                         modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "auth_fail", sender, 3} ))
  850.                                         lan_auth[sender] = nil
  851.                                     end
  852.                                 else
  853.                                     modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "auth_fail", sender, 2} ))
  854.                                     lan_auth[sender] = nil
  855.                                 end
  856.                             else
  857.                                 modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "auth_fail", sender, 1} ))
  858.                                 lan_auth[sender] = nil
  859.                             end
  860.                         elseif data[3] == "join_group" then
  861.                             local group = data[5]
  862.                             if (group <= 1) or ((lan_multicast[group] ~= nil) and (lan_multicast[group][data[2]] ~= nil)) then
  863.                                 modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "group_fail", sender} ))
  864.                             else
  865.                                 if not lan_multicast[group] then
  866.                                     lan_multicast[group] = {}
  867.                                 end
  868.                                 lan_multicast[group][data[2]] = true
  869.                                 modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "group_ack", sender} ))
  870.                             end
  871.                         elseif data[3] == "leave_group" then
  872.                             local group = data[5]
  873.                             if (group <= 1) or ((lan_multicast[group] == nil) or (lan_multicast[group][data[2]] == nil)) then
  874.                                 modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "group_fail", sender} ))
  875.                             else
  876.                                 lan_multicast[group][data[2]] = nil
  877.                                 modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "group_ack", sender} ))
  878.                                 local count = 0
  879.                                 for i,v in pairs(lan_multicast[group]) do
  880.                                     count = count+1
  881.                                 end
  882.                                 if count == 0 then
  883.                                     lan_multicast[group] = nil
  884.                                 end
  885.                             end
  886.                         elseif data[3] == "data" then
  887.                             handle_datagram(side, data, data[5], data[6])
  888.                         elseif data[3] == "encrypted_data" then -- encrypted data packet
  889.                             local iv = data[5]
  890.                             local enc_data = data[6]
  891.                             if (#lan_key ~= 0) then
  892.                                 local dec_data = AES.decrypt_bytestream(enc_data, lan_key, iv)
  893.                                 local dec_str = ""
  894.                                 for i=1, #dec_data do
  895.                                     dec_str = dec_str..string.char(dec_data[i])
  896.                                 end
  897.                                 dec_packet = textutils.unserialize(dec_str)
  898.                                 if type(dec_packet) == "table" then
  899.                                     --print(side)
  900.                                     handle_datagram(side, {data[1], data[2], "encrypted_data", data[4]}, dec_packet[1], dec_packet[2])
  901.                                 end
  902.                             end
  903.                         elseif data[3] == "auth_required" then
  904.                             if (#lan_key == 0) then
  905.                                 modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "auth_not_required", sender} ))
  906.                             else
  907.                                 modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "auth_required", sender} ))
  908.                             end
  909.                         elseif data[3] == "id_list" then
  910.                             local list = {}
  911.                             for i,v in pairs(allHosts) do
  912.                                 table.insert(list, i)
  913.                             end
  914.                             modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "id_list", sender, list} ))
  915.                             if (type(debug) == "number") and ((bit.band(debug, debugFlags["LANEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  916.                                 print("LAN: WAN ID list has been requested by "..sender..".")
  917.                             end
  918.                         elseif data[3] == "lan_list" then
  919.                             local list = {}
  920.                             for i,v in pairs(lan_clients) do
  921.                                 table.insert(list, i)
  922.                             end
  923.                             modem[side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "lan_list", sender, list} ))
  924.                             if (type(debug) == "number") and ((bit.band(debug, debugFlags["LANEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  925.                                 print("LAN: LAN ID list has been requested by "..sender..".")
  926.                             end
  927.                         end
  928.                     end
  929.                 end
  930.             end
  931.         elseif event == "timer" then
  932.             if side == pingTimer then
  933.                 for i,v in pairs(localHosts) do
  934.                     lastHostlist[i] = v
  935.                 end
  936.                
  937.                 if (type(debug) == "number") and ((bit.band(debug, debugFlags["timing"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  938.                     print("Running reachability protocol...")
  939.                 end
  940.                
  941.                 local pingStr = textutils.serialize( {crf_identStr, os.computerID(), "ping", lan_multicast, wan_key_ident} )
  942.                
  943.                 localHosts = {}
  944.                 if wirelessModem.transmit then
  945.                     wirelessModem.transmit(crf_freq, crf_freq, pingStr)
  946.                 end
  947.                 for i=1, #wiredModems do
  948.                     wiredModems[i].transmit(crf_freq, crf_freq, pingStr)
  949.                 end
  950.                 for i,v in pairs(lan_clients) do
  951.                     localHosts[i] = v
  952.                 end
  953.             elseif side == lsaCheckTimer then
  954.                 if (type(debug) == "number") and ((bit.band(debug, debugFlags["timing"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  955.                     print("Checking local hostlist...")
  956.                 end
  957.                 local tLSA = false
  958.                 for i,v in pairs(lastHostlist) do
  959.                     if not localHosts[i] then -- A host got dropped
  960.                         tLSA = true
  961.                     end
  962.                 end
  963.                 for i,v in pairs(localHosts) do
  964.                     if not lastHostlist[i] then -- A host got added
  965.                         tLSA = true
  966.                     end
  967.                 end
  968.                 if tLSA then
  969.                     if (type(debug) == "number") and ((bit.band(debug, debugFlags["timing"]) > 0) or (bit.band(debug, debugFlags["lsaEvents"]) > 0 or bit.band(debug, debugFlags["events"]) > 0)) then
  970.                         print("Transmitting LSA...")
  971.                     end
  972.                     transmitLSA(debug)
  973.                 elseif (type(debug) == "number") and ((bit.band(debug, debugFlags["timing"]) > 0) or (bit.band(debug, debugFlags["lsaEvents"]) > 0 or bit.band(debug, debugFlags["events"]) > 0)) then
  974.                     print("Not transmitting LSA...")
  975.                 end
  976.                 pingTime = math.random(1, 20)
  977.                 lsaCheckTime = pingTime+1
  978.                 pingTimer = os.startTimer(pingTime)
  979.                 lsaCheckTimer = os.startTimer(lsaCheckTime)
  980.                 if (type(debug) == "number") and ((bit.band(debug, debugFlags["timing"]) > 0) or (bit.band(debug, debugFlags["lsaEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  981.                     print("Forcing LSA transmit...")
  982.                     print("New timers:")
  983.                     print("Ping: t+"..pingTime.." seconds")
  984.                     print("LSACheck: t+"..lsaCheckTime.." seconds")
  985.                 end
  986.             elseif side == lsaForceTimer then
  987.                 pingTime = math.random(1, 10)
  988.                 lsaCheckTime = pingTime+1
  989.                 --lsaForceTime = lsaCheckTime+math.random(1,10)
  990.                 pingTimer = os.startTimer(pingTime)
  991.                 lsaCheckTimer = os.startTimer(lsaCheckTime)
  992.                 --lsaForceTimer = os.startTimer(lsaForceTime)
  993.                 if (type(debug) == "number") and ((bit.band(debug, debugFlags["timing"]) > 0) or (bit.band(debug, debugFlags["lsaEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  994.                     print("Forcing LSA transmit...")
  995.                     print("New timers:")
  996.                     print("Ping: t+"..pingTime.." seconds")
  997.                     print("LSACheck: t+"..lsaCheckTime.." seconds")
  998.                     --print("LSAForce: t+"..lsaForceTime.." seconds")
  999.                 end
  1000.                 transmitLSA(debug)
  1001.             elseif side == LANBeaconTimer then
  1002.                 for i,v in pairs(modem) do
  1003.                     v.transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "beacon", -1, lan_name, (#lan_key ~= 0)} ))
  1004.                 end
  1005.                 LANBeaconTimer = os.startTimer(15)
  1006.                 if (type(debug) == "number") and ((bit.band(debug, debugFlags["LANEvents"]) > 0) or (bit.band(debug, debugFlags["events"]) > 0)) then
  1007.                     print("LAN: Sending beacon message...")
  1008.                 end
  1009.             end
  1010.         end
  1011.     end
  1012. end
  1013.  
  1014. LAN.get_clients = function()
  1015.     local clients = {}
  1016.     for i,v in pairs(lan_clients) do
  1017.         table.insert(clients, i)
  1018.     end
  1019.     return clients
  1020. end
  1021.  
  1022. LAN.send = function(id, data)
  1023.     modem[lan_clients[id]].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "data", id, os.computerID(), data } ))
  1024. end
  1025.  
  1026. LAN.broadcast = function(data)
  1027.     for client_id, client_side in pairs(lan_clients) do
  1028.         modem[client_side].transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "data", client_id, os.computerID(), data } ))
  1029.     end
  1030. end
  1031.  
  1032. CRF.run = function(debug)
  1033.     if debug == true then
  1034.         debug = 0xFF
  1035.     end
  1036.     if debug == nil then
  1037.         debug = 0
  1038.     end
  1039.     if ((type(debug) == "number") and (debug ~= 0)) then
  1040.         term.setCursorPos(1,1)
  1041.         term.clear()
  1042.     end
  1043.     return function() crf_listenerLoop(debug) end
  1044. end
  1045.  
  1046. CRF.compileDebugFlags = function(ev, tm, rg, sr, de, pe, le, lan)
  1047.     local flags = 0
  1048.     if ev then
  1049.         flags = bit.bor( flags, debugFlags["events"] )
  1050.     end
  1051.     if tm then
  1052.         flags = bit.bor( flags, debugFlags["timing"] )
  1053.     end
  1054.     if rg then
  1055.         flags = bit.bor( flags, debugFlags["routeGen"] )
  1056.     end
  1057.     if sr then
  1058.         flags = bit.bor( flags, debugFlags["bfs"] )
  1059.     end
  1060.     if de then
  1061.         flags = bit.bor( flags, debugFlags["dataEvents"] )
  1062.     end
  1063.     if pe then
  1064.         flags = bit.bor( flags, debugFlags["pingEvents"] )
  1065.     end
  1066.     if le then
  1067.         flags = bit.bor( flags, debugFlags["lsaEvents"] )
  1068.     end
  1069.     if lan then
  1070.         flags = bit.bor( flags, debugFlags["LANEvents"] )
  1071.     end
  1072.     return flags
  1073. end
  1074.  
  1075. CRF.getRoutingTable = function()
  1076.     local copy = {}
  1077.     for i,v in pairs(routingTable) do
  1078.         copy[i] = v
  1079.     end
  1080.     return copy
  1081. end
  1082.  
  1083. CRF.getRoute = function(to)
  1084.     return bfs( CRF.getRoutingTable(), os.computerID(), to )
  1085. end
  1086.  
  1087. CRF.send = function(to, msg)
  1088.     if lan_clients[to] then
  1089.         return LAN.send(to, msg)
  1090.     end
  1091.     if not routingTable[to][1] then
  1092.         error("Could not find route for "..to)
  1093.         return false
  1094.     end
  1095.     local m = peripheral.wrap( routingTable[to][1] )
  1096.     return m.transmit(crf_freq, crf_freq, textutils.serialize( { crf_identStr, os.computerID(), "data", os.computerID(), to, msg, routingTable[to][2] } ))
  1097. end
  1098.  
  1099. CRF.getStatus = function()
  1100.     return crf_running
  1101. end
  1102.  
  1103. CRF.setWANKey = function(key)
  1104.     assert((type(key) == "string"), "setWANKey: key must be type string.")
  1105.     assert(securityEnabled, "setWANKey: Security functions were disabled!")
  1106.     local _, k = SHA2.digestStr(key)
  1107.     wan_key = SHA2.hashToBytes(k)
  1108.     k = SHA2.digest(wan_key)
  1109.     local wan_key_hash = SHA2.hashToBytes(k)
  1110.     wan_key_ident = ""
  1111.     for i=1, #wan_key_hash do
  1112.         wan_key_ident = wan_key_ident..string.format("%X", wan_key_hash[i])
  1113.     end
  1114.     for i,v in pairs(modem) do
  1115.         v.transmit(crf_freq, crf_freq, textutils.serialize( { crf_identStr, os.computerID(), "rekey", wan_key_ident, -1} ))
  1116.     end
  1117. end
  1118.  
  1119. CRF.setHMACVerifyStatus = function(inbound, outbound)
  1120.     wan_verify_inbound = inbound
  1121.     wan_verify_outbound = outbound
  1122. end
  1123.  
  1124. LAN.getStatus = function()
  1125.     return lan_running
  1126. end
  1127.  
  1128. LAN.isSecure = function()
  1129.     return (#lan_key ~= 0)
  1130. end
  1131.  
  1132. LAN.setNetworkName = function(name)
  1133.     lan_name = name
  1134. end
  1135.  
  1136. LAN.setNetworkKey = function(key)
  1137.     assert((type(key) == "string"), "setNetworkKey: key must be type string.")
  1138.     assert(securityEnabled, "setNetworkKey: Security functions were disabled!")
  1139.     local _, k = SHA2.digestStr(key)
  1140.     lan_key = SHA2.hashToBytes(k)
  1141.     for i,v in pairs(modem) do
  1142.         v.transmit(lan_freq, lan_freq, textutils.serialize( { lan_identStr, os.computerID(), "rekey", -1} ))
  1143.     end
  1144. end
  1145.  
  1146. LAN.getNetworkName = function()
  1147.     return lan_name
  1148. end
  1149.  
  1150. -- Detect if we're being run as a program:
  1151. if shell then
  1152.     local file = fs.open(shell.getRunningProgram(), "r")
  1153.     if file then
  1154.         local l = file.readLine()
  1155.         file.close()
  1156.         if string.match(l, "Common Routing Framework") then
  1157.             local do_debug = false
  1158.             if #args > 0 then
  1159.                 if (args[1] and (args[1] ~= "")) then
  1160.                     LAN.setNetworkName(args[1])
  1161.                 end
  1162.                 if args[2] then
  1163.                     LAN.setNetworkKey(args[2])
  1164.                 end
  1165.             else
  1166.                 term.clear()
  1167.                 term.setCursorPos(1,1)
  1168.                 -- (16, 2): Title ("CRFv3.1 LAN Setup")
  1169.                 -- (5, 5): Thank You message ("Thank you for using CRFv3.1.")
  1170.                 -- (5, 7): Question ("Would you like to set up a LAN?", len:37)
  1171.                 --  (43, 7): Yes/No: ("[Yes]/No" or "Yes/[No]")
  1172.                 --  (50/51, 7): "No" select, state 1
  1173.                 --  (43-45, 7): "Yes" select, state 2
  1174.                 -- (2, 9): Textbox ("Name >")
  1175.                 -- (2, 10): Textbox ("Network Key >")
  1176.                 -- (2, 11): Textbox ("WAN Key >")
  1177.                 -- (2, 12): Message ("All fields can be blank.")
  1178.                 -- (2, 13): Button ("[Debug Disabled]" / "[Debug Enabled]")
  1179.                 -- (20, 16): Button ("[Continue]")
  1180.                
  1181.                 local selected_box = 0
  1182.  
  1183.                 local name_box = ""
  1184.                 local key_box = ""
  1185.                 local wan_key_box = ""
  1186.  
  1187.                 -- Inital draw:
  1188.                 term.setCursorPos(16, 2)
  1189.                 term.setTextColor(colors.lime)
  1190.                 term.write("CRFv3.1 LAN Setup")
  1191.                 term.setTextColor(colors.white)
  1192.                 term.setCursorPos(5, 5)
  1193.                 term.write("Thank you for using CRFv3.1.")
  1194.                 term.setCursorPos(5, 7)
  1195.                 term.write("Please set up your router:")
  1196.                 term.setCursorPos(2, 9)
  1197.                 term.write("Name >")
  1198.                 term.setCursorPos(2, 10)
  1199.                 term.write("Network Key >")
  1200.                 term.setCursorPos(2, 11)
  1201.                 term.write("WAN Key >")
  1202.                 term.setCursorPos(2, 12)
  1203.                 term.write("All fields can be blank.")
  1204.                 term.setCursorPos(2, 13)
  1205.                 term.setTextColor(colors.red)
  1206.                 term.write("[Debug Disabled]")
  1207.                 term.setTextColor(colors.white)
  1208.                 term.setCursorPos(20, 16)
  1209.                 term.write("[Continue]")
  1210.  
  1211.                 while true do
  1212.                     local event, a1, a2, a3 = os.pullEvent()
  1213.                     if (event == "char") then
  1214.                         if selected_box == 1 then
  1215.                             name_box = name_box..a1
  1216.                         elseif selected_box == 2 then
  1217.                             key_box = key_box..a1
  1218.                         elseif selected_box == 3 then
  1219.                             wan_key_box = wan_key_box..a1
  1220.                         end
  1221.                     elseif (event == "key") and (a1 == keys.backspace) then
  1222.                         if selected_box == 1 then
  1223.                             name_box = string.sub(name_box, 1, #name_box-1)
  1224.                         elseif selected_box == 2 then
  1225.                             key_box = string.sub(key_box, 1, #key_box-1)
  1226.                         elseif selected_box == 3 then
  1227.                             wan_key_box = string.sub(wan_key_box, 1, #wan_key_box-1)
  1228.                         end
  1229.                     elseif event == "mouse_click" then
  1230.                         if a1 == 1 then
  1231.                             if (a3 == 9) and (a2 >= 2) then
  1232.                                 selected_box = 1
  1233.                             elseif (a3 == 10) and (a2 >= 2) then
  1234.                                 selected_box = 2
  1235.                             elseif (a3 == 11) and (a2 >= 2) then
  1236.                                 selected_box = 3
  1237.                             elseif (a3 == 16) and ((a2 >= 20) and (a2 <= 29)) then
  1238.                                 break
  1239.                             elseif (not do_debug) and ((a3 == 13) and ((a2 >= 2) and (a2 <= 17))) then
  1240.                                 do_debug = true
  1241.                             elseif (do_debug) and ((a3 == 13) and ((a2 >= 2) and (a2 <= 16))) then
  1242.                                 do_debug = false
  1243.                             end
  1244.                         end
  1245.                     end
  1246.                     term.setCursorBlink(false)
  1247.                     term.clear()
  1248.                     term.setCursorPos(16, 2)
  1249.                     term.setTextColor(colors.lime)
  1250.                     term.write("CRFv3.1 LAN Setup")
  1251.                     term.setTextColor(colors.white)
  1252.                     term.setCursorPos(5, 5)
  1253.                     term.write("Thank you for using CRFv3.1.")
  1254.                     term.setCursorPos(5, 7)
  1255.                     term.write("Please set up your router:")
  1256.                     term.setCursorPos(2, 9)
  1257.                     if selected_box == 1 then
  1258.                         term.setTextColor(colors.lime)
  1259.                     end
  1260.                     term.write("Name >")
  1261.                     term.setTextColor(colors.white)
  1262.                     term.write(name_box)
  1263.                     if selected_box == 2 then
  1264.                         term.setTextColor(colors.lime)
  1265.                     end
  1266.                     term.setCursorPos(2, 10)
  1267.                     term.write("Network Key >")
  1268.                     term.setTextColor(colors.white)
  1269.                     term.write(key_box)
  1270.                     term.setCursorPos(2, 11)
  1271.                     if selected_box == 3 then
  1272.                         term.setTextColor(colors.lime)
  1273.                     end
  1274.                     term.write("WAN Key >")
  1275.                     term.setTextColor(colors.white)
  1276.                     term.write(wan_key_box)
  1277.                     term.setCursorPos(2, 12)
  1278.                     term.write("All fields can be blank.")
  1279.                     term.setCursorPos(2, 13)
  1280.                     if do_debug then
  1281.                         term.setTextColor(colors.lime)
  1282.                         term.write("[Debug Enabled]")
  1283.                     else
  1284.                         term.setTextColor(colors.red)
  1285.                         term.write("[Debug Disabled]")
  1286.                     end
  1287.                     term.setTextColor(colors.white)
  1288.                     term.setCursorPos(20, 16)
  1289.                     term.write("[Continue]")
  1290.                     if selected_box == 1 then
  1291.                         term.setCursorPos(2+#"Name >"+#name_box, 9)
  1292.                     elseif selected_box == 2 then
  1293.                         term.setCursorPos(2+#"Network Key >"+#key_box, 10)
  1294.                     elseif selected_box == 3 then
  1295.                         term.setCursorPos(2+#"WAN Key >"+#wan_key_box, 11)
  1296.                     end
  1297.                     term.setCursorBlink(true)
  1298.                 end
  1299.                 if key_box ~= "" then
  1300.                     LAN.setNetworkKey(key_box)
  1301.                 end
  1302.                 if name_box ~= "" then
  1303.                     LAN.setNetworkName(name_box)
  1304.                 end
  1305.                 if wan_key_box ~= "" then
  1306.                     CRF.setWANKey(wan_key_box)
  1307.                 end
  1308.             end
  1309.             -- ev, tm, rg, sr, de, pe, le, lan
  1310.             local flags = {}
  1311.             for i=3, #args do
  1312.                 if string.sub(args[i], 1, 1) == "-" then
  1313.                     flags[string.sub(args[i], 2)] = true
  1314.                 end
  1315.             end
  1316.             local combined = CRF.compileDebugFlags(
  1317.                 flags.ev,
  1318.                 flags.tm,
  1319.                 flags.rg,
  1320.                 flags.sr,
  1321.                 flags.de,
  1322.                 flags.pe,
  1323.                 flags.le,
  1324.                 flags.lan
  1325.             )
  1326.             term.clear()
  1327.             term.setCursorPos(1,1)
  1328.             term.setCursorBlink(false)
  1329.             if not do_debug then
  1330.                 print("Don't worry, the router's running. Sorry, but we can't really have anything else showing due to the way the router works internally.")
  1331.                 CRF.run(combined)()
  1332.             else
  1333.                 CRF.run(0xFF)()
  1334.             end
  1335.         end
  1336.     end
  1337. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement