
                     T H E  Medium Access Control (MAC) LAYER
                     ========================================
                            (C) 1993 by Oliver Rehmann
                             100016.732@compuserve.com
                    


Motivation
==========

When I first came into contact with the MAC layer I was a high school
student. It was a dream of mine to write the worlds best network sniffer. :-)

The project failed because of the MAC layer. There was no accurate information
about this layer of the OSI reference model and as a high school student 
I did not have  enough money to buy all those expensive books about networks. 
Another stumbling block was that I didn't have a low level driver for my LAN 
adapter (NE2000).

I know there exist hundreds of books about this subject. What I am trying
to convey you is a summary of information you need when working on the
MAC layer of an Ethernet. Thus the information provided in this document 
is only for Ethernet !!!


History of ETHERNET
===================

Ethernet was developed by Xerox in the seventies. The specification of 
Ethernet Version 1.0 has been released 1980 by Dec, Intel and Xerox
(The Blue Book Ethernet).

Two years later the same group (DIX) released version 2.0 of Ethernet.
Another three years later the IEEE group specified the 802.3 paper.

Quick Reference : Ethernet (Version 1.0)
----------------------------------------

Topology                : Bus
Media Access            : CSMA/CD = Carrier Sense Multiple Access with 
                                    Collision Detection

Throughput              : 10 Mbit/sec.

max. distance between 
two stations            : 2800m

max. stations           : 1024


Frame format:
-------------

Preamble    length      : 8 Bytes
Destination address     : 6 Bytes
Source      address     : 6 Bytes
Type field              : 2 Bytes
Data field length       : 46 - 1500 Bytes
Frame Checksum          : 4 Bytes
                        ------------------------
                          72 - 1526 Bytes
                        ========================


The OSI Reference model
=======================

When talking about networks, it is useful to refer to the OSI reference 
model (OSI = Open Systems Interconnection).


Ŀ
 Layer 7                
 Application            
Ĵ
 Layer 6                
 Presentation           
Ĵ
 Layer 5                
 Session                
Ĵ
 Layer 4                
 Transport              
Ĵ
 Layer 3                
 Network                
Ĵ                     
 Layer 2b               
 Logical Link Control            D a t a  L i n k  C o n t r o l
 (LLC)                  
            Ĵ                  L a y e r
 Layer 2a               
 Medium Access Control                    (2a + 2b)
 (MAC)                  
Ĵ                     
 Layer 1b               
 Physical (PHY)                       P h y s i c a l
                        
            Ĵ                 L a y e r
 Layer 1a               
 Physical Medium                         (1a + 1b)
 Dependent (PMD)        
                     

What I will describe are layers 2a and 2b (MAC and LLC).
Normally, if you are interfacing with your LAN adapter at packet level,
layer one is invisible to you. The transceiver is on this layer.

Layer 2
-------
Data Link Control: Errorfree Frame Transmission between physically
                   connected nodes.

On this layer the programmer has to handle incoming and outgoing packets.
These packets often are called frames.

IEEE 802.3 (Ethernet) Frame
===========================

Ŀ
 7 Bytes   1 Byte  6 Bytes  6 Bytes  2 Bytes  46...1500 Bytes  4 Bytes 
 Preamble    SFD   Dest.    Source   Length   of Data            FCS   
                   Address  Address  (Type)   (at least 46 B)          

                                                        LLC        
legend of frame format:

  Preamble : 7 Bytes                      => 10101010
  SFD      : 1 Byte Start Frame Delemiter => 10101011
  
  Preamble and SFD are used for synchronisation of all receivers.
  
  Destination address : 6 Byte hardware address of receiver
  Source      address : 6 Byte hardware address of sender 
  
         example.
          
          8000207F59E8 => 8000207F59E8

          This is called an Ethernet hardware address. They are unique.
          
  Length   : If this word (2 Bytes) is smaller than 5EEh (1500+18) the frame
             is a standard IEEE 802.3 frame. Length represents the number of
             bytes in the Data (LLC) field.
             If the length field is greater than 5EEh it is an ETHERNET frame.
             The difference is that length is no longer a valid length but
             it represents a type. (See table in file ETHERNET.TYP)
             
  Data     : 46..1500 Bytes of Data. The smallest frame on an Ethernet
  (LLC)      (CSMA/CD) has to be at least 64 Bytes. The header consists of
             18 Bytes so the data field must hold 46 or more Bytes.
             
  FCS      : Frame Check Sequence. This is a cyclic redundancy checksum
  

Data representation
-------------------

When receiving packets from your LAN adapter (ex. through Crynrware packet 
drivers) you must know what type of CPU your computer has. This is important 
for data representation.

The type (length) field in an Ethernet frame always corresponds to a Big Endian 
system (ex. Motorola 68000, etc.).

Intel 80x86 CPUs are Little Endian systems so you have to swap the lo and hi
byte of a word.

Ex. DOD IP = 0800h -> Swap -> 0008h (on a 80x86 PC)

Summary
-------

Ethernet and IEEE 802.3 frames differ from each other by the type field.

Ethernet defines different types (see file ETHERNET.TYP). 

IEEE 802.3 uses the type field as a length field to say how many bytes
the data field holds. The type of the packet is stored in the LLC header
which is part of the data field.

This can be very time consuming work for a LAN adapter because it 
always has to look into the LLC header to determine the packet type.

Ethernet addresses
------------------

