Skip to content

Instantly share code, notes, and snippets.

@pablohdzvizcarra
Created April 19, 2024 03:24
Show Gist options
  • Save pablohdzvizcarra/1b107c13c68ff93e7765568c2a47c634 to your computer and use it in GitHub Desktop.
Save pablohdzvizcarra/1b107c13c68ff93e7765568c2a47c634 to your computer and use it in GitHub Desktop.
Representation fo the OSI Model with golang code
package main
// OSI Model Open System Intercommunication Model
// You can see the OSI Model as an standard for applications.
// Each layer in the OSI model is decoupled from the other layers.
// ## SENDER
// 7 layers each describe a specific networking component
// Layer 7 - Application: HTTP/FTP/gRPC.
// Layer 6 - Presentation: Encoding, serialization.
// Layer 5 - Session: Connection establishment, TLS.
// Layer 4 - Transport: UCP/TCP. -- We know the port (8080, 443, 22) SEGMENT
// Layer 3 - Network: IP packets, IP address, routing. PACKET
// Layer 2 - Data Link: Frames, Mac address ethernet. FRAME
// Layer 1 - Physical: Electric signals, fiber or radio waves.
// ## RECEIVER
// Layer 1 - Physical: Radio, electric or light is received anc converted into digital bits.
// Layer 2 - Data link: The bits from Layer 1 is assembled into frames
// Layer 3 - Network: The frames from layer 2 are assembled into IP packet.
// Layer 4 - Transport:
// - The IP packets from in layer 3 are assembled into TCP/UDP packets.
// - Deals with congestion control, flow control, error detection and correction in case of TCP.
// - If segment is SYN we do not need to go further into more layers as we are still processing the connection request.
// Layer 5 - Session:
// - Connection establishment, TLS.
// - If the connection is not established we do not need to go further into more layers.
// - We only arrive at this layer if the connection is established (three way handshake is completed).
// Layer 6 - Presentation: Deserialize flat byte strings back to JSON for the app to consume.
// Layer 7 - Application: application understand the JSON POST request and your express json or apache request event is triggered.
// Example: client sends an HTTP request to a server.
// -- Client -- Server
// Application (HTTP) Application (HTTP)
// Presentation (JSON) Presentation (JSON)
// Session (Connection) Session (Connection)
// Transport (TCP/UDP) Transport (TCP/UDP)
// Network (IP) Network (IP)
// Data Link (Frames) Data Link (Frames)
// Physical (Electric signals) -----> Physical (Electric signals)
// Example: client send an HTTP request to a server, but the client and server needs to create a session first.
// -- Client -- Server
// Application (HTTP)
// Presentation (JSON)
// Session (Connection) Session (Connection) -- Server sends SYN-ACK
// Transport (TCP/UDP) Transport (TCP/UDP)
// Network (IP) Network (IP)
// Data Link (Frames) Data Link (Frames)
// Physical (Electric signals) -----> Physical (Electric signals)
// Example: client sends an HTTP request to a server.
// -- Client -- Server
// Application (HTTP) Application (HTTP)
// Presentation (JSON) Presentation (JSON)
// Session (Connection) Session (Connection)
// Transport [Source port and destination port] Transport [Source port and destination port]
// Network [Source IP and destination IP] Network [Source IP and destination IP]
// Data Link [Source MAC and destination MAC] Data Link [Source MAC and destination MAC]
// Physical (Electric signals) -----> Physical (Electric signals)
import (
"encoding/hex"
"encoding/json"
"fmt"
"hash/crc32"
)
// Each frame becomes string of bytes which converted either into a radio signal (wifi),
// electric signal (ethernet), or light (fiber)
func layerOne(frame []byte, medium string) []byte {
frameBytes := []byte(frame)
frameHex := hex.EncodeToString(frameBytes)
switch medium {
case "wifi":
fmt.Printf("Converting frame to radio signal: %s\n", frameHex)
case "ethernet":
fmt.Printf("Converting frame to electric signal: %s\n", frameHex)
case "fiber":
fmt.Printf("Converting frame to light signal: %s\n", frameHex)
}
return frame
}
func layerTwo(data []byte) map[string]interface{} {
frame := map[string]interface{}{
"Destination MAC Address": "AA:BB:CC:DD:EE:FF",
"Source Mac Address": "FF:EE:DD:CC:BB:AA",
"EtherType": "0x0800", // EtherType for IPV4
"Frame check sequence": calculateCRC32([]byte(data)),
"Data": data,
}
return frame
}
func calculateCRC32(data []byte) uint32 {
return crc32.ChecksumIEEE(data)
}
func layerThree(frame map[string]interface{}) map[string]interface{} {
frame["Source IP Address"] = "192.168.1.1"
frame["Destination IP Address"] = "192.168.1.2"
return frame
}
func layerFour(frame map[string]interface{}) map[string]interface{} {
frame["Transport Protocol"] = "TCP"
frame["Source Port"] = 12345
frame["Destination Port"] = 80
return frame
}
func layerFive(frame map[string]interface{}) map[string]interface{} {
frame["Session ID"] = "ABC123"
return frame
}
func layerSix(frame map[string]interface{}) map[string]interface{} {
frame["Data Format"] = "JSON"
return frame
}
func layerSeven(frame map[string]interface{}) string {
bytesSlice, _ := frame["Data"]
str := string(bytesSlice.([]byte))
frame["Data"] = str
jsonData, _ := json.Marshal(frame)
return string(jsonData)
}
func main() {
fmt.Println("Starting application")
// This function execution is like simulating sending sending electrical signals to a Ethernet cable
// create a json string
json := `{"name": "John Doe", "age": 30, "city": "New York"}`
dataBytes := []byte(json)
fmt.Println(dataBytes)
frame := layerOne(dataBytes, "ethernet")
frameUpdated := layerTwo(frame)
frameUpdated = layerThree(frameUpdated)
frameUpdated = layerFour(frameUpdated)
frameUpdated = layerFive(frameUpdated)
frameUpdated = layerSix(frameUpdated)
finalData := layerSeven(frameUpdated)
fmt.Println(finalData)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment