Sie sind auf Seite 1von 73

NCTUNS

# NCTUns 3.0 network simulator # Developed by Network and System Laboratory Department of Computer Science # National Chiao Tung University, Taiwan

I. REQUIREMENT Software:
1. OS Platform: Fedora Core 4 (Red Hat) Linux (with gcc compiler installed) 2. X window system (GNOME/KDE window manager is recommended.) 3. Root privilege 4. bash/tcsh assigned as the user's login shell (for command console function) NOTE: You must be the root user to successfully run install.sh!

Hardware:
1. 256 MB RAM or more (512 MB recommended for running large-network cases) 2. 1.6 GHz Pentium PC or faster 3. 200 MB disk space or more

II. INSTALLATION PROCEDURE


Please refer to INSTALL for the package installation procedure.

III. RUN THE PROGRAMS


1. Set two environment variables. Before running all of the NCTUns 3.0 programs, two environment variables must be set. If you install the NCTUns 3.0 package into the default /usr/local/nctuns directory, in the following description ${where-you-install} should be replaced with /usr/local/nctuns. NCTUNSHOME should be set to ${where-you-install} and LD_LIBRARY_PATH should be set to ${where-you-install}/lib

E.g., if you use tcsh, you can add the following lines to your file setenv NCTUNSHOME ${where-you-install} setenv LD_LIBRARY_PATH ${where-you-install}/lib E.g., if you use bash, you can add the following lines to your export NCTUNSHOME=${where-you-install} export LD_LIBRARY_PATH=${where-you-install}/lib

.cshrc shell configuration

.bashrc shell file

If you do not add these commands to your .cshrc or .bashrc file, you will need to manually set these variables in each opened xterm window before executing a NCTUns 3.0 program. Note that because dispatcher and coordinator MUST be run by the root user, the above environment settings must be added to the ROOT user's shell file. As for the GUI program, it can be run by either a normal user or the root user. In case it is run by a normal user, the above settings should also be added to that user's shell file. 2. Specify the dispatcher's IP address You can open ${where-you-install}/etc/coordinator.cfg and find the following line: 127.0.0.1" ^^^^^^^^^^ On most machines, 127.0.0.1 is the default IP address assigned to the loopback interface lo. As such, this default setting should work for the single-machine mode on most machines. If the lo interface does not work properly on your machine (e.g., the 127.0.0.1 address may not have been automatically assgined to lo), you can (1) manually assign 127.0.0.1 to lo0 by running the "ifconfig lo 127.0.0.1" command, or (2) change the dispatcher IP address in this file to your machine's own IP address (e.g., 140.113.17.5). The effect is the same. If you would like to use the multi-machine mode, you should change the IP address to the IP address of a remote dispatcher. For example, there is a dispatcher located at NSL's simulation service center.You can visit the NCTUns web site (http://NSL.csie.nctu.edu.tw/nctuns.html) to find out that machine's IP address. 3. Now you can run up the dispatcher program, which is located at ${where-youinstall}/bin/dispatcher. Note that, to run up the dispatcher program correctly, you MUST be the root user. 4. Now you can run up the coordinator program, which is located at ${where-youinstall}/bin/coordinator. Note that, to run up the coordinator program correctly, you MUST be the root user. 5. Finally, you can run up the GUI program, which is located at ${where-youinstall}/bin/nctunsclient. To run up the GUI program correctly, you can be either the root user or a normal user. However, for security reasons, in the GUI program's Settings>Dispatcher dialog, you are not allowed to enter and use the root account to submit and run a simulation job on a (can be local or remote) simulation server. Instead, you "DISPATCHER_IP

need to specify and use a normal user account/password such as nctuns/nctuns has been created on that simulation server.

that

6. If you have some ip firewall settings on your machine, you should clean up all rules before you run any simulation case. This is for correctly using divert sockets in the kernel, which are needed in Mobile IP-related simulation cases. If after flushing all rules, you still encounter kernel panic problems when running these cases, it is recommended that you re-install a new Fedore Core 4 and choose to disable the "Firewall" option during the installation. You can use the following command to see your ip firewall settings: iptables -L You can use the following command to clean up all rules: iptables -F 7. In Fedora Core 4, SELINUX is enabled by default. However, some NCTUns daemons will run incorrectly with this option enabled. The simplest way to fix this problem is to turn it off by setting "SELINUX=disable" in /etc/sysconfig/selinux.

Installation of NCTUNS
Step 1: Step 2: Step 3: Step 4: tar zxvf <filename> cd NCTUns ./install.sh vi /root/.bashrc export NCTUNSHOME=/usr/local/nctuns export LD_LIBRARY_PATH=/usr/local/nctuns/lib PATH=$PATH:$NCTUNSHOME/bin export PATH Step 5: iptables F (To disable firewall)

Step 6: Check whether rsh and rlogin services enabled ( These services comes under xinetd) Step 7: Step 8: Step 9: Settings: #vi /etc/xinet.d Disable=NO
----- ----- ---- ----

Check whether xinetd service is running Read Final check file for check list. reboot the system

FINAL CHECK
===============================================================

Before you start using NCTUns, please check whether you have done all of these steps. According to our technical support experiences, most problems are caused by not performing all of these steps.

0. The NCTUns programs have been successfully compiled and installed. 1. You have rebooted your system and is using the newly-built kernel. 2. The rlogin and rsh services in /etc/xinetd.d/rlogin and /etc/xinetd.d/rsh have been enabled. 3. The NCTUNSHOME and LD_LIBRARY_PATH environment variables have been set properly. You can use the following command to do this job: [csh/tcsh] # source /usr/local/nctuns/etc/nctuns.csh [bash] # source /usr/local/nctuns/etc/nctuns.bash

4. You have flushed iptable rules by running "iptables -F". 5. You have set "SELINUX=disabled" in /etc/sysconfig/selinux
===============================================================

STEPS TO START NCTUNS


Three things we are going to start. They are: Dispatcher (With ADMIN privilege) Coordinator (With ADMIN privilege) Nctunsclient (With ADMIN or user privilege)

But after drawing the topology, you should submit the simulation with user privilege only We need three terminals. 1st terminal to execute ./dispatcher at the server 2nd terminal to execute ./coordinator at the server 3rd terminal to execute ./nctunsclient at the client

STEP 1: STEP 2:

# cd /usr/local/nctuns/bin # ./dispatcher <enter key> Right click on the blank space of the screen and select open tab

STEP 3:

# ./coordinator <enter key> Right click on the blank space of the screen and select open tab

STEP 4:

# ./nctunsclient <enter key>

The main screen of NCTUns:

To submit the simulation you should be the normal user

WORKING WITH NCTUNS


There are 4 steps in doing the NCTUNS experiments. They are as below. 1. Drawing a network topology 2. Editing nodes properties 3. Running the simulation 4. Post analysis Drawing a network topology: Identification of tools on the toolbar:

D E R P

Select D E R P X A Draw topology Edit property Run Simulation Play back Delete Label Point to point link Moving path Hub (Blue color) X Switch (Green color) Host (Black color) Router (Red color) WLAN mobile node (Infra-structure mode) Yellow color Top row

A user can draw a new network topology or change an existing simulation topology only in the Draw topology mode. Draw topology mode is the default mode of NCTUNs. To check whether the mode is in draw mode or not do as follow. Choose Menu File Operating mode and make sure that the Draw Topology mode is checked. 1. Move the cursor to the toolbar. 2. Left-click the router icon on the toolbar 3. Left-click any where in the blank working area to add a router to the current network topology. In the same way we can add switch,hub,WLAN access point etc. 4. Left-click the host icon on the toolbar. Add the required number of hosts to the current topology. 5. To add links between the hosts and the router, left-click the link icon on the toolbar to select it. 6. Left-click a host and hold the mouse button. Drag this link to the router and then release the mouse left button on top of the router. Now a link between the selected host and the router has been created. 7. Add the other, required number of links in the same way. This completes the creation of a simple network topology.

8. Save this network topology by choosing MenuFileSave. It is saved with a .tpl


extension.

Editing Nodes Properties:


A network node (device) may have many parameters to set. Some parameters are Bandwidth Queue size IP address

The GUI automatically finds subnets in a network and generates and assigns IP and MAC addresses to layer 3 network interfaces. If the user switches the mode back to the Draw Topology mode and when the user again switches the mode back to the Edit topology mode, nodes IP and MAC addresses will be regenerated and assigned to layer 3 interfaces.

10

Therefore the application programs now may use wrong IP addresses to communicate with their partners. Procedure to note down the IP address:

1. Double click the host1A host dialog box opens 2. Click the node editor on the dialog box Different layers get displayed 3. Click the interface Module editor box opens. This shows the IP address.
Step 1:

11

Step 2 and 3:

12

Procedure to set the bandwidth: Double click on the hub/switch to set bandwidth to some initial value say 10 Mbps.

13

Procedure to set the transmission time (Traffic generation time): Double click the hostA host dialog box opens Click the AddTraffic dialog box opens Set the start time as 0.0 seconds Set the stop time as 40.0 seconds

14

Procedure to set the simulation time: Select the Setting menu. Select the Simulation Menu and click

15

Procedure to set the error rate: Setup the error rate and data rate in the physical layer. Procedure to set the data rate: Setup the error rate and data rate in the physical layer.

16

Running the Simulation The user must switch mode explicitly from Edit property to Run Simulation. Whenever the mode is switched to the Run Simulation mode, the many simulation files that collectively describe the simulation case will be exported. These simulation files will be transferred to the simulation server for it to execute the simulation. These files are stored in the mainFilename.sim directory, where mainFilename is the name of the simulation case chosen in the Draw Topology mode.

17

Playing back the packet animation trace


After the simulation is finished, the simulation server will send back the simulation result files to the GUI program .The GUI program after receiving these files, will store these files in the results directoy. It will then automatically switch to play back mode. The received files include the following types: Packet animation trace file Log files Data files

The packet animation trace file can be replayed later by the packet animation player. The performance curve of the log files can be plotted by the performance monitor.

18

POST ANALYSIS
When the user wants to review the simulation results of a simulation case that has been finished before, he/she can run up the GUI program again and then open the cases topology file. The user can switch the mode directly to the Play Back mode. The GUI program will then automatically reload the results (including the packet animation trace file and performance log file)

SIMULATION COMMANDS
UDP CONNECTION: 01. stg Senderss Transmission Gram Syntax: Example: stg [ -t duration(sec)] [-p port number] HostIPaddr stg u 1024 100 1.0.1.2

Where u is packet data payload size in bytes 100 duration in seconds 02. rtg Receivers Transmission Gram Syntax: TCP CONNECTION: 03. stcp Syntax: stcp [ -p port ] [ -l writesize] hostIPaddr Example: stcp p 7000 l 4000 1.0.1.2 Where -p is port number -l write size 04. rtcp Syntax: rtcp [-p port] [-l readsize] Example: rtcp p 7000 l 1024 Where p port number -l read size rtg u w log1

19

Experiment 1
Objective: 01. How much the packets get dropped in Half duplex. 02. How much the packets get dropped in Full duplex

Q: Simulate a three point-to-point network with a duplex link between them. Set the queue size and vary the bandwidth and find the number of packets dropped.

Using Hub:

Draw the following topology:

Hub Node no. 3

Host1 Node no. 1 IP: 1.0.1.1 stg u 1024 300 1.0.1.2

Host2 Node no. 2 IP:1.0.1.2 rtg u w log1

Editing node properties:


Note down the IP address of all the nodes.

Node number 1 2

Name Host1 Host2

IP address

Procedure to note down the IP address: 1. Double click the host1A host dialog box opens 2. Click the node editor on the dialog box Different layers get displayed 3. Click the interface Module editor box opens. This shows the IP address.

Setting the parameters for node 1: 4. Double click the host1A host dialog box opens 5. Click the node editor on the dialog box Different layers get displayed a. Click MAC8023 Module editor box opens i. Select Half Duplex as the transmission mode
ii. Select the followings in the log Packet statistics

20

1. Number of Drop packets 2. Number of Collosions 3. Throughput of incoming packets 4. Throughput of outgoing packets b. Click FIFO Module editor box opens i. Select the Queue size to 50 6. Click the AddTraffic dialog box opens a. Set the start time as 0.0 seconds b. Set the stop time as 40.0 seconds c. Type the command: Syntax: stg [ -t duration(sec)] [-p port number] HostIPaddr stg u 1024 100 1.0.1.2

Setting the parameters for node 2:


Double-click on host(node 2), and follow the same step as above with only change in command according to the following syntax: Syntax: rtg [ -t ] [-w log] [-p port number] rtg u w log1

Setting the bandwidth:


Double click on the link between node 1 and the hub to set bandwidth to some initial value say 10 Mbps. Repeat the same for the other node. Click on the E button(Edit property) present on the toolbar in to save the changes made to the topology.

Running the Simulation:


Click on the R button(Run simulation). By doing so a user can run/pause/continue/abort/disconnect/reconnect/submit a simulation. Now go to Menu Simulation Run. Executing this command submit the current simulation job to one available simulation server managed by the dispatcher. When the simulation server is executed the user will see the time knot at the bottom of the screen. It reflects the current virtual time (progress) of simulation case. To start the playback, the user can left-click the start icon (|>) of time bar located at the bottom. The animation player will then playing the recorded packet animation. To view the results, go to the filename,results folder.

To summarize the parameters are as follows:

21

Parameter IP Address Transmission mode Queue size Bandwidth . Exercises: Queue size 50 50

Host1 Host2 1.0.1.1 1.0.1.2 Half duplex Half duplex 50 50

Hub

Link

10 mbps

Bandwidth No. of drop packets 10 9

No. of collosion s

Thro Thro incoming outgoing packets packets

Experiment 1a Using switch:


Repeat the same above experiment using switch with the following parameters. Transmission mode: Full duplex. Commands to be used: stcp p 7000 l 4000 1.0.1.2 rtcp p 7000 l 1024

Experiment 2
Objective : 01. How much the packets will be sent by UDP connection

22

02. How much the packets will be sent by TCP connection Q: Simulate a four node point to point network and connect the link as follows: Apply a TCP agent between n0 and n3 and apply a UDP agent between n1 and n3. Apply relevant application over TCP and UDP agents changing the parameters and determine the number of packets sent by two agents.

UDP Connection

Draw the following topology:


Host3 Node no. 3 IP:1.0.1.3 rtg u w log1

TCP Connection UDP Connection

Host1 Node no. 1 IP: 1.0.1.1 stg u 1024 300 1.0.1.2

Host2 Node no. 2 IP:1.0.1.2 stg u 1024 100 1.0.1.3

Setup a UDP connection between node 2 and node 3 using the following commands stg u 1024 100 1.0.1.3 rtg u w log1 Setup a TCP connection between node 1 and node 3 using the following commands stcp P 7000 L 4000 1.0.1.3 rtcp p 7000 l 1024 Set the output throughput log to determine the number of packets sent by TCP/UDP To view the results, go to the filename.results folder.
Queu e size # drop UDP # incoming # outgoing packets # drop TCP # incoming packets # outgoing packets

Bandwidth

# Colloi

# Colli

50

10

Experiment 3
Objective: 01. Finding the Throughput of FTP Internet Traffic 02. Finding the Throughput of Telenet Internet Traffic (Note: FTP Time to be set from 0 to 21 seconds and telnet time to be set from 22 to 40)

23

Q: Simulate the different types of Internet traffic such as FTP and TELENET over a network and analyze the throughput.

Draw the following topology (This same topology is repeated for Expt. 5,6,7).
HOST1 Switch X HUB HOST2
FTP Internet traffic: Go to the edit mode and setup FTP traffic between node1 and node3 using port number 21 Set the input and output throughput log file To view the results , go the filename.results folder Telenet Internet traffic: Go to the edit mode and setup a telenet traffic between node1 and node 4 using the port number 7300 Set the input and output throughput log file as described in the above experiments. To view the results, go to the filename.results folder.
Queu e size FTP Bandwidth # drop # Colloi # incoming # outgoing packets # drop # Colli Telenet # incoming packets # outgoing packets

HOST3

HUB

HOST4

50

10

Experiment 4
Objective: To find number of packets dropped due to congestion. Q: Simulate the transmission of ping messages over a network topology consisting of 6 nodes and find the number of packets dropped due to congestion.

24

Draw the following topology.

Click on the subnet icon on the toolbar and then click on the screen of the working window. Select the required number of hosts and a suitable radius between the host and the switch. In the edit mode, get the IP address of one of the hosts say, host 1 and then for the other host say, host say host2 set the drop packet and no of collusions statistics as described in the earlier experiments. Now run the simulation Now click on any one of the hosts and click on command console and ping the destination node. Note: The no: of drop packets are obtained only when the traffic is more in the network. The simulation time must be kept to high value like 1000 or 2000.

25

Experiment 5
Objective: To study the effect of error rate and data rate(Bandwidth) on throughput Q: Simulate an Ethernet LAN using N nodes (6-10) , change error rate and data rate and compare throughput.

Draw the following topology.

HOST1 Switch X HUB HOST2 HUB

HOST3

HOST4

Setup a TCP connection between a host on one hub and host on another hub using the following command. Stcp p 7000 l 1024 1.0.1.6 Rtcp p 7000 l 1024 Setup the error rate and data rate in the physical layer. Setup the input and output throughput in the mac layer Change error rate and data rate and compare the throughputs. View the results in the filename.results
Queu e size

Data rate (Bandwidth)

Error rate

Output throughput

Input throughput

50 50 50 50

10 10 100 100

0.0 1.0 0.0 1.0

26

Experiment 6
Objective: To study the effect of packets collisions due to multiple traffic Q: Simulate an Ethernet LAN using N nodes and set multiple traffic nodes and determine collisions across different nodes.

Draw the following topology.


HOST1 Switch X HUB HOST2 HUB HOST4 HOST3

Setup multiple traffic connections between the hosts on one hub and hosts on another hub using the following command: stcp p 7000 l 1024 1.0.1.6 rtcp p 7000 l 1024 Setup the collision log at the destination hosts in the MAC layer as described in the earlier experiments. View the results in the filename.results.

Queu e size

Bandwidth

Node number

Collisions

50 50

10 10

3 4

27

Experiment 7
Objective: To plot congestion (collision) graph for different source/destination Q: Simulate an Ethernet LAN using N nodes and set multiple traffic nodes and plot congestion window for different source/destination.

Draw the following topology.


HOST1 Switch X HUB HOST2 HUB HOST4 HOST3

Setup multiple traffic connections between the hosts on one hub and hosts on another hub using the following command: stcp p 7000 l 1024 1.0.1.6 rtcp p 7000 l 1024 Setup the collision log at the destination hosts in the MAC layer as described in the earlier experiments. To plot the congestion window go to the menu Tools Plot Graph File Open Filename.results filename.coll.log View the results in the filename.results.
Queu e size Bandwidth Node number Collisions

50 50

10 10

3 4

28

Experiment 8
Objective: Simulation of simple BSS Q: Simulate simple BSS and with transmitting nodes in LAN by simulation and determine the performance with respective transmission of packets.

Draw the following topology.

SUBNET ID 1 SUBNET ID 2

WLAN ACCESS POINT

WLAN ACCESS POINT

Procedure to generate IP address for mobile node: Tools>WLAN>Generate

Subnet ID Gate way

The Router has 3 IP address because three subnet are connected to it. Procedure to select the IP address of the Default gateway:

Double click Router Click Node editor Click Interface

Setup a ttcp connection between the mobile nodes and host using following command.

29

Transmitter/Sender: ttcp r u s [-p port number] ttcp t u s p 7000 1.0.1.2 Setup the input throughput log at the destination host. Receiver: Ttcp r u s p 7000 To set the transmission range go to Menu Settings WLAN mobile node Show transmission range View the results in the filename.results.

30

PART B
Program 1:Error detecting using CRC-CCITT(16 Bits)
Q.Write a program for error detecting code CRC-CCIT (16 Bits)

What Is a CRC?
The Cyclic Redundancy Check is a way to detecting small changes in blocks of data. Error detection is especially important when computer programs are transmitted or stored, because an error of even one bit (perhaps out of hundreds of thousands) is often sufficient to make a program faulty. Although a few errors in a text file might be acceptable (since the text can be reedited when received or recovered), an error-free file is preferable. An error-correcting protocol triggered by CRC error-detection can provide this accuracy at low cost. CRC is based on binary division. In CRC, instead of adding bits together to achieve a desired parity, a sequence of redundant bits called the CRC remainder, is appended to the end of a data unit so that the resulting data unit becomes exactly divisible by a second, predetermined binary number. At its destination, the incoming data unit is divided by the same number. If at this step there is no remainder, the data unit is assumed to be intact and is therefore accepted. A remainder indicates that the data unit has been damaged in transit and therefore must be rejected. The redundancy bits used by CRC are derived by dividing the data unit by a predetermined divisor; the remainder is the CRC. To be valid, a CRC must have two qualities; It must have exactly one less bit than the divisor, and appending it to the end of the data string must make the resulting bit sequence exactly divisible by the divisor. Polynomials: The CRC generator (the divisor) is most often represented not as a string of 1s and 0s but as an algebraic polynomial. The polynomial format is useful for two reasons: It is short, and it can be used to prove the concept mathematically. Following is a list of the most used CRC polynomials
CRC-12: x12 + x11 + x3 + x2 + x + 1 CRC-16: CRC-CCITT:

x16 + x15 + x2 + 1
x16 + x12 + x5 + 1

CRC-32: x32 + x26 +x23 + x22 + x16 +x12 +x11 + x10 +x8 +x7 +x5 +x4 + x2 + x + 1

The CRC-12 is used for transmission of streams of 6-bit characters and generates 12-bit FCS.

31

Both CRC-16 and CCRC-CCITT are used for 8 bit transmission streams and both result in 16 bit FCS. The last two are widely used in the USA and Europe respectively and give adequate protection for most applications. Applications that need extra protection can make use of the CRC-32 which generates 32 bit FCS. The CRC-32 is used by the local network standards committee (IEEE-802) and in some DOD applications. Computation of CRC:

n bits

Data

CRC
Data Divisor CRC

Data

00.0 n+1 bits

Divisor Remainder

Remainder

CRC n bits

Zero, accept Nonzero,reject

Receiver
Three basic steps:

Sender

First, a string of n 0s is appended to the data unit. The number n is one less than the number of bits in the predetermined divisor, which is n+1 bits. Second, the newly elongated data unit is divided by the divisor using a process called binary division. The remainder resulting from this division is the CRC. Third, the CRC of n bits derived in step 2 replaces the appended 0s at the end of the data unit. Note that the CRC may consist of all 0s.

32

The data unit arrives at the receiver data first, followed by the CRC. The receiver treats the whole string as a unit and divides it by the same divisor that was used to find the CRC remainder. If the string arrives without error, the CRC checker yields a remainder of zero and the data unit passes. If the string has been changed in transit, the divisor yields a non-zero remainder and the data unit does not pass.

The CRC generator:


Quotient

111101
Divisor

1101

When the leftmost bit of the remainder is zero, we must use 0000 instead of the original divisor.

1 0 0 1 0 0 0 1 1 0 1 1 0 0 0 1 1 0 1 1 0 1 0 1 1 0 1 1 1 1 0 1 1 0 1 0 1 1 0 0 0 1 1 1 1 0

0 0

Data plus extra zeros. The number of zeros is one less than the number of bits in the divisor

0 0 0 0 0 1 0 1

Remainder

33

A CRC generator uses modulo-2 divison. In the first step, the four-bit divisor is subtracted from the first four bits of the dividend. Each bit of the divisor is subtracted from the corresponding bit of the dividend without disturbing the next higher bit. In this process, the divisor always begins with a 1;the divisor is subtracted from a portion of the previous dividend/remainder that is equal to it in length; the divisor can only be subtracted from a dividend /remainder whose leftmost bit is 1. Any time the leftmost bit of the dividend or remainder is zero, A string of zeros of the same length as the divisor replaces the divisor in that step of the process. For example, if the divisor is of four bits long, it is replaced by four zeros( Remember, we are dealing with bit pattern, not with quantitative values; 0000 is not the same as 0). This restriction means that, at any step the leftmost subtraction will be either 0-0 or 1-1, both of which equal 0. So after subtraction the leftmost bit of the remainder will always be a leading zero, which is dropped off and the next unused bit of the dividend is pulled down to fill out the remainder. Note that only the first bit of the remainder is dropped- If the second bit is also zero, it is retained, and the dividend/remainder for the next step will begin with 0. This process repeats until the entire dividend has been used.

The CRC Checker:

Divisor

111101

Quotient

1101

When the leftmost bit of the remainder is zero, we must use 0000 instead of the original divisor.

1 0 0 1 0 0 0 1 1 0 1 1 0 0 0 1 1 0 1 1 0 1 0 1 1 0 1 1 1 1 0 1 1 0 1 0 1 1 0 0 0 1 1 1 1 0

0 1

Data plus CRC received

0 0 0 1 0 1 0 0

Result 34

A CRC checker functions exactly like the generator. After receiving the data appended with the CRC, it does the same modulo-2 division. If the remainder is all 0s, the CRC is dropped and the data accepted; otherwise, the received stream of bits is discarded and data are resent. PROGRAM:
#include <stdio.h> #include <string.h> #define POLY 0x11021 #define MSB 0x10000 //converting msg into bits void showbits(unsigned int msg) { unsigned int bits[50],i=0; while(msg >1) { bits[i]=msg%2; msg=msg/2; ++i; } printf("%u",msg);

//mod 2 given msg to store bits in array

//print the msb

while(i>0) { --i; printf("%u",bits[i]); //reverse the remaining bits to get rite order } } // mod 2 division unsigned int mod2div(unsigned int dividend , unsigned int divisor) { unsigned int i,reminder; reminder=dividend>>7; //take only 17 bits from dividend starting from MSB which //is equal to generator length

for(i=0;i<8;i++) // mod 2 division { if(reminder & MSB) { reminder = reminder^divisor; //if msb is 1 xor divisor reminder=reminder<<1; } else { reminder = reminder ^0; //if msb is 0 xor by 0 reminder = reminder<<1;

35

} if(dividend & 0x40) //get next bit of dividend reminder = reminder+1; dividend = dividend<<1; } reminder=reminder>>1; return reminder; } //encoding N decoding using CRC int main() { char data; unsigned int appen_data,code,opt,checksum; printf("Enter a character:"); scanf("%c",&data); printf("\ndata:\n"); showbits(data); appen_data= data<<16; //appending 16 zeros to data //eliminate the extra bit in previous loop

checksum = mod2div(appen_data,POLY); //find checksum printf("\ncode:\n"); code = appen_data | checksum; //code=data+checksum showbits(code); printf("\n\n \" option 1 to receive corrupted data \" "); printf("\n \" option 2 to receive correct data \" \n "); printf("\nEnter option :"); scanf("%u",&opt); switch(opt) { case 1: printf("\nchecksum is:"); showbits(mod2div(code+5 ,POLY)); printf("\nreceived is data is corrupted:\n"); break; case 2: printf("\nchecksum is:"); showbits(mod2div(code,POLY)); printf("\nreceived is data is correct:\n"); break; } return 0; } OUTPUT:

36

Enter a character: A Data: 1000001 Code: 10000010101100011100101 Option 1 to receive corrupted data Option 2 to receive correct data Enter option: 1 Checksum is :1111 Received data is corrupted Enter a character: A Data: 1000001 Code: 10000010101100011100101 Option 1 to receive corrupted data Option 2 to receive correct data Enter option: 2 Checksum is:0 Received data is correct.

37

Program 2: Frame sorting


q.Write a program for frame sorting technique used in buffers We need the frame sorter when the frame source is using TCP/IP so we can run packet re-assemblers on other computers in an effort to balance the workload. If the frames are coming in over ISIS IP multicasts, we don't need a sorter: Each reassembler can receive all frames and discard those they don't need. This way we get each frame on the network one time only, and the work in each re-assembler to input and reject frames on the wrong virtual channel is very little. If ISIS is not using true IP multicasting, then, once again, the sorter is needed to reduce the network traffic. There are side benefits to such a design. In cases like I&T where the frame source is using TCP/IP, we need to sort the transfer frames by virtual channel so we can run some packet re-assemblers on other workstations to balance the compute load. But even so, we may re-assemble housekeeping packets on the workstation doing the frame sorting. Why do it in a separate process? This is especially true on Solaris where we have control over thread binding, and therefore, thread concurrency. In a multi-threaded environment, the frame sorter and packet re-assembler both can be constructed from a collection of objects: input tasks, output tasks, packet assembly tasks, pool objects, sorter objects, and queue objects. The packet re-assembler might looks like this: input --> queue --> pkt assy --> sorter --> queue --> output Transfer frames enter an input. Input enqueues and possibly archives them. The packet assembly task reads frames out of the queue and constructs packets. It hands completed packets to a sorter which enqueues them for output tasks and possibly archives them. Each output task reads packets from its queue and sends packets out

PROGRAM:
#include<stdio.h> struct frame { int fslno; char finfo[20]; }; struct frame arr[10]; int n; void sort() { int i,j,ex; struct frame temp;

38

for(i=0;i<=n-1;i++) { ex=0; for(j=0;j<n-i-1;j++) if(arr[j].fslno>arr[j+1].fslno) { temp=arr[j]; arr[j]=arr[j+1]; arr[j+1]=temp; ex++; } if(ex==0) break; } } int main() { int i; system("clear"); printf("enter the no of frame"); scanf("%d",&n); printf("enter the frame sequence and contents\n"); for(i=0;i<n;i++) scanf("%d%s",&arr[i].fslno,arr[i].finfo); sort(); printf("the frame in sequence\n"); for(i=0;i<n;i++) printf("sequence no:\t%d\t%s\t payload\n",arr[i].fslno,arr[i].finfo); } output: enter the no of frame3 enter the frame sequence and contents 2 40 3 20 1 25 the frame in sequence sequence no: 1 25 payload sequence no: 2 40 payload sequence no: 3 20 payload

39

Program 3: Distance Vector Algorithm


Q.Write a program for distance vector algorithm to find suitable path for transmission Most routing protocols fall into one of two classes: distance vector or link state. A distance-vector routing protocol uses the Bellman-Ford algorithm to calculate paths. The name distance vector is derived from the fact that routes are advertised as vectors of (distance, direction), where distance is defined in terms of a metric and direction is defined in terms of the next-hop router. A typical distance vector routing protocol uses a routing algorithm in which routers periodically send routing updates to all neighbors by broadcasting their entire route tables.3

PROGRAM:
#include<stdio.h> #include<stdlib.h> struct dva { char nodname; int delay; char nexthop; }mod[10][10],rt[10][10]; int main() { int dm[10][10]; int i,n,j,k,l; printf("Enter the number of routers and the matrix table: "); scanf("%d",&n); for(i=0;i<n;i++) { for(j=0;j<n;j++) { scanf("%d",&dm[i][j]); } } //Initialisation of routing tables for(i=0;i<n;i++) { for(j=0;j<n;j++) { rt[i][j].nodname=j+65; rt[i][j].delay=dm[i][j]; rt[i][j].nexthop=i+65; }

40

} printf("\nInitial states of the routing tables\n\n"); for(i=0;i<n;i++) { printf("Router %c\n",i+65); for(j=0;j<n;j++) { printf("%c\t%d\t%c\n",rt[i][j].nodname,rt[i][j].delay,rt[i][j].nexthop); } printf("\n\n"); } //Updating the routing tables for(i=0;i<n;i++) { for(j=0;j<n;j++) { if(i==j || dm[i][j]==99) continue; for(l=0;l<n;l++) //modified table { mod[j][l].delay=dm[i][j]+rt[j][l].delay; mod[j][l].nodname=rt[j][l].nodname; mod[j][l].nexthop=j+65; } for(k=0;k<n;k++) //oldtable vs modified { if(mod[j][k].delay<rt[i][k].delay) { rt[i][k].delay=mod[j][k].delay; rt[i][k].nexthop=mod[j][k].nexthop; } } } } //Printing the routing tables printf("\nFinal states of the routing tables\n\n"); for(i=0;i<n;i++) { printf("Router %c\n",i+65); for(j=0;j<n;j++) { printf("%c\t%d\t%c\n",rt[i][j].nodname,rt[i][j].delay,rt[i][j].nexthop); } printf("\n\n"); }

41

} Output: Enter the number of routers and matrix table : 3 0 10 5 10 0 20 5 20 0 Initial states of the routing tables Router A A B C 0 10 5 A A A

Router B A B C 10 0 20 B B B

Router C A B C 5 20 0 C C C

Final states of the routing tables Router A A B C 0 10 5 A A A

Router B A B C 10 0 15 B B A

Router C A B C 5 15 0 C A C

42

Program 4: Spanning Tree


