You are on page 1of 92

lOMoARcPSD|11775577

2021 S1 Practicals with Answers

Computer Systems (University of Melbourne)

StuDocu is not sponsored or endorsed by any college or university


Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

School of Computing and Information Systems


COMP30023: Computer Systems

Week 01 - CLI Revision

In this activity, you will (re)?gain1 familiarity with basic *nix CLI commands.
This will help you in completing practical/lab classes and projects and interacting with the VM.
You should complete Part 1 and 2 of the prelab before starting this activity.
However, it is possible to complete these activities on dimefox.

If you are already familiar with the CLI, we strongly encourage you to complete the exercises in Section
3.4 and 4.1, towards the end of this document.

1 Upload files with scp


In this task, you will download the cli.tar.gz archive file from the LMS and upload it to your server
using the scp command.

If you have completed the optional SSH config setup in the prelab, execute the following command on
your local machine:
$ scp <local-path-of-file> comp30023:
If you have not completed the optional setup, use the command:
$ scp -i <path-to-private-key> <local-path-of-file> <username>@<ip>:

Now SSH into your server to confirm that the file has been uploaded ( ls ).
You may also want to download files from your server in later practicals, which can be achieved by
executing the following command on your local machine:
$ scp comp30023:<remote-path-of-file> .
or
$ scp -i <path-to-private-key> <username>@<ip>:<remote-path-of-file> .

Tip: Directories can be transferred using the -r flag.


To synchronise local and remote directories, consider the rsync command.

2 The basics
Command Line Interface utility tools you will use in this section:
• Shell command: cd
• coreutils commands: pwd, mkdir, rm, ls, cat

For all of the utility tools above, you can read about their usage using man. For example, if you wanted
to know how to use mkdir, you can run the following command verbatim:
$ man mkdir
which will give similar output to:
1 Regex all the things!

Downloaded by Lucien Lu (llucien7789@gmail.com)


lOMoARcPSD|11775577

MKDIR(1) User Commands MKDIR(1)

NAME
mkdir - make directories

SYNOPSIS
mkdir [OPTION]... DIRECTORY...

DESCRIPTION
Create the DIRECTORY(ies), if they do not already exist.
Mandatory arguments to long options are mandatory for short options
too.
-m, --mode=MODE
set file mode (as in chmod), not a=rwx - umask
-p, --parents
no error if existing, make parent directories as needed
-v, --verbose
print a message for each created directory
-Z set SELinux security context of each created directory to the
default type
--context[=CTX]
like -Z, or if CTX is specified then set the SELinux or SMACK
security context to CTX
--help display this help and exit
--version
output version information and exit

AUTHOR
Written by David MacKenzie.
REPORTING BUGS
GNU coreutils online help: <https://www.gnu.org/software/coreutils/>
Report any translation bugs to <https://translationproject.org/team/>
COPYRIGHT
Copyright © 2020 Free Software Foundation, Inc. License GPLv3+: GNU
GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

SEE ALSO
mkdir(2)
Full documentation <https://www.gnu.org/software/coreutils/mkdir>
or available locally via: info '(coreutils) mkdir invocation'
GNU coreutils 8.32 March 2020 MKDIR(1)
Press q to exit.

Now perform the following tasks:


1. Determine which directory you’re in with the pwd command.

2. Use the ls command (with the appropriate flags) to list all the files and directories (including
hidden files and their attributes) that are in your home directory. Are there any hidden files?

3. Use cat (or if you prefer, less / more etc.) to print the contents of the file
.ssh/authorized_keys to the terminal. Does the output look familiar?
Tip: use the tab key to autocomplete file/directory names (e.g. type cd .s , tab key, and tab key
again).
4. Make a new directory named test using mkdir .

Downloaded by Lucien Lu (llucien7789@gmail.com)


lOMoARcPSD|11775577

5. cd into the test directory that you created, and check pwd again.
Tip: use the up arrow to repeat previous commands. See 2 (optional) for other convenient shortcuts.
6. Remove the test directory with the rm command.
Refer to the sample commands listed in the appendix if you’re stuck.

3 Files
In this section, you will use the following commands to explore and perform some common operations
on files:

• coreutils: cat, cp, mv, head, tail, grep


• file, tar

3.1 Extract the prelab files


Execute $ tar xf cli.tar.gz 3 to extract the files for this activity.
cd into the cli folder.

3.2 File management


In this exercise, you will use cp and mv to complete some basic file operations.

1. Use the ls command to list the files which are in this directory.

2. Copy the file named empty file to a file named empty .


Tip: Use a \ to escape the space or surround empty file with quotation marks.

3. Use the mv command to rename the directory named


No I6OvLQd
copying
No HanKgUl
copying
allowed!
No E4gftTS
copying
allowed!allowed! 4 to
c8TV0aG1ETk
dir .

4. Use the mv command to move the file empty into the dir directory.

3.3 Examining files


Debugging often involves the examination of log files and program output.
In this exercise, you will use head , tail and grep to extract information from the file subjects (a
list of BSci-credited subjects taken from the unimelb handbook).

1. But first, let’s run the command $ file * 5 . Looking at this output, what do you think the
file command does?

2. Use $ head subjects to print the first 10 lines of the file subjects .

3. Read the man page of head to determine the flag used to modify the number of lines which are
outputted. Use this knowledge to print the first 20 lines instead.
4. Similarly, use the tail command to print the last 20 lines of the file.

5. The grep command can be used to search for and print lines that match patterns.
The basic syntax is as follows: $ grep search_pattern path/to/file .
Use grep to search for subjects starting with COMP.
2 https://ss64.com/bash/syntax-keyboard.html
3 https://explainshell.com/explain?cmd=tar+xf+filename.tar.gz
4 This was randomly generated with pwgen . It is deliberately long, to discourage you from typing it out.
5* is a glob. This pattern is a wildcard which matches all visible files

Downloaded by Lucien Lu (llucien7789@gmail.com)


lOMoARcPSD|11775577

3.4 Line endings


In this exercise, you will use the commands from above to briefly examine the files which are in the cli
directory.
1. Use the cat command to output the file welcome .
What do you notice about the positioning of the $ ?
Why do you think this is the case? Run $ file welcome if you are unsure.

2. Now use cat to concatenate the files welcome and comp30023 , and then concatenate the files
welcome and comp30023_1 . Is there any visible difference?

3. What if we compare the outputs with the diff command?


Redirect the outputs6 of the cat command into files out1 and out2 and run diff out1 out2 .
Note: 1c1 indicates that line 1 in the first file was changed to line 1 in the second file.
Why does diff indicate that out1 and out2 are different?
Hint: try $ file comp30023 comp30023_1 .
Can we make diff ignore differences in line endings?

4 Other useful commands and variations (challenge, extension)


• which to “show the full path of (shell commands)”, e.g. which ssh .
• wc -l or nl to count the number of lines in a file.

• grep with regex, e.g. grep -E 'COMP|INFO|SWEN' subjects

• cut to “remove sections from each line of files”, e.g. cut -d' ' -f2- subjects .

• sort to sort lines, uniq to omit repeated lines (once sorted).


• Combining commands with pipes, where the output of the command before the pipe becomes the
input of the command after the pipe (more on this in the later half of the subject). e.g.
cat subjects | grep -E 'COMP|INFO|SWEN' | wc -l to count the number of subjects starting
with COMP/INFO/SWEN.

4.1 Exercises
Use commands you learnt above to answer the following questions:
1. How many subjects are there in subjects ?

2. Use command(s) (e.g. cut ) to extract a list of subject codes.


3. How many 10001 subjects are there?
4. How many subjects start with C?
5. When sorted by subject name (not code), what is the last COMP subject that is listed?
6. How many letters of the alphabet are represented in the first character of subject codes?
7. What subject prefix (e.g. COMP, SWEN etc.) is most frequently occurring? What is its count?

5 Additional resources
• https://missing.csail.mit.edu/
• https://linuxjourney.com/lesson/alias-command
• http://www.ee.surrey.ac.uk/Teaching/Unix
6 e.g using > or tee

Downloaded by Lucien Lu (llucien7789@gmail.com)


lOMoARcPSD|11775577

A Sample solutions
A.2
1. $ pwd , output should be /home/<username>

2. $ ls -la . Yes, there should be hidden files and directories, e.g. .bashrc , .ssh/ .

3. $ cat .ssh/authorized_keys , $ cat ~/.ssh/authorized_keys ,


$ cat /home/<username>/.ssh/authorized_keys are all valid solutions. The output should
be your public key (which gives you access to your VM).

4. $ mkdir test or $ mkdir test/

5. $ cd test or $ cd test/ , then pwd should show that you’re within /home/<username>/test

6. $ rm -r test , or since the directory is empty, $ rmdir test/

A.3
A.3.2
1. $ ls

2. $ cp empty\ file empty or $ cp "empty file" empty

3. $ mv I6OvLQdHanKgUlE4gftTSc8TV0aG1ETk dir , use tab completion to autocomplete I6... .

4. $ mv empty dir/ , mv empty dir/empty

A.3.3
1. FILE(1) BSD General Commands Manual FILE(1)
NAME
file — determine file type
...
2. $ head subjects

AGRI20026 Plant Growth Processes


AGRI20036 Ecology and Grazing Management
... 8 more lines

3. $ head -n 20 subjects , head --lines=20 subjects

4. $ tail -n 20 subjects

... 12 more lines


ZOOL30008 Experimental Marine Biology
ZOOL30009 Tropical Field Ecology

5. $ grep COMP subjects

COMP10001 Foundations of Computing


...
COMP30023 Computer Systems
...
COMP30027 Machine Learning

Tip: can also use regex, e.g.


$ grep ^COMP subjects to match start of line,
or $ grep -E 'COMP[0-9]{5}' subjects to match the numeric code also.

Downloaded by Lucien Lu (llucien7789@gmail.com)


lOMoARcPSD|11775577

A.3.4
1. $ (to be more specific, your primary Prompt String or PS1) should trail welcome ,
e.g. welcome username@host:cli$ .
This is because there is no trailing newline.
2. cat welcome comp30023 , cat welcome comp30023_1 , no visible difference.

3. cat welcome comp30023 > out1 && cat welcome comp30023_1 > out2 && diff out1 out2
diff indicates that out1 and out2 are different. This is because comp30023 and
comp30023_1 have different line endings, which should be apparent after running the file
command on both files.
It is possible to make diff strip CR characters, using --strip-trailing-cr
Bonus: How can we inspect files to determine their line endings?
Use xxd to print the hexdump of both files.
$ xxd comp30023
00000000: 746f 2063 6f6d 7033 3030 3233 0a to comp30023.
$ xxd comp30023_1
00000000: 746f 2063 6f6d 7033 3030 3233 0d0a to comp30023..
From this, we can see that comp30023 ends in 0a, which corresponds to LF (\n), while comp30023_1
ends in 0d0a, which corresponds to CRLF (\r\n) (see ASCII table).
4. Bonus: The unimelb file is a GIF (a binary file)

$ file unimelb
unimelb: GIF image data, version 89a, 115 x 111
$ xxd unimelb | head
00000000: 4749 4638 3961 7300 6f00 c400 0000 5c9b GIF89as.o.....\.
00000010: 4576 ac00 5e9a 6487 b7ff ffff d1d9 ea30 Ev..^.d........0 ... truncated

Where does the information from file come from?


GIF 89a is immediately apparent.
For dimensions, look to bytes 6-10 (i.e. 7300 6f00), and convert 0x0073 and 0x006f to decimal.
73 00 becomes 0x0073 and 00 6f become 0x6f00 due to little-endian byte ordering.
https://github.com/file/file/blob/81f15c2b0d6e9eaf524ff7bab37426c21af75fb7/magic/
Magdir/images#L512

A.4
A.4.1
1. $ wc -l subjects
356
2. $ cut -d' ' -f1 subjects , awk -F' ' '{print $1}' subjects

3. $ grep 10001 subjects | wc -l


8
4. $ grep '^C' subjects | wc -l
42
5. $ grep ^COMP subjects | sort -k 2 | tail -n 1
COMP30026 Models of Computation
6. $ cut -c 1 subjects | sort | uniq | wc -l
15
7. $ cut -c 1-4 subjects | sort | uniq -c | sort -n | tail -n 1
39 MAST

Downloaded by Lucien Lu (llucien7789@gmail.com)


lOMoARcPSD|11775577

School of Computing and Information Systems


COMP30023: Computer Systems

Practical Week 2
1 Introduction
Git is a distributed version control system originally developed by Linus Torvalds to maintain Linux kernel
code. It is now widely used in all kinds of projects to track changes in files and enable collaboration
among developers. This lab will serve as a brief introduction to Git so that you can start using it to
manage code in your own projects.

2 COMP30023 Gitlab Access


Please first complete the Gitlab Access assignment https://canvas.lms.unimelb.edu.au/courses/
107590/assignments/205171, to gain access to your assignment/project submission repositories.
Do not wait for the automated program to grant you access (it runs half-hourly and only supplies
access to project repositories). Instead, you should continue with the activities below with your https:
//gitlab.eng.unimelb.edu.au account.

3 Installing new packages


While Ubuntu Server (the Linux distribution that we’re using) comes with some standard packages1 (e.g.
coreutils2 ), not all the commands and tools that we’re going to use in this subject is preinstalled.
We can use Ubuntu’s default package manager to install new software.
Install new package(s) with $ sudo apt install <package-name> <package-name> ... 3

Let’s install gcc, make, and git, which will be required to complete the projects.
Confirm correct installation of git and the gcc compiler.
Command: $ gcc --version , $ git --version

4 Introducing Yourself to Git


Before we start using Git, we need to setup our name and email. Note that this is just for identification
purposes, and not to log in to any system. This process will need to be repeated on each user account
on which you want to use git.

Command: $ git config --global user.name "Your Name"


Command: $ git config --global user.email "yourusername@student.unimelb.edu.au" 4

Now that Git knows who we are, let’s create our first repository.
1 http://releases.ubuntu.com/20.04/ubuntu-20.04.2.0-desktop-amd64.manifest
2 https://en.wikipedia.org/wiki/List_of_GNU_Core_Utilities_commands
3 You may need to run $ sudo apt update first
4 The --global option means that Git will use these values for every Git project the current user creates. The values
are written to ~/.gitconfig

Downloaded by Lucien Lu (llucien7789@gmail.com)


lOMoARcPSD|11775577

5 Creating a Git Project


Git projects are more commonly known as Git repositories. Let’s initialise a repository.

1. Create a new directory. Let’s call it git-repo-1 .

2. Navigate into the newly created directory.

3. Initialise a repository in this directory. Command: $ git init


This will create a new (hidden)5 directory named .git in the git-repo-1 directory. This
directory will contain all version information related to this repository.

Sample solutions will be released at the end of the week.


Ask your classnames and demonstrator for help during practical classes.

6 Adding Files to Git


A file can exist in three stages in a Git repository: Working, Staging and Commit 6 .

• Any changes not explicitly added to the Staging area reside in the Working Directory.

• Changes can be added to the Staging Area (also known as Index) using the git add command.
This marks the changes that should go into the next commit
• The git commit command adds the marked changes from the step above to the (local) repository.

Figure 17 shows the flow of operations:

Figure 1: Flow of operations

Let’s see this in practice:


1. Create an empty file named test.c with the touch command.
Command: $ touch test.c

2. This file is now in the working directory and untracked by Git. Run the git status command
to see this.
Command: $ git status

3. Add some content to the file to make it compilable, using nano , vim , echo etc.
e.g. the line void main(){} in test.c .

5 You can use the command ls -a to view the directory.


6 You can also stage parts of a file, which is unique to Git and a main reason for the intermediate Staging step
7 Source: https://git-scm.com/about/staging-area

Downloaded by Lucien Lu (llucien7789@gmail.com)


lOMoARcPSD|11775577

Brief instructions for nano :


$ nano test.c , type in text, ctrl-x, letter y, enter key.

Brief instructions for vim :


$ vim test.c , letter i to enter insert mode, type in text, escape key to exit insert mode and back
to normal mode, :x, Enter to save.
4. Add this file to the staging area.
Command: $ git add test.c

5. View the status of the repository now using the git status command again. Notice that the
test.c file is now listed under ‘Changes to be committed’.
6. If you have modified multiple files and want to add all of them to the staging area at once, you can
use the git add . command.

7 Committing Changes
Now that we have added our changes to the staging area (i.e. marked the changes we want to commit),
let’s commit the changes.
Committing the changes stores a snapshot of the current state of the files. This allows you to roll back
to this version if needed in the future. Note that this snapshot is stored locally on your machine.
1. Command: $ git commit -m "Created test.c with main()"
Every commit needs to be accompanied by a commit message, which is what we specified using
the -m parameter.
2. Inspect the current status of the repository using git status .

You can also combine the add and commit steps in one operation using the
git commit --all -m "commit message" command.
Note that this combined operation only commits changes to files added earlier, and does not commit
new files.

8 .gitignore
Now that we have made our first commit, let’s compile test.c with gcc.
1. Write a Makefile to compile test.c with gcc to an executable named test .
Discuss with your classnames, demonstrator if you have forgotten how to do so. Solutions will be
released at the end of the week.
2. Execute $ make .
3. Verify that compilation was successful (i.e. does test exist? is test executable?).
4. Execute $ git status again. Both Makefile and test should be unstaged at this point.
5. We shouldn’t stage and commit test, as it is a binary file which is machine architecture depen-
dent and can be reproduced any time that we run make. By committing it, we are bloating our
repositories with different versions of test. When repositories are then pushed to servers, all of
these rubbish files will have to be uploaded!
While it is possible to selectively choose files to stage and commit them (e.g. $ git add Makefile ),
the convenience of using $ git add . is lost. This is the purpose of the .gitignore file, which
can be used to specify (in separate lines) the file(s) and director(ies) which should be ignored by git.

Let’s create a .gitignore file with a line:


test
This tells git to ignore files named test.

Downloaded by Lucien Lu (llucien7789@gmail.com)


lOMoARcPSD|11775577

6. Check $ git status again. Once you’re happy, stage Makefile and .gitignore simultane-
ously and commit the changes, giving the commit an appropriate message.

7. Use the $ git log command to view the history of commits you have made.

Note: you are expected to follow good version control practices (sensible commit messages, no useless
executables etc.) for project repositories. More on this in the project specifications.

9 Setting up GitLab
It is common practice in teams to have a Git server that everyone push es their code to.
Github and Gitlab are examples of publicly-available hosting services. We will be using Gitlab, open
source software that is hosted on the servers of the Faculty of Engineering and IT.

Login to https://gitlab.eng.unimelb.edu.au.
Click ‘Create a Project’ and create a project named comp30023-practical-2 . Set the visibility level
to ‘Private’.

10 Pushing Changes
Note that every git operation up to now has been done locally. That is, our changes to the files have
not been sent to a remote server.

1. For this, we need to tell Git which external repository (remote) we want to link our local repository
to.
Command:
8
$ git remote add origin https://gitlab.eng.unimelb.edu.au/husernamei/comp30023-practical-2.git

You can check the URLs using git remote -v and where necessary, amend it using
git remote set-url origin <new-url> .

2. Push your changes to the server by using the git push command.
Command: $ git push -u origin master
After this first push you can push changes by simply using the command git push

You do not need to push after every commit.


It is appropriate to push after every major change (e.g. a new feature, a bug fix, some refactoring etc.)

11 Cloning
It is common to join a team with an ongoing project which does source code management using Git. We
use the git clone command to get a copy of existing code stored on an external Git server.

1. Run this command from a directory outside the Git repository we have been working in
Command:
$ git clone https://gitlab.eng.unimelb.edu.au/husernamei/comp30023-practical-2.git

2. Note that a new directory has been created with the name comp30023-practical-2 . Browse
to this directory, view files. Use the git status and git log commands to note that the full
history of the repository has been downloaded.
8 We are setting an alias named origin to the URL so that we don’t have to type the entire remote URL each time we
do a push

Downloaded by Lucien Lu (llucien7789@gmail.com)


lOMoARcPSD|11775577

12 Branches
Git allows you to organise code in branches.9 For example, you might create a new branch for a new
feature of your application. You can then keep continued development on the core of the application
(e.g. bug fixes) separate from the new feature development.

Note: The use of gitk , if available, can be very helpful when dealing with multiple branches.

1. The default branch in Git is named ‘master’. Use the git branch command to list the current
branches.
Command: $ git branch
The currently active branch is shown with an asterisk.
2. The most common way to create a new branch in Git is to create a new branch and switch to it in
the same command10 . Let’s create a new branch named ‘new-feature’.
Command: $ git checkout -b new-feature or $ git switch -c new-feature

3. Run the git branch command again. Notice the newly created branch is currently active.

4. Create a new file, add it to the staging area and commit it using the commands you have learnt.
5. Switch back to the master branch
Command: $ git checkout master or $ git switch master

6. List the files (including hidden ones) in the directory using the ls command. Notice that we only
see .gitignore , Makefile , test and test.c . This is because the change we made was in
the other branch named ‘new-feature’.
When we have finished developing the feature, we will want to bring those changes into the master
branch. We do that using the git merge command
Command: $ git merge new-feature
This command brings in the changes in the ‘new-feature’ branch to the currently active branch.
For this reason it is important to be sure of what the current branch is.
7. List the files in the directory using ls . Notice that the file you created in the ‘new-feature’ branch
is now available in the master branch.
8. This merge was an example of a merge without ‘merge-conflicts’. A merge-conflict occurs when the
same line has changed in both branches.
Information on resolving merge-conflicts, and on the idea of branches as pointers to commits is avail-
able at https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging

13 Tags
Git is a Version Control System. It allows the labelling of different versions of code (e.g. like in software
versions such as Microsoft Word 16.0.8730.2175)

You can add a tag to a commit using


$ git tag -a v0.15 -m "Release version 15"

The -a parameter is the tag label or ‘annotation’. The -m argument allows the addition a message to
the tag.

Tags in Git need to be explicitly pushed. You can push a single tag using $ git push origin v0.15 ,
or all created tags using $ git push --tags .
9 Git’s lightweight branching capabilities are often called its ‘killer feature’
10 This is a shorthand for the commands git branch and git checkout

Downloaded by Lucien Lu (llucien7789@gmail.com)


lOMoARcPSD|11775577

14 Resources
Git is complex and feature-rich; we have only just scratched the surface of its capabilities in this short
hour. The resources below will help you learn more.
• https://git-scm.com/book/en/v2
A canonical reference. Authoritative and extremely well written.
• http://eagain.net/articles/git-for-computer-scientists/
In the author’s own words: ‘Quick introduction to git internals for people who are not scared by
words like Directed Acyclic Graph.’

• https://www.youtube.com/watch?v=4XpnKHJAok8
Straight from the horse’s mouth. Linus Torvalds on Git.
• http://gitolite.com/uses-of-index.html
Why the index/staging area is so useful
Git is very widely used, which means there is an abundance of resources on the Internet. Happy learning!

Downloaded by Lucien Lu (llucien7789@gmail.com)


lOMoARcPSD|11775577

School of Computing and Information Systems


COMP30023: Computer Systems

Practical Week 2
1 Introduction
Git is a distributed version control system originally developed by Linus Torvalds to maintain Linux kernel
code. It is now widely used in all kinds of projects to track changes in files and enable collaboration
among developers. This lab will serve as a brief introduction to Git so that you can start using it to
manage code in your own projects.

2 COMP30023 Gitlab Access


Please first complete the Gitlab Access assignment https://canvas.lms.unimelb.edu.au/courses/
107590/assignments/205171, to gain access to your assignment/project submission repositories.
Do not wait for the automated program to grant you access (it runs half-hourly and only supplies
access to project repositories). Instead, you should continue with the activities below with your https:
//gitlab.eng.unimelb.edu.au account.

3 Installing new packages


While Ubuntu Server (the Linux distribution that we’re using) comes with some standard packages1 (e.g.
coreutils2 ), not all the commands and tools that we’re going to use in this subject is preinstalled.
We can use Ubuntu’s default package manager to install new software.
Install new package(s) with $ sudo apt install <package-name> <package-name> ... 3

Let’s install gcc, make, and git, which will be required to complete the projects.
Confirm correct installation of git and the gcc compiler.
Command: $ gcc --version , $ git --version

4 Introducing Yourself to Git


Before we start using Git, we need to setup our name and email. Note that this is just for identification
purposes, and not to log in to any system. This process will need to be repeated on each user account
on which you want to use git.

Command: $ git config --global user.name "Your Name"


Command: $ git config --global user.email "yourusername@student.unimelb.edu.au" 4

Now that Git knows who we are, let’s create our first repository.
1 http://releases.ubuntu.com/20.04/ubuntu-20.04.2.0-desktop-amd64.manifest
2 https://en.wikipedia.org/wiki/List_of_GNU_Core_Utilities_commands
3 You may need to run $ sudo apt update first
4 The --global option means that Git will use these values for every Git project the current user creates. The values
are written to ~/.gitconfig

Downloaded by Lucien Lu (llucien7789@gmail.com)


lOMoARcPSD|11775577

5 Creating a Git Project


Git projects are more commonly known as Git repositories. Let’s initialise a repository.

1. Create a new directory. Let’s call it git-repo-1 .

2. Navigate into the newly created directory.

3. Initialise a repository in this directory. Command: $ git init


This will create a new (hidden)5 directory named .git in the git-repo-1 directory. This
directory will contain all version information related to this repository.

Sample solutions will be released at the end of the week.


Ask your classnames and demonstrator for help during practical classes.

6 Adding Files to Git


A file can exist in three stages in a Git repository: Working, Staging and Commit 6 .

• Any changes not explicitly added to the Staging area reside in the Working Directory.

• Changes can be added to the Staging Area (also known as Index) using the git add command.
This marks the changes that should go into the next commit
• The git commit command adds the marked changes from the step above to the (local) repository.

Figure 17 shows the flow of operations:

Figure 1: Flow of operations

Let’s see this in practice:


1. Create an empty file named test.c with the touch command.
Command: $ touch test.c

2. This file is now in the working directory and untracked by Git. Run the git status command
to see this.
Command: $ git status

3. Add some content to the file to make it compilable, using nano , vim , echo etc.
e.g. the line void main(){} in test.c .

5 You can use the command ls -a to view the directory.


6 You can also stage parts of a file, which is unique to Git and a main reason for the intermediate Staging step
7 Source: https://git-scm.com/about/staging-area

Downloaded by Lucien Lu (llucien7789@gmail.com)


lOMoARcPSD|11775577

Brief instructions for nano :


$ nano test.c , type in text, ctrl-x, letter y, enter key.

Brief instructions for vim :


$ vim test.c , letter i to enter insert mode, type in text, escape key to exit insert mode and back
to normal mode, :x, Enter to save.
4. Add this file to the staging area.
Command: $ git add test.c

5. View the status of the repository now using the git status command again. Notice that the
test.c file is now listed under ‘Changes to be committed’.
6. If you have modified multiple files and want to add all of them to the staging area at once, you can
use the git add . command.

7 Committing Changes
Now that we have added our changes to the staging area (i.e. marked the changes we want to commit),
let’s commit the changes.
Committing the changes stores a snapshot of the current state of the files. This allows you to roll back
to this version if needed in the future. Note that this snapshot is stored locally on your machine.
1. Command: $ git commit -m "Created test.c with main()"
Every commit needs to be accompanied by a commit message, which is what we specified using
the -m parameter.
2. Inspect the current status of the repository using git status .

You can also combine the add and commit steps in one operation using the
git commit --all -m "commit message" command.
Note that this combined operation only commits changes to files added earlier, and does not commit
new files.

8 .gitignore
Now that we have made our first commit, let’s compile test.c with gcc.
1. Write a Makefile to compile test.c with gcc to an executable named test .
Discuss with your classnames, demonstrator if you have forgotten how to do so. Solutions will be
released at the end of the week.
2. Execute $ make .
3. Verify that compilation was successful (i.e. does test exist? is test executable?).
4. Execute $ git status again. Both Makefile and test should be unstaged at this point.
5. We shouldn’t stage and commit test, as it is a binary file which is machine architecture depen-
dent and can be reproduced any time that we run make. By committing it, we are bloating our
repositories with different versions of test. When repositories are then pushed to servers, all of
these rubbish files will have to be uploaded!
While it is possible to selectively choose files to stage and commit them (e.g. $ git add Makefile ),
the convenience of using $ git add . is lost. This is the purpose of the .gitignore file, which
can be used to specify (in separate lines) the file(s) and director(ies) which should be ignored by git.

Let’s create a .gitignore file with a line:


test
This tells git to ignore files named test.

Downloaded by Lucien Lu (llucien7789@gmail.com)


lOMoARcPSD|11775577

6. Check $ git status again. Once you’re happy, stage Makefile and .gitignore simultane-
ously and commit the changes, giving the commit an appropriate message.

7. Use the $ git log command to view the history of commits you have made.

Note: you are expected to follow good version control practices (sensible commit messages, no useless
executables etc.) for project repositories. More on this in the project specifications.

9 Setting up GitLab
It is common practice in teams to have a Git server that everyone push es their code to.
Github and Gitlab are examples of publicly-available hosting services. We will be using Gitlab, open
source software that is hosted on the servers of the Faculty of Engineering and IT.

Login to https://gitlab.eng.unimelb.edu.au.
Click ‘Create a Project’ and create a project named comp30023-practical-2 . Set the visibility level
to ‘Private’.

10 Pushing Changes
Note that every git operation up to now has been done locally. That is, our changes to the files have
not been sent to a remote server.

1. For this, we need to tell Git which external repository (remote) we want to link our local repository
to.
Command:
8
$ git remote add origin https://gitlab.eng.unimelb.edu.au/husernamei/comp30023-practical-2.git

You can check the URLs using git remote -v and where necessary, amend it using
git remote set-url origin <new-url> .

2. Push your changes to the server by using the git push command.
Command: $ git push -u origin master
After this first push you can push changes by simply using the command git push

You do not need to push after every commit.


It is appropriate to push after every major change (e.g. a new feature, a bug fix, some refactoring etc.)

11 Cloning
It is common to join a team with an ongoing project which does source code management using Git. We
use the git clone command to get a copy of existing code stored on an external Git server.

1. Run this command from a directory outside the Git repository we have been working in
Command:
$ git clone https://gitlab.eng.unimelb.edu.au/husernamei/comp30023-practical-2.git

2. Note that a new directory has been created with the name comp30023-practical-2 . Browse
to this directory, view files. Use the git status and git log commands to note that the full
history of the repository has been downloaded.
8 We are setting an alias named origin to the URL so that we don’t have to type the entire remote URL each time we
do a push

Downloaded by Lucien Lu (llucien7789@gmail.com)


lOMoARcPSD|11775577

12 Branches
Git allows you to organise code in branches.9 For example, you might create a new branch for a new
feature of your application. You can then keep continued development on the core of the application
(e.g. bug fixes) separate from the new feature development.

Note: The use of gitk , if available, can be very helpful when dealing with multiple branches.

1. The default branch in Git is named ‘master’. Use the git branch command to list the current
branches.
Command: $ git branch
The currently active branch is shown with an asterisk.
2. The most common way to create a new branch in Git is to create a new branch and switch to it in
the same command10 . Let’s create a new branch named ‘new-feature’.
Command: $ git checkout -b new-feature or $ git switch -c new-feature

3. Run the git branch command again. Notice the newly created branch is currently active.

4. Create a new file, add it to the staging area and commit it using the commands you have learnt.
5. Switch back to the master branch
Command: $ git checkout master or $ git switch master

6. List the files (including hidden ones) in the directory using the ls command. Notice that we only
see .gitignore , Makefile , test and test.c . This is because the change we made was in
the other branch named ‘new-feature’.
When we have finished developing the feature, we will want to bring those changes into the master
branch. We do that using the git merge command
Command: $ git merge new-feature
This command brings in the changes in the ‘new-feature’ branch to the currently active branch.
For this reason it is important to be sure of what the current branch is.
7. List the files in the directory using ls . Notice that the file you created in the ‘new-feature’ branch
is now available in the master branch.
8. This merge was an example of a merge without ‘merge-conflicts’. A merge-conflict occurs when the
same line has changed in both branches.
Information on resolving merge-conflicts, and on the idea of branches as pointers to commits is avail-
able at https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging

13 Tags
Git is a Version Control System. It allows the labelling of different versions of code (e.g. like in software
versions such as Microsoft Word 16.0.8730.2175)

You can add a tag to a commit using


$ git tag -a v0.15 -m "Release version 15"

The -a parameter is the tag label or ‘annotation’. The -m argument allows the addition a message to
the tag.

Tags in Git need to be explicitly pushed. You can push a single tag using $ git push origin v0.15 ,
or all created tags using $ git push --tags .
9 Git’s lightweight branching capabilities are often called its ‘killer feature’
10 This is a shorthand for the commands git branch and git checkout

Downloaded by Lucien Lu (llucien7789@gmail.com)


lOMoARcPSD|11775577

14 Resources
Git is complex and feature-rich; we have only just scratched the surface of its capabilities in this short
hour. The resources below will help you learn more.
• https://git-scm.com/book/en/v2
A canonical reference. Authoritative and extremely well written.
• http://eagain.net/articles/git-for-computer-scientists/
In the author’s own words: ‘Quick introduction to git internals for people who are not scared by
words like Directed Acyclic Graph.’

• https://www.youtube.com/watch?v=4XpnKHJAok8
Straight from the horse’s mouth. Linus Torvalds on Git.
• http://gitolite.com/uses-of-index.html
Why the index/staging area is so useful
Git is very widely used, which means there is an abundance of resources on the Internet. Happy learning!

Downloaded by Lucien Lu (llucien7789@gmail.com)


lOMoARcPSD|11775577

A Sample solutions
A.5
5.1: $ mkdir git-repo-1
5.2: $ cd git-repo-1

A.6
6.3: Use a CLI editor, or simply $ echo "..." > test.c

A.8
8.1

test: test.c
gcc -o test test.c
With tab as indentation.

8.3: $ ls test , or perhaps $ stat test etc., then $ ./test

8.4:
Untracked files:
(use "git add <file>..." to include in what will be committed)
.gitignore
test
8.5: echo "test" > .gitignore
8.6: git add . && git commit -m "Add Makefile, ignore test executable"

Downloaded by Lucien Lu (llucien7789@gmail.com)


lOMoARcPSD|11775577

School of Computing and Information Systems


COMP30023: Computer Systems

Practical Week 3
1 Introduction
In this practical, we will be exploring threads, processes and interprocess communication.
NOTE: You can do this lab without following the order.

2 Creating a Thread
The main() function of a C program runs on its own thread (commonly called the ‘main’ thread)
We can create additional, independent threads by using the pthread_create function provided by pthread.h .
thread1.c on the LMS creates such a thread. The thread runs the function say_hello() upon creation.

1. Compile and run thread1.c . Note the use of the -lpthread option to explicitly link the pthread library
Command: $ gcc thread1.c -o thread1 -lpthread && ./thread1

2. Notice how the second thread said hello before the first thread? This is because the pthread_join
function will wait for the thread specified in the function call to finish executing before proceeding with
the current thread.
In this scenario the main thread ‘waited’ for the other thread to ‘join’ it before proceeding.
3. Can you guess what might happen if we did not call the pthread_join function? Comment that line in
the code, compile and rerun to observe the output.
Discuss with your classmates (or demonstrator) if you are unable to understand the behaviour you observe.
4. Do you think these threads are user or kernel threads?

3 Threads and Race Conditions


Race conditions, where the final result of a computation depends on the order in which threads happened to
run, may occur when several threads access a shared resource.

1. The code thread2.c given on the LMS has two threads accessing the common global variable count .
This code has a race condition.
Run the code several times and observe that the output changes each time.
2. We can solve race conditions such as these by defining a section of code that can only be executed by one
thread at a time (called a ‘critical section’ or ‘critical region‘).
We can use a mutex to define a critical section. The methods pthread_mutex_lock(&lock) and
pthread_mutex_unlock(&lock) can be used to define a critical section, where lock is a global variable
that is of type pthread_mutex_t .

3. The definition, initialisation, and destroying of the mutex have been written for you in thread2.c . De-
termine the critical section that would prevent the race condition and use the function calls to lock and
unlock the mutex to fix the race condition.

pthread_mutex_lock(&lock)
/* Code in Critical Section */
pthread_mutex_unlock(&lock)

4. Challenge task: try to introduce a deadlock into your program.

1
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

4 OS Processes
4.1 fork
fork() creates a new process by duplicating the calling process. The new process is referred to as the child
process. The calling process is referred to as the parent process.
The child process and the parent process run in separate memory spaces. At the time of fork() both memory
spaces have the same content.

First, compile the demo fork program (see Appendix):


$ gcc -o fork fork.c

Run the program in the background.


$ ./fork &

While the program runs in background, run top in tree mode to watch how child processes are spawned from
the parent process.
$ top
While top is running, push Shift + V to enable forrest view1 . Find the fork program and watch how child
processes get spawned.

4.2 exec
Taken from the manpages verbatim:
The exec family of functions shall replace the current process image with a new process image. The new image
shall be constructed from a regular, executable file called the new process image file. There shall be no return
from a successful exec, because the calling process image is overlaid by the new process image.
First, compile the demo exec program:

$ gcc -o exec exec.c

Run the program.


$ ./exec

What program does it actually exec into? Discuss with your classmate and demonstrator.

4.3 pipe
The pipe() function shall create a pipe and place two file descriptors, one each into the arguments fildes[0] and
fildes[1], that refer to the open file descriptions for the read and write ends of the pipe. Their integer values
shall be the two lowest available at the time of the pipe() call.
First, compile the demo pipe program:

$ gcc -o pipe pipe.c

Run the program.


$ ./pipe

You now have a brief idea how exec, fork and pipe works. You are encouraged to author a simple C program
that can utilise all 3 libc functions. An idea would be to author a program that forks a new process and waits
for input from the parent process (via stdin) to print from the child process. For example, try simulating
execution of $ ls *.c | wc -l.

1 This view shows parent-child relationships between processes

2
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

A thread1.c
/*************************************
Demo for pthread commands
compile: gcc threadX.c -o threadX -lpthread
***************************************/

#include <pthread.h>
#include <stdio.h>

void* say_hello(void* param); /* the work_function */

int main(int args, char** argv) {


pthread_t tid; /* thread identifier */

/* create the thread */


pthread_create(&tid, NULL, say_hello, NULL);

/* wait for thread to exit */


pthread_join(tid, NULL);

printf("Hello from first thread\n");


return 0;
}

void* say_hello(void* param) {


printf("Hello from second thread\n");
return NULL;
}

B thread2.c
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define ITERATIONS 1000000

void* runner(void* param); /* thread doing the work */

int count = 0;
pthread_mutex_t lock;

int main(int argc, char** argv) {


pthread_t tid1, tid2;
int value;

if (pthread_mutex_init(&lock, NULL) != 0) {
printf("mutex init failed\n");
exit(1);
}

if (pthread_create(&tid1, NULL, runner, NULL)) {


printf("Error creating thread 1\n");
exit(1);
}
if (pthread_create(&tid2, NULL, runner, NULL)) {
printf("Error creating thread 2\n");
exit(1);

3
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

/* wait for the threads to finish */


if (pthread_join(tid1, NULL)) {
printf("Error joining thread\n");
exit(1);
}
if (pthread_join(tid2, NULL)) {
printf("Error joining thread\n");
exit(1);
}

if (count != 2 * ITERATIONS)
printf("** ERROR ** count is [%d], should be %d\n", count, 2 * ITERATIONS);
else
printf("OK! count is [%d]\n", count);

pthread_exit(NULL);
pthread_mutex_destroy(&lock);
}

/* thread doing the work */


void* runner(void* param) {
int i, temp;
for (i = 0; i < ITERATIONS; i++) {
temp = count; /* copy the global count locally */
temp = temp + 1; /* increment the local copy */
count = temp; /* store the local value into the global count */
}
}

C fork.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char** argv) {


pid_t root = getpid();
// when forking, program does not start again since memory/register values are exactly the same
// i.e. instruction pointer is at the same line too. So fork() wont execute again.
pid_t pid = fork();
printf("from %d forking into %d\n", root, pid);
sleep(20);

// watch 2 different PIDs spawn 2 more child processes.


pid_t mypid = getpid();
pid = fork();
printf("from %d forking into %d\n", mypid, pid);
sleep(20);

if (getpid() == root) {
sleep(20);
printf("root exiting\n");
} else {
printf("Child -- PID %d exiting\n", getpid());
}
return 0;
}

4
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

D exec.c
#include<unistd.h>

int main(int argc, char **argv) {


return execv("/usr/bin/ls", argv);
}

E pipe.c
/*****************************************************************************
Excerpt from "Linux Programmer's Guide - Chapter 6"
(C)opyright 1994-1995, Scott Burkett
*****************************************************************************
MODULE: pipe.c
*****************************************************************************/

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(void) {
int fd[2], nbytes;
pid_t childpid;
char string[] = "Hello, world!\n";
char readbuffer[80];

pipe(fd);

if ((childpid = fork()) == -1) {


perror("fork");
exit(1);
}

if (childpid == 0) {
/* Child process closes up input side of pipe */
close(fd[0]);

/* Send "string" through the output side of pipe */


write(fd[1], string, (strlen(string) + 1));
exit(0);
} else {
/* Parent process closes up output side of pipe */
close(fd[1]);

/* Read in a string from the pipe */


nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
printf("Received string: %s", readbuffer);
}

return (0);
}

5
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

School of Computing and Information Systems


COMP30023: Computer Systems

Practical Week 3
1 Introduction
In this practical, we will be exploring threads, processes and interprocess communication.
NOTE: You can do this lab without following the order.

2 Creating a Thread
The main() function of a C program runs on its own thread (commonly called the ‘main’ thread)
We can create additional, independent threads by using the pthread_create function provided by pthread.h .
thread1.c on the LMS creates such a thread. The thread runs the function say_hello() upon creation.

1. Compile and run thread1.c . Note the use of the -lpthread option to explicitly link the pthread library
Command: $ gcc thread1.c -o thread1 -lpthread && ./thread1

2. Notice how the second thread said hello before the first thread? This is because the pthread_join
function will wait for the thread specified in the function call to finish executing before proceeding with
the current thread.
In this scenario the main thread ‘waited’ for the other thread to ‘join’ it before proceeding.
3. Can you guess what might happen if we did not call the pthread_join function? Comment that line in
the code, compile and rerun to observe the output.
Discuss with your classmates (or demonstrator) if you are unable to understand the behaviour you observe.
4. Do you think these threads are user or kernel threads?

3 Threads and Race Conditions


