Thursday, October 23, 2014

RIP information


RIP messages:


  1. RIP Request and the RIP Response.
  2. RIP updates are placed as UDP payload inside an IP datagram
  3.  UDP reserved port number 520.









RIP both the versions:

RIP packet structure
It is hard to fully understand a routing protocol without knowing what information is carried in its packets. Knowing what information is exchanged between routers and how will help you better understand the RIP protocol, and better configure your network for it.
This section provides information on the contents of RIP 1 and RIP 2 packets.
RIP version 1



RIP version 1, or RIP IP packets are 24 bytes in length, with some empty areas left for future expansion.

RIP IP packets



1-byte command
1-byte version
2-byte zero field
2-byte AFI
2-byte zero field
4-byte IP address
4-byte zero field
4-byte zero field
4-byte metric
A RIP 1 packet contains the following fields:
Command — Indicates whether the packet is a request or a response. The request asks that a router send all or part of its routing table. The response can be an unsolicited regular routing update or a reply to a request. Responses contain routing table entries. Multiple RIP packets are used to convey information from large routing tables.
Version — Specifies the RIP version used. This field can signal different potentially incompatible versions.
Zero field — This field defaults to zero, and is not used by RFC 1058 RIP.
Address-family identifier (AFI) — Specifies the address family used. RIP is designed to carry routing information for several different protocols. Each entry has an address-family identifier to indicate the type of address being specified. The AFI for IP is 2.
IP Address — Specifies the IP address for the entry.
Metric — This is the number of hops or routers traversed along the route on its trip to the destination. The metric is between 1 and 15 for that number of hops. If the route is unreachable the metric is 16.
RIP version 2
RIP version 2 has more features than RIP 1, which is reflected in its packets which carry more information. All but one of the empty zero fields in RIP 1 packets are used in RIP 2.
Table 11:RIP 2 packets


1-byte
command
1-byte
version
2-byte
unused
2-byte
AFI
2-byte
route tag
4-byte IP address
4-byte
subnet
4-byte
next hop
4-byte metric
A RIP 2 packet contains fields described above in RIP 1, as well as the following:
Unused — Has a value set to zero, and is intended for future use
Route tag — Provides a method for distinguishing between internal routes learned by RIP and external routes learned from other protocols.
Subnet mask — Contains the subnet mask for the entry. If this field is zero, no subnet mask has been specified for the entry.
Next hop — Indicates the IP address of the next hop to which packets for the entry should be forwarded.


Reference:

http://ciscoiseasy.blogspot.in/2010/12/lesson-34-dynamic-routing-protocols.html
http://www.tcpipguide.com/free/t_RIPVersion1RIP1MessageFormat.htm
http://www.inetdaemon.com/tutorials/internet/ip/routing/rip/
http://lostintransit.se/2012/08/10/rip-request-and-response-packets/
ftp://ftp.landata.ru/Huawei_Symantec/Security/%CF%F0%EE%F8%E8%E2%EA%E8/%CD%EE%E2%FB%E9%20%F1%EE%F4%F2%20%E4%EB%FF%20USG/USG/data/3118G206_02.cdp/outfiles/merge_en.files/cfg_inter/topics/rip_intro_pkt.html



ARP layer in OSI model and format


Answer:

Layer 2 or 2.5 and not LAYER 3 since router not forwards the arp packet

http://networkengineering.stackexchange.com/questions/5064/on-which-layer-of-the-osi-model-does-the-arp-protocol-belong



Packet format:

Check this ARP Request capture:
Ethernet II, Src: 00:30:b8:83:cb:40, Dst: ff:ff:ff:ff:ff:ff
    Destination: ff:ff:ff:ff:ff:ff (Broadcast)
    Source: 
00:30:b8:83:cb:40  (00:30:b8:83:cb:40 )
    Type: ARP (0x0806)
    Trailer: FFE000200020003035800000FFE000100030              Address Resolution Protocol (request)
    Hardware type: Ethernet (0x0001)
    Protocol type: IP (0x0800)
    Hardware size: 6
    Protocol size: 4
    Opcode: request (0x0001)
    Sender MAC address: 