Write a program for spanning tree algorithm(kruskals/prims) to find loop less path Spanning tree is a subset of the original topology that has no loops. It is a sub graph containing all the nodes of the graph and some arcs selected such that there is exactly one path between each pair of nodes. When weights are given for all pairs of nodes in a graph, the spanning tree with minimum total weight can be found leading to the minimum spanning tree (Total weight equals sum of all its arcs). Prims algorithm: Here a node is chosen initially as the root. The nodes of the graph are then appended to the tree one at a time until all nodes are included in the tree. The node added to the tree at each point is the node adjacent to a node of the tree by an arc of minimum weight. A minimum spanning tree is constructed when all the nodes of the graph are added to the tree. The minimum spanning tree can be created from a weighted graph and this represents the cheapest way of connecting all nodes in the graph. To get the minimum spanning tree for the graph, a practical tree at any point is built by the prims algorithm.

PROGRAM:
#include<stdio.h> #define MAX 20 #define INFINITY 999 enum boolean{TRUE,FALSE}; void prim(int i[][MAX],int t[MAX],int n); int mincost=0; int main() { int n,c[MAX][MAX],t[2*(MAX-1)]; int i,j; printf("this program implements prims algorithm\n"); printf("How many nodes does the graph have"); scanf("%d",&n); printf("Enter the cost adjacency matrix"); printf("\n999 indicates no connection"); for(i=0;i<n;i++) for(j=0;j<n;j++) scanf("%d",&c[i][j]); prim(c,t,n); printf("Spanning tree:\n"); for(i=0;i<2*(n-1);i+=2) printf("(%d%d)\n",t[i]+1,t[i+1]+1); printf("mincost=%d",mincost); return 0; } void prim(int c[][MAX],int t[MAX],int n) { int i,j; enum boolean v[MAX];

43

int k,s,min,v1,v2; for(i=0;i<n;i++) v[i]=FALSE; v[0]=TRUE; k=0; t[k]=1; s=0; k++; while(k<n) { min=INFINITY; for(i=0;i<n;i++) for(j=1;j<n;j++) if(v[i]==TRUE && v[j]==FALSE && c[i][j]<min) { min=c[i][j]; v1=i; v2=j; } mincost=mincost+min; if(min==INFINITY) { printf("graph is disconnected,tree impossible"); exit(1); } v[v2]=TRUE; k++; t[s++]=v1; t[s++]=v2; } } OUTPUT:
How many nodes does the graph have: 4 Enter the cost adjacency matrix 0 5 999 8 5 0 6 999 999 6 0 7 8 999 7 0

Spanning tree: (1,2) (2,3) (3,4) min cost=18

44

Program 5: Socket Programming


Uing TCP/IP sockets, write a client-server program to make client sending the file name and the server to send back the contents of the requested file if present

Diagram of client-server socket connection via xinetd. Note that the client communicates by reading and writing the socket, but the server program communicates via stdin and stdout.
Most interprocess communication uses the client server model. These programs refer to the two processes which will communicate with each other. Sockets are interfaces that can "plug into" each other over a network. Once so "plugged in", the programs so connected communicate. All data communication will take place through the sockets interface. When programming with sockets, usually theres creation of server and client programs. The server will sit listening for incoming connections from clients and handling. The system calls for establishing a connection are somewhat different for the client and the server., but both involve the basic construct of a socket. Two process establish their own socket. The system calls for establishing a connection are somewhat different for the client and the server, but both involve the basic construct of a socket. A socket is one end of an interprocess communication channel. The two processes each establish their own socket.

The steps involved in establishing a socket on the client side are as follows1. Create a socket with the socket() system call .

45

2. Connect the socket to the address of the server using the connect() system call. 3. Send and receive data.There are a number of ways to do this, but the simplest is to use the read() and write() systen calls. The stepd involved in establishing a socket on the server side are as follows1. Create a socket with the socket() system call. 2. Bind the socket to an address using the bind() system call. For a server socket on the internet,an address consists of a port number on the host machine. 3. Listen for connections with the listen() system call. 4. Acept a connection with the accept() system call. This call typically blocks until a client connects with the server. 5. Send and receive the data. Socket Types: When a socket is created, the program has to specify the address domain and the socket type. Two processes can communicate with each other only if their sockets are of the same type and in the same domain, in which two processes running on any two hosts on the Internet communicate. Each of these has it's own adress format. The address of a socket in the Unix domain is a character string which is basically an entry in the file system. The address of a socket in the Internet domain consists of the Internet address of the host machine (every computer on the Internet has a unique 32 bit address, often referred to as it's IP address). In addition , each socket needs a port number on that host. Port numbers are 16 bit unsigned integers. The lower numbers are reserved in Unix for standard services. For eg, the port number for the FTP server is 21. There are two widely used socket types, stream sockets , and datgram sockets. Stream sockets treat communications as a continuous stream of characters, while datagram sockets have to read entire messages at once. Each uses it's own communications protocol. Stream sockets use TCP , which is a reliable , stream oriented protocol, and datagram sockets use UDP, which is unreliable and message oriented. The primary socket calls are as follows:1. socket() - Create a new socket and return it's descriptor. 2. bind() - Associate a socket with a port and address . 3. Listen() -Establish a queue for connection requests.

46

4. Accept()- Accepts a connection request. 5. Connect()- Initiate a connection to a remote host. 6. Recv() - Receive data from a socket descriptor. 7. Send() - Send data to a socket descriptor. 8. Close() - one-way close of a socket descriptor, The other system calls used are as follows:1. gethostbyname- given a hostname , returns a structure which specifies it's DNS name(s) and IP address(es). 2. getservbyname given service name and protocol , returns a structure which specifies its name(s) and its port address. The socket utility functions are as follows:1. htons/ntohl- convert short/long from host byte order to network byte order. 2. inet_ntoa/inet_addr- converts 32 bit IP address (network byte order to/from a dotted decimal string) The header files used in order are:1.<sys/types.h> -prerequisite typedefs. 2. <errno.h> -names for erno values (error numbers) 3. <sys/socket.> - struct sock addr ;system prototypes and constants . 4. <netdb.h.h> - network info lookup prototypes and structures. 5. <netinet/in.h> - struct sockaddr_in; byte ordering macros. 6. <arpa/inet.h> - utility function prototypes.

Utility Routines Here is a description of some utility routines that are used a lot in the C++ code.

htonl() and htons(): Convert long integer and short integer (respectively) from host byte order (on x86 this is Least Significant Byte First) to standard network byte order (Most Significant Byte First).

47

ntohl() and ntohs(): The opposite of htonl() and htons() (see above); i.e., convert network byte order to host byte order. Converts an IP address from binary form to the numbers and dots notation.

inet_ntoa():

gethostbyname(): Takes an IP address in numbers and dots notation, and returns a structure with various pieces of information. It's not really necessary to know what that structure is all about, just that it's needed when making the socket connection. memset() is not specific to sockets, but you might not have seen it before. It is defined in <string.h>, and it is just an efficient way to set all elements of an array to a given value.

The TCP server goes through five (or six) main steps, as regards the socket. 1. Create a socket, using the socket() function call: listenSocket = socket(AF_INET, SOCK_STREAM, 0); if (listenSocket < 0) { cerr << "cannot create listen socket"; exit(1); } SOCK_STREAM is a constant that indicates this will be a TCP (reliable) connection; use SOCK_DGRAM for (unreliable) UDP communication. Don't worry about the other parameters; they never change. 2. Bind the socket to the port that clients will connect to: serverAddress.sin_family = AF_INET; serverAddress.sin_addr.s_addr = htonl(INADDR_ANY); serverAddress.sin_port = htons(listenPort); if (bind(listenSocket, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) < 0) { cerr << "cannot bind socket"; exit(1); } Don't worry about understanding all that serverAddress stuff. Just notice that listenPort is a variable with the port number. 3. Wait for clients: listen(listenSocket, 5); The second parameter is the backlog, or the maximum length the queue of pending connections may grow to, according to the Linux man page.

48

4. Establish a connection with a client that requests one, using the accept() function call: clientAddressLength = sizeof(clientAddress); connectSocket = accept(listenSocket, (struct sockaddr *) &clientAddress, &clientAddressLength); if (connectSocket < 0) { cerr << "cannot accept connection "; exit(1); } This creates a new socket, which is used for this particular connection. The original socket may continue accepting more connections, and establishing new sockets for them, while this connection is still active. (But that would probably require the program to be multi-threaded....) Multiple sockets open on the same port will be distinguished by being connected to different (ip address, port) combinations on the client side. 5. Read and write over the socket using the recv() and send() functions, respectively. Here is the whole read/write loop from the sample program: memset(line, 0x0, LINE_ARRAY_SIZE); while (recv(connectSocket, line, MAX_MSG, 0) > 0) { cout << " -- " << line << "\n"; // Convert line to upper case. for (i = 0; line[i] != '\0'; i++) line[i] = toupper(line[i]); // Send converted line back to client. if (send(connectSocket, line, strlen(line) + 1, 0) < 0) cerr << "Error: cannot send modified data"; memset(line, 0x0, LINE_ARRAY_SIZE); // set line to all zeroes } 6. Close the socket. Either the client or the server should close the socket at the end of communication. Only one needs to do it, and it doesn't matter which. In this example, the client does it (see below). The TCP Client The TCP client goes through three (or four) main steps, as regards the socket. 1. Create a socket, using the socket() function call: socketDescriptor = socket(AF_INET, SOCK_STREAM, 0); if (socketDescriptor < 0) { cerr << "cannot create socket\n"; exit(1); }

49

SOCK_STREAM is a constant that indicates this will be a TCP (reliable) connection; use SOCK_DGRAM for (unreliable) UDP communication. Don't worry about the other parameters; they never change. 2. Connect to the server, using the connect() function: serverAddress.sin_family = hostInfo->h_addrtype; memcpy((char *) &serverAddress.sin_addr.s_addr, hostInfo->h_addr_list[0], hostInfo->h_length); serverAddress.sin_port = htons(serverPort); if (connect(socketDescriptor, (struct sockaddr *) &serverAddress, sizeof(serverAddress)) < 0) { cerr << "cannot connect\n"; exit(1); } Again, don't worry about most of the details. serverPort is the port that the server is listening on. The system will assign the client an arbitrary unused port number as the return address. 3. Read and write using recv() and send(), respectively. This is essentially the same as for the server; see above. 4. Close the socket. 5. close(socketDescriptor);

EXECUTION INSTRUCTIONS:
There are two programs(Server-side & Client-side) to be typed on an editor (eg vi or kdevelop), exit the editor after saving the progarm, complile the programs on different terminals using the command cc <programname>.c -o <output filename> and then the command ./<output filename> is entered if no errors are encountered(else correct the errors and then perform the above).

1. Compile and execute the Server side program specifying an unsed port no.
after the ouput filename, then in the other terminal compile and execute the Client side program with IP address of Server system and common port no. and wait for reply.

2. Enter the pathname of any file on the Server system as a request to the Server
3. Now switch to Server terminal and check if the file requested is present or not and the status of Server. If the file is found then switch to the Client terminal and watch the contents of file displayed on the terminal. Else it displays that file is not found with pathname.

******************end*************

50

PROGRAM:
Server side: #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <sys/fcntl.h> void error(char *msg) { perror(msg); exit(0); } int main(int argc,char *argv[]) { int serv_sockfd, cli_sockfd, portno, clilen,n,bytes; char buffer[256],c[2000]; struct sockaddr_in serv_addr, cli_addr; FILE *fd; if (argc < 2) { fprintf(stderr,"ERROR, no port provided \n"); exit(0); } serv_sockfd = socket(AF_INET,SOCK_STREAM,0); if(serv_sockfd<0) error("ERROR OPENING SOCKET"); bzero((char *) &serv_addr,sizeof(serv_addr)); portno = atoi(argv[1]); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = INADDR_ANY; serv_addr.sin_port = htons(portno); if(bind(serv_sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr))<0) error("ERROR ON BINDING"); listen(serv_sockfd,5); clilen=sizeof(cli_addr); printf("SERVER:waiting for client....\n"); cli_sockfd = accept(serv_sockfd,(struct sockaddr *) &cli_addr,&clilen);

51

if(cli_sockfd < 0) error("ERROR on accept"); bzero(buffer,256); n=read(cli_sockfd,buffer,255); if(n<0) error("ERROR reading from socket"); printf("SERVER: %s \n",buffer); if((fd=open(buffer,O_RDONLY)) > 0) { printf("SERVER: %s found!\n Transfering the contents ...\n",buffer); while(1) { bytes=read(fd,c,2000); if(bytes >0) n = write(cli_sockfd,c,bytes); else break; } if(n<0) error("Error writing to socket"); } else { printf("SERVER:File not found!\n"); n=write(cli_sockfd,"File not found!",15); if(n<0) error("Error writing to socket"); } close(serv_sockfd); close(cli_sockfd); return 0; } Client side program #include <stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #include <string.h> void error(char *msg) { perror(msg); exit(0); }

52

int main(int argc, char *argv[]) { int sockfd,portno,n; struct sockaddr_in serv_addr; struct hostent *server; char buffer[256],buf[2000]; if (argc<3) { fprintf(stderr, "Usage %s hostname port\n", argv[0]); exit(0); } portno= atoi(argv[2]); sockfd = socket(AF_INET,SOCK_STREAM,0); if(sockfd<0) error("Error opening socket"); printf("\nClient online!\n"); server=gethostbyname(argv[1]); if(server ==NULL) { fprintf(stderr,"Error, no such host\n"); exit(0); } printf("\nSERVER Online!\n"); bzero((struct sockaddr_in *)&serv_addr,sizeof(serv_addr)); serv_addr.sin_family = AF_INET; bcopy((char *) server->h_addr,(char *) &serv_addr.sin_addr.s_addr,server->h_length); serv_addr.sin_port=htons(portno); if(connect(sockfd,&serv_addr,sizeof(serv_addr))<0) error("Error connecting"); printf("Client: Enter path with filename:\n"); scanf("%s",&buffer); n=write(sockfd,buffer,strlen(buffer)); if(n<0) error("ERROR writing to socket"); bzero(buf,2000); while(1) {

53

n=read(sockfd,buf,1999); if(n<=0) exit(0); write(1,buf,n); } close(sockfd); return 0; } Sample Input/Output: Server: waiting for client .. Sam.c found ! Transferring the contents Client: Server online .! Enter the filename with path: sam.c

54

Program 6: IPC CHANNELS - FIFO


Implement the program using as message queues or FIFO as IPC channels IPC Channels are mechanism to transfer data between processes FIFO's is used to send data between a Client and Server. If we have a server that is contacted by numerous clients, each client can write its request to a well-known(i.e, the pathname is known by all clients) FIFO that the server creates. The figure below shows this arrangement. Since there are multiple writers for the FIFO, the requests sent by the clients to the server need to be less than PIPE_BUF bytes in size. This prevents any interleaving of the client writes. The problem in using FIFO's for this type of client-server communication is how to send replies back from the server to each client. A single FIFO can't be used, as the clients would never know when to read their response, versus responses for other clients. One solution is for each client to send its process ID with the request. The server then creates a unique FIFO for each client, using a pathname based on the client's process ID.

Server

Client-specific FIFO

Well-known FIFO

Client-specific FIFO

Client

Client

ii. BACKGROUND REQUIRED: 1. UNIX File I/O system calls 2. UNIX IPC system calls iii. ALGORITHM: There are two programs- Server side & Client side.

55

Server side: 1. command. Ex: mknod(<fifo name>, S_IFIFO | 0666 , 0) 1. Open the above FIFO in readonly mode to accept requests from the clients. 2. When the client opens the other end of FIFO in writeonly mode then read the contents and store the request(pathname of file) in a buffer. 3. Now create another FIFO(client-specific) in writeonly mode to send the reply(contents of the file requested) 4. Open the file requested by client and write the contents into the clientspeicfic FIFO and terminate the connection. Client side: 1. Open the well-known Server FIFO in write mode. 2. Write the pathname of file into this FIFO and send as a request. 3. Now open the Client-specific FIFO in read mode and wait for reply from server. 4. When the contents of file are available on this FIFO display it on the terminal. iv. EXECUTION INSTRUCTIONS: There are two programs(Server-side & Client-side) to be typed on an editor (eg vi or kdevelop), exit the editor after saving the progarm, complile the programs on different terminals using the command cc <programname>.c and then the command ./a.out is entered if no errors are encountered(else correct the errors and then perform the above). 1. Compile and execute the Server side progarm first then in the other terminal compile and execute the client side program. 2. Enter the pathname of any file on the system as a request to the Server and wait for reply. Create a well-known FIFO using mknod

3. Now switch to Server terminal and check if the file requested is present or not
and the status of Server. If the file is found then switch to the Client terminal and watch the contents of file displayed on the terminal. Else it displays that file is not found with pathname.

56

PROGRAM:
#include<stdio.h> #include<stdlib.h> #include<error.h> #include<string.h> #include<fcntl.h> #include<sys/types.h> #include<sys/stat.h> #include<unistd.h> #define FIFO1 "fifo1" #define FIFO2 "fifo2" int main() { char p[100],c[5000]; int num,fifo_W,fifo_R,file_R; mknod(FIFO1,S_IFIFO|0666,0); mknod(FIFO2,S_IFIFO|0666,0); printf("SERVER ONLINE!\n\n"); fifo_R = open(FIFO1,O_RDONLY); fifo_W = open(FIFO2,O_WRONLY); printf("\nClient ONLINE!!\nwaiting for request..\n\n"); if((num=read(fifo_R,p,100))==-1) perror("Read error\n"); else { p[num]='\0'; if((file_R=open(p,O_RDONLY))<0) { perror("\nFILE"); write(fifo_W,"ERROR",strlen("ERROR")); return 1; } else { num = read(file_R,c,5000); if(num ==-1) perror("Read"); else { printf("SERVER: !! \nTransferring the content..%s",p); write(fifo_W,c,5000); } }

57

} printf("Transfer Completed\n"); return 1; }

FIFO CLIENT: #include<stdio.h> #include<stdlib.h> #include<error.h> #include<string.h> #include<fcntl.h> #include<sys/types.h> #include<sys/stat.h> #include<unistd.h> #define FIFO1 "fifo1" #define FIFO2 "fifo2" int main() { char p[100],c[5000]; int num,fifo_R,fifo_W; mknod(FIFO1,S_IFIFO|0666,0); mknod(FIFO2,S_IFIFO|0666,0); printf("CLIENT Working...\n"); fifo_W=open(FIFO1,O_WRONLY); fifo_R=open(FIFO2,O_RDONLY); printf("\n client:!!\n enter the path\n"); scanf("%s",p); num =write(fifo_W,p,strlen(p)); if(num==-1) { perror("write error\n"); return 1; } else { printf("waiting for reply.. \n"); if((num =read(fifo_R,c,5000))==-1) perror("Transfer error!\n"); else { c[num]='\0'; if(strcmp(c,"ERROR")==0) { printf("File not found,connection ended\n"); return 1; } printf("File received..!! \n displaying the content..\n");

58

printf("%s\n",c); } } return 1; }

OUTPUT:
Server: server inline! Client online! Waiting for request. Server!! Transferring the contents . Transfer completed Client: Client working ! Enter the path: sam.c File received. Displaying the contents

59

60

Program 7:Data encryption/DECRYPTION using RSA Alog.


Write a program for simple RSA algorithm to encrypt and decrypt the data The RSA Public key algorithm was invented in 1977 by Ron Rivest, Adi Shamir and Leonard Adleman (RSA). The algorithm Supports Encryption and Digital Signatures. It is the most widely used public key algorithm. RSA gets its security from the integer factorization problem. The algorithm is relatively easy to understand and implement. It has been patent free since 2000. RSA is used in security protocols such as IPSEC/IKE -IP data security,TLS/SSL -transport data security (web), PGP -email security,SSH -terminal connection security,SILC -conferencing service security.

Theoretical Concepts:
RSA gets its security from the factorization problem. The difficulty of factoring large numbers is the basis of security of RSA. The Integer factorization problem (finding a number's prime factors): For a positive integer n, find its prime factors: n = p1 p2 ... pi where pi is positive distinct prime number Example: 257603 = 41 * 61 * 103 Factorization algorithms can be used to factor faster than brute forcing. Some of them are Trial division, Pollard's rho, Pollard's p-1, Quadratic sieve, elliptic curve factorization, Random square factoring, Number field sieve, etc. A Prime number is a positive integer and is divisible only by itself and 1. Prime numbers are found with primality testing; an algorithm which tests a probable prime for primality. If primality testing returns false prime numbers the cryptographic algorithm may be insecure (or will not function correctly). RSA depends on prime numbers in key generation. It also uses strong primes, numbers whose factors of the prime are also primes.

The RSA algorithm:


61

Key generation: 1)Select random prime numbers p and q, and check that p != q 2)Compute modulus n = pq 3)Compute phi = (p - 1)(q - 1) 4)Select public exponent e, 1 < e < phi such that gcd(e,phi) = 1 5)Compute private exponent d = e^-1 mod phi 6)Public key is {n, e}, private key is d Encryption: c = me mod n, decryption: m = cd mod n The selected public exponent e, which is used as public key with n. It is used to encrypt messages and to verify digital signatures. The e is stored for later with n. The e is usually small number but it can be 1 < e < phi . The e must be relatively prime to phi , hence gcd(e, phi ) = 1. (gcd = greatest common divisor, using the Euclidean algorithm) The private exponent d, is the actual RSA private key. The d must not be disclosed at any time or the security of the RSA is compromised. The d is found by computing the multiplicative inverse d = e^-1 mod phi . The extended Euclidean algorithm is commonly used to compute inverses. The d exponent is used to decrypt messages and to compute digital signatures. Implementations try to find as small d as possible to make decryption faster. This is fine as long as it is assured that d is about the same size as n. If it is only one quarter of size it is not considered safe to be used. It is possible to find a smaller d by using lcm(p-1,q-1) instead of phi (lcm = least common multiple, lcm(p-1,q-1) = phi /gcd(p-1,q-1) ). Example of RSA with small numbers: p = 47, q = 71, compute n = pq = 3337 Compute phi = 46 * 70 = 3220 Let e be 79, compute d = 79-1 mod 3220 = 1019 Public key is n and e, private key d, discard p and q.

62

Encrypt message m = 688, 68879 mod 3337 = 1570 = c. Decrypt message c = 1570, 15701019 mod 3337 = 688 = m. Execution Instructions: The program is typed on an editor (eg vi,gedit or kdevelop),exit the editor after saving the progarm, complile using the command cc <programname>.c and then the command ./a.out is entered if no errors are encountered(else correct the errors and then perform the above). 1: The program when executed will ask for two prime numbers to be entered for p and q respectively. 2: Then the value of e has to entered. It is preferred if p is greater than q and e is 3 for testing. 3: The message to be encrypted has to be entered. 4: The program will display the original message, encrypted message and the decrypted message.

PROGRAM:
#include<stdio.h> #include<stdlib.h> #include<math.h> #include<string.h> unsigned long modexp(unsigned long msg,unsigned long exp,unsigned long n) { unsigned long i,k=1; for(i=0;i<exp;i++) k=(k*msg)%n; return k; } int main() { unsigned long p,q,e,d,n,z,i,C,M; int len; char data[100]; //get two random prime values such that p*q > message block , p!=q //if messsage block is of k bits then, p*q > 2^k //P and Q are relatively prime numbers

63

printf("Enter the value of P and Q(such that p*q >255)\n"); scanf("%lu%lu",&p,&q); //steps invloved in key generation n=p*q; z=(p-1)*(q-1); for(i=1;i<z;i++) //calculation of encryption key "e" { //"e"satisfies gcd(z,e)==1 , 1<e<z if((z%i)==0) continue; else break; } e=i; printf("\nencryption key is :%lu",e); for(i=1;i<z;i++) //calculation of decryption key "d" if(((e*i-1)%z)==0) //"d"satisfies de=1modz ,d<z break; d=i; printf("\ndecryption key is :%lu",d); //Get the message from the STDIN printf("\n pls,enter the message :"); scanf("%s",data); len=strlen(data); for(i=0;i<len;i++) { M=(unsigned long)data[i]; C=modexp(M,e,n); printf("\nencrypted value and its char representation:%lu\t %c",C,C); M=modexp(C,d,n); printf("\ndecrypted value and its char representation:%lu\t %c",M,M); } getchar(); return 0; }

Sample input: to Sample output:

64

Encrypted data: Decrypted data : Encrypted data: Decrypted data :

617 t 914 0

65

Program 8: Hamming Code


