Skip to content

Commit

Permalink
IP and ICMP protocol implemented. Issue in getting the reply.
Browse files Browse the repository at this point in the history
  • Loading branch information
gokhan-uysal committed Jul 12, 2024
1 parent 8251286 commit 19f19d0
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 243 deletions.
50 changes: 43 additions & 7 deletions cmd/pingo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"encoding/hex"
"fmt"
"net"
"syscall"

"github.com/code-brew-lab/pingo/pkg/netcore"
Expand All @@ -14,25 +15,60 @@ func main() {
fmt.Println(err)
return
}
defer syscall.Close(fd)

ip, err := netcore.NewIPBuilder(net.IPv4(216, 239, 38, 120)).
Protocol(netcore.ProtocolICMP).
Build()
if err != nil {
fmt.Println(err)
return
}

icmp, err := netcore.NewICMP(netcore.ControlKindExtendedEchoRequest)
if err != nil {
fmt.Println(err)
return
}

datagram, err := netcore.NewDatagram(ip, icmp)
if err != nil {
fmt.Println(err)
return
}

addr := &syscall.SockaddrInet4{
Port: 0,
Addr: [4]byte{216, 239, 38, 120},
}

err = syscall.Sendto(fd, datagram.Marshal(), 0, addr)
if err != nil {
fmt.Println(err)
return
}

for {
buf := make([]byte, 1024)
numRead, err := syscall.Read(fd, buf)
buff := make([]byte, 1024)
numRead, err := syscall.Read(fd, buff)
if err != nil {
fmt.Println(err)
continue
}

datagram, err := netcore.ParseDatagram(buf[:numRead], netcore.ProtocolICMP)
datagram, err := netcore.ParseDatagram(buff[:numRead], netcore.ProtocolICMP)
if err != nil {
fmt.Println(err)
continue
}

fmt.Printf("Raw Datagram: %s\n", hex.EncodeToString(datagram.Raw()))
fmt.Printf("Raw Datagram: %s\n", hex.EncodeToString(datagram.Marshal()))
ip := datagram.IP()
t := datagram.Transporter()
fmt.Println(hex.EncodeToString(ip.Marshal()))
fmt.Print(hex.EncodeToString(t.Marshal()))
icmp := datagram.ICMP()
fmt.Println(ip.SourceIP())
fmt.Println(ip.DestinationIP())
fmt.Println(icmp.Kind())
fmt.Println(icmp.Code().String(icmp.Kind()))

}
}
11 changes: 7 additions & 4 deletions pkg/netcore/checksum/checksum.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@ import (
)

func Calculate(b []byte) uint16 {
if len(b)%2 != 0 {
b = append(b, 0)
raw := make([]byte, len(b))
copy(raw, b)

if len(raw)%2 != 0 {
raw = append(raw, 0)
}

var sum uint32
for i := 0; i < len(b); i += 2 {
sum += uint32(binary.BigEndian.Uint16(b[i : i+2]))
for i := 0; i < len(raw); i += 2 {
sum += uint32(binary.BigEndian.Uint16(raw[i : i+2]))
}

for sum>>16 != 0 {
Expand Down
186 changes: 31 additions & 155 deletions pkg/netcore/control_message.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,16 @@ type (

const (
// ControlKind definitions
ControlKindEchoReply ControlKind = 0x0 // 0 - Echo Reply
ControlKindDestinationUnreachable ControlKind = 0x3 // 3 - Destination Unreachable
ControlKindSourceQuench ControlKind = 0x4 // 4 - Source Quench
ControlKindRedirectMessage ControlKind = 0x5 // 5 - Redirect Message
ControlKindEchoRequest ControlKind = 0x8 // 8 - Echo Request
ControlKindRouterAdvertisement ControlKind = 0x9 // 9 - Router Advertisement
ControlKindRouterSolicitation ControlKind = 0xA // 10 - Router Solicitation
ControlKindTimeExceeded ControlKind = 0xB // 11 - Time Exceeded
ControlKindParameterProblem ControlKind = 0xC // 12 - Parameter Problem: Bad IP header
ControlKindTimestamp ControlKind = 0xD // 13 - Timestamp
ControlKindTimestampReply ControlKind = 0xE // 14 - Timestamp Reply
ControlKindInformationRequest ControlKind = 0xF // 15 - Information Request
ControlKindInformationReply ControlKind = 0x10 // 16 - Information Reply
ControlKindAddressMaskRequest ControlKind = 0x11 // 17 - Address Mask Request
ControlKindAddressMaskReply ControlKind = 0x12 // 18 - Address Mask Reply
ControlKindTraceroute ControlKind = 0x1E // 30 - Traceroute
ControlKindDeprecatedDatagramConversion ControlKind = 0x1F // 31 - Deprecated Datagram Conversion Error
ControlKindExtendedEchoRequest ControlKind = 0x2A // 42 - Extended Echo Request
ControlKindExtendedEchoReply ControlKind = 0x2B // 43 - Extended Echo Reply
ControlKindEchoReply ControlKind = 0x0 // 0 - Echo Reply
ControlKindDestinationUnreachable ControlKind = 0x3 // 3 - Destination Unreachable
ControlKindEchoRequest ControlKind = 0x8 // 8 - Echo Request
ControlKindExtendedEchoReply ControlKind = 0x2B // 43 - Extended Echo Reply
ControlKindExtendedEchoRequest ControlKind = 0x2A // 42 - Extended Echo Request
)

// ControlCode definitions for Echo Reply (ControlKind = 0)
const (
ControlCodeEchoReply ControlCode = 0x0 // 0 - Echo reply
ControlCodeEchoReply ControlCode = 0x0
)

// ControlCode definitions for Destination Unreachable (ControlKind = 3)
Expand All @@ -53,34 +39,23 @@ const (
ControlCodePrecedenceCutoffInEffect ControlCode = 0xF // 15 - Precedence cutoff in effect
)

// ControlCode definitions for Redirect Message (ControlKind = 5)
// ControlCode definitions for Echo Request (ControlKind = 8)
const (
ControlCodeRedirectDatagramForNetwork ControlCode = 0x0 // 0 - Redirect Datagram for the Network
ControlCodeRedirectDatagramForHost ControlCode = 0x1 // 1 - Redirect Datagram for the Host
ControlCodeRedirectDatagramForToSNet ControlCode = 0x2 // 2 - Redirect Datagram for the ToS & network
ControlCodeRedirectDatagramForToSHost ControlCode = 0x3 // 3 - Redirect Datagram for the ToS & host
ControlCodeEchoRequest ControlCode = 0x0
)

// ControlCode definitions for Time Exceeded (ControlKind = 11)
const (
ControlCodeTTLExpiredInTransit ControlCode = 0x0 // 0 - TTL expired in transit
ControlCodeFragmentReassemblyTimeExceeded ControlCode = 0x1 // 1 - Fragment reassembly time exceeded
)

// ControlCode definitions for Parameter Problem (ControlKind = 12)
// ControlCode definitions for Extended Echo Reply (ControlKind = 43)
const (
ControlCodePointerIndicatesError ControlCode = 0x0 // 0 - Pointer indicates the error
ControlCodeMissingRequiredOption ControlCode = 0x1 // 1 - Missing a required option
ControlCodeBadLength ControlCode = 0x2 // 2 - Bad length
ControlCodeNoError ControlCode = 0x0
ControlCodeMalformedQuery ControlCode = 0x1
ControlCodeNoSuchInterface ControlCode = 0x2
ControlCodeNoSuchTableEntry ControlCode = 0x3
ControlCodeMultipleInterfacesSatisfyQuery ControlCode = 0x4
)

// ControlCode definitions for Extended Echo Reply (ControlKind = 43)
// ControlCode definitions for Extended Echo Request (ControlKind = 42)
const (
ControlCodeNoError ControlCode = 0x0 // 0 - No Error
ControlCodeMalformedQuery ControlCode = 0x1 // 1 - Malformed Query
ControlCodeNoSuchInterface ControlCode = 0x2 // 2 - No Such Interface
ControlCodeNoSuchTableEntry ControlCode = 0x3 // 3 - No Such Table Entry
ControlCodeMultipleInterfacesSatisfyQuery ControlCode = 0x4 // 4 - Multiple Interfaces Satisfy Query
ControlCodeExtendedEchoRequest ControlCode = 0x0
)

func ParseControlKind(kind uint8) ControlKind {
Expand All @@ -89,40 +64,12 @@ func ParseControlKind(kind uint8) ControlKind {
return ControlKindEchoReply
case uint8(ControlKindDestinationUnreachable):
return ControlKindDestinationUnreachable
case uint8(ControlKindSourceQuench):
return ControlKindSourceQuench
case uint8(ControlKindRedirectMessage):
return ControlKindRedirectMessage
case uint8(ControlKindEchoRequest):
return ControlKindEchoRequest
case uint8(ControlKindRouterAdvertisement):
return ControlKindRouterAdvertisement
case uint8(ControlKindRouterSolicitation):
return ControlKindRouterSolicitation
case uint8(ControlKindTimeExceeded):
return ControlKindTimeExceeded
case uint8(ControlKindParameterProblem):
return ControlKindParameterProblem
case uint8(ControlKindTimestamp):
return ControlKindTimestamp
case uint8(ControlKindTimestampReply):
return ControlKindTimestampReply
case uint8(ControlKindInformationRequest):
return ControlKindInformationRequest
case uint8(ControlKindInformationReply):
return ControlKindInformationReply
case uint8(ControlKindAddressMaskRequest):
return ControlKindAddressMaskRequest
case uint8(ControlKindAddressMaskReply):
return ControlKindAddressMaskReply
case uint8(ControlKindTraceroute):
return ControlKindTraceroute
case uint8(ControlKindDeprecatedDatagramConversion):
return ControlKindDeprecatedDatagramConversion
case uint8(ControlKindExtendedEchoRequest):
return ControlKindExtendedEchoRequest
case uint8(ControlKindExtendedEchoReply):
return ControlKindExtendedEchoReply
case uint8(ControlKindExtendedEchoRequest):
return ControlKindExtendedEchoRequest
default:
return ControlKind(255) // Reserved
}
Expand All @@ -138,40 +85,12 @@ func (c ControlKind) String() string {
return "Echo Reply"
case ControlKindDestinationUnreachable:
return "Destination Unreachable"
case ControlKindSourceQuench:
return "Source Quench"
case ControlKindRedirectMessage:
return "Redirect Message"
case ControlKindEchoRequest:
return "Echo Request"
case ControlKindRouterAdvertisement:
return "Router Advertisement"
case ControlKindRouterSolicitation:
return "Router Solicitation"
case ControlKindTimeExceeded:
return "Time Exceeded"
case ControlKindParameterProblem:
return "Parameter Problem: Bad IP header"
case ControlKindTimestamp:
return "Timestamp"
case ControlKindTimestampReply:
return "Timestamp Reply"
case ControlKindInformationRequest:
return "Information Request"
case ControlKindInformationReply:
return "Information Reply"
case ControlKindAddressMaskRequest:
return "Address Mask Request"
case ControlKindAddressMaskReply:
return "Address Mask Reply"
case ControlKindTraceroute:
return "Traceroute"
case ControlKindDeprecatedDatagramConversion:
return "Deprecated Datagram Conversion Error"
case ControlKindExtendedEchoRequest:
return "Extended Echo Request"
case ControlKindExtendedEchoReply:
return "Extended Echo Reply"
case ControlKindExtendedEchoRequest:
return "Extended Echo Request"
default:
return "Reserved"
}
Expand Down Expand Up @@ -216,33 +135,8 @@ func ParseControlCode(kind ControlKind, code uint8) ControlCode {
case uint8(ControlCodePrecedenceCutoffInEffect):
return ControlCodePrecedenceCutoffInEffect
}
case ControlKindRedirectMessage:
switch code {
case uint8(ControlCodeRedirectDatagramForNetwork):
return ControlCodeRedirectDatagramForNetwork
case uint8(ControlCodeRedirectDatagramForHost):
return ControlCodeRedirectDatagramForHost
case uint8(ControlCodeRedirectDatagramForToSNet):
return ControlCodeRedirectDatagramForToSNet
case uint8(ControlCodeRedirectDatagramForToSHost):
return ControlCodeRedirectDatagramForToSHost
}
case ControlKindTimeExceeded:
switch code {
case uint8(ControlCodeTTLExpiredInTransit):
return ControlCodeTTLExpiredInTransit
case uint8(ControlCodeFragmentReassemblyTimeExceeded):
return ControlCodeFragmentReassemblyTimeExceeded
}
case ControlKindParameterProblem:
switch code {
case uint8(ControlCodePointerIndicatesError):
return ControlCodePointerIndicatesError
case uint8(ControlCodeMissingRequiredOption):
return ControlCodeMissingRequiredOption
case uint8(ControlCodeBadLength):
return ControlCodeBadLength
}
case ControlKindEchoRequest:
return ControlCodeEchoRequest
case ControlKindExtendedEchoReply:
switch code {
case uint8(ControlCodeNoError):
Expand All @@ -256,6 +150,8 @@ func ParseControlCode(kind ControlKind, code uint8) ControlCode {
case uint8(ControlCodeMultipleInterfacesSatisfyQuery):
return ControlCodeMultipleInterfacesSatisfyQuery
}
case ControlKindExtendedEchoRequest:
return ControlCodeExtendedEchoRequest
}
return ControlCode(255) // Reserved
}
Expand All @@ -266,6 +162,8 @@ func (c ControlCode) Uint8() uint8 {

func (c ControlCode) String(kind ControlKind) string {
switch kind {
case ControlKindEchoReply:
return "Echo Reply"
case ControlKindDestinationUnreachable:
switch c {
case ControlCodeNetworkUnreachable:
Expand Down Expand Up @@ -301,33 +199,8 @@ func (c ControlCode) String(kind ControlKind) string {
case ControlCodePrecedenceCutoffInEffect:
return "Precedence cutoff in effect"
}
case ControlKindRedirectMessage:
switch c {
case ControlCodeRedirectDatagramForNetwork:
return "Redirect Datagram for the Network"
case ControlCodeRedirectDatagramForHost:
return "Redirect Datagram for the Host"
case ControlCodeRedirectDatagramForToSNet:
return "Redirect Datagram for the ToS & network"
case ControlCodeRedirectDatagramForToSHost:
return "Redirect Datagram for the ToS & host"
}
case ControlKindTimeExceeded:
switch c {
case ControlCodeTTLExpiredInTransit:
return "TTL expired in transit"
case ControlCodeFragmentReassemblyTimeExceeded:
return "Fragment reassembly time exceeded"
}
case ControlKindParameterProblem:
switch c {
case ControlCodePointerIndicatesError:
return "Pointer indicates the error"
case ControlCodeMissingRequiredOption:
return "Missing a required option"
case ControlCodeBadLength:
return "Bad length"
}
case ControlKindEchoRequest:
return "Echo Request"
case ControlKindExtendedEchoReply:
switch c {
case ControlCodeNoError:
Expand All @@ -341,6 +214,9 @@ func (c ControlCode) String(kind ControlKind) string {
case ControlCodeMultipleInterfacesSatisfyQuery:
return "Multiple Interfaces Satisfy Query"
}
case ControlKindExtendedEchoRequest:
return "Extended Echo Request"
}

return "Reserved"
}
Loading

0 comments on commit 19f19d0

Please sign in to comment.