Layered Network Structure
Layered network structure is the central idea behind the design of computer networks. It decomposes the complex task of network communication into a number of relatively independent layers. This page covers the basic concepts of layering along with protocols, interfaces, and services.
1. Purpose of Layering
Layering serves several purposes:
- Simplifying complexity: splits a complex networking problem into several simple ones
- Modular design: each layer is designed independently, which eases development and maintenance
- Standardisation: gives devices from different vendors a common interface standard
- Flexibility: each layer can be upgraded and improved on its own
2. Basic Principles of Layering
Layer Independence
- Each layer interacts only with its adjacent layers
- An upper layer does not care how a lower layer is implemented
- A lower layer does not care what application sits above it
Functional Encapsulation
- Each layer implements a specific function
- Layers communicate through standard interfaces
- The internal implementation is transparent to the outside
Protocol Standardisation
- Every layer has standardised protocols
- Devices from different vendors can interoperate
- The network is easier to extend and maintain
1. Definition of a Protocol
A protocol is the set of rules and conventions that peer entities in the same layer follow when they communicate.
2. Elements of a Protocol
Syntax
- Data format and encoding
- Field lengths and ordering
- Control characters and special symbols
Semantics
- The meaning of control information
- The interpretation of each operation
- How errors are handled
Timing
- The order in which events occur
- Requirements for matching speeds
- Synchronisation and asynchronous mechanisms
3. Protocol Design Example
// Protocol header structure
typedef struct {
uint8_t version; // Protocol version
uint8_t type; // Message type
uint16_t length; // Data length
uint32_t sequence; // Sequence number
uint32_t checksum; // Checksum
} ProtocolHeader;
// Protocol type enumeration
typedef enum {
PROTO_TYPE_DATA = 0x01,
PROTO_TYPE_ACK = 0x02,
PROTO_TYPE_NACK = 0x03,
PROTO_TYPE_HEARTBEAT = 0x04
} ProtocolType;
// Protocol message structure
typedef struct {
ProtocolHeader header;
uint8_t data[1024]; // Data part
} ProtocolMessage;
// Create a protocol message
ProtocolMessage* create_protocol_message(ProtocolType type, const uint8_t* data, uint16_t length) {
ProtocolMessage* msg = malloc(sizeof(ProtocolMessage));
if (!msg) return NULL;
msg->header.version = 1;
msg->header.type = type;
msg->header.length = length;
msg->header.sequence = get_next_sequence();
if (data && length > 0) {
memcpy(msg->data, data, length);
}
msg->header.checksum = calculate_checksum(msg);
return msg;
}
// Validate a protocol message
int validate_protocol_message(const ProtocolMessage* msg) {
if (!msg) return 0;
// Check the version
if (msg->header.version != 1) return 0;
// Check the length
if (msg->header.length > 1024) return 0;
// Check the checksum
uint32_t calculated_checksum = calculate_checksum(msg);
if (msg->header.checksum != calculated_checksum) return 0;
return 1;
}
1. Definition of an Interface
An interface is the connection and the interaction rules between two adjacent layers. It defines how an upper layer calls the services of a lower layer.
2. Characteristics of an Interface
Standardisation
- Interface definitions are public standards
- Different implementations must follow the same interface
- This eases interoperability and compatibility
Abstraction
- The interface hides implementation details
- An upper layer does not need to know how a lower layer is implemented
- It provides a clear way to make calls
Stability
- Once an interface is defined it should stay stable
- It avoids frequent interface changes
- It preserves backward compatibility
3. Interface Design Example
// Network interface definition
typedef struct {
int (*send)(const void* data, size_t length);
int (*receive)(void* buffer, size_t max_length);
int (*connect)(const char* address, int port);
int (*disconnect)(void);
int (*get_status)(void);
} NetworkInterface;
// Transport layer interface
typedef struct {
int (*send_packet)(const uint8_t* data, uint16_t length, uint32_t dest_addr);
int (*receive_packet)(uint8_t* buffer, uint16_t max_length, uint32_t* src_addr);
int (*open_connection)(uint32_t dest_addr, uint16_t dest_port);
int (*close_connection)(int connection_id);
int (*get_connection_status)(int connection_id);
} TransportInterface;
// Network layer interface
typedef struct {
int (*route_packet)(const uint8_t* data, uint16_t length, uint32_t dest_addr);
int (*forward_packet)(const uint8_t* data, uint16_t length, int interface_id);
int (*add_route)(uint32_t network, uint32_t mask, uint32_t next_hop);
int (*remove_route)(uint32_t network, uint32_t mask);
} NetworkLayerInterface;
// Data link layer interface
typedef struct {
int (*send_frame)(const uint8_t* data, uint16_t length, uint8_t* dest_mac);
int (*receive_frame)(uint8_t* buffer, uint16_t max_length, uint8_t* src_mac);
int (*get_mac_address)(uint8_t* mac_addr);
int (*set_mac_address)(const uint8_t* mac_addr);
} DataLinkInterface;
1. Definition of a Service
A service is the set of functions a lower layer offers to the layer above. It defines the operations the upper layer may use.
2. Types of Service
Connection-Oriented Service
- Characteristics: establish a connection, transfer data, release the connection
- Advantages: high reliability, ordering guaranteed
- Disadvantages: larger overhead, higher latency
- Typical application: the TCP protocol
Connectionless Service
- Characteristics: send data directly, with no connection to set up
- Advantages: small overhead, low latency
- Disadvantages: lower reliability, no ordering guarantee
- Typical application: the UDP protocol
3. Service Primitives
Request Primitive
- The upper layer asks the lower layer for a service
- Parameters are usually passed along
- The caller may block while waiting for a response
Indication Primitive
- The lower layer notifies the upper layer of an event
- It usually carries information about the event
- It may trigger handling in the upper layer
Response Primitive
- The upper layer responds to an indication from the lower layer
- It usually carries the result of the handling
- It may affect the state of the lower layer
Confirm Primitive
- The lower layer confirms to the upper layer that a request completed
- It usually carries the execution result
- It may carry status information
4. Service Implementation Example
// Service primitive type
typedef enum {
PRIMITIVE_REQUEST = 0,
PRIMITIVE_INDICATION = 1,
PRIMITIVE_RESPONSE = 2,
PRIMITIVE_CONFIRM = 3
} PrimitiveType;
// Service primitive structure
typedef struct {
PrimitiveType type;
uint32_t service_id;
uint32_t connection_id;
void* data;
size_t data_length;
int result;
} ServicePrimitive;
// Transport layer service
typedef struct {
int (*connect_request)(uint32_t dest_addr, uint16_t dest_port);
int (*connect_indication)(uint32_t src_addr, uint16_t src_port);
int (*connect_response)(int connection_id, int accept);
int (*connect_confirm)(int connection_id, int status);
int (*data_request)(int connection_id, const void* data, size_t length);
int (*data_indication)(int connection_id, const void* data, size_t length);
int (*disconnect_request)(int connection_id);
int (*disconnect_indication)(int connection_id);
} TransportService;
// Network layer service
typedef struct {
int (*send_request)(uint32_t dest_addr, const void* data, size_t length);
int (*send_confirm)(int request_id, int status);
int (*receive_indication)(uint32_t src_addr, const void* data, size_t length);
} NetworkService;
// Data link layer service
typedef struct {
int (*send_request)(const uint8_t* dest_mac, const void* data, size_t length);
int (*send_confirm)(int request_id, int status);
int (*receive_indication)(const uint8_t* src_mac, const void* data, size_t length);
} DataLinkService;
1. Vertical Communication
Vertical communication is communication between adjacent layers inside the same node.
// Inter-layer communication manager
typedef struct {
NetworkInterface network_interface;
TransportInterface transport_interface;
NetworkLayerInterface network_layer_interface;
DataLinkInterface data_link_interface;
} LayerCommunicationManager;
// Pass data upwards
int pass_data_up(LayerCommunicationManager* manager, int layer_id,
const void* data, size_t length) {
switch(layer_id) {
case 1: // physical layer to data link layer
return manager->data_link_interface.receive_frame(
(uint8_t*)data, length, NULL);
case 2: // data link layer to network layer
return manager->network_layer_interface.forward_packet(
(uint8_t*)data, length, 0);
case 3: // network layer to transport layer
return manager->transport_interface.receive_packet(
(uint8_t*)data, length, NULL);
default:
return -1;
}
}
// Pass data downwards
int pass_data_down(LayerCommunicationManager* manager, int layer_id,
const void* data, size_t length) {
switch(layer_id) {
case 3: // transport layer to network layer
return manager->network_layer_interface.route_packet(
(uint8_t*)data, length, 0);
case 2: // network layer to data link layer
return manager->data_link_interface.send_frame(
(uint8_t*)data, length, NULL);
case 1: // data link layer to physical layer
return manager->network_interface.send(data, length);
default:
return -1;
}
}
2. Horizontal Communication
Horizontal communication is communication between peer layers in different nodes.
// Peer layer communication
typedef struct {
uint32_t local_addr;
uint32_t remote_addr;
int layer_id;
ProtocolMessage* protocol;
} PeerCommunication;
// Send to a peer layer
int send_to_peer(PeerCommunication* comm, const void* data, size_t length) {
// Create the protocol message
ProtocolMessage* msg = create_protocol_message(
PROTO_TYPE_DATA, (uint8_t*)data, length);
if (!msg) return -1;
// Add the layer identifier
msg->header.type |= (comm->layer_id << 4);
// Hand it to the lower layer
return pass_data_down(NULL, comm->layer_id, msg,
sizeof(ProtocolHeader) + length);
}
// Receive from a peer layer
int receive_from_peer(PeerCommunication* comm, void* buffer, size_t max_length) {
// Receive the data from the lower layer
uint8_t temp_buffer[1024];
int received = pass_data_up(NULL, comm->layer_id, temp_buffer, 1024);
if (received <= 0) return received;
// Parse the protocol message
ProtocolMessage* msg = (ProtocolMessage*)temp_buffer;
if (!validate_protocol_message(msg)) return -1;
// Check the layer identifier
if ((msg->header.type >> 4) != comm->layer_id) return -1;
// Copy the data
size_t data_length = msg->header.length;
if (data_length > max_length) data_length = max_length;
memcpy(buffer, msg->data, data_length);
return data_length;
}
1. Modular Design
- Each layer is developed and tested on its own
- It eases collaboration between teams
- It lowers the complexity of the system
2. Standardised Interfaces
- Devices from different vendors interoperate
- The network is easy to extend
- Development costs go down
3. Flexibility
- Each layer can be upgraded independently
- Different implementations are supported
- Different application requirements can be met
4. Maintainability
- Faults are easier to localise
- A change affects a smaller area
- The system is easier to maintain
| Term | Abbreviation | Explanation |
|---|---|---|
| Layered Architecture | - | Hierarchical design of a network |
| Protocol | - | Rules and formats for communication |
| Interface | - | Interface between adjacent layers |
| Service | - | Functions a lower layer offers to the layer above |
| Service Access Point | SAP | Endpoint of an inter-layer interface |
| Protocol Data Unit | PDU | Data unit of each layer |
| Frame | - | PDU of the data link layer |
| Packet / Datagram | - | PDU of the network layer |
| Segment | - | PDU of the transport layer |
| Message | - | PDU of the application layer |
| Encapsulation | - | Process of adding a header |
| Decapsulation | - | Process of removing a header |
| Entity | - | Active element within a layer |
| Peer Entity | - | Entity in the same layer of a different system |
| Connection-oriented Service | - | Service that establishes a connection first |
| Connectionless Service | - | Service that needs no connection |
| Acknowledgment | ACK | Acknowledgement sent by the receiver |
