You are on page 1of 38

NAME : J.

ARULPANDIYAN
REG.NO : 2012503507
SUBJECT : NETWORKS LABORATORY














EX NO : 5
DATE : 25.08.14
DOMAIN NAME SYSTEM

AIM:
To write a program to implement domain name system using c program.
THEORY:
The DNS translates Internet domain and host names to IP addresses. DNS
automatically converts the names we type in our Web browser address bar to the IP addresses of
Web servers hosting those sites.
DNS implements a distributed database to store this name and address information for
all public hosts on the Internet. DNS assumes IP addresses do not change (are statically assigned
rather than dynamically assigned).
The DNS database resides on a hierarchy of special database servers. When clients
like Web browsers issue requests involving Internet host names, a piece of software called
the DNS resolver (usually built into the network operating system) first contacts a DNS server to
determine the server's IP address. If the DNS server does not contain the needed mapping, it will
in turn forward the request to a different DNS server at the next higher level in the hierarchy.
After potentially several forwarding and delegation messages are sent within the DNS hierarchy,
the IP address for the given host eventually arrives at the resolver, that in turn completes the
request over Internet Protocol.


DNS additionally includes support forcaching requests and for redundancy. Most
network operating systems support configuration of primary, secondary, and tertiary DNS
servers, each of which can service initial requests from clients.Internet Service Providers
(ISPs) maintain their own DNS servers and use DHCP to automatically configure clients,
relieving most home users of the burden of DNS configuration.
PROGRAM:
//DNS Query Program on Linux
//Header Files
#include<stdio.h> //printf
#include<string.h> //strlen
#include<stdlib.h> //malloc
#include<sys/socket.h>
#include<arpa/inet.h> //inet_addr , inet_ntoa , ntohs etc
#include<netinet/in.h>
#include<unistd.h> //getpid

//List of DNS Servers registered on the system
char dns_servers[10][100];
int dns_server_count = 0;
//Types of DNS resource records :)

#define T_A 1 //Ipv4 address
#define T_NS 2 //Nameserver
#define T_CNAME 5 // canonical name
#define T_SOA 6 /* start of authority zone */
#define T_PTR 12 /* domain name pointer */
#define T_MX 15 //Mail server

//Function Prototypes
void ngethostbyname (unsigned char* , int);
void ChangetoDnsNameFormat (unsigned char*,unsigned char*);
unsigned char* ReadName (unsigned char*,unsigned char*,int*);
void get_dns_servers();

//DNS header structure
struct DNS_HEADER
{
unsigned short id; // identification number

unsigned char rd :1; // recursion desired
unsigned char tc :1; // truncated message
unsigned char aa :1; // authoritive answer
unsigned char opcode :4; // purpose of message
unsigned char qr :1; // query/response flag

unsigned char rcode :4; // response code
unsigned char cd :1; // checking disabled
unsigned char ad :1; // authenticated data
unsigned char z :1; // its z! reserved
unsigned char ra :1; // recursion available

unsigned short q_count; // number of question entries
unsigned short ans_count; // number of answer entries
unsigned short auth_count; // number of authority entries
unsigned short add_count; // number of resource entries
};

//Constant sized fields of query structure
struct QUESTION
{
unsigned short qtype;
unsigned short qclass;
};

//Constant sized fields of the resource record structure
#pragma pack(push, 1)
struct R_DATA
{
unsigned short type;
unsigned short _class;
unsigned int ttl;
unsigned short data_len;
};
#pragma pack(pop)

//Pointers to resource record contents
struct RES_RECORD
{
unsigned char *name;
struct R_DATA *resource;
unsigned char *rdata;
};

//Structure of a Query
typedef struct
{
unsigned char *name;
struct QUESTION *ques;
} QUERY;

int main( int argc , char *argv[])
{
unsigned char hostname[100];

//Get the DNS servers from the resolv.conf file
get_dns_servers();

//Get the hostname from the terminal
printf("Enter Hostname to Lookup : ");
scanf("%s" , hostname);

//Now get the ip of this hostname , A record
ngethostbyname(hostname , T_A);

return 0;
}