Write a program for hamming code generation for error detection and correction Hamming code developed by Richard W Hamming for detecting and correcting single bit errors in transmitted data. This Technique required that three parity bits be transmitted with every four data bits. The algorithm is called (7,4) code, because it requires seven bits to encoded four bits of data. Parity: A parity bit is an extra bit that forces a binary string to have a specific parity. Encoding of data: In traditional Hamming codes(7,4) , Four bits of data are encoded into seven bit block. This 7 bits block is called Hamming code word. The extra three bits of the Hamming code word are called as parity bits. All of the parity bits are even parity. The method for transforming four bits of data into a seven bit Hamming code word is to use 4x7 generator matrix [G] The [ G] matrix is as follows:

[G]=011 1000 101 0100 110 0010 111 0001 Example: Procedure to encode the data value 1010 using the Hamming Code . [ 1010 ] 0111000 1010100 1100010 1110001 = (1x0) + (0x1) + (1x1) + (0x1) (1x1) + (0x0) + (1x1) + (0x1) (1x1) + (0x1) + (1x0) + (0x1) (1x1) + (0x0) + (1x0) + (0x0) (1x0) + (0x1) + (1x0) + (0x0) (1x0) + (0x0) + (1x1) + (0x0) (1x0) + (0x0) + (1x0) + (0x1) = 1 0 1 1 0 1 0

Data value

Generator matrix

Hammin g Code

So 1010 encodes to 1011010. In this

101

1 0 10 Data bits

Parity bits

66

Decoding: To verify the Hamming code word, we need the parity checking matrix. The parity checking matrix is as follows:

H=

1000111 0101011 0011101

Example : Using the parity check matrix from the example above we can correct and verify the code word 1011011 Multiply the Hamming code matrix with the parity check matrix.

1000111 0101011 0011101

1 0 1 1 0 1 0

0 0 0

Parity check matrix

Hamming code

Syndrome matrix

The product of parity check matrix and Hamming code matrix is called Syndrome matrix. The Syndrome matrix column contains all zeros. So there is no parity error. You wont find any column in parity check matrix containing all zeros. Let us make a deliberate error in the Hamming code. Let us assume we have got 1011011 as hamming code instead of 1011010.

1000111 0101011 0011101

1 0 1 1 0 1 1

1 1 1

67

The Syndrome matrix column contains all 1s. In the Parity check matrix, at the seventh column you will find all ones. Therefore there is a parity error at the seventh column.

PROGRAM:
#include<stdio.h> #include<math.h> #include<stdlib.h> char d1[5],d2[5],d3[5],d4[5]; char p1[5],p2[5],p3[5]; char gmatrix[4][8],data[5]; int encoded[8]; int con(char x); int main() { int i,j; system("clear"); printf("\nProgram for hamming code encoding-Implementation\n"); printf("\nEnter the 4 bit data...: "); scanf("%s",data); for(i=0;i<4;i++) { d1[i]=d2[i]=d3[i]=d4[i]='0'; p1[i]=p2[i]=p3[i]='1'; } printf("\n------------\n"); d1[0]=d2[1]=d3[2]=d4[3]='1'; p1[0]=p2[1]=p3[2]='0'; printf("%s\n%s\n%s\n%s\n",d1,d2,d3,d4); printf("%s\n%s\n%s\n",p1,p2,p3); for(i=0;i<4;i++) gmatrix[i][0]=p1[i]; for(i=0;i<4;i++) gmatrix[i][1]=p2[i]; for(i=0;i<4;i++) gmatrix[i][2]=p3[i]; for(i=0;i<4;i++) gmatrix[i][3]=d1[i]; for(i=0;i<4;i++) gmatrix[i][4]=d2[i]; for(i=0;i<4;i++) gmatrix[i][5]=d3[i]; for(i=0;i<4;i++) gmatrix[i][6]=d4[i]; printf("The generator matrix is:\n "); for(i=0;i<4;i++) printf("%s\n",gmatrix[i]); for(i=0;i<7;i++) for(j=0;j<4;j++) encoded[i]=encoded[i]+con(data[j])*con(gmatrix[j][i]); puts("encoded");

68

for(i=0;i<7;i++) { encoded[i]=encoded[i]%2; printf("%d",encoded[i]); } puts(" "); } int con(char x) { if(x=='1') return 1; else return 0; }

hamming decode: #include<stdio.h> #include<math.h> #include<stdlib.h> int hmatrix[3][7]={1,0,0,0,1,1,1, 0,1,0,1,0,1,1, 0,0,1,1,1,0,1}; char edata[7]; int syndrome[3]={0,0,0}; int errdig=0; int main() { int i,j, flag; printf("Enter Encoded bits\n"); for(i=0;i<7;i++) scanf("%c",&edata[i]); for(i=0;i<3;i++) for(j=0;j<7;j++) syndrome[i]=syndrome[i]^hmatrix[i][j]*edata[j]; //matrix multiplication for(j=0;j<7;j++) { flag=0; for(i=0;i<3;i++) { if(syndrome[i]==hmatrix[i][j]) //compare syndrome with H column flag++; } if(flag==3) { errdig =j+1 ;

69

break; } } if(flag!=3) errdig =0; if(0==errdig) printf("error free data\n"); else { printf("error in bit no %d....%c \n\n",errdig,edata[errdig-1]); errdig--; if(edata[errdig]=='1') //flip error digit edata[errdig]='0'; else edata[errdig]='1'; } for(i=3;i<7;i++) printf("%c",edata[i]); puts(" "); }

Sample input/output: Enter the 4 bit data :1100 Encoded : 1101100 Enter encoded bits: 110 1100 Error free data 1100

70

Program 9:Leaky bucket algorithm


Q. Write a program for congestion for congestion control using bucket algorithm
The leaky-bucket implementation is used to control the rate at which traffic is sent to the network. A leaky bucket provides a mechanism by which bursty traffic can be shaped to present a steady stream of traffic to the network, as opposed to traffic with erratic bursts of low-volume and high volume flows.

The leaky-bucket algorithm


The algorithm can be conceptually understood as follows:

Consider a bucket with a hole in the bottom. The empty space of the bucket represents an amount of credit available measured in bytes. The size of the bucket is b bytes. This means that if the bucket is empty, b bytes of credit is available. If a packet arrives and its size is less than the available credit, the packet can be forwarded. Otherwise, it is discarded or queued depending on the application.

71

The bucket leaks through the hole in its bottom at a constant rate of r bytes per second, this indicates credit accumulation.

PROGRAM:
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<sys/types.h> #include<error.h> #include<sys/stat.h> #include<unistd.h> #define min(x,y) ((x)<(y)?(x):(y)) #define max(x,y) ((x)>(y)?(x):(y)) #define MAX 25 int main() { int cap,oprt,cont,i=0,inp[MAX],ch,nsec,drop; printf("LEAKY BUCKET ALGO\n"); printf("\nEnter the bucket size: \n"); scanf("%d",&cap); printf("\nEnter the output rate: "); scanf("%d",&oprt); do { printf("\nEnter the number of packets entering at %d second\n",i+1); scanf("%d",&inp[i]); i++; printf("\nEnter 1 to insert packet or 0 to quit\n"); scanf("%d",&ch); }while(ch); nsec=i; printf("\n(SECOND):(PACK RECVD):(PACK SENT):(PACK LEFT IN BUCKET): (PACK DROPPED)\n"); cont=0; drop=0; for(i=0;i<nsec;i++) { cont+=inp[i]; if(cont>cap) { drop=cont-cap; cont=cap; } printf("(%d): ",i+1); printf("\t\t(%d): ",inp[i]); printf("\t\t(%d): ",min(cont,oprt)); cont=cont-min(cont,oprt); printf("\t\t(%d)",cont); printf("\t\t(%d)\n",drop); }

72

for(;cont!=0;i++) { if(cont>cap) cont=cap; drop=0; printf("(%d): ",i+1); printf("\t\t(0):"); printf("\t\t(%d): ",min(cont,oprt)); cont=cont-min(cont,oprt); printf("\t\t(%d)",cont); printf("\t\t(%d)\n",drop); } return (0); }

OUTPUT: Enter the bucket size: 10 Enter the output rate:2 Enter the number of packets entering at 1 second : 4 Enter the number of packets entering at 2 second: 6 Enter the number of packets entering at 3 second: 3 Sample output: Second 1 2 3 4 5 6 7 packet received 4 6 3 0 0 0 0 packet sent 2 2 2 2 2 2 1 packets left in bucket 2 6 7 5 3 1 0

73

Das könnte Ihnen auch gefallen