aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas DeMarinis <ndemarinis@wpi.edu>2023-09-01 18:20:11 -0400
committerNicholas DeMarinis <ndemarinis@wpi.edu>2023-09-01 18:20:11 -0400
commit6772405e1560fed367fac4f774f7d40b0b3ec6a5 (patch)
tree2e742f4f09f3f9faea6f6220716ae9d11fdc76d1
parent970a41c7665c635fc7a10b287f6dfa62b0eb3430 (diff)
Added ARM64 reference binaries and snowcast dissector.
-rwxr-xr-xreference/arm64/snowcast_controlbin1873112 -> 1881144 bytes
-rwxr-xr-xreference/arm64/snowcast_listenerbin1544472 -> 1551576 bytes
-rwxr-xr-xreference/arm64/snowcast_serverbin2004920 -> 2078616 bytes
-rw-r--r--util/snowcast-dissector/README.md68
-rw-r--r--util/snowcast-dissector/cs168_snowcast.lua107
5 files changed, 175 insertions, 0 deletions
diff --git a/reference/arm64/snowcast_control b/reference/arm64/snowcast_control
index 0f2ceaf..4336ed0 100755
--- a/reference/arm64/snowcast_control
+++ b/reference/arm64/snowcast_control
Binary files differ
diff --git a/reference/arm64/snowcast_listener b/reference/arm64/snowcast_listener
index 3991c31..0ddb872 100755
--- a/reference/arm64/snowcast_listener
+++ b/reference/arm64/snowcast_listener
Binary files differ
diff --git a/reference/arm64/snowcast_server b/reference/arm64/snowcast_server
index 587da32..5d9a380 100755
--- a/reference/arm64/snowcast_server
+++ b/reference/arm64/snowcast_server
Binary files differ
diff --git a/util/snowcast-dissector/README.md b/util/snowcast-dissector/README.md
new file mode 100644
index 0000000..a62522e
--- /dev/null
+++ b/util/snowcast-dissector/README.md
@@ -0,0 +1,68 @@
+# CS1680 Snowcast Dissector
+
+THis directory contains a dissector (also known as a decoder) for the Snowcast
+protocol implementation for CS168.
+
+## Installation Instructions
+
+The dissector is provided as a Lua script in this directory. For security
+reasons, Wireshark does not run Lua scripts when run as root--therefore, you
+must ensure that you are using Wireshark as your local user, not with root or
+sudo. To run wireshark as a standard user, make sure your user is added to the
+`wireshark` group. If you are using the provided VM, the the vagrant user is
+already in the wireshark group. However, if you are running Wireshark on your
+own system, you will need to configure this yourself.
+
+Once you have Wireshark running as your user. Add the dissector to Wireshark,
+by copying the script into your plugins directory.
+
+To do this:
+
+ 1. Run wireshark as your user (**not with root or sudo**).
+ 2. Open Wireshark's Help menu and select "About Wireshark".
+ 3. In the folders tab, find the entry "Personal Lua Plugins". For example:
+ `~/.config/wireshark/plugins`
+ 4. Copy the script to this directory (if it doesn't exist, create it) and
+ restart wireshark
+ 5. Open the "About Wireshark" window again and look in the Plugins tab. You
+ should now see cs168_rip.lua in the list of plugins.
+
+## Using the dissector
+
+_To make sure your dissector is working, please run the Snowcast reference
+binaries_
+
+Wireshark will automatically invoke the Snowcast dissector when it encounters a
+TCP packets on port 1680. This means that if you start the Snowcast server on
+port 1680, TCP packets on port 1680 will automatically be decoded as Snowcast
+commands and replies.
+
+To use the Snowcast dissector with other port numbers we can instruct wireshark
+to interpret TCP packets on a given port as Snowcast commands and responses.
+We can tell wireshark to do this using Wireshark's "User-Specified Decodes"
+feature:
+
+1. Run your binaries and to start capturing packets. You should be capturing
+ packets on the loopback interface.
+2. Find a TCP packet related to this assignment and select it. These packets
+ will have a destination and source port number. One of these port numbers
+ should be the port number you selected when starting up the Snowcast server.
+3. Right click on the TCP packet and select "Decode As..."
+4. Double click "(none)" under "current" and select CS168SNOWCAST.
+
+Wireshark should no update and decode the TCP packets with your specified port
+number as Snowcast commands and replies.
+
+If you do not see Snowcast commands and replies, check your "Decode As..." rule
+from step 4. If you still do not see Snowcast commands and replies, make sure
+that the plugin is loaded in the help menu.
+
+### Disclaimer
+
+The steps listed above will invoke the decoder only on a single TCP port. You
+should repeat the steps above each time you change TCP ports
+
+## Feedback
+
+If you have questions or encounter any issues with the decoder, please post on
+EdStem or see the course staff for help.
diff --git a/util/snowcast-dissector/cs168_snowcast.lua b/util/snowcast-dissector/cs168_snowcast.lua
new file mode 100644
index 0000000..511aa59
--- /dev/null
+++ b/util/snowcast-dissector/cs168_snowcast.lua
@@ -0,0 +1,107 @@
+-- CS168 Snowcast Protocol Dissector
+
+snowcast_protocol = Proto("CS168Snowcast", "CS168 Snowcast Protocol")
+
+message = ProtoField.uint8("cs168snowcast.messsage_type", "messageType", base.DEC)
+
+-- HELLO fields
+udp_port = ProtoField.uint16("cs168snowcast.udp_port", "udpPort", base.DEC)
+-- SET_STATION fields
+station_number = ProtoField.uint16("cs168snowcast.station_number", "stationNumber", base.DEC)
+-- WELCOME fields
+num_stations = ProtoField.uint16("cs168snowcast.num_stations", "numStations", base.DEC)
+-- ANNOUNCE fields
+song_name_size = ProtoField.uint8("cs168snowcast.song_name_size", "songnameSize", base.DEC)
+song_name = ProtoField.string("cs168snowcast.song_name", "songname")
+-- INVALID_COMMAND fields
+reply_string_size = ProtoField.uint8("cs168snowcast.reply_string_size", "replyStringSize", base.DEC)
+reply_string = ProtoField.string("cs168snowcast.reply_string", "replyString")
+
+snowcast_protocol.fields = {
+ message,
+ udp_port,
+ station_number,
+ num_stations,
+ song_name_size,
+ song_name,
+ reply_string_size,
+ reply_string
+}
+
+function snowcast_protocol.dissector(buffer, pinfo, tree)
+ length = buffer:len()
+ if length == 0 then return end
+
+ pinfo.cols.protocol = snowcast_protocol.name
+
+ local subtree = tree:add(snowcast_protocol, buffer(), "Snowcast Protocol Data")
+
+ local packet_len = buffer:reported_length_remaining()
+
+ local message_num = buffer(0, 1):uint()
+ local message_name = get_message_name(message_num)
+
+ -- Add command ID and name
+ subtree:add(message, buffer(0, 1)):append_text(" (" .. message_name .. ") ")
+
+ -- Clear any existing info in the info column so the TCP stuff info isn't in the way
+ pinfo.cols.info = ""
+
+ pinfo.cols.info:append("Snowcast " .. message_name)
+
+ if message_num == 0 then
+ -- Handling HELLO command
+ local udpPort = buffer(1, 2):uint()
+ subtree:add(udp_port, buffer(1, 2))
+ pinfo.cols.info:append(" (UDP Port: " .. udpPort .. ") ")
+ elseif message_num == 1 then
+ -- Handling SET_STATION command
+ local stationNumber = buffer(1, 2):uint()
+ subtree:add(station_number, buffer(1, 2))
+ pinfo.cols.info:append(" (Station Number: " .. stationNumber .. ") ")
+ elseif message_num == 2 then
+ -- Handling WELCOME reply
+ local numStations = buffer(1, 2):uint()
+ subtree:add(num_stations, buffer(1, 2))
+ pinfo.cols.info:append(" (Station Number: " .. numStations .. ") ")
+ elseif message_num == 3 then
+ -- Handling ANNOUNCE reply
+ local songnameSize = buffer(1, 1):uint()
+ subtree:add(reply_string_size, buffer(1, 1))
+
+ local songname = buffer(2, songnameSize):string()
+ subtree:add(reply_string, buffer(2, songnameSize))
+
+ pinfo.cols.info:append(" (Song Name [" .. songnameSize .. " bytes]: " .. songname .. ") ")
+ elseif message_num == 4 then
+ -- Handling INVALID_COMMAND reply
+ local replyStringSize = buffer(1, 1):uint()
+ subtree:add(reply_string_size, buffer(1, 1))
+
+ local replyString = buffer(2, replyStringSize):string()
+ subtree:add(reply_string, buffer(2, replyStringSize))
+
+ pinfo.cols.info:append(" (Reply String [" .. replyStringSize .. " bytes]: " .. replyString .. ") ")
+ end
+end
+
+function get_message_name(message_num)
+ local message_name = "UNNOWN"
+
+ if message_num == 0 then
+ message_name = "HELLO"
+ elseif message_num == 1 then
+ message_name = "SET_STATION"
+ elseif message_num == 2 then
+ message_name = "WELCOME REPLY"
+ elseif message_num == 3 then
+ message_name = "ANNOUNCE REPLY"
+ elseif message_num == 4 then
+ message_name = "INVALID_COMMAND REPLY"
+ end
+
+ return message_name
+end
+
+local tcp_port = DissectorTable.get("tcp.port")
+tcp_port:add(1680, snowcast_protocol)