/*
* Perform a DNS query by sending a packet
* */
void ngethostbyname(unsigned char *host , int query_type)
{
unsigned char buf[65536],*qname,*reader;
int i , j , stop , s;

struct sockaddr_in a;

struct RES_RECORD answers[20],auth[20],addit[20]; //the replies from the DNS server
struct sockaddr_in dest;

struct DNS_HEADER *dns = NULL;
struct QUESTION *qinfo = NULL;

printf("Resolving %s" , host);

s = socket(AF_INET , SOCK_DGRAM , IPPROTO_UDP); //UDP packet for DNS queries

dest.sin_family = AF_INET;
dest.sin_port = htons(53);
dest.sin_addr.s_addr = inet_addr(dns_servers[0]); //dns servers

//Set the DNS structure to standard queries
dns = (struct DNS_HEADER *)&buf;

dns->id = (unsigned short) htons(getpid());
dns->qr = 0; //This is a query
dns->opcode = 0; //This is a standard query
dns->aa = 0; //Not Authoritative
dns->tc = 0; //This message is not truncated
dns->rd = 1; //Recursion Desired
dns->ra = 0; //Recursion not available! hey we dont have it (lol)
dns->z = 0;
dns->ad = 0;
dns->cd = 0;
dns->rcode = 0;
dns->q_count = htons(1); //we have only 1 question
dns->ans_count = 0;
dns->auth_count = 0;
dns->add_count = 0;

//point to the query portion
qname =(unsigned char*)&buf[sizeof(struct DNS_HEADER)];

ChangetoDnsNameFormat(qname , host);
qinfo =(struct QUESTION*)&buf[sizeof(struct DNS_HEADER) + (strlen((const
char*)qname) + 1)]; //fill it

qinfo->qtype = htons( query_type ); //type of the query , A , MX , CNAME , NS etc
qinfo->qclass = htons(1); //its internet (lol)

printf("\nSending Packet...");
if( sendto(s,(char*)buf,sizeof(struct DNS_HEADER) + (strlen((const char*)qname)+1) +
sizeof(struct QUESTION),0,(struct sockaddr*)&dest,sizeof(dest)) < 0)
{
perror("sendto failed");
}
printf("Done");

//Receive the answer
i = sizeof dest;
printf("\nReceiving answer...");
if(recvfrom (s,(char*)buf , 65536 , 0 , (struct sockaddr*)&dest , (socklen_t*)&i ) < 0)
{
perror("recvfrom failed");
}
printf("Done");

dns = (struct DNS_HEADER*) buf;

//move ahead of the dns header and the query field
reader = &buf[sizeof(struct DNS_HEADER) + (strlen((const char*)qname)+1) + sizeof(struct
QUESTION)];

printf("\nThe response contains : ");
printf("\n %d Questions.",ntohs(dns->q_count));
printf("\n %d Answers.",ntohs(dns->ans_count));
printf("\n %d Authoritative Servers.",ntohs(dns->auth_count));
printf("\n %d Additional records.\n\n",ntohs(dns->add_count));

//Start reading answers
stop=0;

for(i=0;i<ntohs(dns->ans_count);i++)
{
answers[i].name=ReadName(reader,buf,&stop);
reader = reader + stop;

answers[i].resource = (struct R_DATA*)(reader);
reader = reader + sizeof(struct R_DATA);

if(ntohs(answers[i].resource->type) == 1) //if its an ipv4 address
{
answers[i].rdata = (unsigned char*)malloc(ntohs(answers[i].resource->data_len));

for(j=0 ; j<ntohs(answers[i].resource->data_len) ; j++)
{
answers[i].rdata[j]=reader[j];
}

answers[i].rdata[ntohs(answers[i].resource->data_len)] = '\0';

reader = reader + ntohs(answers[i].resource->data_len);
}
else
{
answers[i].rdata = ReadName(reader,buf,&stop);
reader = reader + stop;
}
}

//read authorities
for(i=0;i<ntohs(dns->auth_count);i++)
{
auth[i].name=ReadName(reader,buf,&stop);
reader+=stop;

auth[i].resource=(struct R_DATA*)(reader);
reader+=sizeof(struct R_DATA);

auth[i].rdata=ReadName(reader,buf,&stop);
reader+=stop;
}

//read additional
for(i=0;i<ntohs(dns->add_count);i++)
{
addit[i].name=ReadName(reader,buf,&stop);
reader+=stop;

addit[i].resource=(struct R_DATA*)(reader);
reader+=sizeof(struct R_DATA);

if(ntohs(addit[i].resource->type)==1)
{
addit[i].rdata = (unsigned char*)malloc(ntohs(addit[i].resource->data_len));
for(j=0;j<ntohs(addit[i].resource->data_len);j++)
addit[i].rdata[j]=reader[j];

addit[i].rdata[ntohs(addit[i].resource->data_len)]='\0';
reader+=ntohs(addit[i].resource->data_len);
}
else
{
addit[i].rdata=ReadName(reader,buf,&stop);
reader+=stop;
}
}

//print answers
printf("\nAnswer Records : %d \n" , ntohs(dns->ans_count) );
for(i=0 ; i < ntohs(dns->ans_count) ; i++)
{
printf("Name : %s ",answers[i].name);

if( ntohs(answers[i].resource->type) == T_A) //IPv4 address
{
long *p;
p=(long*)answers[i].rdata;
a.sin_addr.s_addr=(*p); //working without ntohl
printf("has IPv4 address : %s",inet_ntoa(a.sin_addr));
}

if(ntohs(answers[i].resource->type)==5)
{
//Canonical name for an alias
printf("has alias name : %s",answers[i].rdata);
}

printf("\n");
}

//print authorities
printf("\nAuthoritive Records : %d \n" , ntohs(dns->auth_count) );
for( i=0 ; i < ntohs(dns->auth_count) ; i++)
{

printf("Name : %s ",auth[i].name);
if(ntohs(auth[i].resource->type)==2)
{
printf("has nameserver : %s",auth[i].rdata);
}
printf("\n");
}

//print additional resource records
printf("\nAdditional Records : %d \n" , ntohs(dns->add_count) );
for(i=0; i < ntohs(dns->add_count) ; i++)
{
printf("Name : %s ",addit[i].name);
if(ntohs(addit[i].resource->type)==1)
{
long *p;
p=(long*)addit[i].rdata;
a.sin_addr.s_addr=(*p);
printf("has IPv4 address : %s",inet_ntoa(a.sin_addr));
}
printf("\n");
}
return;
}

/*
*
* */
u_char* ReadName(unsigned char* reader,unsigned char* buffer,int* count)
{
unsigned char *name;
unsigned int p=0,jumped=0,offset;
int i , j;

*count = 1;
name = (unsigned char*)malloc(256);

name[0]='\0';

//read the names in 3www6google3com format
while(*reader!=0)
{
if(*reader>=192)
{
offset = (*reader)*256 + *(reader+1) - 49152; //49152 = 11000000 00000000 ;)
reader = buffer + offset - 1;
jumped = 1; //we have jumped to another location so counting wont go up!
}
else
{
name[p++]=*reader;
}

reader = reader+1;

if(jumped==0)
{
*count = *count + 1; //if we havent jumped to another location then we can count up
}
}

name[p]='\0'; //string complete
if(jumped==1)
{
*count = *count + 1; //number of steps we actually moved forward in the packet
}

//now convert 3www6google3com0 to www.google.com
for(i=0;i<(int)strlen((const char*)name);i++)
{
p=name[i];
for(j=0;j<(int)p;j++)
{
name[i]=name[i+1];
i=i+1;
}
name[i]='.';
}
name[i-1]='\0'; //remove the last dot
return name;
}

/*
* Get the DNS servers from /etc/resolv.conf file on Linux
* */
void get_dns_servers()
{
FILE *fp;
char line[200] , *p;
if((fp = fopen("/etc/resolv.conf" , "r")) == NULL)
{
printf("Failed opening /etc/resolv.conf file \n");
}

while(fgets(line , 200 , fp))
{
if(line[0] == '#')
{
continue;
}
if(strncmp(line , "nameserver" , 10) == 0)
{
p = strtok(line , " ");
p = strtok(NULL , " ");

//p now is the dns ip :)
//????
}
}

strcpy(dns_servers[0] , "208.67.222.222");
strcpy(dns_servers[1] , "208.67.220.220");
}

/*
* This will convert www.google.com to 3www6google3com
* got it :)
* */
void ChangetoDnsNameFormat(unsigned char* dns,unsigned char* host)
{
int lock = 0 , i;
strcat((char*)host,".");

for(i = 0 ; i < strlen((char*)host) ; i++)
{
if(host[i]=='.')
{
*dns++ = i-lock;
for(;lock<i;lock++)
{
*dns++=host[lock];
}
lock++; //or lock=i+1;
}
}
*dns++='\0';
}
OUTPUT:

RESULT:
Thus the IP address is found for DOMAIN name.









EX NO : 6
DATE : 15.09.14
IMPLEMENTATION OF PING USING RAW SOCKETS
AIM:
To write a program to implement PING using RAW sockets.
THEORY:
Well, there are several types of sockets: TCP and UDP go over the wire formatted as
TCP or UDP packets, unix-domain sockets don't generally go over the wire (they're used for
interprocess communication). These are some of the built-in socket types that the kernel
understands (i.e. it will handle the connection management stuff at the front of each of these
packet types). Raw sockets are used to generate/receive packets of a type that the kernel doesn't
explicitly support.
An easy example that you're probably familiar with is PING. Ping works by sending out
an ICMP (internet control message protocol - another IP protocol distinct from TCP or UDP)
echo packet. The kernel has built-in code to respond to echo/ping packets; it has to in order to
comply with the TCP/IP spec. It doesn't have code to generate these packets, because it isn't
required. So, rather than create another system call with associated code in the kernel to
accomplish this, the "ping packet generator" is a program in user space. It formats an ICMP echo
packet and sends it out over a SOCK_RAW, waiting for a response. That's why ping runs as set-
uid root.
In standard sockets, the payload to be transmitted is encapsulated according to the
chosen transport layer protocol (e.g. TCP,UDP). In contrast, raw sockets usually receive raw
packets including the header. When transmitting packets, the automatic addition of a header may
be a configurable option of the socket.






Raw sockets are used in security related applications like nmap, packet-sniffer. One
possible use case for raw sockets is the implementation of new transport-layer protocols in user
space. Raw sockets are typically available in network equipment, and used for routing
protocols such as the Internet Group Management Protocol (IGMP) and Open Shortest Path
First (OSPF), and in the Internet Control Message Protocol (ICMP, best known for the ping sub
operation).

PROGRAM:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <linux/ip.h>
#include <linux/icmp.h>
#include <string.h>
#include <unistd.h>


char dst_addr[15];
char src_addr[15];

unsigned short in_cksum(unsigned short *, int);
void parse_argvs(char**, char*, char* );
void usage();
char* getip();

