Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion config/modules/all.conf
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ include subset/connection/build.conf
include subset/bacnet/build.conf
include subset/security/build.conf
include subset/cloud/build.conf
include subset/manual/build.conf
include subset/manual/build.conf
include subset/network/build.conf
6 changes: 3 additions & 3 deletions docker/include/bin/start_faux
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,11 @@ if [ -n "${options[ntp_pass]}" -o -n "${options[ntp_fail]}" ]; then
fi

if [ -n "${options[broadcast_client]}" ]; then
echo Starting broatcast client.
cip_port=41794
echo Starting broadcast client.
port=41794
cycle_seconds=20
duration_seconds=360
python TransportClient/client.py $broadcast_ip $cip_port broadcast $duration_seconds $cycle_seconds &
python TransportClient/client.py $broadcast_ip $port broadcast $duration_seconds $cycle_seconds &
fi

if [ -n "${options[discover]}" ]; then
Expand Down
63 changes: 58 additions & 5 deletions docs/device_report.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ Overall device result FAIL
|Other|1/2|
|Connectivity|n/a|

|Expectation|pass|fail|skip|gone|
|---|---|---|---|---|
|Required|1|0|0|0|
|Recommended|2|0|0|0|
|Other|1|2|22|2|
|Expectation|pass|fail|skip|info|gone|
|---|---|---|---|---|---|
|Required|1|0|0|0|0|
|Recommended|2|0|0|0|0|
|Other|1|6|22|1|2|

|Result|Test|Category|Expectation|Notes|
|---|---|---|---|---|
Expand All @@ -66,14 +66,19 @@ Overall device result FAIL
|skip|cloud.udmi.pointset|Other|Other|No device id|
|skip|cloud.udmi.state|Other|Other|No device id|
|skip|cloud.udmi.system|Other|Other|No device id|
|info|communication.type.broadcast|Other|Other||
|fail|connection.dhcp_long|Other|Other||
|fail|connection.mac_oui|Other|Other|Manufacturer prefix not found!|
|fail|connection.min_send|Other|Other||
|skip|connection.port_duplex|Other|Other|No local IP has been set, check system config|
|skip|connection.port_link|Other|Other|No local IP has been set, check system config|
|skip|connection.port_speed|Other|Other|No local IP has been set, check system config|
|pass|manual.test.travis|Security|Recommended|Manual test - for testing|
|fail|network.ntp.support|Other|Other||
|skip|poe.negotiation|Other|Other|No local IP has been set, check system config|
|skip|poe.power|Other|Other|No local IP has been set, check system config|
|skip|poe.support|Other|Other|No local IP has been set, check system config|
|fail|protocol.app_min_send|Other|Other||
|fail|protocol.bacnet.pic|Other|Other|PICS file defined however a BACnet device was not found.|
|skip|protocol.bacnet.version|Other|Other|Bacnet device not found.|
|skip|security.firmware|Other|Other|Could not retrieve a firmware version with nmap. Check bacnet port.|
Expand Down Expand Up @@ -567,5 +572,53 @@ RESULT pass manual.test.travis Manual test - for testing
|---|---|
|enabled|True|

## Module network


#### Report

```
--------------------
connection.dhcp_long
--------------------
Device sends ARP request on DHCP lease expiry.
--------------------
RESULT fail connection.dhcp_long
--------------------
connection.min_send
--------------------
Device sends data at a frequency of less than 5 minutes.
--------------------


RESULT fail connection.min_send
--------------------
communication.type.broadcast
--------------------
Device sends unicast or broadcast packets.
--------------------
RESULT info communication.type.broadcast
--------------------
protocol.app_min_send
--------------------
Device sends application packets at a frequency of less than 5 minutes.
--------------------


RESULT fail protocol.app_min_send
--------------------
network.ntp.support
--------------------
Device sends NTP request packets.
--------------------
RESULT fail network.ntp.support
```

#### Module Config

|Attribute|Value|
|---|---|
|enabled|True|

## Report complete

23 changes: 18 additions & 5 deletions subset/network/TransportClient/client.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
"""
Used within the faux device to start a client which will send out broadcast packets.

Usage:
python TransportClient/client.py $broadcast_ip $port broadcast $duration_seconds $cycle_seconds
"""

import socket, sys, time

arguments = sys.argv
Expand All @@ -7,19 +14,25 @@
transport_type = str(arguments[3])
duration_seconds = int(arguments[4])
cycle_seconds = int(arguments[5])
message = "Fried lizards taste like chicken"
message = "Fried lizards taste like chicken!"

def broadcast_setup_socket():

def get_broadcast_socket():
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
client.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
return client


def send_message(message, transport_type):
client = None

if transport_type == 'broadcast':
client = broadcast_setup_socket()
sent = client.sendto(message, (udp_ip_address, udp_port))
client = get_broadcast_socket()

client.sendto(message, (udp_ip_address, udp_port))


while(duration_seconds > 0):
while duration_seconds > 0:
print('{t} to {a}'.format(t=transport_type, a=udp_ip_address))
send_message(message, transport_type)
time.sleep(cycle_seconds)
Expand Down
20 changes: 0 additions & 20 deletions subset/network/debug_generate_capture.py

This file was deleted.

65 changes: 56 additions & 9 deletions subset/network/network_tests.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
"""
This script can be called to run a specific network module test.

Currently supports:
- connection.min_send
- connection.dhcp_long
- protocol.app_min_send
- communication.type.broadcast
- network.ntp.support

Usage: python network_tests.py <test_to_run> <monitor.pcap file> <target_ip>

E.g. python network_tests.py connection.min_send $MONITOR $TARGET_IP
"""

import subprocess, time, sys, json

arguments = sys.argv
Expand Down Expand Up @@ -30,12 +45,15 @@
tcpdump_display_ntp_packets = 'tcpdump dst port 123 -r ' + cap_pcap_file
tcpdump_display_eapol_packets = 'tcpdump port 1812 or port 1813 or port 3799 -r ' + cap_pcap_file
tcpdump_display_broadcast_packets = 'tcpdump broadcast and src host ' + device_address + ' -r ' + cap_pcap_file
tcpdump_display_multicast_packets = 'tcpdump -n \'ip[16] & 240 = 224\' -r ' + cap_pcap_file


def write_report(string_to_append):
print(string_to_append.strip())
with open(report_filename, 'a+') as file_open:
file_open.write(string_to_append)


def shell_command_with_result(command, wait_time, terminate_flag):
process = subprocess.Popen(command, universal_newlines=True, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
text = process.stdout.read()
Expand All @@ -45,8 +63,10 @@ def shell_command_with_result(command, wait_time, terminate_flag):
process.terminate()
return str(text)


def add_packet_count_to_report(packet_type, packet_count):
write_report("{i} {t} Packets recieved={p}\n".format(i=ignore, t=packet_type, p=packet_count))
write_report("{i} {t} packets received={p}\n".format(i=ignore, t=packet_type, p=packet_count))


def add_packet_info_to_report(packets_received):
packet_list = packets_received.rstrip().split("\n")
Expand All @@ -55,23 +75,27 @@ def add_packet_info_to_report(packets_received):
write_report("{i} {p}\n".format(i=ignore, p=packet_list[x]))
write_report("{i} packets_count={p}\n".format(i=ignore, p=len(packet_list)))


def decode_shell_result(shell_result):
if len(shell_result) > min_packet_length_bytes:
packet_request_list = shell_result.rstrip().split("\n")
packets_received = len(packet_request_list)
return packets_received
return 0


def packets_received_count(shell_result):
if shell_result is None:
return 0
else:
return decode_shell_result(shell_result)


def load_json_config(json_filename):
with open(json_filename, 'r') as json_file:
return json.load(json_file)


def add_to_port_list(port_map):
global port_list
for port, port_info in port_map.items():
Expand All @@ -80,13 +104,15 @@ def add_to_port_list(port_map):
if value == True:
port_list.append(port)


def remove_from_port_list(port_map):
global port_list
for exclude in port_map:
for port in port_list:
if port == exclude:
port_list.remove(exclude)


def decode_json_config(config_file, map_name, action):
dictionary = load_json_config(config_file)
for key, value in dictionary.items():
Expand All @@ -99,6 +125,7 @@ def decode_json_config(config_file, map_name, action):
elif action == 'remove':
remove_from_port_list(port_map)


def test_connection_min_send():
arp_shell_result = shell_command_with_result(tcpdump_display_arp_packets, 0, False)
arp_packets_received = packets_received_count(arp_shell_result)
Expand All @@ -113,6 +140,7 @@ def test_connection_min_send():
add_packet_info_to_report(shell_result)
return 'pass' if app_packets_received > 0 else 'fail'


def test_connection_dhcp_long():
shell_result = shell_command_with_result(tcpdump_display_arp_packets, 0, False)
arp_packets_received = packets_received_count(shell_result)
Expand All @@ -123,6 +151,7 @@ def test_connection_dhcp_long():
else:
return 'fail'


def test_protocol_app_min_send():
"""
reads module_config json file and adds ports to port_list
Expand All @@ -148,19 +177,35 @@ def test_protocol_app_min_send():
else:
return 'fail'


def test_communication_type_broadcast():
shell_result = shell_command_with_result(tcpdump_display_broadcast_packets, 0, False)
broadcast_packets_received = packets_received_count(shell_result)
if broadcast_packets_received > 0:
""" Runs the communication.type.broadcast DAQ test.

Counts the number of unicast, broadcast and multicast packets sent.

"""

broadcast_result = shell_command_with_result(tcpdump_display_broadcast_packets, 0, False)
broadcast_packets = packets_received_count(broadcast_result)
if broadcast_packets > 0:
add_summary("Broadcast packets received.")
add_packet_count_to_report("Broadcast", broadcast_packets_received)
shell_result = shell_command_with_result(tcpdump_display_all_packets, 0, False)
all_packets_received = packets_received_count(shell_result)
if (all_packets_received - broadcast_packets_received) > 0:
add_packet_count_to_report("Broadcast", broadcast_packets)

multicast_result = shell_command_with_result(tcpdump_display_multicast_packets, 0, False)
multicast_packets = packets_received_count(multicast_result)
if multicast_packets > 0:
add_summary("Multicast packets received.")
add_packet_count_to_report("Multicast", multicast_packets)

unicast_result = shell_command_with_result(tcpdump_display_all_packets, 0, False)
unicast_packets = packets_received_count(unicast_result) - broadcast_packets - multicast_packets
if unicast_packets > 0:
add_summary("Unicast packets received.")
add_packet_count_to_report("Unicast", all_packets_received - broadcast_packets_received)
add_packet_count_to_report("Unicast", unicast_packets)

return 'info'


def test_ntp_support():
shell_result = shell_command_with_result(tcpdump_display_ntp_packets, 0, False)
ntp_packets_received = packets_received_count(shell_result)
Expand All @@ -171,10 +216,12 @@ def test_ntp_support():
else:
return 'fail'


def add_summary(text):
global summary_text
summary_text = summary_text + " " + text if summary_text else text


write_report("{b}{t}\n{b}".format(b=dash_break_line, t=test_request))

if test_request == 'connection.min_send':
Expand Down
43 changes: 43 additions & 0 deletions subset/network/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Network Module

## connection.dhcp_long
- Located in network_tests.py, started up in test_network.
- The aim of the test is to check that the device issues a DHCPREQUEST after having been disconnected and after the DHCP lease has expired.

### Testing procedure:
- Runs a tcpdump command check if any ARP packets are being sent.
- PASS: If packets are found from the tcpdump scan.
- FAIL: If packets are not found from the tcpdump scan.

## connection.min_send
- Located in network_tests.py, started up in test_network.
- Check if a device sends any data packet at a frequency of less than five minutes.

### Result cases:
- PASS: The time between packets is measured - pass if time between any two packets is less than five minutes (deals with case where a monitor scan is long)
- FAIL: If data packets are sent, and there are packets with time interval of less than five minutes found, then fail.
- SKIP: If no data packets are sent and the monitor scan period is short, the test will skip instead of failing.

## communication.type.broadcast
- Located in network_tests.py, started up in test_network.
- This test counts the number of unicast, broadcast and multicast packets sent out by reading from the .pcap file that DAQ has created during runtime.

### Testing procedure:
1. Run tcpdump command to find broadcast packets coming from the specified source address.
2. To get the number of broadcast packets, it counts the lines from the tcpdump output. Add this to the final report.
3. Run tcpdump command again to find multicast packets with the first byte of their addresses that are between 224 to 239 inclusive.
4. To get the number of multicast packets, it counts the lines from the tcpdump output. Add this to the final report.
5. Run the tcpdump again but to find all packets sent.
6. To get the number of unicast packets, subtract the number of broadcast and multicast packets if any, from the unicast packet count, and add to the report.

### Result cases:
This is an 'info' test, it does not have a pass/fail/skip case.

## network.ntp.support
- Located in network_tests.py, started up in test_network.
- Does the device support: RFC 5905 - Network Time Protocol Version 4: Protocol and Algorithms Specification

### Testing procedure:
- Runs a tcpdump command check if any packets are being sent to a destination port of 123.
- PASS: If packets are found from the tcpdump scan.
- FAIL: If packets are not found from the tcpdump scan.
Loading