Race conditions, where the final result of a computation depends on the order in which threads happened to
run, may occur when several threads access a shared resource.

1. The code thread2.c given on the LMS has two threads accessing the common global variable count .
This code has a race condition.
Run the code several times and observe that the output changes each time.
2. We can solve race conditions such as these by defining a section of code that can only be executed by one
thread at a time (called a ‘critical section’ or ‘critical region‘).
We can use a mutex to define a critical section. The methods pthread_mutex_lock(&lock) and
pthread_mutex_unlock(&lock) can be used to define a critical section, where lock is a global variable
that is of type pthread_mutex_t .

3. The definition, initialisation, and destroying of the mutex have been written for you in thread2.c . De-
termine the critical section that would prevent the race condition and use the function calls to lock and
unlock the mutex to fix the race condition.

pthread_mutex_lock(&lock)
/* Code in Critical Section */
pthread_mutex_unlock(&lock)

4. Challenge task: try to introduce a deadlock into your program.

1
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

4 OS Processes
4.1 fork
fork() creates a new process by duplicating the calling process. The new process is referred to as the child
process. The calling process is referred to as the parent process.
The child process and the parent process run in separate memory spaces. At the time of fork() both memory
spaces have the same content.

First, compile the demo fork program (see Appendix):


$ gcc -o fork fork.c

Run the program in the background.


$ ./fork &

While the program runs in background, run top in tree mode to watch how child processes are spawned from
the parent process.
$ top
While top is running, push Shift + V to enable forrest view1 . Find the fork program and watch how child
processes get spawned.

4.2 exec
Taken from the manpages verbatim:
The exec family of functions shall replace the current process image with a new process image. The new image
shall be constructed from a regular, executable file called the new process image file. There shall be no return
from a successful exec, because the calling process image is overlaid by the new process image.
First, compile the demo exec program:

$ gcc -o exec exec.c

Run the program.


$ ./exec

What program does it actually exec into? Discuss with your classmate and demonstrator.

4.3 pipe
The pipe() function shall create a pipe and place two file descriptors, one each into the arguments fildes[0] and
fildes[1], that refer to the open file descriptions for the read and write ends of the pipe. Their integer values
shall be the two lowest available at the time of the pipe() call.
First, compile the demo pipe program:

$ gcc -o pipe pipe.c

Run the program.


$ ./pipe

You now have a brief idea how exec, fork and pipe works. You are encouraged to author a simple C program
that can utilise all 3 libc functions. An idea would be to author a program that forks a new process and waits
for input from the parent process (via stdin) to print from the child process. For example, try simulating
execution of $ ls *.c | wc -l.

1 This view shows parent-child relationships between processes

2
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

A thread1.c
/*************************************
Demo for pthread commands
compile: gcc threadX.c -o threadX -lpthread
***************************************/

#include <pthread.h>
#include <stdio.h>

void* say_hello(void* param); /* the work_function */

int main(int args, char** argv) {


pthread_t tid; /* thread identifier */

/* create the thread */


pthread_create(&tid, NULL, say_hello, NULL);

/* wait for thread to exit */


pthread_join(tid, NULL);

printf("Hello from first thread\n");


return 0;
}

void* say_hello(void* param) {


printf("Hello from second thread\n");
return NULL;
}

B thread2.c
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define ITERATIONS 1000000

void* runner(void* param); /* thread doing the work */

int count = 0;
pthread_mutex_t lock;

int main(int argc, char** argv) {


pthread_t tid1, tid2;

if (pthread_mutex_init(&lock, NULL) != 0) {
printf("mutex init failed\n");
exit(1);
}

if (pthread_create(&tid1, NULL, runner, NULL)) {


printf("Error creating thread 1\n");
exit(1);
}
if (pthread_create(&tid2, NULL, runner, NULL)) {
printf("Error creating thread 2\n");
exit(1);
}

3
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

/* wait for the threads to finish */


if (pthread_join(tid1, NULL)) {
printf("Error joining thread\n");
exit(1);
}
if (pthread_join(tid2, NULL)) {
printf("Error joining thread\n");
exit(1);
}

if (count != 2 * ITERATIONS)
printf("** ERROR ** count is [%d], should be %d\n", count, 2 * ITERATIONS);
else
printf("OK! count is [%d]\n", count);

pthread_exit(NULL);
pthread_mutex_destroy(&lock);
return 0;
}

/* thread doing the work */


void* runner(void* param) {
int i, temp;
for (i = 0; i < ITERATIONS; i++) {
temp = count; /* copy the global count locally */
temp = temp + 1; /* increment the local copy */
count = temp; /* store the local value into the global count */
}
return NULL;
}

C fork.c
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>

int main(int argc, char** argv) {


pid_t root = getpid();
// when forking, program does not start again since memory/register values are exactly the same
// i.e. instruction pointer is at the same line too. So fork() wont execute again.
pid_t pid = fork();
printf("from %d forking into %d\n", root, pid);
sleep(20);

// watch 2 different PIDs spawn 2 more child processes.


pid_t mypid = getpid();
pid = fork();
printf("from %d forking into %d\n", mypid, pid);
sleep(20);

if (getpid() == root) {
sleep(20);
printf("root exiting\n");
} else {
printf("Child -- PID %d exiting\n", getpid());
}
return 0;
}

4
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

D exec.c
#include<unistd.h>

int main(int argc, char **argv) {


return execv("/usr/bin/ls", argv);
}

E pipe.c
/*****************************************************************************
Excerpt from "Linux Programmer's Guide - Chapter 6"
(C)opyright 1994-1995, Scott Burkett
*****************************************************************************
MODULE: pipe.c
*****************************************************************************/

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>

int main(void) {
int fd[2], nbytes;
pid_t childpid;
char string[] = "Hello, world!\n";
char readbuffer[80];

pipe(fd);

if ((childpid = fork()) == -1) {


perror("fork");
exit(1);
}

if (childpid == 0) {
/* Child process closes up input side of pipe */
close(fd[0]);

/* Send "string" through the output side of pipe */


write(fd[1], string, (strlen(string) + 1));
exit(0);
} else {
/* Parent process closes up output side of pipe */
close(fd[1]);

/* Read in a string from the pipe */


nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
printf("Received string: %s", readbuffer);
}

return (0);
}

5
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

Sample solutions
2
A couple of (observed) possibilities:
$ ./thread1
Hello from first thread
$ ./thread1
Hello from first thread
Hello from second thread
$ ./thread1
Hello from first thread
Hello from second thread
Hello from second thread
In the first case, the main thread returns and terminates the process before the completion of printf.
In the second case, the printf happens before the process is terminated.
In the third case, why does the second thread print twice? https://stackoverflow.com/questions/13550662

You will probably not encounter the second and third cases unless you’re on a multi-core system (note that the
allocated VMs are single-core).

What if we want the main thread to exit but allow the second thread to run to completion?
We can replace pthread_join with pthread_exit.
pthread_exit terminates the calling thread (the main thread).
When the last thread in the process terminates, exit(3) is called with an exit status code of zero (terminating
the process).
See: $ man 3 pthread_exit

pthreads is an API, defined in the POSIX standard.


Whether user-level threads or kernel-level threads are used is implementation specific.
The Linux implementation of pthreads use kernel-level threads23 .
It is also possible to create threads using the clone system call in Linux (see TB 10.3.3).

3
Why can’t I put the locks around pthread_create, pthread_join?
The main thread will obtain lock, call pthread function, then unlock.
This does not solve the problem because the code which contains the race condition is not executed by the main
thread.

What is the race condition?


Access/modification of global variable count.
For example:
1. Thread A copies count to temp. It is interrupted.
2. Thread B gets a chance to run and it copies count to temp, increments temp and saves it back.
3. Thread A resumes at some point, it increments temp (which is outdated) and saves it to count.
4. count is now lower than it should be.
Solution: Put lock/unlock statements immediately outside the loop.
Why not put the locks inside? Because of performance overheads in locking/unlocking.

However, consider scenario:


for each loop iteration
perform long task which is independent
critical section to update some global variable
Then it may be worthwhile to surround the critical section with the lock instead.
2 https://stackoverflow.com/questions/8639150
3 https://stackoverflow.com/questions/10392800

6
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

Challenge
Taking inspiration from lecture slides:
void* runner(void* param) {
for (int i = 0; i < 10000; i++) {
pthread_mutex_lock(&lock1);
printf("thread 1 lock 1\n");
pthread_mutex_lock(&lock2);
printf("thread 1 lock 2\n");
// do work
pthread_mutex_unlock(&lock1);
pthread_mutex_unlock(&lock2);
}
}
void* runner2(void* param) {
for (int i = 0; i < 10000; i++) {
pthread_mutex_lock(&lock2);
printf("thread 2 lock 2\n");
pthread_mutex_lock(&lock1);
printf("thread 2 lock 1\n");
// do work
pthread_mutex_unlock(&lock2);
pthread_mutex_unlock(&lock1);
}
}

7
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

4
Example execution of fork.c:
./fork (pid 1150653)
pid_t root = getpid(); root = 1150653
pid_t pid = fork();
printf("from %d forking into %d\n", root, pid);

./fork (pid 1150653)


|_ ./fork (pid 1150654)
from 1150653 forking into 1150654 parent process gets child process's pid for fork
from 1150653 forking into 0 child process gets 0 as return value for fork

pid_t mypid = getpid();


pid = fork();
printf("from %d forking into %d\n", mypid, pid);
./fork (pid 1150653)
|_ ./fork (pid 1150654)
|_ ./fork (pid 1150684)
|_ ./fork (pid 1150683)
from 1150653 forking into 1150683
fork 1150654 forking into 1150684
from 1150653 forking into 0
from 1150654 forking into 0

if (getpid() != root)
printf("Child -- PID %d exiting\n", getpid());
Child -- PID 1150654 exiting
Child -- PID 1150683 exiting
Child -- PID 1150684 exiting
./fork (pid 1150653)
|_ ./fork (pid 1150654 - Zombie)
|_ ./fork (pid 1150683 - Zombie)

printf("root exiting\n");

Why do I still see the child processes after they have exited?
They are zombie processes: see https://stackoverflow.com/questions/4825379.

8
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

/*****************************************************************************
ls *.c | wc -l
Adapted from pipe.c
Excerpt from "Linux Programmer’s Guide - Chapter 6"
(C)opyright 1994-1995, Scott Burkett
*****************************************************************************/

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <glob.h>

int main(int argc, char* argv[]) {


int fd[2];
pid_t childpid;
pipe(fd);
if((childpid = fork()) == -1) {
perror("fork");
exit(1);
}
if(childpid == 0) {
/* Child process closes up input side of pipe */
close(fd[0]);
/* redirect stdout, https://stackoverflow.com/questions/1720535 */
dup2(fd[1], STDOUT_FILENO);

/* glob for *.c, https://stackoverflow.com/questions/53686987 */


glob_t globbuf;
globbuf.gl_offs = 1;
glob("*.c", GLOB_DOOFFS, NULL, &globbuf);
globbuf.gl_pathv[0] = "ls";
execv("/usr/bin/ls", globbuf.gl_pathv);
} else {
/* Parent process closes up output side of pipe */
close(fd[1]);
/* redirect stdin */
dup2(fd[0], STDIN_FILENO);
char* args[] = { "wc", "-l", NULL };
execv("/usr/bin/wc", args);
}
return 0;
}

9
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

School of Computing and Information Systems


COMP30023: Computer Systems

Practical Week 4

1 Spatial & Temporal Locality


The principle of spatial locality says that if a program accesses one memory address, there is
a good chance that it will also access other nearby addresses. CPU caches take advantage of
this by reading in cache lines from physical memory and reading from the CPU cache is order
of magnitudes faster than actually reading from Physical RAM1 .
Write two programs, fast.c and slow.c, which access or modify a two dimensional array in
a way that is fast (exhibits spatial locality) and slow (does not exhibit spatial locality) respec-
tively.
Ensure that fast takes at least 0.3 seconds to run.

You may want to use the time command, e.g. $ time ./slow , to measure the time it takes
for a program to finish.

The principle of temporal locality states says that if a program accesses one memory address,
there is a good chance it will access the same memory address again.
Write another pair of programs, fast-temp.c and slow-temp.c, which access or modify a one
dimensional array in a way that is fast (exhibits temporal locality) and slow respectively.

Sample solutions will be later released.


1 https://gist.github.com/jboner/2841832

Downloaded by Lucien Lu (llucien7789@gmail.com)


lOMoARcPSD|11775577

School of Computing and Information Systems


COMP30023: Computer Systems

Practical Week 4

1 Spatial & Temporal Locality


The principle of spatial locality says that if a program accesses one memory address, there is
a good chance that it will also access other nearby addresses. CPU caches take advantage of
this by reading in cache lines from physical memory and reading from the CPU cache is order
of magnitudes faster than actually reading from Physical RAM1 .
Write two programs, fast.c and slow.c, which access or modify a two dimensional array in
a way that is fast (exhibits spatial locality) and slow (does not exhibit spatial locality) respec-
tively.
Ensure that fast takes at least 0.3 seconds to run.

You may want to use the time command, e.g. $ time ./slow , to measure the time it takes
for a program to finish.

The principle of temporal locality states says that if a program accesses one memory address,
there is a good chance it will access the same memory address again.
Write another pair of programs, fast-temp.c and slow-temp.c, which access or modify a one
dimensional array in a way that is fast (exhibits temporal locality) and slow respectively.

Sample solutions will be later released.


1 https://gist.github.com/jboner/2841832

Downloaded by Lucien Lu (llucien7789@gmail.com)


lOMoARcPSD|11775577

A fast.c
#define BIG 10000
int big[BIG][BIG];
int main(void) {
for (int i = 0; i < BIG; i++) {
for (int j = 0; j < BIG; j++) {
big[i][j] = 0;
}
}
return 0;
}

B slow.c
#define BIG 10000
int big[BIG][BIG];
int main(void) {
for (int i = 0; i < BIG; i++) {
for (int j = 0; j < BIG; j++) {
big[j][i] = 0;
}
}
return 0;
}

C fast-temp.c
int arr[16777216];
int main(void) {
unsigned long long cur;
int index[] = {1, 25, 168, 1229, 9592, 78498, 128, 2048, 65536, 99999};
for (long iter = 0; iter < 10000000; iter++) {
for (int i = 0; i < 10; i++) {
cur = (index[i] * 8121 + 28411) % 16777216;
arr[cur] += 1;
}
}
return 0;
}

D slow-temp.c
int arr[16777216];
int main(void) {
unsigned long long cur = 0;
for (long iter = 0; iter < 10000000; iter++) {
for (int i = 0; i < 10; i++) {
cur = (cur * 8121 + 28411) % 16777216;
arr[cur] += 1;
}
}
return 0;
}

Downloaded by Lucien Lu (llucien7789@gmail.com)


lOMoARcPSD|11775577

School of Computing and Information Systems


COMP30023: Computer Systems

Practical Week 5

1 Introduction
In this workshop, we’ll be looking at key generation, encryption, decryption and generating message digests using
the SHA256 hashing algorithm.
As mentioned in the lectures, it is uncommon to encrypt messages directly using asymmetric cryptography. What
we do instead is:
1. First exchange a symmetric key securely (we will use asymmetric key cryptography for this step)
2. Use this exchanged symmetric key for encrypting the actual messages
In this lab we will follow this process step by step using the openssl tool. This lab is best completed with a partner.

2 Asymmetric Encryption
2.1 Generating RSA Keys
We will first create public and private RSA keys using openssl
1. Generate a private key using 2048 bit RSA.
$ openssl genpkey -algorithm RSA -out rsa-private.pem -pkeyopt rsa_keygen_bits:2048
2. View the private key file contents.
$ cat rsa-private.pem
3. Output the corresponding RSA public key.
$ openssl rsa -pubout -in rsa-private.pem -out rsa-public.pem
4. View the public key file contents.
$ cat rsa-public.pem

5. Share your public key with a friend (e.g. email it to them).

3 Symmetric Encryption
3.1 Generating a secret key
To participate in any encryption/decryption scheme, we must first generate a secret key.
1. Create a 256 bit CBC mode AES key (this is a symmetric key).
$ openssl enc -aes-256-cbc -k secret -P -md sha1
2. Save the string listed as ‘key’ to a file named key.txt.
3. You may want to save the initialisation vector (iv) shown to be used when encrypting your message later.
However, remember that initialisation vectors need to be random and not reused. They however do not need
to be kept secret.

1
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

3.2 Exchanging the secret key


Let’s encrypt the symmetric key using RSA, such that our friend can receive a copy of the secret key.

1. Encrypt the symmetric key you generated above using your friend’s public key.
The idea is that only your friend can decrypt the ciphertext containing the secret key (since only they should
have access to their private key file).
$ openssl rsautl -encrypt -in key.txt -pubin -inkey friend-public.pem > aes-encrypted-rsa.dat

2. View the encrypted AES key - the bytes should look like gibberish.
$ xxd aes-encrypted-rsa.dat

3. Email the encrypted AES key to your friend. They should be able to decrypt the key using their private RSA
key. Try to determine the command to decrypt (if you are stuck - see1 ).

3.3 Encryption
Using the material generated above, we can now encrypt our messages.

1. Create a file message.txt with an interesting message.

2. You may want to use the command $ openssl rand -hex 96 > iv.txt to generate a new IV.

3. Encrypt the file using the AES symmetric key. The command will be something like
$ openssl enc -aes-256-cbc -in message.txt -out ciphertext.enc -K $(cat key.txt) -iv $(cat iv.txt)

4. Send this ciphertext and the IV to your friend.


5. As a challenge, you are now tasked to figure out how to do decryption using the shared secret key (which you
should have obtained in 3.2) and the AES encrypted message (which your friend just sent you).
Hint: $ man openssl enc

4 SHA256 Message Digests


In this section, we create SHA256 message digests to commit messages. To verify the commitment, it is necessary
for an adversary/verifier to reveal the message and hash it to check if the digest is equal to the received digest.

1. Lets reuse our message.txt file from the previous section to produce a sha256 message digest.
$ sha256sum message.txt

2. Create another message file message2.txt and produce a manifest of digests for all the text files.
$ sha256sum *.txt > manifest
3. You can now easily verify all the files have not been tampered with by checking the manifest file.
$ sha256sum -c manifest .
4. Try tampering message.txt and you should see that $ sha256sum -c manifest errors out.

Think about the following scenario and how it relates to the above:
Alice knows Bob’s public key (this is an assumption) and wants to communicate with Bob. After establishing a
connection, how does she know that the party on the other end is Bob?

5 Bonus: putting it all together


Obviously software integrity is very important nowadays and software authors go to great lengths to ensure that
their users actually use untampered copy of their software. Discuss with your demonstrator how you would design
a safe way to distribute software using what you learnt above.

1 $ openssl rsautl -decrypt -in aes-encrypted-rsa.dat -inkey friend-private.pem

2
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

School of Computing and Information Systems


COMP30023: Computer Systems

Practical Week 5

1 Introduction
In this workshop, we’ll be looking at key generation, encryption, decryption and generating message digests using
the SHA256 hashing algorithm.
As mentioned in the lectures, it is uncommon to encrypt messages directly using asymmetric cryptography. What
we do instead is:
1. First exchange a symmetric key securely (we will use asymmetric key cryptography for this step)
2. Use this exchanged symmetric key for encrypting the actual messages
In this lab we will follow this process step by step using the openssl tool. This lab is best completed with a partner.

2 Asymmetric Encryption
2.1 Generating RSA Keys
We will first create public and private RSA keys using openssl
1. Generate a private key using 2048 bit RSA.
$ openssl genpkey -algorithm RSA -out rsa-private.pem -pkeyopt rsa_keygen_bits:2048
2. View the private key file contents.
$ cat rsa-private.pem
3. Output the corresponding RSA public key.
$ openssl rsa -pubout -in rsa-private.pem -out rsa-public.pem
4. View the public key file contents.
$ cat rsa-public.pem

5. Share your public key with a friend (e.g. email it to them).

3 Symmetric Encryption
3.1 Generating a secret key
To participate in any encryption/decryption scheme, we must first generate a secret key.
1. Create a 256 bit CBC mode AES key (this is a symmetric key).
$ openssl enc -aes-256-cbc -k secret -P -md sha1
2. Save the string listed as ‘key’ to a file named key.txt.
3. You may want to save the initialisation vector (iv) shown to be used when encrypting your message later.
However, remember that initialisation vectors need to be random and not reused. They however do not need
to be kept secret.

1
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

3.2 Exchanging the secret key


Let’s encrypt the symmetric key using RSA, such that our friend can receive a copy of the secret key.

1. Encrypt the symmetric key you generated above using your friend’s public key.
The idea is that only your friend can decrypt the ciphertext containing the secret key (since only they should
have access to their private key file).
$ openssl rsautl -encrypt -in key.txt -pubin -inkey friend-public.pem > aes-encrypted-rsa.dat

2. View the encrypted AES key - the bytes should look like gibberish.
$ xxd aes-encrypted-rsa.dat

3. Email the encrypted AES key to your friend. They should be able to decrypt the key using their private RSA
key. Try to determine the command to decrypt (if you are stuck - see1 ).

3.3 Encryption
Using the material generated above, we can now encrypt our messages.

1. Create a file message.txt with an interesting message.

2. You may want to use the command $ openssl rand -hex 96 > iv.txt to generate a new IV.

3. Encrypt the file using the AES symmetric key. The command will be something like
$ openssl enc -aes-256-cbc -in message.txt -out ciphertext.enc -K $(cat key.txt) -iv $(cat iv.txt)

4. Send this ciphertext and the IV to your friend.


5. As a challenge, you are now tasked to figure out how to do decryption using the shared secret key (which you
should have obtained in 3.2) and the AES encrypted message (which your friend just sent you).
Hint: $ man openssl enc

4 SHA256 Message Digests


In this section, we create SHA256 message digests to commit messages. To verify the commitment, it is necessary
for an adversary/verifier to reveal the message and hash it to check if the digest is equal to the received digest.

1. Lets reuse our message.txt file from the previous section to produce a sha256 message digest.
$ sha256sum message.txt

2. Create another message file message2.txt and produce a manifest of digests for all the text files.
$ sha256sum *.txt > manifest
3. You can now easily verify all the files have not been tampered with by checking the manifest file.
$ sha256sum -c manifest .
4. Try tampering message.txt and you should see that $ sha256sum -c manifest errors out.

Think about the following scenario and how it relates to the above:
Alice knows Bob’s public key (this is an assumption) and wants to communicate with Bob. After establishing a
connection, how does she know that the party on the other end is Bob?

5 Bonus: putting it all together


Obviously software integrity is very important nowadays and software authors go to great lengths to ensure that
their users actually use untampered copy of their software. Discuss with your demonstrator how you would design
a safe way to distribute software using what you learnt above.

1 From your perspective, you should use your private key to decrypt what your friend sent you, i.e.

$ openssl rsautl -decrypt -in aes-encrypted-rsa.dat -inkey rsa-private.pem .

2
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

A Sample solutions
#!/bin/bash
# Parties: Alice, Bob
# Goal - Alice wants to securely send a message to Bob
set -e

# 2.1
# Bob generates RSA key pair
openssl genpkey -algorithm RSA -out bob-private.pem -pkeyopt rsa_keygen_bits:2048
openssl rsa -pubout -in bob-private.pem -out bob-public.pem
# Bob shares his public key bob-public.pem to Alice (and perhaps rest of the world)

# 3.1
# Alice generates secret key
aes_out=$(openssl enc -aes-256-cbc -k secret -P -md sha1)
echo "$aes_out" | grep "key=" | sed "s/key=//" > alice-secret.txt

# 3.2
# Alice encrypts secret key with Bob's public key (which Bob sent), Alice sends ciphertext to Bob
openssl rsautl -encrypt -in alice-secret.txt -pubin -inkey bob-public.pem > aes-encrypted-rsa.dat
# Bob decrypts ciphertext from Alice with Bob's private key, gets secret key
openssl rsautl -decrypt -in aes-encrypted-rsa.dat -inkey bob-private.pem > bob-secret.txt

# 3.2
# Alice encrypts message with secret key and new IV, IV is shared with Bob
echo "Hello World!" > message-alice.txt
openssl rand -hex 96 > iv.txt
openssl enc -aes-256-cbc -in message-alice.txt -out ciphertext.enc \
-K "$(cat alice-secret.txt)" -iv "$(cat iv.txt)"

# 3.5
# Bob decrypts message with the same secret key and IV
openssl enc -aes-256-cbc -d -in ciphertext.enc -K "$(cat bob-secret.txt)" \
-iv "$(cat iv.txt)" -out message-bob.txt

# The messages should match


diff message-alice.txt message-bob.txt
echo "Messages match, all good!"

Alice can send a nonce (number only used once) as the message, encrypted with Bob’s public key.
Bob sends the decrypted message back, which Alice can then compare (e.g. with SHA256 checksum) to verify
whether she’s talking to Bob.

The followup question: What if Alice didn’t have Bob’s public key beforehand? How does she know that the public
key that she has is Bob’s?

3
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

School of Computing and Information Systems


COMP30023: Computer Systems

Practical Week 6

1 Introduction
The internet was not built with privacy nor security in mind. Therefore, most if not all modern communication
channel overlay over transport layer security (TLS) or secure socket layer (SSL). In this workshop, we will be going
through the cryptographic primitives underpinning TLS/SSL and how all of these primitives interplay to realise
TLS/SSL.

NOTE: You have been granted sudo privileges from this week onwards.
You should only use your VM for the purpose of completing COMP30023 activities (please ask for approval from
your demonstrator otherwise).
The university’s policies on the use of IT services: https://policy.unimelb.edu.au/category/Facilities%
20and%20IT.

2 Digital Certificates
1. Browse to https://lms.unimelb.edu.au. Is this domain using a digital certificate? Why is it important
that traffic to the LMS is encrypted?
2. View the digital certificate the LMS is using.
The procedure differs between browsers, and even between different versions of browsers. In some versions of
Chrome and Firefox the option to view the certificate can be found by clicking on the padlock icon. In other
versions you will need to open the Developer Console by pressing F12, and then go to the Security tab.
3. Which CA signed the certificate that the LMS is using? Which CA signed the certificate of the CA which
signed the LMS certificate? What is the root CA of the chain?
4. Is www.eng.unimelb.edu.au using a digital certificate? Why is it less important (though still recommended)
that this website uses HTTPS?
5. View the digital certificate for https://www.melbournepollen.com.au/. Which other domains names does
this digital certificate relate to? You can view this information under Subject Alternative Names.
6. Browse to https://badssl.com/. Visit the expired and wrong.host links and view the certificates. Identify
the fields which indicate why the certificate is no longer valid or not valid for the current host.

3 Services with SSL Certificates


In this section, we will be learning about how to setup SSL certificates for a basic webserver. The goal of issuing
a SSL certificate is to publicly share your public key in a secure manner. Recall that negotiating an ephemeral
symmetric key using the Diffie-Hellman key exchange protocol is fundamental insecure over the internet due to
Man-in-the-Middle attacks. Setting up a SSL certificate is one way around this problem1 . In this exercise today,
we will walk through how to:
1 Typically, you will need to issue a SSL certificate signed by a Trusted Certificate Authority. You can do so using certbot which

automatically uses ACME provided by LetsEncrypt (free service).

1
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

1. Set up a CA.
2. Create a certificate signing request and have the CA to sign the certificate.
3. Set up a web server with the certificates.
This activity is intended to be completed in pairs. One person will play the roles of both the CA and client, while
the other person will be the server administrator.

3.1 CA: Creating a CA certificate


A certificate authority (CA) typically distributes their root certificate offline to be included in OS distributions.
One key responsibility of a CA is to keep their private key secure as mismanagement can lead to a breakdown in
the chain of trust which enables an adversary to arbitrarily sign any random rogue intermediate certificates.
A chain of trust is established where the root certificate is used to sign downstream certificates. Clients verify
downstream certificates by checking their signatures against the public key encoded in their upstream certificate
(i.e. the root certificate).

root certificate →signs intermediate certificate →signs end certificate


Example: Verisign →signs unimelb.edu.au →signs www.unimelb.edu.au

In the following steps, we will produce our own chain of trust to setup TLS/SSL.

1. Generate a secure private key and name the private key myCA.key.
$ openssl genrsa -out myCA.key 4096

2. Generate the root CA certificate for your CA.


$ openssl req -x509 -new -nodes -key myCA.key -sha256 -days 365 -out myCA.crt \
-subj '/CN=COMP30023 CA/O=COMP30023'
Note that we have specified the common name and organisation name of the certificate in the command.
It is also possible to manually input this information (by removing -subj ...) or load this information from
a configuration file. Try it out!

Normally, an intermediate certificate will also created, but we will omit it for the sake of time.

3.2 Client: Install the root certificate


1. The client now needs to obtain the root certificate from the CA and install it into their OS trust store.
Note that myCA.key should be kept as a secret, while myCA.crt should be distributed.
2. Copy the .crt file (from the CA) to this directory.
$ sudo cp myCA.crt /usr/local/share/ca-certificates/myCA.crt

3. Let Ubuntu add the .crt file’s path relative to /usr/share/ca-certificates to /etc/ca-certificates.conf.
$ sudo update-ca-certificates

3.3 Server: Create a Certificate Signing Request


1. Install and setup a basic nginx webserver.
$ sudo apt install nginx

2. Create a private key for the service.


$ openssl genrsa -out service.key 4096

3. Create a certificate signing request (CSR), this is basically an unsigned certificate for your service.
$ openssl req -new -key service.key -out service.csr \
-subj '/CN=<###insert-server-ip-here###>/O=COMP30023'

4. Send the CSR (and only the CSR) to the CA.

2
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

3.4 CA: signing the CSR


1. Verify that the person who is requesting the CSR is who they claim to be.
2. Use your CA certificate and key to sign the CSR.
$ openssl x509 -req -in service.csr -CA myCA.crt -CAkey myCA.key -CAcreateserial \
-out service.crt -days 365 -sha256
3. Send the signed service.crt to the web server.

3.5 Server: Setting the Webserver up for HTTPS


• Setting up nginx is quite cumbersome, so copy the configurations over to your VM. Replace /etc/nginx/sites-
available/default with the provided default file (appendix), filling in your IP address.
• Create a directory to store your service certificate and private key.
$ sudo mkdir -p /etc/ssl/service

• Copy the certificate (from CA) and private key (previously generated) to the directory.
$ sudo cp service.* /etc/ssl/service/

• Reload the nginx configuration (the nginx service should already be started).
$ sudo nginx -s reload
So we now have a webserver which is robust against man-in-the-middle attacks.

3.6 Client: Visit the service


Try curling the web server (you may need to install the curl package).
$ curl https://<server-ip>:8443
You can also try to access the service using your browser. Note that will be warned by the browser because the
root certificate is not installed (trusted) locally, whereas it was installed on the VM in a previous step.
Consider the implications of installing the CA certificate into your local root certificate store.

3.7 Client Certificates (Challenge, Bonus)


Certificates can also be used for Client Authentication, where clients prove their identity to the server through the
use of digital certificates.
1. Server: Create a new CA for the web server (following prior instructions).
Copy serverCA.crt to the server certificate directory.
sudo cp serverCA.crt /etc/ssl/service/serverCA.crt

2. Server: Add the following lines directly above location / in /etc/nginx/sites-available/default :


ssl_client_certificate /etc/ssl/service/serverCA.crt;
ssl_verify_client optional;
And this line directly below location / :
if ($ssl_client_verify != SUCCESS) { return 403; }
Reload the nginx configuration to enable client certificate verification.
3. Client: Create a key client.key. Create a CSR client.csr.
4. Server: With the server CA, sign the CSR, to produce client.crt.
5. Client: Use the client key client.key and certificate client.crt to authenticate with the server.
$ curl --key client.key --cert client.crt https://<server-ip>:8443
Now remove the --key and --cert arguments and observe the results.
6. Client (Extension): Create a PKCS#12 file and visit the website before and after installing it in your browser.

3
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

4 2-way communication using symmetric key encryption


In this section, we will be looking at setting up authenticated secure communication channels using Diffie-Hellman
Key Exchange protocol. You must have completed Section 3 before this. You are encouraged to work in pairs
to do this section.

4.1 Diffie-Hellman Key Exchange


A primer on how it works.
1. There must be a mutually agreed public parameter such as the generator, g and the group order, always a
prime, p. This is typically a value chosen from well-defined internet standards.

2. Keying material is generated by both the client and the server. Let sk be a randomly chosen number between
0 and 2256 and pk = g sk . By the discrete logarithm hardness problem, it is computationally infeasible2 for an
adversary to compute logg (pk) to find sk 3 .
3. The client and server will exchange their public key over an insecure channel. The client typically generates
keying materials on the fly. So, client has (skc , pkc , g) and server has (sks , pks , g). sk is the secret key; pk is
the private key.
4. Client sends pkc and receives pks .
5. Client then computes ek = g skc pks ; while server computes ek = g sks pkc
6. ek is ephemeral symmetric key for the secure communication channel between the client and the server.

Now let us setup a very simple chatting application that is secured using TLS using Netcat.

WARN: This section of the workshop is an extension of last week’s workshop material.

Realistically, you would want to author a proper program to do all the above steps automatically, but just to
observe and learn how everything works like clockwork under the hood, we will be doing every single step by hand,
manually using netcat and openssl. As a bonus, you are encouraged to author a program in any programming
language of your choice to properly accomplish the task.
The purpose of this exercise is to get your hands on how key derivation happens and numerical operations involved.
You will usually use libraries to perform these steps. Do not write your own crypto.

1. Let g = 2, p = 22953686867719691230002707821868552601124472329079 and pick a random sk ∈ [0, p − 1]4


2. Compute pk = g sk (mod p), and give this pk to your friend.

3. Your friend should now have given you their pkfriend , now compute the ephemeral symmetric key ek = (g sk )pk
(mod p)
4. The arbitrary-precision decimal calculator dc has an inbuilt operator for computing g a (mod p) for very
large numbers. The syntax is slightly cryptic (for the curious: it uses reverse Polish notation) but the value
can be computed by entering
g <SPACE> a <SPACE> p | p
where the g, a and p should be your values, the <SPACE> is either a space or a newline, the | (the character
above <ENTER> on a US keyboard) is the operator that does the work, and the final p is the literal letter
p (for “print”).
Run the command dc with no arguments, and then cut-and-paste your numbers into the above expression.
To exit dc, enter either ^C or ^D (control-C or control-D).

Tasks using the material above:


2 For now, it is computational infeasible, but not necessarily a decade later. Always stay up to date with the state of the art in

Cryptography.
3 Convince yourself by briefly searching up how logarithm tables are constructed.
4 We use smaller numbers to make it easier. This is very insecure.

4
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

1. Compute the symmetric key, ek to realise a secure communication channel between your partner and you.
Confirm that both of you got the same key independent of each other.
2. Both of you should now have the same key. However, this is not in the format required for AES. To overcome
this, we will use this shared secret value to generate a shared symmetric (AES) key:
openssl enc -aes-256-cbc -k your key -S 0 -P -md sha1.

3. You may want to save the initialisation vector (iv) shown to be used when encrypting your message later. How-
ever, remember that initialisation vectors need to be random, unknown to the person choosing the message,
and not reused. However they do not need to be kept secret.
4. Recall that last week, we have some experience using the same command.

4.2 Running Netcat


Netcat can be used in both client/server mode. You and your partner should now start a netcat server to receive
incoming connections.
nc -l <PORT> .
Pick a port number between 8000 to 10000.
Your partner should now be able to connect by running
nc <YOUR IP ADDRESS> <PORT>
Now you can send/receive messages (without encryption) with your partner.
To improve your security further, overlay the netcat communication channel with encryption by encrypting your
messages using the same steps in last week’s workshop. To send the encrypted message to your partner, just paste
the encrypted output in the netcat client session and your partner should receive the encrypted message on their
server session. Your partner should then decrypt the encrypted message using the same decryption steps as per last
week’s workshop material.

4.3 Bonus: Authenticating your partner’s Public Key


As you’d have already known, reliably receiving your partner’s public key over the internet is not very secure
since there’s no way for you to know that your partner’s public key have not been tampered with. One way to
authenticate the public key is to get a CA to issue a certificate that signs your partner’s public key. In section 3,
we have shown you how your can start your own CA and issue certificates for your services, but this is inadequate
for the purposes of authenticating your public key. Discuss why not with your demonstrator?
Strategy to achieve authenticated encryption.
1. Ask your partner to install your root certificate you have generated in section 3.
2. Your partner should now be able to verify the authenticity of your public key by visiting your website with
cURL since it conveniently does all the requisite TLS checks.

3. Extract the public key from the webserver certificate. e.g.


openssl s_client -connect gitlab.eng.unimelb.edu.au:443 < /dev/null 2>&1 |
openssl x509 -pubkey -noout -modulus 2>&1 |
grep Modulus | cut -d '=' -f2

4. You can use this public key to compute the symmetric key for a shared secret key as per the procedure
described above.

5 Endnotes
This is just the tip of the iceberg. There are many many more other interesting protocols at play that aim to make
internet communication more secure and private. In your own time, you should also check out DNSSEC, SMTPS,
Domain Authenticated Named Entity, DNS-over-TLS, and more.

5
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

A NGINX Configuration File


server {
# SSL configuration
#
listen 8443 ssl default_server;
listen [::]:8443 ssl default_server;
ssl_certificate /etc/ssl/service/service.crt;
ssl_certificate_key /etc/ssl/service/service.key;
root /var/www/html;

# Add index.php to the list if you are using PHP


index index.html index.htm index.nginx-debian.html;

server_name _;

location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
}

6
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

School of Computing and Information Systems


COMP30023: Computer Systems

Practical Week 6

1 Introduction
The internet was not built with privacy nor security in mind. Therefore, most if not all modern communication
channel overlay over transport layer security (TLS) or secure socket layer (SSL). In this workshop, we will be going
through the cryptographic primitives underpinning TLS/SSL and how all of these primitives interplay to realise
TLS/SSL.

NOTE: You have been granted sudo privileges from this week onwards.
You should only use your VM for the purpose of completing COMP30023 activities (please ask for approval from
your demonstrator otherwise).
The university’s policies on the use of IT services: https://policy.unimelb.edu.au/category/Facilities%
20and%20IT.

2 Digital Certificates
1. Browse to https://lms.unimelb.edu.au. Is this domain using a digital certificate? Why is it important
that traffic to the LMS is encrypted?
2. View the digital certificate the LMS is using.
The procedure differs between browsers, and even between different versions of browsers. In some versions of
Chrome and Firefox the option to view the certificate can be found by clicking on the padlock icon. In other
versions you will need to open the Developer Console by pressing F12, and then go to the Security tab.
3. Which CA signed the certificate that the LMS is using? Which CA signed the certificate of the CA which
signed the LMS certificate? What is the root CA of the chain?
4. Is www.eng.unimelb.edu.au using a digital certificate? Why is it less important (though still recommended)
that this website uses HTTPS?
5. View the digital certificate for https://www.melbournepollen.com.au/. Which other domains names does
this digital certificate relate to? You can view this information under Subject Alternative Names.
6. Browse to https://badssl.com/. Visit the expired and wrong.host links and view the certificates. Identify
the fields which indicate why the certificate is no longer valid or not valid for the current host.

3 Services with SSL Certificates


In this section, we will be learning about how to setup SSL certificates for a basic webserver. The goal of issuing
a SSL certificate is to publicly share your public key in a secure manner. Recall that negotiating an ephemeral
symmetric key using the Diffie-Hellman key exchange protocol is fundamental insecure over the internet due to
Man-in-the-Middle attacks. Setting up a SSL certificate is one way around this problem1 . In this exercise today,
we will walk through how to:
1 Typically, you will need to issue a SSL certificate signed by a Trusted Certificate Authority. You can do so using certbot which

automatically uses ACME provided by LetsEncrypt (free service).

1
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

1. Set up a CA.
2. Create a certificate signing request and have the CA to sign the certificate.
3. Set up a web server with the certificates.
This activity is intended to be completed in pairs. One person will play the roles of both the CA and client, while
the other person will be the server administrator.

3.1 CA: Creating a CA certificate


A certificate authority (CA) typically distributes their root certificate offline to be included in OS distributions.
One key responsibility of a CA is to keep their private key secure as mismanagement can lead to a breakdown in
the chain of trust which enables an adversary to arbitrarily sign any random rogue intermediate certificates.
A chain of trust is established where the root certificate is used to sign downstream certificates. Clients verify
downstream certificates by checking their signatures against the public key encoded in their upstream certificate
(i.e. the root certificate).

root certificate →signs intermediate certificate →signs end certificate


Example: Verisign →signs unimelb.edu.au →signs www.unimelb.edu.au

In the following steps, we will produce our own chain of trust to setup TLS/SSL.

1. Generate a secure private key and name the private key myCA.key.
$ openssl genrsa -out myCA.key 4096

2. Generate the root CA certificate for your CA.


$ openssl req -x509 -new -nodes -key myCA.key -sha256 -days 365 -out myCA.crt \
-subj '/CN=COMP30023 CA/O=COMP30023'
Note that we have specified the common name and organisation name of the certificate in the command.
It is also possible to manually input this information (by removing -subj ...) or load this information from
a configuration file. Try it out!

Normally, an intermediate certificate will also created, but we will omit it for the sake of time.

3.2 Client: Install the root certificate


1. The client now needs to obtain the root certificate from the CA and install it into their OS trust store.
Note that myCA.key should be kept as a secret, while myCA.crt should be distributed.
2. Copy the .crt file (from the CA) to this directory.
$ sudo cp myCA.crt /usr/local/share/ca-certificates/myCA.crt

3. Let Ubuntu add the .crt file’s path relative to /usr/share/ca-certificates to /etc/ca-certificates.conf.
$ sudo update-ca-certificates

3.3 Server: Create a Certificate Signing Request


1. Install and setup a basic nginx webserver.
$ sudo apt install nginx

2. Create a private key for the service.


$ openssl genrsa -out service.key 4096

3. Create a certificate signing request (CSR), this is basically an unsigned certificate for your service.
$ openssl req -new -key service.key -out service.csr \
-subj '/CN=<###insert-server-ip-here###>/O=COMP30023'

4. Send the CSR (and only the CSR) to the CA.

2
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

3.4 CA: signing the CSR


1. Verify that the person who is requesting the CSR is who they claim to be.
2. Use your CA certificate and key to sign the CSR.
$ openssl x509 -req -in service.csr -CA myCA.crt -CAkey myCA.key -CAcreateserial \
-out service.crt -days 365 -sha256
3. Send the signed service.crt to the web server.

3.5 Server: Setting the Webserver up for HTTPS