int main(int argc, char* argv[])
{
struct iphdr* ip;
struct iphdr* ip_reply;
struct icmphdr* icmp;
struct sockaddr_in connection;
char* packet;
char* buffer;
int sockfd;
int optval;
int addrlen;

if (getuid() != 0)
{
fprintf(stderr, "%s: root privelidges needed\n", *(argv + 0));
exit(EXIT_FAILURE);
}

parse_argvs(argv, dst_addr, src_addr);
printf("Source address: %s\n", src_addr);
printf("Destination address: %s\n", dst_addr);

/*
* allocate all necessary memory
*/
ip = malloc(sizeof(struct iphdr));
ip_reply = malloc(sizeof(struct iphdr));
icmp = malloc(sizeof(struct icmphdr));
packet = malloc(sizeof(struct iphdr) + sizeof(struct icmphdr));
buffer = malloc(sizeof(struct iphdr) + sizeof(struct icmphdr));
/****************************************************************/

ip = (struct iphdr*) packet;
icmp = (struct icmphdr*) (packet + sizeof(struct iphdr));

/*
* here the ip packet is set up except checksum
*/
ip->ihl = 5;
ip->version = 4;
ip->tos = 0;
ip->tot_len = sizeof(struct iphdr) + sizeof(struct icmphdr);
ip->id = htons(random());
ip->ttl = 255;
ip->protocol = IPPROTO_ICMP;
ip->saddr = inet_addr(src_addr);
ip->daddr = inet_addr(dst_addr);


if ((sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1)
{
perror("socket");
exit(EXIT_FAILURE);
}

/*
* IP_HDRINCL must be set on the socket so that
* the kernel does not attempt to automatically add
* a default ip header to the packet
*/

setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &optval, sizeof(int));

/*
* here the icmp packet is created
* also the ip checksum is generated
*/
icmp->type = ICMP_ECHO;
icmp->code = 0;
icmp->un.echo.id = 0;
icmp->un.echo.sequence = 0;
icmp->checksum = 0;
icmp-> checksum = in_cksum((unsigned short *)icmp, sizeof(struct icmphdr));

ip->check = in_cksum((unsigned short *)ip, sizeof(struct iphdr));

connection.sin_family = AF_INET;
connection.sin_addr.s_addr = inet_addr(dst_addr);

/*
* now the packet is sent
*/

sendto(sockfd, packet, ip->tot_len, 0, (struct sockaddr *)&connection, sizeof(struct
sockaddr));
printf("Sent %d byte packet to %s\n", sizeof(packet), dst_addr);

/*
* now we listen for responses
*/
addrlen = sizeof(connection);
if (recvfrom(sockfd, buffer, sizeof(struct iphdr) + sizeof(struct icmphdr), 0, (struct sockaddr
*)&connection, &addrlen) == -1)
{
perror("recv");
}
else
{
printf("Received %d byte reply from %s:\n", sizeof(buffer), dst_addr);
ip_reply = (struct iphdr*) buffer;
printf("ID: %d\n", ntohs(ip_reply->id));
printf("TTL: %d\n", ip_reply->ttl);
}
close(sockfd);
return 0;
}

void parse_argvs(char** argv, char* dst, char* src)
{
int i;
if(!(*(argv + 1)))
{
/* there are no options on the command line */
usage();
exit(EXIT_FAILURE);
}
if (*(argv + 1) && (!(*(argv + 2))))
{
/*
* only one argument provided
* assume it is the destination server
* source address is local host
*/
strncpy(dst, *(argv + 1), 15);
strncpy(src, getip(), 15);
return;
}
else if ((*(argv + 1) && (*(argv + 2))))
{
/*
* both the destination and source address are defined
* for now only implemented is a source address and
* destination address
*/
strncpy(dst, *(argv + 1), 15);
i = 2;
while(*(argv + i + 1))
{
if (strncmp(*(argv + i), "-s", 2) == 0)
{
strncpy(src, *(argv + i + 1), 15);
break;
}
i++;
}

}
}

void usage()
{
fprintf(stderr, "\nUsage: pinger [destination] <-s [source]>\n");
fprintf(stderr, "Destination must be provided\n");
fprintf(stderr, "Source is optional\n\n");
}

char* getip()
{
char buffer[256];
struct hostent* h;

gethostname(buffer, 256);
h = gethostbyname(buffer);

return inet_ntoa(*(struct in_addr *)h->h_addr);

}
/*
* in_cksum --
* Checksum routine for Internet Protocol
* family headers (C Version)
*/
unsigned short in_cksum(unsigned short *addr, int len)
{
register int sum = 0;
u_short answer = 0;
register u_short *w = addr;
register int nleft = len;
/*
* Our algorithm is simple, using a 32 bit accumulator (sum), we add
* sequential 16 bit words to it, and at the end, fold back all the
* carry bits from the top 16 bits into the lower 16 bits.
*/
while (nleft > 1)
{
sum += *w++;
nleft -= 2;
}
/* mop up an odd byte, if necessary */
if (nleft == 1)
{
*(u_char *) (&answer) = *(u_char *) w;
sum += answer;
}
/* add back carry outs from top 16 bits to low 16 bits */
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return (answer);
}








OUTPUT:









RESULT:
Thus the ping is implemented using raw sockets and the required output is obtained.
EX NO : 7
DATE : 22.09.14
DISTANCE VECTOR PROTOCOL
AIM:
To write a program to implement PING using RAW sockets.
THEORY:
Routers using distance-vector protocol do not have knowledge of the entire path to a destination.
Instead they use two methods:
1. Direction in which router or exit interface a packet should be forwarded.
2. Distance from its destination
Distance-vector protocols are based on calculating the direction and distance to any link in a
network. "Direction" usually means the next hop address and the exit interface. "Distance" is a
measure of the cost to reach a certain node. The least cost route between any two nodes is the
route with minimum distance. Each node maintains a vector (table) of minimum distance to
every node. The cost of reaching a destination is calculated using various route metrics. RIP uses
the hop count of the destination whereas IGRP takes into account other information such as node
delay and available bandwidth.



