Beruflich Dokumente
Kultur Dokumente
# 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
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
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
===============================================================
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:
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.
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
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:
Node number 1 2
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
21
Parameter IP Address Transmission mode Queue size Bandwidth . Exercises: Queue size 50 50
Hub
Link
10 mbps
No. of collosion s
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
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
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.
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
Error rate
Output throughput
Input throughput
50 50 50 50
10 10 100 100
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.
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.
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.
SUBNET ID 1 SUBNET ID 2
The Router has 3 IP address because three subnet are connected to it. Procedure to select the IP address of the Default gateway:
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
Divisor Remainder
Remainder
CRC n bits
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.
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.
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
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);
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:
#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:
#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
Router B A B C 10 0 15 B B A
Router C A B C 5 15 0 C A C
42
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
44
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
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
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
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.
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; }
64
617 t 914 0
65
[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
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=
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.
1 0 1 1 0 1 0
0 0 0
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.
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
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