The first three bytes of an Ethernet address identify the vendor of
the LAN adapter.

   example:

     08-00-09-12-7F-05  : 08-00-09 -> Vendor is Hewlett Packard  (HP)
     08-00-20-24-AB-55  : 08-00-20 -> Vendor is Sun Microsystems (SUN)

The well known vendor identifiers are listed in the file ETHERNET.VND.


Turbo Pascal definitions
------------------------

Data structures used for MAC layer handling.

TYPE

       { 6 Byte Ethernet address }
       EthernetAddr = Array[00..05] of Byte;

       { Definition of a Medium Access Control header }
       MACHeader    = RECORD
                        DestAddr   : EthernetAddr;
                        SourceAddr : EthernetAddr;
                        TypeLen    : Word;
                      END;


Turbo Pascal functions
----------------------

Functions for handling data on the MAC layer.

FUNCTION SwapWord(sWord : Word) : Word;
{ͻ
  FUNCTION  SwapWord;                                                  
 Ķ
  Description   :  Swaps the lo and hi byte of a word.                
                   Used for type (length) field manipulation.         
 Ķ
  Creation date :  20-SEPT-93                                         
 ͼ}
VAR tWord : Word;
BEGIN
  tWord := (Lo(sWord) SHL 8) + Hi(sWord);
  SwapWord := tWord;
END;

FUNCTION ByteToHEXASCII(tByte : Byte) : String;
{ͻ
  FUNCTION  ByteToHEXASCII (...) : String;                             
 Ķ
  Description   :  Converts a byte  into a HEX-ASCII-String.          
                                                                      
 Ķ
  Creation date :  20-SEPT-93                                         
 ͼ}
CONST
   HEXChars: array [0..15] of char = '0123456789ABCDEF';
VAR Nibble1 : Byte;
    Nibble2 : Byte;
    tStr    : String;
BEGIN
  Nibble1 := (tByte AND $0F);        { AND 00001111b }
  Nibble2 := (tByte AND $F0) SHR 4;  { AND 11110000b }
  tStr := HEXChars[Nibble2]+HEXChars[Nibble1];
  ByteToHEXASCII := tStr;
END;

FUNCTION WordToHEXASCII(tWord : Word) : String;
{ͻ
  FUNCTION  WordToHEXASCII (...) : String;                             
 Ķ
  Description   :  Converts a word into a HEX-ASCII-String            
                                                                      
 Ķ
  Creation date :  20-SEPT-93                                         
 ͼ}
VAR tStr : String;
BEGIN
  tStr := ByteToHexASCII(Hi(tWord));
  tStr := tStr+ByteToHexASCII(Lo(tWord));
  WordToHexASCII := tStr;
END;

PROCEDURE TranslateEthernetAddress(tStr : String; VAR tEtheraddr : EthernetAddr);
{ͻ
  PROCEDURE TranslateEthernetAddress(..);                              
 Ķ
  Description   :  Translates a dash separated Ethernet address into  
                   6 Bytes.                                           
 Ķ
  Creation date :  20-SEPT-93                                         
 ͼ}
VAR tDigit : String;
    tByte  : Byte;
    Err    : Integer;
    tVal   : Byte;
BEGIN
  tDigit :='';
  FOR tByte := 1 TO Length(tStr) DO
  BEGIN
    IF (Copy(tStr,tByte,1) <> '-') THEN tDigit := tDigit + Copy(tStr,tByte,1);
  END;
  FOR tByte := 0 TO 5 DO
  BEGIN
    Val('$'+Copy(tDigit,(tByte*2)+1,2),tVal,Err);
    tEtheraddr[tByte] := tVal;
  END;
END;

FUNCTION GetEthernetAddress(tEtherAddr : EthernetAddr) : String;
{ͻ
  FUNCTION GetEthernetAddress;                                         
 Ķ
  Description   :  Translates an Ethernet address into a dash         
                   separated string.                                  
 Ķ
  Creation date :  20-SEPT-93                                         
 ͼ}
VAR tString : String;
    tDigit  : String[02];
    tCount  : Byte;
    AddrLen : Byte;
BEGIN
  AddrLen := SizeOf(EthernetAddr)-1;
  tString := '';

  FOR tCount := 0 TO AddrLen DO
  BEGIN
    tString := tString + ByteToHexASCII(tEtherAddr[tCount]);
    IF (tCount < AddrLen) THEN tString := tString + '-';
  END;
  GetEthernetAddress := tString;
END;

FUNCTION CompareEthernetAddr(Addr1,Addr2 : EthernetAddr) : Boolean;
{ͻ
  FUNCTION CompareEthernetAddr;                                        
 Ķ
  Description   :  Compares two Ethernet addresses.                   
                   Returns TRUE if they are equal.                    
 Ķ
  Creation date :  20-SEPT-93                                         
 ͼ}
VAR Result : Boolean;
    Count  : Byte;
BEGIN
  Result := TRUE;
  Count  := 0;
  REPEAT
    IF (Addr1[Count] <> Addr2[Count]) THEN Result := FALSE;
    Inc(Count);
  UNTIL Not(Result) OR (Count = 6);
  CompareEthernetAddr := Result;
END;


Conditions
==========

This paper can be freely copied as long as Copyright indications 
are not changed or dropped.

The author can not be held responsible for any damages resulting 
from the use of information given in this document.

The author can be reached through the following e-mail adresses:

Internet  : 100016.732@compuserve.com
            CZ8OR@zcvx00.decnet.ascom.ch
CompuServe: ID : 100016,732