00:30:b8:83:cb:40 (00:30:b8:83:cb:40    Sender IP address: 201.6.115.1 (201.6.115.1)
    Target MAC address: 00:00:00_00:00:00 (00:00:00:00:00:00)
    Target IP address: 201.6.115.254 (201.6.115.254)








http://cauew.blogspot.in/2008/08/arp-rarp-proxy-arp-gratuitous-arp-and.html
http://www.tcpipguide.com/free/t_ARPMessageFormat.htm
http://wiki.wireshark.org/AddressResolutionProtocol



Saturday, August 30, 2014

what is strict aliasing and pointer aliasing and use of restrict keyword


pointer aliasing:
  • Pointers alias when they point to the same address.
    • Writing via one pointer will change the value read through another.
  • The compiler often doesn’t know which pointers alias.
    • The compiler must assume that any write through a pointer may affect the value read from any another pointer!
    • So compiler will not optimize code to handle the memory correctly
Strict aliasing:
1
2
3
4
5
int foo(int *x, int *y) {
  *x = 0;
  *y = 1;
  return *x;
}
Generated code typically looks like this:
foo:    movl    $0, (%rdi)
        movl    $1, (%rsi)
        movl    (%rdi), %eax
        ret

1
2
3
4
5
int foo(int *x, long *y) {
=====> int and long pointer and so optimized
  *x = 0;
  *y = 1;
  return *x;
}
Since a pointer-to-int and a pointer-to-long may be assumed to not alias each other, the function can be compiled to return zero:

foo2:   movl    $0, (%rdi)
        xorl    %eax, %eax
        movq    $1, (%rsi)
        ret

http://www.davespace.co.uk/arm/efficient-c-for-arm/aliasing.html
http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html


restrcit:

Listing 2.1: Example of using the restrict-Keyword
1 int * aPtr ;
2 int * restrict aPtr ;


without restrict:
=================

1 void update (int *a , int *b , int * c )
2 {
3 * a += * c;
4 * b += * c;
5 }


Listing 2.3: The assembler-code to listing 2.2      (6 instructions as variable "c" loaded every time due to strict aliasing rule of c )
=================================================

1 update :
2 movl (% rdx ) , % eax
3 addl % eax , (% rdi )
4 movl (% rdx ) , % eax
5 addl % eax , (% rsi )
6 ret



void update_restrict (int *a , int *b , int * restrict c )
2 {
3 * a += * c;
4 * b += * c;
5 }


Listing 2.5: The assembler-code to listing 2.4 (only 5 instrcturions due to restrict keyword and variable "c" will not be loaded every time)
1 update_restrict :
2 movl (% rdx ) , % eax
3 addl % eax , (% rdi )
4 addl % eax , (% rsi )
5 ret


Bottom line:
=========
Due to strict alaising rules (i.e. 3 different pointers of same data type may have hold same variable's adddress in 3 pointer variable(in above example). so compiler every time will load the variable C from memory before perfomring the operations. so addtional load instruction is done in the assembly level

if we are sure that for the third variable always be unique memory then with the help of restrict keyword we can tell compiler to optimize the code. i.e no need of two load command. only one load command is sufficent.

Best reference:
https://wr.informatik.uni-hamburg.de/_media/teaching/wintersemester_2013_2014/epc-1314-fasselt-c-keywords-report.pdf


http://en.wikipedia.org/wiki/Restrict
http://www.lysator.liu.se/c/restrict.html
http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule
http://stackoverflow.com/questions/12255686/understanding-restrict-qualifier-by-examples

According to the C language rationale document, the aliasing rules were originally made to avoid forcing compilers to always make worst-case aliasing assumptions. With the addition of the “restrict” keyword, we have a superior solution for this problem and the aliasing rules are no longer needed for that purpose.
http://blog.regehr.org/archives/959



variable length arugment list in c

keypoints

  • initialization of variable 
    • (va_list  <variable>)
  • like malloc or memset  
    • va_start(<variable>,<number>) 
  • like foreach  
    • va_arg(<variable>,<datatype>) inside loop
  • like memory free 
    • va_end(<variable>)

#include <stdio.h> #include <stdarg.h> double average(int num,...) { va_list valist; double sum = 0.0; int i; /* initialize valist for num number of arguments */ va_start(valist, num); /* access all the arguments assigned to valist */ for (i = 0; i < num; i++) { sum += va_arg(valist, int); } /* clean memory reserved for valist */ va_end(valist); return sum/num; } int main() { printf("Average of 2, 3, 4, 5 = %f\n", average(4, 2,3,4,5)); printf("Average of 5, 10, 15 = %f\n", average(3, 5,10,15)); }

very best explanation for each call present here:

The standard header <stdarg.h> contains a set of macro definitions that define how to step through an argument list. The implementation of this header will vary from machine to machine, but the interface it presents is uniform.
  1. The type va_list is used to declare a variable that will refer to each argument in turn; in minimal_printf , this variable is called ap , for "argument pointer".
  2. The macro va_start initializes ap to point to the first unnamed argument. It must be called once before ap is used.
  3. There must be at least one named argument; the final named argument is used by va_start to get started.
  4. Each call of va_arg returns one argument and steps ap to the next; va_arg uses a type name to determine what type to return and how big a step to take.
  5. Finally, va_end does whatever cleanup is necessary. It must be called before the program returns.
Here is the implemetation of our minimal_printf() which gives us idea about both the original printf() and variable number of argument function.

https://www.hackerearth.com/practice/notes/know-our-printf-variable-number-of-arguments-to-a-function/

Easy printf implementaion:

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

void errmsg( const char* format, ... )
{
  va_list arglist;

  printf( "Error: " );
  va_start( arglist, format );
  vprintf( format, arglist );
  va_end( arglist );
}

int main( void )
{
  errmsg( "%s %d %s", "Failed", 100, "times" );
  return EXIT_SUCCESS;
}
Ref: https://stackoverflow.com/questions/5977326/call-printf-using-va-list

or

#include<stdio.h>
#include<stdarg.h>

char ErrStr[128];
char Status[128];
int flag=1;

void Feeder( char *buff,...)
{
    va_list arglist;

    va_start(arglist,buff);

    //customized operations...
    if (flag<0)
        vsprintf(ErrStr,buff,arglist);
    else if (flag>=0)
        vsprintf(Status,buff,arglist);

    va_end(arglist);
}

int main()
{
    Feeder("Hello World %d %f %s\n",5,5.55,"55.55");
    if(Status[0])
        printf("Result: %s\n",Status);

    return 0;
}
Ref: http://cc.byexamples.com/2007/01/18/va-list-create-function-like-printf-2/

Full printf implementation:

 #include<stdio.h> 
#include<stdarg.h>      

void Myprintf(char *,...);     //Our printf function
char* convert(unsigned int, int);   //Convert integer number into octal, hex, etc.


int main() 
{ 
 Myprintf(" WWW.FIRMCODES.COM \n %d", 9); 
 
 return 0;
} 


void Myprintf(char* format,...) 
{ 
 char *traverse; 
 unsigned int i; 
 char *s; 
 
 //Module 1: Initializing Myprintf's arguments 
 va_list arg; 
 va_start(arg, format); 
 
 for(traverse = format; *traverse != '\0'; traverse++) 
 { 
  while( *traverse != '%' ) 
  { 
   putchar(*traverse);
   traverse++; 
  } 
  
  traverse++; 
  
  //Module 2: Fetching and executing arguments
  switch(*traverse) 
  { 
   case 'c' : i = va_arg(arg,int);  //Fetch char argument
      putchar(i);
      break; 
      
   case 'd' : i = va_arg(arg,int);   //Fetch Decimal/Integer argument
      if(i<0) 
      { 
       i = -i;
       putchar('-'); 
      } 
      puts(convert(i,10));
      break; 
      
   case 'o': i = va_arg(arg,unsigned int); //Fetch Octal representation
      puts(convert(i,8));
      break; 
      
   case 's': s = va_arg(arg,char *);   //Fetch string
      puts(s); 
      break; 
      
   case 'x': i = va_arg(arg,unsigned int); //Fetch Hexadecimal representation
      puts(convert(i,16));
      break; 
  } 
 } 
 
 //Module 3: Closing argument list to necessary clean-up
 va_end(arg); 
} 

char *convert(unsigned int num, int base) 
{ 
 static char Representation[]= "0123456789ABCDEF";
 static char buffer[50]; 
 char *ptr; 
 
 ptr = &buffer[49]; 
 *ptr = '\0'; 
 
 do 
 { 
  *--ptr = Representation[num%base]; 
  num /= base; 
 }while(num != 0); 
 
 return(ptr); 
}
#include <stdio.h>
#include <stdarg.h>

extern char *itoa(int, char *, int);

void myprintf(const char *fmt, ...)
{
const char *p;
va_list argp;
int i;
char *s;
char fmtbuf[256];

va_start(argp, fmt);

for(p = fmt; *p != '\0'; p++)
 {
 if(*p != '%')
  {
  putchar(*p);
  continue;
  }

 switch(*++p)
  {
  case 'c':
   i = va_arg(argp, int);
   putchar(i);
   break;

  case 'd':
   i = va_arg(argp, int);
   s = itoa(i, fmtbuf, 10);
   fputs(s, stdout);
   break;

  case 's':
   s = va_arg(argp, char *);
   fputs(s, stdout);
   break;

  case 'x':
   i = va_arg(argp, int);
   s = itoa(i, fmtbuf, 16);
   fputs(s, stdout);
   break;

  case '%':
   putchar('%');
   break;
  }
 }

va_end(argp);
}



REf:
http://www.firmcodes.com/write-printf-function-c/
https://www.eskimo.com/~scs/cclass/int/sx11b.html

Used area:
  • To calculate average
  • in cli framework
Reference: