Envoy/Downloads/GoNetDev-master/Protocols/ICMP.go

180 lines
4.0 KiB
Go
Raw Normal View History

2023-10-27 16:45:33 +00:00
package Protocols
import (
"encoding/binary"
"fmt"
"github.com/sabouaram/GoNetDev/Protocols/Const_Fields"
"github.com/sabouaram/GoNetDev/Protocols/Utils"
"reflect"
"strconv"
)
// RFC 792 INTERNET CONTROL MESSAGE PROTOCOL
/* Developer: Salim BOU ARAM, e-mail: salimbouaram12@gmail.com */
type ICMP struct {
Type []byte
Code []byte
Checksum []byte
Identifier []byte
SequenceN []byte
Payload []byte
}
func NewICMPHeader() (header *ICMP) {
return &ICMP{}
}
func (ICMPH *ICMP) BuildICMPHeader(Type uint8) {
var Header []byte
switch Type {
case Const_Fields.ICMP_Type_Echo:
{
Header = make([]byte, 40)
ICMPH.Type = Header[0:1]
ICMPH.Code = Header[1:2]
ICMPH.Checksum = Header[2:4]
ICMPH.Identifier = Header[4:6]
ICMPH.SequenceN = Header[6:8]
ICMPH.Payload = Header[8:]
ICMPH.Type = []byte{Type}
ICMPH.Code = []byte{0x00}
ICMPH.Checksum = []byte{0x00, 0x00}
ICMPH.Identifier = []byte{0x00, 0x01}
ICMPH.SequenceN = []byte{0x00, 0x4f}
ICMPH.Payload = []byte{0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
ICMPH.CheckSum()
}
case Const_Fields.ICMP_Type_Reply:
{
Header = make([]byte, 40)
ICMPH.Type = Header[0:1]
ICMPH.Code = Header[1:2]
ICMPH.Checksum = Header[2:4]
ICMPH.Identifier = Header[4:6]
ICMPH.SequenceN = Header[6:8]
ICMPH.Payload = Header[8:]
ICMPH.Type = []byte{Type}
ICMPH.Code = []byte{0x00}
ICMPH.Checksum = []byte{0x00, 0x00}
ICMPH.Identifier = []byte{0x00, 0x001}
ICMPH.SequenceN = []byte{0x00, 0x54}
ICMPH.Payload = []byte{0x74, 0x65, 0x73, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
ICMPH.CheckSum()
}
case Const_Fields.ICMP_Type_Exceeded:
{
// -> TO DO
}
case Const_Fields.ICMP_Type_Unreachable:
{
// -> TO DO
}
case Const_Fields.ICMP_Type_Paremeter_problem:
{
// -> TO DO
}
case Const_Fields.ICMP_Type_Source_quench:
{
// -> TO DO
}
case Const_Fields.ICMP_Type_Redirect:
{
// -> TO DO
}
case Const_Fields.ICMP_Type_Timestamp:
{
// -> TO DO
}
case Const_Fields.ICMP_Type_TimestampReply:
{
// -> TO DO
}
case Const_Fields.ICMP_Type_InformationRequest:
{
// -> TO DO
}
case Const_Fields.ICMP_Type_InformationReply:
{
// -> TO DO
}
}
}
func (ICMPH *ICMP) CheckSum() {
byte_array := ICMPH.ICMPBytes()
var intsum int64 = 0
for i := 0; i <= len(byte_array)-1; i += 2 {
uintsumf, _ := strconv.ParseUint(fmt.Sprintf("%x", byte_array[i:i+2]), 16, 16)
intsum += int64(uintsumf)
if intsum > 65536 {
intsum -= 65536
}
}
cheksum := uint16(intsum) ^ 0xffff
binary.BigEndian.PutUint16(ICMPH.Checksum, cheksum)
}
func (ICMPH *ICMP) SetPayload(data []byte) {
ICMPH.Payload = []byte{}
ICMPH.Payload = data
ICMPH.CheckSum()
}
func (ICMPH *ICMP) GetIdentifier() (Identifier []byte) {
return ICMPH.Identifier
}
func (ICMPH *ICMP) SetIdentifier(Identifier []byte) {
ICMPH.Identifier = []byte{}
ICMPH.Identifier = Identifier
ICMPH.CheckSum()
}
func (ICMPH *ICMP) GetSequenceN() (SequenceN []byte) {
return ICMPH.SequenceN
}
func (ICMPH *ICMP) SetSequenceN(SequenceN []byte) {
ICMPH.SequenceN = []byte{}
ICMPH.SequenceN = SequenceN
ICMPH.CheckSum()
}
func (ICMPH *ICMP) GetType() uint8 {
array := [8]uint8{}
copy(array[:], ICMPH.Type)
return array[0]
}
func (ICMPH *ICMP) ParseICMP(byte_slice []byte) {
ICMPH.Type = byte_slice[0:1]
ICMPH.Code = byte_slice[1:2]
ICMPH.Checksum = byte_slice[2:4]
ICMPH.Identifier = byte_slice[4:6]
ICMPH.SequenceN = byte_slice[6:8]
ICMPH.Payload = byte_slice[8:40]
}
func (ICMPH *ICMP) ICMPBytes() []byte {
sRValue := reflect.ValueOf(ICMPH).Elem()
sRType := sRValue.Type()
array := [][]byte{}
for i := 0; i < sRType.NumField(); i++ {
if len(sRValue.Field(i).Bytes()) != 0 {
array = append(array, sRValue.Field(i).Bytes())
}
}
return Utils.ConcatAppend(array)
}