Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
11 views21 pages

Acn Lab Manual

Uploaded by

divyasiddoju508
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views21 pages

Acn Lab Manual

Uploaded by

divyasiddoju508
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 21

ADVANCED COMPUTER NETWORKS LAB MANUAL

1. IMPLEMENT THE IP FRAGMENTATION AND REASSEMBLY


ALGORITHM

from math import floor


from typing import List

class IPFragment:
def __init__(self, identification, offset, mf, header_len, payload):
self.identification = identification
self.offset = offset # in 8-byte blocks
self.mf = mf # More Fragments flag (1 if more fragments follow)
self.header_len = header_len
self.payload = payload

def __repr__(self):
return (f"ID={self.identification}, Offset={self.offset * 8} bytes, "
f"MF={self.mf}, PayloadLen={len(self.payload)}")

def fragment_ip_packet(payload: bytes, mtu: int, header_len: int = 20, identification:


int = 1234) -> List[IPFragment]:
"""
Fragments the payload based on MTU and returns a list of IPFragment objects.
"""
max_data = floor((mtu - header_len) / 8) * 8
fragments = []
offset = 0
i=0

while offset < len(payload):


end = min(offset + max_data, len(payload))
frag_payload = payload[offset:end]
mf = 1 if end < len(payload) else 0
fragment = IPFragment(
identification=identification,
offset=offset // 8,
mf=mf,
header_len=header_len,
payload=frag_payload
)
fragments.append(fragment)
offset += max_data
i += 1

return fragments

def reassemble_ip_fragments(fragments: List[IPFragment]) -> bytes:


"""
Reassembles fragments and returns the full payload.
"""
fragments.sort(key=lambda f: f.offset)

complete_payload = bytearray()
expected_offset = 0

for frag in fragments:


