Lab: War Dialing
Due: Wednesday, November 11 at 11:59pm (one week after it is assigned) · Worth: 8 points
Find every responding host in a simulated address block. Your report must cover all 1024 addresses, including those where the request fails. The test data uses the DPRK range 175.45.176.0 through 175.45.179.255; the simulation sends no requests to those computers.
War dialing meant trying telephone numbers to find computers with modems, as in WarGames. This exercise uses IP addresses and HTTP requests.
Start
Create lab-wardialing from the starter template and clone your copy. Activate its Python environment, then install Requests:
$ python -m pip install requestsA Host That Answers
An IPv4 address has four numbers from 0 through 255 separated by periods; DNS translates readable domain names to addresses. Your is_server_at_hostname(hostname) function will accept either, without the http:// prefix.
First, test a request against your own computer. In a second terminal with the environment activated, start a local server:
$ python -m http.server 8001 --bind 127.0.0.1In the first terminal, create check_server.py using the reading’s download example. Request http://127.0.0.1:8001 with timeout=5 and print its status code. Here 127.0.0.1 means your computer, and 8001 is the port. Run python check_server.py, stop the server with Ctrl+C, then rerun the file and compare the results. The first request should return 200; the second should raise requests.ConnectionError. This scratch check is ungraded.
For this lab, any HTTP response, including 403 or 404, proves that a server answered. Do not use response.ok or raise_for_status() to decide whether a server exists. Connection failures and timeouts should return False; both are kinds of requests.RequestException. The timeout documentation explains why timeout=5 limits waiting for connection or response activity, rather than the entire download.
Every Address Once
Complete the functions in wardial.py, checking their doctests after each one:
Run the published examples:
$ python -m doctest wardial.pyNo output means they pass. The request tests use patched responses and exceptions, as in last week’s lab, without making network requests. If your starter still tests Google or Facebook, replace its server-detection docstring with the current starter’s version, preserving your implementation.
The Complete Scan
Finish the existing if __name__ == '__main__': block:
- Use
enumerate_ipsto setdprk_ipsto the 1024 addresses beginning at175.45.176.0. - Set
dprk_ips_with_serversto the addresses for whichis_server_at_hostnamereturnsTrue, using a loop or comprehension.
Keep the final print inside that guard so importing wardial.py does not run the scan. Test with the supplied simulation:
$ python offline_scan.pyIt runs your script with replacement network responses. Check for 1024 distinct requests and two detected servers: 175.45.176.5 and 175.45.179.250. Fewer requests can mean an enumeration error or an exception that stopped the loop. These responders are test fixtures, not live results.
Note the result, rewrite the loop as a comprehension (or expand the comprehension), and rerun the simulation. The address count and detected list should stay the same. Either form earns full credit; this comparison needs no extra output file.
Use offline_scan.py for this lab; do not run python wardial.py against the public range. Any separate live experiment needs the address owner’s authorization.
Submit
Commit and sync wardial.py, then use Gradescope’s GitHub option to submit your lab-wardialing repository and branch. A description and simulation output in README.md are optional documentation practice.
The 8 automatic points cover incrementing (2), enumeration (2), server detection (2), and an independently simulated scan (2). Gradescope checks new response and failure cases without contacting live servers.
Grading Rubric
Gradescope checks each item separately and adds the points earned.
Total: 8 points.