Updates are performed periodically in a distance-vector protocol where all or part of
a router's routing table is sent to all its neighbors that are configured to use the same distance-
vector routing protocol. RIP supports cross-platform distance vector routing whereas IGRP is
a Cisco Systems proprietary distance vector routing protocol. Once a router has this information
it is able to amend its own routing table to reflect the changes and then inform its neighbors of
the changes. This process has been described as routing by rumor because routers are relying
on the information they receive from other routers and cannot determine if the information is
actually valid and true. There are a number of features which can be used to help with instability
and inaccurate routing information.
EGP and BGP are not pure distance-vector routing protocols because a distance-
vector protocol calculates routes based only on link costs whereas in BGP, for example, the local
route preference value takes priority over the link cost.
Distance vector protocols (a vector contains both distance and direction), such as
RIP, determine the path to remote networks using hop count as the metric. A hop count is
defined as the number of times a packet needs to pass through a router to reach a remote
destination. For IP RIP, the maximum hop is 15. A hop count of 16 indicates an unreachable
network. Two versions of RIP exist: version 1 and version 2. IGRP is another example of a
distance vector protocol with a higher hop count of 255 hops. A higher hop counts allows your
network to scale larger. One of the drawbacks of protocols, such as RIP and IGRP, is
convergence time, which is the time it takes for routing information changes to propagate
through all your topology

PROGRAM:

#include<stdio.h>
struct node
{
unsigned dist[20];
unsigned from[20];
}rt[10];
int main()
{
int costmat[20][20];
int nodes,i,j,k,count=0;
printf("\nEnter the number of nodes : ");
scanf("%d",&nodes);//Enter the nodes
printf("\nEnter the cost matrix :\n");
for(i=0;i<nodes;i++)
{
for(j=0;j<nodes;j++)
{
scanf("%d",&costmat[i][j]);
costmat[i][i]=0;
rt[i].dist[j]=costmat[i][j];//initialise the distance equal to cost matrix
rt[i].from[j]=j;
}
}
do
{
count=0;
for(i=0;i<nodes;i++)//We choose arbitary vertex k and we calculate the direct distance
from the node i to k using the cost matrix
//and add the distance from k to node j
for(j=0;j<nodes;j++)
for(k=0;k<nodes;k++)
if(rt[i].dist[j]>costmat[i][k]+rt[k].dist[j])
{//We calculate the minimum distance
rt[i].dist[j]=rt[i].dist[k]+rt[k].dist[j];
rt[i].from[j]=k;
count++;
}
}while(count!=0);
for(i=0;i<nodes;i++)
{
printf("\n\n For router %d\n",i+1);
for(j=0;j<nodes;j++)
{
printf("\t\nnode %d via %d Distance %d ",j+1,rt[i].from[j]+1,rt[i].dist[j]);
}
}
printf("\n\n");

}

OUTPUT:




RESULT:
Thus the distance vector protocol is studied and implemented.
EX NO : 8
DATE : 29.09.14
LINK STATE ROUTING PROTOCOL
AIM:
To write a program to implement link state routing protocol using c program.
THEORY:
The information available to a distance vector router has been compared to the information
available from a road sign. Link state routing protocols are like a road map. A link state router
cannot be fooled as easily into making bad routing decisions, because it has a complete picture of
the network. The reason is that unlike the routing-by-rumor approach of distance vector, link
state routers have firsthand information from all their peer
7
routers. Each router originates
information about itself, its directly connected links, and the state of those links (hence the
name). This information is passed around from router to router, each router making a copy of it,
but never changing it. The ultimate objective is that every router has identical information about
the internetwork, and each router will independently calculate its own best paths.
Link state protocols, sometimes called shortest path first or distributed database protocols, are
built around a well-known algorithm from graph theory, E. W. Dijkstra'a shortest path algorithm.
Examples of link state routing protocols are:
Open Shortest Path First (OSPF) for IP
The ISO's Intermediate System to Intermediate System (IS-IS) for CLNS and IP
DEC's DNA Phase V
Novell's NetWare Link Services Protocol (NLSP)
Although link state protocols are rightly considered more complex than distance vector
protocols, the basic functionality is not complex at all:
1. Each router establishes a relationshipan adjacencywith each of its neighbors.
2. Each router sends link state advertisements (LSAs), some
3. Each router stores a copy of all the LSAs it has seen in a database. If all works well, the
databases in all routers should be identical.
4. The completed topological database, also called the link state database, describes a
graph of the internetwork. Using the Dijkstra algorithm, each router calculates the
shortest path to each network and enters this information into the route table.