actual_offset = frag.offset * 8
if actual_offset != expected_offset:
raise ValueError(f"Fragment at offset {actual_offset} doesn't match expected
offset {expected_offset}")
complete_payload += frag.payload
expected_offset += len(frag.payload)

if fragments[-1].mf != 0:
raise ValueError("Reassembly failed: last fragment missing (MF != 0)")

return bytes(complete_payload)

# ------------------ DEMO ------------------ #


if __name__ == "__main__":
# Input data
data = b"This is a sample data string that is going to be fragmented and then
reassembled."
mtu = 30
header_len = 20 # standard IPv4 header
print("Original Payload:", data.decode())
print("Length:", len(data))

# Fragment
fragments = fragment_ip_packet(data, mtu, header_len)
print(f"\nGenerated {len(fragments)} fragments:\n")
for i, frag in enumerate(fragments):
print(f"Fragment {i}: {frag}")

# Reassemble
try:
reassembled = reassemble_ip_fragments(fragments)
print("\nReassembled Payload:", reassembled.decode())
print("Reassembly Successful:", reassembled == data)
except ValueError as e:
print("Reassembly Error:", e)

2. IMPLEMENT THE IP FORWARDING ALGORITHM

from __future__ import annotations


from dataclasses import dataclass
from ipaddress import IPv4Address, IPv4Network
from typing import List, Optional

# -------------------------------
# Data models
# -------------------------------

@dataclass
class Route:
network: IPv4Network # e.g. IPv4Network("10.0.0.0/8")
next_hop: Optional[IPv4Address] # None => directly connected
iface: str

@dataclass
class Packet:
src: IPv4Address
dst: IPv4Address
ttl: int = 64
payload: bytes = b""

# -------------------------------
# Forwarding logic
# -------------------------------

def longest_prefix_match(routes: List[Route], dst: IPv4Address) -> Optional[Route]:


"""
Return the route with the longest prefix that matches 'dst'.
If none matches, return None.
"""
best = None
best_prefix = -1
for r in routes:
if dst in r.network:
plen = r.network.prefixlen
if plen > best_prefix:
best_prefix = plen
best = r
return best

def forward(packet: Packet, routes: List[Route]) -> Optional[tuple[Route,


IPv4Address]]:
"""
Simulate IPv4 forwarding:
- Decrement TTL; drop if TTL <= 0
- Find longest-prefix-match route
- Return (selected_route, next_hop_ip) if forwardable, else None

next_hop_ip is:
- route.next_hop if present
- packet.dst if directly connected
"""
# TTL handling
packet.ttl -= 1
if packet.ttl <= 0:
print("Drop: TTL expired")
return None

route = longest_prefix_match(routes, packet.dst)


if route is None:
print("Drop: No matching route")
return None

next_hop = route.next_hop if route.next_hop is not None else packet.dst


return route, next_hop

# -------------------------------
# Demo
# -------------------------------

if __name__ == "__main__":
# Build a tiny routing table
routing_table = [
Route(IPv4Network("10.1.0.0/16"), next_hop=None, iface="eth0"),
# directly connected
Route(IPv4Network("10.1.2.0/24"), next_hop=None, iface="eth1"),
# more specific, directly connected
Route(IPv4Network("0.0.0.0/0"), next_hop=IPv4Address("192.0.2.1"),
iface="eth2"), # default via gateway
]

# Packets to test
pkts = [
Packet(IPv4Address("10.1.2.50"), IPv4Address("10.1.2.99")), # should
pick /24 on eth1
Packet(IPv4Address("10.1.2.50"), IPv4Address("10.1.9.8")), # should
pick /16 on eth0
Packet(IPv4Address("10.1.2.50"), IPv4Address("8.8.8.8")), # should pick
default via 192.0.2.1
]

for i, p in enumerate(pkts, 1):


print(f"\nPacket {i}: {p.src} -> {p.dst}, ttl={p.ttl}")
res = forward(p, routing_table)
if res is None:
print(" => dropped")
else:
route, nh = res
print(f" => forwarded out {route.iface}, next-hop {nh}, new ttl={p.ttl}")

3. IMPLEMENT THE SIMPLEST SLIDING WINDOW PROTOCOL OF TCP

import random
from collections import deque
from dataclasses import dataclass

# -------------------- Config --------------------


MSS = 4 # bytes per segment
WINDOW_SIZE = 4 # sender window size
RTT = 5 # one-way delay = RTT/2, but we’ll just schedule arrivals at
now+RTT
RTO = 15 # retransmission timeout
LOSS_PROB = 0.15 # packet loss prob (data or ACK)
DATA = b"HELLO_THIS_IS_A_SMALL_TCP_SLIDING_WINDOW_DEMO"

random.seed(1)

# -------------------- Data structures --------------------


@dataclass
class Segment:
seq: int
data: bytes

@dataclass
class Ack:
ackno: int # cumulative ack (next byte expected)

# -------------------- Network simulator --------------------


class Network:
def __init__(self):
self.events = [] # list of (deliver_time, payload, dst)

def send(self, now, payload, dst):


# Drop?
if random.random() < LOSS_PROB:
print(f"[{now:03}] NET: *** LOST *** {payload}")
return
deliver_time = now + RTT
self.events.append((deliver_time, payload, dst))

def tick(self, now):


delivered = []
remain = []
for t, p, d in self.events:
if t <= now:
delivered.append((p, d))
else:
remain.append((t, p, d))
self.events = remain
return delivered

# -------------------- Receiver --------------------


class Receiver:
def __init__(self):
self.rcv_nxt = 0 # next expected byte
self.buffer = {} # (we won't use out-of-order buffering in GBN)

def recv(self, seg: Segment):


if seg.seq == self.rcv_nxt:
self.rcv_nxt += len(seg.data)
# (Go-Back-N: drop any out-of-order; in Selective Repeat we'd buffer)
# else: ignore out-of-order
return Ack(self.rcv_nxt)

# -------------------- Sender (Go-Back-N) --------------------


class Sender:
def __init__(self, data: bytes):
self.data = data
self.base = 0 # oldest unacked byte
self.nextseq = 0 # next byte to send
self.win = WINDOW_SIZE * MSS
self.unacked = {} # seq -> (segment, send_time)
self.timer_start = None
self.done = False

def in_window(self):
return self.nextseq < self.base + self.win

def make_segment(self):
if self.nextseq >= len(self.data):
return None
# amount we can send now
to_send = min(MSS, len(self.data) - self.nextseq)
seg = Segment(self.nextseq, self.data[self.nextseq:self.nextseq + to_send])
return seg

def on_send(self, now, net: Network):


while self.in_window():
seg = self.make_segment()
if seg is None:
break
net.send(now, seg, "receiver")
print(f"[{now:03}] SND: seq={seg.seq:03}, len={len(seg.data)},
win=[{self.base},{self.base+self.win})")
self.unacked[seg.seq] = (seg, now)
if self.timer_start is None:
self.timer_start = now
self.nextseq += len(seg.data)

def on_ack(self, now, ack: Ack):


if ack.ackno > self.base:
# ack all bytes below ackno
to_del = [s for s in self.unacked if s + len(self.unacked[s][0].data) <=
ack.ackno]
for s in to_del:
del self.unacked[s]
self.base = ack.ackno
print(f"[{now:03}] RCV: ACK {ack.ackno:03} -> base={self.base:03}")
# restart timer if we still have unacked data
self.timer_start = now if self.unacked else None

if self.base >= len(self.data) and not self.unacked:


self.done = True

def check_timeout(self, now, net: Network):


if self.timer_start is None:
return
if now - self.timer_start >= RTO:
print(f"[{now:03}] TO! Retransmitting from base={self.base:03}")
self.timer_start = now
# Go-Back-N: retransmit all unacked from base
for seq in sorted(self.unacked):
seg, _ = self.unacked[seq]
net.send(now, seg, "receiver")
self.unacked[seq] = (seg, now)
print(f"[{now:03}] RTX: seq={seg.seq:03}, len={len(seg.data)}")

# -------------------- Main simulation loop --------------------


def simulate():
sender = Sender(DATA)
receiver = Receiver()
net = Network()
now = 0
MAX_TIME = 1000

# initial send
sender.on_send(now, net)
while now < MAX_TIME and not sender.done:
# deliver network events
for payload, dst in net.tick(now):
if dst == "receiver" and isinstance(payload, Segment):
ack = receiver.recv(payload)
net.send(now, ack, "sender")
print(f"[{now:03}] RCV: seg seq={payload.seq:03},
len={len(payload.data)} -> send ACK {ack.ackno}")
elif dst == "sender" and isinstance(payload, Ack):
sender.on_ack(now, payload)
# after ACK, try sending more
sender.on_send(now, net)

# timeout?
sender.check_timeout(now, net)
now += 1

print("\nDone.")

if __name__ == "__main__":
simulate()

4. CONNECT TWO SYSTEMS USING A SWITCH AND CONFIGURE


PRIVATE IP ADDRESSES TO THE SYSTEMS AND PING THEM FROM EACH
OTHER.USING WIRESHARK, CAPTURE PACKETS AND ANALYZE ALL
THE HEADER INFORMATION IN THE PACKETS CAPTURED

1.AIM

To interconnect two hosts through a Layer-2 switch, assign private IPv4 addresses,
verify connectivity using ping (ICMP), and capture/analyze the exchanged
frames/packets in Wireshark.

2) Objectives

Physically connect two systems via a switch.

Configure IPv4 addresses from a private range (RFC 1918).

Test reachability with ping.


Capture ARP and ICMP traffic.

Decode Ethernet, IPv4, and ICMP header fields.

3) Topology

css
CopyEdit
PC-A <----> Switch <----> PC-B

Interfaces (example):

PC-A: Ethernet0

PC-B: Ethernet0

4) Requirements

2 PCs / VMs with Ethernet NICs (Windows or Linux).

1 unmanaged switch (any simple L2 switch will do) + 2 straight-through


Ethernet cables.

Wireshark installed on at least one PC (capture on both if available).

Admin privileges to set IP addresses and run Wireshark.

5) IP Addressing Plan (example)

Use any private block; here we choose 192.168.10.0/24:

PC-A: 192.168.10.1/24

PC-B: 192.168.10.2/24

Gateway: not required (same LAN); leave blank or 0.0.0.0.

6) Procedure
A. Physical setup

Power on the switch.

Connect PC-A and PC-B to any two switch ports using Ethernet cables.

Verify link lights on NICs and switch ports.

B. Configure IP addresses

Windows (PowerShell as Administrator):

powershell
CopyEdit
Get-NetAdapter
New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress 192.168.10.1 -
PrefixLength 24
# On PC-B:
New-NetIPAddress -InterfaceAlias "Ethernet" -IPAddress 192.168.10.2 -
PrefixLength 24

(Or via Control Panel → Network & Internet → Change adapter settings → IPv4 →
Manual.)

Linux:

bash
CopyEdit
# PC-A
sudo ip addr add 192.168.10.1/24 dev eth0
sudo ip link set eth0 up
# PC-B
sudo ip addr add 192.168.10.2/24 dev eth0
sudo ip link set eth0 up

Verify:

bash
CopyEdit
# Windows
ipconfig
# Linux
ip addr show dev eth0

C. Start Wireshark capture


Open Wireshark on PC-A.

Select the active Ethernet interface.

(Optional) Set a capture filter to reduce noise:

arp or icmp

Click Start.

D. Ping test

From PC-A:

bash
CopyEdit
ping 192.168.10.2

From PC-B (optional):

bash
CopyEdit
ping 192.168.10.1

Observe that the first ping may take slightly longer because ARP resolution
happens before ICMP.

E. Stop capture & save

Stop Wireshark after a few replies.

Save as two_host_switch_ping.pcapng.

7) What you should see in Wireshark

(i) ARP exchange

ARP Request (Broadcast):

Ethernet

Dst MAC: ff:ff:ff:ff:ff:ff (broadcast)

Src MAC: MAC of PC-A

Type: 0x0806 (ARP)


ARP

Opcode: 1 (request)

Sender IP: 192.168.10.1

Target IP: 192.168.10.2

Question: “Who has 192.168.10.2? Tell 192.168.10.1”

ARP Reply (Unicast):

Ethernet

Dst MAC: MAC of PC-A

Src MAC: MAC of PC-B

Type: 0x0806

ARP

Opcode: 2 (reply)

Sender IP/MAC: 192.168.10.2 / MAC of PC-B

After this, the ARP cache on PC-A will map 192.168.10.2 -> <PC-B MAC>.

(ii) ICMP Echo / Echo Reply

For each ping:

Ethernet

Type: 0x0800 (IPv4)

Src MAC: PC-A MAC

Dst MAC: PC-B MAC

IPv4 Header

Version: 4

IHL: 5 (if no options) ⇒ 20 bytes


DSCP/ECN: Usually 0

Total Length: e.g., 84 bytes (depends on OS/ping size)

Identification: (varies per packet)

Flags/Fragment Offset: DF may be set; usually no fragmentation on


LAN

TTL: ~128 (Windows) or 64 (Linux)

Protocol: 1 (ICMP)

Header Checksum

Source IP: 192.168.10.1

Destination IP: 192.168.10.2

ICMP Header

Type: 8 (Echo Request) / 0 (Echo Reply)

Code: 0

Checksum

Identifier & Sequence Number

Data: typically ASCII bytes (e.g., 56 bytes in Linux default)

8) Useful Wireshark Display Filters

arp — show only ARP frames.

icmp — show only ICMP packets.

ip.addr == 192.168.10.1 && icmp

eth.addr == aa:bb:cc:dd:ee:ff

ip.flags.df == 1 — show packets with DF (Don't Fragment) set.

frame.number == X — jump to a specific frame.


9) Sample Observation Table

Frame # Proto Src MAC/IP Dst MAC/IP Key Fields