• Setting up nginx is quite cumbersome, so copy the configurations over to your VM. Replace /etc/nginx/sites-
available/default with the provided default file (appendix), filling in your IP address.
• Create a directory to store your service certificate and private key.
$ sudo mkdir -p /etc/ssl/service

• Copy the certificate (from CA) and private key (previously generated) to the directory.
$ sudo cp service.* /etc/ssl/service/

• Reload the nginx configuration (the nginx service should already be started).
$ sudo nginx -s reload
So we now have a webserver which is robust against man-in-the-middle attacks.

3.6 Client: Visit the service


Try curling the web server (you may need to install the curl package).
$ curl https://<server-ip>:8443
You can also try to access the service using your browser. Note that will be warned by the browser because the
root certificate is not installed (trusted) locally, whereas it was installed on the VM in a previous step.
Consider the implications of installing the CA certificate into your local root certificate store.

3.7 Client Certificates (Challenge, Bonus)


Certificates can also be used for Client Authentication, where clients prove their identity to the server through the
use of digital certificates.
1. Server: Create a new CA for the web server (following prior instructions).
Copy serverCA.crt to the server certificate directory.
sudo cp serverCA.crt /etc/ssl/service/serverCA.crt

2. Server: Add the following lines directly above location / in /etc/nginx/sites-available/default :


ssl_client_certificate /etc/ssl/service/serverCA.crt;
ssl_verify_client optional;
And this line directly below location / :
if ($ssl_client_verify != SUCCESS) { return 403; }
Reload the nginx configuration to enable client certificate verification.
3. Client: Create a key client.key. Create a CSR client.csr.
4. Server: With the server CA, sign the CSR, to produce client.crt.
5. Client: Use the client key client.key and certificate client.crt to authenticate with the server.
$ curl --key client.key --cert client.crt https://<server-ip>:8443
Now remove the --key and --cert arguments and observe the results.
6. Client (Extension): Create a PKCS#12 file and visit the website before and after installing it in your browser.

3
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

4 2-way communication using symmetric key encryption


In this section, we will be looking at setting up authenticated secure communication channels using Diffie-Hellman
Key Exchange protocol. You must have completed Section 3 before this. You are encouraged to work in pairs
to do this section.

4.1 Diffie-Hellman Key Exchange


A primer on how it works.
1. There must be a mutually agreed public parameter such as the generator, g and the group order, always a
prime, p. This is typically a value chosen from well-defined internet standards.

2. Keying material is generated by both the client and the server. Let sk be a randomly chosen number between
0 and 2256 and pk = g sk . By the discrete logarithm hardness problem, it is computationally infeasible2 for an
adversary to compute logg (pk) to find sk 3 .
3. The client and server will exchange their public key over an insecure channel. The client typically generates
keying materials on the fly. So, client has (skc , pkc , g) and server has (sks , pks , g). sk is the secret key; pk is
the private key.
4. Client sends pkc and receives pks .
5. Client then computes ek = g skc pks ; while server computes ek = g sks pkc
6. ek is ephemeral symmetric key for the secure communication channel between the client and the server.

Now let us setup a very simple chatting application that is secured using TLS using Netcat.

WARN: This section of the workshop is an extension of last week’s workshop material.

Realistically, you would want to author a proper program to do all the above steps automatically, but just to
observe and learn how everything works like clockwork under the hood, we will be doing every single step by hand,
manually using netcat and openssl. As a bonus, you are encouraged to author a program in any programming
language of your choice to properly accomplish the task.
The purpose of this exercise is to get your hands on how key derivation happens and numerical operations involved.
You will usually use libraries to perform these steps. Do not write your own crypto.

1. Let g = 2, p = 22953686867719691230002707821868552601124472329079 and pick a random sk ∈ [0, p − 1]4


2. Compute pk = g sk (mod p), and give this pk to your friend.

3. Your friend should now have given you their pkfriend , now compute the ephemeral symmetric key ek = (g sk )pk
(mod p)
4. The arbitrary-precision decimal calculator dc has an inbuilt operator for computing g a (mod p) for very
large numbers. The syntax is slightly cryptic (for the curious: it uses reverse Polish notation) but the value
can be computed by entering
g <SPACE> a <SPACE> p | p
where the g, a and p should be your values, the <SPACE> is either a space or a newline, the | (the character
above <ENTER> on a US keyboard) is the operator that does the work, and the final p is the literal letter
p (for “print”).
Run the command dc with no arguments, and then cut-and-paste your numbers into the above expression.
To exit dc, enter either ^C or ^D (control-C or control-D).

Tasks using the material above:


2 For now, it is computational infeasible, but not necessarily a decade later. Always stay up to date with the state of the art in

Cryptography.
3 Convince yourself by briefly searching up how logarithm tables are constructed.
4 We use smaller numbers to make it easier. This is very insecure.

4
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

1. Compute the symmetric key, ek to realise a secure communication channel between your partner and you.
Confirm that both of you got the same key independent of each other.
2. Both of you should now have the same key. However, this is not in the format required for AES. To overcome
this, we will use this shared secret value to generate a shared symmetric (AES) key:
openssl enc -aes-256-cbc -k your key -S 0 -P -md sha1.

3. You may want to save the initialisation vector (iv) shown to be used when encrypting your message later. How-
ever, remember that initialisation vectors need to be random, unknown to the person choosing the message,
and not reused. However they do not need to be kept secret.
4. Recall that last week, we have some experience using the same command.

4.2 Running Netcat


Netcat can be used in both client/server mode. You and your partner should now start a netcat server to receive
incoming connections.
nc -l <PORT> .
Pick a port number between 8000 to 10000.
Your partner should now be able to connect by running
nc <YOUR IP ADDRESS> <PORT>
Now you can send/receive messages (without encryption) with your partner.
To improve your security further, overlay the netcat communication channel with encryption by encrypting your
messages using the same steps in last week’s workshop. To send the encrypted message to your partner, just paste
the encrypted output in the netcat client session and your partner should receive the encrypted message on their
server session. Your partner should then decrypt the encrypted message using the same decryption steps as per last
week’s workshop material.

4.3 Bonus: Authenticating your partner’s Public Key


As you’d have already known, reliably receiving your partner’s public key over the internet is not very secure
since there’s no way for you to know that your partner’s public key have not been tampered with. One way to
authenticate the public key is to get a CA to issue a certificate that signs your partner’s public key. In section 3,
we have shown you how your can start your own CA and issue certificates for your services, but this is inadequate
for the purposes of authenticating your public key. Discuss why not with your demonstrator?
Strategy to achieve authenticated encryption.
1. Ask your partner to install your root certificate you have generated in section 3.
2. Your partner should now be able to verify the authenticity of your public key by visiting your website with
cURL since it conveniently does all the requisite TLS checks.

3. Extract the public key from the webserver certificate. e.g.


openssl s_client -connect gitlab.eng.unimelb.edu.au:443 < /dev/null 2>&1 |
openssl x509 -pubkey -noout -modulus 2>&1 |
grep Modulus | cut -d '=' -f2

4. You can use this public key to compute the symmetric key for a shared secret key as per the procedure
described above.

5 Endnotes
This is just the tip of the iceberg. There are many many more other interesting protocols at play that aim to make
internet communication more secure and private. In your own time, you should also check out DNSSEC, SMTPS,
Domain Authenticated Named Entity, DNS-over-TLS, and more.

5
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

A NGINX Configuration File


server {
# SSL configuration
#
listen 8443 ssl default_server;
listen [::]:8443 ssl default_server;
ssl_certificate /etc/ssl/service/service.crt;
ssl_certificate_key /etc/ssl/service/service.key;
root /var/www/html;

# Add index.php to the list if you are using PHP


index index.html index.htm index.nginx-debian.html;

server_name _;

location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
}

6
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

B Sample Solutions
B.2 Digital certificates
B.2.1
Yes. Passwords are transmitted, there is also sensitive information (e.g. grades, student lists).

B.2.3
Chain: *.unimelb.edu.au - QuoVadis Global SSL ICA G3 - QuoVadis Root CA 2 G3
Server - Intermediate - Root (as of Mar 2021)

B.2.4
Yes. The website contains static information, so confidentiality is less of an issue. However, the integrity and
availability of content is not guaranteed without HTTPS.

B.2.5
There are many.

B.2.6
Not After for expired, and Subject Alternative Name for wrong.host.

B.3 Services with SSL


#!/bin/bash
set -e

# CA
openssl genrsa -out myCA.key 4096
openssl req -x509 -new -nodes -key myCA.key -sha256 -days 365 -out myCA.crt \
-subj '/CN=COMP30023 CA/O=COMP30023'
# Client install
sudo cp myCA.crt /usr/local/share/ca-certificates/myCA.crt
sudo update-ca-certificates
# Server CSR
sudo apt-get -y install nginx
openssl genrsa -out service.key 4096
openssl req -new -key service.key -out service.csr \
-subj '/CN=115.146.92.110/O=COMP30023'
# CA signs CSR
openssl x509 -req -in service.csr -CA myCA.crt -CAkey myCA.key -CAcreateserial \
-out service.crt -days 365 -sha256
# Server setup
sudo cp default /etc/nginx/sites-available/default
sudo mkdir -p /etc/ssl/service
sudo cp service.* /etc/ssl/service/
sudo nginx -s reload
sleep 2 # Sleep for reload
# Client opens
curl https://115.146.92.110:8443

# Server CA
openssl genrsa -out serverCA.key 4096
openssl req -x509 -new -nodes -key serverCA.key -sha256 -days 365 -out serverCA.crt \
-subj '/CN=COMP30023 Server CA/O=COMP30023'

7
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

sudo cp serverCA.crt /etc/ssl/service/serverCA.crt


sudo cp default2 /etc/nginx/sites-available/default
sudo nginx -s reload
# Client
openssl genrsa -out client.key 4096
openssl req -new -key client.key -out client.csr \
-subj '/CN=115.146.92.110/O=COMP30023'
# Server signs CSR, replace config
openssl x509 -req -in client.csr -CA serverCA.crt -CAkey serverCA.key \
-CAcreateserial -out client.crt -days 365 -sha256
# Client curls
curl --key client.key --cert client.crt https://115.146.92.110:8443
curl https://115.146.92.110:8443
# pkcs12 for browser
openssl pkcs12 -export -out client.pfx -inkey client.key -in client.crt \
-certfile serverCA.crt -password pass:comp30023

B.4 Diffie Hellman Key Exchange


#!/bin/bash
g=2
p=22953686867719691230002707821868552601124472329079

# Alice generates sk1, pk1 = g^sk1 mod p, sends pk1 to Bob


sk1=21341241
pk1=$(echo "$g $sk1 $p | p" | dc)

# Bob generates b, pk2 = g^sk2 mod p, sends pk2 to Alice


sk2=19230482109481
pk2=$(echo "$g $sk2 $p | p" | dc)
# Bob calculates (pk1)^sk2 mod p, which is g^(sk1*sk2) mod p
ek2=$(echo "$pk1 $sk2 $p | p" | dc)

# Alice calculates (pk2)^sk1 mod p, which is g^(sk1*sk2) mod p


ek1=$(echo "$pk2 $sk1 $p | p" | dc)

echo "$ek1 == $ek2"

8
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

School of Computing and Information Systems


COMP30023: Computer Systems

Lab Week 7
Sniffing packets with Wireshark

1 Introduction
Debugging network problems often requires the inspection of the packets being sent. Is the program
sending the correct packets? Is DNS working? Can the network find which node has which IP
address?
A program that captures all packets, including those not addressed to it, is said to “sniff” the
network. One of the most popular network sniffers is Wireshark https://www.wirshark.org.
This not only captures packets, but also decodes the protocol layers making which assists in
understanding what is happening on the network.
In this lab, you will experiment with Wireshark. This may be useful for your project, if you
develop that on your own computer.
You will also practice using bit-manipulation operations in C, which will also be useful for your
project, wherever you develop it.

2 Starting Wireshark
Unlike most labs, this lab should be performed on your own computer, not on your VM.
Install Wireshark from https://www.wireshark.org. If you are asked to install NPCAP, do not
check the “Restrict NPCAP driver’s access to Administrators only”. If you are curious, check the
“Support raw 802.11 traffic” option.
Run Wireshark. If you run Linux, run it as root. If you get an error about Lua being disabled,
ignore it.

Select an interface to monitor. Wireshark shows the amount of traffic on each of the interfaces.
Choose any that has traffic, except any labelled Loopback or the like.

1 (llucien7789@gmail.com)
Downloaded by Lucien Lu
lOMoARcPSD|11775577

Double click on the name of the interface. This will start filling the top pane with lines of text
on coloured backgrounds. Each of these is the summary of a packet, and the background colour
indicates the protocol.

Wait a minute or so to collect a good sample of traffic, and then click the red square second from
the left of the toolbar (stop).
Click on the text box just under the tool bar with the grey text “Apply a display filter”. Enter
“tcp” and click on the icon at the end of the row with a white arrow pointing right on a greyish
blue background. This will display only TCP packets. However, not all packets may display as
TCP in the “protocol” field (between “destination” and “length”).
Question: Why not?
Click on one of the lines representing packets. Observe the middle and bottom panels change.
Click on the arrow (>) to the left of “Transmission Control Protocol” and scroll to see all of the
TCP header fields.
Click on some of the fields, and notice that some of the hexadecimal numbers in the bottom pane
are highlighted.
Question: Can you relate these numbers to the field that you clicked on? How does this relate
to the concepts of encapsulation and layers?
Question: How many bytes per packet seem to be overhead? How many seem to be application
layer payload (i.e., user data, without all of the headers)?
Identify as many protocols as you can from the Wireshark output. You don’t need to work out
what each one does yet; just find their names. Clear the filter text box to look at protocols
other than TCP. Try doing different network-based activities: web browsing, Zoom, sending and

2 (llucien7789@gmail.com)
Downloaded by Lucien Lu
lOMoARcPSD|11775577

receiving email (if you have a non-web mail client), streaming audio or video, using ssh to your
VM.
Question: Based on where in the packet their headers are, can you identify which protocols are
at higher levels and which are at lower levels?
You may choose to have a challenge with your friends or classmates: each time you find a protocol
that nobody has listed yet, post it to a chat service. (Please leave Zoom chat free for those wanting
to ask questions.) See who gets the most “firsts” at the end of class.
Once you have collected several protocols, try to work out the levels they operate at. (Wikipedia
can help with most of them.)
Question: How many protocols did you see at each level? Would that be different if you were at
a different point in the network?

3 Domain Name System (DNS)


The domain name system is a distributed database that, among other tings, translates human-
readable (text) names for hosts, like www.unimelb.edu.au into machine-readable (numeric) IP
addresses used to direct packets to the hosts.
Replace the contents of the filter text box below the toolbar by “dns”. Click on “Domain Name
System” in the middle pane and scroll to the bottom. Observe the hyperlink in blue showing
the matching request or response. The protocol analyser performs this matching to help diagnose
problems where the DNS server does not respond, or responds very slowly.
Question: What DNS packets do you see if you repeatedly access the same host? What happens
when you access a new one?

4 Bit and byte operations


The output from Wireshark has shown that many fields in network headers are smaller than a
byte, or multiple bytes. We will now explore how to extract the integer values from these fields.

4.1 Combining bytes


As you know, packets and TCP streams represent a sequence of bytes. Integers over 255 must be
represented by multiple bytes (as 255 the largest unsigned number representable by 8 bits). The
question is, which byte should be first in the sequence? “Network” byte ordering is that the most
significant byte is always first and the least significant byte is last. The first byte is stored at a
lower memory address within a buffer, and so these numbers are in “big endian” order. Most –
but not all – computers currently use “little endian” order (although this is just a fashion; big
endian has been popular in the past and may be again). That means that we cannot simply read
the data in the buffer “as if” it were a short int, int or long long int.
The C library provides functions that will portably convert the network order bytes into a short
or long integer, and the reverse. These functions are
ntohs network to host, short (16 bits)
ntohl network to host, long (32 bits)
htons host to network, short (16 bits)
htonl host to network, long (32 bits)

3 (llucien7789@gmail.com)
Downloaded by Lucien Lu
lOMoARcPSD|11775577

Run the following code and explain its output.

#include <stdio.h>
#include <arpa/inet.h>
int main () {
char a[4];
int *b = (void*)a;
short int *c = (void*)a;

*b = htonl (1);
printf ("*b %d *c %d\n", *b, *c);

*b = htonl (65536);
printf ("*b %d *c %d\n", *b, *c);
}

Try adding *c = htons(1); at different places in the code and see what happens.
Question: Can you explain it?
Question: Can you use this approach to determine if the machine you are running on is big-endian
or little-endian?

4.2 Bit operations


Consider the following extract from bytes 12 and 13 of a TCP header:

1 1 1 1 1 1
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
- - - - - - - - - - - - - - - -
| | | N C E U A P R S F
|data offset|reservd| S W C R C S S Y I
| | | R R G K H T N N
How can we read the ACK (acknowledgement) flag from bit 11, or the data offset field from bits
0 to 3?
C was designed for this sort of bit manipulation, and has several useful operators:

& bitwise AND (1 & 0 = 0)


| bitwise OR (1 | 0 = 1)
^ bitwise XOR (1 ^ 0 = 1, 1 ^ 1 = 0)
>> shift right (4 >> 1 = 2)
<< shift left (4 << 1 = 8)

With these, we can read ACK = (buf[12] >> 4) & 1.


Question: How else could you do this?

You can read the data offset using a single bit manipulation operation.
Question: How?

You can read the reserved field using two operators.


Question: How could you do that?

There is a very important difference between the types char (a signed value) and unsigned char.
Question: What is ((unsigned char)200) >> 1? What is ((char)(-56)) >> 1? What is
((char)100 + (char)100) >> 1? Explain why these are sensible answers. Should you usually
use signed or unsigned values for manipulating bit fields?

4 (llucien7789@gmail.com)
Downloaded by Lucien Lu
lOMoARcPSD|11775577

School of Computing and Information Systems


COMP30023: Computer Systems

Practical Week 8

1 HTTP and HTML


In this section we will use our browser to view HTTP headers.
Instructions will be provided for Firefox and Chromium-based browsers. You are also welcome to complete the
lab using a different browser (e.g. Safari, non-chromium Edge), though your demonstrator will not be able to
help you in this regard.
1. Firefox: From the menu in the top-right of the browser, select “Web Developer” near the bottom, and
then “Toggle Tools” near the top of the opened menu.
Chrome: From the menu in the top-right of the browser, hover over “More Tools” near the bottom, and
then select “Developer tools” from the bottom.
2. Select the “Network” tab from the top bar, and visit the URL https://www.google.com.au.
3. This will show one line per web request/response. Select one, at the bottom right it will show you the
request and response headers.

1.1 Using cURL


If you prefer using the command line, you can also use the curl tool.
First, you may have to install the curl tool, $ sudo apt install curl .

You can perform a GET request by issuing the following command:


$ curl -s -vv google.com
* Trying 142.250.66.238:80...
* TCP_NODELAY set
* Connected to google.com (142.250.66.238) port 80 (#0)
> GET / HTTP/1.1
> Host: google.com
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
< Location: http://www.google.com/
< Content-Type: text/html; charset=UTF-8
< Date: Fri, 12 Mar 2021 02:58:57 GMT
< Expires: Sun, 11 Apr 2021 02:58:57 GMT
< Cache-Control: public, max-age=2592000
< Server: gws
< Content-Length: 219
< X-XSS-Protection: 0
< X-Frame-Options: SAMEORIGIN
<
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>

1
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

The ”>” symbol at the start of a line represents the request header that is being sent to the destination server,
while the ”<” symbol represents the response header that is being received on your host. Using cURL is very
common practice when trying to debug HTTP API calls or solving any protocol messaging issues that rely on
HTTP. You will notice that the response body does not actually contain the HTML page for google.com due
to a 301 Moved response code.

You can ask cURL to follow redirects:


$ curl -s -vv -L google.com
The -L flag tells cURL to follow redirects. The -vv flag increases the verbosity of cURL to provide more
information. The -s flag suppresses the request progress bar.
The output of this command is shown below. You can see that it now contains the body, but does not fetch
the components of the page that are not part of the HTML.

$ curl -s -vv -L google.com


* Trying 142.250.66.238:80...
* TCP_NODELAY set
* Connected to google.com (142.250.66.238) port 80 (#0)
> GET / HTTP/1.1
> Host: google.com
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
< Location: http://www.google.com/
< Content-Type: text/html; charset=UTF-8
< Date: Fri, 12 Mar 2021 03:01:08 GMT
< Expires: Sun, 11 Apr 2021 03:01:08 GMT
< Cache-Control: public, max-age=2592000
< Server: gws
< Content-Length: 219
< X-XSS-Protection: 0
< X-Frame-Options: SAMEORIGIN
<
* Ignoring the response-body
* Connection #0 to host google.com left intact
* Issue another request to this URL: 'http://www.google.com/'
* Trying 142.250.76.100:80...
* TCP_NODELAY set
* Connected to www.google.com (142.250.76.100) port 80 (#1)
> GET / HTTP/1.1
> Host: www.google.com
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Fri, 12 Mar 2021 03:01:08 GMT
< Expires: -1
< Cache-Control: private, max-age=0
< Content-Type: text/html; charset=ISO-8859-1
< P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
< Server: gws
< X-XSS-Protection: 0
< X-Frame-Options: SAMEORIGIN
< Set-Cookie: 1P_JAR=2021-03-12-03; expires=Sun, 11-Apr-2021 03:01:08 GMT; path=/;
domain=.google.com; Secure
< Set-Cookie: NID=211=oXUedXlqFeEqBXzfzqMBFhIVdnG9-J5jiAJ6iYqB3v6eGM6iCn7cXE7o5fDsOLT8i1uD9drWj
f4pfjW-jInJJag-eEidIiLLoayv0yrJ8Eizu6tPQZe6fOdOwg8wAYzOH6ljcc0p9Pf8WF69mRflhVHrlG
OxPzaGnpwzKvOUsCQ; expires=Sat, 11-Sep-2021 03:01:08 GMT; path=/; domain=.google.com; HttpOnly
< Accept-Ranges: none

2
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

< Vary: Accept-Encoding


< Transfer-Encoding: chunked
<
<!doctype html>... Rest of HTML body

You are welcome to explore cURL by running $ man curl .

1.2 Using wget


Similarly, you can use wget to download web resources.
e.g. $ wget https://www.google.com

wget allows the downloading of all web elements to view the site correctly.
e.g. $ wget -p -k https://cis.unimelb.edu.au

1.3 Questions to ask yourself


In a new tab, look up the meaning of each header.
You may find the site https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers useful, or you can
search with your favourite search engine.

Look at the page. How many bytes do you think it would take to implement this page? Check the sum of the
sizes of the requests.
Note how many requests there are for such a simple page. Can you identify what each request is for? Which
ones do you think are cacheable?
How many different domain names are used to build this page?

1.4 Viewing the HTML


In a new window, open https://www.google.com again. Press CTRL+U. This will bring up the page source
in a new tab.
Search for the string <img in the HTML.
I found one (not logged in to my Google account). How are the other images loaded?

1.5 Visit a simple web page


Repeat the capture process, while visiting the simple URL view-source:http://info.cern.ch/hypertext/
WWW/TheProject.html. Press CTRL+U again to see the source. This is a reconstruction of the first web page.
It only uses very simple HTML.
Identify all of the tags. What does each do? Note that the tag names are in capitals here; tag names are
case-insensitive. Also note that the tags can be broken across lines.
Compare the size of this web page with that of the Google page.

2 Resolving DNS Names


In this section, you will learn how to use dig to query DNS records.
1. To resolve the A record of a domain name (i.e. unimelb.edu.au)
$ dig unimelb.edu.au
What is the IP address you see hosting unimelb.edu.au?

2. To query for another record type, we can specify the record type as an argument. e.g.
$ dig TXT unimelb.edu.au

3. Find the IPv6 address of example.com.


4. Find the IPv6 addresses of the primary mail server of gmail.com.

5. What is the IP address of the DNS server which responded to your query? Find out how to specify a
different server.

3
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

3 Mail headers
In this section, you will study the headers in a typical email.

3.1 Look at the raw text of one of your emails


Log on to your university gmail account, and open any one of your emails.
Open the menu on the right, and select ”show original”:

This will show the full email, including all of the headers. Note that this does not include the SMTP “envelope”.

3.2 Observe the structure and headers


Identify the blank line that indicates the end of the headers.

Observe that some headers span more than one line. (Note that some wrap around, and may seem to be on
multiple lines, but do not actually have a carriage-return/line-feed where they wrap. These are considered a
single line.) Can you guess how the system knows where each header ends?

Find all of the headers shown in the lecture slides, if you can. Are the values (or at least the format of the
values) what you imagined?

What other headers are there?


Observe that many headers begin with X- . That indicates that these are non-standard headers.

Identify the meanings of the headers starting ARC.

3.3 Resources
1. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
2. https://mkyong.com/computer-tips/how-to-view-http-headers-in-google-chrome
3. https://stackoverflow.com/questions/39760367/view-http-headers-in-safari-10

Figure 1: What is wrong here? https://xkcd.com/1144

4
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

School of Computing and Information Systems


COMP30023: Computer Systems

Practical Week 8

1 HTTP and HTML


In this section we will use our browser to view HTTP headers.
Instructions will be provided for Firefox and Chromium-based browsers. You are also welcome to complete the
lab using a different browser (e.g. Safari, non-chromium Edge), though your demonstrator will not be able to
help you in this regard.
1. Firefox: From the menu in the top-right of the browser, select “Web Developer” near the bottom, and
then “Toggle Tools” near the top of the opened menu.
Chrome: From the menu in the top-right of the browser, hover over “More Tools” near the bottom, and
then select “Developer tools” from the bottom.
2. Select the “Network” tab from the top bar, and visit the URL https://www.google.com.au.
3. This will show one line per web request/response. Select one, at the bottom right it will show you the
request and response headers.

1.1 Using cURL


If you prefer using the command line, you can also use the curl tool.
First, you may have to install the curl tool, $ sudo apt install curl .

You can perform a GET request by issuing the following command:


$ curl -s -vv google.com
* Trying 142.250.66.238:80...
* TCP_NODELAY set
* Connected to google.com (142.250.66.238) port 80 (#0)
> GET / HTTP/1.1
> Host: google.com
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
< Location: http://www.google.com/
< Content-Type: text/html; charset=UTF-8
< Date: Fri, 12 Mar 2021 02:58:57 GMT
< Expires: Sun, 11 Apr 2021 02:58:57 GMT
< Cache-Control: public, max-age=2592000
< Server: gws
< Content-Length: 219
< X-XSS-Protection: 0
< X-Frame-Options: SAMEORIGIN
<
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>

1
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

The ”>” symbol at the start of a line represents the request header that is being sent to the destination server,
while the ”<” symbol represents the response header that is being received on your host. Using cURL is very
common practice when trying to debug HTTP API calls or solving any protocol messaging issues that rely on
HTTP. You will notice that the response body does not actually contain the HTML page for google.com due
to a 301 Moved response code.

You can ask cURL to follow redirects:


$ curl -s -vv -L google.com
The -L flag tells cURL to follow redirects. The -vv flag increases the verbosity of cURL to provide more
information. The -s flag suppresses the request progress bar.
The output of this command is shown below. You can see that it now contains the body, but does not fetch
the components of the page that are not part of the HTML.

$ curl -s -vv -L google.com


* Trying 142.250.66.238:80...
* TCP_NODELAY set
* Connected to google.com (142.250.66.238) port 80 (#0)
> GET / HTTP/1.1
> Host: google.com
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 301 Moved Permanently
< Location: http://www.google.com/
< Content-Type: text/html; charset=UTF-8
< Date: Fri, 12 Mar 2021 03:01:08 GMT
< Expires: Sun, 11 Apr 2021 03:01:08 GMT
< Cache-Control: public, max-age=2592000
< Server: gws
< Content-Length: 219
< X-XSS-Protection: 0
< X-Frame-Options: SAMEORIGIN
<
* Ignoring the response-body
* Connection #0 to host google.com left intact
* Issue another request to this URL: 'http://www.google.com/'
* Trying 142.250.76.100:80...
* TCP_NODELAY set
* Connected to www.google.com (142.250.76.100) port 80 (#1)
> GET / HTTP/1.1
> Host: www.google.com
> User-Agent: curl/7.68.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Fri, 12 Mar 2021 03:01:08 GMT
< Expires: -1
< Cache-Control: private, max-age=0
< Content-Type: text/html; charset=ISO-8859-1
< P3P: CP="This is not a P3P policy! See g.co/p3phelp for more info."
< Server: gws
< X-XSS-Protection: 0
< X-Frame-Options: SAMEORIGIN
< Set-Cookie: 1P_JAR=2021-03-12-03; expires=Sun, 11-Apr-2021 03:01:08 GMT; path=/;
domain=.google.com; Secure
< Set-Cookie: NID=211=oXUedXlqFeEqBXzfzqMBFhIVdnG9-J5jiAJ6iYqB3v6eGM6iCn7cXE7o5fDsOLT8i1uD9drWj
f4pfjW-jInJJag-eEidIiLLoayv0yrJ8Eizu6tPQZe6fOdOwg8wAYzOH6ljcc0p9Pf8WF69mRflhVHrlG
OxPzaGnpwzKvOUsCQ; expires=Sat, 11-Sep-2021 03:01:08 GMT; path=/; domain=.google.com; HttpOnly
< Accept-Ranges: none

2
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

< Vary: Accept-Encoding


< Transfer-Encoding: chunked
<
<!doctype html>... Rest of HTML body

You are welcome to explore cURL by running $ man curl .

1.2 Using wget


Similarly, you can use wget to download web resources.
e.g. $ wget https://www.google.com

wget allows the downloading of all web elements to view the site correctly.
e.g. $ wget -p -k https://cis.unimelb.edu.au

1.3 Questions to ask yourself


In a new tab, look up the meaning of each header.
You may find the site https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers useful, or you can
search with your favourite search engine.

Look at the page. How many bytes do you think it would take to implement this page? Check the sum of the
sizes of the requests.
Note how many requests there are for such a simple page. Can you identify what each request is for? Which
ones do you think are cacheable?
How many different domain names are used to build this page?

1.4 Viewing the HTML


In a new window, open https://www.google.com again. Press CTRL+U. This will bring up the page source
in a new tab.
Search for the string <img in the HTML.
I found one (not logged in to my Google account). How are the other images loaded?

1.5 Visit a simple web page


Repeat the capture process, while visiting the simple URL view-source:http://info.cern.ch/hypertext/
WWW/TheProject.html. Press CTRL+U again to see the source. This is a reconstruction of the first web page.
It only uses very simple HTML.
Identify all of the tags. What does each do? Note that the tag names are in capitals here; tag names are
case-insensitive. Also note that the tags can be broken across lines.
Compare the size of this web page with that of the Google page.

2 Resolving DNS Names


In this section, you will learn how to use dig to query DNS records.
1. To resolve the A record of a domain name (i.e. unimelb.edu.au)
$ dig unimelb.edu.au
What is the IP address you see hosting unimelb.edu.au?

2. To query for another record type, we can specify the record type as an argument. e.g.
$ dig TXT unimelb.edu.au

3. Find the IPv6 address of example.com.


4. Find the IPv6 addresses of the primary mail server of gmail.com.

5. What is the IP address of the DNS server which responded to your query? Find out how to specify a
different server.

3
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

3 Mail headers
In this section, you will study the headers in a typical email.

3.1 Look at the raw text of one of your emails


Log on to your university gmail account, and open any one of your emails.
Open the menu on the right, and select ”show original”:

This will show the full email, including all of the headers. Note that this does not include the SMTP “envelope”.

3.2 Observe the structure and headers


Identify the blank line that indicates the end of the headers.

Observe that some headers span more than one line. (Note that some wrap around, and may seem to be on
multiple lines, but do not actually have a carriage-return/line-feed where they wrap. These are considered a
single line.) Can you guess how the system knows where each header ends?

Find all of the headers shown in the lecture slides, if you can. Are the values (or at least the format of the
values) what you imagined?

What other headers are there?


Observe that many headers begin with X- . That indicates that these are non-standard headers.

Identify the meanings of the headers starting ARC.

3.3 Resources
1. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
2. https://mkyong.com/computer-tips/how-to-view-http-headers-in-google-chrome
3. https://stackoverflow.com/questions/39760367/view-http-headers-in-safari-10

Figure 1: What is wrong here? https://xkcd.com/1144

4
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

A Sample solutions
A.1 HTTP and HTML
A.1.4 Questions
How many bytes?
Chromium: x kB resources
Firefox: x KB / ... transferred

Requests made for: HTML, font, stylesheet, javascript, image files


Static files are cachable. Can refresh (not force refresh) page and see files which are loaded from cache (304
status). See also response headers related to caching (e.g. cache-control).
Domain names: See Domain column (enable in Chromium by right clicking column headers, Header options)

A.1.5 Viewing the HTML


Inline SVGs in HTML

A.1.6
https://developer.mozilla.org/en-US/docs/Web/HTML/Element

A.2 DNS
Answers may vary
1. unimelb.edu.au. 60 IN A 172.20.0.43
2. See ANSWER SECTION for TXT records

3. $ dig AAAA example.com

4. $ dig MX gmail.com

gmail.com. 2201 IN MX 10 alt1.gmail-smtp-in.l.google.com.


gmail.com. 2201 IN MX 40 alt4.gmail-smtp-in.l.google.com.
gmail.com. 2201 IN MX 20 alt2.gmail-smtp-in.l.google.com.
gmail.com. 2201 IN MX 5 gmail-smtp-in.l.google.com.
gmail.com. 2201 IN MX 30 alt3.gmail-smtp-in.l.google.com.

Then $ dig AAAA gmail-smtp-in.l.google.com. (5 is highest priority)

5. IP address and port after SERVER: in output.


Specify server using: $ dig @<server> ...

A.3 Mail
Terminated by CRLF (like HTTP headers), https://tools.ietf.org/html/rfc2822#section-2.2
ARC: https://tools.ietf.org/html/rfc8617

5
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

School of Computing and Information Systems


COMP30023: Computer Systems

Practical Week 9

1 Socket Programming in C
Sockets are the endpoints used by applications to send messages from one host to another. The socket of a TCP
connection is defined by its 5-tuple, the protocol (TCP), source IP address, source port, destination IP address,
and destination port. Most operating systems provides an application programming interface (API) for socket
programming, abstracting the lower layers of the protocol stack.

The listings server.c and client.c provide code for implementing server/client communication with TCP.
You may want to study this code as it can be helpful to you in your project.

1. Compile and run server.c on your VM. Use a port between 8000-9000 when running the program.
Command: $ gcc server.c -o server
$ ./server 8198

2. Without terminating the server program, now create another new tab/window in your SSH client program
(or open another terminal window) and connect via SSH to your VM. You should now have two SSH
sessions for your VM. You can use one of these sessions to run the server and the other to run the client.
3. On the client session that you just created, connect via Netcat to the custom server.
$ nc <IP_Address_of_VM> 8198
You should now be able to send a message from the client and receive it on the server.
4. Now use the provided client program to connect to the server instead.
Start the server program again.
In the client session, compile and run client.c .
Command: gcc client.c -o client
$ ./client <IP_Address_of_VM> 8198

Note: When you restart the server after interacting with a client, you may get the error
ERROR on binding: Address already in use
If this is the case, switch to another port before starting the server again.

1.1 netstat
Netstat can be a valuable debugging tool. A common use case is to use it to display all the open ports on your
machine. Let’s use it to identify our server process.

1. Run the server again.


Run the command $ sudo netstat -tulnp
Notice how we are able to view which processes are listening on which ports.
2. Identify the process ID (or PID) of your server, which is running on port 8198.

3. Kill the the server process using the PID, with command:
$ kill -2 PID , which sends SIGINT (like Ctrl-C)
$ kill -9 PID can also be used, to terminate processes immediately (cannot be caught or ignored)

4. Use the netstat command to observe that there is now no process listening on port 8198.

1
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

1.2 Coding Tasks (basic)


As you are now familiar with socket programming in C, you should try adding the following functionalities to
the client and server programs.
1. From the server program, convert the received client message to uppercase and send it to back to the
client. The client should print the converted message received from the server.
2. The current implementation uses non-persistent TCP connection (Think: Why?), your job is to make the
connection persistent so that the client can keep sending messages.
3. As you have implemented a persistent TCP connection for both the client and the server, there is no way
that the server/client can know when to close the TCP connection. Therefore, implement a termination
protocol by sending a special message GOODBYE-CLOSE-TCP from the client to the server. After
sending this special message, the client should close the TCP connection. In addition, upon receiving this
special message, the server should also close the TCP connection.
4. Instead of exchanging messages, send the contents of any .txt file from the client to the server and save
the contents as a text file on the server. Start from the original client.c, server.c.

1.3 Coding Tasks (Extension)


If the above tasks are too easy for you, have some fun implementing a custom FTP protocol to Download/Upload
any text files to the server. We are calling it a custom FTP protocol as we are not following the RFC. Instead,
we are making our own rules on how the client and server should communicate. The details of the custom FTP
protocol are as follows:

1. Client Message: [DOWNLOAD FILE-NAME]. This message is for downloading a file from the server.
If the server receives this client message and the requested file exists on the server, it will send a message
containing [OK FILE-CONTENT] to the client and the client should save the FILE-CONTENT as
FILE-NAME. If the file doesn’t exist in the server, the server should send a message containing [NOT-
FOUND] to the client.
2. Client Message: [UPLOAD FILE-NAME FILE-CONTENT]. This message is for uploading the
contents of a file from the client’s machine to the server. At first, when a user types this message, the
client will read the contents of the local file to generate the message. Then it will send the message
to the server. Upon receiving this message, the server will save the FILE-CONTENT in a file named
FILE-NAME.
* If you are too passionate about protocol and RFCs, you are welcome to implement a complete FTP
server1 .

2 Telnet + HTTP (Bonus)


Web browsers communicate with web servers by issuing HTTP Requests.
In this activity, we will manually send a HTTP request using telnet, which allows for interactive (insecure)
remote communication via text.

1. Establish a Telnet connection to the server at example.com on port 80.


If you’re on a 172.26.128.0/20 VM, use the host cis.unimelb.edu.au instead.
e.g. $ telnet example.com 80

2. Let’s issue a well-formed HTTP version 1.1 (HTTP/1.1) GET request to the index page.
Press enter twice after entering the text (once to signal the end of the Host header, and another time to
signal the end of header fields). e.g.
GET / HTTP/1.1
Host: example.com
3. Inspect the result.

3 Resources
Beej’s Guide to Network Programming: https://beej.us/guide/bgnet/html/
1 https://tools.ietf.org/html/rfc959

2
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

School of Computing and Information Systems


COMP30023: Computer Systems

Practical Week 9 & Week 10 Hints

Week 9
1. To convert the message to uppercase:
(a) Identify where the characters are stored.
(b) Loop over the array which stores the characters, and convert each letter to uppercase.
You may want to read the man page for toupper, in <ctype.h>.
There is no upper(whole_string) in C (at least not in the standard library).
2. To make connection persistent, we want to be able to send and receive (client), and receive and send
(server) multiple messages on one TCP connection. The current code exits after handling one message.
The logical conclusion would be to make some code loop infinitely. But where?
After which call do we get the socket for the connection? What call closes the connection?
Note that sockfd is the welcome (or listen) socket and newsockfd is the connection socket.
3. GOODBYE-CLOSE-TCP is a string, so we can perform string comparison and break the connection.
Also, a return status of 0 on read indicates that the other side of the connection has closed the socket.

Week 10
1.2
1. The port is #define(ed). The address is currently NULL.
They are both specified on the same line.

From the man page:


node specifies either a numerical network address (for IPv4, numbers-and-dots notation as supported by
inet_aton(3); for IPv6, hexadecimal string format as supported by inet_pton(3)), or a network hostname,
whose network addresses are looked up and resolved.

If node is NULL, then the network address will be set to the loopback interface address (INADDR_LOOP-
BACK for IPv4 addresses, IN6ADDR_LOOPBACK_INIT for IPv6 address); this is used by applications
that intend to communicate with peers running on the same host.
2. i == sockfd handles incoming connection requests. The else branch handles messages from clients.
We first read the message from the client. Then, if the read was successful, we enter the nested else
branch (the last else branch near the end of the code). Then, we loop from 0 to the maximum file
descriptor recorded. If the file descriptor j is not the same socket that we received the message from, is
not the welcome socket, and is in the set, then we send the message to that socket. Effectively, this loop
is causing the message to be sent to all other connected sockets.
Your task is to modify the code in this else branch to send the message back to the sender only.

2.1
2. Follow similar steps to Practical 9. However, we want to accept infinitely many new connections, rather
than loop over just one connection (which is closed after the response has been sent).
3. TCP is stream-oriented. This means that the message sent by two write() calls can require 1 read(), 2
read(), or perhaps even more read() calls. read() until all the bytes (up to the indicated length) have
been read.

1
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

School of Computing and Information Systems


COMP30023: Computer Systems

Practical Week 10

1 I/O Multiplexing
In a previous lab, you have learned about the basics of Socket Programming in C. You have used a very simple
server and client to exchange a message back and forth. You have added more functionalities to both the
client and the server. However, our communications always involved only a single server and a single client. In
reality, this is not the case, and a server needs to handle incoming requests from multiple clients. For example,
when a DNS Server is running, multiple clients will send requests to the server.

You have used the function accept() in the server side to handle the initial incoming connection request from
the client. After that, you have used the function read() to fetch the client message from the socket and
responded accordingly. Note that, both of these functions are blocking calls (the server has to wait until the
function returns). Therefore, it is not possible to handle multiple connections through these functions. You
might think adding multiple accept() and read() calls will be enough, but what if the server needs to read()
something when it is waiting for an accept()? Hence, to handle multiple connections, we want to be notified
if one or more I/O conditions are ready (i.e., input is ready to be read, or the descriptor is capable of taking
more output). This capability is called I/O multiplexing and is provided by the select() and poll() functions in
C. I/O multiplexing is typically used in networking applications in the following scenarios 1 .
• When a client is handling multiple descriptors (normally interactive input and a network socket);
• When a client wants to handle multiple sockets at the same time;
• If a TCP server handles both a listening socket and its connected sockets;
• If a server handles both TCP and UDP protocols;
• If a server handles multiple services and perhaps multiple protocols;
In this lab, we will learn how to use the select() function in C to support I/O multiplexing. Some other necessary
functions that need to be used can be studied from the example source codes. Please also search for the man
pages to learn about any specific function.

1.1 Multi-person Chat Server


Now, we will run a multi-person chat server which can be used to broadcast a message sent by any client to all
the connected clients with the server. Study the source code of select-server.c . A further reading on how
I/O multiplexing works and the explanation of the given source code can be found here2 .
1. Compile and run select-server.c on your VM.
Command: $ gcc select-server.c -o server
$ ./server
2. Create another new tab/window in your SSH client program (such as MobaXterm, or open another
terminal in Ubuntu/OSX) and connect via SSH to your VM. Now, you have two ssh sessions running in
your VM where the first one is running the server program. Use the new session to run telnet.
Command: $ telnet localhost 9034
3. Create more ssh sessions and run telnet from these sessions to connect to the server. Now, whenever you
type something in one of your telnet sessions, it should appear in all the other sessions.
1 https://notes.shichao.io/unp/ch6/
2 https://beej.us/guide/bgnet/html/#slightly-advanced-techniques

1
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

1.2 Coding Tasks


Add the following features in the multi-person chat server.
1. Make both the IP and the port of the server configurable which should be passed as command-line
arguments. Note that, by default, the server will run on localhost and the port of the server is hard-coded
to be 9034. As you are now configuring both your IP and port, you can pass your VM IP when running
the server code. Therefore, you will be able you to connect to your server even from your local machine.
Note that, you have to choose any port from 8000 to 10000, which are the only open ports in your VM.
Command: $ telnet VM-IP Server-Port . Please replace VM-IP and Server-Port with real
values before running.

* Have some fun by using one of your lab-mate’s server as the only host. Now, multiple people can connect
to the same server to have a group chat!
2. Instead of sending the message from one telnet session to all the others, send the message back to the
sender only. Therefore, each client should only get the message they typed as a response from the server.

2 Summation Protocol
In this exercise, we will be working with a simple made-up request/response protocol.
Completing this exercise may help you with your project.
The protocol works over TCP, with the packet format being as follows:
0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
| Number of numbers (prefix) |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
| Number 1 |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
| Number 2 (optional) |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ... |
| ... |
To describe the above diagram in written form:
Packets have a 4-byte prefix header, which indicate the number of 4-byte numbers which follow the header.
Numbers are presented in big endian (network byte order).

Both requests and responses follow the same packet format.


A request contains one or more numbers.
Servers should send a response containing the prefix and 1 number (the sum of numbers in the request).
For simplicity, we classify integer overflow to be undefined behaviour and don’t specify what happens when a
packet is malformed.

2.1 Tasks
Note: these tasks build upon previous exercises (last week and this week).
1. Read both the server and client code.
Once you understand how the code works, use the client to send a request to the server.
If you repeatedly encounter the “Haven’t received...” error, move on to the next step.
2. Uncomment the sleep statement in the client code, and observe the behaviour of the server.
Fix this behaviour by modifying the server code (Hint: TCP is stream oriented).
3. Modify the server to handle multiple client requests.
4. (Recommended if doing blocking option in project 2): Now increase the duration of the sleep statement
in the client code. Assume that this delay is necessary and cannot be removed.
Modify the server code to use pthreads/select()/epoll() to handle multiple requests simultaneously.
Print the number of requests received so far to stdout (bearing in mind race conditions).

2
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

School of Computing and Information Systems


COMP30023: Computer Systems

Practical Week 11
Sniffing packets with Wireshark, and understanding IP addresses

1 Wireshark
You have come across Wireshark in a previous lab. Review that lab if you have forgotten how to use it. Here
we will use Wireshark to study some of the protocols you have come across in this course. It is easiest to run
this section on your local computer rather than the VM.

1.1 IP carrying TCP


1. Start a capture using the shark fin at the top left
2. Select any packet with protocol TCP or something that runs over TCP, like TLS or HTTP
3. Expand the “Internet Protocol” line in the bottom frame, using the triangle on the left of the line

4. Expand the lines “Differentiated Services” and “Flags”


5. Match each field to the location in the IP header shown in the lecture slides
6. Try to understand what each value means.
• Does this packet support Explicit congestion notification (ECN)?
• What does “Header length 20 (5)” mean? Why are there two numbers?
• Look at the identification number. Compare that with another packet you capture. Are they the
same?
7. Repeat this for a few other packets that you capture.

• Which IP header fields seem to have the same value in most packets, and which seem to vary?

1.2 IP carrying UDP


1. Repeat the above for packets with protocol UDP or something that runs over UDP, like DNS.

2. Which IP header fields have the same values as for the TCP case, and which are different?
In particular, are there any fields that are the same for all TCP packets, and the same for all UDP packets,
but differ between TCP and UDP packets? Which ones?

1.3 Monitoring HTTP requests


1. Start a new capture (using the shark fin at the top left).
2. Visit http://example.com and stop the capture.

3. Enter into the filter: http.host matches "example.com".


Q: What packet(s) do you see?
4. Now right click on the first packet and Follow the HTTP Stream.

1
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

1.4 Address Resolution Protocol (ARP)


The internet protocol runs on top of other network protocols. Each of these network protocols has its own
addressing scheme. IP hosts find the names of hosts on the underlying network (called the “link layer” by most
TCP/IP people) such as ethernet or WiFi using the Address Resolution Protocol (ARP).

Whenever an IP host wants to send to another IP node on the same network, such as the router, it must have
that node’s address. This is typically called a MAC address, and sometimes erroneously called a hardware
address. This is usually cached, but if the host is contacting a new node or if the cache has been cleared it will
issue an ARP request. We will now watch as we force your computer to issue an ARP request.
1. Open a command window.
2. You will now clear the ARP cache. The instructions below will tell you to type some commands. Before
you press henteri on the final command, start a new capture in Wireshark by clicking on the blue fin icon
at the far left of the toolbar.
Windows Open the command window as administrator.
https://www.intowindows.com/command-prompt-as-administrator-in-windows-10
Type
netsh interface ip delete arpcache
Mac or FreeBSD Enter the command
arp -a -d
Linux First find the default gateway using arp by itself. This will probably list a single address and a
single interface. If so, the interface should match the one you are sniffing and the address will be
your gateway address. Then type the command
sudo arp -i interface_you_are_sniffing -d gateway_address
Wait a few seconds and then stop the Wireshark capture. (If you forgot to start it, just repeat the above
steps, remembering to start Wireshark before pressing enter)
3. Type arp into the filter text box below the toolbar. This should bring up two ARP packets. If not, repeat
the above steps and access the web between clearing the cache and stopping the capture.
4. Click on the line of the first ARP packet, and observe the destination Ethernet address. This will be a
“special” addresses: ff:ff:ff:ff:ff:ff. What does that mean, and why is this mode used?
5. Click on the line of the second ARP packet. What is its source address? Can you relate that to the
contents of the first ARP packet?

1.5 Monitoring your project code


Now use Wireshark to capture the packets to and from your DNS server.
Do the packets contain what you expected them to contain?

2 Understanding IP addresses
Look at the routing table on your computer – either your VM or your local computer. In Linux, this is done by
the command route with no arguments. On Windows, it is done by opening a command window (Windowskey-
R then type cmd), and typing the command route print. On MacOS, type the command netstat -rn. If
your computer doesn’t have many routes, you can use the sample output below.
For each network address (or as many as you have time for)
1. Work out how many bits of the address make the network address, and how many bits make the host
address.
2. Work out how many addresses are in that network.
This will be very repetitive if you go through each address below. Only do the ones that will give you different
answers.
Notice that some have a destination netmask of 255.255.255.255. In those cases, that isn’t the network mask
of the network the destination is on. That is saying that this is the actual (network|host) address, and that
routing decisions need to be based on matching the entire 32 bits.
Can you identify the “default routes”, used when no other network address matches?

2
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

===========================================================================
Interface List
20...00 05 9a 3c 7a 00 ......Cisco AnyConnect Secure Mobility Client Virtual Miniport Adapter for Windo
17...b0 5c da e5 e6 e7 ......Intel(R) Ethernet Connection (4) I219-V
13...0a 00 27 00 00 0d ......VirtualBox Host-Only Ethernet Adapter
11...02 00 4c 4f 4f 50 ......Npcap Loopback Adapter
26...f4 d1 08 4d 6c 74 ......Microsoft Wi-Fi Direct Virtual Adapter #3
3...f6 d1 08 4d 6c 73 ......Microsoft Wi-Fi Direct Virtual Adapter #4
14...f4 d1 08 4d 6c 73 ......Intel(R) Dual Band Wireless-AC 8265 #2
18...f4 d1 08 4d 6c 77 ......Bluetooth Device (Personal Area Network)
1...........................Software Loopback Interface 1
===========================================================================

IPv4 Route Table


===========================================================================
Active Routes:

3
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

Network Destination Netmask Gateway Interface Metric


0.0.0.0 0.0.0.0 192.168.0.1 192.168.0.13 50
0.0.0.0 0.0.0.0 10.1.16.1 10.1.20.177 2
10.1.16.0 255.255.248.0 On-link 10.1.20.177 257
10.1.20.177 255.255.255.255 On-link 10.1.20.177 257
10.1.23.255 255.255.255.255 On-link 10.1.20.177 257
113.197.7.0 255.255.255.0 192.168.0.1 192.168.0.13 50
127.0.0.0 255.0.0.0 On-link 127.0.0.1 331
127.0.0.1 255.255.255.255 On-link 127.0.0.1 331
127.255.255.255 255.255.255.255 On-link 127.0.0.1 331
138.44.4.0 255.255.255.224 192.168.0.1 192.168.0.13 50
138.44.4.128 255.255.255.224 192.168.0.1 192.168.0.13 50
138.44.66.144 255.255.255.240 192.168.0.1 192.168.0.13 50
138.44.71.0 255.255.255.192 192.168.0.1 192.168.0.13 50
138.44.72.0 255.255.252.0 192.168.0.1 192.168.0.13 50
138.44.128.96 255.255.255.224 192.168.0.1 192.168.0.13 50
138.44.132.0 255.255.254.0 192.168.0.1 192.168.0.13 50
138.44.160.0 255.255.255.224 192.168.0.1 192.168.0.13 50
138.44.162.96 255.255.255.224 192.168.0.1 192.168.0.13 50
138.44.162.144 255.255.255.240 192.168.0.1 192.168.0.13 50
138.44.163.199 255.255.255.255 192.168.0.1 192.168.0.13 50
138.44.163.202 255.255.255.255 192.168.0.1 192.168.0.13 50
138.44.163.203 255.255.255.255 192.168.0.1 192.168.0.13 50
138.44.164.0 255.255.255.192 192.168.0.1 192.168.0.13 50
138.44.166.0 255.255.254.0 192.168.0.1 192.168.0.13 50
138.44.177.64 255.255.255.224 192.168.0.1 192.168.0.13 50
169.254.0.0 255.255.0.0 On-link 169.254.250.142 281
169.254.0.0 255.255.0.0 10.1.16.1 10.1.20.177 2
169.254.250.142 255.255.255.255 On-link 169.254.250.142 281
169.254.255.255 255.255.255.255 On-link 169.254.250.142 281
182.255.102.208 255.255.255.240 192.168.0.1 192.168.0.13 50
182.255.102.240 255.255.255.240 192.168.0.1 192.168.0.13 50
182.255.112.8 255.255.255.255 192.168.0.1 192.168.0.13 50
182.255.112.11 255.255.255.255 192.168.0.1 192.168.0.13 50
182.255.112.21 255.255.255.255 192.168.0.1 192.168.0.13 50
192.168.0.0 255.255.255.0 On-link 192.168.0.13 306
192.168.0.0 255.255.255.0 10.1.16.1 10.1.20.177 2
192.168.0.1 255.255.255.255 On-link 192.168.0.13 51
192.168.0.13 255.255.255.255 On-link 192.168.0.13 306
192.168.0.255 255.255.255.255 On-link 192.168.0.13 306
192.168.56.0 255.255.255.0 On-link 192.168.56.1 281
192.168.56.0 255.255.255.0 10.1.16.1 10.1.20.177 2
192.168.56.1 255.255.255.255 On-link 192.168.56.1 281
192.168.56.255 255.255.255.255 On-link 192.168.56.1 281
202.158.223.128 255.255.255.224 192.168.0.1 192.168.0.13 50
203.21.130.30 255.255.255.255 192.168.0.1 192.168.0.13 51
224.0.0.0 240.0.0.0 On-link 127.0.0.1 331
224.0.0.0 240.0.0.0 On-link 192.168.56.1 281
224.0.0.0 240.0.0.0 On-link 192.168.0.13 306
224.0.0.0 240.0.0.0 On-link 169.254.250.142 281
224.0.0.0 240.0.0.0 On-link 10.1.20.177 257
255.255.255.255 255.255.255.255 On-link 127.0.0.1 331
255.255.255.255 255.255.255.255 On-link 192.168.56.1 281
255.255.255.255 255.255.255.255 On-link 192.168.0.13 306
255.255.255.255 255.255.255.255 On-link 169.254.250.142 281
255.255.255.255 255.255.255.255 On-link 10.1.20.177 257
===========================================================================
Persistent Routes:
None

IPv6 Route Table

4
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

===========================================================================
Active Routes:
If Metric Network Destination Gateway
14 306 ::/0 fe80::be30:d9ff:fece:1de2
20 36 ::/0 On-link
1 331 ::1/128 On-link
14 51 2001:8004:11d0:4e2a::cb15:821e/128 fe80::be30:d9ff:fece:1de2
14 306 2001:8004:1d62:4439::/64 On-link
20 36 2001:8004:1d62:4439::/64 On-link
14 306 2001:8004:1d62:4439:1f0:b68f:96da:d51a/128 On-link
14 306 2001:8004:1d62:4439:25c1:6438:7d45:2984/128 On-link
20 291 fe80::/64 On-link
14 306 fe80::1f0:b68f:96da:d51a/128 On-link
20 291 fe80::300a:2945:9ff8:5cb7/128 On-link
20 291 fe80::5e9f:c20c:51b4:5e34/126 On-link
20 291 fe80::5e9f:c20c:51b4:5e36/128 On-link
13 281 fe80::a02e:bac4:b4e0:60ea/128 On-link
11 281 fe80::b4c0:3f1c:a775:fa8e/128 On-link
1 331 ff00::/8 On-link
13 281 ff00::/8 On-link
14 306 ff00::/8 On-link
11 281 ff00::/8 On-link
===========================================================================
Persistent Routes:
None

5
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

School of Computing and Information Systems


COMP30023: Computer Systems

Practical Week 11
Sniffing packets with Wireshark, and understanding IP addresses

1 Wireshark
You have come across Wireshark in a previous lab. Review that lab if you have forgotten how to use it. Here
we will use Wireshark to study some of the protocols you have come across in this course. It is easiest to run
this section on your local computer rather than the VM.

1.1 IP carrying TCP


1. Start a capture using the shark fin at the top left
2. Select any packet with protocol TCP or something that runs over TCP, like TLS or HTTP
3. Expand the “Internet Protocol” line in the bottom frame, using the triangle on the left of the line

4. Expand the lines “Differentiated Services” and “Flags”


5. Match each field to the location in the IP header shown in the lecture slides
6. Try to understand what each value means.
• Does this packet support Explicit congestion notification (ECN)?
• What does “Header length 20 (5)” mean? Why are there two numbers?
• Look at the identification number. Compare that with another packet you capture. Are they the
same?
7. Repeat this for a few other packets that you capture.

• Which IP header fields seem to have the same value in most packets, and which seem to vary?

1.2 IP carrying UDP


1. Repeat the above for packets with protocol UDP or something that runs over UDP, like DNS.

2. Which IP header fields have the same values as for the TCP case, and which are different?
In particular, are there any fields that are the same for all TCP packets, and the same for all UDP packets,
but differ between TCP and UDP packets? Which ones?

1.3 Monitoring HTTP requests


1. Start a new capture (using the shark fin at the top left).
2. Visit http://example.com and stop the capture.

3. Enter into the filter: http.host matches "example.com".


Q: What packet(s) do you see?
4. Now right click on the first packet and Follow the HTTP Stream.

1
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

1.4 Address Resolution Protocol (ARP)


The internet protocol runs on top of other network protocols. Each of these network protocols has its own
addressing scheme. IP hosts find the names of hosts on the underlying network (called the “link layer” by most
TCP/IP people) such as ethernet or WiFi using the Address Resolution Protocol (ARP).

Whenever an IP host wants to send to another IP node on the same network, such as the router, it must have
that node’s address. This is typically called a MAC address, and sometimes erroneously called a hardware
address. This is usually cached, but if the host is contacting a new node or if the cache has been cleared it will
issue an ARP request. We will now watch as we force your computer to issue an ARP request.
1. Open a command window.
2. You will now clear the ARP cache. The instructions below will tell you to type some commands. Before
you press henteri on the final command, start a new capture in Wireshark by clicking on the blue fin icon
at the far left of the toolbar.
Windows Open the command window as administrator.
https://www.intowindows.com/command-prompt-as-administrator-in-windows-10
Type
netsh interface ip delete arpcache
Mac or FreeBSD Enter the command
arp -a -d
Linux First find the default gateway using arp by itself. This will probably list a single address and a
single interface. If so, the interface should match the one you are sniffing and the address will be
your gateway address. Then type the command
sudo arp -i interface_you_are_sniffing -d gateway_address
Wait a few seconds and then stop the Wireshark capture. (If you forgot to start it, just repeat the above
steps, remembering to start Wireshark before pressing enter)
3. Type arp into the filter text box below the toolbar. This should bring up two ARP packets. If not, repeat
the above steps and access the web between clearing the cache and stopping the capture.
4. Click on the line of the first ARP packet, and observe the destination Ethernet address. This will be a
“special” addresses: ff:ff:ff:ff:ff:ff. What does that mean, and why is this mode used?
5. Click on the line of the second ARP packet. What is its source address? Can you relate that to the
contents of the first ARP packet?

1.5 Monitoring your project code


Now use Wireshark to capture the packets to and from your DNS server.
Do the packets contain what you expected them to contain?

2 Understanding IP addresses
Look at the routing table on your computer – either your VM or your local computer. In Linux, this is done by
the command route with no arguments. On Windows, it is done by opening a command window (Windowskey-
R then type cmd), and typing the command route print. On MacOS, type the command netstat -rn. If
your computer doesn’t have many routes, you can use the sample output below.
For each network address (or as many as you have time for)
1. Work out how many bits of the address make the network address, and how many bits make the host
address.
2. Work out how many addresses are in that network.
This will be very repetitive if you go through each address below. Only do the ones that will give you different
answers.
Notice that some have a destination netmask of 255.255.255.255. In those cases, that isn’t the network mask
of the network the destination is on. That is saying that this is the actual (network|host) address, and that
routing decisions need to be based on matching the entire 32 bits.
Can you identify the “default routes”, used when no other network address matches?

2
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

===========================================================================
Interface List
20...00 05 9a 3c 7a 00 ......Cisco AnyConnect Secure Mobility Client Virtual Miniport Adapter for Windo
17...b0 5c da e5 e6 e7 ......Intel(R) Ethernet Connection (4) I219-V
13...0a 00 27 00 00 0d ......VirtualBox Host-Only Ethernet Adapter
11...02 00 4c 4f 4f 50 ......Npcap Loopback Adapter
26...f4 d1 08 4d 6c 74 ......Microsoft Wi-Fi Direct Virtual Adapter #3
3...f6 d1 08 4d 6c 73 ......Microsoft Wi-Fi Direct Virtual Adapter #4
14...f4 d1 08 4d 6c 73 ......Intel(R) Dual Band Wireless-AC 8265 #2
18...f4 d1 08 4d 6c 77 ......Bluetooth Device (Personal Area Network)
1...........................Software Loopback Interface 1
===========================================================================

IPv4 Route Table


===========================================================================
Active Routes:

3
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

Network Destination Netmask Gateway Interface Metric


0.0.0.0 0.0.0.0 192.168.0.1 192.168.0.13 50
0.0.0.0 0.0.0.0 10.1.16.1 10.1.20.177 2
10.1.16.0 255.255.248.0 On-link 10.1.20.177 257
10.1.20.177 255.255.255.255 On-link 10.1.20.177 257
10.1.23.255 255.255.255.255 On-link 10.1.20.177 257
113.197.7.0 255.255.255.0 192.168.0.1 192.168.0.13 50
127.0.0.0 255.0.0.0 On-link 127.0.0.1 331
127.0.0.1 255.255.255.255 On-link 127.0.0.1 331
127.255.255.255 255.255.255.255 On-link 127.0.0.1 331
138.44.4.0 255.255.255.224 192.168.0.1 192.168.0.13 50
138.44.4.128 255.255.255.224 192.168.0.1 192.168.0.13 50
138.44.66.144 255.255.255.240 192.168.0.1 192.168.0.13 50
138.44.71.0 255.255.255.192 192.168.0.1 192.168.0.13 50
138.44.72.0 255.255.252.0 192.168.0.1 192.168.0.13 50
138.44.128.96 255.255.255.224 192.168.0.1 192.168.0.13 50
138.44.132.0 255.255.254.0 192.168.0.1 192.168.0.13 50
138.44.160.0 255.255.255.224 192.168.0.1 192.168.0.13 50
138.44.162.96 255.255.255.224 192.168.0.1 192.168.0.13 50
138.44.162.144 255.255.255.240 192.168.0.1 192.168.0.13 50
138.44.163.199 255.255.255.255 192.168.0.1 192.168.0.13 50
138.44.163.202 255.255.255.255 192.168.0.1 192.168.0.13 50
138.44.163.203 255.255.255.255 192.168.0.1 192.168.0.13 50
138.44.164.0 255.255.255.192 192.168.0.1 192.168.0.13 50
138.44.166.0 255.255.254.0 192.168.0.1 192.168.0.13 50
138.44.177.64 255.255.255.224 192.168.0.1 192.168.0.13 50
169.254.0.0 255.255.0.0 On-link 169.254.250.142 281
169.254.0.0 255.255.0.0 10.1.16.1 10.1.20.177 2
169.254.250.142 255.255.255.255 On-link 169.254.250.142 281
169.254.255.255 255.255.255.255 On-link 169.254.250.142 281
182.255.102.208 255.255.255.240 192.168.0.1 192.168.0.13 50
182.255.102.240 255.255.255.240 192.168.0.1 192.168.0.13 50
182.255.112.8 255.255.255.255 192.168.0.1 192.168.0.13 50
182.255.112.11 255.255.255.255 192.168.0.1 192.168.0.13 50
182.255.112.21 255.255.255.255 192.168.0.1 192.168.0.13 50
192.168.0.0 255.255.255.0 On-link 192.168.0.13 306
192.168.0.0 255.255.255.0 10.1.16.1 10.1.20.177 2
192.168.0.1 255.255.255.255 On-link 192.168.0.13 51
192.168.0.13 255.255.255.255 On-link 192.168.0.13 306
192.168.0.255 255.255.255.255 On-link 192.168.0.13 306
192.168.56.0 255.255.255.0 On-link 192.168.56.1 281
192.168.56.0 255.255.255.0 10.1.16.1 10.1.20.177 2
192.168.56.1 255.255.255.255 On-link 192.168.56.1 281
192.168.56.255 255.255.255.255 On-link 192.168.56.1 281
202.158.223.128 255.255.255.224 192.168.0.1 192.168.0.13 50
203.21.130.30 255.255.255.255 192.168.0.1 192.168.0.13 51
224.0.0.0 240.0.0.0 On-link 127.0.0.1 331
224.0.0.0 240.0.0.0 On-link 192.168.56.1 281
224.0.0.0 240.0.0.0 On-link 192.168.0.13 306
224.0.0.0 240.0.0.0 On-link 169.254.250.142 281
224.0.0.0 240.0.0.0 On-link 10.1.20.177 257
255.255.255.255 255.255.255.255 On-link 127.0.0.1 331
255.255.255.255 255.255.255.255 On-link 192.168.56.1 281
255.255.255.255 255.255.255.255 On-link 192.168.0.13 306
255.255.255.255 255.255.255.255 On-link 169.254.250.142 281
255.255.255.255 255.255.255.255 On-link 10.1.20.177 257
===========================================================================
Persistent Routes:
None

IPv6 Route Table

4
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

===========================================================================
Active Routes:
If Metric Network Destination Gateway
14 306 ::/0 fe80::be30:d9ff:fece:1de2
20 36 ::/0 On-link
1 331 ::1/128 On-link
14 51 2001:8004:11d0:4e2a::cb15:821e/128 fe80::be30:d9ff:fece:1de2
14 306 2001:8004:1d62:4439::/64 On-link
20 36 2001:8004:1d62:4439::/64 On-link
14 306 2001:8004:1d62:4439:1f0:b68f:96da:d51a/128 On-link
14 306 2001:8004:1d62:4439:25c1:6438:7d45:2984/128 On-link
20 291 fe80::/64 On-link
14 306 fe80::1f0:b68f:96da:d51a/128 On-link
20 291 fe80::300a:2945:9ff8:5cb7/128 On-link
20 291 fe80::5e9f:c20c:51b4:5e34/126 On-link
20 291 fe80::5e9f:c20c:51b4:5e36/128 On-link
13 281 fe80::a02e:bac4:b4e0:60ea/128 On-link
11 281 fe80::b4c0:3f1c:a775:fa8e/128 On-link
1 331 ff00::/8 On-link
13 281 ff00::/8 On-link
14 306 ff00::/8 On-link
11 281 ff00::/8 On-link
===========================================================================
Persistent Routes:
None

5
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

A Sample solutions
A.2 IP carrying TCP
RFC 3168, Section 5
The not-ECT codepoint '00' indicates a packet that is not using ECN.
The CE codepoint '11' is set by a router to indicate congestion to
the end nodes. Routers that have a packet arriving at a full queue
drop the packet, just as they do in the absence of ECN.
From lecture slides:
Header length in 32 bit words; min 5, max 15, so need to multiply the value indicated by the 4 bits by 4

Identification stay the same when fragmentation occurs, should be different otherwise.

A.3 IP carrying UDP


The version field will be the same (4). IP address and TTL of out-going packets will be the same.
The header length will be the same for most packets, only differing for those with options.
Packet ID and checksum will be different for (almost) every packet.
The protocol field will be different (UDP, 17, instead of TCP, 6)

A.4 HTTP
I observed 2 requests:
GET / HTTP/1.1 and GET /favicon.ico HTTP/1.1

After right clicking, you should see the request and response stream.
If you click on one of the response packets, e.g. HTTP/1.1 200 OK, you may observe that the body is garbled.
This is because gzip content-encoding is used.

A.5 ARP
First frame (ARP Request)
Frame: Destination is Broadcast (ff:ff:ff:ff:ff:ff)
Sender MAC/IP: your MAC/IP
Target MAC: 00:00:00:00:00:00, Target IP: IP address of device which we want the MAC address of

Second frame (ARP Response)


Frame: Destination (your MAC address, Source of previous frame)
Sender MAC/IP: MAC of Sender (the MAC we want), IP of Sender (Target IP of ARP request)
Destination MAC/IP: See Sender of ARP request

A.6 IP addresses
Example from 172 VM:
172.26.128.0 0.0.0.0 255.255.240.0 U 0 0 0 eth0

1. Subnet mask indicates 20 network bits (8+8+4 1s). Therefore, 12 host bits.
2. 212 addresses

Example of default route:


default 172.26.128.1 0.0.0.0 UG 1024 0 0 eth0

6
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

School of Computing and Information Systems


COMP30023: Computer Systems

Practical Week 12

1 Introduction
In this workshop, we will be learning about utility tools for the networking layer on Linux.

2 ip and route
First, lets look at how to obtain our host IP address, without relying on external 3rd party services.
1. On your VM, run
$ ip addr

Find your VM’s IP address, and netmask. Express this as “/n”. Confirm that the broadcast address is the
IP address for your subnet that has all 1s for the host component. Together, write a list of the subnets
that everyone in your breakout room belongs to. Does your host have any other IP addresses? How many?
How many does each interface?
2. On your VM, type the command $ ip neigh to find reachable networking peers. Discuss what do the
entries XX:XX:XX:XX:XX:XX represent?
3. The ip utility tool is quite comprehensive and more or less gives you every piece of information related
to the network layer. To learn more, run
$ ip help

4. On your VM, type the command $ route -n to find your IPv4 routing table. Observe the use of the
address 0.0.0.0 to mean “default” in two contexts. That is the rule that will be used for all packets not
matching any other rule. Is your gateway an internal or external address? Is your default gateway on the
same subnet as you? Is it possible to have a default gateway that is not on your local subnet?
For the curious: Why is there an entry for the address range 169.254.0.0/16?
(Hint: http://packetlife.net/blog/2008/sep/24/169-254-0-0-addresses-explained,
https://datatracker.ietf.org/doc/html/rfc3927)

3 ping
The ping tool is commonly used to test reachability of a host on a network.
Using the command line on your local device for this task:
1. Perform a ping request to the server cis.unimelb.edu.au (on your local device).
Command: $ ping cis.unimelb.edu.au (Terminate using Ctrl+C)

2. Now perform a ping request to the server ping.online.net (on your local device).
Compare the round trip times with those seen above.
Use iplocation.net to determine the country the server ping.online.net is located in.
3. A common method to determine whether you have Internet connectivity is to ping a highly reliable server
on the Internet. Some examples of such servers are 4.2.2.2, 1.1.1.1 and 8.8.8.8.
Try pinging these servers. Use the command $ whois 4.2.2.2 to see who owns that IP address.
What kind of servers do you think these IP addresses relate to?
https://www.tummy.com/articles/famous-dns-server/ is a nice article which talks about the history
of the famous IP address 4.2.2.2.

1
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

4 traceroute
The traceroute command finds the path that packets follow when heading to a destination. It does this by
starting with a time-to-live (TTL) value of 1. After one hop, this packet is discarded, and the router that
discards it sends an Internet Control Messaging Protocol (ICMP) packet back saying that it has expired. The
source address of this packet is taken as the first hop of the path to the destination. This is repeated with a
TTL of 2, and then 3, and so on until the destination is reached, or the TTL reaches 30. Install it with the
command
$ sudo apt install traceroute

Then run it with


$ traceroute cis.unimelb.edu.au

The last few lines may say ”* * *”. That means that either the router at which TTL=0 doesn’t reply
with an ICMP message, or that one of the routers along the path drops the ICMP messages, or the initial
traceroute probes. If you have time, traceroute to several locations in the unimelb.edu.au domain, such as
eng.unimelb.edu.au. From these, try to work out the local connectivity.

Looking Glass servers provide web-based access to the routers of Internet Service Providers. A list of looking
glass servers is available at traceroute.org.
Use the looking glass servers of Telstra (https://www.telstra.net/cgi-bin/trace) and iiNet (http://
looking-glass.iinet.net.au/lg.cgi) to send traceroute requests to the same server (e.g. ping.online.net)
from different cities.
Observe the common links in the traceroutes. Does the oceanic link look the same?

5 Network Scanning
Now that we have kind of know how to explore, troubleshoot our personal host. Lets learn how to investigate,
troubleshoot external hosts from our host. The go-to tool is nmap . Install this by running $ sudo apt install nmap .

WARNING: YOU MUST USE YOUR ASSIGNED VM FOR THIS subsection.

1. Let’s start with the basics, to do a basic default port scan on a target host (i.e. 172.26.129.247). Run:
$ nmap 172.26.129.247

2. If nmap does not give you any hints as to what ports are open, it may be because that the target host
blocks ping probes. To get around that, you can run:
$ nmap -Pn IP
Try this command again with the host and check if there is an open SMTP port.
If a SMTP port is open, use telnet to send a HELO comp30023 message and see if you receive a positive
response (i.e. 250). If you received a 250, you have successfully interacted with a STMP server.
Press Ctrl-] and type quit (or Ctrl-D) to exit.
3. Now, lets go on a treasure hunt and find a funny service that one of our tutors have prepared.
nmap also allows you to scan port ranges. Run:
$ nmap -Pn -p8000-10000 172.26.129.247

Start the treasure hunt from the first port in the range 8000-10000 (which is hosting a HTTP server):
$ curl 172.26.129.247:<PORT>

and follow the trail to find the treasure.


4. nmap is a very useful tool as a developer, you can use this to troubleshoot most, if not all network
applications to figure out what problems exist from a networking perspective. If firewalls are blocking
your service, or just to do sanity checks to check if a service is running and accessible from an external
host. Read more about nmap in man nmap . A word of caution, using nmap on public networks, from
your home IP address is a federal cybercrime offence punishable by law and most certainly violates the
Terms of Service of your ISP. You should also not run nmap scans originating from the university servers
to external networks without permission.

2
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

6 Bonus: TLS and Wireshark


1. Open the file https-trace.pcapng given on the LMS using Wireshark.
2. Why does there seem to be more than one Client Hello message?
3. How many Cipher Suite options does the client send the server? Which cipher suite does the server pick?

4. View the certificate details from the frames that carry the actual certificates. Which website was visited
while recording this Wireshark trace? Which organisation issued the certificate? What are the validity
(notBefore and notAfter) dates and times?

7 Bonus: Capturing TLS Traffic Using Wireshark


1. Close all applications that may be connecting to the Internet in the background.
2. Go to Capture -> Options in Wireshark.
3. Click on the interface that you are using to connect to the Internet.
4. Specify tcp port https as the capture filter. Disable promiscuous mode.

5. Start the capture.


6. Browse to a website that uses HTTPS.
7. Stop the capture (click red square button).

8. Find the IP address of the website by using nslookup <URL>

9. Apply a display filter by typing in ip.addr == <IP Address> and ssl in the textbox in the main
Wireshark window
10. Answer the questions in Section 6 for the trace you just captured.

3
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

School of Computing and Information Systems


COMP30023: Computer Systems

Practical Week 12

1 Introduction
In this workshop, we will be learning about utility tools for the networking layer on Linux.

2 ip and route
First, lets look at how to obtain our host IP address, without relying on external 3rd party services.
1. On your VM, run
$ ip addr

Find your VM’s IP address, and netmask. Express this as “/n”. Confirm that the broadcast address is the
IP address for your subnet that has all 1s for the host component. Together, write a list of the subnets
that everyone in your breakout room belongs to. Does your host have any other IP addresses? How many?
How many does each interface?
2. On your VM, type the command $ ip neigh to find reachable networking peers. Discuss what do the
entries XX:XX:XX:XX:XX:XX represent?
3. The ip utility tool is quite comprehensive and more or less gives you every piece of information related
to the network layer. To learn more, run
$ ip help

4. On your VM, type the command $ route -n to find your IPv4 routing table. Observe the use of the
address 0.0.0.0 to mean “default” in two contexts. That is the rule that will be used for all packets not
matching any other rule. Is your gateway an internal or external address? Is your default gateway on the
same subnet as you? Is it possible to have a default gateway that is not on your local subnet?
For the curious: Why is there an entry for the address range 169.254.0.0/16?
(Hint: http://packetlife.net/blog/2008/sep/24/169-254-0-0-addresses-explained,
https://datatracker.ietf.org/doc/html/rfc3927)

3 ping
The ping tool is commonly used to test reachability of a host on a network.
Using the command line on your local device for this task:
1. Perform a ping request to the server cis.unimelb.edu.au (on your local device).
Command: $ ping cis.unimelb.edu.au (Terminate using Ctrl+C)

2. Now perform a ping request to the server ping.online.net (on your local device).
Compare the round trip times with those seen above.
Use iplocation.net to determine the country the server ping.online.net is located in.
3. A common method to determine whether you have Internet connectivity is to ping a highly reliable server
on the Internet. Some examples of such servers are 4.2.2.2, 1.1.1.1 and 8.8.8.8.
Try pinging these servers. Use the command $ whois 4.2.2.2 to see who owns that IP address.
What kind of servers do you think these IP addresses relate to?
https://www.tummy.com/articles/famous-dns-server/ is a nice article which talks about the history
of the famous IP address 4.2.2.2.

1
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

4 traceroute
The traceroute command finds the path that packets follow when heading to a destination. It does this by
starting with a time-to-live (TTL) value of 1. After one hop, this packet is discarded, and the router that
discards it sends an Internet Control Messaging Protocol (ICMP) packet back saying that it has expired. The
source address of this packet is taken as the first hop of the path to the destination. This is repeated with a
TTL of 2, and then 3, and so on until the destination is reached, or the TTL reaches 30. Install it with the
command
$ sudo apt install traceroute

Then run it with


$ traceroute cis.unimelb.edu.au

The last few lines may say ”* * *”. That means that either the router at which TTL=0 doesn’t reply
with an ICMP message, or that one of the routers along the path drops the ICMP messages, or the initial
traceroute probes. If you have time, traceroute to several locations in the unimelb.edu.au domain, such as
eng.unimelb.edu.au. From these, try to work out the local connectivity.

Looking Glass servers provide web-based access to the routers of Internet Service Providers. A list of looking
glass servers is available at traceroute.org.
Use the looking glass servers of Telstra (https://www.telstra.net/cgi-bin/trace) and iiNet (http://
looking-glass.iinet.net.au/lg.cgi) to send traceroute requests to the same server (e.g. ping.online.net)
from different cities.
Observe the common links in the traceroutes. Does the oceanic link look the same?

5 Network Scanning
Now that we have kind of know how to explore, troubleshoot our personal host. Lets learn how to investigate,
troubleshoot external hosts from our host. The go-to tool is nmap . Install this by running $ sudo apt install nmap .

WARNING: YOU MUST USE YOUR ASSIGNED VM FOR THIS subsection.

1. Let’s start with the basics, to do a basic default port scan on a target host (i.e. 172.26.129.247). Run:
$ nmap 172.26.129.247

2. If nmap does not give you any hints as to what ports are open, it may be because that the target host
blocks ping probes. To get around that, you can run:
$ nmap -Pn IP
Try this command again with the host and check if there is an open SMTP port.
If a SMTP port is open, use telnet to send a HELO comp30023 message and see if you receive a positive
response (i.e. 250). If you received a 250, you have successfully interacted with a STMP server.
Press Ctrl-] and type quit (or Ctrl-D) to exit.
3. Now, lets go on a treasure hunt and find a funny service that one of our tutors have prepared.
nmap also allows you to scan port ranges. Run:
$ nmap -Pn -p8000-10000 172.26.129.247

Start the treasure hunt from the first port in the range 8000-10000 (which is hosting a HTTP server):
$ curl 172.26.129.247:<PORT>

and follow the trail to find the treasure.


4. nmap is a very useful tool as a developer, you can use this to troubleshoot most, if not all network
applications to figure out what problems exist from a networking perspective. If firewalls are blocking
your service, or just to do sanity checks to check if a service is running and accessible from an external
host. Read more about nmap in man nmap . A word of caution, using nmap on public networks, from
your home IP address is a federal cybercrime offence punishable by law and most certainly violates the
Terms of Service of your ISP. You should also not run nmap scans originating from the university servers
to external networks without permission.

2
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

6 Bonus: TLS and Wireshark


1. Open the file https-trace.pcapng given on the LMS using Wireshark.
2. Why does there seem to be more than one Client Hello message?
3. How many Cipher Suite options does the client send the server? Which cipher suite does the server pick?

4. View the certificate details from the frames that carry the actual certificates. Which website was visited
while recording this Wireshark trace? Which organisation issued the certificate? What are the validity
(notBefore and notAfter) dates and times?

7 Bonus: Capturing TLS Traffic Using Wireshark


1. Close all applications that may be connecting to the Internet in the background.
2. Go to Capture -> Options in Wireshark.
3. Click on the interface that you are using to connect to the Internet.
4. Specify tcp port https as the capture filter. Disable promiscuous mode.

5. Start the capture.


6. Browse to a website that uses HTTPS.
7. Stop the capture (click red square button).

8. Find the IP address of the website by using nslookup <URL>

9. Apply a display filter by typing in ip.addr == <IP Address> and ssl in the textbox in the main
Wireshark window
10. Answer the questions in Section 6 for the trace you just captured.

3
Downloaded by Lucien Lu (llucien7789@gmail.com)
lOMoARcPSD|11775577

A Sample solutions
A.2 IP
1. Student VMs should have two interface, lo (loopback) with address 127.0.0.1 and eth0.

Possible subnets:
172.26.128.0/20 (Internal network VMs), 45.113.232.0/22 and 115.146.92.0/22 (International VMs)

Example: 115.146.92.110/22 from ip addr


Take network bits.
/22 falls within 3rd octet, 92 is 0b01011100, take first 6 (22 - 16) bits, decimal of first 6 bits is 92.
115.146.92.0/22 is the subnet.

2. MAC address
3. N/A

4. On a 115.146.92.110/22 VM:
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 115.146.92.1 0.0.0.0 UG 1024 0 0 eth0
45.113.232.0 0.0.0.0 255.255.252.0 U 1024 0 0 eth0
103.6.254.0 0.0.0.0 255.255.254.0 U 1024 0 0 eth0
115.146.92.0 0.0.0.0 255.255.252.0 U 0 0 0 eth0
169.254.169.254 115.146.92.6 255.255.255.255 UGH 1024 0 0 eth0
On a 45.113.232.0/22 VM:
Destination Gateway Genmask Flags Metric Ref Use Iface
0.0.0.0 45.113.232.1 0.0.0.0 UG 1024 0 0 eth0
45.113.232.0 0.0.0.0 255.255.252.0 U 0 0 0 eth0
103.6.254.0 0.0.0.0 255.255.254.0 U 1024 0 0 eth0
115.146.92.0 0.0.0.0 255.255.252.0 U 1024 0 0 eth0
169.254.169.254 45.113.232.102 255.255.255.255 UGH 1024 0 0 eth0
On a 172.26.128.0/20 VM:

Destination Gateway Genmask Flags Metric Ref Use Iface


0.0.0.0 172.26.128.1 0.0.0.0 UG 1024 0 0 eth0
169.254.169.254 172.26.128.5 255.255.255.255 UGH 1024 0 0 eth0
172.26.36.0 0.0.0.0 255.255.252.0 U 1024 0 0 eth0
172.26.128.0 0.0.0.0 255.255.240.0 U 0 0 0 eth0

Is your gateway an internal or external address?


The gateway address is internal to the network. However, it can be either a private (where NAT/proxy is
used to reach the Internet - see reserved IP ranges) or public IP address.
Is your default gateway on the same subnet as you? Yes
Is it possible to have a default gateway that is not on your local subnet? No

A.3 ping
The roundtrip times depend on where you are in the world and how Internet traffic is routed, since you’re
performing this task on your own machine. If you’re in Melbourne, you should expect the roundtrip time to
cis.unimelb.edu.au to be much lower.

4.2.2.2, 1.1.1.1 and 8.8.8.8 are DNS servers

4
Downloaded by Lucien Lu (llucien7789@gmail.com)

You might also like