Neighbours
Neighbour discovery is the first step in getting a link state environment up and running. In
keeping with the friendly neighbor terminology, a Hello protocol is used for this step. The
protocol will define a Hello packet format and a procedure for exchanging the packets and
processing the information the packets contain.
At a minimum, the Hello packet will contain a router ID and the
instance, an IP address from one of the router's interfaces. Other fields of the packet may carry a
subnet mask, Hello intervals, a specified maximum period the router will wait to hear a Hello
before declaring the neighbor "dead," a descriptor of the circuit type, and flags to help in
bringing up adjacencies.
When two routers have discovered each other as neighbors, they
Beyond building adjacencies, Hello packets serve as keepalives to monitor the adjacency. If
Hellos are not heard from an adjacent neighbor within a certain established time, the neighbor is
consider_ed unreachable and the adjacency is broken. A typical interval for the exchange of
hello packets is 10 seconds, and a typical dead period is four times that.
Link State Flooding
After the adjacencies are established, the routers may begin sending out LSAs. As the
term flooding implies, the advertisements are sent to every neighbor. In turn, each received LSA
is copied and forwarded to every neighbor except the one that sent the LSA. This process is the
source of one of link state's advantages over distance vector. LSAs are forwarded almost
immediately, whereas distance vector must run its algorithm and update its route table before
routing updates, even the triggered ones, can be forwarded. As a result, link state protocols
converge much faster than distance vector protocols converge when the topology changes.
The flooding process is the most complex piece of a link state protocol. There are several ways
to make flooding more efficient and more reliable, such as using unicast and multicast addresses,
checksums, and positive acknowledgments. These topics are examined in the protocol-specific
chapters, but two procedures are vitally important to the flooding process: sequencing and aging.
PROGRAM:
#include<stdio.h>
#include<string.h>
int main()
{
int count,src_router,i,j,k,w,v,min;
int cost_matrix[100][100],dist[100],last[100];
int flag[100];
printf("\n Enter the no of routers");
scanf("%d",&count);
printf("\n Enter the cost matrix values:");
for(i=0;i<count;i++)
{
for(j=0;j<count;j++)
{
printf("\n%d->%d:",i,j);
scanf("%d",&cost_matrix[i][j]);
if(cost_matrix[i][j]<0)cost_matrix[i][j]=1000;
}
}
printf("\n Enter the source router:");
scanf("%d",&src_router);
for(v=0;v<count;v++)
{
flag[v]=0;
last[v]=src_router;
dist[v]=cost_matrix[src_router][v];
}
flag[src_router]=1;
for(i=0;i<count;i++)
{
min=1000;
for(w=0;w<count;w++)
{
if(!flag[w])
if(dist[w]<min)
{
v=w;
min=dist[w];
}
}
flag[v]=1;
for(w=0;w<count;w++)
{
if(!flag[w])
if(min+cost_matrix[v][w]<dist[w])
{
dist[w]=min+cost_matrix[v][w];
last[w]=v;
}
}
}
for(i=0;i<count;i++)
{
printf("\n%d==>%d:Path taken:%d",src_router,i,i);
w=i;
while(w!=src_router)
{
printf("\n<--%d",last[w]);w=last[w];
}
printf("\n Shortest path cost:%d",dist[i]);
}
}

OUTPUT:







RESULT:

Thus the link state protocol is studied and implemented using c program.

You might also like