1 ARP 192.168.10.1 192.168.10.2 (asked) ARP Request, Broadcast
2 ARP 192.168.10.2 192.168.10.1 ARP Reply
3 ICMP 192.168.10.1 192.168.10.2 Echo Request, TTL=128
4 ICMP 192.168.10.2 192.168.10.1 Echo Reply, TTL=64

10) Troubleshooting

No link lights: bad cable/NIC or disabled interface.

Ping fails:

Wrong subnet mask (must both be /24 here).

Firewalls blocking ICMP (enable/allow ping).

ARP cache stale—clear with arp -d * (Windows) / ip neigh flush all


(Linux).

No packets in Wireshark: captured wrong interface, or running without admin


privileges.

11) Result

Two hosts on the same switch were successfully configured with private IPv4
addresses, verified with ICMP ping, and the ARP + ICMP packet flows were
captured and fully analyzed at Ethernet, IPv4, and ICMP layers.

5. INSTALL TELNET ON ONE OF THE SYSTEMS CONNECTED


BY A SWITCH AND TELNET TO IT FROM THE OTHER
SYSTEM.USING WIRESHARK, CAPTURE THE PACKETS AND
ANALYZE THE TCP 3 WAY HANDSHAKE FOR CONNECTION
ESTTABLISHMENT AND TEAR SOWN

1) Aim

Install and run Telnet on one host, connect to it from another host on the same
switch, and capture the traffic with Wireshark to analyze:

The TCP 3-way handshake (SYN → SYN/ACK → ACK) used for


connection establishment

The TCP connection teardown (FIN/ACK … FIN/ACK) — or RST if


aborted

2) Network Topology

css
CopyEdit
PC-A (client) <----> Switch <----> PC-B (Telnet server)

Both hosts are already assigned private IPs (from your previous experiment), e.g.:

PC-A: 192.168.10.1/24

PC-B: 192.168.10.2/24

3) Requirements

2 PCs (Windows or Linux) connected via a switch

Wireshark (installed on at least one PC; ideally on the server side to see full
flow)

Telnet server on PC-B, Telnet client on PC-A

Admin/root privileges
4) Installation & Configuration

A) Linux

On PC-B (server):

bash
CopyEdit
# Ubuntu/Debian
sudo apt update
sudo apt install telnetd # (BSD telnetd) or openbsd-inetd + telnetd
sudo systemctl enable inetd --now # if using inetd/openbsd-inetd# confirm it's
listening on TCP/23
sudo ss -ltnp | grep :23

On PC-A (client):

bash
CopyEdit
sudo apt install telnet

B) Windows

Client: Windows often ships with Telnet client disabled. Enable from:
Control Panel → Programs and Features → Turn Windows features on or off
→ Telnet Client.

Server: Windows no longer ships Telnet Server by default. Use a lightweight


alternative (e.g., WinSSHD/freeSSHd with Telnet enabled) or run a Linux
VM/container as the server.

(If your lab insists on Windows-only, you may set up a Telnet server on Windows
using third-party tools, or run a Linux VM as the Telnet host.)

5) Wireshark Capture

Launch Wireshark on PC-B (server) or PC-A (client).

Select the active Ethernet interface.

(Optional) Capture filter to limit traffic:

nginx
CopyEdit
tcp port 23

or leave blank and use display filters later.

Click Start.

6) Perform Telnet Session

From PC-A (client):

bash
CopyEdit
telnet 192.168.10.2 23

You should see a login banner/prompt (depends on telnetd config). Type a few
characters/commands, then logout or press Ctrl-] then quit to close.

Stop Wireshark capture and save it as telnet_tcp_handshake.pcapng.

7) Analyze in Wireshark

A) Useful display filters

Handshake only:

ini
CopyEdit
tcp.flags.syn == 1

Show just Telnet TCP stream:

ini
CopyEdit
tcp.port == 23

or right-click any Telnet packet → Follow → TCP Stream.

Teardown packets:

ini
CopyEdit
tcp.flags.fin == 1 or tcp.flags.rst == 1

B) TCP 3-Way Handshake (what to look for)

Step Packet Flags Key fields to examine


Client → Seq=x, ACK=0 (not valid); MSS, Window Scale,
1 SYN
Server SACK Permitted, Timestamps options
Server → SYN,
2 Seq=y, Ack=x+1; Options (often symmetric to client)
Client ACK
Client →
3 ACK Seq=x+1, Ack=y+1, no data
Server

In Wireshark “Packet Details” pane, expand:

Ethernet → IP → Transmission Control Protocol

Look at TCP Options (common: MSS, Window Scale, SACK Permitted,


Timestamps)

Note Initial Window Size, Window Scaling factor, Calculated window size

Example (relative sequence numbers enabled):

Frame 10: 192.168.10.1 → 192.168.10.2 TCP [SYN] Seq=0, Win=64240,


MSS=1460, WS=128, SACK_PERM=1, TSval=1000

Frame 11: 192.168.10.2 → 192.168.10.1 TCP [SYN, ACK] Seq=0, Ack=1,


Win=65160, MSS=1460, WS=128, SACK_PERM=1, TSval=2000

Frame 12: 192.168.10.1 → 192.168.10.2 TCP [ACK] Seq=1, Ack=1,


Win=64240, TSval=1010

(Numbers are illustrative; yours will differ.)

C) Data transfer phase

Telnet is cleartext. You can inspect keystrokes and server responses in Follow
TCP Stream.

You’ll see PSH, ACK flags frequently as interactive data is pushed.

D) TCP Teardown (FIN/ACK)

A graceful close usually looks like:

FIN, ACK from the side that closes first (say client).
Seq = last_byte_sent + 1, Ack = last_byte_received + 1

ACK from the peer (server).

FIN, ACK from the peer (server).

ACK from the original side (client).

(Sometimes a side sends a RST to abort. Note the flag and reason.)

Typical filter to see all FIN/RST:

ini
CopyEdit
tcp.flags.fin == 1 or tcp.flags.rst == 1

Example (relative numbers):

# Dir Flags Seq Ack


50 Client → Server FIN, ACK 105 210
51 Server → Client ACK 210 106
52 Server → Client FIN, ACK 210 106
53 Client → Server ACK 106 211

8) Sample Observation Table

Frame Src IP:Port → Dst Seq Ack Options


Flags Window
# IP:Port (rel) (rel) (MSS/WS/SACK/TS)
192.168.10.1:50000 → MSS=1460, WS=128,
10 SYN 0 0 64240
192.168.10.2:23 SACK, TS
192.168.10.2:23 → SYN, MSS=1460, WS=128,
11 0 1 65160
192.168.10.1:50000 ACK SACK, TS
192.168.10.1:50000 →
12 ACK 1 1 64240 TS
192.168.10.2:23
PSH,
… … … … … …
ACK
192.168.10.1:50000 → FIN,
50 105 210 … …
192.168.10.2:23 ACK
192.168.10.2:23 →
51 ACK 210 106 … …
192.168.10.1:50000
192.168.10.2:23 → FIN,
52 210 106 … …
192.168.10.1:50000 ACK
192.168.10.1:50000 →
53 ACK 106 211 … …
192.168.10.2:23
9) Troubleshooting

Cannot connect:

Telnet server not running or blocked by firewall.

Wrong IP/port (default Telnet is TCP/23).

No packets in Wireshark:

Wrong capture interface or no admin privileges.

RST observed immediately:

Server not listening on port 23, or TCP wrappers/inetd disallows


connection.

“Connection closed by foreign host”:

Server/inetd closed session after login failure/timeouts.

10) Result

Successfully installed and ran Telnet between two hosts on the same switch, captured
the traffic, and analyzed the TCP 3-way handshake and 4-way termination (or
RST) using Wireshark, identifying key header fields (flags, sequence/ack numbers,
window, options).

You might also like