DCN Notes
DCN Notes
DCN Notes
PING COMMAND:
• The ping command is a network diagnostic tool used to test the reachability
and latency (response time) of a remote host or IP address. It is available on
most operating systems, including Windows, macOS, and Linux.
• When you execute the ping command followed by a target host or IP address,
the command sends out small packets of data to the specified destination.
The target host then responds to these packets, allowing you to measure the
time it takes for the packets to reach the destination and return.
1. Basic Ping:
ping <host or IP>
This command sends ICMP echo requests to the specified host or IP address and
displays the round-trip time (RTT) for each reply. It continues to send echo requests
until interrupted.
2 / 73
TRACEROUTE:
• Traceroute is a network diagnostic tool used to track the path that packets
take from your computer to a target host or IP address on a network. It
provides information about each hop (router) along the path, showing the IP
addresses and response times for each hop.
• To use the traceroute command in Linux, follow these steps:
• Open a terminal: Launch a terminal application on your Linux system. You can
typically find it in the applications menu or by using the search function.
4 / 73
• Run the traceroute command: In the terminal, type the following command:
traceroute <host or IP>
• Replace <host or IP> with the target host or IP address you want to trace the
route to. For example
traceroute www.example.com
• View the output: Press Enter to execute the command. The traceroute
command will start sending packets to the target and display the information
about each hop in the route. The output will include the hop number, IP
address, and round-trip time (RTT) for each hop.
• Analyze the output: Review the output to identify the route taken by the
packets and examine the RTT values. Higher RTT values may indicate network
congestion or latency at that particular hop.
• Stop the traceroute: The traceroute command will continue sending packets
until it reaches the maximum hop limit (usually 30 hops) or until you interrupt
it manually by pressing Ctrl+C in the terminal.
• Note: The traceroute command in Linux may require administrative (root)
privileges to function properly. If you encounter any issues or receive
"Permission denied" errors, try executing the command with sudo:
sudo traceroute <host or IP>
Using sudo will prompt you to enter your password before executing the command.
5 / 73
NETSTAT:
The netstat command allows you to monitor and analyze various aspects of network
activity on your system. It provides details such as active network connections,
listening ports, routing tables, and network interface statistics. By using netstat, you
can gather valuable information about network performance, troubleshooting
network issues, and identifying active connections.
Here are some common uses of the netstat command:
1. Displaying Active Network Connections:
netstat -a
This command shows all active network connections, including TCP, UDP, and Unix
domain sockets.
For example:
netstat -a
This command will display all active network connections.
DIG:
• The dig command, short for "Domain Information Groper," is a command-
line network administration tool used to perform DNS (Domain Name
System) queries.
• It is commonly available on Unix-like operating systems, including Linux and
macOS.
• The dig command allows you to retrieve various types of DNS information
from DNS servers.
• It provides a flexible and powerful way to query DNS records, troubleshoot
DNS-related issues, and gather DNS-related information
8 / 73
IFCONFIG:
ifconfig (interface configuration) is a command-line tool used to configure and
display the network interface parameters on a Unix-like system. It allows you to
view and modify the IP address, network masks, network interfaces, and other
network-related configurations.
IWCONFIG:
iwconfig is a command-line tool used to configure and display wireless network
interface parameters on Linux systems. It provides information about wireless
interfaces, such as SSID (network name), mode, channel, encryption, and signal
strength.
ROUTE:
Route is a command-line tool used to view and manipulate the IP routing table on
a Unix-like system. It allows you to examine and modify the routing information
used by the operating system to determine how network packets are forwarded
between different networks or subnets
9 / 73
MTR:
MTR (My traceroute) is a command-line network diagnostic tool that combines
the functionality of ping and traceroute. It continuously sends ICMP echo requests
to the target host while providing detailed information about each hop in the
route, including round-trip times, packet loss, and network latency
Result:
In conclusion, network command line tools are essential utilities for network
administrators, developers, and users who need to perform network-related tasks,
diagnostics, and troubleshooting from the command line interface. These network
command tools are tested and verified.
10 / 73
PROCEDURE:
• The Ping application should send ICMP Echo Request packetsto a specified
target host or IP address and measure the round-trip time (RTT) for each
packet.
• The application should display the RTT for each packet received, as well as
the overall statistics, including packet loss percentage and average RTT.
• The Traceroute application should send UDP packets with increasing TTL
values to a specified target host or IP address and print out the
intermediate hops along the path.
• The application should display the IP address or hostname of each
intermediate hop and the round-trip time (RTT) for each hop.
CODE
PING
import subprocess
from twisted.internet import reactor, defer
class PingProtocol:
def __init__(self):
self.deferred = defer.Deferred()
def print_result(result):
print(result.decode())
def print_error(failure):
print(failure)
11 / 73
protocol = PingProtocol()
protocol.ping('google.com')
protocol.deferred.addCallbacks(print_result, print_error)
reactor.run()
TRACEROUTE
import subprocess
from twisted.internet import reactor, defer
class TracerouteCmd:
def __init__(self):
self.deferred = defer.Deferred()
def print_result(result):
print(result.decode())
def print_error(failure):
print(failure)
protocol = TracerouteCmd()
protocol.traceroute('google.com')
protocol.deferred.addCallbacks(print_result, print_error)
reactor.run()
12 / 73
OUTPUT
RESULT
Hence, the ping and traceroute commands are implemented using twisted python
and verified the output successfully.
13 / 73
PROCEDURE:
1. Start with an empty network topology.
2. Determine the number of nodes or devices to be included in the network.
3. Decide on the type of topology to construct (e.g., star, ring, bus, mesh, tree).
4. Create the nodes or devices for the network and assign unique identifiers to
each node.
5. If using a pre-defined topology (e.g., star), connect each node to a central
node or hub.
6. If using a dynamic topology (e.g., mesh), determine the connection scheme
based on your requirements.
7. For each node, determine its connections or neighbors based on the chosen
topology.
8. Establish the connections between nodes by creating links or channels.
9. Assign appropriate parameters to the links, such as bandwidth, latency, and
reliability.
10.Store or represent the network topology in a suitable data structure, such as
a graph or adjacency list.
11.Provide methods or functions to access and manipulate the network
topology as needed.
12.Optionally, visualize or display the network topology using appropriate tools
or libraries.
13.Test the constructed network topology by performing simulations or
running network protocols on it.
14.Iterate and refine the topology construction process as necessary based on
the desired network characteristics and requirements.
14 / 73
CODE
BUS TOPOLOGY:
class DropLink(protocol.Protocol):
def __init__(self, factory):
self.factory = factory
self.name = None
def connectionMade(self):
self.factory.clients.append(self)
print("New client connected to bus backbone.")
class BusBackbone(protocol.Factory):
15 / 73
def __init__(self):
self.clients = []
if __name__ == "__main__":
reactor.listenTCP(8000, BusBackbone())
print("Bus server started.")
print("Enter your name as first message to register. To send a message to a
particular username use '@username: message'.")
reactor.run()
MESH TOPOLOGY:
class MeshProtocol(protocol.Protocol):
def __init__(self, factory):
self.factory = factory
self.name = None
def connectionMade(self):
self.factory.clients.append(self)
print("New client connected.")
client.transport.write(f"(Private) {self.name}:
{message}\n".encode())
break
else:
self.transport.write(f"Error: User {recipient} not
found.\n".encode())
class MeshFactory(protocol.Factory):
def __init__(self):
self.clients = []
if __name__ == "__main__":
reactor.listenTCP(8000, MeshFactory())
print("Bus server started.")
print("Enter your name as first message to register. To send a message to a
particular username use '@username: message'.")
reactor.run()
STAR TOPOLOGY:
class StarProtocol(protocol.Protocol):
def __init__(self, factory):
self.factory = factory # factory that stores all the clients connected
to the server
self.name = None # name of the client that will connect to the server
def connectionMade(self):
'''establishing a connection to the server'''
print('New client connected: ', self.transport.getPeer())
self.factory.clients.append(self)
if not self.name:
self.name = message
print(self.name, ' has connected to the server.') # if the client
has not connected
else:
if message.startswith('@'):
# already existing client sends a message
'''one client will send message to another client '''
recipient, private_message = message[1:].split(":", 1)
self.sendthroughServer(recipient, private_message)
else:
'''if destination is not specified, the message is simply sent to
the server.'''
self.transport.write(message)
class StarFactory(protocol.Factory):
def __init__(self):
self.clients = []
if __name__ == "__main__":
reactor.listenTCP(8080, StarFactory())
print("Server started. Listening on port 8080...")
print("Enter client name to register. Enter @ before the starting of a
message to send message to another client.")
reactor.run()
18 / 73
RING TOPLOGY:
class RingProtocol(protocol.Protocol):
def __init__(self, factory):
self.factory = factory
self.name = None
def connectionMade(self):
print('New client connected: ', self.transport.getPeer())
self.factory.clients.append(self)
client.transport.write(f"(Private) {self.name}:
{message}\n".encode())
break
else:
self.transport.write(f"Error: User {recipient} not
found.\n".encode())
class RingFactory(protocol.Factory):
def __init__(self):
self.clients = []
self.names = []
if __name__ == "__main__":
reactor.listenTCP(8080, RingFactory())
print("Server started. Listening on port 8080...")
print("Enter client name to register. Enter @ before the starting of a
message to send message to another client.")
reactor.run()
OUTPUT:
20 / 73
RESULT:
Hence, the four basic network topologies such as Star, Mesh, Ring and Bus have
been implemented using Twisted Python and verified the output successfully.
21 / 73
AIM:
PROCEDURE
It is designed to send packets across the internet and ensure the successful
delivery of data and messages over network.
22 / 73
b) ARP packets
c) DNS
Domain Name System (DNS) turns domain names into IP addresses, which allow
browsers to get to websites and other internet resources. Every device on the
internet has an IP address, which other devices can use to locate the device.
23 / 73
d) UDP
UDP is a short form for User Datagram protocol. It is one of the simplest transport
layer protocol. It is a connectionless and unreliable transport protocol.
e) HTTP
f) FTP
FTP (File Transfer Protocol) is a network protocol for transmitting files between
computers over Transmission Control Protocol/Internet Protocol (TCP/IP)
connections.
24 / 73
g) SMTP
Result:
Thus, the required network packets has been captured and analysed using
Wireshark.
25 / 73
PROCEDURE:
1. Create an account on CISCO website.
2. Click on the installation link after logging in:
https://skillsforall.com/resources/lab- downloads?courseLang=en-US.
3. Connect devices as per the topology.
4. Basic configuration of the devices.
5. Assign IP address to the PC’s.
6. Test and verify the network connectivity (ping command)
Initial:
Final:
27 / 73
Result:
Hence, the given topology was implemented successfully using CISCO packet
tracer.
28 / 73
SOCKET PROGRAMMING:
• A socket is a communications connection point (endpoint) that you can
name and address in a network.
• Socket programming shows how to use socket APIs to establish
communication links between remote and local processes. One socket
(node) listens on a particular port at an IP, while the other socket reaches
out to the other to form a connection. The server forms the listener socket
while the client reaches out to the server.
• In socket programming, there are typically two roles: the client and the
server. Client: The client initiates a connection to a server. It can send
requests or messages to the server and receive responses.
• Server: The server listens for incoming connections from clients. It accepts
connections, processes client requests, and sends back responses.
RESULT
Thus, the study of socket programming and client-server model have been done.
31 / 73
PROCEDURE:
ECHO CLIENT/SERVER
1. Based on the IP Address and Port Number the connection is established
between the Server and Client.
2. Port Number should be same in Server and Client.
3. Local Host should be specified in Client.
4. Client will have its data echoed back to server.
CHAT SERVER/CLIENT
1. For every client joining the server should be displayed and notified in the
chatroom with their names, for the clients who are already available.
2. All the messages sent by each client is listed out with their name.
Every message sent by each client is displayed to all the others present in
the chat room.
3. ‘/quit’ when entered can make the client lose connection with the chat
server.
FILE TRANSFER
1. initialize the server with a port number and directory path.
2. Handle the connection events (connection made, lost, and data received).
3. Implement the FTP commands (e.g., LIST, RETR, STOR) to handle client
requests.
4. Provide methods to manage file transfers and directory operations.
5. Run the server using reactor.listenTCP with the specified port number.
32 / 73
CODES
ECHO
echoserver.py
from twisted.internet import protocol,reactor
class echo(protocol.Protocol):
def dataReceived(self, data):
print("Message from Client -", data.decode())
print("Client Connected!")
ack_msg = f"{data.decode()}"
ack = "ACK[" + ack_msg + "]"
print("Acknoledgement Sent!")
self.transport.write(ack.encode())
class echofactory(protocol.Factory):
def buildProtocol(self, addr):
return echo()
reactor.listenTCP(8000,echofactory())
reactor.run()
echoclient.py
from twisted.internet import reactor, protocol
class EchoClient(protocol.Protocol):
def connectionMade(self):
msg = input("Enter the message to Server - ")
self.transport.write(msg.encode())
def dataReceived(self, data):
print ("Acknoledgement from Server -", data.decode())
self.transport.loseConnection()
class EchoFactory(protocol.ClientFactory):
def buildProtocol(self, addr):
return EchoClient()
def clientConnectionFailed(self, connector, reason):
print ("Connection failed.")
reactor.stop()
def clientConnectionLost(self, connector, reason):
print ("Connection lost.")
reactor.stop()
reactor.connectTCP("localhost", 8000, EchoFactory())
reactor.run()
33 / 73
CHAT
from twisted.internet import reactor, protocol
from twisted.protocols.basic import LineOnlyReceiver
class ChatProtocol(LineOnlyReceiver):
def __init__(self, factory):
self.factory = factory
self.name = None
self.state = "GETNAME"
self.client = None
def connectionMade(self):
self.sendLine("What's your name?".encode())
def connectionLost(self, reason):
if self.name in self.factory.users:
del self.factory.users[self.name]
self.broadcastMessage(f"{self.name} has left the chat room.")
def lineReceived(self, line):
if self.state == "GETNAME":
self.handle_GETNAME(line.decode())
else:
self.handle_CHAT(line.decode())
def handle_GETNAME(self, name):
if name in self.factory.users:
self.sendLine("Name already taken, please choose another
name.".encode())
return
self.sendLine(f"Welcome, {name}!".encode())
self.broadcastMessage(f"{name} has joined the chat room.")
self.name = name
self.factory.users[name] = self
self.state = "CHAT"
def handle_CHAT(self, message):
if message.lower() == "/quit":
self.transport.loseConnection()
else:
message = f"<{self.name}> {message}"
self.broadcastMessage(message)
def broadcastMessage(self, message):
for name, protocol in self.factory.users.items():
if protocol != self:
protocol.sendLine(message.encode())
def connectionMade(self):
self.sendLine("Connected to the chat server. Type '/quit' to
exit.".encode())
self.factory.clients.append(self)
def connectionLost(self, reason):
self.factory.clients.remove(self)
34 / 73
class ChatFactory(protocol.Factory):
def __init__(self):
self.users = {}
self.clients = []
def buildProtocol(self, addr):
return ChatProtocol(self)
def broadcastMessage(self, message):
for client in self.clients:
client.sendLine(message.encode())
if __name__ == "__main__":
reactor.listenTCP(9000, ChatFactory())
print("Chat server started. Listening on port 9000...")
reactor.run()
FILE TRANSFER
ftpserver.py
from twisted.internet import reactor, protocol
import os
import time
class FileTransferProtocol(protocol.Protocol):
def connectionMade(self):
print("Client connected.")
def dataReceived(self, data):
if data == b"SEND":
self.transport.write(b"READY")
self.transferFile = True
self.startTime = time.time() # Start measuring time
elif self.transferFile:
with open("received_file.txt", "wb") as f:
f.write(data)
self.transport.write(b"RECEIVED")
self.transferFile = False
endTime = time.time() # Stop measuring time
rtt = endTime - self.startTime
print("Round trip time:", rtt)
else:
self.transport.write(b"ERROR")
class FileTransferFactory(protocol.Factory):
def buildProtocol(self, addr):
return FileTransferProtocol()
if __name__ == "__main__":
reactor.listenTCP(7000, FileTransferFactory())
print("Server started.")
reactor.run()
35 / 73
ftpclient.py
from twisted.internet import reactor, protocol
import os
import time
class FileTransferClientProtocol(protocol.Protocol):
def connectionMade(self):
self.startTime = time.time() # Start measuring time
try:
f = open("myfile.txt", "rb")
self.fileData = f.read()
f.close()
if len(self.fileData) == 0:
print("File is empty.")
self.transport.loseConnection()
else:
self.transport.write(b"SEND")
except FileNotFoundError:
print("File not found.")
self.transport.loseConnection()
class FileTransferClientFactory(protocol.ClientFactory):
protocol = FileTransferClientProtocol
if __name__ == "__main__":
reactor.connectTCP("localhost", 7000, FileTransferClientFactory())
reactor.run()
36 / 73
OUTPUT:
ECHO
CHAT
FILE TRANSFER
RESULT:
The TCP Echo Server and Echo Client for Single Server, Chat Server and File Transfer
applications have been implemented and tested successfully using Twisted Python.
37 / 73
PROCEDURE:
ECHO
1. Based on the IP Address and Port Number the connection is established
between the Server and Client.
2. Port Number should be same in Server and Client.
3. Local Host should be specified in Client.
4. Client will have its data echoed back to server.
CHAT
1. Initialize the server with a port number.
2. Create a socket using UDP protocol.
3. Bind the socket to the server's IP address and port number.
4. Create an empty list to store the client addresses.
5. Start a loop to listen for incoming messages:
6. Receive a message from a client.
7. Check if the client address is already in the list of client addresses.
8. If not, add the client address to the list
9. Broadcast the received message to all clients in the list, except the sender.
FILE TRANSFER
1. Initialize the server with a port number.
2. Create a socket using UDP protocol.
3. Bind the socket to the server's IP address and port number.
4. Start a loop to listen for incoming requests:
5. Receive a request from a client
38 / 73
6. Parse the request to identify the FTP command (e.g., LIST, RETR, STOR)
7. Handle the request based on the FTP command:
8. For LIST command, retrieve the directory listing and send it to the client.
9. For RETR command, read the requested file and send it to the client.
10. For STOR command, receive the file from the client and save it on the server
11. Send a response to the client indicating the success or failure of the request.
CODE
ECHO
echoserver.py
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
class EchoUDP(DatagramProtocol):
def datagramReceived(self, datagram, address):
print("Datagram: ",datagram.decode())
self.transport.write(datagram, address)
def main():
reactor.listenUDP(8000, EchoUDP())
print("Started to listen")
reactor.run()
if __name__ == '__main__':
main()
echoclient.py
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
import time
class EchoClientDatagramProtocol(DatagramProtocol):
a = input("Enter the message: ")
strings = [f"{a}".encode()]
def startProtocol(self):
self.transport.connect('127.0.0.1', 8000)
self.sendDatagram()
def sendDatagram(self):
if len(self.strings):
datagram = self.strings.pop(0)
self.timestamp = time.time()
self.transport.write(datagram)
else:
39 / 73
reactor.stop()
def datagramReceived(self, datagram, host):
rtt = time.time() - self.timestamp
print('Datagram received: ', datagram.decode(), f"< RTT: {rtt:.4f}s >")
self.sendDatagram()
def main():
protocol = EchoClientDatagramProtocol()
t = reactor.listenUDP(0, protocol)
reactor.run()
if __name__ == '__main__':
main()
CHAT
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
class ChatServer(DatagramProtocol):
def __init__(self):
self.users = {} # maps user addresses to usernames
def datagramReceived(self, data, addr):
message = data.decode('utf-8').strip()
if addr in self.users:
# if the user is already registered, broadcast the message to all other
users
username = self.users[addr]
message = f"<{username}> {message}"
for user_addr in self.users:
if user_addr != addr:
self.transport.write(message.encode('utf-8'), user_addr)
else:
# if the user is not registered, use the first message as their username
self.users[addr] = message.split()[0]
self.transport.write(b"Welcome to the chat!\n", addr)
if __name__ == "__main__":
reactor.listenUDP(5000, ChatServer())
print("Server started.")
reactor.run()
40 / 73
FILE TRANSFER
ftpserver.py
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
import pickle
import time
import os
class EchoUDP(DatagramProtocol):
def datagramReceived(self, datagram, address):
receive_time = time.time() # Get the receive timestamp
file_name, file_data, send_time = pickle.loads(datagram)
print(f'{file_name} received!')
rtt = receive_time - send_time # Calculate RTT
print(f'RTT: {rtt} seconds')
file_path = file_name.rstrip('.txt') + 'Server.txt'
with open(file_path, 'wb') as file:
file.write(b'file_data')
file_size = os.path.getsize(file_path) # File size
print(f'{file_name} saved. File size: {file_size} bytes')
def main():
reactor.listenUDP(1234, EchoUDP())
print("UDP server started.")
reactor.run()
if __name__ == '__main__':
main()
ftpclient.py
from __future__ import print_function
import pickle
import time
from twisted.internet.protocol import DatagramProtocol
from twisted.internet import reactor
class EchoClientDatagramProtocol(DatagramProtocol):
def startProtocol(self):
self.transport.connect('127.0.0.1', 1234)
self.sendDatagram()
def sendDatagram(self):
file_name = input('Enter file name to send: ')
file = open(f'{file_name}', 'r')
file_data = file.read()
send_time = time.time() # Get the send timestamp
41 / 73
def main():
protocol = EchoClientDatagramProtocol()
t = reactor.listenUDP(0, protocol)
reactor.run()
if __name__ == '__main__':
main()
OUTPUT:
ECHO
CHAT
42 / 73
FTP
RESULT:
The UDP Echo Server and Echo Client for Single Server, Single Client and Single
Server, Multiple Client, Chat Server and File Transfer applications have been
implemented and tested successfully using Twisted Python
43 / 73
PROCEDURE
ARP:
a. Initialize the ARP module.
b. Start a loop to listen for incoming ARP requests:
c. Receive an ARP request packet.
d. Extract the sender's IP and MAC addresses from the request packet.
e. Check if the target IP address matches the IP address of the local host:
f. If yes, construct an ARP response packet with the local host's MAC
address and the sender's IP address.
g. Send the ARP response packet back to the sender.
RARP
1. Initialize the RARP module.
2. Start a loop to listen for incoming RARP requests:
3. Receive a RARP request packet.
4. Extract the sender's MAC address from the request packet.
5. Check if the target MAC address matches the MAC address of the local host
6. If yes, construct a RARP response packet with the local host's IP address.
7. Send the RARP response packet back to the sender
44 / 73
CODE
ARP SERVER
from twisted.internet import reactor, protocol
import struct
class ARPServer(protocol.Protocol):
def connectionMade(self):
print("client connected")
arp_packet_format = "!6s4s6s4s"
arp_data = struct.unpack(arp_packet_format, rec.get('req_format'))
(
Source_Hardware_Address,
Source_Protocol_Address,
Target_Hardware_Address,
Target_Protocol_Address
) = arp_data
if rec.get('req') == "ARP_REQUEST":
for i in arp_table:
if i == rec.get('ip'):
mac_address = arp_table[i]
else:
continue
l = []
for i in mac_address.split(':'):
l.append(int(i))
ip_address = rec.get('ip')
response_packet = struct.pack(
arp_packet_format,
45 / 73
Target_Hardware_Address,
Target_Protocol_Address,
Source_Hardware_Address,
bytes(l),
)
if mac_address != '0:0:0:0:0:0':
arp_reply = f'ARP_REPLY {ip_address} {mac_address}\n'
to_client['data'] = arp_reply
self.transport.write(str(to_client).encode())
print("MAC Address sent")
else:
self.transport.write(b'hi')
print("Invalid IP received")
class ARPServerFactory(protocol.Factory):
def buildProtocol(self, addr):
return ARPServer()
arp_table = {}
arp_table['192.168.1.1'] = '00:11:22:33:44:55'
reactor.listenTCP(1234, ARPServerFactory())
reactor.run()
ARP CLIENT
from twisted.internet import reactor, protocol
import struct
class ARPClient(protocol.Protocol):
def connectionMade(self):
arp_packet_format = "!6s4s6s4s"
request_packet = struct.pack(
arp_packet_format,
bytes([0, 17, 34, 51, 68, 85]), # Example source hardware address
bytes([0, 0, 0, 0]), # Example source protocol address
bytes([17, 18, 19, 20, 21, 22]), # Example target hardware address
bytes([26, 27, 28, 29]) # Example target protocol address
)
a = input("Enter IP address:")
to_server = {'ip': a, 'req_format': request_packet, 'req': 'ARP_REQUEST'}
self.transport.write(str(to_server).encode())
46 / 73
if recv.get('data').startswith('ARP_REPLY'):
reply_parts = recv.get('data').split()
if len(reply_parts) == 3:
mac_address = reply_parts[2]
ip_address = reply_parts[1]
print(f"Received ARP reply: IP = {ip_address}, MAC =
{mac_address}")
self.transport.loseConnection()
else:
print("Invalid ARP reply")
self.transport.loseConnection()
else:
print("Invalid IP Address given!")
self.transport.loseConnection()
class ARPClientFactory(protocol.ClientFactory):
def buildProtocol(self, addr):
return ARPClient()
RARP SERVER:
from twisted.internet import reactor, protocol
import struct
class RARPServer(protocol.Protocol):
def connectionMade(self):
print("client connected")
rarp_packet_format = "!6s4s6s4s"
rarp_data = struct.unpack(rarp_packet_format, rec.get('req_format'))
(
Source_Hardware_Address,
Source_Protocol_Address,
Target_Hardware_Address,
Target_Protocol_Address
) = rarp_data
if rec.get('req') == "RARP_REQUEST":
for i in rarp_table:
if i == rec.get('mac'):
ip_address = rarp_table[i]
else:
continue
l = []
for i in ip_address.split('.'):
l.append(int(i))
mac_address = rec.get('mac')
response_packet = struct.pack(
rarp_packet_format,
Target_Hardware_Address,
Target_Protocol_Address,
Source_Hardware_Address,
48 / 73
bytes(l),
)
if ip_address != '0.0.0.0':
rarp_reply = f'RARP_REPLY {mac_address} {ip_address}\n'
to_client['data'] = rarp_reply
self.transport.write(str(to_client).encode())
print("IP Address sent")
else:
self.transport.write(b'hi')
print("Invalid MAC received")
class RARPServerFactory(protocol.Factory):
def buildProtocol(self, addr):
return RARPServer()
rarp_table = {}
rarp_table['00:11:22:33:44:55'] = '192.168.1.1'
reactor.listenTCP(1234, RARPServerFactory())
reactor.run()
RARP CLIENT
from twisted.internet import reactor, protocol
import struct
class RARPClient(protocol.Protocol):
def connectionMade(self):
rarp_packet_format = "!6s4s6s4s"
request_packet = struct.pack(
rarp_packet_format,
bytes([00, 11, 22, 33, 44, 55]), # Example source hardware address
bytes([0, 0, 0, 0]), # Example source protocol address
bytes([17, 18, 19, 20, 21, 22]), # Example target hardware address
bytes([26, 27, 28, 29]) # Example target protocol address
)
a = input("Enter MAC address:")
to_server = {'mac': a, 'req_format': request_packet, 'req':
'RARP_REQUEST'}
self.transport.write(str(to_server).encode())
recv = eval(data.decode())
rarp_packet_format = "!6s4s6s4s"
(
Source_Hardware_Address,
Source_Protocol_Address,
Target_Hardware_Address,
Target_Protocol_Address
) = struct.unpack(rarp_packet_format, recv.get('reply_format'))
if recv.get('data').startswith('RARP_REPLY'):
reply_parts = recv.get('data').split()
if len(reply_parts) == 3:
mac_address = reply_parts[1]
ip_address = reply_parts[2]
print(f"Received RARP reply: MAC = {mac_address}, IP =
{ip_address}")
self.transport.loseConnection()
else:
print("Invalid RARP reply")
self.transport.loseConnection()
else:
print("Invalid MAC Address given!")
self.transport.loseConnection()
class RARPClientFactory(protocol.ClientFactory):
def buildProtocol(self, addr):
return RARPClient()
OUTPUT
ARP
RARP
RESULT
Thus, the simulation of ARP/RARP protocols have been implemented and tested
successfully using Twisted Python.
51 / 73
PROCEDURE
1. Sender:
• Initialize with sequence number 0.
• Read data and create a packet.
• Send packet to receiver.
• Start timer.
2. Receiver:
• Wait for packet from sender.
• Receive packet.
• If sequence number matches expected, deliver data and send ACK.
• If sequence number doesn't match expected, discard packet and send
NAK.
3. Sender:
• Wait for ACK/NAK.
• If ACK received, stop timer, update sequence number, read new data,
and repeat.
• If NAK received, resend packet and restart timer.
4. Sender:
• If timeout occurs, resend packet and restart timer.
5. Receiver:
• After sending ACK/NAK, return to step 2.
6. Sender:
52 / 73
CODE
SERVER:
from twisted.internet import reactor, protocol
class StopAndWaitServer(protocol.Protocol):
def connectionMade(self):
print("Client connected:", self.transport.getPeer())
self.send_message()
def send_message(self):
message = input("Enter message: ")
self.transport.write(message.encode())
print("Message sent to client:", message)
self.expected_ack = "ACK"
# self.schedule_resend()
def schedule_resend(self):
self.resend_call = reactor.callLater(5, self.resend_message)
def resend_message(self):
print("ACK not received. Resending message...")
self.send_message()
class StopAndWaitServerFactory(protocol.Factory):
def buildProtocol(self, addr):
return StopAndWaitServer()
server_port = 8000
factory = StopAndWaitServerFactory()
reactor.listenTCP(server_port, factory)
reactor.run()
54 / 73
CLIENT:
from twisted.internet import reactor, protocol
class StopAndWaitClient(protocol.Protocol):
def connectionMade(self):
print("Connected to server.")
self.send_ack()
def send_ack(self):
self.transport.write(input("Enter ack: ").encode())
print("ACK sent")
class StopAndWaitClientFactory(protocol.ClientFactory):
def buildProtocol(self, addr):
return StopAndWaitClient()
server_address = 'localhost'
server_port = 8000
factory = StopAndWaitClientFactory()
reactor.connectTCP(server_address, server_port, factory)
reactor.run()
55 / 73
OUTPUTS
RESULT
Thus, the Stop and Wait and Sliding Window protocols have been implemented
and tested successfully using Twisted Python.
56 / 73
PROCEDURE
o User Input: Obtain the URL of the web page to be downloaded from the
user
o Initialize the program and prepare to download the web page.
o Establish a connection to the web server hosting the requested page.
o Send an HTTP GET request to the server, asking for the contents of the web
page.
o Wait for the server to respond with the requested web page.
o Receive the data in chunks as the server sends them.
o Combine the received chunks of data to form the complete content of the
web page.
o Output the contents of the web page on the screen for the user to see.
CODE :
from twisted.internet import reactor
from twisted.web.client import Agent
from twisted.web.client import readBody
def download_web_page(url):
agent = Agent(reactor)
def handle_response(response):
d = readBody(response) # Read the response body
def process_body(body):
print(body.decode()) # Process the received data
reactor.stop()
d.addCallback(process_body)
return d
def handle_error(error):
print(f"An error occurred: {error}") # Handle any errors
reactor.stop()
d.addCallbacks(handle_response, handle_error)
reactor.run()
if __name__ == "__main__":
download_web_page("http://www.google.com/")
OUTPUT
RESULT
Web page information has successfully been downloaded via HTTP protocol and
implemented using twisted python.
58 / 73
PROCEDURE
1. Define an interface specifying available functions/methods for remote
invocation.
2. Serialize input parameters and return values for transmission.
3. Deserialize received data to obtain original values.
4. Use a client stub/proxy to invoke remote functions/methods.
5. Implement a server stub/skeleton to handle requests and invoke actual
functions/methods.
6. Utilize an RPC framework to manage communication between client and
server.
CODE
SERVER
from twisted.internet import reactor, protocol
class RPCServerProtocol(protocol.Protocol):
def dataReceived(self, data):
request = data.decode().strip()
result = self.processRequest(request)
self.transport.write(result.encode())
class RPCServerFactory(protocol.Factory):
def buildProtocol(self, addr):
return RPCServerProtocol()
if __name__ == "__main__":
59 / 73
reactor.listenTCP(8000, RPCServerFactory())
print("RPC server is running...")
reactor.run()
CLIENT
from twisted.internet import reactor, protocol
class RPCClientProtocol(protocol.Protocol):
def connectionMade(self):
self.transport.write(b"add 10 5")
class RPCClientFactory(protocol.ClientFactory):
protocol = RPCClientProtocol
reactor.run()
OUTPUT
RESULT:
RPC has been successfully implemented using twisted python
60 / 73
PROCEDURE
1. Create an IPv4Network object representing the desired subnet.
2. Define a protocol class (SubnetCheckerProtocol) that inherits from
twisted.internet.protocol.Protocol.
3. Implement the dataReceived method in the protocol class to handle
incoming data from clients.
4. Parse the received data as an IP address.
5. Check if the IP address falls within the defined subnet.
6. Send a response indicating whether the IP address is within the subnet or
outside.
7. Close the connection.
8. Define a factory class (SubnetCheckerFactory) that inherits from
twisted.internet.protocol.Factory.
9. Implement the buildProtocol method in the factory class to create instances
of the protocol class for each connection.
10.Start the reactor, listening on a specific port, and using the factory to handle
incoming connections.
11.Print a message indicating that the subnet checker server is running.
12.Run the reactor.
CODE:
from twisted.internet import reactor, protocol
import ipaddress
SUBNET = ipaddress.IPv4Network("192.168.0.0/24")
class SubnetCheckerProtocol(protocol.Protocol):
def dataReceived(self, data):
ip_address = data.strip().decode()
if self.is_in_subnet(ip_address):
self.transport.write(b"IP address is within the subnet")
else:
self.transport.write(b"IP address is outside the subnet")
self.transport.loseConnection()
try:
ip = ipaddress.IPv4Address(ip_address)
return ip in SUBNET
except ipaddress.AddressValueError:
return False
class SubnetCheckerFactory(protocol.Factory):
def buildProtocol(self, addr):
return SubnetCheckerProtocol()
if __name__ == "__main__":
reactor.listenTCP(8000, SubnetCheckerFactory())
print("Subnet checker server is running...")
reactor.run()
OUTPUT:
RESULT:
An illustration of subnetting has be implemented using Twisted python.
62 / 73
PROCEDURE
DNS
1. Create a server that listens for DNS requests on a specific port.
2. Define a method to handle incoming DNS requests.
3. When a request arrives, read and understand the request.
4. Process the request by performing the necessary logic (e.g., looking up the
IP address associated with the domain name).
5. Prepare a response based on the processing result.
6. Send the response back to the client.
7. Repeat steps 2 to 6 for each new incoming request.
SMTP
1. Set up a server that listens on a specific port (typically port 25) for incoming
connections.
2. Accept incoming client connections.
3. Receive the SMTP commands and email messages from the clients.
4. Parse the commands and messages to extract the necessary information.
5. Perform the appropriate actions based on the received commands (e.g.,
sending acknowledgement, validating recipients, delivering messages).
6. Send back response codes and messages to the client to indicate the status
of the SMTP operation.
7. Repeat steps 3 to 6 for each client connection.
8. Close the connection when the SMTP operation is complete
63 / 73
SNMP
1. The client sends an SNMP GET request to the server.
2. The server receives the request, processes it, and sends an SNMP response
back to the client.
3. Upon receiving the response, the client processes it.
4. The client can then send additional data to the server by using
self.transport.write() within the datagramReceived method.
5. The server receives the additional data and can process it accordingly
CODE:
DNS:
dnsserver.py
from twisted.internet import reactor, protocol
class DNSProtocol(protocol.Protocol):
def dataReceived(self, data):
request = data.strip()
response = self.processRequest(request)
self.transport.write(response)
class DNSFactory(protocol.Factory):
def buildProtocol(self, addr):
return DNSProtocol()
if __name__ == "__main__":
reactor.listenTCP(53, DNSFactory())
print("DNS server is running...")
reactor.run()
dnsclient.py
from twisted.internet import reactor, protocol
64 / 73
class DNSClientProtocol(protocol.Protocol):
def connectionMade(self):
domain = input("Enter a domain name: ")
self.transport.write(domain.encode())
class DNSClientFactory(protocol.ClientFactory):
def buildProtocol(self, addr):
return DNSClientProtocol()
if __name__ == "__main__":
reactor.connectTCP("localhost", 53, DNSClientFactory())
reactor.run()
SMTP:
smtpserver.py
from twisted.internet import protocol, reactor
class SMTPServerProtocol(protocol.Protocol):
def connectionMade(self):
self.transport.write(b'220 smtp.example.com Simple Mail Transfer Service
Ready\r\n')
if request.startswith('HELO') or request.startswith('EHLO'):
self.transport.write(b'250 Hello ' + request.split()[1].encode() +
b', pleased to meet you\r\n')
elif request.startswith('MAIL FROM:'):
self.transport.write(b'250 OK\r\n')
elif request.startswith('RCPT TO:'):
self.transport.write(b'250 OK\r\n')
elif request == 'DATA':
self.transport.write(b'354 Start mail input; end with
<CRLF>.<CRLF>\r\n')
self.state = 'DATA'
elif self.state == 'DATA' and request == '.':
65 / 73
class SMTPServerFactory(protocol.Factory):
def buildProtocol(self, addr):
return SMTPServerProtocol()
if __name__ == '__main__':
reactor.listenTCP(25, SMTPServerFactory())
reactor.run()
smtpclient.py
class SMTPClientProtocol(protocol.Protocol):
def connectionMade(self):
self.sendLine(b'HELO client.example.com')
if response.startswith('250'):
self.sendLine(b'MAIL FROM:<john@example.com>')
elif response.startswith('250'):
self.sendLine(b'RCPT TO:<sarah@example.com>')
elif response.startswith('250'):
self.sendLine(b'DATA')
elif response.startswith('354'):
self.sendLine(b'From: john@example.com\r\n'
b'To: sarah@example.com\r\n'
b'Subject: Hello Sarah\r\n'
b'\r\n'
b'Hi Sarah, how are you doing? Just wanted to say
hello!\r\n'
b'.')
66 / 73
elif response.startswith('250'):
self.sendLine(b'QUIT')
elif response.startswith('221'):
self.transport.loseConnection()
class SMTPClientFactory(protocol.ClientFactory):
def buildProtocol(self, addr):
return SMTPClientProtocol()
if __name__ == '__main__':
reactor.connectTCP('localhost', 25, SMTPClientFactory())
reactor.run()
SNMP:
snmpserver.py
from twisted.internet import protocol, reactor
class SMTPServerProtocol(protocol.Protocol):
def connectionMade(self):
self.transport.write(b'220 smtp.example.com Simple Mail Transfer Service
Ready\r\n')
if request.startswith('HELO') or request.startswith('EHLO'):
self.transport.write(b'250 Hello ' + request.split()[1].encode() +
b', pleased to meet you\r\n')
elif request.startswith('MAIL FROM:'):
self.transport.write(b'250 OK\r\n')
elif request.startswith('RCPT TO:'):
self.transport.write(b'250 OK\r\n')
elif request == 'DATA':
self.transport.write(b'354 Start mail input; end with
<CRLF>.<CRLF>\r\n')
self.state = 'DATA'
elif self.state == 'DATA' and request == '.':
self.transport.write(b'250 OK, message received and queued for
delivery\r\n')
self.state = 'IDLE'
elif request == 'QUIT':
67 / 73
self.transport.write(b'221 Goodbye\r\n')
self.transport.loseConnection()
else:
self.transport.write(b'500 Command not recognized\r\n')
class SMTPServerFactory(protocol.Factory):
def buildProtocol(self, addr):
return SMTPServerProtocol()
if __name__ == '__main__':
reactor.listenTCP(25, SMTPServerFactory())
reactor.run()
smtpclient.py
from twisted.internet import protocol, reactor
class SMTPClientProtocol(protocol.Protocol):
def connectionMade(self):
self.sendLine(b'HELO client.example.com')
if response.startswith('250'):
self.sendLine(b'MAIL FROM:<john@example.com>')
elif response.startswith('250'):
self.sendLine(b'RCPT TO:<sarah@example.com>')
elif response.startswith('250'):
self.sendLine(b'DATA')
elif response.startswith('354'):
self.sendLine(b'From: john@example.com\r\n'
b'To: sarah@example.com\r\n'
b'Subject: Hello Sarah\r\n'
b'\r\n'
b'Hi Sarah, how are you doing? Just wanted to say
hello!\r\n'
b'.')
elif response.startswith('250'):
self.sendLine(b'QUIT')
elif response.startswith('221'):
self.transport.loseConnection()
68 / 73
class SMTPClientFactory(protocol.ClientFactory):
def buildProtocol(self, addr):
return SMTPClientProtocol()
if __name__ == '__main__':
reactor.connectTCP('localhost', 25, SMTPClientFactory())
reactor.run()
OUTPUT:
DNS
SMTP
SNMP
RESULT
DNS, SMTP using TCP and SNMP using UDP have been implemented with Twisted
python
69 / 73
PROCEDURE
Network Simulator (NS):
Network Simulator (NS) is an open-source discrete event network simulator
that is widely used for simulating network protocols, traffic, and behaviour. NS
provides a comprehensive environment for designing, implementing, and
evaluating network models. It allows researchers and network engineers to
experiment with various scenarios and study the performance of network
protocols and algorithms.
Results and Findings: The simulation results obtained from NS provide insights
into the behaviour and effectiveness of various congestion control algorithms.
By comparing different algorithms, researchers can identify their strengths and
weaknesses, enabling them to make informed decisions regarding their
deployment in real-world networks. The results may reveal the impact of
network parameters, traffic patterns, and other factors on the performance of
congestion control mechanisms.
RESULT
Study of Network simulation and congestion control has been performed and
concepts of congestion control have been understood.
71 / 73
PROCEDURE
1. Initialize the protocol with a node ID.
2. Handle connection events (connection made, lost, and data received).
3. Implement the flooding mechanism to send messages periodically to
neighbours.
4. Provide methods to manage neighbours and protocol lifecycle.
5. Set the server and client node IDs.
6. Create protocol instances for the server-side and client-side.
7. Run the server using reactor.listenTCP with the port number and the server
protocol instance.
8. Run the client using reactor.connectTCP with the server's IP address, port
number, and the client protocol instance.
9. Start the event loop with reactor.run().
CODE:
{server side}
class FloodingProtocol(protocol.Protocol):
def __init__(self, node_id):
self.node_id = node_id
self.neighbors = []
def connectionMade(self):
print(f"Node {self.node_id} connected to the network.")
self.startFlooding()
def startFlooding(self):
message = f"Hello from Node {self.node_id}"
self.sendMessage(message)
reactor.callLater(1, self.startFlooding)
def startProtocol(self):
pass
def stopProtocol(self):
reactor.stop()
class FloodingFactory(protocol.Factory):
def __init__(self, node_id):
self.node_id = node_id
if __name__ == "__main__":
node_id = "A" # Replace with the ID of the current node
factory = FloodingFactory(node_id)
reactor.listenTCP(8000, factory) # Replace with the desired port number
reactor.run()
{client side}
class FloodingClient(protocol.Protocol):
def __init__(self, node_id):
self.node_id = node_id
def connectionMade(self):
print(f"Client {self.node_id} connected to the server.")
self.sendMessage()
def sendMessage(self):
message = f"Hello from Client {self.node_id}"
self.transport.write(message.encode())
def startProtocol(self):
pass
def stopProtocol(self):
reactor.stop()
class FloodingClientFactory(protocol.ClientFactory):
def __init__(self, node_id):
self.node_id = node_id
if __name__ == "__main__":
node_id = "C" # Replace with the ID of the client node
factory = FloodingClientFactory(node_id)
reactor.connectTCP("localhost", 8000, factory) # Replace with the IP address
and port of the server
reactor.run()
OUTPUT
RESULT
Flooding algorithm has been successfully implemented using twisted python.